blob: 482fb423adc438784203e1379062babef52d5c7a [file] [edit]
//@ requireOptions("--useWasmSIMD=1")
//@ skip if !$isSIMDPlatform
import { instantiate } from "../wabt-wrapper.js"
import * as assert from "../assert.js"
// Test chained shuffle composition (shuffle-of-shuffle optimization)
// and same-child binary shuffle normalization.
async function test() {
let wat = `(module
(memory (export "mem") 1)
;; unpackhi(a, unpacklo(b, b)):
;; Inner: shuffle(b, b, {0..7, 16..23}) = dup low qword of b
;; Outer: shuffle(a, inner, {8..15, 24..31}) = {a[8..15], inner[8..15]=[b[0..7]]}
;; Composed result: {a[8..15], b[0..7]}
(func (export "unpackhi_unpacklo") (param i32 i32)
(v128.store (i32.const 32)
(i8x16.shuffle 8 9 10 11 12 13 14 15 24 25 26 27 28 29 30 31
(v128.load (local.get 0))
(i8x16.shuffle 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23
(v128.load (local.get 1))
(v128.load (local.get 1))))))
;; Same child on both sides: shuffle(x, x, {0..7, 16..23}) dup low qword
(func (export "dup_low_qword") (param i32)
(v128.store (i32.const 16)
(i8x16.shuffle 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23
(v128.load (local.get 0))
(v128.load (local.get 0)))))
;; Identity shuffle
(func (export "identity") (param i32)
(v128.store (i32.const 16)
(i8x16.shuffle 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
(v128.load (local.get 0))
(v128.load (local.get 0)))))
)`
const instance = await instantiate(wat, {}, { simd: true })
const mem = new Uint8Array(instance.exports.mem.buffer)
// Set up: a = [0..15] at offset 0, b = [16..31] at offset 64
for (let i = 0; i < 16; i++) {
mem[i] = i
mem[64 + i] = 16 + i
}
function getResult(offset, len) {
return Array.from(mem.slice(offset, offset + len)).join(',')
}
// unpackhi_unpacklo: {a[8..15], b[0..7]}
instance.exports.unpackhi_unpacklo(0, 64)
assert.eq(getResult(32, 16), '8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23')
// dup_low_qword: {a[0..7], a[0..7]}
instance.exports.dup_low_qword(0)
assert.eq(getResult(16, 16), '0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7')
// identity: unchanged
instance.exports.identity(0)
assert.eq(getResult(16, 16), '0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15')
// Run many times to trigger OMG
for (let i = 0; i < wasmTestLoopCount; ++i) {
instance.exports.unpackhi_unpacklo(0, 64)
instance.exports.dup_low_qword(0)
instance.exports.identity(0)
}
// Verify correctness after OMG
instance.exports.unpackhi_unpacklo(0, 64)
assert.eq(getResult(32, 16), '8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23')
}
await assert.asyncTest(test())