diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index ca550d7225a..0a6d205ee63 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -31,6 +31,7 @@ #include "ir/stack-utils.h" #include "ir/utils.h" #include "support/colors.h" +#include "wasm-features.h" #include "wasm-type.h" #include "wasm-validator.h" #include "wasm.h" @@ -1500,9 +1501,31 @@ void FunctionValidator::visitSIMDShuffle(SIMDShuffle* curr) { } void FunctionValidator::visitSIMDTernary(SIMDTernary* curr) { - shouldBeTrue(getModule()->features.hasSIMD(), - curr, - "SIMD operations require SIMD [--enable-simd]"); + FeatureSet required = FeatureSet::None; + switch (curr->op) { + case RelaxedMaddVecF16x8: + case RelaxedNmaddVecF16x8: + required |= FeatureSet::FP16; + [[fallthrough]]; + case LaneselectI8x16: + case LaneselectI16x8: + case LaneselectI32x4: + case LaneselectI64x2: + case RelaxedMaddVecF32x4: + case RelaxedNmaddVecF32x4: + case RelaxedMaddVecF64x2: + case RelaxedNmaddVecF64x2: + case DotI8x16I7x16AddSToVecI32x4: + required |= FeatureSet::RelaxedSIMD; + [[fallthrough]]; + case Bitselect: + required |= FeatureSet::SIMD; + } + if (!shouldBeTrue(required <= getModule()->features, + curr, + "SIMD ternary operation requires additional features")) { + getStream() << getMissingFeaturesList(*getModule(), required) << '\n'; + } shouldBeEqualOrFirstIsUnreachable( curr->type, Type(Type::v128), curr, "SIMD ternary must have type v128"); shouldBeEqualOrFirstIsUnreachable( diff --git a/test/lit/validation/simd-ternary.wast b/test/lit/validation/simd-ternary.wast new file mode 100644 index 00000000000..31e3abced20 --- /dev/null +++ b/test/lit/validation/simd-ternary.wast @@ -0,0 +1,10 @@ +;; RUN: not wasm-opt --enable-simd %s 2>&1 | filecheck %s + +;; CHECK: SIMD ternary operation requires additional features, on +;; CHECK: [--enable-relaxed-simd --enable-fp16] + +(module + (func $fp16 (param v128 v128 v128) + (f16x8.relaxed_madd (local.get 0) (local.get 1) (local.get 2)) + ) +)