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; + } +}