This fixes an oversight in loop_optimizer_init () loop-fixup code
that fails to honor AVOID_CFG_MANIPULATIONS.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to
trunk and 4.9 branch.

Richard.

2014-04-23  Richard Biener  <rguent...@suse.de>

        PR middle-end/60891
        * loop-init.c (loop_optimizer_init): Make sure to apply
        LOOPS_MAY_HAVE_MULTIPLE_LATCHES before fixing up loops.

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

Index: gcc/loop-init.c
===================================================================
--- gcc/loop-init.c     (revision 209559)
+++ gcc/loop-init.c     (working copy)
@@ -94,20 +94,15 @@ loop_optimizer_init (unsigned flags)
   else
     {
       bool recorded_exits = loops_state_satisfies_p 
(LOOPS_HAVE_RECORDED_EXITS);
+      bool needs_fixup = loops_state_satisfies_p (LOOPS_NEED_FIXUP);
 
       gcc_assert (cfun->curr_properties & PROP_loops);
 
       /* Ensure that the dominators are computed, like flow_loops_find does.  
*/
       calculate_dominance_info (CDI_DOMINATORS);
 
-      if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
-       {
-         loops_state_clear (~0U);
-         fix_loop_structure (NULL);
-       }
-
 #ifdef ENABLE_CHECKING
-      else
+      if (!needs_fixup)
        verify_loop_structure ();
 #endif
 
@@ -115,6 +110,14 @@ loop_optimizer_init (unsigned flags)
       if (recorded_exits)
        release_recorded_exits ();
       loops_state_clear (~0U);
+
+      if (needs_fixup)
+       {
+         /* Apply LOOPS_MAY_HAVE_MULTIPLE_LATCHES early as fix_loop_structure
+            re-applies flags.  */
+         loops_state_set (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
+         fix_loop_structure (NULL);
+       }
     }
 
   /* Apply flags to loops.  */
Index: gcc/testsuite/gcc.dg/torture/pr60891.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr60891.c      (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr60891.c      (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-tree-ch -fno-tree-cselim 
-fno-tree-dominator-opts" } */
+
+int a, b, c, d, e, f;
+
+void foo (int x)
+{
+  for (;;)
+    {
+      int g = c;
+      if (x)
+       {
+         if (e)
+           while (a)
+             --f;
+       }
+      for (b = 5; b; b--)
+       {
+       }
+      if (!g)
+       x = 0;
+    }
+}

Reply via email to