From patchwork Thu Jan 5 15:17:38 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Attempt to prevent cross-jumping of noreturn calls with different args sizes (PR debug/51762) Date: Thu, 05 Jan 2012 05:17:38 -0000 From: Jakub Jelinek X-Patchwork-Id: 134494 Message-Id: <20120105151738.GK18937@tyan-ft48-01.lab.bos.redhat.com> To: Richard Henderson Cc: gcc-patches@gcc.gnu.org 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 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 --- 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 (); +}