https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82386
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So one option is to defer the splitting after we've processed the whole this_basic_block, like: --- combine.c.jj 2017-09-15 17:53:28.000000000 +0200 +++ combine.c 2017-10-02 15:43:53.102116326 +0200 @@ -1498,6 +1498,36 @@ combine_instructions (rtx_insn *f, unsig retry: ; } + if ((new_direct_jump_p & 2) != 0) + { + /* Some conditional traps were turned into unconditional ones. + Split basic block after them. */ + new_direct_jump_p = 1; + for (insn = BB_HEAD (this_basic_block); + insn != NEXT_INSN (BB_END (this_basic_block)); + insn = next) + { + next = NEXT_INSN (insn); + if (NONDEBUG_INSN_P (insn) + && GET_CODE (PATTERN (insn)) == TRAP_IF + && XEXP (PATTERN (insn), 0) == const1_rtx) + { + if (insn == BB_END (this_basic_block) + && EDGE_COUNT (this_basic_block->succs) == 0) + { + emit_barrier_after_bb (this_basic_block); + break; + } + basic_block bb = BLOCK_FOR_INSN (insn); + gcc_assert (bb == this_basic_block); + edge e = split_block (bb, insn); + this_basic_block = e->dest; + remove_edge (e); + emit_barrier_after_bb (bb); + next = BB_HEAD (this_basic_block); + } + } + } } default_rtl_profile (); @@ -4659,7 +4689,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, has been created. Adjust the CFG accordingly. */ if (returnjump_p (i3) || any_uncondjump_p (i3)) { - *new_direct_jump_p = 1; + *new_direct_jump_p |= 1; mark_jump_label (PATTERN (i3), i3, 0); update_cfg_for_uncondjump (i3); } @@ -4668,7 +4698,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, && (returnjump_p (undobuf.other_insn) || any_uncondjump_p (undobuf.other_insn))) { - *new_direct_jump_p = 1; + *new_direct_jump_p |= 1; update_cfg_for_uncondjump (undobuf.other_insn); } @@ -4676,10 +4706,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, && XEXP (PATTERN (i3), 0) == const1_rtx) { basic_block bb = BLOCK_FOR_INSN (i3); - gcc_assert (bb); - remove_edge (split_block (bb, i3)); - emit_barrier_after_bb (bb); - *new_direct_jump_p = 1; + gcc_assert (bb && this_basic_block == bb); + *new_direct_jump_p |= 2; } if (undobuf.other_insn @@ -4687,10 +4715,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, && XEXP (PATTERN (undobuf.other_insn), 0) == const1_rtx) { basic_block bb = BLOCK_FOR_INSN (undobuf.other_insn); - gcc_assert (bb); - remove_edge (split_block (bb, undobuf.other_insn)); - emit_barrier_after_bb (bb); - *new_direct_jump_p = 1; + gcc_assert (bb && this_basic_block == bb); + *new_direct_jump_p |= 2; } /* A noop might also need cleaning up of CFG, if it comes from the @@ -4700,7 +4726,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, && SET_SRC (newpat) == pc_rtx && SET_DEST (newpat) == pc_rtx) { - *new_direct_jump_p = 1; + *new_direct_jump_p |= 1; update_cfg_for_uncondjump (i3); } @@ -4710,7 +4736,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, && SET_SRC (PATTERN (undobuf.other_insn)) == pc_rtx && SET_DEST (PATTERN (undobuf.other_insn)) == pc_rtx) { - *new_direct_jump_p = 1; + *new_direct_jump_p |= 1; update_cfg_for_uncondjump (undobuf.other_insn); } Another option I'm going to try next is ignore any try_combine in basic blocks without predecessors, those are necessarily dead and going to be purged afterwards, so I fail to see why we should be wasting time to combine anything in there.