On 9/16/26 18:41, Oleg Tolmatcev wrote:
Targets that cannot guarantee arbitrary stack alignment cap stack slots at
MAX_SUPPORTED_STACK_ALIGNMENT.  Win64 SEH caps MAX_STACK_ALIGNMENT at 128
bits; aarch64 does not define MAX_STACK_ALIGNMENT and is capped at
STACK_BOUNDARY, also 128 bits.  assign_stack_local silently ignored any
alignment beyond that cap.

A 256-bit vector requires 32-byte alignment, but its slot could therefore
receive only 16-byte alignment while later MEM attributes still claimed 32.
x86 could select vmovaps from that MEM_ALIGN and fault on the under-aligned
slot (PR54412, MSYS2/MINGW-packages#1209).  An escaped pointer has the same
problem even when the local move is unaligned, since its type still promises
the callee a 32-byte-aligned object.

Make assign_stack_local_1 honour an explicit alignment beyond the cap by
reserving enough space and aligning an address inside it at run time, as
assign_parm_setup_block already did for BLKmode parameters and
expand_stack_vars does for locals.  Base the extra space on the alignment
guaranteed for VIRTUAL_STACK_VARS_REGNUM rather than on the maximum alignment
supported by the backend, since the frame itself is not guaranteed to have
the latter alignment on all targets.

Let a new internal assign_stack_local_2 return the address before run-time
alignment.  Store it in the temp slot and realign the address on reuse, while
avoiding splitting or combining over-aligned slots.

Honour required temporary alignment at run time, but cap merely preferred
alignment.  Preserve zero-size behavior and the target's preferred stack
boundary, and emit run-time alignment only during expansion to RTL.

Use ASLK_REDUCE_ALIGN where less alignment is acceptable: LRA spill slots and
the deliberately over-aligned SJLJ function context.

Regtested on x86_64-pc-linux-gnu and, under QEMU, on
aarch64-unknown-linux-gnu, with no new failures.

gcc/ChangeLog:

        PR target/54412
        * except.cc (sjlj_build_landing_pads): Pass ASLK_REDUCE_ALIGN.
        * function.cc (assign_stack_local_2): New function, split from
        assign_stack_local_1.  Honour an explicit alignment beyond
        MAX_SUPPORTED_STACK_ALIGNMENT by overallocating the slot and aligning
        its address at run time.  Optionally return the address before run-time
        alignment.
        (assign_stack_local_1): Wrap assign_stack_local_2.
        (temp_slot): Add base_addr.
        (assign_stack_temp_for_type): Distinguish required and preferred
        alignment.  Record the address before run-time alignment and recalculate
        the aligned address when reusing an over-aligned slot.  Do not split an
        over-aligned BLKmode slot.
        (combine_temp_slots): Do not combine over-aligned slots.
        (assign_parm_setup_block): Let assign_stack_local align the slot.
        * lra-spills.cc (assign_mem_slot): Pass ASLK_REDUCE_ALIGN.

gcc/testsuite/ChangeLog:

        PR target/54412
        * g++.target/i386/pr54412-highpart-extract-rt.C: Adjust the comment to
        describe safe reuse of an over-aligned temporary.

Signed-off-by: Oleg Tolmatcev <[email protected]>
---
  gcc/except.cc     |  12 ++---
  gcc/function.cc   | 131 +++++++++++++++++++++++++++++++++++-----------
  gcc/lra-spills.cc |   5 +-
  3 files changed, 108 insertions(+), 40 deletions(-)

Anymore review comments? Can this be pushed?

Reply via email to