-
Notifications
You must be signed in to change notification settings - Fork 13.4k
tests: FiveU16s extern ABI test fails on big endian PPC64 ELFv2 (musl) #128579
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Indeed, if I remove those two lines, it passes the tests correctly: --- a/compiler/rustc_target/src/abi/call/powerpc64.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc64.rs
@@ -69,9 +69,7 @@ fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, abi: ABI)
let size = ret.layout.size;
let bits = size.bits();
if bits <= 128 {
- let unit = if cx.data_layout().endian == Endian::Big {
- Reg { kind: RegKind::Integer, size }
- } else if bits <= 8 {
+ let unit = if bits <= 8 {
Reg::i8()
} else if bits <= 16 {
Reg::i16() But I'm not sure why they are there and if this could possibly cause breakage elsewhere. I'd be happy to open a PR with this change for comment if that is the best way forward, or we can continue to discuss here. |
Indeed, there is fallout - this test used to pass:
|
Reading over the ELF ABI specification and how LLVM and GCC implement this, arguments and return values should be treated the same. So, trying to duplicate the logic from --- a/compiler/rustc_target/src/abi/call/powerpc64.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc64.rs
@@ -69,19 +69,15 @@ fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, abi: ABI)
let size = ret.layout.size;
let bits = size.bits();
if bits <= 128 {
- let unit = if cx.data_layout().endian == Endian::Big {
- Reg { kind: RegKind::Integer, size }
- } else if bits <= 8 {
- Reg::i8()
- } else if bits <= 16 {
- Reg::i16()
- } else if bits <= 32 {
- Reg::i32()
+ if bits <= 64 {
+ ret.cast_to(Uniform::new(Reg { kind: RegKind::Integer, size }, size))
} else {
- Reg::i64()
+ let reg = if ret.layout.align.abi.bytes() > 8 { Reg::i128() } else { Reg::i64() };
+ ret.cast_to(Uniform::consecutive(
+ reg,
+ size.align_to(Align::from_bytes(reg.size.bytes()).unwrap()),
+ ))
};
-
- ret.cast_to(Uniform::new(unit, size));
return;
}
and gave me:
which is actually the first time I've ever seen Rust complete its test suite fully on a big endian PPC64/musl environment! Since the logic doesn't vary between endian in I suppose since the original code had a BE case which was suspiciously similar to the first half of |
Refactor `powerpc64` call ABI handling As the [specification](https://openpowerfoundation.org/specifications/64bitelfabi/) for the ELFv2 ABI states that returned aggregates are returned like arguments as long as they are at most two doublewords, I've merged the `classify_arg` and `classify_ret` functions to reduce code duplication. The only functional change is to fix rust-lang#128579: the `classify_ret` function was incorrectly handling aggregates where `bits > 64 && bits < 128`. I've used the aggregate handling implementation from `classify_arg` which doesn't have this issue. `@awilfox` could you test this on `powerpc64-unknown-linux-musl`? I'm only able to cross-test on `powerpc64-unknown-linux-gnu` and `powerpc64le-unknown-linux-gnu` locally at the moment, and as a tier 3 target `powerpc64-unknown-linux-musl` has zero CI coverage. Fixes: rust-lang#128579
Refactor `powerpc64` call ABI handling As the [specification](https://openpowerfoundation.org/specifications/64bitelfabi/) for the ELFv2 ABI states that returned aggregates are returned like arguments as long as they are at most two doublewords, I've merged the `classify_arg` and `classify_ret` functions to reduce code duplication. The only functional change is to fix rust-lang#128579: the `classify_ret` function was incorrectly handling aggregates where `bits > 64 && bits < 128`. I've used the aggregate handling implementation from `classify_arg` which doesn't have this issue. ``@awilfox`` could you test this on `powerpc64-unknown-linux-musl`? I'm only able to cross-test on `powerpc64-unknown-linux-gnu` and `powerpc64le-unknown-linux-gnu` locally at the moment, and as a tier 3 target `powerpc64-unknown-linux-musl` has zero CI coverage. Fixes: rust-lang#128579
Rollup merge of rust-lang#128643 - beetrees:ppc64-abi-fix, r=bjorn3 Refactor `powerpc64` call ABI handling As the [specification](https://openpowerfoundation.org/specifications/64bitelfabi/) for the ELFv2 ABI states that returned aggregates are returned like arguments as long as they are at most two doublewords, I've merged the `classify_arg` and `classify_ret` functions to reduce code duplication. The only functional change is to fix rust-lang#128579: the `classify_ret` function was incorrectly handling aggregates where `bits > 64 && bits < 128`. I've used the aggregate handling implementation from `classify_arg` which doesn't have this issue. `@awilfox` could you test this on `powerpc64-unknown-linux-musl`? I'm only able to cross-test on `powerpc64-unknown-linux-gnu` and `powerpc64le-unknown-linux-gnu` locally at the moment, and as a tier 3 target `powerpc64-unknown-linux-musl` has zero CI coverage. Fixes: rust-lang#128579
I tried this code:
I expected to see this happen: test suite passing
Instead, this happened:
The return failure is:
The pass failure is:
Meta
rustc --version --verbose
:This occurs in every version since the test was added. I see this with 1.79.0 and 1.80.0 as well as my 1.81.0 beta build (
rustc 1.81.0-beta.2 (08328a323 2024-07-25) (Adelie 1.81.0_beta20240730-r0 [BETA])
).I haven't dug in to all of the nitty-gritty yet, but I have a feeling
rust/compiler/rustc_target/src/abi/call/powerpc64.rs
Lines 72 to 73 in 0514789
The text was updated successfully, but these errors were encountered: