On December 31, 2020 4:51:26 PM GMT+01:00, Richard Sandiford <richard.sandif...@arm.com> wrote: >This PR is about a case in which the vectoriser was feeding >incorrect alignment information to tree-data-ref.c, leading >to incorrect runtime alias checks. The alignment was taken >from the TREE_TYPE of the DR_REF, which in this case was a >COMPONENT_REF with a normally-aligned type. However, the >underlying MEM_REF was only byte-aligned. > >This patch uses dr_alignment to calculate the (byte) alignment >instead, just like we do when creating vector MEM_REFs. > >Tested on aarch64-linux-gnu, aarch64_be-elf and x86_64-linux-gnu. >OK to install?
Ok. Richard. >Richard > > >gcc/ > PR tree-optimization/94994 > * tree-vect-data-refs.c (vect_vfa_align): Use dr_alignment. > >gcc/testsuite/ > PR tree-optimization/94994 > * gcc.dg/vect/pr94994.c: New test. >--- > gcc/testsuite/gcc.dg/vect/pr94994.c | 61 +++++++++++++++++++++++++++++ > gcc/tree-vect-data-refs.c | 2 +- > 2 files changed, 62 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.dg/vect/pr94994.c > >diff --git a/gcc/testsuite/gcc.dg/vect/pr94994.c >b/gcc/testsuite/gcc.dg/vect/pr94994.c >new file mode 100644 >index 00000000000..e98aeb090d8 >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/vect/pr94994.c >@@ -0,0 +1,61 @@ >+#include <stdint.h> >+#include "tree-vect.h" >+ >+#define BLOCK_SIZE (sizeof (uint32_t)) >+ >+struct unaligned { >+ uint32_t x; >+} __attribute__((packed, may_alias)); >+ >+static inline uint32_t >+load_unaligned (const char *p) >+{ >+ return ((struct unaligned *) p)->x; >+} >+ >+static inline void >+store_unaligned (uint32_t x, char *p) >+{ >+ ((struct unaligned *) p)->x = x; >+} >+ >+void __attribute__((noipa)) >+copy (char *dst, const char *src, size_t n) >+{ >+ for (size_t i = 0; i < n; i += BLOCK_SIZE) >+ store_unaligned (load_unaligned (src + i), dst + i); >+} >+ >+#define INPUT_SIZE 64 >+#define MAX_STEP 32 >+ >+char x[INPUT_SIZE + MAX_STEP]; >+ >+int >+main (void) >+{ >+ check_vect (); >+ >+ for (unsigned int i = 1; i < MAX_STEP; ++i) >+ { >+ for (unsigned int j = 0; j < INPUT_SIZE + MAX_STEP; ++j) >+ x[j] = j + 10; >+ copy (x + i, x, INPUT_SIZE); >+ for (int j = 0; j < INPUT_SIZE + i; ++j) >+ { >+ int expected; >+ if (j < i) >+ expected = j + 10; >+ else if (i >= BLOCK_SIZE) >+ expected = j % i + 10; >+ else if ((j - i) % BLOCK_SIZE < i) >+ expected = x[j - i]; >+ else >+ expected = j - i + 10; >+ if (x[j] != expected) >+ __builtin_abort (); >+ } >+ } >+ >+ return 0; >+} >diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c >index 137017091e8..5fe9cad4da8 100644 >--- a/gcc/tree-vect-data-refs.c >+++ b/gcc/tree-vect-data-refs.c >@@ -3258,7 +3258,7 @@ vect_vfa_access_size (vec_info *vinfo, >dr_vec_info *dr_info) > static unsigned int > vect_vfa_align (dr_vec_info *dr_info) > { >- return TYPE_ALIGN_UNIT (TREE_TYPE (DR_REF (dr_info->dr))); >+ return dr_alignment (dr_info->dr); > } > > /* Function vect_no_alias_p.