The following patch fixes (?) PR55833 by recomputing irreducible loops
after every unswitch-transformation.  With this testcase, when we perform
loop unswitching on the RTL level, we end up in situation where we have
a loop into which we get through loop exit of another loop which is
a part of an irreducible region.  Between those two loops is something like
preheader, which isn't marked as irreducible, nor its edges.  
verify_loop_structure
then ICEs because of that.  Another hunk of this patch is just cheaper checking,
written by Richi.

Regtested/bootstrapped on x86_64-linux.

Zdenek, any thoughts on this?

2013-01-10  Richard Biener  <rguent...@suse.de>
            Marek Polacek  <pola...@redhat.com>

        PR rtl-optimization/55833
        * loop-unswitch.c (unswitch_loops): Move loop verification...
        (unswitch_single_loop): ...here.  Call mark_irreducible_loops.

        * gcc.dg/pr55833.c: New test.

--- gcc/loop-unswitch.c.mp      2013-01-10 16:50:28.899559875 +0100
+++ gcc/loop-unswitch.c 2013-01-10 16:50:34.203575403 +0100
@@ -145,12 +145,7 @@ unswitch_loops (void)
   /* Go through inner loops (only original ones).  */
 
   FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
-    {
-      unswitch_single_loop (loop, NULL_RTX, 0);
-#ifdef ENABLE_CHECKING
-      verify_loop_structure ();
-#endif
-    }
+    unswitch_single_loop (loop, NULL_RTX, 0);
 
   iv_analysis_done ();
 }
@@ -370,6 +365,13 @@ unswitch_single_loop (struct loop *loop,
   nloop = unswitch_loop (loop, bbs[i], copy_rtx_if_shared (cond), cinsn);
   gcc_assert (nloop);
 
+  /* We changed the CFG.  Recompute irreducible BBs and edges.  */
+  mark_irreducible_loops ();
+
+#ifdef ENABLE_CHECKING
+  verify_loop_structure ();
+#endif
+
   /* Invoke itself on modified loops.  */
   unswitch_single_loop (nloop, rconds, num + 1);
   unswitch_single_loop (loop, conds, num + 1);
--- gcc/testsuite/gcc.dg/pr55833.c.mp   2013-01-10 17:23:26.016102692 +0100
+++ gcc/testsuite/gcc.dg/pr55833.c      2013-01-10 17:23:15.898073384 +0100
@@ -0,0 +1,28 @@
+/* PR rtl-optimization/55833 */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int a, b, c;
+
+void foo()
+{
+    unsigned d, l, *p, k = 1;
+
+    if(bar())
+    {
+label:
+       if((a = a <= 0))
+        {
+            if(c)
+                d = b;
+
+            if (b || d ? l : k ? : 0)
+                a = d = 0;
+
+            goto label;
+               }
+    }
+
+    while(*p++)
+        goto label;
+}

        Marek

Reply via email to