-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Wasm traps on saturating float casts #46298
Copy link
Copy link
Closed
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.Category: This is a bug.O-wasmTarget: WASM (WebAssembly), http://webassembly.org/Target: WASM (WebAssembly), http://webassembly.org/
Metadata
Metadata
Assignees
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.Category: This is a bug.O-wasmTarget: WASM (WebAssembly), http://webassembly.org/Target: WASM (WebAssembly), http://webassembly.org/
Type
Fields
Give feedbackNo fields configured for issues without a type.
In https://internals.rust-lang.org/t/help-us-benchmark-saturating-float-casts/6231/19 @alexcrichton reported that wasm traps on out-of-range floats being cast to integers. This is a problem for the current implementation of saturating float casts, which executes the cast unconditionally and then only uses it if the input was in range. LLVM says that the result is undefined (i.e.,
undef) rather than the behavior being undefined. On all other targets I'm aware of, the operation just gets lowered to an instruction that returns some integer result for those cases.I've checked the wasm spec, which says:
As wasm doesn't want everything-goes UB as in C or LLVM or Rust, "undefined" operations are specified to trap. So this is intentional in wasm, which makes sense to me. They'd rather trap than return a questionable result, and they certainly can't tolerate hardware-dependent behavior.
So how do we work around this? We could emit branches instead of unconditionally executing the cast, at the cost of a more complicated implementation (need to juggle multiple basic blocks) and other downsides (branch predictor pressure, input-data-dependent performance). It might also be an argument in favor of making the saturation explicit in MIR rather than doing it during LLVM IR codegen:
cc @sunfishcode @eddyb