This is an automated email from the git hooks/post-receive script.
richard pushed a commit to branch tor-browser-91.9esr-11.0-1 in repository tor-browser.
commit 2441d0fa27c06e94d55c283e2848dde15ccc4f6d Author: Yury Delendik ydelendik@mozilla.com AuthorDate: Tue Mar 29 19:52:46 2022 +0000
Bug 1761850 - Fix wasm select on ARM64. r=jseward, a=RyanVM
JSOpToCondition is applicable only to integer types. JSOpToDoubleCondition and ConditionFromDoubleCondition sequence has to be used for float types.
Differential Revision: https://phabricator.services.mozilla.com/D142288 --- .../jit-test/tests/wasm/binop-arm64-ion-codegen.js | 2 +- js/src/jit-test/tests/wasm/regress/bug1761850.js | 96 ++++++++++++++++++++++ js/src/jit/arm64/CodeGenerator-arm64.cpp | 9 +- 3 files changed, 105 insertions(+), 2 deletions(-)
diff --git a/js/src/jit-test/tests/wasm/binop-arm64-ion-codegen.js b/js/src/jit-test/tests/wasm/binop-arm64-ion-codegen.js index 36b26b1350ce3..acb9e7d6c7ab6 100644 --- a/js/src/jit-test/tests/wasm/binop-arm64-ion-codegen.js +++ b/js/src/jit-test/tests/wasm/binop-arm64-ion-codegen.js @@ -300,7 +300,7 @@ codegenTestARM64_adhoc( 'f', `9e6703e0 fmov d0, xzr 1e622000 fcmp d0, d2 - 1e63bc20 fcsel d0, d1, d3, lt`) + 1e633c20 fcsel d0, d1, d3, lo`)
// FP ABS should not tie its input to its output.
diff --git a/js/src/jit-test/tests/wasm/regress/bug1761850.js b/js/src/jit-test/tests/wasm/regress/bug1761850.js new file mode 100644 index 0000000000000..159db484019dc --- /dev/null +++ b/js/src/jit-test/tests/wasm/regress/bug1761850.js @@ -0,0 +1,96 @@ +// Testing runtime execution of select + comparison operations. +// Normally they are folded into shorter/faster sequence than select alone. + +function cross(xs) { + let results = []; + for ( let x of xs ) + for ( let y of xs ) + results.push([x,y]); + return results; +} + +const floatOps = { + lt(a, b) { return a < b ? 0 : 1; }, + le(a, b) { return a <= b ? 0 : 1; }, + gt(a, b) { return a > b ? 0 : 1; }, + ge(a, b) { return a >= b ? 0 : 1; }, + eq(a, b) { return a === b ? 0 : 1; }, + ne(a, b) { return a !== b ? 0 : 1; }, +} + +for (let ty of ['f32', 'f64']) { + for (let op of ['lt', 'le', 'gt', 'ge', 'eq', 'ne']) { + const module = new WebAssembly.Module(wasmTextToBinary(`(module + (memory (export "memory") 1 1) + (func (export "test") (result i32) + i32.const 128 + i32.load8_u + i32.const 129 + i32.load8_u + i32.const 0 + ${ty}.load + i32.const ${ty == 'f32' ? 4 : 8} + ${ty}.load + ${ty}.${op} + select + ) + (data (i32.const 128) "\00\01"))`)); + const instance = new WebAssembly.Instance(module); + const arr = new (ty == 'f32' ? Float32Array : Float64Array)(instance.exports.memory.buffer); + for (let [a, b] of cross( + [0, 1, -1e100, Infinity, -Infinity, 1e100, -1e-10, 1/-Infinity, NaN] + )) { + arr[0] = a; arr[1] = b; + assertEq(instance.exports.test(), floatOps[op](arr[0], arr[1])) + } + } +} + +const intOps = { + lt(a, b) { return a < b ? 0 : 1; }, + le(a, b) { return a <= b ? 0 : 1; }, + gt(a, b) { return a > b ? 0 : 1; }, + ge(a, b) { return a >= b ? 0 : 1; }, + eq(a, b) { return a === b ? 0 : 1; }, + ne(a, b) { return a !== b ? 0 : 1; }, +} + +for (let [ty, signed] of [['i32', true], ['i32', false], ['i64', true], ['i64', false]]) { + for (let op of ['lt', 'le', 'gt', 'ge', 'eq', 'ne']) { + const module = new WebAssembly.Module(wasmTextToBinary(`(module + (memory (export "memory") 1 1) + (func (export "test") (result i32) + i32.const 128 + i32.load8_u + i32.const 129 + i32.load8_u + i32.const 0 + ${ty}.load + i32.const ${ty == 'i32' ? 4 : 8} + ${ty}.load + ${ty}.${op}${op[0] == 'l' || op[0] == 'g' ? (signed ? '_s' : '_u') : ''} + select + ) + (data (i32.const 128) "\00\01"))`)); + const instance = new WebAssembly.Instance(module); + const arr = new (ty == 'i32' ? (signed ? Int32Array : Uint32Array) : + (signed ? BigInt64Array : BigUint64Array)) + (instance.exports.memory.buffer); + const c = ty == 'i32' ? (a => a|0) : BigInt; + for (let [a, b] of cross( + [c(0), ~c(0), c(1), ~c(1), c(1) << c(8), ~c(1) << c(12)] + )) { + arr[0] = a; arr[1] = b; + assertEq(instance.exports.test(), intOps[op](arr[0], arr[1])) + } + } +} + + +function cross(xs) { + let results = []; + for ( let x of xs ) + for ( let y of xs ) + results.push([x,y]); + return results; +} diff --git a/js/src/jit/arm64/CodeGenerator-arm64.cpp b/js/src/jit/arm64/CodeGenerator-arm64.cpp index f179f052961de..7c02fe103f34b 100644 --- a/js/src/jit/arm64/CodeGenerator-arm64.cpp +++ b/js/src/jit/arm64/CodeGenerator-arm64.cpp @@ -2489,7 +2489,14 @@ void CodeGenerator::visitWasmCompareAndSelect(LWasmCompareAndSelect* ins) { }
// Act on flag. - Assembler::Condition cond = JSOpToCondition(ins->compareType(), ins->jsop()); + Assembler::Condition cond; + if (compTy == MCompare::Compare_Float32 || + compTy == MCompare::Compare_Double) { + cond = Assembler::ConditionFromDoubleCondition( + JSOpToDoubleCondition(ins->jsop())); + } else { + cond = JSOpToCondition(compTy, ins->jsop()); + } MIRType insTy = ins->mir()->type(); if (insTy == MIRType::Int32) { Register outReg = ToRegister(ins->output());