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

Reply via email to