Earlier today I was trying my hand at getting the run-pass test suite passing on wasm32-unknown-unknown, but alas I hit a failure in the saturating-float-casts.rs
test! I believe that in wasm32 we’ll actually want to unconditionally turn on the saturating cast behavior because an out-of-bounds cast is actually a trap!
So the problem I’m seeing is that when executing the saturating-float-casts.rs
test it’ll fail with integer result unrepresentable
which I think means an out of bounds cast. I minimized the test to:
use std::f64;
#[inline(never)]
fn bar<T>(t: T) -> T { t }
#[no_mangle]
pub fn foo() -> f64 {
if bar(f64::INFINITY) as i8 != i8::max_value() {
extern { fn exit(); }
unsafe { exit(); }
}
bar(f64::NEG_INFINITY)
}
I couldn’t really quite follow the wasm IR, but I figured I could take a stab at the LLVM IR. So instead of a wasm target the IR here is generated for x86_64-unknown-linux-gnu with optimizations disabled
define double @foo() unnamed_addr #2 {
start:
%_1 = alloca {}, align 1
; call wut::bar
%0 = call double @_ZN3wut3bar17h434e9ad8e9a22fa7E(double 0x7FF0000000000000)
br label %bb1
bb1: ; preds = %start
%1 = fptosi double %0 to i8
I think that this IR may not be correct? @hanna-kruppe correct me if I’m wrong though! According to LLVM’s documentation the fptosi
instruction is undefined behavior if the source doesn’t fit in the destination, but in this case I think it’s unconditionally putting f64::INFINITY
into the destination of i8
? I think this is what’s causing a trap on wasm as that instruction generates a trap instead of doing anything else.
@hanna-kruppe is this expected behavior? Or maybe I’ve misdiagnosed? I can certainly open an issue with more details if that would help!