aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-03-28 22:19:36 -0800
committerRichard Henderson <rth@gcc.gnu.org>2002-03-28 22:19:36 -0800
commitf8ed19583966af84157bae20f3fbe422e74ec7c2 (patch)
tree16034cad640b80685e8cdfd819c623f43262295f /gcc
parent54e203858d9abbd383f7ad829bd4d439e2b55180 (diff)
downloadgcc-f8ed19583966af84157bae20f3fbe422e74ec7c2.zip
gcc-f8ed19583966af84157bae20f3fbe422e74ec7c2.tar.gz
gcc-f8ed19583966af84157bae20f3fbe422e74ec7c2.tar.bz2
re PR target/6087 (3.1 i86 FP stack pop bug)
PR target/6087 * reload1.c (fixup_abnormal_edges): Move insn to edge via sequence. From-SVN: r51543
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/reload1.c13
-rw-r--r--gcc/testsuite/g++.dg/opt/reg-stack.C47
3 files changed, 64 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f4b73ff..ff8c894 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2002-03-28 Richard Henderson <rth@redhat.com>
+
+ PR target/6087
+ * reload1.c (fixup_abnormal_edges): Move insn to edge via sequence.
+
2002-03-28 Alexandre Oliva <aoliva@redhat.com>
* config/i386/freebsd.h (LINK_SPEC): Don't pass default
diff --git a/gcc/reload1.c b/gcc/reload1.c
index fce489d..c36799f 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -9517,8 +9517,19 @@ fixup_abnormal_edges ()
next = NEXT_INSN (insn);
if (INSN_P (insn))
{
- insert_insn_on_edge (PATTERN (insn), e);
+ rtx seq;
+
delete_insn (insn);
+
+ /* We're not deleting it, we're moving it. */
+ INSN_DELETED_P (insn) = 0;
+
+ /* Emit a sequence, rather than scarfing the pattern, so
+ that we don't lose REG_NOTES etc. */
+ /* ??? Could copy the test from gen_sequence, but don't
+ think it's worth the bother. */
+ seq = gen_rtx_SEQUENCE (VOIDmode, gen_rtvec (1, insn));
+ insert_insn_on_edge (seq, e);
}
insn = next;
}
diff --git a/gcc/testsuite/g++.dg/opt/reg-stack.C b/gcc/testsuite/g++.dg/opt/reg-stack.C
new file mode 100644
index 0000000..76d3cee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/reg-stack.C
@@ -0,0 +1,47 @@
+// PR target/6087
+// The code that moves around insns emitted by reg-stack to cope with
+// exception edges lost the REG_DEAD note indicating a pop. Which
+// eventually fills up the register stack resulting in Z == NaN.
+
+// { dg-do run }
+// { dg-options "-O" }
+
+extern "C" void abort ();
+
+struct Base
+{
+ virtual ~Base() {}
+};
+
+struct Foo : public Base
+{
+ Foo ();
+};
+
+double x = 3;
+double y = 4;
+
+double bar ()
+{
+ double z = x*x+y*y;
+ if (z != 25.0)
+ throw 1;
+ return z;
+}
+
+Foo::Foo ()
+{
+ bar ();
+}
+
+int main ()
+{
+ try {
+ int i;
+ for (i = 0; i < 10; ++i)
+ new Foo;
+ } catch (...) {
+ abort ();
+ }
+ return 0;
+}