Commit 117f6ef4 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd] Fix decoding of load splats

Load splat opcodes are currently multi-byte, but were not passing the
right lengths for decoding of immediates.

Bug: v8:10258
Change-Id: I2c93c3f915eaa43a74722cf0285f161d16ef0ff6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2154769Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67326}
parent 961d4ce2
......@@ -1442,7 +1442,8 @@ class WasmDecoder : public Decoder {
FOREACH_SIMD_MEM_OPCODE(DECLARE_OPCODE_CASE)
#undef DECLARE_OPCODE_CASE
{
MemoryAccessImmediate<validate> imm(decoder, pc + 1, UINT32_MAX);
MemoryAccessImmediate<validate> imm(decoder, pc + length,
UINT32_MAX);
return 1 + length + imm.length;
}
// Shuffles require a byte per lane, or 16 immediate bytes.
......
......@@ -2762,8 +2762,11 @@ class ThreadImpl {
template <typename s_type, typename result_type, typename load_type>
bool DoSimdLoadSplat(Decoder* decoder, InterpreterCode* code, pc_t pc,
int* const len, MachineRepresentation rep) {
// len is the number of bytes the make up this op, including prefix byte, so
// the prefix_len for ExecuteLoad is len, minus the prefix byte itself.
// Think of prefix_len as: number of extra bytes that make up this op.
if (!ExecuteLoad<result_type, load_type>(decoder, code, pc, len, rep,
/*prefix_len=*/1)) {
/*prefix_len=*/*len - 1)) {
return false;
}
result_type v = Pop().to<result_type>();
......
......@@ -483,6 +483,8 @@ bool ExpectFused(ExecutionTier tier) {
#define WASM_SIMD_LOAD_SPLAT(opcode, index) \
index, WASM_SIMD_OP(opcode), ZERO_ALIGNMENT, ZERO_OFFSET
#define WASM_SIMD_LOAD_SPLAT_OFFSET(opcode, index, offset) \
index, WASM_SIMD_OP(opcode), ZERO_ALIGNMENT, offset
#define WASM_SIMD_LOAD_EXTEND(opcode, index) \
index, WASM_SIMD_OP(opcode), ZERO_ALIGNMENT, ZERO_OFFSET
......@@ -3439,6 +3441,29 @@ WASM_SIMD_TEST(SimdLoadStoreLoadMemargOffset) {
}
}
// Test a multi-byte opcode with offset values that encode into valid opcodes.
// This is to exercise decoding logic and make sure we get the lengths right.
WASM_SIMD_TEST(S8x16LoadSplatOffset) {
// This offset is [82, 22] when encoded, which contains valid opcodes.
constexpr int offset = 4354;
WasmRunner<int32_t> r(execution_tier, lower_simd);
int8_t* memory = r.builder().AddMemoryElems<int8_t>(kWasmPageSize);
int8_t* global = r.builder().AddGlobal<int8_t>(kWasmS128);
BUILD_V(r,
WASM_SET_GLOBAL(
0, WASM_SIMD_LOAD_SPLAT_OFFSET(kExprS8x16LoadSplat, WASM_I32V(0),
U32V_2(offset))),
WASM_ONE);
// We don't really care about all valid values, so just test for 1.
int8_t x = 7;
r.builder().WriteMemory(&memory[offset], x);
r.Call();
for (int i = 0; i < 16; i++) {
CHECK_EQ(x, ReadLittleEndianValue<int8_t>(&global[i]));
}
}
template <typename T>
void RunLoadSplatTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode op) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment