The following fixes PR65517 - we need to mark loops for fixup if we remove a path inside a loop.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2015-03-23 Richard Biener <rguent...@suse.de> PR middle-end/65517 * tree-cfg.c (remove_edge_and_dominated_blocks): Mark loops for fixup if necessary. * gcc.dg/torture/pr65517.c: New testcase. Index: gcc/testsuite/gcc.dg/torture/pr65517.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr65517.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr65517.c (working copy) @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +typedef void (*argmatch_exit_fn)(); +int a; +void __argmatch_die () { __builtin_exit (0); } + +int +main () +{ + while (1) + { + argmatch_exit_fn b = __argmatch_die; + if (a) + b (); + } + return 0; +} Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c (revision 221591) +++ gcc/tree-cfg.c (working copy) @@ -7824,6 +7824,13 @@ remove_edge_and_dominated_blocks (edge e basic_block bb, dbb; bitmap_iterator bi; + /* If we are removing a path inside a non-root loop that may change + loop ownership of blocks or remove loops. Mark loops for fixup. */ + if (current_loops + && loop_outer (e->src->loop_father) != NULL + && e->src->loop_father == e->dest->loop_father) + loops_state_set (LOOPS_NEED_FIXUP); + if (!dom_info_available_p (CDI_DOMINATORS)) { remove_edge (e);