[liftoff] Fix i64.sub special case
In the case that {dst}, {lhs} and {rhs} all point to the same register, we would emit wrong code (negating the register and adding it to itself). This CL fixes this by checking if {lhs == rhs}, and just clearing the {dst} register in that case. R=thibaudm@chromium.org Bug: chromium:1247659 Change-Id: I7913617850adb34a5ad812369f16a7422358454d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3151955 Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/main@{#76765}
This commit is contained in:
parent
5b01050e9a
commit
f235120c5e
@ -1317,7 +1317,9 @@ void LiftoffAssembler::emit_i64_addi(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
|
||||
void LiftoffAssembler::emit_i64_sub(LiftoffRegister dst, LiftoffRegister lhs,
|
||||
LiftoffRegister rhs) {
|
||||
if (dst.gp() == rhs.gp()) {
|
||||
if (lhs.gp() == rhs.gp()) {
|
||||
xorq(dst.gp(), dst.gp());
|
||||
} else if (dst.gp() == rhs.gp()) {
|
||||
negq(dst.gp());
|
||||
addq(dst.gp(), lhs.gp());
|
||||
} else {
|
||||
|
87
test/mjsunit/regress/wasm/regress-1247659.js
Normal file
87
test/mjsunit/regress/wasm/regress-1247659.js
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
|
||||
const builder = new WasmModuleBuilder();
|
||||
builder.addMemory(16, 17);
|
||||
builder.addGlobal(kWasmI32, 1, WasmInitExpr.I32Const(10));
|
||||
// Generate function 1 (out of 3).
|
||||
builder.addFunction('load', kSig_i_v)
|
||||
.addBody([
|
||||
kExprI32Const, 0, // i32.const
|
||||
kExprI32LoadMem8U, 0, 5, // i32.load8_u
|
||||
])
|
||||
.exportFunc();
|
||||
// Generate function 2 (out of 3).
|
||||
builder.addFunction(undefined, makeSig([kWasmI64, kWasmI32], []))
|
||||
.addLocals(kWasmI64, 3)
|
||||
.addLocals(kWasmI32, 5)
|
||||
.addBody([
|
||||
// locals: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]; stack: []
|
||||
kExprGlobalGet, 0, // global.get
|
||||
// locals: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]; stack: [10]
|
||||
kExprLocalSet, 5, // local.set
|
||||
// locals: [1, 0, 0, 0, 0, 10, 0, 0, 0, 0]; stack: []
|
||||
kExprI32Const, 0, // i32.const
|
||||
// locals: [1, 0, 0, 0, 0, 10, 0, 0, 0, 0]; stack: [0]
|
||||
kExprI32Eqz, // i32.eqz
|
||||
// locals: [1, 0, 0, 0, 0, 10, 0, 0, 0, 0]; stack: [1]
|
||||
kExprLocalSet, 6, // local.set
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 0, 0, 0]; stack: []
|
||||
kExprGlobalGet, 0, // global.get
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 0, 0, 0]; stack: [10]
|
||||
kExprLocalSet, 7, // local.set
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 10, 0, 0]; stack: []
|
||||
kExprI32Const, 0, // i32.const
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 10, 0, 0]; stack: [0]
|
||||
kExprI32Const, 1, // i32.const
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 10, 0, 0]; stack: [0, 1]
|
||||
kExprI32Sub, // i32.sub
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 10, 0, 0]; stack: [-1]
|
||||
kExprLocalSet, 8, // local.set
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 10, -1, 0]; stack: []
|
||||
kExprI32Const, 1, // i32.const
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 10, -1, 0]; stack: [1]
|
||||
kExprI32Const, 15, // i32.const
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 10, -1, 0]; stack: [1, 15]
|
||||
kExprI32And, // i32.and
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 10, -1, 0]; stack: [1]
|
||||
kExprLocalSet, 9, // local.set
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 10, -1, 1]; stack: []
|
||||
kExprLocalGet, 0, // local.get
|
||||
// locals: [1, 0, 0, 0, 0, 10, 1, 10, -1, 1]; stack: [1]
|
||||
kExprLocalSet, 2, // local.set
|
||||
// locals: [1, 0, 1, 0, 0, 10, 1, 10, -1, 1]; stack: []
|
||||
kExprLocalGet, 0, // local.get
|
||||
// locals: [1, 0, 1, 0, 0, 10, 1, 10, -1, 1]; stack: [1]
|
||||
kExprLocalSet, 3, // local.set
|
||||
// locals: [1, 0, 1, 1, 0, 10, 1, 10, -1, 1]; stack: []
|
||||
kExprLocalGet, 2, // local.get
|
||||
// locals: [1, 0, 1, 1, 0, 10, 1, 10, -1, 1]; stack: [1]
|
||||
kExprLocalGet, 3, // local.get
|
||||
// locals: [1, 0, 1, 1, 0, 10, 1, 10, -1, 1]; stack: [1, 1]
|
||||
kExprI64Sub, // i64.sub
|
||||
// locals: [1, 0, 1, 1, 0, 10, 1, 10, -1, 1]; stack: [0]
|
||||
kExprLocalSet, 4, // local.set
|
||||
// locals: [1, 0, 1, 1, 0, 10, 1, 10, -1, 1]; stack: []
|
||||
kExprI32Const, 1, // i32.const
|
||||
// locals: [1, 0, 1, 1, 0, 10, 1, 10, -1, 1]; stack: [1]
|
||||
kExprLocalGet, 4, // local.get
|
||||
// locals: [1, 0, 1, 1, 0, 10, 1, 10, -1, 1]; stack: [1, 0]
|
||||
kExprI64StoreMem16, 1, 0x03, // i64.store16
|
||||
]);
|
||||
// Generate function 3 (out of 3).
|
||||
builder.addFunction('invoker', kSig_v_v)
|
||||
.addBody([
|
||||
...wasmI64Const(1), // i64.const
|
||||
...wasmI32Const(0), // i32.const
|
||||
kExprCallFunction, 1, // call function #1
|
||||
])
|
||||
.exportFunc();
|
||||
const instance = builder.instantiate();
|
||||
|
||||
var exports = instance.exports;
|
||||
exports.invoker();
|
||||
assertEquals(0, exports.load());
|
Loading…
Reference in New Issue
Block a user