This fixes VRP to properly fixup loops when it removes edges from the CFG.
Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2013-03-25 Richard Biener <rguent...@suse.de> PR tree-optimization/56689 * tree-vrp.c (execute_vrp): Mark loops for fixup if we removed any edge. * gcc.dg/torture/pr56689.c: New testcase. Index: gcc/tree-vrp.c =================================================================== --- gcc/tree-vrp.c (revision 197029) +++ gcc/tree-vrp.c (working copy) @@ -9329,7 +9329,11 @@ execute_vrp (void) } if (to_remove_edges.length () > 0) - free_dominance_info (CDI_DOMINATORS); + { + free_dominance_info (CDI_DOMINATORS); + if (current_loops) + loops_state_set (LOOPS_NEED_FIXUP); + } to_remove_edges.release (); to_update_switch_stmts.release (); Index: gcc/testsuite/gcc.dg/torture/pr56689.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr56689.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr56689.c (working copy) @@ -0,0 +1,46 @@ +/* { dg-do compile } */ + +extern int baz (); +extern void bar (void); +extern void noret (void) __attribute__ ((__noreturn__)); + +void +fix_register (const char *name, int fixed, int call_used, int nregs) +{ + int i; + int reg; + + if ((reg = baz ()) >= 0) + { + for (i = reg; i < nregs; i++) + { + if ((i == 15 || i == 11) && (fixed == 0 || call_used == 0)) + { + switch (fixed) + { + case 0: + switch (call_used) + { + case 1: + bar (); + break; + default: + (noret ()); + } + case 1: + switch (call_used) + { + case 1: + break; + case 0: + default: + (noret ()); + } + break; + default: + (noret ()); + } + } + } + } +}