Skip to content

Commit

Permalink
Prototype i32x4.widen_i8x16_{s,u}
Browse files Browse the repository at this point in the history
As proposed in WebAssembly/simd#395. Note that the other
instructions in the proposal have not been implemented in LLVM or in V8, so
there is no need to implement them in Binaryen right now either. This PR
introduces a new expression class for the new instructions because they uniquely
take an immediate argument identifying which portion of the input vector to
widen.
  • Loading branch information
tlively committed Feb 1, 2021
1 parent eafb0a4 commit ab7e625
Show file tree
Hide file tree
Showing 23 changed files with 197 additions and 33 deletions.
2 changes: 2 additions & 0 deletions scripts/gen-s-parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,8 @@
("i32x4.trunc_sat_f64x2_zero_u", "makeUnary(s, UnaryOp::TruncSatZeroUVecF64x2ToVecI32x4)"),
("f32x4.demote_f64x2_zero", "makeUnary(s, UnaryOp::DemoteZeroVecF64x2ToVecF32x4)"),
("f64x2.promote_low_f32x4", "makeUnary(s, UnaryOp::PromoteLowVecF32x4ToVecF64x2)"),
("i32x4.widen_i8x16_s", "makeSIMDWiden(s, SIMDWidenOp::WidenSVecI8x16ToVecI32x4)"),
("i32x4.widen_i8x16_u", "makeSIMDWiden(s, SIMDWidenOp::WidenUVecI8x16ToVecI32x4)"),

