ABI mismatch on powerpc64 (elfv1) for union containing floats
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
with
https://godbolt.org/z/EYxKxTs4f
// --target=powerpc64-unknown-linux-gnu -Copt-level=3
#[repr(C)] pub union TwoFloats { a: f32, b: f32 }
#[unsafe(no_mangle)]
extern "C" fn foo(x: TwoFloats) -> f32 {
unsafe { x.a }
}
rustc emits
foo:
.quad .Lfunc_begin0
.quad .TOC.@tocbase
.quad 0
.Lfunc_begin0:
blr
I.e. the argument is already in a float register, and it stays there for the return. But with GCC and Clang the equivalent
https://godbolt.org/z/Mx8GEzdvn
typedef union { float a; float b; } TwoFloats;
float foo(TwoFloats x) {
return x.a;
}
Has an explicit move from GPR to memory to FPR
foo:
.quad .Lfunc_begin0
.quad .TOC.@tocbase
.quad 0
.Lfunc_begin0:
stw 3, -4(1)
lfs 1, -4(1)
blr
You can see this difference in the LLVM IR emitted by rustc and clang too:
; rust
define noundef float @foo(float returned %0) unnamed_addr {
start:
ret float %0
}
; clang
define dso_local float @foo(i32 %x.coerce) local_unnamed_addr {
entry:
%0 = bitcast i32 %x.coerce to float
ret float %0
}
This came up in relation to https://github.com/rust-lang/rust/pull/161987.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the rustc invocation for the powerpc64-unknown-linux-gnu target and inspect the emitted LLVM IR, then compare it with the linked Clang output. Trace how the union argument and return value are lowered for the elfv1 ABI; done means the generated ABI matches the C compiler's register and coercion behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100