re PR rtl-optimization/49710 (segfault)
authorJan Hubicka <jh@suse.cz>
Thu, 5 Jan 2012 19:25:14 +0000 (20:25 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 5 Jan 2012 19:25:14 +0000 (19:25 +0000)
PR middle-end/49710
* cfgloopmanip.c (remove_path): Walk loop hiearchy upwards when
unlooping loops.

From-SVN: r182919

gcc/ChangeLog
gcc/cfgloopmanip.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr49710.c [new file with mode: 0644]

index 4e5c771ab27021cf825b4a949c38ba65f1b258bd..1e612427ebf7b1c91837662a0a1c9dd36c3a7327 100644 (file)
@@ -1,3 +1,9 @@
+2012-01-05  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/49710
+       * cfgloopmanip.c (remove_path): Walk loop hiearchy upwards when
+       unlooping loops.
+
 2012-01-05  Richard Guenther  <rguenther@suse.de>
 
        PR lto/50490
index 967541756b5f8b60e0f4feb1782a1afcaaaa814f..33bcf4b987279f500c834564b28145b7a5ccb102 100644 (file)
@@ -291,6 +291,7 @@ remove_path (edge e)
   sbitmap seen;
   bool irred_invalidated = false;
   edge_iterator ei;
+  struct loop *l, *f;
 
   if (!can_remove_branch_p (e))
     return false;
@@ -314,10 +315,12 @@ remove_path (edge e)
      we belong to.  In this case first unloop the loops, then proceed
      normally.   We may assume that e->dest is not a header of any loop,
      as it now has exactly one predecessor.  */
-  while (loop_outer (e->src->loop_father)
-        && dominated_by_p (CDI_DOMINATORS,
-                           e->src->loop_father->latch, e->dest))
-    unloop (e->src->loop_father, &irred_invalidated);
+  for (l = e->src->loop_father; loop_outer (l); l = f)
+    {
+      f = loop_outer (l);
+      if (dominated_by_p (CDI_DOMINATORS, l->latch, e->dest))
+        unloop (l, &irred_invalidated);
+    }
 
   /* Identify the path.  */
   nrem = find_path (e, &rem_bbs);
index c4af2c8dd47e8fc3f854b49e1b98bb5c01672025..d324db6a2e38f334097f3508497fb19dba794c88 100644 (file)
@@ -1,3 +1,8 @@
+2012-01-05  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/49710
+       * gcc.c-torture/compile/pr49710.c: New file.
+
 2012-01-05  Richard Guenther  <rguenther@suse.de>
 
        * g++.dg/torture/pr49309.C: Skip for -flto.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr49710.c b/gcc/testsuite/gcc.c-torture/compile/pr49710.c
new file mode 100644 (file)
index 0000000..2a6e331
--- /dev/null
@@ -0,0 +1,35 @@
+int a, b, c, d;
+
+static void
+foo (int *x)
+{
+  c = 0;
+  while (1)
+    {
+      if (*x)
+break;
+      while (b)
+for (; c; c = 0);
+      for (d = 18; d != 18; d++)
+if (c)
+  {
+    foo (x);
+    return;
+  }
+    }
+}
+
+static void
+bar ()
+{
+  foo (0);
+  foo (0);
+  for (;;)
+    ;
+}
+
+baz ()
+{
+  for (; a;)
+    bar ();
+}