diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2021-01-05 19:27:53 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-05 16:27:53 -0800 |
commit | b79661ee03fc74b3f860bf04e6f1019f7b11c722 (patch) | |
tree | 5f25958499f95e219fadc8d4cc2e2b0801bddf6b /src | |
parent | 3e5ce644e0336bc7ce82a5f6df6b1f671097556d (diff) | |
download | binaryen-b79661ee03fc74b3f860bf04e6f1019f7b11c722.tar.gz binaryen-b79661ee03fc74b3f860bf04e6f1019f7b11c722.tar.bz2 binaryen-b79661ee03fc74b3f860bf04e6f1019f7b11c722.zip |
Prototype SIMD extending pairwise add instructions (#3466)
As proposed in https://github.com/WebAssembly/simd/pull/380, using the opcodes
used in LLVM and V8. Since these opcodes overlap with the opcodes of
i64x2.all_true and i64x2.any_true, which have long since been removed from the
SIMD proposal, this PR also removes those instructions.
Diffstat (limited to 'src')
-rw-r--r-- | src/binaryen-c.cpp | 2 | ||||
-rw-r--r-- | src/binaryen-c.h | 3 | ||||
-rw-r--r-- | src/gen-s-parser.inc | 43 | ||||
-rw-r--r-- | src/ir/cost.h | 6 | ||||
-rw-r--r-- | src/ir/features.h | 2 | ||||
-rw-r--r-- | src/js/binaryen.js-post.js | 8 | ||||
-rw-r--r-- | src/literal.h | 2 | ||||
-rw-r--r-- | src/passes/Print.cpp | 18 | ||||
-rw-r--r-- | src/tools/fuzzing.h | 4 | ||||
-rw-r--r-- | src/wasm-binary.h | 7 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 12 | ||||
-rw-r--r-- | src/wasm.h | 6 | ||||
-rw-r--r-- | src/wasm/literal.cpp | 6 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 24 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 24 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 6 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 6 |
17 files changed, 102 insertions, 77 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index b6e14d694..59ca3aebc 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -580,8 +580,6 @@ BinaryenOp BinaryenDotSVecI16x8ToVecI32x4(void) { return DotSVecI16x8ToVecI32x4; } BinaryenOp BinaryenNegVecI64x2(void) { return NegVecI64x2; } -BinaryenOp BinaryenAnyTrueVecI64x2(void) { return AnyTrueVecI64x2; } -BinaryenOp BinaryenAllTrueVecI64x2(void) { return AllTrueVecI64x2; } BinaryenOp BinaryenShlVecI64x2(void) { return ShlVecI64x2; } BinaryenOp BinaryenShrSVecI64x2(void) { return ShrSVecI64x2; } BinaryenOp BinaryenShrUVecI64x2(void) { return ShrUVecI64x2; } diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 33ada13b1..a32d9ff1c 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -486,8 +486,6 @@ BINARYEN_API BinaryenOp BinaryenMaxSVecI32x4(void); BINARYEN_API BinaryenOp BinaryenMaxUVecI32x4(void); BINARYEN_API BinaryenOp BinaryenDotSVecI16x8ToVecI32x4(void); BINARYEN_API BinaryenOp BinaryenNegVecI64x2(void); -BINARYEN_API BinaryenOp BinaryenAnyTrueVecI64x2(void); -BINARYEN_API BinaryenOp BinaryenAllTrueVecI64x2(void); BINARYEN_API BinaryenOp BinaryenShlVecI64x2(void); BINARYEN_API BinaryenOp BinaryenShrSVecI64x2(void); BINARYEN_API BinaryenOp BinaryenShrUVecI64x2(void); @@ -528,6 +526,7 @@ BINARYEN_API BinaryenOp BinaryenCeilVecF64x2(void); BINARYEN_API BinaryenOp BinaryenFloorVecF64x2(void); BINARYEN_API BinaryenOp BinaryenTruncVecF64x2(void); BINARYEN_API BinaryenOp BinaryenNearestVecF64x2(void); +// TODO: Add extending pairwise adds to C and JS APIs once merged BINARYEN_API BinaryenOp BinaryenTruncSatSVecF32x4ToVecI32x4(void); BINARYEN_API BinaryenOp BinaryenTruncSatUVecF32x4ToVecI32x4(void); BINARYEN_API BinaryenOp BinaryenTruncSatSVecF64x2ToVecI64x2(void); diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index d4e1afe38..c564f3974 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -4,8 +4,8 @@ #ifdef INSTRUCTION_PARSER #undef INSTRUCTION_PARSER -char op[28] = {'\0'}; -strncpy(op, s[0]->c_str(), 27); +char op[30] = {'\0'}; +strncpy(op, s[0]->c_str(), 29); switch (op[0]) { case 'a': { switch (op[1]) { @@ -800,6 +800,17 @@ switch (op[0]) { goto parse_error; case 'x': { switch (op[9]) { + case 'a': { + switch (op[28]) { + case 's': + if (strcmp(op, "i16x8.extadd_pairwise_i8x16_s") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseSVecI8x16ToI16x8); } + goto parse_error; + case 'u': + if (strcmp(op, "i16x8.extadd_pairwise_i8x16_u") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseUVecI8x16ToI16x8); } + goto parse_error; + default: goto parse_error; + } + } case 'm': { switch (op[13]) { case 'h': { @@ -1554,6 +1565,17 @@ switch (op[0]) { goto parse_error; case 'x': { switch (op[9]) { + case 'a': { + switch (op[28]) { + case 's': + if (strcmp(op, "i32x4.extadd_pairwise_i16x8_s") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseSVecI16x8ToI32x4); } + goto parse_error; + case 'u': + if (strcmp(op, "i32x4.extadd_pairwise_i16x8_u") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseUVecI16x8ToI32x4); } + goto parse_error; + default: goto parse_error; + } + } case 'm': { switch (op[13]) { case 'h': { @@ -2298,20 +2320,9 @@ switch (op[0]) { } case 'x': { switch (op[6]) { - case 'a': { - switch (op[7]) { - case 'd': - if (strcmp(op, "i64x2.add") == 0) { return makeBinary(s, BinaryOp::AddVecI64x2); } - goto parse_error; - case 'l': - if (strcmp(op, "i64x2.all_true") == 0) { return makeUnary(s, UnaryOp::AllTrueVecI64x2); } - goto parse_error; - case 'n': - if (strcmp(op, "i64x2.any_true") == 0) { return makeUnary(s, UnaryOp::AnyTrueVecI64x2); } - goto parse_error; - default: goto parse_error; - } - } + case 'a': + if (strcmp(op, "i64x2.add") == 0) { return makeBinary(s, BinaryOp::AddVecI64x2); } + goto parse_error; case 'b': if (strcmp(op, "i64x2.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI64x2); } goto parse_error; diff --git a/src/ir/cost.h b/src/ir/cost.h index c218cbaab..ef0a2bde1 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -189,8 +189,6 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> { case AllTrueVecI32x4: case BitmaskVecI32x4: case NegVecI64x2: - case AnyTrueVecI64x2: - case AllTrueVecI64x2: case BitmaskVecI64x2: case AbsVecF32x4: case NegVecF32x4: @@ -206,6 +204,10 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> { case FloorVecF64x2: case TruncVecF64x2: case NearestVecF64x2: + case ExtAddPairwiseSVecI8x16ToI16x8: + case ExtAddPairwiseUVecI8x16ToI16x8: + case ExtAddPairwiseSVecI16x8ToI32x4: + case ExtAddPairwiseUVecI16x8ToI32x4: case TruncSatSVecF32x4ToVecI32x4: case TruncSatUVecF32x4ToVecI32x4: case TruncSatSVecF64x2ToVecI64x2: diff --git a/src/ir/features.h b/src/ir/features.h index 6dff96398..aa87bd5bd 100644 --- a/src/ir/features.h +++ b/src/ir/features.h @@ -57,8 +57,6 @@ inline FeatureSet get(UnaryOp op) { case AnyTrueVecI32x4: case AllTrueVecI32x4: case NegVecI64x2: - case AnyTrueVecI64x2: - case AllTrueVecI64x2: case AbsVecF32x4: case NegVecF32x4: case SqrtVecF32x4: diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 128e148e2..6cdf26e32 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -416,8 +416,6 @@ function initializeConstants() { 'MaxSVecI32x4', 'MaxUVecI32x4', 'NegVecI64x2', - 'AnyTrueVecI64x2', - 'AllTrueVecI64x2', 'ShlVecI64x2', 'ShrSVecI64x2', 'ShrUVecI64x2', @@ -1828,12 +1826,6 @@ function wrapModule(module, self = {}) { 'neg'(value) { return Module['_BinaryenUnary'](module, Module['NegVecI64x2'], value); }, - 'any_true'(value) { - return Module['_BinaryenUnary'](module, Module['AnyTrueVecI64x2'], value); - }, - 'all_true'(value) { - return Module['_BinaryenUnary'](module, Module['AllTrueVecI64x2'], value); - }, 'shl'(vec, shift) { return Module['_BinaryenSIMDShift'](module, Module['ShlVecI64x2'], vec, shift); }, diff --git a/src/literal.h b/src/literal.h index bf8937533..5b590e07f 100644 --- a/src/literal.h +++ b/src/literal.h @@ -576,8 +576,6 @@ public: Literal extMulLowUI32x4(const Literal& other) const; Literal extMulHighUI32x4(const Literal& other) const; Literal negI64x2() const; - Literal anyTrueI64x2() const; - Literal allTrueI64x2() const; Literal shlI64x2(const Literal& other) const; Literal shrSI64x2(const Literal& other) const; Literal shrUI64x2(const Literal& other) const; diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index b921fb074..f9d469faf 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -957,12 +957,6 @@ struct PrintExpressionContents case NegVecI64x2: o << "i64x2.neg"; break; - case AnyTrueVecI64x2: - o << "i64x2.any_true"; - break; - case AllTrueVecI64x2: - o << "i64x2.all_true"; - break; case BitmaskVecI64x2: o << "i64x2.bitmask"; break; @@ -1008,6 +1002,18 @@ struct PrintExpressionContents case NearestVecF64x2: o << "f64x2.nearest"; break; + case ExtAddPairwiseSVecI8x16ToI16x8: + o << "i16x8.extadd_pairwise_i8x16_s"; + break; + case ExtAddPairwiseUVecI8x16ToI16x8: + o << "i16x8.extadd_pairwise_i8x16_u"; + break; + case ExtAddPairwiseSVecI16x8ToI32x4: + o << "i32x4.extadd_pairwise_i16x8_s"; + break; + case ExtAddPairwiseUVecI16x8ToI32x4: + o << "i32x4.extadd_pairwise_i16x8_u"; + break; case TruncSatSVecF32x4ToVecI32x4: o << "i32x4.trunc_sat_f32x4_s"; break; diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 7d9131767..09e83031d 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -2168,9 +2168,7 @@ private: AnyTrueVecI16x8, AllTrueVecI16x8, AnyTrueVecI32x4, - AllTrueVecI32x4, - AnyTrueVecI64x2, - AllTrueVecI64x2), + AllTrueVecI32x4), make(Type::v128)}); } case Type::funcref: diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 382bfbd4f..b2c922dc2 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -897,8 +897,6 @@ enum ASTNodes { I64x2WidenLowUI32x4 = 0xc9, I64x2WidenHighUI32x4 = 0xca, I64x2Neg = 0xc1, - I64x2AnyTrue = 0xc2, - I64x2AllTrue = 0xc3, I64x2Shl = 0xcb, I64x2ShrS = 0xcc, I64x2ShrU = 0xcd, @@ -939,6 +937,11 @@ enum ASTNodes { F64x2PMin = 0xf6, F64x2PMax = 0xf7, + I16x8ExtAddPairWiseSI8x16 = 0xc2, + I16x8ExtAddPairWiseUI8x16 = 0xc3, + I32x4ExtAddPairWiseSI16x8 = 0xa5, + I32x4ExtAddPairWiseUI16x8 = 0xa6, + I32x4TruncSatSF32x4 = 0xf8, I32x4TruncSatUF32x4 = 0xf9, F32x4ConvertSI32x4 = 0xfa, diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 019a56db1..3d963269d 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -488,10 +488,6 @@ public: return value.bitmaskI32x4(); case NegVecI64x2: return value.negI64x2(); - case AnyTrueVecI64x2: - return value.anyTrueI64x2(); - case AllTrueVecI64x2: - return value.allTrueI64x2(); case BitmaskVecI64x2: WASM_UNREACHABLE("unimp"); case AbsVecF32x4: @@ -522,6 +518,14 @@ public: return value.truncF64x2(); case NearestVecF64x2: return value.nearestF64x2(); + case ExtAddPairwiseSVecI8x16ToI16x8: + WASM_UNREACHABLE("unimp"); + case ExtAddPairwiseUVecI8x16ToI16x8: + WASM_UNREACHABLE("unimp"); + case ExtAddPairwiseSVecI16x8ToI32x4: + WASM_UNREACHABLE("unimp"); + case ExtAddPairwiseUVecI16x8ToI32x4: + WASM_UNREACHABLE("unimp"); case TruncSatSVecF32x4ToVecI32x4: return value.truncSatToSI32x4(); case TruncSatUVecF32x4ToVecI32x4: diff --git a/src/wasm.h b/src/wasm.h index 1d5642625..12aacd2ed 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -174,8 +174,6 @@ enum UnaryOp { AllTrueVecI32x4, BitmaskVecI32x4, NegVecI64x2, - AnyTrueVecI64x2, - AllTrueVecI64x2, BitmaskVecI64x2, AbsVecF32x4, NegVecF32x4, @@ -191,6 +189,10 @@ enum UnaryOp { FloorVecF64x2, TruncVecF64x2, NearestVecF64x2, + ExtAddPairwiseSVecI8x16ToI16x8, + ExtAddPairwiseUVecI8x16ToI16x8, + ExtAddPairwiseSVecI16x8ToI32x4, + ExtAddPairwiseUVecI16x8ToI32x4, // SIMD conversions TruncSatSVecF32x4ToVecI32x4, diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index f526cebf3..49d3cbf63 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -1868,12 +1868,6 @@ Literal Literal::allTrueI32x4() const { Literal Literal::bitmaskI32x4() const { return bitmask<4, &Literal::getLanesI32x4>(*this); } -Literal Literal::anyTrueI64x2() const { - return any_true<2, &Literal::getLanesI64x2>(*this); -} -Literal Literal::allTrueI64x2() const { - return all_true<2, &Literal::getLanesI64x2>(*this); -} template<int Lanes, LaneArray<Lanes> (Literal::*IntoLanes)() const, diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 70aaa6a61..e616493af 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -4836,14 +4836,6 @@ bool WasmBinaryBuilder::maybeVisitSIMDUnary(Expression*& out, uint32_t code) { curr = allocator.alloc<Unary>(); curr->op = NegVecI64x2; break; - case BinaryConsts::I64x2AnyTrue: - curr = allocator.alloc<Unary>(); - curr->op = AnyTrueVecI64x2; - break; - case BinaryConsts::I64x2AllTrue: - curr = allocator.alloc<Unary>(); - curr->op = AllTrueVecI64x2; - break; case BinaryConsts::I64x2Bitmask: curr = allocator.alloc<Unary>(); curr->op = BitmaskVecI64x2; @@ -4904,6 +4896,22 @@ bool WasmBinaryBuilder::maybeVisitSIMDUnary(Expression*& out, uint32_t code) { curr = allocator.alloc<Unary>(); curr->op = NearestVecF64x2; break; + case BinaryConsts::I16x8ExtAddPairWiseSI8x16: + curr = allocator.alloc<Unary>(); + curr->op = ExtAddPairwiseSVecI8x16ToI16x8; + break; + case BinaryConsts::I16x8ExtAddPairWiseUI8x16: + curr = allocator.alloc<Unary>(); + curr->op = ExtAddPairwiseUVecI8x16ToI16x8; + break; + case BinaryConsts::I32x4ExtAddPairWiseSI16x8: + curr = allocator.alloc<Unary>(); + curr->op = ExtAddPairwiseSVecI16x8ToI32x4; + break; + case BinaryConsts::I32x4ExtAddPairWiseUI16x8: + curr = allocator.alloc<Unary>(); + curr->op = ExtAddPairwiseUVecI16x8ToI32x4; + break; case BinaryConsts::I32x4TruncSatSF32x4: curr = allocator.alloc<Unary>(); curr->op = TruncSatSVecF32x4ToVecI32x4; diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 6af7279bb..776928b88 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -1028,14 +1028,6 @@ void BinaryInstWriter::visitUnary(Unary* curr) { case NegVecI64x2: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Neg); break; - case AnyTrueVecI64x2: - o << int8_t(BinaryConsts::SIMDPrefix) - << U32LEB(BinaryConsts::I64x2AnyTrue); - break; - case AllTrueVecI64x2: - o << int8_t(BinaryConsts::SIMDPrefix) - << U32LEB(BinaryConsts::I64x2AllTrue); - break; case BitmaskVecI64x2: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Bitmask); @@ -1084,6 +1076,22 @@ void BinaryInstWriter::visitUnary(Unary* curr) { o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F64x2Nearest); break; + case ExtAddPairwiseSVecI8x16ToI16x8: + o << int8_t(BinaryConsts::SIMDPrefix) + << U32LEB(BinaryConsts::I16x8ExtAddPairWiseSI8x16); + break; + case ExtAddPairwiseUVecI8x16ToI16x8: + o << int8_t(BinaryConsts::SIMDPrefix) + << U32LEB(BinaryConsts::I16x8ExtAddPairWiseUI8x16); + break; + case ExtAddPairwiseSVecI16x8ToI32x4: + o << int8_t(BinaryConsts::SIMDPrefix) + << U32LEB(BinaryConsts::I32x4ExtAddPairWiseSI16x8); + break; + case ExtAddPairwiseUVecI16x8ToI32x4: + o << int8_t(BinaryConsts::SIMDPrefix) + << U32LEB(BinaryConsts::I32x4ExtAddPairWiseUI16x8); + break; case TruncSatSVecF32x4ToVecI32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4TruncSatSF32x4); diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 745ce8c06..a45be1fd3 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1866,6 +1866,10 @@ void FunctionValidator::visitUnary(Unary* curr) { case FloorVecF64x2: case TruncVecF64x2: case NearestVecF64x2: + case ExtAddPairwiseSVecI8x16ToI16x8: + case ExtAddPairwiseUVecI8x16ToI16x8: + case ExtAddPairwiseSVecI16x8ToI32x4: + case ExtAddPairwiseUVecI16x8ToI32x4: case TruncSatSVecF32x4ToVecI32x4: case TruncSatUVecF32x4ToVecI32x4: case TruncSatSVecF64x2ToVecI64x2: @@ -1893,11 +1897,9 @@ void FunctionValidator::visitUnary(Unary* curr) { case AnyTrueVecI8x16: case AnyTrueVecI16x8: case AnyTrueVecI32x4: - case AnyTrueVecI64x2: case AllTrueVecI8x16: case AllTrueVecI16x8: case AllTrueVecI32x4: - case AllTrueVecI64x2: case BitmaskVecI8x16: case BitmaskVecI16x8: case BitmaskVecI32x4: diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 436eedb2b..264f2bf83 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -783,6 +783,10 @@ void Unary::finalize() { case FloorVecF64x2: case TruncVecF64x2: case NearestVecF64x2: + case ExtAddPairwiseSVecI8x16ToI16x8: + case ExtAddPairwiseUVecI8x16ToI16x8: + case ExtAddPairwiseSVecI16x8ToI32x4: + case ExtAddPairwiseUVecI16x8ToI32x4: case TruncSatSVecF32x4ToVecI32x4: case TruncSatUVecF32x4ToVecI32x4: case TruncSatSVecF64x2ToVecI64x2: @@ -808,11 +812,9 @@ void Unary::finalize() { case AnyTrueVecI8x16: case AnyTrueVecI16x8: case AnyTrueVecI32x4: - case AnyTrueVecI64x2: case AllTrueVecI8x16: case AllTrueVecI16x8: case AllTrueVecI32x4: - case AllTrueVecI64x2: case BitmaskVecI8x16: case BitmaskVecI16x8: case BitmaskVecI32x4: |