re PR tree-optimization/81573 (wrong code at -O3 on x86_64-linux-gnu)
authorRichard Biener <rguenther@suse.de>
Thu, 27 Jul 2017 13:46:07 +0000 (13:46 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 27 Jul 2017 13:46:07 +0000 (13:46 +0000)
2017-07-27  Richard Biener  <rguenther@suse.de>

PR tree-optimization/81573
PR tree-optimization/81494
* tree-vect-loop.c (vect_create_epilog_for_reduction): Handle
multi defuse cycle case.

* gcc.dg/torture/pr81573.c: New testcase.

From-SVN: r250627

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr81573.c [new file with mode: 0644]
gcc/tree-vect-loop.c

index 3ae2f46c8f2b2cf88ea5b8411d4cf9bed4b824a7..77a77ebca7f5507483679bd8017bdc2f74ffcbb1 100644 (file)
@@ -1,3 +1,10 @@
+2017-07-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/81573
+       PR tree-optimization/81494
+       * tree-vect-loop.c (vect_create_epilog_for_reduction): Handle
+       multi defuse cycle case.
+
 2017-07-27  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/81571
index e12654400b92c477b7705b2f4f4fb4aa3fcd440a..fe0b88c84fed7cfc05eccc9f255d498e0f78e34e 100644 (file)
@@ -1,3 +1,9 @@
+2017-07-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/81573
+       PR tree-optimization/81494
+       * gcc.dg/torture/pr81573.c: New testcase.
+
 2017-07-27  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/81571
diff --git a/gcc/testsuite/gcc.dg/torture/pr81573.c b/gcc/testsuite/gcc.dg/torture/pr81573.c
new file mode 100644 (file)
index 0000000..3f0904a
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+int a = 1, *c = &a, d;
+char b;
+
+int main ()
+{
+  for (; b > -27; b--)
+    {
+      *c ^= b;
+      *c ^= 1;
+    }
+  while (a > 1)
+    ;
+  return 0; 
+}
index 5b1b8a1fdee321e2550a64c41bd4519552575935..8740a7573acdd5e44777e5f8ca80ab2086685f8a 100644 (file)
@@ -4787,20 +4787,17 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple *stmt,
   if (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
     {
       tree first_vect = PHI_RESULT (new_phis[0]);
-      tree tmp;
       gassign *new_vec_stmt = NULL;
-
       vec_dest = vect_create_destination_var (scalar_dest, vectype);
       for (k = 1; k < new_phis.length (); k++)
         {
          gimple *next_phi = new_phis[k];
           tree second_vect = PHI_RESULT (next_phi);
-
-          tmp = build2 (code, vectype,  first_vect, second_vect);
-          new_vec_stmt = gimple_build_assign (vec_dest, tmp);
-          first_vect = make_ssa_name (vec_dest, new_vec_stmt);
-          gimple_assign_set_lhs (new_vec_stmt, first_vect);
+          tree tem = make_ssa_name (vec_dest, new_vec_stmt);
+          new_vec_stmt = gimple_build_assign (tem, code,
+                                             first_vect, second_vect);
           gsi_insert_before (&exit_gsi, new_vec_stmt, GSI_SAME_STMT);
+         first_vect = tem;
         }
 
       new_phi_result = first_vect;
@@ -4810,6 +4807,28 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple *stmt,
           new_phis.safe_push (new_vec_stmt);
         }
     }
+  /* Likewise if we couldn't use a single defuse cycle.  */
+  else if (ncopies > 1)
+    {
+      gcc_assert (new_phis.length () == 1);
+      tree first_vect = PHI_RESULT (new_phis[0]);
+      gassign *new_vec_stmt = NULL;
+      vec_dest = vect_create_destination_var (scalar_dest, vectype);
+      gimple *next_phi = new_phis[0];
+      for (int k = 1; k < ncopies; ++k)
+       {
+         next_phi = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (next_phi));
+         tree second_vect = PHI_RESULT (next_phi);
+          tree tem = make_ssa_name (vec_dest, new_vec_stmt);
+          new_vec_stmt = gimple_build_assign (tem, code,
+                                             first_vect, second_vect);
+          gsi_insert_before (&exit_gsi, new_vec_stmt, GSI_SAME_STMT);
+         first_vect = tem;
+       }
+      new_phi_result = first_vect;
+      new_phis.truncate (0);
+      new_phis.safe_push (new_vec_stmt);
+    }
   else
     new_phi_result = PHI_RESULT (new_phis[0]);