diff --git a/common.gypi b/common.gypi index 936d7bc53182e2..6af75f45839f6e 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.56', + 'v8_embedder_string': '-node.57', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/wasm/baseline/arm/liftoff-assembler-arm.h b/deps/v8/src/wasm/baseline/arm/liftoff-assembler-arm.h index e7f5d82c220682..fe8105d4eb2833 100644 --- a/deps/v8/src/wasm/baseline/arm/liftoff-assembler-arm.h +++ b/deps/v8/src/wasm/baseline/arm/liftoff-assembler-arm.h @@ -140,6 +140,8 @@ template inline void I64BinopI(LiftoffAssembler* assm, LiftoffRegister dst, LiftoffRegister lhs, int32_t imm) { + // The compiler allocated registers such that either {dst == lhs} or there is + // no overlap between the two. DCHECK_NE(dst.low_gp(), lhs.high_gp()); (assm->*op)(dst.low_gp(), lhs.low_gp(), Operand(imm), SetCC, al); // Top half of the immediate sign extended, either 0 or -1. diff --git a/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32.h b/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32.h index 113674a2531bc7..065aed0ebbe0c7 100644 --- a/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32.h +++ b/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32.h @@ -1097,31 +1097,19 @@ template inline void OpWithCarryI(LiftoffAssembler* assm, LiftoffRegister dst, LiftoffRegister lhs, int32_t imm) { - // First, compute the low half of the result, potentially into a temporary dst - // register if {dst.low_gp()} equals any register we need to - // keep alive for computing the upper half. - LiftoffRegList keep_alive = LiftoffRegList::ForRegs(lhs.high_gp()); - Register dst_low = keep_alive.has(dst.low_gp()) - ? assm->GetUnusedRegister(kGpReg, keep_alive).gp() - : dst.low_gp(); - - if (dst_low != lhs.low_gp()) assm->mov(dst_low, lhs.low_gp()); - (assm->*op)(dst_low, Immediate(imm)); + // The compiler allocated registers such that either {dst == lhs} or there is + // no overlap between the two. + DCHECK_NE(dst.low_gp(), lhs.high_gp()); - // Now compute the upper half, while keeping alive the previous result. - keep_alive = LiftoffRegList::ForRegs(dst_low); - Register dst_high = keep_alive.has(dst.high_gp()) - ? assm->GetUnusedRegister(kGpReg, keep_alive).gp() - : dst.high_gp(); + // First, compute the low half of the result. + if (dst.low_gp() != lhs.low_gp()) assm->mov(dst.low_gp(), lhs.low_gp()); + (assm->*op)(dst.low_gp(), Immediate(imm)); - if (dst_high != lhs.high_gp()) assm->mov(dst_high, lhs.high_gp()); + // Now compute the upper half. + if (dst.high_gp() != lhs.high_gp()) assm->mov(dst.high_gp(), lhs.high_gp()); // Top half of the immediate sign extended, either 0 or -1. int32_t sign_extend = imm < 0 ? -1 : 0; - (assm->*op_with_carry)(dst_high, sign_extend); - - // If necessary, move result into the right registers. - LiftoffRegister tmp_result = LiftoffRegister::ForPair(dst_low, dst_high); - if (tmp_result != dst) assm->Move(dst, tmp_result, kWasmI64); + (assm->*op_with_carry)(dst.high_gp(), sign_extend); } } // namespace liftoff diff --git a/deps/v8/src/wasm/baseline/liftoff-compiler.cc b/deps/v8/src/wasm/baseline/liftoff-compiler.cc index 071dce0f3deae1..987f46b6ffbd00 100644 --- a/deps/v8/src/wasm/baseline/liftoff-compiler.cc +++ b/deps/v8/src/wasm/baseline/liftoff-compiler.cc @@ -1122,9 +1122,12 @@ class LiftoffCompiler { int32_t imm = rhs_slot.i32_const(); LiftoffRegister lhs = __ PopToRegister(); + // Either reuse {lhs} for {dst}, or choose a register (pair) which does + // not overlap, for easier code generation. + LiftoffRegList pinned = LiftoffRegList::ForRegs(lhs); LiftoffRegister dst = src_rc == result_rc - ? __ GetUnusedRegister(result_rc, {lhs}, {}) - : __ GetUnusedRegister(result_rc, {}); + ? __ GetUnusedRegister(result_rc, {lhs}, pinned) + : __ GetUnusedRegister(result_rc, pinned); CallEmitFn(fnImm, dst, lhs, imm); __ PushRegister(ValueType(result_type), dst); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-1146861.js b/deps/v8/test/mjsunit/regress/wasm/regress-1146861.js new file mode 100644 index 00000000000000..d9d80e58ccc1a1 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/wasm/regress-1146861.js @@ -0,0 +1,56 @@ +// Copyright 2020 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. + +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const builder = new WasmModuleBuilder(); +builder.addGlobal(kWasmI32, 1); +builder.addType(makeSig([], [kWasmF64])); +// Generate function 1 (out of 1). +builder.addFunction(undefined, 0 /* sig */) + .addLocals(kWasmI32, 8).addLocals(kWasmI64, 3) + .addBodyWithEnd([ +// signature: d_v +// body: +kExprGlobalGet, 0x00, // global.get +kExprLocalSet, 0x00, // local.set +kExprI32Const, 0x00, // i32.const +kExprI32Eqz, // i32.eqz +kExprLocalSet, 0x01, // local.set +kExprGlobalGet, 0x00, // global.get +kExprLocalSet, 0x02, // local.set +kExprI32Const, 0x01, // i32.const +kExprI32Const, 0x01, // i32.const +kExprI32Sub, // i32.sub +kExprLocalSet, 0x03, // local.set +kExprGlobalGet, 0x00, // global.get +kExprLocalSet, 0x04, // local.set +kExprI32Const, 0x00, // i32.const +kExprI32Eqz, // i32.eqz +kExprLocalSet, 0x05, // local.set +kExprGlobalGet, 0x00, // global.get +kExprLocalSet, 0x06, // local.set +kExprI32Const, 0x00, // i32.const +kExprI32Const, 0x01, // i32.const +kExprI32Sub, // i32.sub +kExprLocalSet, 0x07, // local.set +kExprBlock, kWasmStmt, // block @45 + kExprI32Const, 0x00, // i32.const + kExprIf, kWasmStmt, // if @49 + kExprLocalGet, 0x0a, // local.get + kExprLocalSet, 0x08, // local.set + kExprElse, // else @55 + kExprNop, // nop + kExprEnd, // end @57 + kExprLocalGet, 0x08, // local.get + kExprLocalSet, 0x09, // local.set + kExprLocalGet, 0x09, // local.get + kExprI64Const, 0xff, 0x01, // i64.const + kExprI64Add, // i64.add + kExprDrop, // drop + kExprEnd, // end @69 +kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, // f64.const +kExprEnd, // end @79 +]); +builder.instantiate();