aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2011-03-31 11:10:59 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2011-03-31 11:10:59 +0000
commitace31bca4a35b5da87957a80aecfffada0094818 (patch)
treef6502bc5afdf187f5c4a72916b0580756aa22456 /gcc
parent178aa0f6487a8b296c30e7c81bcb59ef6ddccc81 (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c34
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/other/i386-9.C12
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;
+}