Skip to content

Add i32x4.dot_i16x8_s #2420

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 1 commit into from
Nov 4, 2019
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
1 change: 1 addition & 0 deletions build-js.sh
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ export_function "_BinaryenMinSVecI32x4"
export_function "_BinaryenMinUVecI32x4"
export_function "_BinaryenMaxSVecI32x4"
export_function "_BinaryenMaxUVecI32x4"
export_function "_BinaryenDotSVecI16x8ToVecI32x4"
export_function "_BinaryenNegVecI64x2"
export_function "_BinaryenAnyTrueVecI64x2"
export_function "_BinaryenAllTrueVecI64x2"
Expand Down
1 change: 1 addition & 0 deletions scripts/gen-s-parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@
("i32x4.min_u", "makeBinary(s, BinaryOp::MinUVecI32x4)"),
("i32x4.max_s", "makeBinary(s, BinaryOp::MaxSVecI32x4)"),
("i32x4.max_u", "makeBinary(s, BinaryOp::MaxUVecI32x4)"),
("i32x4.dot_i16x8_s", "makeBinary(s, BinaryOp::DotSVecI16x8ToVecI32x4)"),
("i64x2.neg", "makeUnary(s, UnaryOp::NegVecI64x2)"),
("i64x2.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI64x2)"),
("i64x2.all_true", "makeUnary(s, UnaryOp::AllTrueVecI64x2)"),
Expand Down
3 changes: 3 additions & 0 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,9 @@ BinaryenOp BinaryenMinSVecI32x4(void) { return MinSVecI32x4; }
BinaryenOp BinaryenMinUVecI32x4(void) { return MinUVecI32x4; }
BinaryenOp BinaryenMaxSVecI32x4(void) { return MaxSVecI32x4; }
BinaryenOp BinaryenMaxUVecI32x4(void) { return MaxUVecI32x4; }
BinaryenOp BinaryenDotSVecI16x8ToVecI32x4(void) {
return DotSVecI16x8ToVecI32x4;
}
BinaryenOp BinaryenNegVecI64x2(void) { return NegVecI64x2; }
BinaryenOp BinaryenAnyTrueVecI64x2(void) { return AnyTrueVecI64x2; }
BinaryenOp BinaryenAllTrueVecI64x2(void) { return AllTrueVecI64x2; }
Expand Down
1 change: 1 addition & 0 deletions src/binaryen-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ BINARYEN_API BinaryenOp BinaryenMinSVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenMinUVecI32x4(void);
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);
Expand Down
3 changes: 3 additions & 0 deletions src/gen-s-parser.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1409,6 +1409,9 @@ switch (op[0]) {
default: goto parse_error;
}
}
case 'd':
if (strcmp(op, "i32x4.dot_i16x8_s") == 0) { return makeBinary(s, BinaryOp::DotSVecI16x8ToVecI32x4); }
goto parse_error;
case 'e': {
switch (op[7]) {
case 'q':
Expand Down
3 changes: 3 additions & 0 deletions src/ir/cost.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,9 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
case MaxUVecI32x4:
ret = 1;
break;
case DotSVecI16x8ToVecI32x4:
ret = 1;
break;
case AddVecI64x2:
ret = 1;
break;
Expand Down
4 changes: 4 additions & 0 deletions src/js/binaryen.js-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ Module['MinSVecI16x8'] = Module['_BinaryenMinSVecI16x8']();
Module['MinUVecI16x8'] = Module['_BinaryenMinUVecI16x8']();
Module['MaxSVecI16x8'] = Module['_BinaryenMaxSVecI16x8']();
Module['MaxUVecI16x8'] = Module['_BinaryenMaxUVecI16x8']();
Module['DotSVecI16x8ToVecI32x4'] = Module['_BinaryenDotSVecI16x8ToVecI32x4']();
Module['NegVecI32x4'] = Module['_BinaryenNegVecI32x4']();
Module['AnyTrueVecI32x4'] = Module['_BinaryenAnyTrueVecI32x4']();
Module['AllTrueVecI32x4'] = Module['_BinaryenAllTrueVecI32x4']();
Expand Down Expand Up @@ -1676,6 +1677,9 @@ function wrapModule(module, self) {
'max_u': function(left, right) {
return Module['_BinaryenBinary'](module, Module['MaxUVecI32x4'], left, right);
},
'dot_i16x8_s': function(left, right) {
return Module['_BinaryenBinary'](module, Module['DotSVecI16x8ToVecI32x4'], left, right);
},
'trunc_sat_f32x4_s': function(value) {
return Module['_BinaryenUnary'](module, Module['TruncSatSVecF32x4ToVecI32x4'], value);
},
Expand Down
1 change: 1 addition & 0 deletions src/literal.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ class Literal {
Literal minUI32x4(const Literal& other) const;
Literal maxSI32x4(const Literal& other) const;
Literal maxUI32x4(const Literal& other) const;
Literal dotSI16x8toI32x4(const Literal& other) const;
Literal negI64x2() const;
Literal anyTrueI64x2() const;
Literal allTrueI64x2() const;
Expand Down
3 changes: 3 additions & 0 deletions src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,9 @@ struct PrintExpressionContents
case MaxUVecI32x4:
o << "i32x4.max_u";
break;
case DotSVecI16x8ToVecI32x4:
o << "i32x4.dot_i16x8_s";
break;
case AddVecI64x2:
o << "i64x2.add";
break;
Expand Down
1 change: 1 addition & 0 deletions src/tools/fuzzing.h
Original file line number Diff line number Diff line change
Expand Up @@ -2169,6 +2169,7 @@ class TranslateToFuzzReader {
MinUVecI32x4,
MaxSVecI32x4,
MaxUVecI32x4,
DotSVecI16x8ToVecI32x4,
AddVecI64x2,
SubVecI64x2,
AddVecF32x4,
Expand Down
1 change: 1 addition & 0 deletions src/wasm-binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,7 @@ enum ASTNodes {
I32x4MinU = 0x81,
I32x4MaxS = 0x82,
I32x4MaxU = 0x83,
I32x4DotSVecI16x8 = 0xd9,
I64x2Neg = 0x84,
I64x2AnyTrue = 0x85,
I64x2AllTrue = 0x86,
Expand Down
2 changes: 2 additions & 0 deletions src/wasm-interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,8 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
return left.maxSI32x4(right);
case MaxUVecI32x4:
return left.maxUI32x4(right);
case DotSVecI16x8ToVecI32x4:
return left.dotSI16x8toI32x4(right);
case AddVecI64x2:
return left.addI64x2(right);
case SubVecI64x2:
Expand Down
1 change: 1 addition & 0 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ enum BinaryOp {
MinUVecI32x4,
MaxSVecI32x4,
MaxUVecI32x4,
DotSVecI16x8ToVecI32x4,
AddVecI64x2,
SubVecI64x2,
AddVecF32x4,
Expand Down
11 changes: 11 additions & 0 deletions src/wasm/literal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1829,6 +1829,17 @@ Literal Literal::maxF64x2(const Literal& other) const {
return binary<2, &Literal::getLanesF64x2, &Literal::max>(*this, other);
}

Literal Literal::dotSI16x8toI32x4(const Literal& other) const {
LaneArray<8> lhs = getLanesSI16x8();
LaneArray<8> rhs = other.getLanesSI16x8();
LaneArray<4> result;
for (size_t i = 0; i < 4; ++i) {
result[i] = Literal(lhs[i * 2].geti32() * rhs[i * 2].geti32() +
lhs[i * 2 + 1].geti32() * rhs[i * 2 + 1].geti32());
}
return Literal(result);
}

Literal Literal::bitselectV128(const Literal& left,
const Literal& right) const {
return andV128(left).orV128(notV128().andV128(right));
Expand Down
4 changes: 4 additions & 0 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3939,6 +3939,10 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Binary>();
curr->op = MaxUVecI32x4;
break;
case BinaryConsts::I32x4DotSVecI16x8:
curr = allocator.alloc<Binary>();
curr->op = DotSVecI16x8ToVecI32x4;
break;
case BinaryConsts::I64x2Add:
curr = allocator.alloc<Binary>();
curr->op = AddVecI64x2;
Expand Down
4 changes: 4 additions & 0 deletions src/wasm/wasm-stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,10 @@ void BinaryInstWriter::visitBinary(Binary* curr) {
case MaxUVecI32x4:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4MaxU);
break;
case DotSVecI16x8ToVecI32x4:
o << int8_t(BinaryConsts::SIMDPrefix)
<< U32LEB(BinaryConsts::I32x4DotSVecI16x8);
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not particularly about thie PR but Just curious, is there a reason we have different names for Op and BinaryConsts, such as ExtractLaneSVecI18x16 vs. I8x16ExtractLaneS?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BinaryConsts exactly mirror the underlying instruction naming with . and _ removed and the name CamelCased, but the Binaryen Op names are shuffled around to put the operation first and the relevant types later. This name change is meant to increase clarity by emphasizing the operation over the types, but it can also make the types clearer in conversion ops by inserting To into the op name, as in DotSVecI16x8ToVecI32x4.

case AddVecI64x2:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Add);
break;
Expand Down
1 change: 1 addition & 0 deletions src/wasm/wasm-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,7 @@ void FunctionValidator::visitBinary(Binary* curr) {
case MinUVecI32x4:
case MaxSVecI32x4:
case MaxUVecI32x4:
case DotSVecI16x8ToVecI32x4:
case AddVecI64x2:
case SubVecI64x2:
case AddVecF32x4:
Expand Down
1 change: 1 addition & 0 deletions test/binaryen.js/kitchen-sink.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ function test_core() {
module.i32x4.min_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.i32x4.max_s(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.i32x4.max_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.i32x4.dot_i16x8_s(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.i64x2.add(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.i64x2.sub(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
module.f32x4.add(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
Expand Down
Loading