summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/fuzzing/fuzzing.cpp247
-rw-r--r--src/tools/tool-options.h1
-rw-r--r--src/wasm-binary.h1
-rw-r--r--src/wasm-features.h7
-rw-r--r--src/wasm/wasm-binary.cpp4
-rw-r--r--src/wasm/wasm-validator.cpp42
-rw-r--r--src/wasm/wasm.cpp1
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt2
-rw-r--r--test/example/c-api-kitchen-sink.txt2
-rw-r--r--test/lit/help/wasm-as.test4
-rw-r--r--test/lit/help/wasm-ctor-eval.test4
-rw-r--r--test/lit/help/wasm-dis.test4
-rw-r--r--test/lit/help/wasm-emscripten-finalize.test4
-rw-r--r--test/lit/help/wasm-merge.test4
-rw-r--r--test/lit/help/wasm-metadce.test4
-rw-r--r--test/lit/help/wasm-opt.test4
-rw-r--r--test/lit/help/wasm-reduce.test4
-rw-r--r--test/lit/help/wasm-split.test4
-rw-r--r--test/lit/help/wasm2js.test4
-rw-r--r--test/lit/validation/fp16.wast11
-rw-r--r--test/passes/strip-target-features_roundtrip_print-features_all-features.txt1
-rw-r--r--test/unit/test_features.py1
22 files changed, 226 insertions, 134 deletions
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index a143d2ff2..7a3007e43 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -3271,116 +3271,119 @@ Expression* TranslateToFuzzReader::makeBinary(Type type) {
}
case Type::v128: {
assert(wasm.features.hasSIMD());
- return buildBinary({pick(EqVecI8x16,
- NeVecI8x16,
- LtSVecI8x16,
- LtUVecI8x16,
- GtSVecI8x16,
- GtUVecI8x16,
- LeSVecI8x16,
- LeUVecI8x16,
- GeSVecI8x16,
- GeUVecI8x16,
- EqVecI16x8,
- NeVecI16x8,
- LtSVecI16x8,
- LtUVecI16x8,
- GtSVecI16x8,
- GtUVecI16x8,
- LeSVecI16x8,
- LeUVecI16x8,
- GeSVecI16x8,
- GeUVecI16x8,
- EqVecI32x4,
- NeVecI32x4,
- LtSVecI32x4,
- LtUVecI32x4,
- GtSVecI32x4,
- GtUVecI32x4,
- LeSVecI32x4,
- LeUVecI32x4,
- GeSVecI32x4,
- GeUVecI32x4,
- EqVecF16x8,
- EqVecF16x8,
- NeVecF16x8,
- LtVecF16x8,
- GtVecF16x8,
- LeVecF16x8,
- GeVecF16x8,
- EqVecF32x4,
- NeVecF32x4,
- LtVecF32x4,
- GtVecF32x4,
- LeVecF32x4,
- GeVecF32x4,
- EqVecF64x2,
- NeVecF64x2,
- LtVecF64x2,
- GtVecF64x2,
- LeVecF64x2,
- GeVecF64x2,
- AndVec128,
- OrVec128,
- XorVec128,
- AndNotVec128,
- AddVecI8x16,
- AddSatSVecI8x16,
- AddSatUVecI8x16,
- SubVecI8x16,
- SubSatSVecI8x16,
- SubSatUVecI8x16,
- MinSVecI8x16,
- MinUVecI8x16,
- MaxSVecI8x16,
- MaxUVecI8x16,
- // TODO: avgr_u
- // TODO: q15mulr_sat_s
- // TODO: extmul
- AddVecI16x8,
- AddSatSVecI16x8,
- AddSatUVecI16x8,
- SubVecI16x8,
- SubSatSVecI16x8,
- SubSatUVecI16x8,
- MulVecI16x8,
- MinSVecI16x8,
- MinUVecI16x8,
- MaxSVecI16x8,
- MaxUVecI16x8,
- AddVecI32x4,
- SubVecI32x4,
- MulVecI32x4,
- MinSVecI32x4,
- MinUVecI32x4,
- MaxSVecI32x4,
- MaxUVecI32x4,
- DotSVecI16x8ToVecI32x4,
- AddVecI64x2,
- SubVecI64x2,
- AddVecF16x8,
- SubVecF16x8,
- MulVecF16x8,
- DivVecF16x8,
- MinVecF16x8,
- MaxVecF16x8,
- AddVecF32x4,
- SubVecF32x4,
- MulVecF32x4,
- DivVecF32x4,
- MinVecF32x4,
- MaxVecF32x4,
- AddVecF64x2,
- SubVecF64x2,
- MulVecF64x2,
- DivVecF64x2,
- MinVecF64x2,
- MaxVecF64x2,
- NarrowSVecI16x8ToVecI8x16,
- NarrowUVecI16x8ToVecI8x16,
- NarrowSVecI32x4ToVecI16x8,
- NarrowUVecI32x4ToVecI16x8,
- SwizzleVecI8x16),
+ return buildBinary({pick(FeatureOptions<BinaryOp>()
+ .add(FeatureSet::SIMD,
+ EqVecI8x16,
+ NeVecI8x16,
+ LtSVecI8x16,
+ LtUVecI8x16,
+ GtSVecI8x16,
+ GtUVecI8x16,
+ LeSVecI8x16,
+ LeUVecI8x16,
+ GeSVecI8x16,
+ GeUVecI8x16,
+ EqVecI16x8,
+ NeVecI16x8,
+ LtSVecI16x8,
+ LtUVecI16x8,
+ GtSVecI16x8,
+ GtUVecI16x8,
+ LeSVecI16x8,
+ LeUVecI16x8,
+ GeSVecI16x8,
+ GeUVecI16x8,
+ EqVecI32x4,
+ NeVecI32x4,
+ LtSVecI32x4,
+ LtUVecI32x4,
+ GtSVecI32x4,
+ GtUVecI32x4,
+ LeSVecI32x4,
+ LeUVecI32x4,
+ GeSVecI32x4,
+ GeUVecI32x4,
+ EqVecF32x4,
+ NeVecF32x4,
+ LtVecF32x4,
+ GtVecF32x4,
+ LeVecF32x4,
+ GeVecF32x4,
+ EqVecF64x2,
+ NeVecF64x2,
+ LtVecF64x2,
+ GtVecF64x2,
+ LeVecF64x2,
+ GeVecF64x2,
+ AndVec128,
+ OrVec128,
+ XorVec128,
+ AndNotVec128,
+ AddVecI8x16,
+ AddSatSVecI8x16,
+ AddSatUVecI8x16,
+ SubVecI8x16,
+ SubSatSVecI8x16,
+ SubSatUVecI8x16,
+ MinSVecI8x16,
+ MinUVecI8x16,
+ MaxSVecI8x16,
+ MaxUVecI8x16,
+ // TODO: avgr_u
+ // TODO: q15mulr_sat_s
+ // TODO: extmul
+ AddVecI16x8,
+ AddSatSVecI16x8,
+ AddSatUVecI16x8,
+ SubVecI16x8,
+ SubSatSVecI16x8,
+ SubSatUVecI16x8,
+ MulVecI16x8,
+ MinSVecI16x8,
+ MinUVecI16x8,
+ MaxSVecI16x8,
+ MaxUVecI16x8,
+ AddVecI32x4,
+ SubVecI32x4,
+ MulVecI32x4,
+ MinSVecI32x4,
+ MinUVecI32x4,
+ MaxSVecI32x4,
+ MaxUVecI32x4,
+ DotSVecI16x8ToVecI32x4,
+ AddVecI64x2,
+ SubVecI64x2,
+ AddVecF32x4,
+ SubVecF32x4,
+ MulVecF32x4,
+ DivVecF32x4,
+ MinVecF32x4,
+ MaxVecF32x4,
+ AddVecF64x2,
+ SubVecF64x2,
+ MulVecF64x2,
+ DivVecF64x2,
+ MinVecF64x2,
+ MaxVecF64x2,
+ NarrowSVecI16x8ToVecI8x16,
+ NarrowUVecI16x8ToVecI8x16,
+ NarrowSVecI32x4ToVecI16x8,
+ NarrowUVecI32x4ToVecI16x8,
+ SwizzleVecI8x16)
+ .add(FeatureSet::FP16,
+ EqVecF16x8,
+ EqVecF16x8,
+ NeVecF16x8,
+ LtVecF16x8,
+ GtVecF16x8,
+ LeVecF16x8,
+ GeVecF16x8,
+ AddVecF16x8,
+ SubVecF16x8,
+ MulVecF16x8,
+ DivVecF16x8,
+ MinVecF16x8,
+ MaxVecF16x8)),
make(Type::v128),
make(Type::v128)});
}
@@ -3586,7 +3589,9 @@ Expression* TranslateToFuzzReader::makeSIMDExtract(Type type) {
op = ExtractLaneVecI64x2;
break;
case Type::f32:
- op = ExtractLaneVecF32x4;
+ op = pick(FeatureOptions<SIMDExtractOp>()
+ .add(FeatureSet::SIMD, ExtractLaneVecF32x4)
+ .add(FeatureSet::FP16, ExtractLaneVecF16x8));
break;
case Type::f64:
op = ExtractLaneVecF64x2;
@@ -3621,12 +3626,16 @@ Expression* TranslateToFuzzReader::makeSIMDExtract(Type type) {
}
Expression* TranslateToFuzzReader::makeSIMDReplace() {
- SIMDReplaceOp op = pick(ReplaceLaneVecI8x16,
- ReplaceLaneVecI16x8,
- ReplaceLaneVecI32x4,
- ReplaceLaneVecI64x2,
- ReplaceLaneVecF32x4,
- ReplaceLaneVecF64x2);
+ SIMDReplaceOp op =
+ pick(FeatureOptions<SIMDReplaceOp>()
+ .add(FeatureSet::SIMD,
+ ReplaceLaneVecI8x16,
+ ReplaceLaneVecI16x8,
+ ReplaceLaneVecI32x4,
+ ReplaceLaneVecI64x2,
+ ReplaceLaneVecF32x4,
+ ReplaceLaneVecF64x2)
+ .add(FeatureSet::FeatureSet::FP16, ReplaceLaneVecF16x8));
Expression* vec = make(Type::v128);
uint8_t index;
Type lane_t;
@@ -3647,6 +3656,10 @@ Expression* TranslateToFuzzReader::makeSIMDReplace() {
index = upTo(2);
lane_t = Type::i64;
break;
+ case ReplaceLaneVecF16x8:
+ index = upTo(8);
+ lane_t = Type::f32;
+ break;
case ReplaceLaneVecF32x4:
index = upTo(4);
lane_t = Type::f32;
diff --git a/src/tools/tool-options.h b/src/tools/tool-options.h
index c9d891a00..bfa9a9b5c 100644
--- a/src/tools/tool-options.h
+++ b/src/tools/tool-options.h
@@ -95,6 +95,7 @@ struct ToolOptions : public Options {
.addFeature(FeatureSet::MultiMemory, "multimemory")
.addFeature(FeatureSet::TypedContinuations, "typed continuations")
.addFeature(FeatureSet::SharedEverything, "shared-everything threads")
+ .addFeature(FeatureSet::FP16, "float 16 operations")
.add("--enable-typed-function-references",
"",
"Deprecated compatibility flag",
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 1fbe7535c..a4439f026 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -436,6 +436,7 @@ extern const char* StringsFeature;
extern const char* MultiMemoryFeature;
extern const char* TypedContinuationsFeature;
extern const char* SharedEverythingFeature;
+extern const char* FP16Feature;
enum Subsection {
NameModule = 0,
diff --git a/src/wasm-features.h b/src/wasm-features.h
index 366b75200..92b07b547 100644
--- a/src/wasm-features.h
+++ b/src/wasm-features.h
@@ -46,11 +46,12 @@ struct FeatureSet {
MultiMemory = 1 << 15,
TypedContinuations = 1 << 16,
SharedEverything = 1 << 17,
+ FP16 = 1 << 18,
MVP = None,
// Keep in sync with llvm default features:
// https://github.com/llvm/llvm-project/blob/c7576cb89d6c95f03968076e902d3adfd1996577/clang/lib/Basic/Targets/WebAssembly.cpp#L150-L153
Default = SignExt | MutableGlobals,
- All = (1 << 18) - 1,
+ All = (1 << 19) - 1,
};
static std::string toString(Feature f) {
@@ -91,6 +92,8 @@ struct FeatureSet {
return "typed-continuations";
case SharedEverything:
return "shared-everything";
+ case FP16:
+ return "fp16";
default:
WASM_UNREACHABLE("unexpected feature");
}
@@ -141,6 +144,7 @@ struct FeatureSet {
bool hasSharedEverything() const {
return (features & SharedEverything) != 0;
}
+ bool hasFP16() const { return (features & FP16) != 0; }
bool hasAll() const { return (features & All) != 0; }
void set(FeatureSet f, bool v = true) {
@@ -164,6 +168,7 @@ struct FeatureSet {
void setMultiMemory(bool v = true) { set(MultiMemory, v); }
void setTypedContinuations(bool v = true) { set(TypedContinuations, v); }
void setSharedEverything(bool v = true) { set(SharedEverything, v); }
+ void setFP16(bool v = true) { set(FP16, v); }
void setMVP() { features = MVP; }
void setAll() { features = All; }
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index e84639801..06d17fdfb 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1358,6 +1358,8 @@ void WasmBinaryWriter::writeFeaturesSection() {
return BinaryConsts::CustomSections::TypedContinuationsFeature;
case FeatureSet::SharedEverything:
return BinaryConsts::CustomSections::SharedEverythingFeature;
+ case FeatureSet::FP16:
+ return BinaryConsts::CustomSections::FP16Feature;
case FeatureSet::None:
case FeatureSet::Default:
case FeatureSet::All:
@@ -3892,6 +3894,8 @@ void WasmBinaryReader::readFeatures(size_t payloadLen) {
feature = FeatureSet::TypedContinuations;
} else if (name == BinaryConsts::CustomSections::SharedEverythingFeature) {
feature = FeatureSet::SharedEverything;
+ } else if (name == BinaryConsts::CustomSections::FP16Feature) {
+ feature = FeatureSet::FP16;
} else {
// Silently ignore unknown features (this may be and old binaryen running
// on a new wasm).
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 24f5379fb..4881ea7ac 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1274,6 +1274,9 @@ void FunctionValidator::visitSIMDExtract(SIMDExtract* curr) {
lanes = 2;
break;
case ExtractLaneVecF16x8:
+ shouldBeTrue(getModule()->features.hasFP16(),
+ curr,
+ "FP16 operations require FP16 [--enable-fp16]");
lane_t = Type::f32;
lanes = 8;
break;
@@ -1324,6 +1327,9 @@ void FunctionValidator::visitSIMDReplace(SIMDReplace* curr) {
lanes = 2;
break;
case ReplaceLaneVecF16x8:
+ shouldBeTrue(getModule()->features.hasFP16(),
+ curr,
+ "FP16 operations require FP16 [--enable-fp16]");
lane_t = Type::f32;
lanes = 8;
break;
@@ -1708,6 +1714,24 @@ void FunctionValidator::visitBinary(Binary* curr) {
curr->left->type, Type(Type::f64), curr, "f64 op");
break;
}
+ case EqVecF16x8:
+ case NeVecF16x8:
+ case LtVecF16x8:
+ case LeVecF16x8:
+ case GtVecF16x8:
+ case GeVecF16x8:
+ case AddVecF16x8:
+ case SubVecF16x8:
+ case MulVecF16x8:
+ case DivVecF16x8:
+ case MinVecF16x8:
+ case MaxVecF16x8:
+ case PMinVecF16x8:
+ case PMaxVecF16x8:
+ shouldBeTrue(getModule()->features.hasFP16(),
+ curr,
+ "FP16 operations require FP16 [--enable-fp16]");
+ [[fallthrough]];
case EqVecI8x16:
case NeVecI8x16:
case LtSVecI8x16:
@@ -1744,12 +1768,6 @@ void FunctionValidator::visitBinary(Binary* curr) {
case LeSVecI64x2:
case GtSVecI64x2:
case GeSVecI64x2:
- case EqVecF16x8:
- case NeVecF16x8:
- case LtVecF16x8:
- case LeVecF16x8:
- case GtVecF16x8:
- case GeVecF16x8:
case EqVecF32x4:
case NeVecF32x4:
case LtVecF32x4:
@@ -1813,14 +1831,6 @@ void FunctionValidator::visitBinary(Binary* curr) {
case ExtMulHighSVecI64x2:
case ExtMulLowUVecI64x2:
case ExtMulHighUVecI64x2:
- case AddVecF16x8:
- case SubVecF16x8:
- case MulVecF16x8:
- case DivVecF16x8:
- case MinVecF16x8:
- case MaxVecF16x8:
- case PMinVecF16x8:
- case PMaxVecF16x8:
case AddVecF32x4:
case SubVecF32x4:
case MulVecF32x4:
@@ -2060,6 +2070,10 @@ void FunctionValidator::visitUnary(Unary* curr) {
curr->value->type, Type(Type::i64), curr, "expected i64 splat value");
break;
case SplatVecF16x8:
+ shouldBeTrue(getModule()->features.hasFP16(),
+ curr,
+ "FP16 operations require FP16 [--enable-fp16]");
+ [[fallthrough]];
case SplatVecF32x4:
shouldBeEqual(
curr->type, Type(Type::v128), curr, "expected splat to have v128 type");
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index ff641c7eb..e768f0dc4 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -56,6 +56,7 @@ const char* StringsFeature = "strings";
const char* MultiMemoryFeature = "multimemory";
const char* TypedContinuationsFeature = "typed-continuations";
const char* SharedEverythingFeature = "shared-everything";
+const char* FP16Feature = "fp16";
} // namespace CustomSections
} // namespace BinaryConsts
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index 212194c9c..d41301751 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -33,7 +33,7 @@ Features.RelaxedSIMD: 4096
Features.ExtendedConst: 8192
Features.Strings: 16384
Features.MultiMemory: 32768
-Features.All: 262143
+Features.All: 524287
InvalidId: 0
BlockId: 1
IfId: 2
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index e568cfba0..17344ccab 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -47,7 +47,7 @@ BinaryenFeatureMemory64: 2048
BinaryenFeatureRelaxedSIMD: 4096
BinaryenFeatureExtendedConst: 8192
BinaryenFeatureStrings: 16384
-BinaryenFeatureAll: 262143
+BinaryenFeatureAll: 524287
(f32.neg
(f32.const -33.61199951171875)
)
diff --git a/test/lit/help/wasm-as.test b/test/lit/help/wasm-as.test
index 3a863dbd6..a2ee3d45e 100644
--- a/test/lit/help/wasm-as.test
+++ b/test/lit/help/wasm-as.test
@@ -112,6 +112,10 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads
;; CHECK-NEXT:
+;; CHECK-NEXT: --enable-fp16 Enable float 16 operations
+;; CHECK-NEXT:
+;; CHECK-NEXT: --disable-fp16 Disable float 16 operations
+;; CHECK-NEXT:
;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag
diff --git a/test/lit/help/wasm-ctor-eval.test b/test/lit/help/wasm-ctor-eval.test
index 2d57e3e8c..4ad75a8d0 100644
--- a/test/lit/help/wasm-ctor-eval.test
+++ b/test/lit/help/wasm-ctor-eval.test
@@ -119,6 +119,10 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads
;; CHECK-NEXT:
+;; CHECK-NEXT: --enable-fp16 Enable float 16 operations
+;; CHECK-NEXT:
+;; CHECK-NEXT: --disable-fp16 Disable float 16 operations
+;; CHECK-NEXT:
;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag
diff --git a/test/lit/help/wasm-dis.test b/test/lit/help/wasm-dis.test
index 63c7f8bd0..96e999c2c 100644
--- a/test/lit/help/wasm-dis.test
+++ b/test/lit/help/wasm-dis.test
@@ -105,6 +105,10 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads
;; CHECK-NEXT:
+;; CHECK-NEXT: --enable-fp16 Enable float 16 operations
+;; CHECK-NEXT:
+;; CHECK-NEXT: --disable-fp16 Disable float 16 operations
+;; CHECK-NEXT:
;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag
diff --git a/test/lit/help/wasm-emscripten-finalize.test b/test/lit/help/wasm-emscripten-finalize.test
index c92960dfb..fbf86209c 100644
--- a/test/lit/help/wasm-emscripten-finalize.test
+++ b/test/lit/help/wasm-emscripten-finalize.test
@@ -147,6 +147,10 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads
;; CHECK-NEXT:
+;; CHECK-NEXT: --enable-fp16 Enable float 16 operations
+;; CHECK-NEXT:
+;; CHECK-NEXT: --disable-fp16 Disable float 16 operations
+;; CHECK-NEXT:
;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag
diff --git a/test/lit/help/wasm-merge.test b/test/lit/help/wasm-merge.test
index fe3f1cdb2..108fd3673 100644
--- a/test/lit/help/wasm-merge.test
+++ b/test/lit/help/wasm-merge.test
@@ -135,6 +135,10 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads
;; CHECK-NEXT:
+;; CHECK-NEXT: --enable-fp16 Enable float 16 operations
+;; CHECK-NEXT:
+;; CHECK-NEXT: --disable-fp16 Disable float 16 operations
+;; CHECK-NEXT:
;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag
diff --git a/test/lit/help/wasm-metadce.test b/test/lit/help/wasm-metadce.test
index e25a0214d..665d78746 100644
--- a/test/lit/help/wasm-metadce.test
+++ b/test/lit/help/wasm-metadce.test
@@ -734,6 +734,10 @@
;; CHECK-NEXT: --disable-shared-everything Disable shared-everything
;; CHECK-NEXT: threads
;; CHECK-NEXT:
+;; CHECK-NEXT: --enable-fp16 Enable float 16 operations
+;; CHECK-NEXT:
+;; CHECK-NEXT: --disable-fp16 Disable float 16 operations
+;; CHECK-NEXT:
;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag
diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test
index 3a577099b..4eea3c431 100644
--- a/test/lit/help/wasm-opt.test
+++ b/test/lit/help/wasm-opt.test
@@ -743,6 +743,10 @@
;; CHECK-NEXT: --disable-shared-everything Disable shared-everything
;; CHECK-NEXT: threads
;; CHECK-NEXT:
+;; CHECK-NEXT: --enable-fp16 Enable float 16 operations
+;; CHECK-NEXT:
+;; CHECK-NEXT: --disable-fp16 Disable float 16 operations
+;; CHECK-NEXT:
;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag
diff --git a/test/lit/help/wasm-reduce.test b/test/lit/help/wasm-reduce.test
index cacf260fa..61e171ba9 100644
--- a/test/lit/help/wasm-reduce.test
+++ b/test/lit/help/wasm-reduce.test
@@ -141,6 +141,10 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads
;; CHECK-NEXT:
+;; CHECK-NEXT: --enable-fp16 Enable float 16 operations
+;; CHECK-NEXT:
+;; CHECK-NEXT: --disable-fp16 Disable float 16 operations
+;; CHECK-NEXT:
;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag
diff --git a/test/lit/help/wasm-split.test b/test/lit/help/wasm-split.test
index bc09796d7..a6074c85d 100644
--- a/test/lit/help/wasm-split.test
+++ b/test/lit/help/wasm-split.test
@@ -222,6 +222,10 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-shared-everything Disable shared-everything threads
;; CHECK-NEXT:
+;; CHECK-NEXT: --enable-fp16 Enable float 16 operations
+;; CHECK-NEXT:
+;; CHECK-NEXT: --disable-fp16 Disable float 16 operations
+;; CHECK-NEXT:
;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag
diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test
index 3c0a17e7a..501d1d3f1 100644
--- a/test/lit/help/wasm2js.test
+++ b/test/lit/help/wasm2js.test
@@ -697,6 +697,10 @@
;; CHECK-NEXT: --disable-shared-everything Disable shared-everything
;; CHECK-NEXT: threads
;; CHECK-NEXT:
+;; CHECK-NEXT: --enable-fp16 Enable float 16 operations
+;; CHECK-NEXT:
+;; CHECK-NEXT: --disable-fp16 Disable float 16 operations
+;; CHECK-NEXT:
;; CHECK-NEXT: --enable-typed-function-references Deprecated compatibility flag
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-typed-function-references Deprecated compatibility flag
diff --git a/test/lit/validation/fp16.wast b/test/lit/validation/fp16.wast
new file mode 100644
index 000000000..b1c8ce9c2
--- /dev/null
+++ b/test/lit/validation/fp16.wast
@@ -0,0 +1,11 @@
+;; Test that fp16 operations require the fp16 feature.
+
+;; RUN: not wasm-opt %s --enable-simd 2>&1 | filecheck %s --check-prefix NO-FP16
+;; RUN: wasm-opt %s --enable-simd --enable-fp16 -o - -S | filecheck %s --check-prefix FP16
+
+;; NO-FP16: FP16 operations require FP16 [--enable-fp16]
+;; FP16: (type $0 (func (param v128 v128) (result v128)))
+
+(module
+ (func (export "f16x8.add") (param $0 v128) (param $1 v128) (result v128) (f16x8.add (local.get $0) (local.get $1)))
+)
diff --git a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
index 2c6523e6d..901f43bc5 100644
--- a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
+++ b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
@@ -16,6 +16,7 @@
--enable-multimemory
--enable-typed-continuations
--enable-shared-everything
+--enable-fp16
(module
(type $0 (func (result v128 externref)))
(func $foo (type $0) (result v128 externref)
diff --git a/test/unit/test_features.py b/test/unit/test_features.py
index 3bd9ac127..f5c3fabc5 100644
--- a/test/unit/test_features.py
+++ b/test/unit/test_features.py
@@ -426,4 +426,5 @@ class TargetFeaturesSectionTest(utils.BinaryenTestCase):
'--enable-multimemory',
'--enable-typed-continuations',
'--enable-shared-everything',
+ '--enable-fp16',
], p2.stdout.splitlines())