Bug 1953381 - Fix x86 PBLEND optimizations for v128.bitselect. r=jseward a=pascalc

Differential Revision: https://phabricator.services.mozilla.com/D241259
This commit is contained in:
Yury Delendik 2025-03-13 14:11:31 +00:00
parent 042609f471
commit 8d7942934b
3 changed files with 35 additions and 3 deletions

View file

@ -0,0 +1,32 @@
// |jit-test| skip-if: !wasmSimdEnabled()
for (let [mask, exp] of [
[0xFF000000, 0x12bcdef0], // optimized to PBLENDVB on x86
[0x00FFFFFF, 0x9a345678], // optimized to PBLENDVB on x86
[0xFFFF0000, 0x1234def0], // optimized to PBLENDW on x86
[0x0000FFFF, 0x9abc5678], // optimized to PBLENDW on x86
[0x10000000, 0x9abcdef0], // non-optimizable mask
[0x9FFFFFFF, 0x12345678], // non-optimizable mask
[0x00000000, 0x9abcdef0],
[0xFFFFFFFF, 0x12345678],
]) {
const ins = wasmEvalText(`(module
(memory (export "memory") 1 1)
(func (export "test")
i32.const 48
i32.const 0
v128.load
i32.const 16
v128.load
v128.const i32x4 ${mask} ${mask} ${mask} ${mask}
v128.bitselect
v128.store
)
(data (i32.const 0) "\\78\\56\\34\\12\\78\\56\\34\\12\\78\\56\\34\\12\\78\\56\\34\\12")
(data (i32.const 16) "\\f0\\de\\bc\\9a\\f0\\de\\bc\\9a\\f0\\de\\bc\\9a\\f0\\de\\bc\\9a")
)`);
ins.exports.test();
var result = new DataView(ins.exports.memory.buffer).getUint32(48, true);
var expected = exp >>> 0;
assertEq(result, expected);
}

View file

@ -29,7 +29,7 @@ codegenTestX64_adhoc(
(func (export "f") (param v128) (param v128) (param v128) (result v128)
(v128.bitselect (local.get 0) (local.get 1) (v128.const i32x4 -1 0 0 -1))))`,
'f',
`66 0f 3a 0e c1 c3 pblendw \\$0xC3, %xmm1, %xmm0`);
`66 0f 3a 0e c1 3c pblendw \\$0x3C, %xmm1, %xmm0`);
// vpblendvp optimization when bitselect follows comparison.
// Non-AVX pblendvb uses xmm0 as an implicit read-only operand.

View file

@ -1161,9 +1161,9 @@ bool MWasmTernarySimd128::specializeBitselectConstantMaskAsShuffle(
const SimdConstant::I8x16& bytes = constant.asInt8x16();
for (int8_t i = 0; i < 16; i++) {
if (bytes[i] == -1) {
shuffle[i] = i + 16;
} else if (bytes[i] == 0) {
shuffle[i] = i;
} else if (bytes[i] == 0) {
shuffle[i] = i + 16;
} else {
return false;
}