ITADN

Mismatched ABI for f128 comparison builtins on wasm64-unknown-unknown

#1199OpenSpxg 创建于 2026-04-16
S
Spxgcommented
On `wasm64-unknown-unknown`, there seems to be an ABI mismatch for `f128` comparison builtins such as `__gttf2`, `__lttf2`, `__eqtf2`, etc. `compiler-builtins` defines these builtins with `CmpResult = isize`, which becomes `i64` on `wasm64`. However, LLVM appears to lower `f128` comparisons (`>`, `<`, `==`, etc.) to runtime libcalls that expect an `i32` return value. As a result, the produced contain inconsistent signatures for the same symbols, make it broken. I think this is actually an LLVM issue (I’ll make an issue with LLVM soon), but I am wondering whether `compiler-builtins` could special-case wasm64 here as a practical workaround. Emscripten appears to special-case this behavior here: https://github.com/emscripten-core/emscripten/blob/88e0002141254cdb772b558f63d2c1ad9b215eb2/system/lib/compiler-rt/lib/builtins/fp_compare_impl.inc#L15 GCC's cmp_result is i32, there is also related LLVM issue here: https://github.com/llvm/llvm-project/issues/75302 If such a workaround is acceptable, I can make a PR. Reproduce: ```rust #![feature(f128)] #[unsafe(no_mangle)] pub fn issue(a: f128, b: f128) -> bool { a > b } ``` ``` cargo +nightly build --target wasm64-unknown-unknown -Zbuild-std=panic_abort,std --release warning: linker stderr: rust-lld: function signature mismatch: __gttf2 >>> defined as (i64, i64, i64, i64) -> i32 in /home/uharsn/repo/playground/target/wasm64-unknown-unknown/debug/deps/playground.27e5bot53bshdzky4drqb5i4f.0fmq2dj.rcgu.o >>> defined as (i64, i64, i64, i64) -> i64 in /home/uharsn/repo/playground/target/wasm64-unknown-unknown/debug/deps/libcompiler_builtins-1ab02c0bce5b5843.rlib(compiler_builtins-1ab02c0bce 5b5843.compiler_builtins.76b268114ccd8a12-cgu.02.rcgu.o) llvm-nm target/wasm64-unknown-unknown/release/playground.wasm 00000027 D __stack_pointer 00000075 T issue 00000071 t signature_mismatch:__gttf2 wasm-tools print target/wasm64-unknown-unknown/release/playground.wasm (func $signature_mismatch:__gttf2 (;0;) (type 0) (param i64 i64 i64 i64) (result i32) unreachable ) (func $issue (;1;) (type 0) (param i64 i64 i64 i64) (result i32) local.get 0 local.get 1 local.get 2 local.get 3 call $signature_mismatch:__gttf2 i32.const 0 i32.gt_s ) ```
1 条评论