re PR tree-optimization/53636 (SLP may create invalid unaligned memory accesses)
authorUlrich Weigand <ulrich.weigand@linaro.org>
Fri, 15 Jun 2012 13:30:36 +0000 (13:30 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Fri, 15 Jun 2012 13:30:36 +0000 (13:30 +0000)
gcc/
PR tree-optimization/53636
* tree-vect-data-refs.c (vect_compute_data_ref_alignment): Verify
stride when doing basic-block vectorization.

gcc/testsuite/
PR tree-optimization/53636
* gcc.target/arm/pr53636.c: New test.

From-SVN: r188661

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr53636.c [new file with mode: 0644]
gcc/tree-vect-data-refs.c

index 5ce784a4c0e12eed31a520d2cda4de369bb8b713..99e290433f5fb6f5ecc7d34e355bef96463af9dd 100644 (file)
@@ -1,3 +1,9 @@
+2012-06-15  Ulrich Weigand  <ulrich.weigand@linaro.org>
+
+       PR tree-optimization/53636
+       * tree-vect-data-refs.c (vect_compute_data_ref_alignment): Verify
+       stride when doing basic-block vectorization.
+
 2012-06-15  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>
 
        * tree-vect-generic.c (lower_vec_perm): Propagate vector constants
index f3d10e3fb5e581f17ee352f630a04067ab7938a3..ca264c33a3c92f8b8cbd37b7e964dd19f756d49a 100644 (file)
@@ -1,3 +1,8 @@
+2012-06-15  Ulrich Weigand  <ulrich.weigand@linaro.org>
+
+       PR tree-optimization/53636
+       * gcc.target/arm/pr53636.c: New test.
+
 2012-06-15  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/51581
diff --git a/gcc/testsuite/gcc.target/arm/pr53636.c b/gcc/testsuite/gcc.target/arm/pr53636.c
new file mode 100644 (file)
index 0000000..dbad795
--- /dev/null
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-require-effective-target arm_neon_hw } */
+/* { dg-options "-O -ftree-vectorize" } */
+/* { dg-add-options arm_neon } */
+
+void fill (short *buf) __attribute__ ((noinline));
+void fill (short *buf)
+{
+  int i;
+
+  for (i = 0; i < 11 * 8; i++)
+    buf[i] = i;
+}
+
+void test (unsigned char *dst) __attribute__ ((noinline));
+void test (unsigned char *dst)
+{
+  short tmp[11 * 8], *tptr;
+  int i;
+
+  fill (tmp);
+
+  tptr = tmp;
+  for (i = 0; i < 8; i++)
+    {
+      dst[0] = (-tptr[0] + 9 * tptr[0 + 1] + 9 * tptr[0 + 2] - tptr[0 + 3]) >> 7;
+      dst[1] = (-tptr[1] + 9 * tptr[1 + 1] + 9 * tptr[1 + 2] - tptr[1 + 3]) >> 7;
+      dst[2] = (-tptr[2] + 9 * tptr[2 + 1] + 9 * tptr[2 + 2] - tptr[2 + 3]) >> 7;
+      dst[3] = (-tptr[3] + 9 * tptr[3 + 1] + 9 * tptr[3 + 2] - tptr[3 + 3]) >> 7;
+      dst[4] = (-tptr[4] + 9 * tptr[4 + 1] + 9 * tptr[4 + 2] - tptr[4 + 3]) >> 7;
+      dst[5] = (-tptr[5] + 9 * tptr[5 + 1] + 9 * tptr[5 + 2] - tptr[5 + 3]) >> 7;
+      dst[6] = (-tptr[6] + 9 * tptr[6 + 1] + 9 * tptr[6 + 2] - tptr[6 + 3]) >> 7;
+      dst[7] = (-tptr[7] + 9 * tptr[7 + 1] + 9 * tptr[7 + 2] - tptr[7 + 3]) >> 7;
+
+      dst += 8;
+      tptr += 11;
+    }
+}
+
+int main (void)
+{
+  char buf [8 * 8];
+
+  test (buf);
+
+  return 0;
+}
+
index ed967f236ade66588bc8435404a58fedd2fe3afc..29dff45482be9a923428e0528de6fab4641fae7a 100644 (file)
@@ -861,6 +861,24 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
        }
     }
 
+  /* Similarly, if we're doing basic-block vectorization, we can only use
+     base and misalignment information relative to an innermost loop if the
+     misalignment stays the same throughout the execution of the loop.
+     As above, this is the case if the stride of the dataref evenly divides
+     by the vector size.  */
+  if (!loop)
+    {
+      tree step = DR_STEP (dr);
+      HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
+
+      if (dr_step % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0)
+       {
+         if (vect_print_dump_info (REPORT_ALIGNMENT))
+           fprintf (vect_dump, "SLP: step doesn't divide the vector-size.");
+         misalign = NULL_TREE;
+       }
+    }
+
   base = build_fold_indirect_ref (base_addr);
   alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);