On Fri, Mar 27, 2026 at 1:25 PM Uros Bizjak <[email protected]> wrote:
>
> On Fri, Mar 27, 2026 at 12:14 PM Richard Biener <[email protected]> wrote:
> >
> > The following fixes a confusion seen in the x86 backend by
> > assign_parm_adjust_stack_rtl failing to trigger a local stack copy
> > for an incoming stack parameter that is not aligned according to
> > its type.  The condition was introduced in r0-64961-gbfc45551d5ace4
> > but there is the MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY
> > condition not triggering for the case in question where both
> > MEM_ALIGN and PREFERRED_STACK_BOUNDARY are 128.  x86 supports
> > stack-realignment so we can honor the declared alignment and this
> > clears up the confusion.  The following replaces the bound
> > by MAX_SUPPORTED_STACK_ALIGNMENT if SUPPORTS_STACK_ALIGNMENT
> > and the parameter has it's address taken and with BIGGEST_ALIGNMENT
> > if SUPPORTS_STACK_ALIGNMENT otherwise, only affecting x86 and nvptx
> > at this point.
> >
> > In addition to this it changes the i386 backends computation of
> > the maximum stack alignment used to bound itself to BIGGEST_ALIGNMENT
> > because the middle-end does not (and in general cannot) enforce actual
> > alignment of all stack objects according to their type.
> >
> > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> >
> > Compared to v2 this uses BIGGEST_ALIGNMENT if the parameter does not
> > have its address taken and caps ix86_update_stack_alignment on
> > BIGGEST_ALIGNMENT as well.
>
> I don't think capping ix86_update_stack_alignment to BIGGEST_ALIGNMENT
> is correct. For TARGET_IAMCU, biggest alignment is 32, but it still
> can use FXSAVE that wants 16-byte (128-bit) alignment.
> set_fast_math_sse in libgcc/config/i386/crtfastmath.c uses:
>
>       /* Check if DAZ is available.  */
>       struct
>       {
>     unsigned short cwd;
>     unsigned short swd;
>     unsigned short twd;
>     unsigned short fop;
>     unsigned int fip;
>     unsigned int fcs;
>     unsigned int foo;
>     unsigned int fos;
>     unsigned int mxcsr;
>     unsigned int mxcsr_mask;
>     unsigned int st_space[32];
>     unsigned int xmm_space[32];
>     unsigned int padding[56];
>       } __attribute__ ((aligned (16))) fxsave;
>
> which will probably fail with your x86 change due to unsatisfied
> alignment requirements.

This testcase illustrates above:

--cut here--
void foo (void)
{
  struct
  {
    unsigned short cwd;
    unsigned short swd;
    unsigned short twd;
    unsigned short fop;
    unsigned int fip;
    unsigned int fcs;
    unsigned int foo;
    unsigned int fos;
    unsigned int mxcsr;
    unsigned int mxcsr_mask;
    unsigned int st_space[32];
    unsigned int xmm_space[32];
    unsigned int padding[56];
  } __attribute__ ((aligned (16))) fxsave;

  __builtin_ia32_fxsave(&fxsave);
}
--cut here--

gcc -O2  -miamcu -m32 -mfxsr:

foo:
       pushl   %ebp
       movl    %esp, %ebp
       andl    $-16, %esp
       subl    $512, %esp
       fxsave  (%esp)
       leave
       ret

The compiler realigns the stack without problems, even if
BIGGEST_ALIGNMENT for TARGET_IAMCU is 32 bits.

Uros.

Reply via email to