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.