diff mbox

Attempt to prevent cross-jumping of noreturn calls with different args sizes (PR debug/51762)

Message ID 20120105151738.GK18937@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Jan. 5, 2012, 3:17 p.m. UTC
Hi!

The attached testcase on i?86 (32-bit) ICEs, because the csa pass
cross-jumps the two noret calls, eventhough they have different args size
depths.

The following patch attempts to fix that up by forcibly adding REG_ARGS_SIZE
notes to all noreturn calls when not accumulating outgoing args, which works
for this and passed bootstrap/regtest on x86_64-linux and i686-linux.
Ok?

2012-01-05  Jakub Jelinek  <jakub@redhat.com>

	PR debug/51762
	* calls.c (emit_call_1): For noreturn calls force a REG_ARGS_SIZE
	note when !ACCUMULATE_OUTGOING_ARGS.

	* gcc.dg/pr51762.c: New test.


	Jakub

Comments

Richard Henderson Jan. 5, 2012, 8:34 p.m. UTC | #1
On 01/06/2012 02:17 AM, Jakub Jelinek wrote:
> 	PR debug/51762
> 	* calls.c (emit_call_1): For noreturn calls force a REG_ARGS_SIZE
> 	note when !ACCUMULATE_OUTGOING_ARGS.
> 
> 	* gcc.dg/pr51762.c: New test.

Ok.


r~
diff mbox

Patch

--- gcc/calls.c.jj	2011-12-21 19:24:55.000000000 +0100
+++ gcc/calls.c	2012-01-05 13:56:02.415231434 +0100
@@ -445,6 +445,11 @@  emit_call_1 (rtx funexp, tree fntree ATT
       if (SUPPORTS_STACK_ALIGNMENT)
         crtl->need_drap = true;
     }
+  /* For noreturn calls when not accumulating outgoing args force
+     REG_ARGS_SIZE note to prevent crossjumping of calls with different
+     args sizes.  */
+  else if (!ACCUMULATE_OUTGOING_ARGS && (ecf_flags & ECF_NORETURN) != 0)
+    add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
 
   if (!ACCUMULATE_OUTGOING_ARGS)
     {
--- gcc/testsuite/gcc.dg/pr51762.c.jj	2012-01-05 13:52:53.188328851 +0100
+++ gcc/testsuite/gcc.dg/pr51762.c	2012-01-05 13:28:50.000000000 +0100
@@ -0,0 +1,19 @@ 
+/* PR debug/51762 */
+/* { dg-do compile } */
+/* { dg-options "-g -Os -fomit-frame-pointer -fno-asynchronous-unwind-tables" } */
+
+void noret (void) __attribute__ ((noreturn));
+int bar (void);
+void baz (const char *);
+static int v = -1;
+
+void
+foo (void)
+{
+  if (bar () && v == -1)
+    {
+      baz ("baz");
+      noret ();
+    }
+  noret ();
+}