summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2006-06-16 13:21:45 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2006-06-16 13:21:45 +0000
commit50e6dbf3d29376a62eb0a58068f8e794fb38d24b (patch)
treea40f1b62f264bb2144d100e2c702367189d4d55f
parente5e80d40d79599acccc7da72bf71ffacd7ac082b (diff)
downloadgcc-50e6dbf3d29376a62eb0a58068f8e794fb38d24b.tar.gz
PR middle-end/27802
* reg-stack.c (subst_stack_regs): Handle noreturn function calls that (would) return their results in stack registers. * gcc.dg/pr27802-1.c: New test case. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114721 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/reg-stack.c10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr27802-1.c16
4 files changed, 37 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 96ca8930f88..17355cefd1a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-06-16 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/27802
+ * reg-stack.c (subst_stack_regs): Handle noreturn function calls
+ that (would) return their results in stack registers.
+
2006-06-16 Michael Matz <matz@suse.de>
Richard Guenther <rguenther@suse.de>
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 83f4ebb081e..fc742bdce60 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -2282,6 +2282,16 @@ subst_stack_regs (rtx insn, stack regstack)
if (NOTE_P (insn) || INSN_DELETED_P (insn))
return control_flow_insn_deleted;
+ /* If this a noreturn call, we can't insert pop insns after it.
+ Instead, reset the stack state to empty. */
+ if (CALL_P (insn)
+ && find_reg_note (insn, REG_NORETURN, NULL))
+ {
+ regstack->top = -1;
+ CLEAR_HARD_REG_SET (regstack->reg_set);
+ return control_flow_insn_deleted;
+ }
+
/* If there is a REG_UNUSED note on a stack register on this insn,
the indicated reg must be popped. The REG_UNUSED note is removed,
since the form of the newly emitted pop insn references the reg,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 313a39f1585..31c1fad9a38 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-06-16 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/27802
+ * gcc.dg/pr27802-1.c: New test case.
+
2006-06-15 Mark Mitchell <mark@codesourcery.com>
PR c++/27689
diff --git a/gcc/testsuite/gcc.dg/pr27802-1.c b/gcc/testsuite/gcc.dg/pr27802-1.c
new file mode 100644
index 00000000000..839459ac01a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr27802-1.c
@@ -0,0 +1,16 @@
+/* Noreturn functions returning FP types used to confuse reg-stack on x86. */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+double bar1() __attribute__((noreturn));
+void foo1() { bar1(); }
+
+double bar2() __attribute__((noreturn));
+double foo2() { return bar2(); }
+
+void bar3() __attribute__((noreturn));
+double foo3() { bar3(); }
+
+double bar4() __attribute__((noreturn));
+double foo4() { bar4(); }
+