This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[x86] Fix PR target/48142
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 31 Mar 2011 01:03:53 +0200
- Subject: [x86] Fix PR target/48142
Hi,
this is a regression present for x86-64 on mainline and 4.6 branch with the
options -Os -mpreferred-stack-boundary=5 -fstack-check -fno-omit-frame-pointer.
This improbable combination of options is necessary because you need to have
stack checking + stack realignment + !ACCUMULATE_OUTGOING_ARGS. In this case,
the DW_CFA_GNU_args_size CFIs must be correct in spite of the frame pointer.
Tested on {i586,x86_64}-suse-linux, OK for mainline and 4.6 branch?
2011-03-30 Eric Botcazou <ebotcazou@adacore.com>
PR target/48142
* config/i386/i386.c (ix86_adjust_stack_and_probe): Differentiate
frame-related from frame-unrelated adjustments to the stack pointer.
2011-03-30 Eric Botcazou <ebotcazou@adacore.com>
* g++.dg/other/pr48142.C: New test.
--
Eric Botcazou
// PR target/48142
// Testcase by Zdenek Sojka <zsojka@seznam.cz>
// { dg-do run { target i?86-*-* x86_64-*-* } }
// { dg-options "-Os -mpreferred-stack-boundary=5 -fstack-check -fno-omit-frame-pointer" }
int main()
{
try { throw 0; }
catch (...) {}
return 0;
}
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c (revision 171716)
+++ config/i386/i386.c (working copy)
@@ -10006,7 +10006,7 @@ ix86_adjust_stack_and_probe (const HOST_
probe that many bytes past the specified size to maintain a protection
area at the botton of the stack. */
const int dope = 4 * UNITS_PER_WORD;
- rtx size_rtx = GEN_INT (size);
+ rtx size_rtx = GEN_INT (size), last;
/* See if we have a constant small number of probes to generate. If so,
that's the easy case. The run-time loop is made up of 11 insns in the
@@ -10046,9 +10046,9 @@ ix86_adjust_stack_and_probe (const HOST_
emit_stack_probe (stack_pointer_rtx);
/* Adjust back to account for the additional first interval. */
- emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (stack_pointer_rtx,
- PROBE_INTERVAL + dope)));
+ last = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx,
+ PROBE_INTERVAL + dope)));
}
/* Otherwise, do the same as above, but in a loop. Note that we must be
@@ -10109,15 +10109,33 @@ ix86_adjust_stack_and_probe (const HOST_
}
/* Adjust back to account for the additional first interval. */
- emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- plus_constant (stack_pointer_rtx,
- PROBE_INTERVAL + dope)));
+ last = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx,
+ PROBE_INTERVAL + dope)));
release_scratch_register_on_entry (&sr);
}
gcc_assert (cfun->machine->fs.cfa_reg != stack_pointer_rtx);
- cfun->machine->fs.sp_offset += size;
+
+ /* Even if the stack pointer isn't the CFA register, we need to correctly
+ describe the adjustments made to it, in particular differentiate the
+ frame-related ones from the frame-unrelated ones. */
+ if (size > 0)
+ {
+ rtx expr = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (2));
+ XVECEXP (expr, 0, 0)
+ = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx, -size));
+ XVECEXP (expr, 0, 1)
+ = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx,
+ PROBE_INTERVAL + dope + size));
+ add_reg_note (last, REG_FRAME_RELATED_EXPR, expr);
+ RTX_FRAME_RELATED_P (last) = 1;
+
+ cfun->machine->fs.sp_offset += size;
+ }
/* Make sure nothing is scheduled before we are done. */
emit_insn (gen_blockage ());