[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