вт, 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.

Oleg

Reply via email to