пт, 11 сент. 2026 г. в 14:02, Richard Biener <[email protected]>: > > On Fri, 11 Sep 2026, Oleg Tolmatcev wrote: > > > пт, 28 авг. 2026 г. в 19:09, Richard Biener <[email protected]>: > > > > > > > > > > > > > Am 28.08.2026 um 18:24 schrieb Oleg Tolmatcev > > > > <[email protected]>: > > > > > > > > пт, 28 авг. 2026 г. в 15:55, Richard Biener <[email protected]>: > > > >> > > > >>> On Thu, 27 Aug 2026, Oleg Tolmatcev 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. > > > >> > > > >> It seems to me that assign_stack_local itself guarantees alignment. > > > >> Why does it (or rather assign_stack_local_1 with kind == > > > >> ASLK_RECORD_PAD) > > > >> not work? > > > >> > > > >> Richard. > > > > > > > > assign_stack_local_1 silently caps the the alignment at > > > > MAX_SUPPORTED_STACK_ALIGNMENT which for Win64 SEH is 16 bytes: > > > > > > > > /* Ignore alignment if it exceeds MAX_SUPPORTED_STACK_ALIGNMENT. */ > > > > if (alignment_in_bits > MAX_SUPPORTED_STACK_ALIGNMENT) > > > > { > > > > alignment_in_bits = MAX_SUPPORTED_STACK_ALIGNMENT; > > > > alignment = MAX_SUPPORTED_STACK_ALIGNMENT / BITS_PER_UNIT; > > > > } > > > > > > > > kind == ASLK_RECORD_PAD means that that the padding will be recorded > > > > in a free list for later reuse. It has no influence on alignment and > > > > assign_stack_local_1 does not even look at it before capping the > > > > alignment. > > > > > > I question whether this is correct then. When requesting a stack slot > > > with a specific alignment and not explicitly allowing a lesser alignment > > > we should get that alignment honored (or ICE). I don’t think a new API > > > for this is sound. Note I am not an expert on the history of this > > > semantics. > > > > > > Richard > > > > > > > > > > > Oleg > > > > assign_stack_local_1 was introduced by H.J. Lu, so I am CCing him. > > > > This patch fixes the alignment bug in the simplest way I could find, with as > > few lines as possible. It extracts existing code from > > assign_parm_setup_block > > and reuses it in assign_stack_temp_for_type, assign_parm_setup_reg and > > assign_parm_setup_stack. I don't think a simpler fix is possible, but I am > > not an expert, of course. > > > > I need guidance on how to proceed with the patch. Thank you. > > So I'd prefer if the assign_stack_local_1 code doing > > /* Ignore alignment if it exceeds MAX_SUPPORTED_STACK_ALIGNMENT. */ > if (alignment_in_bits > MAX_SUPPORTED_STACK_ALIGNMENT) > { > alignment_in_bits = MAX_SUPPORTED_STACK_ALIGNMENT; > alignment = MAX_SUPPORTED_STACK_ALIGNMENT / BITS_PER_UNIT; > } > > were extended with the logic you add in assign_stack_local_aligned > unless the ASLK_REDUCE_ALIGN bit is set. That is, you'd pad the > size here and perform align_dynamic_address at the end before > we generate the MEM. > > Richard.
I sent a v2 of my patch, that implements your proposal. Oleg
