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.