The fix for this PR is to also schedule fixup of loops even if we're removing an entry into an irreducible region -- that might scramble the loop structure so we need to be careful.
Bootstrapped/regtested on x86_64-linux, ok for trunk? 2015-08-27 Marek Polacek <pola...@redhat.com> PR middle-end/67005 * tree-ssa-dce.c (remove_dead_stmt): Also schedule fixup if removing an entry into an irreducible region. * gcc.dg/torture/pr67005.c: New test. diff --git gcc/testsuite/gcc.dg/torture/pr67005.c gcc/testsuite/gcc.dg/torture/pr67005.c index e69de29..922c5c4 100644 --- gcc/testsuite/gcc.dg/torture/pr67005.c +++ gcc/testsuite/gcc.dg/torture/pr67005.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +int a; +void +f (void) +{ + if (!a); + else + lbl: + a = a; + + if (a) + a = 8; + goto lbl; +} diff --git gcc/tree-ssa-dce.c gcc/tree-ssa-dce.c index 2d2edc8..b2cd23f 100644 --- gcc/tree-ssa-dce.c +++ gcc/tree-ssa-dce.c @@ -1125,10 +1125,12 @@ remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb) if (e != e2) { cfg_altered = true; - /* If we made a BB unconditionally exit a loop then this - transform alters the set of BBs in the loop. Schedule - a fixup. */ - if (loop_exit_edge_p (bb->loop_father, e)) + /* If we made a BB unconditionally exit a loop or removed + an entry into an irreducible region, then this transform + alters the set of BBs in the loop. Schedule a fixup. */ + if (loop_exit_edge_p (bb->loop_father, e) + || (e2->flags & EDGE_IRREDUCIBLE_LOOP) + || (e2->dest->flags & BB_IRREDUCIBLE_LOOP)) loops_state_set (LOOPS_NEED_FIXUP); remove_edge (e2); } Marek