Stack allocation: enforce a per-architecture minimal stack-pointer alignment - #1546
Merged
Conversation
vbgl
reviewed
Aug 28, 2026
Add an sp_min_align architecture parameter bounding the alignment the stack pointer keeps across calls: stack allocation raises the frame alignment of every function that actually uses the stack up to it (frame sizes are rounded up to the frame alignment, so this bounds the stack-pointer alignment itself). Functions with no stack footprint keep their alignment, so export functions with no stack use are unaffected. All architectures declare U8 here (no constraint), so this commit does not change the generated code.
Armv7-M guarantees that stack pointer values are at least 4-byte aligned: writes to SP force bits [1:0] to zero (Arm v7-M Architecture Reference Manual, B1.5.7). With no minimal alignment, a function whose frame is only 1- or 2-byte aligned lets the export prologue write a non-4-byte-aligned SP (BIC #1 on the aligned copy), which the hardware silently rounds, shifting every subsequent SP-relative access. Set sp_min_align to U32 for arm-m4 so such frames are padded to 4 bytes. The instack function of tests/success/common/unaligned.jazz asserted the computed alignment with #[stackalign=u16], which is now architecture-dependent; move it to per-architecture copies (unaligned_stackalign.jazz): u16 on x86-64 and risc-v, and u32 on arm-m4, failing before this change.
vbgl
approved these changes
Aug 28, 2026
vbgl
left a comment
Member
There was a problem hiding this comment.
LGTM. Why is this PR marked as “draft”?
Contributor
Author
|
clebreto
marked this pull request as ready for review
August 28, 2026 12:20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Split out of #1541, as suggested in review: the mechanism is independent of the ARMv8-A backend.
sp_min_alignarchitecture parameter bounding the alignment the stack pointer keeps across calls; stack allocation raises the frame alignment of every function that actually uses the stack up to it (frame sizes are rounded up to the frame alignment, so this bounds the SP alignment itself). All architectures declareU8, so no generated code changes.U32on arm-m4. Armv7-M guarantees that stack pointer values are at least 4-byte aligned — writes to SP force bits [1:0] to zero (Arm v7-M Architecture Reference Manual, B1.5.7) — so a frame that is only 1- or 2-byte aligned lets the export prologue write a non-4-byte-aligned SP (BIC r12, r12, #1beforeMOV sp, r12), which the hardware silently rounds, shifting every subsequent SP-relative access. The newtests/success/arm-m4/unaligned_stackalign.jazzasserts the computed alignment with#[stackalign=u32]and fails without this commit; theinstackfunction oftests/success/common/unaligned.jazzmoves to per-architecture copies since the expected alignment is now architecture-dependent.No command-line override: the per-architecture default is the only value with a real use case.
The ARMv8-A backend (#1541) relies on this mechanism with a 16-byte floor (AArch64 SP alignment checking); once this lands, the corresponding hunks disappear from that PR.