Bug 1688262 - Properly guard the simd rotate operation. r=jseward

The trigger for the rotate specialization did not check that the
second run of increasing values in the shuffle pattern, if present,
must start with lane value zero.

Differential Revision: https://phabricator.services.mozilla.com/D102888
This commit is contained in:
Lars T Hansen 2021-01-27 11:36:57 +00:00
parent c07ec516ea
commit 79751bd8e9
2 changed files with 33 additions and 5 deletions

View File

@ -0,0 +1,22 @@
// |jit-test| skip-if: !wasmSimdEnabled()
// Shuffle pattern incorrectly recognized as a rotate due to a missing guard in
// the optimizer.
let ins = wasmEvalText(`
(module
(memory (export "mem") 1)
(func (export "test")
(v128.store (i32.const 0)
(i8x16.shuffle 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6
(v128.load (i32.const 16))
(v128.const i32x4 0 0 0 0)))))
`);
let mem = new Int8Array(ins.exports.mem.buffer);
let input = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25];
let output = [10, 11, 12, 13, 14, 15, 16, 17, 18, 10, 11, 12, 13, 14, 15, 16];
mem.set(input, 16);
ins.exports.test();
let result = Array.from(mem.subarray(0, 16));
assertDeepEq(output, result);

View File

@ -490,15 +490,21 @@ static bool TryPermute32x4(SimdConstant* control) {
// just lanes[0], and *control is unchanged.
static bool TryRotateRight8x16(SimdConstant* control) {
const SimdConstant::I8x16& lanes = control->asInt8x16();
// Look for the first run of consecutive bytes.
// Look for the end of the first run of consecutive bytes.
int i = ScanIncreasingMasked(lanes, 0);
// If we reach the end of the vector, the vector must start at 0.
if (i == 16) {
return lanes[0] == 0;
// First run must start at a value s.t. we have a rotate if all remaining
// bytes are a run.
if (lanes[0] != 16 - i) {
return false;
}
// Second run must start at source lane zero
// If we reached the end of the vector, we're done.
if (i == 16) {
return true;
}
// Second run must start at source lane zero.
if (lanes[i] != 0) {
return false;
}