diff options
Diffstat (limited to 'gcc/cfgrtl.c')
-rw-r--r-- | gcc/cfgrtl.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 16e2eb30a6a..4b1d8350de5 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1875,7 +1875,8 @@ rtl_verify_flow_info_1 (void) | EDGE_CAN_FALLTHRU | EDGE_IRREDUCIBLE_LOOP | EDGE_LOOP_EXIT - | EDGE_CROSSING)) == 0) + | EDGE_CROSSING + | EDGE_PRESERVE)) == 0) n_branch++; if (e->flags & EDGE_ABNORMAL_CALL) @@ -2735,6 +2736,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 |