Rollup merge of #142389 - beetrees:cranelift-arg-ext, r=bjorn3

Apply ABI attributes on return types in `rustc_codegen_cranelift`

- The [x86-64 System V ABI standard](https://gitlab.com/x86-psABIs/x86-64-ABI/-/jobs/artifacts/master/raw/x86-64-ABI/abi.pdf?job=build) doesn't sign/zero-extend integer arguments or return types.
- But the de-facto standard as implemented by Clang and GCC is to sign/zero-extend arguments to 32 bits (but not return types).
- Additionally, Apple targets [sign/zero-extend both arguments and return values to 32 bits](https://developer.apple.com/documentation/xcode/writing-64-bit-intel-code-for-apple-platforms#Pass-arguments-to-functions-correctly).
- However, the `rustc_target` ABI adjustment code currently [unconditionally extends both arguments and return values to 32 bits](e703dff8fe/compiler/rustc_target/src/callconv/x86_64.rs (L240)) on all targets.
- This doesn't cause a miscompilation when compiling with LLVM as LLVM will ignore the `signext`/`zeroext` attribute when applied to return types on non-Apple x86-64 targets.
- Cranelift, however, does not have a similar special case, requiring `rustc` to set the argument extension attribute correctly.
- However, `rustc_codegen_cranelift` doesn't currently apply ABI attributes to return types at all, meaning `rustc_codegen_cranelift` will currently miscompile `i8`/`u8`/`i16`/`u16` returns on x86-64 Apple targets as those targets require sign/zero-extension of return types.

This PR fixes the bug(s) by making the `rustc_target` x86-64 System V ABI only mark return types as sign/zero-extended on Apple platforms, while also making `rustc_codegen_cranelift` apply ABI attributes to return types. The RISC-V and s390x C ABIs also require sign/zero extension of return types, so this will fix those targets when building with `rustc_codegen_cranelift` too.

r? `````@bjorn3`````
This commit is contained in:
León Orell Valerian Liehr
2025-06-15 23:51:56 +02:00
committed by GitHub
8 changed files with 1161 additions and 27 deletions

View File

@@ -7,6 +7,7 @@ use rustc_abi::{
};
use crate::callconv::{ArgAbi, CastTarget, FnAbi};
use crate::spec::HasTargetSpec;
/// Classification of "eightbyte" components.
// N.B., the order of the variants is from general to specific,
@@ -175,7 +176,7 @@ const MAX_SSE_REGS: usize = 8; // XMM0-7
pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
C: HasDataLayout + HasTargetSpec,
{
let mut int_regs = MAX_INT_REGS;
let mut sse_regs = MAX_SSE_REGS;
@@ -236,7 +237,7 @@ where
if arg.layout.is_aggregate() {
let size = arg.layout.size;
arg.cast_to(cast_target(cls, size));
} else {
} else if is_arg || cx.target_spec().is_like_darwin {
arg.extend_integer_width_to(32);
}
}