Skip to content

Commit b79661e

Browse files
authored
Prototype SIMD extending pairwise add instructions (WebAssembly#3466)
As proposed in WebAssembly/simd#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.
1 parent 3e5ce64 commit b79661e

27 files changed

+270
-244
lines changed

scripts/gen-s-parser.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,6 @@
430430
("i32x4.extmul_low_i16x8_u", "makeBinary(s, BinaryOp::ExtMulLowUVecI32x4)"),
431431
("i32x4.extmul_high_i16x8_u", "makeBinary(s, BinaryOp::ExtMulHighUVecI32x4)"),
432432
("i64x2.neg", "makeUnary(s, UnaryOp::NegVecI64x2)"),
433-
("i64x2.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI64x2)"),
434-
("i64x2.all_true", "makeUnary(s, UnaryOp::AllTrueVecI64x2)"),
435433
("i64x2.bitmask", "makeUnary(s, UnaryOp::BitmaskVecI64x2)"),
436434
("i64x2.shl", "makeSIMDShift(s, SIMDShiftOp::ShlVecI64x2)"),
437435
("i64x2.shr_s", "makeSIMDShift(s, SIMDShiftOp::ShrSVecI64x2)"),
@@ -514,6 +512,10 @@
514512
("i64x2.widen_low_i32x4_u", "makeUnary(s, UnaryOp::WidenLowUVecI32x4ToVecI64x2)"),
515513
("i64x2.widen_high_i32x4_u", "makeUnary(s, UnaryOp::WidenHighUVecI32x4ToVecI64x2)"),
516514
("v8x16.swizzle", "makeBinary(s, BinaryOp::SwizzleVec8x16)"),
515+
("i16x8.extadd_pairwise_i8x16_s", "makeUnary(s, UnaryOp::ExtAddPairwiseSVecI8x16ToI16x8)"),
516+
("i16x8.extadd_pairwise_i8x16_u", "makeUnary(s, UnaryOp::ExtAddPairwiseUVecI8x16ToI16x8)"),
517+
("i32x4.extadd_pairwise_i16x8_s", "makeUnary(s, UnaryOp::ExtAddPairwiseSVecI16x8ToI32x4)"),
518+
("i32x4.extadd_pairwise_i16x8_u", "makeUnary(s, UnaryOp::ExtAddPairwiseUVecI16x8ToI32x4)"),
517519
# reference types instructions
518520
# TODO Add table instructions
519521
("ref.null", "makeRefNull(s)"),

src/binaryen-c.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -580,8 +580,6 @@ BinaryenOp BinaryenDotSVecI16x8ToVecI32x4(void) {
580580
return DotSVecI16x8ToVecI32x4;
581581
}
582582
BinaryenOp BinaryenNegVecI64x2(void) { return NegVecI64x2; }
583-
BinaryenOp BinaryenAnyTrueVecI64x2(void) { return AnyTrueVecI64x2; }
584-
BinaryenOp BinaryenAllTrueVecI64x2(void) { return AllTrueVecI64x2; }
585583
BinaryenOp BinaryenShlVecI64x2(void) { return ShlVecI64x2; }
586584
BinaryenOp BinaryenShrSVecI64x2(void) { return ShrSVecI64x2; }
587585
BinaryenOp BinaryenShrUVecI64x2(void) { return ShrUVecI64x2; }

src/binaryen-c.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,6 @@ BINARYEN_API BinaryenOp BinaryenMaxSVecI32x4(void);
486486
BINARYEN_API BinaryenOp BinaryenMaxUVecI32x4(void);
487487
BINARYEN_API BinaryenOp BinaryenDotSVecI16x8ToVecI32x4(void);
488488
BINARYEN_API BinaryenOp BinaryenNegVecI64x2(void);
489-
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI64x2(void);
490-
BINARYEN_API BinaryenOp BinaryenAllTrueVecI64x2(void);
491489
BINARYEN_API BinaryenOp BinaryenShlVecI64x2(void);
492490
BINARYEN_API BinaryenOp BinaryenShrSVecI64x2(void);
493491
BINARYEN_API BinaryenOp BinaryenShrUVecI64x2(void);
@@ -528,6 +526,7 @@ BINARYEN_API BinaryenOp BinaryenCeilVecF64x2(void);
528526
BINARYEN_API BinaryenOp BinaryenFloorVecF64x2(void);
529527
BINARYEN_API BinaryenOp BinaryenTruncVecF64x2(void);
530528
BINARYEN_API BinaryenOp BinaryenNearestVecF64x2(void);
529+
// TODO: Add extending pairwise adds to C and JS APIs once merged
531530
BINARYEN_API BinaryenOp BinaryenTruncSatSVecF32x4ToVecI32x4(void);
532531
BINARYEN_API BinaryenOp BinaryenTruncSatUVecF32x4ToVecI32x4(void);
533532
BINARYEN_API BinaryenOp BinaryenTruncSatSVecF64x2ToVecI64x2(void);

src/gen-s-parser.inc

+27-16
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
#ifdef INSTRUCTION_PARSER
66
#undef INSTRUCTION_PARSER
7-
char op[28] = {'\0'};
8-
strncpy(op, s[0]->c_str(), 27);
7+
char op[30] = {'\0'};
8+
strncpy(op, s[0]->c_str(), 29);
99
switch (op[0]) {
1010
case 'a': {
1111
switch (op[1]) {
@@ -800,6 +800,17 @@ switch (op[0]) {
800800
goto parse_error;
801801
case 'x': {
802802
switch (op[9]) {
803+
case 'a': {
804+
switch (op[28]) {
805+
case 's':
806+
if (strcmp(op, "i16x8.extadd_pairwise_i8x16_s") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseSVecI8x16ToI16x8); }
807+
goto parse_error;
808+
case 'u':
809+
if (strcmp(op, "i16x8.extadd_pairwise_i8x16_u") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseUVecI8x16ToI16x8); }
810+
goto parse_error;
811+
default: goto parse_error;
812+
}
813+
}
803814
case 'm': {
804815
switch (op[13]) {
805816
case 'h': {
@@ -1554,6 +1565,17 @@ switch (op[0]) {
15541565
goto parse_error;
15551566
case 'x': {
15561567
switch (op[9]) {
1568+
case 'a': {
1569+
switch (op[28]) {
1570+
case 's':
1571+
if (strcmp(op, "i32x4.extadd_pairwise_i16x8_s") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseSVecI16x8ToI32x4); }
1572+
goto parse_error;
1573+
case 'u':
1574+
if (strcmp(op, "i32x4.extadd_pairwise_i16x8_u") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseUVecI16x8ToI32x4); }
1575+
goto parse_error;
1576+
default: goto parse_error;
1577+
}
1578+
}
15571579
case 'm': {
15581580
switch (op[13]) {
15591581
case 'h': {
@@ -2298,20 +2320,9 @@ switch (op[0]) {
22982320
}
22992321
case 'x': {
23002322
switch (op[6]) {
2301-
case 'a': {
2302-
switch (op[7]) {
2303-
case 'd':
2304-
if (strcmp(op, "i64x2.add") == 0) { return makeBinary(s, BinaryOp::AddVecI64x2); }
2305-
goto parse_error;
2306-
case 'l':
2307-
if (strcmp(op, "i64x2.all_true") == 0) { return makeUnary(s, UnaryOp::AllTrueVecI64x2); }
2308-
goto parse_error;
2309-
case 'n':
2310-
if (strcmp(op, "i64x2.any_true") == 0) { return makeUnary(s, UnaryOp::AnyTrueVecI64x2); }
2311-
goto parse_error;
2312-
default: goto parse_error;
2313-
}
2314-
}
2323+
case 'a':
2324+
if (strcmp(op, "i64x2.add") == 0) { return makeBinary(s, BinaryOp::AddVecI64x2); }
2325+
goto parse_error;
23152326
case 'b':
23162327
if (strcmp(op, "i64x2.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI64x2); }
23172328
goto parse_error;

src/ir/cost.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,6 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
189189
case AllTrueVecI32x4:
190190
case BitmaskVecI32x4:
191191
case NegVecI64x2:
192-
case AnyTrueVecI64x2:
193-
case AllTrueVecI64x2:
194192
case BitmaskVecI64x2:
195193
case AbsVecF32x4:
196194
case NegVecF32x4:
@@ -206,6 +204,10 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
206204
case FloorVecF64x2:
207205
case TruncVecF64x2:
208206
case NearestVecF64x2:
207+
case ExtAddPairwiseSVecI8x16ToI16x8:
208+
case ExtAddPairwiseUVecI8x16ToI16x8:
209+
case ExtAddPairwiseSVecI16x8ToI32x4:
210+
case ExtAddPairwiseUVecI16x8ToI32x4:
209211
case TruncSatSVecF32x4ToVecI32x4:
210212
case TruncSatUVecF32x4ToVecI32x4:
211213
case TruncSatSVecF64x2ToVecI64x2:

src/ir/features.h

-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ inline FeatureSet get(UnaryOp op) {
5757
case AnyTrueVecI32x4:
5858
case AllTrueVecI32x4:
5959
case NegVecI64x2:
60-
case AnyTrueVecI64x2:
61-
case AllTrueVecI64x2:
6260
case AbsVecF32x4:
6361
case NegVecF32x4:
6462
case SqrtVecF32x4:

src/js/binaryen.js-post.js

-8
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,6 @@ function initializeConstants() {
416416
'MaxSVecI32x4',
417417
'MaxUVecI32x4',
418418
'NegVecI64x2',
419-
'AnyTrueVecI64x2',
420-
'AllTrueVecI64x2',
421419
'ShlVecI64x2',
422420
'ShrSVecI64x2',
423421
'ShrUVecI64x2',
@@ -1828,12 +1826,6 @@ function wrapModule(module, self = {}) {
18281826
'neg'(value) {
18291827
return Module['_BinaryenUnary'](module, Module['NegVecI64x2'], value);
18301828
},
1831-
'any_true'(value) {
1832-
return Module['_BinaryenUnary'](module, Module['AnyTrueVecI64x2'], value);
1833-
},
1834-
'all_true'(value) {
1835-
return Module['_BinaryenUnary'](module, Module['AllTrueVecI64x2'], value);
1836-
},
18371829
'shl'(vec, shift) {
18381830
return Module['_BinaryenSIMDShift'](module, Module['ShlVecI64x2'], vec, shift);
18391831
},

src/literal.h

-2
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,6 @@ class Literal {
576576
Literal extMulLowUI32x4(const Literal& other) const;
577577
Literal extMulHighUI32x4(const Literal& other) const;
578578
Literal negI64x2() const;
579-
Literal anyTrueI64x2() const;
580-
Literal allTrueI64x2() const;
581579
Literal shlI64x2(const Literal& other) const;
582580
Literal shrSI64x2(const Literal& other) const;
583581
Literal shrUI64x2(const Literal& other) const;

src/passes/Print.cpp

+12-6
Original file line numberDiff line numberDiff line change
@@ -957,12 +957,6 @@ struct PrintExpressionContents
957957
case NegVecI64x2:
958958
o << "i64x2.neg";
959959
break;
960-
case AnyTrueVecI64x2:
961-
o << "i64x2.any_true";
962-
break;
963-
case AllTrueVecI64x2:
964-
o << "i64x2.all_true";
965-
break;
966960
case BitmaskVecI64x2:
967961
o << "i64x2.bitmask";
968962
break;
@@ -1008,6 +1002,18 @@ struct PrintExpressionContents
10081002
case NearestVecF64x2:
10091003
o << "f64x2.nearest";
10101004
break;
1005+
case ExtAddPairwiseSVecI8x16ToI16x8:
1006+
o << "i16x8.extadd_pairwise_i8x16_s";
1007+
break;
1008+
case ExtAddPairwiseUVecI8x16ToI16x8:
1009+
o << "i16x8.extadd_pairwise_i8x16_u";
1010+
break;
1011+
case ExtAddPairwiseSVecI16x8ToI32x4:
1012+
o << "i32x4.extadd_pairwise_i16x8_s";
1013+
break;
1014+
case ExtAddPairwiseUVecI16x8ToI32x4:
1015+
o << "i32x4.extadd_pairwise_i16x8_u";
1016+
break;
10111017
case TruncSatSVecF32x4ToVecI32x4:
10121018
o << "i32x4.trunc_sat_f32x4_s";
10131019
break;

src/tools/fuzzing.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -2168,9 +2168,7 @@ class TranslateToFuzzReader {
21682168
AnyTrueVecI16x8,
21692169
AllTrueVecI16x8,
21702170
AnyTrueVecI32x4,
2171-
AllTrueVecI32x4,
2172-
AnyTrueVecI64x2,
2173-
AllTrueVecI64x2),
2171+
AllTrueVecI32x4),
21742172
make(Type::v128)});
21752173
}
21762174
case Type::funcref:

src/wasm-binary.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -897,8 +897,6 @@ enum ASTNodes {
897897
I64x2WidenLowUI32x4 = 0xc9,
898898
I64x2WidenHighUI32x4 = 0xca,
899899
I64x2Neg = 0xc1,
900-
I64x2AnyTrue = 0xc2,
901-
I64x2AllTrue = 0xc3,
902900
I64x2Shl = 0xcb,
903901
I64x2ShrS = 0xcc,
904902
I64x2ShrU = 0xcd,
@@ -939,6 +937,11 @@ enum ASTNodes {
939937
F64x2PMin = 0xf6,
940938
F64x2PMax = 0xf7,
941939

940+
I16x8ExtAddPairWiseSI8x16 = 0xc2,
941+
I16x8ExtAddPairWiseUI8x16 = 0xc3,
942+
I32x4ExtAddPairWiseSI16x8 = 0xa5,
943+
I32x4ExtAddPairWiseUI16x8 = 0xa6,
944+
942945
I32x4TruncSatSF32x4 = 0xf8,
943946
I32x4TruncSatUF32x4 = 0xf9,
944947
F32x4ConvertSI32x4 = 0xfa,

src/wasm-interpreter.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -488,10 +488,6 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
488488
return value.bitmaskI32x4();
489489
case NegVecI64x2:
490490
return value.negI64x2();
491-
case AnyTrueVecI64x2:
492-
return value.anyTrueI64x2();
493-
case AllTrueVecI64x2:
494-
return value.allTrueI64x2();
495491
case BitmaskVecI64x2:
496492
WASM_UNREACHABLE("unimp");
497493
case AbsVecF32x4:
@@ -522,6 +518,14 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
522518
return value.truncF64x2();
523519
case NearestVecF64x2:
524520
return value.nearestF64x2();
521+
case ExtAddPairwiseSVecI8x16ToI16x8:
522+
WASM_UNREACHABLE("unimp");
523+
case ExtAddPairwiseUVecI8x16ToI16x8:
524+
WASM_UNREACHABLE("unimp");
525+
case ExtAddPairwiseSVecI16x8ToI32x4:
526+
WASM_UNREACHABLE("unimp");
527+
case ExtAddPairwiseUVecI16x8ToI32x4:
528+
WASM_UNREACHABLE("unimp");
525529
case TruncSatSVecF32x4ToVecI32x4:
526530
return value.truncSatToSI32x4();
527531
case TruncSatUVecF32x4ToVecI32x4:

src/wasm.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,6 @@ enum UnaryOp {
174174
AllTrueVecI32x4,
175175
BitmaskVecI32x4,
176176
NegVecI64x2,
177-
AnyTrueVecI64x2,
178-
AllTrueVecI64x2,
179177
BitmaskVecI64x2,
180178
AbsVecF32x4,
181179
NegVecF32x4,
@@ -191,6 +189,10 @@ enum UnaryOp {
191189
FloorVecF64x2,
192190
TruncVecF64x2,
193191
NearestVecF64x2,
192+
ExtAddPairwiseSVecI8x16ToI16x8,
193+
ExtAddPairwiseUVecI8x16ToI16x8,
194+
ExtAddPairwiseSVecI16x8ToI32x4,
195+
ExtAddPairwiseUVecI16x8ToI32x4,
194196

195197
// SIMD conversions
196198
TruncSatSVecF32x4ToVecI32x4,

src/wasm/literal.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -1868,12 +1868,6 @@ Literal Literal::allTrueI32x4() const {
18681868
Literal Literal::bitmaskI32x4() const {
18691869
return bitmask<4, &Literal::getLanesI32x4>(*this);
18701870
}
1871-
Literal Literal::anyTrueI64x2() const {
1872-
return any_true<2, &Literal::getLanesI64x2>(*this);
1873-
}
1874-
Literal Literal::allTrueI64x2() const {
1875-
return all_true<2, &Literal::getLanesI64x2>(*this);
1876-
}
18771871

18781872
template<int Lanes,
18791873
LaneArray<Lanes> (Literal::*IntoLanes)() const,

src/wasm/wasm-binary.cpp

+16-8
Original file line numberDiff line numberDiff line change
@@ -4836,14 +4836,6 @@ bool WasmBinaryBuilder::maybeVisitSIMDUnary(Expression*& out, uint32_t code) {
48364836
curr = allocator.alloc<Unary>();
48374837
curr->op = NegVecI64x2;
48384838
break;
4839-
case BinaryConsts::I64x2AnyTrue:
4840-
curr = allocator.alloc<Unary>();
4841-
curr->op = AnyTrueVecI64x2;
4842-
break;
4843-
case BinaryConsts::I64x2AllTrue:
4844-
curr = allocator.alloc<Unary>();
4845-
curr->op = AllTrueVecI64x2;
4846-
break;
48474839
case BinaryConsts::I64x2Bitmask:
48484840
curr = allocator.alloc<Unary>();
48494841
curr->op = BitmaskVecI64x2;
@@ -4904,6 +4896,22 @@ bool WasmBinaryBuilder::maybeVisitSIMDUnary(Expression*& out, uint32_t code) {
49044896
curr = allocator.alloc<Unary>();
49054897
curr->op = NearestVecF64x2;
49064898
break;
4899+
case BinaryConsts::I16x8ExtAddPairWiseSI8x16:
4900+
curr = allocator.alloc<Unary>();
4901+
curr->op = ExtAddPairwiseSVecI8x16ToI16x8;
4902+
break;
4903+
case BinaryConsts::I16x8ExtAddPairWiseUI8x16:
4904+
curr = allocator.alloc<Unary>();
4905+
curr->op = ExtAddPairwiseUVecI8x16ToI16x8;
4906+
break;
4907+
case BinaryConsts::I32x4ExtAddPairWiseSI16x8:
4908+
curr = allocator.alloc<Unary>();
4909+
curr->op = ExtAddPairwiseSVecI16x8ToI32x4;
4910+
break;
4911+
case BinaryConsts::I32x4ExtAddPairWiseUI16x8:
4912+
curr = allocator.alloc<Unary>();
4913+
curr->op = ExtAddPairwiseUVecI16x8ToI32x4;
4914+
break;
49074915
case BinaryConsts::I32x4TruncSatSF32x4:
49084916
curr = allocator.alloc<Unary>();
49094917
curr->op = TruncSatSVecF32x4ToVecI32x4;

src/wasm/wasm-stack.cpp

+16-8
Original file line numberDiff line numberDiff line change
@@ -1028,14 +1028,6 @@ void BinaryInstWriter::visitUnary(Unary* curr) {
10281028
case NegVecI64x2:
10291029
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Neg);
10301030
break;
1031-
case AnyTrueVecI64x2:
1032-
o << int8_t(BinaryConsts::SIMDPrefix)
1033-
<< U32LEB(BinaryConsts::I64x2AnyTrue);
1034-
break;
1035-
case AllTrueVecI64x2:
1036-
o << int8_t(BinaryConsts::SIMDPrefix)
1037-
<< U32LEB(BinaryConsts::I64x2AllTrue);
1038-
break;
10391031
case BitmaskVecI64x2:
10401032
o << int8_t(BinaryConsts::SIMDPrefix)
10411033
<< U32LEB(BinaryConsts::I64x2Bitmask);
@@ -1084,6 +1076,22 @@ void BinaryInstWriter::visitUnary(Unary* curr) {
10841076
o << int8_t(BinaryConsts::SIMDPrefix)
10851077
<< U32LEB(BinaryConsts::F64x2Nearest);
10861078
break;
1079+
case ExtAddPairwiseSVecI8x16ToI16x8:
1080+
o << int8_t(BinaryConsts::SIMDPrefix)
1081+
<< U32LEB(BinaryConsts::I16x8ExtAddPairWiseSI8x16);
1082+
break;
1083+
case ExtAddPairwiseUVecI8x16ToI16x8:
1084+
o << int8_t(BinaryConsts::SIMDPrefix)
1085+
<< U32LEB(BinaryConsts::I16x8ExtAddPairWiseUI8x16);
1086+
break;
1087+
case ExtAddPairwiseSVecI16x8ToI32x4:
1088+
o << int8_t(BinaryConsts::SIMDPrefix)
1089+
<< U32LEB(BinaryConsts::I32x4ExtAddPairWiseSI16x8);
1090+
break;
1091+
case ExtAddPairwiseUVecI16x8ToI32x4:
1092+
o << int8_t(BinaryConsts::SIMDPrefix)
1093+
<< U32LEB(BinaryConsts::I32x4ExtAddPairWiseUI16x8);
1094+
break;
10871095
case TruncSatSVecF32x4ToVecI32x4:
10881096
o << int8_t(BinaryConsts::SIMDPrefix)
10891097
<< U32LEB(BinaryConsts::I32x4TruncSatSF32x4);

src/wasm/wasm-validator.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -1866,6 +1866,10 @@ void FunctionValidator::visitUnary(Unary* curr) {
18661866
case FloorVecF64x2:
18671867
case TruncVecF64x2:
18681868
case NearestVecF64x2:
1869+
case ExtAddPairwiseSVecI8x16ToI16x8:
1870+
case ExtAddPairwiseUVecI8x16ToI16x8:
1871+
case ExtAddPairwiseSVecI16x8ToI32x4:
1872+
case ExtAddPairwiseUVecI16x8ToI32x4:
18691873
case TruncSatSVecF32x4ToVecI32x4:
18701874
case TruncSatUVecF32x4ToVecI32x4:
18711875
case TruncSatSVecF64x2ToVecI64x2:
@@ -1893,11 +1897,9 @@ void FunctionValidator::visitUnary(Unary* curr) {
18931897
case AnyTrueVecI8x16:
18941898
case AnyTrueVecI16x8:
18951899
case AnyTrueVecI32x4:
1896-
case AnyTrueVecI64x2:
18971900
case AllTrueVecI8x16:
18981901
case AllTrueVecI16x8:
18991902
case AllTrueVecI32x4:
1900-
case AllTrueVecI64x2:
19011903
case BitmaskVecI8x16:
19021904
case BitmaskVecI16x8:
19031905
case BitmaskVecI32x4:

0 commit comments

Comments
 (0)