Skip to content

Commit

Permalink
Make wasm +sign-ext and +nontrapping-fptoint the default
Browse files Browse the repository at this point in the history
These have been supported in ~all wasm runtimes for a while now, and +nontrapping-fptoint in particular can make a big performance difference. We should enable these by default, and add a new backdoor (wasm_mvponly) for code paths that need to use the original wasm Minimum Viable Product spec only.
  • Loading branch information
steven-johnson committed Dec 7, 2023
1 parent d1ecc1f commit 52460eb
Show file tree
Hide file tree
Showing 8 changed files with 18 additions and 29 deletions.
17 changes: 8 additions & 9 deletions README_webassembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ backend.
As WebAssembly itself is still under active development, Halide's support has
some limitations. Some of the most important:

- Sign-extension operations are enabled by default (but can be avoided via
Target::WasmMvpOnly).
- Non-trapping float-to-int conversions are enabled by default (but can be
avoided via Target::WasmMvpOnly).
- Fixed-width SIMD (128 bit) can be enabled via Target::WasmSimd128.
- Sign-extension operations can be enabled via Target::WasmSignExt.
- Non-trapping float-to-int conversions can be enabled via
Target::WasmSatFloatToInt.
- Threads have very limited support via Target::WasmThreads; see
[below](#using-threads) for more details.
- Halide's JIT for Wasm is extremely limited and really useful only for
Expand Down Expand Up @@ -152,9 +153,8 @@ cmake -DLLVM_ENABLE_PROJECTS="clang;lld" ...
```
- To run the JIT tests, set `HL_JIT_TARGET=wasm-32-wasmrt` (possibly adding
`wasm_simd128`, `wasm_signext`, and/or `wasm_sat_float_to_int`) and run
CMake/CTest normally. Note that wasm testing is only support under CMake
(not via Make).
`wasm_simd128`) and run CMake/CTest normally. Note that wasm testing is
only supported under CMake (not via Make).
## Enabling wasm AOT
Expand All @@ -165,9 +165,8 @@ will), you need to install Emscripten locally.
(https://emscripten.org/docs/getting_started/downloads.html).
- To run the AOT tests, set `HL_TARGET=wasm-32-wasmrt` (possibly adding
`wasm_simd128`, `wasm_signext`, and/or `wasm_sat_float_to_int`) and run
CMake/CTest normally. Note that wasm testing is only support under CMake
(not via Make).
`wasm_simd128`) and run CMake/CTest normally. Note that wasm testing is
only supported under CMake (not via Make).
# Running benchmarks
Expand Down
3 changes: 1 addition & 2 deletions python_bindings/src/halide/halide_/PyEnums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,8 @@ void define_enums(py::module &m) {
.value("HexagonDma", Target::Feature::HexagonDma)
.value("EmbedBitcode", Target::Feature::EmbedBitcode)
.value("EnableLLVMLoopOpt", Target::Feature::EnableLLVMLoopOpt)
.value("WasmMvpOnly", Target::Feature::WasmMvpOnly)
.value("WasmSimd128", Target::Feature::WasmSimd128)
.value("WasmSignExt", Target::Feature::WasmSignExt)
.value("WasmSatFloatToInt", Target::Feature::WasmSatFloatToInt)
.value("WasmThreads", Target::Feature::WasmThreads)
.value("WasmBulkMemory", Target::Feature::WasmBulkMemory)
.value("SVE", Target::Feature::SVE)
Expand Down
8 changes: 2 additions & 6 deletions src/CodeGen_WebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,21 +333,17 @@ string CodeGen_WebAssembly::mattrs() const {
std::ostringstream s;
string sep;

if (target.has_feature(Target::WasmSignExt)) {
if (!target.has_feature(Target::WasmMvpOnly)) {
s << sep << "+sign-ext";
sep = ",";
s << sep << "+nontrapping-fptoint";
}

if (target.has_feature(Target::WasmSimd128)) {
s << sep << "+simd128";
sep = ",";
}

if (target.has_feature(Target::WasmSatFloatToInt)) {
s << sep << "+nontrapping-fptoint";
sep = ",";
}

if (target.has_feature(Target::WasmThreads)) {
// "WasmThreads" doesn't directly affect LLVM codegen,
// but it does end up requiring atomics, so be sure to enable them.
Expand Down
3 changes: 1 addition & 2 deletions src/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,8 +533,7 @@ const std::map<std::string, Target::Feature> feature_name_map = {
{"embed_bitcode", Target::EmbedBitcode},
{"enable_llvm_loop_opt", Target::EnableLLVMLoopOpt},
{"wasm_simd128", Target::WasmSimd128},
{"wasm_signext", Target::WasmSignExt},
{"wasm_sat_float_to_int", Target::WasmSatFloatToInt},
{"wasm_mvponly", Target::WasmMvpOnly},
{"wasm_threads", Target::WasmThreads},
{"wasm_bulk_memory", Target::WasmBulkMemory},
{"webgpu", Target::WebGPU},
Expand Down
3 changes: 1 addition & 2 deletions src/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,8 @@ struct Target {
CheckUnsafePromises = halide_target_feature_check_unsafe_promises,
EmbedBitcode = halide_target_feature_embed_bitcode,
EnableLLVMLoopOpt = halide_target_feature_enable_llvm_loop_opt,
WasmMvpOnly = halide_target_feature_wasm_mvponly,
WasmSimd128 = halide_target_feature_wasm_simd128,
WasmSignExt = halide_target_feature_wasm_signext,
WasmSatFloatToInt = halide_target_feature_wasm_sat_float_to_int,
WasmThreads = halide_target_feature_wasm_threads,
WasmBulkMemory = halide_target_feature_wasm_bulk_memory,
WebGPU = halide_target_feature_webgpu,
Expand Down
6 changes: 2 additions & 4 deletions src/WasmExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1308,15 +1308,13 @@ wabt::interp::HostFunc::Ptr make_extern_callback(wabt::interp::Store &store,

wabt::Features calc_features(const Target &target) {
wabt::Features f;
if (target.has_feature(Target::WasmSignExt)) {
if (!target.has_feature(Target::WasmMvpOnly)) {
f.enable_sign_extension();
f.enable_sat_float_to_int();
}
if (target.has_feature(Target::WasmSimd128)) {
f.enable_simd();
}
if (target.has_feature(Target::WasmSatFloatToInt)) {
f.enable_sat_float_to_int();
}
return f;
}
#endif // WITH_WABT
Expand Down
3 changes: 1 addition & 2 deletions src/runtime/HalideRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -1386,9 +1386,8 @@ typedef enum halide_target_feature_t {
halide_target_feature_hexagon_dma, ///< Enable Hexagon DMA buffers.
halide_target_feature_embed_bitcode, ///< Emulate clang -fembed-bitcode flag.
halide_target_feature_enable_llvm_loop_opt, ///< Enable loop vectorization + unrolling in LLVM. Overrides halide_target_feature_disable_llvm_loop_opt. (Ignored for non-LLVM targets.)
halide_target_feature_wasm_mvponly, ///< Disable all extensions to WebAssembly codegen (including +sign-ext and +nontrapping-fptoint, which are on by default).
halide_target_feature_wasm_simd128, ///< Enable +simd128 instructions for WebAssembly codegen.
halide_target_feature_wasm_signext, ///< Enable +sign-ext instructions for WebAssembly codegen.
halide_target_feature_wasm_sat_float_to_int, ///< Enable saturating (nontrapping) float-to-int instructions for WebAssembly codegen.
halide_target_feature_wasm_threads, ///< Enable use of threads in WebAssembly codegen. Requires the use of a wasm runtime that provides pthread-compatible wrappers (typically, Emscripten with the -pthreads flag). Unsupported under WASI.
halide_target_feature_wasm_bulk_memory, ///< Enable +bulk-memory instructions for WebAssembly codegen.
halide_target_feature_webgpu, ///< Enable the WebGPU runtime.
Expand Down
4 changes: 2 additions & 2 deletions test/correctness/simd_op_check_wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ class SimdOpCheckWASM : public SimdOpCheckTest {
SimdOpCheckWASM(Target t, int w = 768, int h = 128)
: SimdOpCheckTest(t, w, h) {
use_wasm_simd128 = target.has_feature(Target::WasmSimd128);
use_wasm_sat_float_to_int = target.has_feature(Target::WasmSatFloatToInt);
use_wasm_sign_ext = target.has_feature(Target::WasmSignExt);
use_wasm_sign_ext = !target.has_feature(Target::WasmMvpOnly);
use_wasm_sat_float_to_int = !target.has_feature(Target::WasmMvpOnly);
}

void add_tests() override {
Expand Down

0 comments on commit 52460eb

Please sign in to comment.