aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgexpand.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-03-03 08:25:50 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2014-03-03 08:25:50 +0100
commit79c7fda6d56eea84a95df8ea67387b4cf972e9de (patch)
treed6a8ebe478c2d5333110bafe9cc7ce6fe4dcbb45 /gcc/cfgexpand.c
parent715a5c85f7db0146b2df19452958e26d15d6eab8 (diff)
downloadgcc-79c7fda6d56eea84a95df8ea67387b4cf972e9de.zip
gcc-79c7fda6d56eea84a95df8ea67387b4cf972e9de.tar.gz
gcc-79c7fda6d56eea84a95df8ea67387b4cf972e9de.tar.bz2
re PR middle-end/60175 (ICE on gcc.dg/asan/nosanitize-and-inline.c)
PR middle-end/60175 * function.c (expand_function_end): Don't emit clobber_return_register sequence if clobber_after is a BARRIER. * cfgexpand.c (construct_exit_block): Append instructions before return_label to prev_bb. From-SVN: r208267
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r--gcc/cfgexpand.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 06d494c..5c23b72 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -5273,7 +5273,8 @@ construct_exit_block (void)
edge e, e2;
unsigned ix;
edge_iterator ei;
- rtx orig_end = BB_END (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
+ basic_block prev_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
+ rtx orig_end = BB_END (prev_bb);
rtl_profile_for_bb (EXIT_BLOCK_PTR_FOR_FN (cfun));
@@ -5288,13 +5289,25 @@ construct_exit_block (void)
end = get_last_insn ();
if (head == end)
return;
- /* While emitting the function end we could move end of the last basic block.
- */
- BB_END (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb) = orig_end;
+ /* While emitting the function end we could move end of the last basic
+ block. */
+ BB_END (prev_bb) = orig_end;
while (NEXT_INSN (head) && NOTE_P (NEXT_INSN (head)))
head = NEXT_INSN (head);
- exit_block = create_basic_block (NEXT_INSN (head), end,
- EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
+ /* But make sure exit_block starts with RETURN_LABEL, otherwise the
+ bb frequency counting will be confused. Any instructions before that
+ label are emitted for the case where PREV_BB falls through into the
+ exit block, so append those instructions to prev_bb in that case. */
+ if (NEXT_INSN (head) != return_label)
+ {
+ while (NEXT_INSN (head) != return_label)
+ {
+ if (!NOTE_P (NEXT_INSN (head)))
+ BB_END (prev_bb) = NEXT_INSN (head);
+ head = NEXT_INSN (head);
+ }
+ }
+ exit_block = create_basic_block (NEXT_INSN (head), end, prev_bb);
exit_block->frequency = EXIT_BLOCK_PTR_FOR_FN (cfun)->frequency;
exit_block->count = EXIT_BLOCK_PTR_FOR_FN (cfun)->count;
if (current_loops && EXIT_BLOCK_PTR_FOR_FN (cfun)->loop_father)