http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57067
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- The RTL except.c:can_nonlocal_goto () function does not consider setjmp. Does Index: gcc/except.c =================================================================== --- gcc/except.c (revision 198867) +++ gcc/except.c (working copy) @@ -1936,7 +1936,9 @@ insn_nothrow_p (const_rtx insn) bool can_nonlocal_goto (const_rtx insn) { - if (nonlocal_goto_handler_labels && CALL_P (insn)) + if ((nonlocal_goto_handler_labels + || cfun->calls_stjmp) + && CALL_P (insn)) { rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); if (!note || INTVAL (XEXP (note, 0)) != INT_MIN) fix it? For retaining edges we have to teach find_many_sub_basic_blocks to treat abnormal outgoing edges similar to EH outgoing edges - they have to be re-directed from the block ending in the actual call (and made EDGE_ABNORMAL_CALL which doesn't exist on the GIMPLE CFG). Also if ((e->flags & EDGE_ABNORMAL) && !(e->flags & EDGE_SIBCALL)) remove_edge (e); will happily remove an EDGE_FALLTHRU|EDGE_ABNORMAL edge.