Index: cse.c =================================================================== --- cse.c (revision 119856) +++ cse.c (working copy) @@ -4863,13 +4863,6 @@ cse_insn (rtx insn, rtx libcall_insn) validate_change (insn, &SET_SRC (sets[i].rtl), new, 1); apply_change_group (); - /* With non-call exceptions, if this was an insn that could - trap, we may have made it non-throwing now. For example - we may have replaced a load with a register. */ - if (flag_non_call_exceptions - && insn == BB_END (BLOCK_FOR_INSN (insn))) - purge_dead_edges (BLOCK_FOR_INSN (insn)); - break; } @@ -5959,6 +5952,24 @@ cse_dump_path (struct cse_basic_block_da } +/* Return true if BB has exception handling successor edges. */ + +static bool +have_EH_succ_edges (basic_block bb) +{ + switch (EDGE_COUNT (bb->succs)) + { + case 0: + return false; + case 1: + return single_succ_edge (bb)->flags & EDGE_EH; + default: + return (EDGE_SUCC (bb, 0)->flags & EDGE_EH + || EDGE_SUCC (bb, 1)->flags & EDGE_EH); + } +} + + /* Scan to the end of the path described by DATA. Return an estimate of the total number of SETs, and the lowest and highest insn CUID, of all insns in the path. */ @@ -6109,6 +6120,13 @@ cse_extended_basic_block (struct cse_bas prev_insn = 0; #endif + /* With non-call exceptions, we are not always able to update + the CFG properly inside cse_insn. So clean up possibly + redundant EH edges here. */ + we may have replaced a load with a register. */ + if (flag_non_call_exceptions && have_EH_succ_edges (bb)) + purge_dead_edges (bb); + /* If we changed a conditional jump, we may have terminated the path we are following. Check that by verifying that the edge we would take still exists. If the edge does