http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60175
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
--- gcc/function.c.jj 2014-01-06 22:32:17.000000000 +0100
+++ gcc/function.c 2014-02-14 19:05:27.233008179 +0100
@@ -5156,17 +5156,20 @@ expand_function_end (void)
crtl->return_rtx = outgoing;
}
- /* Emit the actual code to clobber return register. */
- {
- rtx seq;
+ /* Emit the actual code to clobber return register. Don't emit
+ it if clobber_after is a barrier, then the previous basic block
+ certainly doesn't fall thru into the exit block. */
+ if (!BARRIER_P (clobber_after))
+ {
+ rtx seq;
- start_sequence ();
- clobber_return_register ();
- seq = get_insns ();
- end_sequence ();
+ start_sequence ();
+ clobber_return_register ();
+ seq = get_insns ();
+ end_sequence ();
- emit_insn_after (seq, clobber_after);
- }
+ emit_insn_after (seq, clobber_after);
+ }
/* Output the label for the naked return from the function. */
if (naked_return_label)
fixes this for the common case of not falling through into the exit block, if
clobber_after is BARRIER, the clobbers will surely be never reachable and
immediately removed anyway.
Now, even with this patch we generate incorrect frequencies say for -O2
-fsanitize=address on:
int
foo (int i)
{
if (i)
return 4;
int j;
bar (&j);
}
I think in that case we either need to stick the clobber stmts before the
return_label into the predecessor basic block, or create a new basic block to
hold just the clobbers and derive the frequency of the block containing the
clobbers from the frequency of the previous basic block.