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: llvm/llvm-project#75302
If such a workaround is acceptable, I can make a PR.
Reproduce:
#![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
)
On
wasm64-unknown-unknown, there seems to be an ABI mismatch forf128comparison builtins such as__gttf2,__lttf2,__eqtf2, etc.compiler-builtinsdefines these builtins withCmpResult = isize, which becomesi64onwasm64. However, LLVM appears to lowerf128comparisons (>,<,==, etc.) to runtime libcalls that expect ani32return 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-builtinscould 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: llvm/llvm-project#75302
If such a workaround is acceptable, I can make a PR.
Reproduce: