re PR tree-optimization/59594 (wrong code (by tree vectorizer) at -O3 on x86_64-linux...
authorJakub Jelinek <jakub@gcc.gnu.org>
Wed, 29 Jan 2014 09:27:43 +0000 (10:27 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 29 Jan 2014 09:27:43 +0000 (10:27 +0100)
PR tree-optimization/59594
* tree-vect-data-refs.c (vect_analyze_data_ref_accesses): Sort
a copy of the datarefs vector rather than the vector itself.

* gcc.dg/vect/no-vfa-vect-depend-2.c: New test.
* gcc.dg/vect/no-vfa-vect-depend-3.c: New test.
* gcc.dg/vect/pr59594.c: New test.

From-SVN: r207225

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/pr59594.c [new file with mode: 0644]
gcc/tree-vect-data-refs.c

index 246105a932356a2ce8091a13913a1e9e53ddc300..ddf35958c4ffdada49b3ef1cc205aa06b200164f 100644 (file)
@@ -1,3 +1,9 @@
+2014-01-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/59594
+       * tree-vect-data-refs.c (vect_analyze_data_ref_accesses): Sort
+       a copy of the datarefs vector rather than the vector itself.
+
 2014-01-28  Jason Merrill  <jason@redhat.com>
 
        PR c++/53756
index 049da5834474516cd8a22f9025ef9646648a8c73..191845a3b35daf200f4efee3d56634374a92956d 100644 (file)
@@ -1,7 +1,14 @@
+2014-01-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/59594
+       * gcc.dg/vect/no-vfa-vect-depend-2.c: New test.
+       * gcc.dg/vect/no-vfa-vect-depend-3.c: New test.
+       * gcc.dg/vect/pr59594.c: New test.
+
 2014-01-28  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/59414
-       * gfortran.dg/allocate_class_3.f90 : New test
+       * gfortran.dg/allocate_class_3.f90: New test.
 
 2014-01-28  Dodji Seketeli  <dodji@redhat.com>
 
diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-2.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-2.c
new file mode 100644 (file)
index 0000000..3a94c03
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 17
+
+int ia[N] = {48,45,42,39,36,33,30,27,24,21,18,15,12,9,6,3,0};
+int ib[N] = {48,45,42,39,36,33,30,27,24,21,18,15,12,9,6,3,0};
+int res[N] = {48,192,180,168,156,144,132,120,108,96,84,72,60,48,36,24,12};
+
+__attribute__ ((noinline))
+int main1 ()
+{
+  int i;
+
+  /* Not vectorizable due to data dependence: dependence distance 1.  */ 
+  for (i = N - 1; i >= 0; i--)
+    {
+      ia[i] = ia[i+1] * 4;
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ia[i] != 0)
+       abort ();
+    } 
+
+  /* Vectorizable. Dependence distance -1.  */
+  for (i = N - 1; i >= 0; i--)
+    {
+      ib[i+1] = ib[i] * 4;
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ib[i] != res[i])
+       abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "dependence distance negative" 1 "vect"  } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-3.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-3.c
new file mode 100644 (file)
index 0000000..8f937a0
--- /dev/null
@@ -0,0 +1,187 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 64
+
+int ia[N + 1];
+int ib[N + 1];
+
+/* Vectorizable. Dependence distance -1.  */
+__attribute__((noinline)) void
+f1 (void)
+{
+  int i;
+  for (i = 0; i < N; i++)
+    {
+      ia[i + 1] = 1;
+      ib[i] = ia[i];
+    }
+}
+
+/* Not vectorizable due to data dependence: dependence distance 1.  */
+__attribute__((noinline)) void
+f2 (void)
+{
+  int i;
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = 1;
+      ib[i] = ia[i + 1];
+    }
+}
+
+/* Not vectorizable due to data dependence: dependence distance 1.  */
+__attribute__((noinline)) void
+f3 (void)
+{
+  int i;
+  for (i = N - 1; i >= 0; i--)
+    {
+      ia[i + 1] = 1;
+      ib[i] = ia[i];
+    }
+}
+
+/* Vectorizable. Dependence distance -1.  */
+__attribute__((noinline)) void
+f4 (void)
+{
+  int i;
+  for (i = N - 1; i >= 0; i--)
+    {
+      ia[i] = 1;
+      ib[i] = ia[i + 1];
+    }
+}
+
+/* Vectorizable. Dependence distance -1.  */
+__attribute__((noinline)) void
+f5 (void)
+{
+  int i;
+  for (i = 0; i < N; i++)
+    {
+      ia[i + 1] = 1;
+      ia[i] = 2;
+    }
+}
+
+/* Not vectorizable due to data dependence: dependence distance 1.  */
+__attribute__((noinline)) void
+f6 (void)
+{
+  int i;
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = 1;
+      ia[i + 1] = 2;
+    }
+}
+
+/* Not vectorizable due to data dependence: dependence distance 1.  */
+__attribute__((noinline)) void
+f7 (void)
+{
+  int i;
+  for (i = N - 1; i >= 0; i--)
+    {
+      ia[i + 1] = 1;
+      ia[i] = 2;
+    }
+}
+
+/* Vectorizable. Dependence distance -1.  */
+__attribute__((noinline)) void
+f8 (void)
+{
+  int i;
+  for (i = N - 1; i >= 0; i--)
+    {
+      ia[i] = 1;
+      ia[i + 1] = 2;
+    }
+}
+
+__attribute__ ((noinline)) int
+main1 (void)
+{
+  int i, j;
+
+  for (j = 0; j < 8; j++)
+    {
+      for (i = 0; i <= N; i++)
+       {
+         ia[i] = i + 3;
+         ib[i] = i + N + 3;
+         asm ("");
+       }
+
+      switch (j)
+       {
+       case 0: f1 (); break;
+       case 1: f2 (); break;
+       case 2: f3 (); break;
+       case 3: f4 (); break;
+       case 4: f5 (); break;
+       case 5: f6 (); break;
+       case 6: f7 (); break;
+       case 7: f8 (); break;
+       }
+
+      for (i = 0; i <= N; i++)
+       {
+         int ea = i + 3;
+         int eb = i + N + 3;
+         switch (j)
+           {
+           case 0:
+             if (i) ea = 1;
+             if (i == 0) eb = 3;
+             else if (i != N) eb = 1;
+             break;
+           case 1:
+             if (i != N) ea = 1;
+             if (i != N) eb = i + 4;
+             break;
+           case 2:
+             if (i) ea = 1;
+             if (i != N) eb = i + 3;
+             break;
+           case 3:
+             if (i != N) ea = 1;
+             if (i < N - 1) eb = 1;
+             else if (i == N - 1) eb = 67;
+             break;
+           case 4:
+             ea = 1 + (i != N);
+             break;
+           case 5:
+             ea = 2 - (i != N);
+             break;
+           case 6:
+             ea = 1 + (i == 0);
+             break;
+           case 7:
+             ea = 2 - (i == 0);
+             break;
+           }
+         if (ia[i] != ea || ib[i] != eb)
+           abort ();
+       }
+    }
+
+  return 0;
+}
+
+int main ()
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" {xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "dependence distance negative" 4 "vect"  } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr59594.c b/gcc/testsuite/gcc.dg/vect/pr59594.c
new file mode 100644 (file)
index 0000000..6c0b588
--- /dev/null
@@ -0,0 +1,31 @@
+/* PR tree-optimization/59594 */
+
+#include "tree-vect.h"
+
+#define N 1024
+int b[N + 1];
+
+int
+main ()
+{
+  int i;
+  check_vect ();
+  for (i = 0; i < N + 1; i++)
+    {
+      b[i] = i;
+      asm ("");
+    }
+  for (i = N; i >= 0; i--)
+    {
+      b[i + 1] = b[i];
+      b[i] = 1;
+    }
+  if (b[0] != 1)
+    __builtin_abort ();
+  for (i = 0; i < N; i++)
+    if (b[i + 1] != i)
+      __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
index 0deac8177fd141039dede98146f7ce1b1705f0bb..c3e8f372b839921de480db109da7daffd37de612 100644 (file)
@@ -2484,19 +2484,21 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
     return true;
 
   /* Sort the array of datarefs to make building the interleaving chains
-     linear.  */
-  qsort (datarefs.address (), datarefs.length (),
+     linear.  Don't modify the original vector's order, it is needed for
+     determining what dependencies are reversed.  */
+  vec<data_reference_p> datarefs_copy = datarefs.copy ();
+  qsort (datarefs_copy.address (), datarefs_copy.length (),
         sizeof (data_reference_p), dr_group_sort_cmp);
 
   /* Build the interleaving chains.  */
-  for (i = 0; i < datarefs.length () - 1;)
+  for (i = 0; i < datarefs_copy.length () - 1;)
     {
-      data_reference_p dra = datarefs[i];
+      data_reference_p dra = datarefs_copy[i];
       stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
       stmt_vec_info lastinfo = NULL;
-      for (i = i + 1; i < datarefs.length (); ++i)
+      for (i = i + 1; i < datarefs_copy.length (); ++i)
        {
-         data_reference_p drb = datarefs[i];
+         data_reference_p drb = datarefs_copy[i];
          stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
 
          /* ???  Imperfect sorting (non-compatible types, non-modulo
@@ -2573,7 +2575,7 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
        }
     }
 
-  FOR_EACH_VEC_ELT (datarefs, i, dr)
+  FOR_EACH_VEC_ELT (datarefs_copy, i, dr)
     if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) 
         && !vect_analyze_data_ref_access (dr))
       {
@@ -2588,9 +2590,13 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
             continue;
           }
         else
-          return false;
+         {
+           datarefs_copy.release ();
+           return false;
+         }
       }
 
+  datarefs_copy.release ();
   return true;
 }