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.

Reply via email to