Repository navigation
mips64 ABI bug passing 16-byte aligned scalars #161679
Copy link
Copy link
Closed
Labels
A-ABIArea: Concerning the application binary interface (ABI)Area: Concerning the application binary interface (ABI)I-miscompileIssue: Correct Rust code lowers to incorrect machine codeIssue: Correct Rust code lowers to incorrect machine codeO-MIPSTarget: MIPS processorsTarget: MIPS processorsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
16-byte aligned scalars (f128, i128, u128, probably also vectors) are passed in a way that is inconsistent with GCC/Clang. Aggregates seem fine.
E.g. C calling rust (but also rust calling C) fails:
// caller.c
#include <inttypes.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdarg.h>
void val_in_0_perturbed_small(uint8_t arg0, __int128_t arg1, __int128_t arg2, float arg3) {
printf("%d", arg1);
}// callee.rs
extern "C" {
fn val_in_0_perturbed_small(arg0: u8, arg1: i128, arg2: i128, arg3: f32);
}
#[no_mangle]
pub extern "C" fn do_test() {
unsafe {
let arg0 = 192u8;
let arg1 = -42707334047547540181846984563639529008i128;
println!("{:?}", {arg1});
let arg2 = -21356283574076891493948969979685445152i128;
let arg3 = f32::from_bits(4092785136);
val_in_0_perturbed_small(arg0, arg1, arg2, arg3);
}
}When running abi-cafe that prints
func val_in_0_perturbed_small's values differed
values (native-endian hex bytes):
expect: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
caller: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
callee: D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7
the value was arg1: i128
whose arg was arg1: i128
So looks like the callee side is off by 8 bytes.
I used this abi-cafe command (on my fork that cross-compiles https://github.com/folkertdev/abi-cafe):
env RUSTUP_TOOLCHAIN=stage1 QEMU_LD_PREFIX=/usr/mips64el-linux-gnuabi64 ABI_CAFE_RUNNER= ./target/release/abi-cafe --target mips64el-unknown-linux-gnuabi64 --linker mips64el-linux-gnuabi64-gcc --conventions c --reprs c -t i128
Which requires a stage1 toolchain with the right std, e.g. something like this (also building the host is often convenient):
./x build library --target x86_64-unknown-linux-gnu,mips64-unknown-linux-gnuabi64,mips64el-unknown-linux-gnuabi64,mips-unknown-linux-gnu,mipsel-unknown-linux-gnu
Metadata
Metadata
Assignees
Labels
A-ABIArea: Concerning the application binary interface (ABI)Area: Concerning the application binary interface (ABI)I-miscompileIssue: Correct Rust code lowers to incorrect machine codeIssue: Correct Rust code lowers to incorrect machine codeO-MIPSTarget: MIPS processorsTarget: MIPS processorsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Activity
Gelbpunkt commentedon Aug 24, 2026
I'd like to look into this and have fun with MIPS ABI specs again, so:
@rustbot claim
workingjubilee commentedon Aug 24, 2026
"fun"
chenx97 commentedon Sep 1, 2026
The bug likely comes from only handling
pad_i32for aggregates instead of all types.chenx97 commentedon Sep 21, 2026
It's more fun when I see that Clang 22 makes the same mistake.
Rollup merge of #163653 - Gelbpunkt:mips64-16-byte-scalar-alignment, …
Rollup merge of rust-lang#163653 - Gelbpunkt:mips64-16-byte-scalar-al…
Unrolled build for #163653 in rollup 163767