diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f4b73ff0ed1b3bf581e0bc82d32d212f07830ee4..ff8c89471392fc57f36d2a9be3efdbb949f9ec2f 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 fce489da0d0250b36c2023f1f543abc0ac94ded6..c36799f4381fee3db594815cb6c1d61ec368ed1c 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 0000000000000000000000000000000000000000..76d3cee1b016fd2fbd43c9bd6d92000eba3e35ce
--- /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;
+}