re PR middle-end/27802 (ICE with longjmp)
authorRoger Sayle <roger@eyesopen.com>
Fri, 16 Jun 2006 13:21:45 +0000 (13:21 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Fri, 16 Jun 2006 13:21:45 +0000 (13:21 +0000)
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.

From-SVN: r114721

gcc/ChangeLog
gcc/reg-stack.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr27802-1.c [new file with mode: 0644]

index 96ca8930f88a020724da0d301d22c915bd22f1e3..17355cefd1ab6da2fcc2c058e2cf784afdf79016 100644 (file)
@@ -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>
 
index 83f4ebb081ea0477f119c27cd4855b8bda476e78..fc742bdce6080d876d02ac36fdf638372cfc0d88 100644 (file)
@@ -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,
index 313a39f158581c1adf82ddf6397a67cedcfb1d55..31c1fad9a38e2f372770e41eca376a21ec2bb293 100644 (file)
@@ -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 (file)
index 0000000..839459a
--- /dev/null
@@ -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(); }
+