-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tests: FiveU16s extern ABI test fails on big endian PPC64 ELFv2 (musl) #128579
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: