re PR tree-optimization/79088 (wrong code at -O2 on x86_64-linux-gnu)
authorRichard Biener <rguenther@suse.de>
Mon, 23 Jan 2017 22:29:17 +0000 (22:29 +0000)
committerJeff Law <law@gcc.gnu.org>
Mon, 23 Jan 2017 22:29:17 +0000 (15:29 -0700)
2017-01-23  Richard Biener  <rguenther@suse.de>

PR tree-optimization/79088
PR tree-optimization/79188
* tree-ssa-threadupdate.c (mark_threaded_blocks): Move code
resetting loop bounds after last path deletion.  Reset loop
bounds of the target loop, make code match the comments.
* tree-ssa-threadbackwards.c (pass_early_thread_jumps::execute):
Make sure loops need no fixups.

* gcc.dg/torture/pr79088.c: New testcase.
* gcc.dg/torture/pr79188.c: Likewise.

From-SVN: r244837

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr79088.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr79188.c [new file with mode: 0644]
gcc/tree-ssa-threadbackward.c
gcc/tree-ssa-threadupdate.c

index 468e012b14e14c51bf1ac338d720ee57645966b9..8df91c72f4d3c54b52864a6a75f0385a327362fe 100644 (file)
@@ -1,3 +1,13 @@
+2017-01-23  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/79088
+       PR tree-optimization/79188
+       * tree-ssa-threadupdate.c (mark_threaded_blocks): Move code
+       resetting loop bounds after last path deletion.  Reset loop
+       bounds of the target loop, make code match the comments.
+       * tree-ssa-threadbackwards.c (pass_early_thread_jumps::execute):
+       Make sure loops need no fixups.
+
 2017-01-23  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        * config/rs6000/rs6000-builtin.def (VSIEDPF): Add scalar insert
index 004bff932bb100252862e0fc24af6db6f63bef3e..c05ea54fe748ed6a8833e18910e8bf4b3adc151a 100644 (file)
@@ -1,3 +1,10 @@
+2017-01-23  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/79088
+       PR tree-optimization/79188
+       * gcc.dg/torture/pr79088.c: New testcase.
+       * gcc.dg/torture/pr79188.c: Likewise.
+
 2017-01-23  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        * gcc.target/powerpc/bfp/scalar-insert-exp-3.c: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr79088.c b/gcc/testsuite/gcc.dg/torture/pr79088.c
new file mode 100644 (file)
index 0000000..7c78f15
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+
+int a, b, c, d, e = 1;
+
+int main ()
+{
+  int f;
+  if (a)
+    goto L;
+  for (f = 0; f < e; e++)
+    {
+L:
+      if (d)
+       continue;
+      if (c)
+       goto L;
+      for (a = 0; a < 6; a++)
+       for (f = 0; f < 3; f++)
+         while (b)
+           c++;
+    }
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr79188.c b/gcc/testsuite/gcc.dg/torture/pr79188.c
new file mode 100644 (file)
index 0000000..fc3208c
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+
+int a, b, c, d, e, f, h, j, k;
+
+static void fn1 ()
+{
+  int g = 1, i;
+  if (!f)
+    {
+      for (; d < 1; d++)
+       for (i = 0, j = 1; i < 1; i = j)
+         a = 2;
+      for (; e < 1; e++)
+       {
+         for (; k; k++)
+           L:
+               ;
+         for (c = 0; c < 2; c++)
+           {
+             for (i = 0; i < 4; i++)
+               {
+                 for (; h; h++)
+                   g = 0;
+                 b = 0;
+               }
+             if (b)
+               goto L;
+           }
+         a = 0;
+       }
+      if (g < 0)
+       goto L;
+    }
+}
+
+int main ()
+{
+  fn1 ();
+
+  if (a != 0) 
+    __builtin_abort ();
+
+  return 0; 
+}
index e09ecb8906a62c5e54aedf312a906b267e56e3a0..51f30a7639c7ca9adba1da702438731d0cd08ca8 100644 (file)
@@ -865,6 +865,8 @@ pass_early_thread_jumps::gate (function *fun ATTRIBUTE_UNUSED)
 unsigned int
 pass_early_thread_jumps::execute (function *fun)
 {
+  loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
+
   /* Try to thread each block with more than one successor.  */
   basic_block bb;
   FOR_EACH_BB_FN (bb, fun)
@@ -873,6 +875,8 @@ pass_early_thread_jumps::execute (function *fun)
        find_jump_threads_backwards (bb, false);
     }
   thread_through_all_blocks (true);
+
+  loop_optimizer_finalize ();
   return 0;
 }
 
