combine_pending_stack_adjustment_and_call checkin

Jan Hubicka hubicka@atrey.karlin.mff.cuni.cz
Fri Apr 28 04:48:00 GMT 2000


Hi
I am just trying to understand the code in your checkin (I was unable
to find an note in egcs-patches, so I am not exactly sure what are you
shooting for), and it seems to me, that you are just hidding the
existing bug in stack alignment code and making is harder to trigger.

Basically what happends is:
compute_args_size is called
stack gets missalligned in precompute_arguments
and then we hit:

#ifdef PREFERRED_STACK_BOUNDARY
      /* If we push args individually in reverse order, perform stack alignment
	 before the first push (the last arg).  */
      if (PUSH_ARGS_REVERSED && argblock == 0
	  && args_size.constant != unadjusted_args_size)
	{
	  /* When the stack adjustment is pending, we get better code
	     by combining the adjustments.  */
	  if (pending_stack_adjust 
	      && ! (flags & (ECF_CONST | ECF_PURE))
	      && ! inhibit_defer_pop)
	    combine_pending_stack_adjustment_and_call 
	      (unadjusted_args_size,
	       &args_size,
	       preferred_unit_stack_boundary);
	  else if (argblock == 0)
	    anti_adjust_stack (GEN_INT (args_size.constant
					- unadjusted_args_size));
	}
      /* Now that the stack is properly aligned, pops can't safely
	 be deferred during the evaluation of the arguments.  */
      NO_DEFER_POP;
#endif

The combine_pending_stack_adjustment_and_call seems to handle missalignmed case
correctly unlike my original code expecting the stack_pointer_delta +
args_size.constant to be already propertly alligned. (perhaps my original code
is having some bug I am not aware of, just tell me, if I am wrong)

The problem is, that the stack alignment may be changed even when this
code is not executed at all, because of the condition:

args_size.constant != unadjusted_args_size

that decides that adjustment is not necesary - it is quite tricky to construct
testcase here, but here it is:

struct c { int a, b, c; };
struct c missalign_me (int *);
void I_dont_need_alignment (int a, int b, int c, int d);
main ()
{
  I_dont_need_alignment (missalign_me (alloca (10)).a, 1, 2, 3);
}

Note that you need the patch from my last email to even get to the failure
I am taking about and I've verified that my patch
http://egcs.cygnus.com/ml/gcc-patches/1999-10/msg00797.html fixes the problem.

So perhaps we can undo your patch and try this one instead.
I've also verified that the patch apply cleanly to current calls.c and
fixes the problem, so we can make them both live together.

Honza


More information about the Gcc-bugs mailing list