summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binaryen-c.cpp18
-rw-r--r--src/binaryen-c.h6
-rw-r--r--src/emscripten-optimizer/istring.h7
-rw-r--r--src/gen-s-parser.inc33
-rw-r--r--src/js/binaryen.js-post.js24
-rw-r--r--src/passes/Print.cpp18
-rw-r--r--src/tools/fuzzing.h18
-rw-r--r--src/wasm-binary.h6
-rw-r--r--src/wasm-interpreter.h76
-rw-r--r--src/wasm.h8
-rw-r--r--src/wasm/wasm-binary.cpp24
-rw-r--r--src/wasm/wasm-s-parser.cpp6
-rw-r--r--src/wasm/wasm-stack.cpp18
-rw-r--r--src/wasm/wasm-validator.cpp20
-rw-r--r--src/wasm/wasm.cpp6
15 files changed, 278 insertions, 10 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 23f67874f..a4b3e9b5b 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -888,6 +888,24 @@ BinaryenOp BinaryenLoadSplatVec8x16(void) { return LoadSplatVec8x16; }
BinaryenOp BinaryenLoadSplatVec16x8(void) { return LoadSplatVec16x8; }
BinaryenOp BinaryenLoadSplatVec32x4(void) { return LoadSplatVec32x4; }
BinaryenOp BinaryenLoadSplatVec64x2(void) { return LoadSplatVec64x2; }
+BinaryenOp BinaryenLoadExtSVec8x8ToVecI16x8(void) {
+ return LoadExtSVec8x8ToVecI16x8;
+}
+BinaryenOp BinaryenLoadExtUVec8x8ToVecI16x8(void) {
+ return LoadExtUVec8x8ToVecI16x8;
+}
+BinaryenOp BinaryenLoadExtSVec16x4ToVecI32x4(void) {
+ return LoadExtSVec16x4ToVecI32x4;
+}
+BinaryenOp BinaryenLoadExtUVec16x4ToVecI32x4(void) {
+ return LoadExtUVec16x4ToVecI32x4;
+}
+BinaryenOp BinaryenLoadExtSVec32x2ToVecI64x2(void) {
+ return LoadExtSVec32x2ToVecI64x2;
+}
+BinaryenOp BinaryenLoadExtUVec32x2ToVecI64x2(void) {
+ return LoadExtUVec32x2ToVecI64x2;
+}
BinaryenOp BinaryenNarrowSVecI16x8ToVecI8x16(void) {
return NarrowSVecI16x8ToVecI8x16;
}
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index d6531fae0..a31df8cae 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -528,6 +528,12 @@ BINARYEN_API BinaryenOp BinaryenLoadSplatVec8x16(void);
BINARYEN_API BinaryenOp BinaryenLoadSplatVec16x8(void);
BINARYEN_API BinaryenOp BinaryenLoadSplatVec32x4(void);
BINARYEN_API BinaryenOp BinaryenLoadSplatVec64x2(void);
+BINARYEN_API BinaryenOp BinaryenLoadExtSVec8x8ToVecI16x8(void);
+BINARYEN_API BinaryenOp BinaryenLoadExtUVec8x8ToVecI16x8(void);
+BINARYEN_API BinaryenOp BinaryenLoadExtSVec16x4ToVecI32x4(void);
+BINARYEN_API BinaryenOp BinaryenLoadExtUVec16x4ToVecI32x4(void);
+BINARYEN_API BinaryenOp BinaryenLoadExtSVec32x2ToVecI64x2(void);
+BINARYEN_API BinaryenOp BinaryenLoadExtUVec32x2ToVecI64x2(void);
BINARYEN_API BinaryenOp BinaryenNarrowSVecI16x8ToVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenNarrowUVecI16x8ToVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenNarrowSVecI32x4ToVecI16x8(void);
diff --git a/src/emscripten-optimizer/istring.h b/src/emscripten-optimizer/istring.h
index 21f94fcb9..ccb08bf4b 100644
--- a/src/emscripten-optimizer/istring.h
+++ b/src/emscripten-optimizer/istring.h
@@ -161,16 +161,13 @@ struct IString {
namespace std {
-template<>
-struct hash<cashew::IString> : public unary_function<cashew::IString, size_t> {
+template<> struct hash<cashew::IString> {
size_t operator()(const cashew::IString& str) const {
return std::hash<size_t>{}(size_t(str.str));
}
};
-template<>
-struct equal_to<cashew::IString>
- : public binary_function<cashew::IString, cashew::IString, bool> {
+template<> struct equal_to<cashew::IString> {
bool operator()(const cashew::IString& x, const cashew::IString& y) const {
return x == y;
}
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc
index e9da45a18..bab468e2a 100644
--- a/src/gen-s-parser.inc
+++ b/src/gen-s-parser.inc
@@ -760,6 +760,17 @@ switch (op[0]) {
default: goto parse_error;
}
}
+ case 'o': {
+ switch (op[14]) {
+ case 's':
+ if (strcmp(op, "i16x8.load8x8_s") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadExtSVec8x8ToVecI16x8); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i16x8.load8x8_u") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadExtUVec8x8ToVecI16x8); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
case 't': {
switch (op[9]) {
case 's':
@@ -1414,6 +1425,17 @@ switch (op[0]) {
default: goto parse_error;
}
}
+ case 'o': {
+ switch (op[15]) {
+ case 's':
+ if (strcmp(op, "i32x4.load16x4_s") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadExtSVec16x4ToVecI32x4); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i32x4.load16x4_u") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadExtUVec16x4ToVecI32x4); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
case 't': {
switch (op[9]) {
case 's':
@@ -2069,6 +2091,17 @@ switch (op[0]) {
case 'e':
if (strcmp(op, "i64x2.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI64x2, 2); }
goto parse_error;
+ case 'l': {
+ switch (op[15]) {
+ case 's':
+ if (strcmp(op, "i64x2.load32x2_s") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadExtSVec32x2ToVecI64x2); }
+ goto parse_error;
+ case 'u':
+ if (strcmp(op, "i64x2.load32x2_u") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadExtUVec32x2ToVecI64x2); }
+ goto parse_error;
+ default: goto parse_error;
+ }
+ }
case 'n':
if (strcmp(op, "i64x2.neg") == 0) { return makeUnary(s, UnaryOp::NegVecI64x2); }
goto parse_error;
diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js
index 3e1ccd2f8..8769e1c9e 100644
--- a/src/js/binaryen.js-post.js
+++ b/src/js/binaryen.js-post.js
@@ -400,6 +400,12 @@ Module['LoadSplatVec8x16'] = Module['_BinaryenLoadSplatVec8x16']();
Module['LoadSplatVec16x8'] = Module['_BinaryenLoadSplatVec16x8']();
Module['LoadSplatVec32x4'] = Module['_BinaryenLoadSplatVec32x4']();
Module['LoadSplatVec64x2'] = Module['_BinaryenLoadSplatVec64x2']();
+Module['LoadExtSVec8x8ToVecI16x8'] = Module['_BinaryenLoadExtSVec8x8ToVecI16x8']();
+Module['LoadExtUVec8x8ToVecI16x8'] = Module['_BinaryenLoadExtUVec8x8ToVecI16x8']();
+Module['LoadExtSVec16x4ToVecI32x4'] = Module['_BinaryenLoadExtSVec16x4ToVecI32x4']();
+Module['LoadExtUVec16x4ToVecI32x4'] = Module['_BinaryenLoadExtUVec16x4ToVecI32x4']();
+Module['LoadExtSVec32x2ToVecI64x2'] = Module['_BinaryenLoadExtSVec32x2ToVecI64x2']();
+Module['LoadExtUVec32x2ToVecI64x2'] = Module['_BinaryenLoadExtUVec32x2ToVecI64x2']();
Module['NarrowSVecI16x8ToVecI8x16'] = Module['_BinaryenNarrowSVecI16x8ToVecI8x16']();
Module['NarrowUVecI16x8ToVecI8x16'] = Module['_BinaryenNarrowUVecI16x8ToVecI8x16']();
Module['NarrowSVecI32x4ToVecI16x8'] = Module['_BinaryenNarrowSVecI32x4ToVecI16x8']();
@@ -1546,6 +1552,12 @@ function wrapModule(module, self) {
'widen_high_i8x16_u': function(value) {
return Module['_BinaryenUnary'](module, Module['WidenHighUVecI8x16ToVecI16x8'], value);
},
+ 'load8x8_s': function(offset, align, ptr) {
+ return Module['_BinaryenSIMDLoad'](module, Module['LoadExtSVec8x8ToVecI16x8'], offset, align, ptr);
+ },
+ 'load8x8_u': function(offset, align, ptr) {
+ return Module['_BinaryenSIMDLoad'](module, Module['LoadExtUVec8x8ToVecI16x8'], offset, align, ptr);
+ },
};
self['i32x4'] = {
@@ -1633,6 +1645,12 @@ function wrapModule(module, self) {
'widen_high_i16x8_u': function(value) {
return Module['_BinaryenUnary'](module, Module['WidenHighUVecI16x8ToVecI32x4'], value);
},
+ 'load16x4_s': function(offset, align, ptr) {
+ return Module['_BinaryenSIMDLoad'](module, Module['LoadExtSVec16x4ToVecI32x4'], offset, align, ptr);
+ },
+ 'load16x4_u': function(offset, align, ptr) {
+ return Module['_BinaryenSIMDLoad'](module, Module['LoadExtUVec16x4ToVecI32x4'], offset, align, ptr);
+ },
};
self['i64x2'] = {
@@ -1675,6 +1693,12 @@ function wrapModule(module, self) {
'trunc_sat_f64x2_u': function(value) {
return Module['_BinaryenUnary'](module, Module['TruncSatUVecF64x2ToVecI64x2'], value);
},
+ 'load32x2_s': function(offset, align, ptr) {
+ return Module['_BinaryenSIMDLoad'](module, Module['LoadExtSVec32x2ToVecI64x2'], offset, align, ptr);
+ },
+ 'load32x2_u': function(offset, align, ptr) {
+ return Module['_BinaryenSIMDLoad'](module, Module['LoadExtUVec32x2ToVecI64x2'], offset, align, ptr);
+ },
};
self['f32x4'] = {
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index e73747a4f..b856b2000 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -406,6 +406,24 @@ struct PrintExpressionContents
case LoadSplatVec64x2:
o << "v64x2.load_splat";
break;
+ case LoadExtSVec8x8ToVecI16x8:
+ o << "i16x8.load8x8_s";
+ break;
+ case LoadExtUVec8x8ToVecI16x8:
+ o << "i16x8.load8x8_u";
+ break;
+ case LoadExtSVec16x4ToVecI32x4:
+ o << "i32x4.load16x4_s";
+ break;
+ case LoadExtUVec16x4ToVecI32x4:
+ o << "i32x4.load16x4_u";
+ break;
+ case LoadExtSVec32x2ToVecI64x2:
+ o << "i64x2.load32x2_s";
+ break;
+ case LoadExtUVec32x2ToVecI64x2:
+ o << "i64x2.load32x2_u";
+ break;
}
restoreNormalColor(o);
if (curr->offset) {
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index 39cff56d5..45ddc59b1 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -2492,8 +2492,16 @@ private:
}
Expression* makeSIMDLoad() {
- SIMDLoadOp op = pick(
- LoadSplatVec8x16, LoadSplatVec16x8, LoadSplatVec32x4, LoadSplatVec64x2);
+ SIMDLoadOp op = pick(LoadSplatVec8x16,
+ LoadSplatVec16x8,
+ LoadSplatVec32x4,
+ LoadSplatVec64x2,
+ LoadExtSVec8x8ToVecI16x8,
+ LoadExtUVec8x8ToVecI16x8,
+ LoadExtSVec16x4ToVecI32x4,
+ LoadExtUVec16x4ToVecI32x4,
+ LoadExtSVec32x2ToVecI64x2,
+ LoadExtUVec32x2ToVecI64x2);
Address offset = logify(get());
Address align;
switch (op) {
@@ -2507,6 +2515,12 @@ private:
align = pick(1, 2, 4);
break;
case LoadSplatVec64x2:
+ case LoadExtSVec8x8ToVecI16x8:
+ case LoadExtUVec8x8ToVecI16x8:
+ case LoadExtSVec16x4ToVecI32x4:
+ case LoadExtUVec16x4ToVecI32x4:
+ case LoadExtSVec32x2ToVecI64x2:
+ case LoadExtUVec32x2ToVecI64x2:
align = pick(1, 2, 4, 8);
break;
}
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 8de833a79..f299099b2 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -873,6 +873,12 @@ enum ASTNodes {
I32x4WidenHighSI16x8 = 0xcf,
I32x4WidenLowUI16x8 = 0xd0,
I32x4WidenHighUI16x8 = 0xd1,
+ I16x8LoadExtSVec8x8 = 0xd2,
+ I16x8LoadExtUVec8x8 = 0xd3,
+ I32x4LoadExtSVec16x4 = 0xd4,
+ I32x4LoadExtUVec16x4 = 0xd5,
+ I64x2LoadExtSVec32x2 = 0xd6,
+ I64x2LoadExtUVec32x2 = 0xd7,
// bulk memory opcodes
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 94a3f0d54..8c429caa9 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -1086,6 +1086,8 @@ public:
Flow visitAtomicWait(AtomicWait*) { WASM_UNREACHABLE(); }
Flow visitAtomicNotify(AtomicNotify*) { WASM_UNREACHABLE(); }
Flow visitSIMDLoad(SIMDLoad*) { WASM_UNREACHABLE(); }
+ Flow visitSIMDLoadSplat(SIMDLoad*) { WASM_UNREACHABLE(); }
+ Flow visitSIMDLoadExtend(SIMDLoad*) { WASM_UNREACHABLE(); }
Flow visitPush(Push*) { WASM_UNREACHABLE(); }
Flow visitPop(Pop*) { WASM_UNREACHABLE(); }
Flow visitTry(Try*) { WASM_UNREACHABLE(); }
@@ -1702,6 +1704,23 @@ private:
}
Flow visitSIMDLoad(SIMDLoad* curr) {
NOTE_ENTER("SIMDLoad");
+ switch (curr->op) {
+ case LoadSplatVec8x16:
+ case LoadSplatVec16x8:
+ case LoadSplatVec32x4:
+ case LoadSplatVec64x2:
+ return visitSIMDLoadSplat(curr);
+ case LoadExtSVec8x8ToVecI16x8:
+ case LoadExtUVec8x8ToVecI16x8:
+ case LoadExtSVec16x4ToVecI32x4:
+ case LoadExtUVec16x4ToVecI32x4:
+ case LoadExtSVec32x2ToVecI64x2:
+ case LoadExtUVec32x2ToVecI64x2:
+ return visitSIMDLoadExtend(curr);
+ }
+ WASM_UNREACHABLE();
+ }
+ Flow visitSIMDLoadSplat(SIMDLoad* curr) {
Load load;
load.type = i32;
load.bytes = curr->getMemBytes();
@@ -1725,6 +1744,8 @@ private:
load.type = i64;
splat = &Literal::splatI64x2;
break;
+ default:
+ WASM_UNREACHABLE();
}
load.finalize();
Flow flow = this->visit(&load);
@@ -1733,6 +1754,61 @@ private:
}
return (flow.value.*splat)();
}
+ Flow visitSIMDLoadExtend(SIMDLoad* curr) {
+ Flow flow = this->visit(curr->ptr);
+ if (flow.breaking()) {
+ return flow;
+ }
+ NOTE_EVAL1(flow);
+ Address src(uint32_t(flow.value.geti32()));
+ auto loadLane = [&](Address addr) {
+ switch (curr->op) {
+ case LoadExtSVec8x8ToVecI16x8:
+ return Literal(int32_t(instance.externalInterface->load8s(addr)));
+ case LoadExtUVec8x8ToVecI16x8:
+ return Literal(int32_t(instance.externalInterface->load8u(addr)));
+ case LoadExtSVec16x4ToVecI32x4:
+ return Literal(int32_t(instance.externalInterface->load16s(addr)));
+ case LoadExtUVec16x4ToVecI32x4:
+ return Literal(int32_t(instance.externalInterface->load16u(addr)));
+ case LoadExtSVec32x2ToVecI64x2:
+ return Literal(int64_t(instance.externalInterface->load32s(addr)));
+ case LoadExtUVec32x2ToVecI64x2:
+ return Literal(int64_t(instance.externalInterface->load32u(addr)));
+ default:
+ WASM_UNREACHABLE();
+ }
+ WASM_UNREACHABLE();
+ };
+ auto fillLanes = [&](auto lanes, size_t laneBytes) {
+ for (auto& lane : lanes) {
+ lane = loadLane(
+ instance.getFinalAddress(Literal(uint32_t(src)), laneBytes));
+ src = Address(uint32_t(src) + laneBytes);
+ }
+ return Literal(lanes);
+ };
+ switch (curr->op) {
+ case LoadExtSVec8x8ToVecI16x8:
+ case LoadExtUVec8x8ToVecI16x8: {
+ std::array<Literal, 8> lanes;
+ return fillLanes(lanes, 1);
+ }
+ case LoadExtSVec16x4ToVecI32x4:
+ case LoadExtUVec16x4ToVecI32x4: {
+ std::array<Literal, 4> lanes;
+ return fillLanes(lanes, 2);
+ }
+ case LoadExtSVec32x2ToVecI64x2:
+ case LoadExtUVec32x2ToVecI64x2: {
+ std::array<Literal, 2> lanes;
+ return fillLanes(lanes, 4);
+ }
+ default:
+ WASM_UNREACHABLE();
+ }
+ WASM_UNREACHABLE();
+ }
Flow visitHost(Host* curr) {
NOTE_ENTER("Host");
switch (curr->op) {
diff --git a/src/wasm.h b/src/wasm.h
index 7aa3ecea3..8006bd319 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -438,7 +438,13 @@ enum SIMDLoadOp {
LoadSplatVec8x16,
LoadSplatVec16x8,
LoadSplatVec32x4,
- LoadSplatVec64x2
+ LoadSplatVec64x2,
+ LoadExtSVec8x8ToVecI16x8,
+ LoadExtUVec8x8ToVecI16x8,
+ LoadExtSVec16x4ToVecI32x4,
+ LoadExtUVec16x4ToVecI32x4,
+ LoadExtSVec32x2ToVecI64x2,
+ LoadExtUVec32x2ToVecI64x2
};
enum SIMDTernaryOp { Bitselect, QFMAF32x4, QFMSF32x4, QFMAF64x2, QFMSF64x2 };
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 6f10df8f5..1606d74a1 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -4413,6 +4413,30 @@ bool WasmBinaryBuilder::maybeVisitSIMDLoad(Expression*& out, uint32_t code) {
curr = allocator.alloc<SIMDLoad>();
curr->op = LoadSplatVec64x2;
break;
+ case BinaryConsts::I16x8LoadExtSVec8x8:
+ curr = allocator.alloc<SIMDLoad>();
+ curr->op = LoadExtSVec8x8ToVecI16x8;
+ break;
+ case BinaryConsts::I16x8LoadExtUVec8x8:
+ curr = allocator.alloc<SIMDLoad>();
+ curr->op = LoadExtUVec8x8ToVecI16x8;
+ break;
+ case BinaryConsts::I32x4LoadExtSVec16x4:
+ curr = allocator.alloc<SIMDLoad>();
+ curr->op = LoadExtSVec16x4ToVecI32x4;
+ break;
+ case BinaryConsts::I32x4LoadExtUVec16x4:
+ curr = allocator.alloc<SIMDLoad>();
+ curr->op = LoadExtUVec16x4ToVecI32x4;
+ break;
+ case BinaryConsts::I64x2LoadExtSVec32x2:
+ curr = allocator.alloc<SIMDLoad>();
+ curr->op = LoadExtSVec32x2ToVecI64x2;
+ break;
+ case BinaryConsts::I64x2LoadExtUVec32x2:
+ curr = allocator.alloc<SIMDLoad>();
+ curr->op = LoadExtUVec32x2ToVecI64x2;
+ break;
default:
return false;
}
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 9f1fe0044..72d262e63 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -1508,6 +1508,12 @@ Expression* SExpressionWasmBuilder::makeSIMDLoad(Element& s, SIMDLoadOp op) {
defaultAlign = 4;
break;
case LoadSplatVec64x2:
+ case LoadExtSVec8x8ToVecI16x8:
+ case LoadExtUVec8x8ToVecI16x8:
+ case LoadExtSVec16x4ToVecI32x4:
+ case LoadExtUVec16x4ToVecI32x4:
+ case LoadExtSVec32x2ToVecI64x2:
+ case LoadExtUVec32x2ToVecI64x2:
defaultAlign = 8;
break;
}
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index cbe5ba881..8b7ccfb2e 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -569,6 +569,24 @@ void BinaryInstWriter::visitSIMDLoad(SIMDLoad* curr) {
case LoadSplatVec64x2:
o << U32LEB(BinaryConsts::V64x2LoadSplat);
break;
+ case LoadExtSVec8x8ToVecI16x8:
+ o << U32LEB(BinaryConsts::I16x8LoadExtSVec8x8);
+ break;
+ case LoadExtUVec8x8ToVecI16x8:
+ o << U32LEB(BinaryConsts::I16x8LoadExtUVec8x8);
+ break;
+ case LoadExtSVec16x4ToVecI32x4:
+ o << U32LEB(BinaryConsts::I32x4LoadExtSVec16x4);
+ break;
+ case LoadExtUVec16x4ToVecI32x4:
+ o << U32LEB(BinaryConsts::I32x4LoadExtUVec16x4);
+ break;
+ case LoadExtSVec32x2ToVecI64x2:
+ o << U32LEB(BinaryConsts::I64x2LoadExtSVec32x2);
+ break;
+ case LoadExtUVec32x2ToVecI64x2:
+ o << U32LEB(BinaryConsts::I64x2LoadExtUVec32x2);
+ break;
}
assert(curr->align);
emitMemoryAccess(curr->align, /*(unused) bytes=*/0, curr->offset);
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 78c8d3289..1c30d0d2a 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1064,9 +1064,25 @@ void FunctionValidator::visitSIMDLoad(SIMDLoad* curr) {
curr->type, v128, curr, "load_splat must have type v128");
shouldBeEqualOrFirstIsUnreachable(
curr->ptr->type, i32, curr, "load_splat address must have type i32");
- Type lane_t = curr->op == LoadSplatVec64x2 ? i64 : i32;
+ Type memAlignType = none;
+ switch (curr->op) {
+ case LoadSplatVec8x16:
+ case LoadSplatVec16x8:
+ case LoadSplatVec32x4:
+ memAlignType = i32;
+ break;
+ case LoadSplatVec64x2:
+ case LoadExtSVec8x8ToVecI16x8:
+ case LoadExtUVec8x8ToVecI16x8:
+ case LoadExtSVec16x4ToVecI32x4:
+ case LoadExtUVec16x4ToVecI32x4:
+ case LoadExtSVec32x2ToVecI64x2:
+ case LoadExtUVec32x2ToVecI64x2:
+ memAlignType = i64;
+ break;
+ }
Index bytes = curr->getMemBytes();
- validateAlignment(curr->align, lane_t, bytes, /*isAtomic=*/false, curr);
+ validateAlignment(curr->align, memAlignType, bytes, /*isAtomic=*/false, curr);
}
void FunctionValidator::visitMemoryInit(MemoryInit* curr) {
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index 58510cc8f..72fed6c7b 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -645,6 +645,12 @@ Index SIMDLoad::getMemBytes() {
case LoadSplatVec32x4:
return 4;
case LoadSplatVec64x2:
+ case LoadExtSVec8x8ToVecI16x8:
+ case LoadExtUVec8x8ToVecI16x8:
+ case LoadExtSVec16x4ToVecI32x4:
+ case LoadExtUVec16x4ToVecI32x4:
+ case LoadExtSVec32x2ToVecI64x2:
+ case LoadExtUVec32x2ToVecI64x2:
return 8;
}
WASM_UNREACHABLE();