diff --git a/gcc/testsuite/gcc.dg/vect/pr98674.c b/gcc/testsuite/gcc.dg/vect/pr98674.c new file mode 100644 index 00000000000..0f1b6cb060b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr98674.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-msse2" { target sse2 } } */ + +void swap(short *p, int cnt) +{ + while (cnt-- > 0) + { + *p = ((*p << 8) & 0xFF00) | ((*p >> 8) & 0x00FF); + ++p; + } +} + +/* Dependence analysis should not fail. */ +/* { dg-final { scan-tree-dump "dependence distance == 0" "vect" } } */ +/* On x86 with SSE2 we can vectorize this with psllw/psrlw. */ +/* { dg-final { scan-tree-dump "loop vectorized" "vect" { target sse2 } } } */ diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 394470af757..65fe6d5da91 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -1291,6 +1291,23 @@ access_fn_component_p (tree op) } } +/* Returns whether BASE can have a access_fn_component_p with BASE + as base. */ + +static bool +base_supports_access_fn_components_p (tree base) +{ + switch (TREE_CODE (TREE_TYPE (base))) + { + case COMPLEX_TYPE: + case ARRAY_TYPE: + case RECORD_TYPE: + return true; + default: + return false; + } +} + /* Determines the base object and the list of indices of memory reference DR, analyzed in LOOP and instantiated before NEST. */ @@ -3272,8 +3289,13 @@ initialize_data_dependence_relation (struct data_reference *a, && full_seq.start_b + full_seq.length == num_dimensions_b && DR_UNCONSTRAINED_BASE (a) == DR_UNCONSTRAINED_BASE (b) && operand_equal_p (base_a, base_b, OEP_ADDRESS_OF) - && types_compatible_p (TREE_TYPE (base_a), - TREE_TYPE (base_b)) + && (types_compatible_p (TREE_TYPE (base_a), + TREE_TYPE (base_b)) + || (!base_supports_access_fn_components_p (base_a) + && !base_supports_access_fn_components_p (base_b) + && operand_equal_p + (TYPE_SIZE (TREE_TYPE (base_a)), + TYPE_SIZE (TREE_TYPE (base_b)), 0))) && (!loop_nest.exists () || (object_address_invariant_in_loop_p (loop_nest[0], base_a))));