# prefetch instructions
("prefetch.t", "makePrefetch(s, PrefetchOp::PrefetchTemporal)"),
Expand Down
11 changes: 11 additions & 0 deletions src/gen-s-parser.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,17 @@ switch (op[0]) {
default: goto parse_error;
}
}
case 'i': {
switch (op[18]) {
case 's':
if (strcmp(op, "i32x4.widen_i8x16_s") == 0) { return makeSIMDWiden(s, SIMDWidenOp::WidenSVecI8x16ToVecI32x4); }
goto parse_error;
case 'u':
if (strcmp(op, "i32x4.widen_i8x16_u") == 0) { return makeSIMDWiden(s, SIMDWidenOp::WidenUVecI8x16ToVecI32x4); }
goto parse_error;
default: goto parse_error;
}
}
case 'l': {
switch (op[22]) {
case 's':
Expand Down
1 change: 1 addition & 0 deletions src/ir/ReFinalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ void ReFinalize::visitSIMDLoad(SIMDLoad* curr) { curr->finalize(); }
void ReFinalize::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
curr->finalize();
}
void ReFinalize::visitSIMDWiden(SIMDWiden* curr) { curr->finalize(); }
void ReFinalize::visitPrefetch(Prefetch* curr) { curr->finalize(); }
void ReFinalize::visitMemoryInit(MemoryInit* curr) { curr->finalize(); }
void ReFinalize::visitDataDrop(DataDrop* curr) { curr->finalize(); }
Expand Down
1 change: 1 addition & 0 deletions src/ir/cost.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> {
Index visitSIMDShift(SIMDShift* curr) {
return 1 + visit(curr->vec) + visit(curr->shift);
}
Index visitSIMDWiden(SIMDWiden* curr) { return 1 + visit(curr->vec); }
Index visitSIMDShuffle(SIMDShuffle* curr) {
return 1 + visit(curr->left) + visit(curr->right);
}
Expand Down
1 change: 1 addition & 0 deletions src/ir/effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ class EffectAnalyzer {
}
parent.implicitTrap = true;
}
void visitSIMDWiden(SIMDWiden* curr) {}
void visitPrefetch(Prefetch* curr) {
// Do not reorder with respect to other memory ops
parent.writesMemory = true;
Expand Down
20 changes: 20 additions & 0 deletions src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,19 @@ struct PrintExpressionContents
}
o << " " << int(curr->index);
}
void visitSIMDWiden(SIMDWiden* curr) {
prepareColor(o);
switch (curr->op) {
case WidenSVecI8x16ToVecI32x4:
o << "i32x4.widen_i8x16_s ";
break;
case WidenUVecI8x16ToVecI32x4:
o << "i32x4.widen_i8x16_u ";
break;
}
restoreNormalColor(o);
o << int(curr->index);
}
void visitPrefetch(Prefetch* curr) {
prepareColor(o);
switch (curr->op) {
Expand Down Expand Up @@ -2303,6 +2316,13 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> {
printFullLine(curr->vec);
decIndent();
}
void visitSIMDWiden(SIMDWiden* curr) {
o << '(';
PrintExpressionContents(currFunction, o).visit(curr);
incIndent();
printFullLine(curr->vec);
decIndent();
}
void visitPrefetch(Prefetch* curr) {
o << '(';
PrintExpressionContents(currFunction, o).visit(curr);
Expand Down
4 changes: 4 additions & 0 deletions src/wasm-binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,9 @@ enum ASTNodes {
F32x4DemoteZeroF64x2 = 0x57,
F64x2PromoteLowF32x4 = 0x69,

I32x4WidenSI8x16 = 0x67,
I32x4WidenUI8x16 = 0x68,

// prefetch opcodes

PrefetchT = 0xc5,
Expand Down Expand Up @@ -1521,6 +1524,7 @@ class WasmBinaryBuilder {
bool maybeVisitSIMDShift(Expression*& out, uint32_t code);
bool maybeVisitSIMDLoad(Expression*& out, uint32_t code);
bool maybeVisitSIMDLoadStoreLane(Expression*& out, uint32_t code);
bool maybeVisitSIMDWiden(Expression*& out, uint32_t code);
bool maybeVisitPrefetch(Expression*& out, uint32_t code);
bool maybeVisitMemoryInit(Expression*& out, uint32_t code);
bool maybeVisitDataDrop(Expression*& out, uint32_t code);
Expand Down
8 changes: 8 additions & 0 deletions src/wasm-delegations-fields.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,14 @@ switch (DELEGATE_ID) {
DELEGATE_END(SIMDLoadStoreLane);
break;
}
case Expression::Id::SIMDWidenId: {
DELEGATE_START(SIMDWiden);
DELEGATE_FIELD_CHILD(SIMDWiden, vec);
DELEGATE_FIELD_INT(SIMDWiden, op);
DELEGATE_FIELD_INT(SIMDWiden, index);
DELEGATE_END(SIMDWiden);
break;
}
case Expression::Id::PrefetchId: {
DELEGATE_START(Prefetch);
DELEGATE_FIELD_CHILD(Prefetch, ptr);
Expand Down
1 change: 1 addition & 0 deletions src/wasm-delegations.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ DELEGATE(SIMDTernary);
DELEGATE(SIMDShift);
DELEGATE(SIMDLoad);
DELEGATE(SIMDLoadStoreLane);
DELEGATE(SIMDWiden);
DELEGATE(Prefetch);
DELEGATE(MemoryInit);
DELEGATE(DataDrop);
Expand Down
1 change: 1 addition & 0 deletions src/wasm-interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,7 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
}
WASM_UNREACHABLE("invalid op");
}
Flow visitSIMDWiden(SIMDWiden* curr) { WASM_UNREACHABLE("unimp"); }
Flow visitSelect(Select* curr) {
NOTE_ENTER("Select");
Flow ifTrue = visit(curr->ifTrue);
Expand Down
1 change: 1 addition & 0 deletions src/wasm-s-parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ class SExpressionWasmBuilder {
Expression* makeSIMDShift(Element& s, SIMDShiftOp op);
Expression* makeSIMDLoad(Element& s, SIMDLoadOp op);
Expression* makeSIMDLoadStoreLane(Element& s, SIMDLoadStoreLaneOp op);
Expression* makeSIMDWiden(Element& s, SIMDWidenOp op);
Expression* makePrefetch(Element& s, PrefetchOp op);
Expression* makeMemoryInit(Element& s);
Expression* makeDataDrop(Element& s);
Expand Down
20 changes: 19 additions & 1 deletion src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ enum SIMDReplaceOp {
ReplaceLaneVecI32x4,
ReplaceLaneVecI64x2,
ReplaceLaneVecF32x4,
ReplaceLaneVecF64x2
ReplaceLaneVecF64x2,
};

enum SIMDShiftOp {
Expand Down Expand Up @@ -537,6 +537,11 @@ enum SIMDTernaryOp {
SignSelectVec64x2
};

enum SIMDWidenOp {
WidenSVecI8x16ToVecI32x4,
WidenUVecI8x16ToVecI32x4,
};

enum PrefetchOp {
PrefetchTemporal,
PrefetchNontemporal,
Expand Down Expand Up @@ -625,6 +630,7 @@ class Expression {
SIMDShiftId,
SIMDLoadId,
SIMDLoadStoreLaneId,
SIMDWidenId,
MemoryInitId,
DataDropId,
MemoryCopyId,
Expand Down Expand Up @@ -1072,6 +1078,18 @@ class SIMDLoadStoreLane
void finalize();
};

class SIMDWiden : public SpecificExpression<Expression::SIMDWidenId> {
public:
SIMDWiden() = default;
SIMDWiden(MixedArena& allocator) {}

SIMDWidenOp op;
uint8_t index;
Expression* vec;

void finalize();
};

class Prefetch : public SpecificExpression<Expression::PrefetchId> {
public:
Prefetch() = default;
Expand Down
24 changes: 24 additions & 0 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3005,6 +3005,9 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
if (maybeVisitSIMDLoadStoreLane(curr, opcode)) {
break;
}
if (maybeVisitSIMDWiden(curr, opcode)) {
break;
}
if (maybeVisitPrefetch(curr, opcode)) {
break;
}
Expand Down Expand Up @@ -5466,6 +5469,27 @@ bool WasmBinaryBuilder::maybeVisitSIMDLoadStoreLane(Expression*& out,
return true;
}

bool WasmBinaryBuilder::maybeVisitSIMDWiden(Expression*& out, uint32_t code) {
SIMDWidenOp op;
switch (code) {
case BinaryConsts::I32x4WidenSI8x16:
op = WidenSVecI8x16ToVecI32x4;
break;
case BinaryConsts::I32x4WidenUI8x16:
op = WidenUVecI8x16ToVecI32x4;
break;
default:
return false;
}
auto* curr = allocator.alloc<SIMDWiden>();
curr->op = op;
curr->index = getLaneIndex(4);
curr->vec = popNonVoidExpression();
curr->finalize();
out = curr;
return true;
}

bool WasmBinaryBuilder::maybeVisitPrefetch(Expression*& out, uint32_t code) {
PrefetchOp op;
switch (code) {
Expand Down
9 changes: 9 additions & 0 deletions src/wasm/wasm-s-parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,15 @@ SExpressionWasmBuilder::makeSIMDLoadStoreLane(Element& s,
return ret;
}

Expression* SExpressionWasmBuilder::makeSIMDWiden(Element& s, SIMDWidenOp op) {
auto* ret = allocator.alloc<SIMDWiden>();
ret->op = op;
ret->index = parseLaneIndex(s[1], 4);
ret->vec = parseExpression(s[2]);
ret->finalize();
return ret;
}

Expression* SExpressionWasmBuilder::makePrefetch(Element& s, PrefetchOp op) {
Address offset, align;
size_t i = parseMemAttributes(s, offset, align, /*defaultAlign*/ 1);
Expand Down
13 changes: 13 additions & 0 deletions src/wasm/wasm-stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,19 @@ void BinaryInstWriter::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {
o << curr->index;
}

void BinaryInstWriter::visitSIMDWiden(SIMDWiden* curr) {
o << int8_t(BinaryConsts::SIMDPrefix);
switch (curr->op) {
case WidenSVecI8x16ToVecI32x4:
o << U32LEB(BinaryConsts::I32x4WidenSI8x16);
break;
case WidenUVecI8x16ToVecI32x4:
o << U32LEB(BinaryConsts::I32x4WidenUI8x16);
break;
}
o << uint8_t(curr->index);
}

void BinaryInstWriter::visitPrefetch(Prefetch* curr) {
o << int8_t(BinaryConsts::SIMDPrefix);
switch (curr->op) {
Expand Down
5 changes: 5 additions & 0 deletions src/wasm/wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,11 @@ void SIMDLoadStoreLane::finalize() {
}
}

void SIMDWiden::finalize() {
assert(vec);
type = vec->type == Type::unreachable ? Type::unreachable : Type::v128;
}

Index SIMDLoadStoreLane::getMemBytes() {
switch (op) {
case LoadLaneVec8x16:
Expand Down
4 changes: 4 additions & 0 deletions src/wasm2js.h
Original file line number Diff line number Diff line change
Expand Up @@ -2119,6 +2119,10 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m,
unimplemented(curr);
WASM_UNREACHABLE("unimp");
}
Ref visitSIMDWiden(SIMDWiden* curr) {
unimplemented(curr);
WASM_UNREACHABLE("unimp");
}
Ref visitMemoryInit(MemoryInit* curr) {
ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::MEMORY_INIT);
return ValueBuilder::makeCall(ABI::wasm2js::MEMORY_INIT,
Expand Down
6 changes: 3 additions & 3 deletions test/binaryen.js/exception-handling.js.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
)
)

getExpressionInfo(throw) = {"id":47,"type":1,"event":"e"}
getExpressionInfo(rethrow) = {"id":48,"type":1,"depth":0}
getExpressionInfo(try) = {"id":46,"type":1,"hasCatchAll":0}
getExpressionInfo(throw) = {"id":48,"type":1,"event":"e"}
getExpressionInfo(rethrow) = {"id":49,"type":1,"depth":0}
getExpressionInfo(try) = {"id":47,"type":1,"hasCatchAll":0}
58 changes: 29 additions & 29 deletions test/binaryen.js/kitchen-sink.js.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,35 +76,35 @@ SIMDShuffleId: 32
SIMDTernaryId: 33
SIMDShiftId: 34
SIMDLoadId: 35
MemoryInitId: 37
DataDropId: 38
MemoryCopyId: 39
MemoryFillId: 40
PopId: 41
RefNullId: 42
RefIsId: 43
RefFuncId: 44
RefEqId: 45
TryId: 46
ThrowId: 47
RethrowId: 48
TupleMakeId: 49
TupleExtractId: 50
I31NewId: 51
I31GetId: 52
CallRefId: 53
RefTestId: 54
RefCastId: 55
BrOnId: 56
RttCanonId: 57
RttSubId: 58
StructNewId: 59
StructGetId: 60
StructSetId: 61
ArrayNewId: 62
ArrayGetId: 63
ArraySetId: 64
ArrayLenId: 65
MemoryInitId: 38
DataDropId: 39
MemoryCopyId: 40
MemoryFillId: 41
PopId: 42
RefNullId: 43
RefIsId: 44
RefFuncId: 45
RefEqId: 46
TryId: 47
ThrowId: 48
RethrowId: 49
TupleMakeId: 50
TupleExtractId: 51
I31NewId: 52
I31GetId: 53
CallRefId: 54
RefTestId: 55
RefCastId: 56
BrOnId: 57
RttCanonId: 58
RttSubId: 59
StructNewId: 60
StructGetId: 61
StructSetId: 62
ArrayNewId: 63
ArrayGetId: 64
ArraySetId: 65
ArrayLenId: 66
getExpressionInfo={"id":15,"type":4,"op":6}
(f32.neg
(f32.const -33.61199951171875)
Expand Down
10 changes: 10 additions & 0 deletions test/simd.wast
Original file line number Diff line number Diff line change
Expand Up @@ -1436,4 +1436,14 @@
(local.get $0)
)
)
(func $i32x4.widen_i8x16_s (param $0 v128) (result v128)
(i32x4.widen_i8x16_s 0
(local.get $0)
)
)
(func $i32x4.widen_i8x16_u (param $0 v128) (result v128)
(i32x4.widen_i8x16_u 0
(local.get $0)
)
)
)
10 changes: 10 additions & 0 deletions test/simd.wast.from-wast
Original file line number Diff line number Diff line change
Expand Up @@ -1454,4 +1454,14 @@
(local.get $0)
)
)
(func $i32x4.widen_i8x16_s (param $0 v128) (result v128)
(i32x4.widen_i8x16_s 0
(local.get $0)
)
)
(func $i32x4.widen_i8x16_u (param $0 v128) (result v128)
(i32x4.widen_i8x16_u 0
(local.get $0)
)
)
)
Loading

0 comments on commit ab7e625

Please sign in to comment.