The following patch fixes PR64357 (or papers over some latent issue). We were not protecting a certain aspect of simple latches properly (a simple latch should belong to its loop).
Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2015-01-12 Richard Biener <rguent...@suse.de> PR middle-end/64357 * tree-cfg.c (gimple_can_merge_blocks_p): Protect simple latches properly. * gcc.dg/torture/pr64357.c: New testcase. Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c (revision 219446) +++ gcc/tree-cfg.c (working copy) @@ -1723,11 +1727,13 @@ gimple_can_merge_blocks_p (basic_block a } /* Protect simple loop latches. We only want to avoid merging - the latch with the loop header in this case. */ + the latch with the loop header or with a block in another + loop in this case. */ if (current_loops && b->loop_father->latch == b && loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES) - && b->loop_father->header == a) + && (b->loop_father->header == a + || b->loop_father != a->loop_father)) return false; /* It must be possible to eliminate all phi nodes in B. If ssa form Index: gcc/testsuite/gcc.dg/torture/pr64357.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr64357.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr64357.c (working copy) @@ -0,0 +1,34 @@ +/* { dg-do compile } */ + +int a, b, c, d, e, f; + +long long +fn1 (int p) +{ + return p ? p : 1; +} + +static int +fn2 () +{ +lbl: + for (; f;) + return 0; + for (;;) + { + for (b = 0; b; ++b) + if (d) + goto lbl; + c = e; + } +} + +void +fn3 () +{ + for (; a; a = fn1 (a)) + { + fn2 (); + e = 0; + } +}