Fix PR55833.
authorMarek Polacek <mpolacek@gcc.gnu.org>
Thu, 17 Jan 2013 19:19:37 +0000 (19:19 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Thu, 17 Jan 2013 19:19:37 +0000 (19:19 +0000)
From-SVN: r195280

gcc/ChangeLog
gcc/cfgloopmanip.c
gcc/loop-unswitch.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr55833.c [new file with mode: 0644]

index d7816844a51d67ed00d37d709c9c4832d87be770..773f4d7221beefd3054ead7c7aafdb932b75c797 100644 (file)
@@ -1,3 +1,15 @@
+2013-01-17  Richard Biener  <rguenther@suse.de>
+           Marek Polacek  <polacek@redhat.com>
+
+       PR rtl-optimization/55833
+       * loop-unswitch.c (unswitch_loops): Move loop verification...
+       (unswitch_single_loop): ...here.  Call mark_irreducible_loops.
+       * cfgloopmanip.c (fix_loop_placement): Add IRRED_INVALIDATED parameter.
+       Set it to true when we're removing a loop from hierarchy tree in
+       an irreducible region.
+       (fix_bb_placements): Adjust caller.
+       (fix_loop_placements): Likewise.
+
 2013-01-17  Georg-Johann Lay  <avr@gjlay.de>
 
        * config/avr/builtins.def (DEF_BUILTIN): Factor out
index 487560734faabaed5483ec620cbb426c7f6c25a2..8c6c39de86b0a734cd209e24374d1230c4bd270c 100644 (file)
@@ -111,10 +111,13 @@ fix_bb_placement (basic_block bb)
 /* Fix placement of LOOP inside loop tree, i.e. find the innermost superloop
    of LOOP to that leads at least one exit edge of LOOP, and set it
    as the immediate superloop of LOOP.  Return true if the immediate superloop
-   of LOOP changed.  */
+   of LOOP changed.
+
+   IRRED_INVALIDATED is set to true if a change in the loop structures might
+   invalidate the information about irreducible regions.  */
 
 static bool
-fix_loop_placement (struct loop *loop)
+fix_loop_placement (struct loop *loop, bool *irred_invalidated)
 {
   unsigned i;
   edge e;
@@ -139,7 +142,12 @@ fix_loop_placement (struct loop *loop)
       /* The exit edges of LOOP no longer exits its original immediate
         superloops; remove them from the appropriate exit lists.  */
       FOR_EACH_VEC_ELT (exits, i, e)
-       rescan_loop_exit (e, false, false);
+       {
+         /* We may need to recompute irreducible loops.  */
+         if (e->flags & EDGE_IRREDUCIBLE_LOOP)
+           *irred_invalidated = true;
+         rescan_loop_exit (e, false, false);
+       }
 
       ret = true;
     }
@@ -212,7 +220,7 @@ fix_bb_placements (basic_block from,
       if (from->loop_father->header == from)
        {
          /* Subloop header, maybe move the loop upward.  */
-         if (!fix_loop_placement (from->loop_father))
+         if (!fix_loop_placement (from->loop_father, irred_invalidated))
            continue;
          target_loop = loop_outer (from->loop_father);
        }
@@ -965,7 +973,7 @@ fix_loop_placements (struct loop *loop, bool *irred_invalidated)
   while (loop_outer (loop))
     {
       outer = loop_outer (loop);
-      if (!fix_loop_placement (loop))
+      if (!fix_loop_placement (loop, irred_invalidated))
        break;
 
       /* Changing the placement of a loop in the loop tree may alter the
index 25cbf18128397cbce5e4ab79185a6622e4cb5696..ded0aed3e0eb7d7d7cb01884beed9a78e715bf12 100644 (file)
@@ -144,12 +144,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 ();
 }
@@ -369,6 +364,10 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num)
   nloop = unswitch_loop (loop, bbs[i], copy_rtx_if_shared (cond), cinsn);
   gcc_assert (nloop);
 
+#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);
index bfdb73ae5b4b3b5c04b2a66bebe47f4812e48660..1bd5ca36ded8a17ad1e755ba7b90a97f07cc4c64 100644 (file)
@@ -1,3 +1,8 @@
+2013-01-17  Marek Polacek  <polacek@redhat.com>
+
+       PR rtl-optimization/55833
+       * gcc.dg/pr55833.c: New test.
+
 2013-01-17  Jan Hubicka  <jh@suse.cz>
 
        PR tree-optimization/55273
diff --git a/gcc/testsuite/gcc.dg/pr55833.c b/gcc/testsuite/gcc.dg/pr55833.c
new file mode 100644 (file)
index 0000000..7a5c549
--- /dev/null
@@ -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;
+}