re PR tree-optimization/65935 (433.milc in SPEC CPU 2006 is miscompiled)
authorRichard Biener <rguenther@suse.de>
Mon, 4 May 2015 13:31:02 +0000 (13:31 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 4 May 2015 13:31:02 +0000 (13:31 +0000)
2015-05-04  Richard Biener  <rguenther@suse.de>

PR tree-optimization/65935
* tree-vect-slp.c (vect_build_slp_tree): If we swapped operands
then make sure to apply that swapping to the IL.

* gcc.dg/vect/bb-slp-pr65935.c: New testcase.

From-SVN: r222764

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c [new file with mode: 0644]
gcc/tree-vect-slp.c

index c751ea7ed6c014113f7f59fca403c0697a97a453..9ba7b943efc5669f51305e87fb28941aae0815fb 100644 (file)
@@ -1,3 +1,9 @@
+2015-05-04  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/65935
+       * tree-vect-slp.c (vect_build_slp_tree): If we swapped operands
+       then make sure to apply that swapping to the IL.
+
 2015-05-04  Jakub Jelinek  <jakub@redhat.com>
 
        * Makefile.in (PATCHLEVEL_c): New variable.
index eaff1ab5d762dc7f17fa907b4ea181da8737a17a..719e013cbcc7bf95965ec2e80f4f7cec3891973d 100644 (file)
@@ -1,3 +1,8 @@
+2015-05-04  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/65935
+       * gcc.dg/vect/bb-slp-pr65935.c: New testcase.
+
 2015-05-03  Christophe Lyon  <christophe.lyon@linaro.org>
 
        * gcc.target/aarch64/advsimd-intrinsics/binary_op.inc: Call CHECK
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c
new file mode 100644 (file)
index 0000000..057dc20
--- /dev/null
@@ -0,0 +1,63 @@
+/* { dg-do run } */
+/* { dg-additional-options "-O3" } */
+/* { dg-require-effective-target vect_double } */
+
+#include "tree-vect.h"
+
+extern void abort (void);
+extern void *malloc (__SIZE_TYPE__);
+
+struct site {
+    struct {
+       struct {
+           double real;
+           double imag;
+       } e[3][3];
+    } link[32];
+    double phase[32];
+} *lattice;
+int sites_on_node;
+
+void rephase (void)
+{
+  int i,j,k,dir;
+  struct site *s;
+  for(i=0,s=lattice;i<sites_on_node;i++,s++)
+    for(dir=0;dir<32;dir++)
+      for(j=0;j<3;j++)for(k=0;k<3;k++)
+       {
+         s->link[dir].e[j][k].real *= s->phase[dir];
+         s->link[dir].e[j][k].imag *= s->phase[dir];
+       }
+}
+
+int main()
+{
+  int i,j,k;
+  check_vect ();
+  sites_on_node = 1;
+  lattice = malloc (sizeof (struct site) * sites_on_node);
+  for (i = 0; i < 32; ++i)
+    {
+      lattice->phase[i] = i;
+      for (j = 0; j < 3; ++j)
+       for (k = 0; k < 3; ++k)
+         {
+           lattice->link[i].e[j][k].real = 1.0;
+           lattice->link[i].e[j][k].imag = 1.0;
+           __asm__ volatile ("" : : : "memory");
+         }
+    }
+  rephase ();
+  for (i = 0; i < 32; ++i)
+    for (j = 0; j < 3; ++j)
+      for (k = 0; k < 3; ++k)
+       if (lattice->link[i].e[j][k].real != i
+           || lattice->link[i].e[j][k].imag != i)
+         abort ();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp1" } } */
+/* { dg-final { cleanup-tree-dump "slp1" } } */
+/* { dg-final { cleanup-tree-dump "slp2" } } */
index 60f257b4da98a403b083e3670a4a9c9e1526da12..2b8f9bde5ae9d062bbcb031feae55e92fc8d7336 100644 (file)
@@ -1081,13 +1081,25 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
                dump_printf (MSG_NOTE, "%d ", j);
              }
          dump_printf (MSG_NOTE, "\n");
-         /* And try again ... */
+         /* And try again with scratch 'matches' ... */
+         bool *tem = XALLOCAVEC (bool, group_size);
          if (vect_build_slp_tree (loop_vinfo, bb_vinfo, &child,
                                   group_size, max_nunits, loads,
                                   vectorization_factor,
-                                  matches, npermutes, &this_tree_size,
+                                  tem, npermutes, &this_tree_size,
                                   max_tree_size))
            {
+             /* ... so if successful we can apply the operand swapping
+                to the GIMPLE IL.  This is necessary because for example
+                vect_get_slp_defs uses operand indexes and thus expects
+                canonical operand order.  */
+             for (j = 0; j < group_size; ++j)
+               if (!matches[j])
+                 {
+                   gimple stmt = SLP_TREE_SCALAR_STMTS (*node)[j];
+                   swap_ssa_operands (stmt, gimple_assign_rhs1_ptr (stmt),
+                                      gimple_assign_rhs2_ptr (stmt));
+                 }
              oprnd_info->def_stmts = vNULL;
              SLP_TREE_CHILDREN (*node).quick_push (child);
              continue;