diff --git a/README_webassembly.md b/README_webassembly.md index f5fad7d79995..0fdcf80f15f1 100644 --- a/README_webassembly.md +++ b/README_webassembly.md @@ -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 @@ -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 @@ -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 diff --git a/python_bindings/src/halide/halide_/PyEnums.cpp b/python_bindings/src/halide/halide_/PyEnums.cpp index 1913b204fbd4..f86e7072edd5 100644 --- a/python_bindings/src/halide/halide_/PyEnums.cpp +++ b/python_bindings/src/halide/halide_/PyEnums.cpp @@ -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) diff --git a/src/CodeGen_WebAssembly.cpp b/src/CodeGen_WebAssembly.cpp index 948346ad7c2a..3e9aedca3fbf 100644 --- a/src/CodeGen_WebAssembly.cpp +++ b/src/CodeGen_WebAssembly.cpp @@ -333,9 +333,10 @@ 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)) { @@ -343,11 +344,6 @@ string CodeGen_WebAssembly::mattrs() const { 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. diff --git a/src/Target.cpp b/src/Target.cpp index 597d5bf5367d..e222e97d5282 100644 --- a/src/Target.cpp +++ b/src/Target.cpp @@ -533,8 +533,7 @@ const std::map 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}, diff --git a/src/Target.h b/src/Target.h index 76b06aed6b8e..331694e34c3a 100644 --- a/src/Target.h +++ b/src/Target.h @@ -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, diff --git a/src/WasmExecutor.cpp b/src/WasmExecutor.cpp index d82932bd3ea0..b99efdc6d67e 100644 --- a/src/WasmExecutor.cpp +++ b/src/WasmExecutor.cpp @@ -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 diff --git a/src/runtime/HalideRuntime.h b/src/runtime/HalideRuntime.h index 445811009abd..f50e498ce88e 100644 --- a/src/runtime/HalideRuntime.h +++ b/src/runtime/HalideRuntime.h @@ -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. diff --git a/test/correctness/simd_op_check_wasm.cpp b/test/correctness/simd_op_check_wasm.cpp index 87f3a0263047..6b6898c82b85 100644 --- a/test/correctness/simd_op_check_wasm.cpp +++ b/test/correctness/simd_op_check_wasm.cpp @@ -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 { @@ -544,6 +544,7 @@ int main(int argc, char **argv) { argc, argv, { Target("wasm-32-wasmrt"), - Target("wasm-32-wasmrt-wasm_simd128-wasm_sat_float_to_int"), + Target("wasm-32-wasmrt-wasm_simd128"), + Target("wasm-32-wasmrt-wasm_mvponly"), }); }