Skip to content

Prototype SIMD extending pairwise add instructions #3466

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions scripts/gen-s-parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,6 @@
("i32x4.extmul_low_i16x8_u", "makeBinary(s, BinaryOp::ExtMulLowUVecI32x4)"),
("i32x4.extmul_high_i16x8_u", "makeBinary(s, BinaryOp::ExtMulHighUVecI32x4)"),
("i64x2.neg", "makeUnary(s, UnaryOp::NegVecI64x2)"),
("i64x2.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI64x2)"),
("i64x2.all_true", "makeUnary(s, UnaryOp::AllTrueVecI64x2)"),
("i64x2.bitmask", "makeUnary(s, UnaryOp::BitmaskVecI64x2)"),
("i64x2.shl", "makeSIMDShift(s, SIMDShiftOp::ShlVecI64x2)"),
("i64x2.shr_s", "makeSIMDShift(s, SIMDShiftOp::ShrSVecI64x2)"),
Expand Down Expand Up @@ -514,6 +512,10 @@
("i64x2.widen_low_i32x4_u", "makeUnary(s, UnaryOp::WidenLowUVecI32x4ToVecI64x2)"),
("i64x2.widen_high_i32x4_u", "makeUnary(s, UnaryOp::WidenHighUVecI32x4ToVecI64x2)"),
("v8x16.swizzle", "makeBinary(s, BinaryOp::SwizzleVec8x16)"),
("i16x8.extadd_pairwise_i8x16_s", "makeUnary(s, UnaryOp::ExtAddPairwiseSVecI8x16ToI16x8)"),
("i16x8.extadd_pairwise_i8x16_u", "makeUnary(s, UnaryOp::ExtAddPairwiseUVecI8x16ToI16x8)"),
("i32x4.extadd_pairwise_i16x8_s", "makeUnary(s, UnaryOp::ExtAddPairwiseSVecI16x8ToI32x4)"),
("i32x4.extadd_pairwise_i16x8_u", "makeUnary(s, UnaryOp::ExtAddPairwiseUVecI16x8ToI32x4)"),
# reference types instructions
# TODO Add table instructions
("ref.null", "makeRefNull(s)"),
Expand Down
2 changes: 0 additions & 2 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
3 changes: 1 addition & 2 deletions src/binaryen-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
43 changes: 27 additions & 16 deletions src/gen-s-parser.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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]) {
Expand Down Expand Up @@ -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': {
Expand Down Expand Up @@ -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': {
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions src/ir/cost.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down
2 changes: 0 additions & 2 deletions src/ir/features.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 0 additions & 8 deletions src/js/binaryen.js-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,6 @@ function initializeConstants() {
'MaxSVecI32x4',
'MaxUVecI32x4',
'NegVecI64x2',
'AnyTrueVecI64x2',
'AllTrueVecI64x2',
'ShlVecI64x2',
'ShrSVecI64x2',
'ShrUVecI64x2',
Expand Down Expand Up @@ -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);
},
Expand Down
2 changes: 0 additions & 2 deletions src/literal.h
Original file line number Diff line number Diff line change
Expand Up @@ -576,8 +576,6 @@ class Literal {
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;
Expand Down
18 changes: 12 additions & 6 deletions src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 1 addition & 3 deletions src/tools/fuzzing.h
Original file line number Diff line number Diff line change
Expand Up @@ -2168,9 +2168,7 @@ class TranslateToFuzzReader {
AnyTrueVecI16x8,
AllTrueVecI16x8,
AnyTrueVecI32x4,
AllTrueVecI32x4,
AnyTrueVecI64x2,
AllTrueVecI64x2),
AllTrueVecI32x4),
make(Type::v128)});
}
case Type::funcref:
Expand Down
7 changes: 5 additions & 2 deletions src/wasm-binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -897,8 +897,6 @@ enum ASTNodes {
I64x2WidenLowUI32x4 = 0xc9,
I64x2WidenHighUI32x4 = 0xca,
I64x2Neg = 0xc1,
I64x2AnyTrue = 0xc2,
I64x2AllTrue = 0xc3,
I64x2Shl = 0xcb,
I64x2ShrS = 0xcc,
I64x2ShrU = 0xcd,
Expand Down Expand Up @@ -939,6 +937,11 @@ enum ASTNodes {
F64x2PMin = 0xf6,
F64x2PMax = 0xf7,

I16x8ExtAddPairWiseSI8x16 = 0xc2,
I16x8ExtAddPairWiseUI8x16 = 0xc3,
I32x4ExtAddPairWiseSI16x8 = 0xa5,
I32x4ExtAddPairWiseUI16x8 = 0xa6,

I32x4TruncSatSF32x4 = 0xf8,
I32x4TruncSatUF32x4 = 0xf9,
F32x4ConvertSI32x4 = 0xfa,
Expand Down
12 changes: 8 additions & 4 deletions src/wasm-interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,10 +488,6 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
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:
Expand Down Expand Up @@ -522,6 +518,14 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
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:
Expand Down
6 changes: 4 additions & 2 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,6 @@ enum UnaryOp {
AllTrueVecI32x4,
BitmaskVecI32x4,
NegVecI64x2,
AnyTrueVecI64x2,
AllTrueVecI64x2,
BitmaskVecI64x2,
AbsVecF32x4,
NegVecF32x4,
Expand All @@ -191,6 +189,10 @@ enum UnaryOp {
FloorVecF64x2,
TruncVecF64x2,
NearestVecF64x2,
ExtAddPairwiseSVecI8x16ToI16x8,
ExtAddPairwiseUVecI8x16ToI16x8,
ExtAddPairwiseSVecI16x8ToI32x4,
ExtAddPairwiseUVecI16x8ToI32x4,

// SIMD conversions
TruncSatSVecF32x4ToVecI32x4,
Expand Down
6 changes: 0 additions & 6 deletions src/wasm/literal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
24 changes: 16 additions & 8 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
24 changes: 16 additions & 8 deletions src/wasm/wasm-stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions src/wasm/wasm-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
Loading