diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e73daffb5723afc3a408fa16d916dbb909388001..0f56c9c831f599c5e210fefee8b664464ed031ab 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2003-10-03  Jeff Sturm  <jsturm@one-point.com>
+	    Roger Sayle  <roger@eyesopen.com>
+
+	PR optimization/12289
+	* calls.c (emit_call_1): Pretend to have popped the arguments
+	to noreturn and longjmp functions instead of ignoring them.
+	(expand_call): Don't adjust stack_pointer_dela while
+	inhibit_defer_pop is set.
+
 2003-10-03  Andreas Schwab  <schwab@suse.de>
 
 	PR bootstrap/12276
diff --git a/gcc/calls.c b/gcc/calls.c
index fa4f93473c53061f80fe602352e6939c3da679bb..8a3af33570e752c61eeaa8be29ef40384c5338f9 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -530,10 +530,6 @@ emit_call_1 (rtx funexp, tree fndecl ATTRIBUTE_UNUSED, tree funtype ATTRIBUTE_UN
      if the context of the call as a whole permits.  */
   inhibit_defer_pop = old_inhibit_defer_pop;
 
-  /* Don't bother cleaning up after a noreturn function.  */
-  if (ecf_flags & (ECF_NORETURN | ECF_LONGJMP))
-    return;
-
   if (n_popped > 0)
     {
       if (!already_popped)
@@ -557,7 +553,7 @@ emit_call_1 (rtx funexp, tree fndecl ATTRIBUTE_UNUSED, tree funtype ATTRIBUTE_UN
 
       if (rounded_stack_size != 0)
 	{
-	  if (ecf_flags & ECF_SP_DEPRESSED)
+	  if (ecf_flags & (ECF_SP_DEPRESSED | ECF_NORETURN | ECF_LONGJMP))
 	    /* Just pretend we did the pop.  */
 	    stack_pointer_delta -= rounded_stack_size;
 	  else if (flag_defer_pop && inhibit_defer_pop == 0
@@ -3171,9 +3167,14 @@ expand_call (tree exp, rtx target, int ignore)
 
 	  emit_barrier_after (last);
 
-	  /* Stack adjustments after a noreturn call are dead code.  */
-	  stack_pointer_delta = old_stack_allocated;
-	  pending_stack_adjust = 0;
+	  /* Stack adjustments after a noreturn call are dead code.
+	     However when NO_DEFER_POP is in effect, we must preserve
+	     stack_pointer_delta.  */
+	  if (inhibit_defer_pop == 0)
+	    {
+	      stack_pointer_delta = old_stack_allocated;
+	      pending_stack_adjust = 0;
+	    }
 	}
 
       if (flags & ECF_LONGJMP)