diff options
author | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2011-03-31 11:10:59 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2011-03-31 11:10:59 +0000 |
commit | ace31bca4a35b5da87957a80aecfffada0094818 (patch) | |
tree | f6502bc5afdf187f5c4a72916b0580756aa22456 | |
parent | 178aa0f6487a8b296c30e7c81bcb59ef6ddccc81 (diff) | |
download | gcc-ace31bca4a35b5da87957a80aecfffada0094818.zip gcc-ace31bca4a35b5da87957a80aecfffada0094818.tar.gz gcc-ace31bca4a35b5da87957a80aecfffada0094818.tar.bz2 |
re PR target/48142 (miscompilation with -Os -mpreferred-stack-boundary=5 -fstack-check)
PR target/48142
* config/i386/i386.c (ix86_adjust_stack_and_probe): Differentiate
frame-related from frame-unrelated adjustments to the stack pointer.
From-SVN: r171777
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/i386-9.C | 12 |
4 files changed, 49 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8384f35..714650e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-03-31 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-31 Jakub Jelinek <jakub@redhat.com> * common.opt (fdebug-types-section): Move earlier. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index a985b2b..738dc1c 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -10006,7 +10006,7 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size) 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_WIDE_INT size) 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_WIDE_INT size) } /* 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 ()); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f7436e1..6bb003d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,7 +1,10 @@ +2011-03-31 Eric Botcazou <ebotcazou@adacore.com> + + * g++.dg/other/i386-9.C: New test. + 2011-03-30 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> - * go.test/go-test.exp (go-set-goarch): Use sparc64 for 64-bit - SPARC. + * go.test/go-test.exp (go-set-goarch): Use sparc64 for 64-bit SPARC. 2011-03-30 Jason Merrill <jason@redhat.com> diff --git a/gcc/testsuite/g++.dg/other/i386-9.C b/gcc/testsuite/g++.dg/other/i386-9.C new file mode 100644 index 0000000..7964057 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/i386-9.C @@ -0,0 +1,12 @@ +// 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; +} |