On Tue, Aug 25, 2026 at 2:31 PM Oleg Tolmatcev <[email protected]> wrote: > > вт, 25 авг. 2026 г. в 12:45, Richard Biener <[email protected]>: > > > > On Mon, Aug 24, 2026 at 10:12 PM Oleg Tolmatcev > > <[email protected]> wrote: > > > > > > Targets that cannot realign the stack cap their stack alignment and rely > > > on the middle end to align over-aligned stack objects inside their slots. > > > Win64 SEH caps MAX_STACK_ALIGNMENT at 128 bits; aarch64 does not define > > > MAX_STACK_ALIGNMENT at all and is capped at STACK_BOUNDARY, also 128. > > > > > > In several places the middle end does not do that alignment. A 256-bit > > > vector requires 32-byte alignment, its slot gets the capped 16 bytes, and > > > MEM_ALIGN is set to 32 anyway. x86 selects vmovaps from MEM_ALIGN and > > > faults on the under-aligned slot (PR54412, MSYS2/MINGW-packages#1209). > > > There is an even bigger problem. Even with MEM_ALIGN and the slot's > > > alignment consistent, an escaped pointer loses the information about the > > > alignment cap: GCC assumes the object's natural alignment and uses an > > > aligned access on an under-aligned object, which faults on x86. > > > > > > aarch64 does not crash only because its loads and stores do not fault on > > > a misaligned address; the object is under-aligned there just the same. > > > > > > Add assign_stack_local_aligned, which preserves the requested alignment by > > > overallocating a slot and aligning an address inside it, and use it > > > wherever an object gets a stack slot of its own. This is what > > > assign_parm_setup_block already did for BLKmode parameters and what > > > expand_stack_vars does for locals. Such a slot has no fixed frame offset, > > > so it cannot be reused as a temp slot. > > > > > > Finally, defer_stack_allocation and expand_one_stack_var_1 computed a > > > local's stack alignment in two different ways, so a variable the former > > > considered small enough to allocate immediately could trip the > > > large-alignment assert in the latter (PR target/120192). Use > > > align_local_variable in both. > > > > > > Regtested on x86_64-pc-linux-gnu and, under QEMU, on > > > aarch64-unknown-linux-gnu, with no new failures. > > > > > > gcc/ChangeLog: > > > > > > PR target/54412 > > > PR target/120192 > > > * cfgexpand.cc (defer_stack_allocation): Use align_local_variable > > > to compute the alignment, matching expand_one_stack_var_1. > > > * function.cc (assign_stack_local_aligned): New function, split > > > out of assign_parm_setup_block. > > > (assign_stack_temp_for_type): Compute the required alignment from > > > the type and the mode. Allocate an over-aligned temporary with > > > assign_stack_local_aligned and give it no temp_slot entry. Take > > > the resulting alignment from the allocated slot. > > > (assign_parm_setup_block): Use assign_stack_local_aligned. > > > (assign_parm_setup_reg): Likewise. > > > (assign_parm_setup_stack): Likewise. > > > > > > Signed-off-by: Oleg Tolmatcev <[email protected]> > > > --- > > > gcc/cfgexpand.cc | 8 +++-- > > > gcc/function.cc | 87 +++++++++++++++++++++++++++++++++++------------- > > > 2 files changed, 68 insertions(+), 27 deletions(-) > > > > > > diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc > > > index 128cfc7768..8720b77ced 100644 > > > --- a/gcc/cfgexpand.cc > > > +++ b/gcc/cfgexpand.cc > > > @@ -1995,9 +1995,11 @@ defer_stack_allocation (tree var, bool toplevel) > > > if (flag_stack_protect || asan_sanitize_stack_p ()) > > > return true; > > > > > > - unsigned int align = TREE_CODE (var) == SSA_NAME > > > - ? TYPE_ALIGN (TREE_TYPE (var)) > > > - : DECL_ALIGN (var); > > > + /* Keep this in sync with expand_one_stack_var_1. For some targets, > > > + LOCAL_DECL_ALIGNMENT can raise a local variable's effective stack > > > + alignment above DECL_ALIGN, and immediate allocation would then > > > + trip the high-alignment assert in expand_one_stack_var_1. */ > > > + unsigned int align = align_local_variable (var, false) * BITS_PER_UNIT; > > > > If you do only this change, which cases improve and why is this not > > sufficient > > as fix? I'm mostly looking for a possibility to split up the change and > > clearly > > associate test coverage with fix parts here. > > > > Thanks, > > Richard. > > With only this change, pr54412-pr120192.c passes; all the other new > tests still fail. It > fixes only the PR120192 ICE by making defer_stack_allocation use the same > alignment calculation as expand_one_stack_var_1. It does not fix the > under-aligned > slots created through assign_stack_local. > I could split this change and its test into a separate PR120192 patch.
Please do that. This is a quite fragile area, so it's best to divide changes up as much as possible. Richard. > > Oleg