index f85fed314f0f4601883ef044448d22258e67a9fd..8e08ae29e03d33e7d9c3dbb9853d51e5049dfcb0 100644 (file)
@@ -2086,42 +2086,6 @@ mark_threaded_blocks (bitmap threaded_blocks)
   else
     bitmap_copy (threaded_blocks, tmp);
 
-  /* Look for jump threading paths which cross multiple loop headers.
-
-     The code to thread through loop headers will change the CFG in ways
-     that invalidate the cached loop iteration information.  So we must
-     detect that case and wipe the cached information.  */
-  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
-    {
-      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
-      FOR_EACH_EDGE (e, ei, bb->preds)
-       {
-         if (e->aux)
-           {
-             vec<jump_thread_edge *> *path = THREAD_PATH (e);
-
-             for (unsigned int i = 0, crossed_headers = 0;
-                  i < path->length ();
-                  i++)
-               {
-                 basic_block dest = (*path)[i]->e->dest;
-                 basic_block src = (*path)[i]->e->src;
-                 crossed_headers += (dest == dest->loop_father->header);
-                 /* If we step from a block outside an irreducible region
-                    to a block inside an irreducible region, then we have
-                    crossed into a loop.  */
-                 crossed_headers += ((src->flags & BB_IRREDUCIBLE_LOOP)
-                                     != (dest->flags & BB_IRREDUCIBLE_LOOP));
-                 if (crossed_headers > 1)
-                   {
-                     vect_free_loop_info_assumptions (dest->loop_father);
-                     break;
-                   }
-               }
-           }
-       }
-    }
-
   /* If we have a joiner block (J) which has two successors S1 and S2 and
      we are threading though S1 and the final destination of the thread
      is S2, then we must verify that any PHI nodes in S2 have the same
@@ -2166,6 +2130,46 @@ mark_threaded_blocks (bitmap threaded_blocks)
        }
     }
 
+  /* Look for jump threading paths which cross multiple loop headers.
+
+     The code to thread through loop headers will change the CFG in ways
+     that invalidate the cached loop iteration information.  So we must
+     detect that case and wipe the cached information.  */
+  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
+    {
+      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
+      FOR_EACH_EDGE (e, ei, bb->preds)
+       {
+         if (e->aux)
+           {
+             vec<jump_thread_edge *> *path = THREAD_PATH (e);
+
+             for (unsigned int i = 0, crossed_headers = 0;
+                  i < path->length ();
+                  i++)
+               {
+                 basic_block dest = (*path)[i]->e->dest;
+                 basic_block src = (*path)[i]->e->src;
+                 /* If we enter a loop.  */
+                 if (flow_loop_nested_p (src->loop_father, dest->loop_father))
+                   ++crossed_headers;
+                 /* If we step from a block outside an irreducible region
+                    to a block inside an irreducible region, then we have
+                    crossed into a loop.  */
+                 else if (! (src->flags & BB_IRREDUCIBLE_LOOP)
+                          && (dest->flags & BB_IRREDUCIBLE_LOOP))
+                     ++crossed_headers;
+                 if (crossed_headers > 1)
+                   {
+                     vect_free_loop_info_assumptions
+                       ((*path)[path->length () - 1]->e->dest->loop_father);
+                     break;
+                   }
+               }
+           }
+       }
+    }
+
   BITMAP_FREE (tmp);
 }