On Mon, Mar 30, 2026 at 6:18 AM Richard Biener <[email protected]> wrote: > > On Mon, 30 Mar 2026, H.J. Lu wrote: > > > On Mon, Mar 30, 2026 at 1:58 AM Richard Biener <[email protected]> wrote: > > > > > > On Sun, 29 Mar 2026, H.J. Lu wrote: > > > > > > > On Sat, Mar 28, 2026 at 5:18 AM H.J. Lu <[email protected]> wrote: > > > > > > > > > > On Sat, Mar 28, 2026 at 1:16 AM Richard Biener <[email protected]> > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > Am 28.03.2026 um 03:36 schrieb H.J. Lu <[email protected]>: > > > > > > > > > > > > > > On Fri, Mar 27, 2026 at 4:14 AM 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. > > > > > > >> > > > > > > >> OK for the x86 parts? I assume the refined function.cc hunk is > > > > > > >> still > > > > > > >> LGTM from Richard S. side. > > > > > > >> > > > > > > >> Note I still fail to see why we need to scan all insns in the > > > > > > >> backend > > > > > > >> again after RTL expansion should have ensured to keep track of > > > > > > >> the > > > > > > >> maximum needed stack alignment. But I'm trying to avoid touching > > > > > > >> code I do not understand as much as possible. > > > > > > >> > > > > > > >> Thanks, > > > > > > >> Richard. > > > > > > >> > > > > > > >> PR middle-end/120839 > > > > > > >> * function.cc (assign_parm_adjust_stack_rtl): Get the > > > > > > >> parameter > > > > > > >> as arugment. Adjust alignment check forcing a local copy > > > > > > >> for > > > > > > >> SUPPORTS_STACK_ALIGNMENT targets if the argument is not > > > > > > >> aligned > > > > > > >> to its type and the current alignment is less than > > > > > > >> MAX_SUPPORTED_STACK_ALIGNMENT if the parameter has its > > > > > > >> address > > > > > > >> taken or BIGGEST_ALIGNMENT otherwise. > > > > > > >> (assign_parms): Adjust. > > > > > > >> * config/i386/i386.cc (ix86_update_stack_alignment): Bound > > > > > > >> recorded stack alignment requirement by BIGGEST_ALIGNMENT. > > > > > > >> > > > > > > >> * gcc.dg/torture/pr120839.c: New testcase. > > > > > > >> * gcc.target/i386/pr120839-avx.c: Likewise. > > > > > > >> --- > > > > > > >> gcc/config/i386/i386.cc | 2 +- > > > > > > >> gcc/function.cc | 14 +++++++++++--- > > > > > > >> gcc/testsuite/gcc.dg/torture/pr120839.c | 7 +++++++ > > > > > > >> gcc/testsuite/gcc.target/i386/pr120839-avx.c | 8 ++++++++ > > > > > > >> 4 files changed, 27 insertions(+), 4 deletions(-) > > > > > > >> create mode 100644 gcc/testsuite/gcc.dg/torture/pr120839.c > > > > > > >> create mode 100644 gcc/testsuite/gcc.target/i386/pr120839-avx.c > > > > > > >> > > > > > > >> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc > > > > > > >> index 15e0dd547a9..f2a49bbaf46 100644 > > > > > > >> --- a/gcc/config/i386/i386.cc > > > > > > >> +++ b/gcc/config/i386/i386.cc > > > > > > >> @@ -8627,7 +8627,7 @@ ix86_update_stack_alignment (rtx, > > > > > > >> const_rtx pat, void *data) > > > > > > >> unsigned int alignment = MEM_ALIGN (op); > > > > > > >> > > > > > > >> if (alignment > *p->stack_alignment) > > > > > > >> - *p->stack_alignment = alignment; > > > > > > >> + *p->stack_alignment = MIN (alignment, > > > > > > >> BIGGEST_ALIGNMENT); > > > > > > > > > > > > > > This is wrong. X86 backend supports MAX_OFILE_ALIGNMENT > > > > > > > stack alignment. > > > > > > > > > > > > > >> break; > > > > > > >> } > > > > > > >> else > > > > > > >> diff --git a/gcc/function.cc b/gcc/function.cc > > > > > > >> index bba05f3380d..41987b4f7a4 100644 > > > > > > >> --- a/gcc/function.cc > > > > > > >> +++ b/gcc/function.cc > > > > > > >> @@ -2825,7 +2825,7 @@ assign_parm_remove_parallels (struct > > > > > > >> assign_parm_data_one *data) > > > > > > >> always valid and properly aligned. */ > > > > > > >> > > > > > > >> static void > > > > > > >> -assign_parm_adjust_stack_rtl (struct assign_parm_data_one *data) > > > > > > >> +assign_parm_adjust_stack_rtl (tree parm, struct > > > > > > >> assign_parm_data_one *data) > > > > > > >> { > > > > > > >> rtx stack_parm = data->stack_parm; > > > > > > >> > > > > > > >> @@ -2840,7 +2840,15 @@ assign_parm_adjust_stack_rtl (struct > > > > > > >> assign_parm_data_one *data) > > > > > > >> MEM_ALIGN > > > > > > >> (stack_parm)))) > > > > > > >> || (data->nominal_type > > > > > > >> && TYPE_ALIGN (data->nominal_type) > MEM_ALIGN > > > > > > >> (stack_parm) > > > > > > >> - && MEM_ALIGN (stack_parm) < > > > > > > >> PREFERRED_STACK_BOUNDARY))) > > > > > > >> + /* When we can re-align the stack ensure > > > > > > >> appropriate alignment > > > > > > >> + of the function local object up to > > > > > > >> BIGGEST_ALIGNMENT if > > > > > > >> + it is only accessed directly or up to the > > > > > > >> maximum supported > > > > > > >> + alignment if the address is exposed. */ > > > > > > >> + && MEM_ALIGN (stack_parm) < > > > > > > >> (SUPPORTS_STACK_ALIGNMENT > > > > > > >> + ? (TREE_ADDRESSABLE > > > > > > >> (parm) > > > > > > >> + ? > > > > > > >> MAX_SUPPORTED_STACK_ALIGNMENT > > > > > > >> + : > > > > > > >> BIGGEST_ALIGNMENT) > > > > > > >> + : > > > > > > >> PREFERRED_STACK_BOUNDARY)))) > > > > > > > > > > > > > > I think it should be > > > > > > > > > > > > > > @@ -2840,7 +2840,11 @@ assign_parm_adjust_stack_rtl (struct > > > > > > > assign_parm_data_one *data) > > > > > > > MEM_ALIGN (stack_parm)))) > > > > > > > || (data->nominal_type > > > > > > > && TYPE_ALIGN (data->nominal_type) > MEM_ALIGN > > > > > > > (stack_parm) > > > > > > > - && MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY))) > > > > > > > + /* The parm stack slot works if its address isn't taken. > > > > > > > When > > > > > > > + making a local copy, MAX_SUPPORTED_STACK_ALIGNMENT is > > > > > > > + its maximum alignment. */ > > > > > > > + && TREE_ADDRESSABLE (parm) > > > > > > > + && MEM_ALIGN (stack_parm) < > > > > > > > MAX_SUPPORTED_STACK_ALIGNMENT))) > > > > > > > stack_parm = NULL; > > > > > > > > > > > > Even when not address taken the ABI guaranteed alignment of the > > > > > > stack slot might be less than the declared alignment. If the > > > > > > alignment itself is not exposed via the address we have still to > > > > > > avoid faulting, thus BIGGEST_ALIGNMENT > > > > > > > > > > There should be no fault. Otherwise, caller will fault first when > > > > > such an argument > > > > > is pushed onto stack. > > > > > > > > > > > > > Here is the combined patch with tests. > > > > > > > > Adjust alignment check forcing a local copy if the argument on stack is > > > > not aligned to its type and the current alignment, which is determined > > > > by the backend, is less than MAX_SUPPORTED_STACK_ALIGNMENT when the > > > > parameter has its address taken. > > > > > > > > For x86, ignore argument passed on stack when updating stack alignment > > > > since caller is responsible to align the outgoing stack for arguments > > > > passed on stack. > > > > > > @@ -2840,7 +2840,12 @@ assign_parm_adjust_stack_rtl (struct > > > assign_parm_data_one *data) > > > MEM_ALIGN (stack_parm)))) > > > || (data->nominal_type > > > && TYPE_ALIGN (data->nominal_type) > MEM_ALIGN (stack_parm) > > > - && MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY))) > > > + /* Use the parm stack slot, whose alignment is determined > > > + by targetm.calls.function_arg_boundary, if its address > > > + isn't taken. When making a local copy, its maximum > > > + alignment is MAX_SUPPORTED_STACK_ALIGNMENT. */ > > > + && TREE_ADDRESSABLE (parm) > > > + && MEM_ALIGN (stack_parm) < MAX_SUPPORTED_STACK_ALIGNMENT))) > > > > > > This changes the !TREE_ADDRESSABLE (parm) behavior which I think we > > > do not want to do at this point. I think we want > > > > > > && (MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY > > > || (TREE_ADDRESSABLE (parm) > > > && MEM_ALIGN (stack_parm) < > > > MAX_SUPPORTED_STACK_ALIGNMENT)) > > > > This will cause unnecessary stack realignment for > > > > typedef struct { > > double a; > > double b; > > double c; > > double d; > > } c __attribute__((aligned(32))); > > extern double d; > > void > > e (float a1, float a2, float a3, float a4, float a5, float a6, c f) > > { > > d = f.a; > > } > > > > It is > > > > pushq %rbp > > movq %rsp, %rbp > > movsd 16(%rbp), %xmm0 > > popq %rbp > > movsd %xmm0, d(%rip) > > ret > > > > vs > > > > pushq %rbp > > movq %rsp, %rbp > > andq $-32, %rsp > > movdqu 16(%rbp), %xmm0 > > movaps %xmm0, -32(%rsp) > > movsd -32(%rsp), %xmm0 > > movsd %xmm0, d(%rip) > > leave > > ret > > > > MEM_ALIGN (stack_parm) is properly aligned according to ISA > > and ABI as set by target. There is no need to realign stack > > if address isn't taken. > > But that's a separate enhancement, not suitable for stage4. It also > depends on the ABI, you may remove required re-alignment for targets > where the ABI isn't as forgiving. It also seems that any such > change should involve BIGGEST_ALIGNMENT as in my patch.
BIGGEST_ALIGNMENT is the biggest alignment for all types, not for each type. > Please submit separately for stage1. Will do that. > Richard. > > > > this doesn't affect targets that cannot re-align the stack due > > > to the way MAX_SUPPORTED_STACK_ALIGNMENT is derived. For > > > unaffected targets the new check is simply redundant > > > (MAX_SUPPORTED_STACK_ALIGNMENT is then equal to PREFERRED_STACK_BOUNDARY). > > > > > > The middle-end part is OK with that change. > > > > > > I'll leave the x86 part to x86 maintainers. > > > > > > Thanks, > > > Richard. > > > > > > > > > > gcc/ > > > > > > > > PR target/120839 > > > > PR middle-end/124671 > > > > * function.cc (assign_parm_adjust_stack_rtl): Get the parameter > > > > as argument. Adjust alignment check forcing a local copy. > > > > (assign_parms): Adjust. > > > > * config/i386/i386.cc (ix86_argument_passed_on_stack_p): New. > > > > (ix86_update_stack_alignment): Ignore argument passed on stack. > > > > > > > > gcc/testsuite/ > > > > > > > > PR target/120839 > > > > PR middle-end/124671 > > > > * gcc.dg/pr124671.c: New test. > > > > * gcc.target/i386/pr120839-1a.c: Likewise. > > > > * gcc.target/i386/pr120839-1b.c: Likewise. > > > > * gcc.target/i386/pr120839-2.c: Likewise. > > > > > > > > Signed-off-by: H.J. Lu <[email protected]> > > > > Co-Authored-By: Richard Biener <[email protected]> > > > > > > > > > > > > > > -- > > > Richard Biener <[email protected]> > > > SUSE Software Solutions Germany GmbH, > > > Frankenstrasse 146, 90461 Nuernberg, Germany; > > > GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG > > > Nuernberg) > > > > > > > > > > -- > Richard Biener <[email protected]> > SUSE Software Solutions Germany GmbH, > Frankenstrasse 146, 90461 Nuernberg, Germany; > GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg) -- H.J.
