diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 13de48b05529..2e225e752c11 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-11-15 Bernd Schmidt + + PR rtl-optimization/51051 + * cfgrtl.c (cfg_layout_can_merge_blocks_p): Return FALSE if the + move would cause fallthrough into the exit block. + 2011-11-14 Richard Henderson * config/rs6000/rs6000.c (emit_load_locked): Assert the mode is handled. diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 16e2eb30a6a7..aeb4ba184e16 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -2735,6 +2735,16 @@ cfg_layout_can_merge_blocks_p (basic_block a, basic_block b) if (BB_PARTITION (a) != BB_PARTITION (b)) return false; + /* If we would end up moving B's instructions, make sure it doesn't fall + through into the exit block, since we cannot recover from a fallthrough + edge into the exit block occurring in the middle of a function. */ + if (NEXT_INSN (BB_END (a)) != BB_HEAD (b)) + { + edge e = find_fallthru_edge (b->succs); + if (e && e->dest == EXIT_BLOCK_PTR) + return false; + } + /* There must be exactly one edge in between the blocks. */ return (single_succ_p (a) && single_succ (a) == b