Skip to content

Commit 9d06369

Browse files
thibaudmichaudCommit Bot
authored andcommitted
[liftoff][mv] Fix merge issue in multi-value loops
Registers cannot be used as a merge destination if they have more than one use, otherwise the merge will unexpectedly affect other uses of that register. R=ahaas@chromium.org,clemensb@chromium.org Bug: chromium:1084151 Change-Id: I0d6ad97c585920357a37d95361e0320d32c71f4b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2208851 Reviewed-by: Clemens Backes <clemensb@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Thibaud Michaud <thibaudm@chromium.org> Cr-Commit-Position: refs/heads/master@{#67904}
1 parent f84d519 commit 9d06369

2 files changed

Lines changed: 47 additions & 3 deletions

File tree

src/wasm/baseline/liftoff-assembler.cc

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,9 +571,22 @@ LiftoffRegister LiftoffAssembler::PeekToRegister(int index,
571571
void LiftoffAssembler::PrepareLoopArgs(int num) {
572572
for (int i = 0; i < num; ++i) {
573573
VarState& slot = cache_state_.stack_state.end()[-1 - i];
574-
if (!slot.is_const()) continue;
575-
RegClass rc =
576-
kNeedI64RegPair && slot.type() == kWasmI64 ? kGpRegPair : kGpReg;
574+
if (slot.is_stack()) continue;
575+
RegClass rc = reg_class_for(slot.type());
576+
if (slot.is_reg()) {
577+
if (cache_state_.get_use_count(slot.reg()) > 1) {
578+
// If the register is used more than once, we cannot use it for the
579+
// merge. Move it to an unused register instead.
580+
LiftoffRegList pinned;
581+
pinned.set(slot.reg());
582+
LiftoffRegister dst_reg = GetUnusedRegister(rc, pinned);
583+
Move(dst_reg, slot.reg(), slot.type());
584+
cache_state_.dec_used(slot.reg());
585+
cache_state_.inc_used(dst_reg);
586+
slot.MakeRegister(dst_reg);
587+
}
588+
continue;
589+
}
577590
LiftoffRegister reg = GetUnusedRegister(rc, {});
578591
LoadConstant(reg, slot.constant());
579592
slot.MakeRegister(reg);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2020 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --experimental-wasm-mv
6+
7+
load("test/mjsunit/wasm/wasm-module-builder.js");
8+
9+
let builder = new WasmModuleBuilder();
10+
let sig_i_iii = builder.addType(kSig_i_iii);
11+
12+
builder.addFunction("main", sig_i_iii)
13+
.addBody([
14+
kExprLocalGet, 1,
15+
kExprLocalGet, 1,
16+
kExprI32Const, 5,
17+
kExprLoop, sig_i_iii,
18+
kExprLocalGet, 1,
19+
kExprBlock, sig_i_iii,
20+
kExprLocalGet, 1,
21+
kExprLocalGet, 2,
22+
kExprBrIf, 1,
23+
kExprDrop,
24+
kExprDrop,
25+
kExprDrop,
26+
kExprEnd,
27+
kExprDrop,
28+
kExprEnd])
29+
.exportAs("main");
30+
31+
let module = new WebAssembly.Module(builder.toBuffer());

0 commit comments

Comments
 (0)