Skip to content

Commit 6fb4764

Browse files
committed
[Wasm SIMD] Don't use view type for v128 alignment
Define natural alignment separately from ArrayBufferView for 128-bit SIMD. Don't use alignment in calculating array buffer index. Tests: minor (expected vs actual) and major (remove `align=4`) tweaks. Fixes #6258 Contributes to #6259
1 parent b473659 commit 6fb4764

File tree

9 files changed

+41
-30
lines changed

9 files changed

+41
-30
lines changed

lib/Runtime/Language/AsmJsArrayBufferViews.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#endif
1818

1919
// (Name , Align , RegType, MemType , irSuffix )
20+
// (log2)
2021
ARRAYBUFFER_VIEW_INT(INT8 , 0 , int32 , int8 , Int8 )
2122
ARRAYBUFFER_VIEW_INT(UINT8 , 0 , int32 , uint8 , Uint8 )
2223
ARRAYBUFFER_VIEW_INT(INT16 , 1 , int32 , int16 , Int16 )

lib/Runtime/Language/InterpreterStackFrame.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8161,7 +8161,12 @@ namespace Js
81618161
void InterpreterStackFrame::OP_SimdLdArrGeneric(const unaligned T* playout)
81628162
{
81638163
Assert(playout->ViewType < Js::ArrayBufferView::TYPE_COUNT);
8164-
const uint64 index = ((uint64)(uint32)GetRegRawInt(playout->SlotIndex) + playout->Offset /* WASM only */) & (int64)(int)ArrayBufferView::ViewMask[playout->ViewType];
8164+
8165+
if (GetRegRawInt(playout->SlotIndex) < 0) {
8166+
JavascriptError::ThrowRangeError(scriptContext, JSERR_ArgumentOutOfRange, _u("Simd typed array access"));
8167+
}
8168+
8169+
const uint64 index = (uint64)GetRegRawInt(playout->SlotIndex) + playout->Offset;
81658170

81668171
ArrayBufferBase* arr =
81678172
#ifdef ENABLE_WASM_SIMD
@@ -8209,7 +8214,12 @@ namespace Js
82098214
void InterpreterStackFrame::OP_SimdStArrGeneric(const unaligned T* playout)
82108215
{
82118216
Assert(playout->ViewType < Js::ArrayBufferView::TYPE_COUNT);
8212-
const uint64 index = ((uint64)(uint32)GetRegRawInt(playout->SlotIndex) + playout->Offset /* WASM only */) & (int64)(int)ArrayBufferView::ViewMask[playout->ViewType];
8217+
8218+
if (GetRegRawInt(playout->SlotIndex) < 0)
8219+
{
8220+
JavascriptError::ThrowRangeError(scriptContext, JSERR_ArgumentOutOfRange, _u("Simd typed array access"));
8221+
}
8222+
const uint64 index = (uint64)GetRegRawInt(playout->SlotIndex) + playout->Offset;
82138223

82148224
ArrayBufferBase* arr =
82158225
#ifdef ENABLE_WASM_SIMD

lib/WasmReader/WasmByteCodeGenerator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,11 +1604,11 @@ EmitInfo WasmBytecodeGenerator::EmitSimdMemAccess(Js::OpCodeAsmJs op, const Wasm
16041604
WasmTypes::WasmType type = signature[0];
16051605
SetUsesMemory(0);
16061606

1607-
const uint32 mask = Js::ArrayBufferView::ViewMask[viewType];
1607+
const uint32 naturalAlignment = 16;
16081608
const uint alignment = GetReader()->m_currentNode.mem.alignment;
16091609
const uint offset = GetReader()->m_currentNode.mem.offset;
16101610

1611-
if ((mask << 1) & (1 << alignment))
1611+
if (alignment > naturalAlignment)
16121612
{
16131613
throw WasmCompilationException(_u("alignment must not be larger than natural"));
16141614
}

test/wasm.simd/loadTests.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function testLoadOpsForType(funcname, module, laneValues, expectedResults, start
2929

3030
forEachTestPosition ((pos, i) => {intArray[pos + i] = laneValues[i];});
3131
instance[funcname](0);
32-
forEachTestPosition((pos, i) => {assertEquals(intArray[pos + i], expectedResults[i]);});
32+
forEachTestPosition((pos, i) => {assertEquals(expectedResults[i], intArray[pos + i]);});
3333

3434
const MEM_SIZE_IN_BYTES = 1024 * 64;
3535

@@ -76,8 +76,8 @@ const laneValues = [0xAAAAAAAA, 0xFFFFFFFF, 0X80000000, 0x90A762A6];
7676
const expectedResults = [16, 32, 1, 14]; //i32.popcnt
7777
const startPositions = [0, 5, 11, 17];
7878

79-
testLoadOpsForType("m128_load_test", module, laneValues, expectedResults,startPositions);
79+
testLoadOpsForType("m128_load_test", module, laneValues, expectedResults, startPositions);
8080

8181
if (passed) {
8282
print("Passed");
83-
}
83+
}

test/wasm.simd/loads.wasm

0 Bytes
Binary file not shown.

test/wasm.simd/loads.wast

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,48 +7,48 @@
77
(import "dummy" "memory" (memory 1))
88

99
(func (export "m128_load4") (param $x i32) (result i32)
10-
(i32x4.extract_lane 0 (v128.load offset=0 align=4 (get_local $x)))
10+
(i32x4.extract_lane 0 (v128.load offset=0 (get_local $x)))
1111
)
1212

1313
(func (export "m128_load4_offset") (param $x i32) (result i32)
14-
(i32x4.extract_lane 0 (v128.load offset=16 align=4 (get_local $x)))
14+
(i32x4.extract_lane 0 (v128.load offset=16 (get_local $x)))
1515
)
1616

1717
(func (export "m128_load_test") (param $x i32) (local v128)
18-
(set_local 1 (v128.load offset=0 align=4 (get_local $x)))
18+
(set_local 1 (v128.load offset=0 (get_local $x)))
1919
(i32.store offset=0 (get_local $x) (i32.popcnt (i32x4.extract_lane 0 (get_local 1))))
20-
(set_local 1 (v128.load offset=0 align=4 (get_local $x)))
20+
(set_local 1 (v128.load offset=0 (get_local $x)))
2121
(i32.store offset=4 (get_local $x) (i32.popcnt (i32x4.extract_lane 1 (get_local 1))))
22-
(set_local 1 (v128.load offset=0 align=4 (get_local $x)))
22+
(set_local 1 (v128.load offset=0 (get_local $x)))
2323
(i32.store offset=8 (get_local $x) (i32.popcnt (i32x4.extract_lane 2 (get_local 1))))
24-
(set_local 1 (v128.load offset=0 align=4 (get_local $x)))
24+
(set_local 1 (v128.load offset=0 (get_local $x)))
2525
(i32.store offset=12 (get_local $x) (i32.popcnt (i32x4.extract_lane 3 (get_local 1))))
2626
;;
27-
(set_local 1 (v128.load offset=20 align=4 (get_local $x)))
27+
(set_local 1 (v128.load offset=20 (get_local $x)))
2828
(i32.store offset=20 (get_local $x) (i32.popcnt (i32x4.extract_lane 0 (get_local 1))))
29-
(set_local 1 (v128.load offset=20 align=4 (get_local $x)))
29+
(set_local 1 (v128.load offset=20 (get_local $x)))
3030
(i32.store offset=24 (get_local $x) (i32.popcnt (i32x4.extract_lane 1 (get_local 1))))
31-
(set_local 1 (v128.load offset=20 align=4 (get_local $x)))
31+
(set_local 1 (v128.load offset=20 (get_local $x)))
3232
(i32.store offset=28 (get_local $x) (i32.popcnt (i32x4.extract_lane 2 (get_local 1))))
33-
(set_local 1 (v128.load offset=20 align=4 (get_local $x)))
33+
(set_local 1 (v128.load offset=20 (get_local $x)))
3434
(i32.store offset=32 (get_local $x) (i32.popcnt (i32x4.extract_lane 3 (get_local 1))))
3535
;;
36-
(set_local 1 (v128.load offset=44 align=4 (get_local $x)))
36+
(set_local 1 (v128.load offset=44 (get_local $x)))
3737
(i32.store offset=44 (get_local $x) (i32.popcnt (i32x4.extract_lane 0 (get_local 1))))
38-
(set_local 1 (v128.load offset=44 align=4 (get_local $x)))
38+
(set_local 1 (v128.load offset=44 (get_local $x)))
3939
(i32.store offset=48 (get_local $x) (i32.popcnt (i32x4.extract_lane 1 (get_local 1))))
40-
(set_local 1 (v128.load offset=44 align=4 (get_local $x)))
40+
(set_local 1 (v128.load offset=44 (get_local $x)))
4141
(i32.store offset=52 (get_local $x) (i32.popcnt (i32x4.extract_lane 2 (get_local 1))))
42-
(set_local 1 (v128.load offset=44 align=4 (get_local $x)))
42+
(set_local 1 (v128.load offset=44 (get_local $x)))
4343
(i32.store offset=56 (get_local $x) (i32.popcnt (i32x4.extract_lane 3 (get_local 1))))
4444
;;
45-
(set_local 1 (v128.load offset=68 align=4 (get_local $x)))
45+
(set_local 1 (v128.load offset=68 (get_local $x)))
4646
(i32.store offset=68 (get_local $x) (i32.popcnt (i32x4.extract_lane 0 (get_local 1))))
47-
(set_local 1 (v128.load offset=68 align=4 (get_local $x)))
47+
(set_local 1 (v128.load offset=68 (get_local $x)))
4848
(i32.store offset=72 (get_local $x) (i32.popcnt (i32x4.extract_lane 1 (get_local 1))))
49-
(set_local 1 (v128.load offset=68 align=4 (get_local $x)))
49+
(set_local 1 (v128.load offset=68 (get_local $x)))
5050
(i32.store offset=76 (get_local $x) (i32.popcnt (i32x4.extract_lane 2 (get_local 1))))
51-
(set_local 1 (v128.load offset=68 align=4 (get_local $x)))
51+
(set_local 1 (v128.load offset=68 (get_local $x)))
5252
(i32.store offset=80 (get_local $x) (i32.popcnt (i32x4.extract_lane 3 (get_local 1))))
5353
)
5454
)

test/wasm.simd/storeTests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,4 @@ check(undefined, "instance.m128_store4", MEM_SIZE_IN_BYTES - 16, 777, 888, 999,
6666

6767
if (passed) {
6868
print("Passed");
69-
}
69+
}

test/wasm.simd/stores.wasm

0 Bytes
Binary file not shown.

test/wasm.simd/stores.wast

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
(import "dummy" "memory" (memory 1))
88

99
(func (export "m128_store4") (param i32 i32 i32 i32 i32) (local v128)
10-
(set_local 5 (v128.load offset=0 align=4 (i32.const 16)))
11-
(v128.store offset=0 align=4 (get_local 0) (get_local 5))
10+
(set_local 5 (v128.load offset=0 (i32.const 16)))
11+
(v128.store offset=0 (get_local 0) (get_local 5))
1212
)
1313

1414
(func (export "m128_store4_offset") (param i32 i32 i32 i32 i32) (local v128)
15-
(set_local 5 (v128.load offset=0 align=4 (i32.const 16)))
16-
(v128.store offset=16 align=4 (get_local 0) (get_local 5))
15+
(set_local 5 (v128.load offset=0 (i32.const 16)))
16+
(v128.store offset=16 (get_local 0) (get_local 5))
1717
)
1818
)

0 commit comments

Comments
 (0)