Skip to content

fix arm homogeneous aggregate ABI - #161070

Open
folkertdev wants to merge 1 commit into
rust-lang:mainfrom
folkertdev:armv7-align-abi
Open

fix arm homogeneous aggregate ABI#161070
folkertdev wants to merge 1 commit into
rust-lang:mainfrom
folkertdev:armv7-align-abi

Conversation

@folkertdev

@folkertdev folkertdev commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

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

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels 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,
}
};

@folkertdev folkertdev Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);

@folkertdev folkertdev Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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));

@folkertdev folkertdev Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
}

@folkertdev folkertdev Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let align = match abi_kind {
ArmAbiKind::Aapcs | ArmAbiKind::AapcsVfp => arg.layout.unadjusted_abi_align.bytes(),
ArmAbiKind::Aapcs16Vfp => arg.layout.align.bytes(),
};

@folkertdev folkertdev Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@folkertdev folkertdev added the O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state label Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants