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.

Reply via email to