fix arm homogeneous aggregate ABI - #161070
Open
folkertdev wants to merge 1 commit into
Open
Conversation
folkertdev
force-pushed
the
armv7-align-abi
branch
from
August 13, 2026 20:11
6847345 to
083e8a8
Compare
folkertdev
commented
Aug 13, 2026
Comment on lines
+129
to
+141
| // Whether we must use the VFP registers for homogeneous aggregates. | ||
| let is_effectively_vfp = |accept_aapcs16| { | ||
| // When the user requested aapcs explicitly, honor that. | ||
| if matches!(fn_abi.conv, CanonAbi::Arm(ArmCall::Aapcs)) { | ||
| return false; | ||
| } | ||
|
|
||
| match abi_kind { | ||
| ArmAbiKind::AapcsVfp => true, | ||
| ArmAbiKind::Aapcs16Vfp => accept_aapcs16, | ||
| ArmAbiKind::Aapcs => false, | ||
| } | ||
| }; |
Contributor
Author
There was a problem hiding this comment.
I've kept the existing check for the ABI.
Comment on lines
+147
to
+152
| let is_arg_vfp = !fn_abi.c_variadic && is_effectively_vfp(false); | ||
| for arg in fn_abi.args.iter_mut() { | ||
| if arg.is_ignore() { | ||
| continue; | ||
| } | ||
| classify_arg(cx, arg, vfp); | ||
| classify_arg(cx, arg, abi_kind, is_arg_vfp); |
Contributor
Author
There was a problem hiding this comment.
Comment on lines
-101
to
+144
| classify_ret(cx, &mut fn_abi.ret, vfp); | ||
| classify_ret(cx, &mut fn_abi.ret, abi_kind, !fn_abi.c_variadic && is_effectively_vfp(true)); |
Contributor
Author
There was a problem hiding this comment.
Comment on lines
-77
to
+105
| if vfp { | ||
| // watchOS also passes homogeneous aggregates in VFP registers, and unlike `AapcsVfp` it does | ||
| // so even for variadics and for `extern "aapcs"`: the backend will use GPRs if needed. | ||
| if vfp || matches!(abi_kind, ArmAbiKind::Aapcs16Vfp) { | ||
| if let Some(uniform) = is_homogeneous_aggregate(cx, arg) { | ||
| arg.cast_to(uniform); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| let align = arg.layout.align.bytes(); | ||
| // For the composites that are left, watchOS adopts the 64-bit AAPCS rule: those larger than | ||
| // 128 bits are placed in space allocated by the caller, and a pointer is passed. | ||
| if matches!(abi_kind, ArmAbiKind::Aapcs16Vfp) && arg.layout.size.bits() > 128 { | ||
| arg.make_indirect(); | ||
| return; | ||
| } |
Contributor
Author
There was a problem hiding this comment.
| let align = match abi_kind { | ||
| ArmAbiKind::Aapcs | ArmAbiKind::AapcsVfp => arg.layout.unadjusted_abi_align.bytes(), | ||
| ArmAbiKind::Aapcs16Vfp => arg.layout.align.bytes(), | ||
| }; |
Contributor
Author
There was a problem hiding this comment.
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.
This started with abi-cafe finding a mismatch between rustc and clang/gcc, but turned into quite the rabbit hole of bits of ABI that were never implemented. The code is effectively ported from LLVM, and abi-cafe is happy now.
The bug I hit was that aligned structs were passed incorrectly:
https://godbolt.org/z/jErPoPrv5
The assertions for watchOS are best-effort, I can't actually run that. But, it's tier 3, it was already broken, so at worst it's just less broken now.
The relevant code is in https://github.com/llvm/llvm-project/blob/551766823bb7b5a6af84e4ec1c1aff6dff431229/clang/lib/CodeGen/Targets/ARM.cpp, I'll link some specific parts.
r? davidtwco