[RFC] PR12289: expand_call patch

Jeff Sturm jsturm@one-point.com
Wed Sep 24 18:12:00 GMT 2003


PR12289 includes a Java test case roughly equivalent to:

void f(void *p) {
  extern void g(int), h(void *);
  g(0);
  h(p == 0 ? exit(1) : p);
}

The test case causes an ICE in expand_call on x86 targets.  Since the
trees produced by the Java FE look fine to me, I'm guessing the ICE is
caused by a latent bug in the backend.

After studying expand_call for a bit I've judged that stack_pointer_delta
and pending_stack_adjust must be invariant across calls to
rtx_for_function_call.  But the argument to h() includes a noreturn
function, which clears pending_stack_adjust unconditionally.  The trouble
starts when there are pending adjustments prior to calling h(), so that
expand_call aborts when the stack is misaligned.

I'm testing the following.  I'm undecided if this is more or less correct
than simply doing a save/restore of stack_pointer_delta/pending_stack_adjust
within rtx_for_function_call.  Alternatively, this optimization
could be dropped from expand_call if DCE strips the dead stack adjustment
anyway.  I'm open to suggestions from anyone who is more familiar
with this code than I am.

Jeff

2003-09-24  Jeff Sturm  <jsturm@one-point.com>

	* calls.c (expand_call): Don't adjust stack_pointer_delta while
	inhibit_defer_pop is set.

Index: calls.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/calls.c,v
retrieving revision 1.300
diff -u -p -r1.300 calls.c
--- calls.c	18 Sep 2003 20:43:04 -0000	1.300
+++ calls.c	24 Sep 2003 13:00:00 -0000
@@ -3173,9 +3178,16 @@ expand_call (tree exp, rtx target, int i

 	  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;
+	    }
+	  else
+	    stack_pointer_delta = old_stack_allocated + pending_stack_adjust;
 	}

       if (flags & ECF_LONGJMP)



More information about the Gcc-patches mailing list