Skip to content

Commit 70a389a

Browse files
gahaasCommit Bot
authored andcommitted
[wasm][liftoff][ia32] Fix register allocation of CompareExchange
The register that holds the {new_value} for the AtomicCompareExchange8U has to be a byte register on ia32. There was code to guarantee that, but after that code there was code that frees the {eax} register, and that code moved the {new_value} to a different register again. With this CL we first free {eax}, and then find a byte register for the {new_value}. [email protected] Bug: chromium:1140549 Change-Id: I1679f3f9ab26c5416ea251c7925366ff43336d85 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2491031 Reviewed-by: Clemens Backes <[email protected]> Commit-Queue: Andreas Haas <[email protected]> Cr-Commit-Position: refs/heads/master@{#70721}
1 parent d9829b9 commit 70a389a

2 files changed

Lines changed: 35 additions & 7 deletions

File tree

src/wasm/baseline/ia32/liftoff-assembler-ia32.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,16 @@ void LiftoffAssembler::AtomicCompareExchange(
921921
Register expected_reg = is_64_bit_op ? expected.low_gp() : expected.gp();
922922
Register result_reg = expected_reg;
923923

924+
// The cmpxchg instruction uses eax to store the old value of the
925+
// compare-exchange primitive. Therefore we have to spill the register and
926+
// move any use to another register.
927+
ClearRegister(eax, {&dst_addr, &value_reg},
928+
LiftoffRegList::ForRegs(dst_addr, value_reg, expected_reg));
929+
if (expected_reg != eax) {
930+
mov(eax, expected_reg);
931+
expected_reg = eax;
932+
}
933+
924934
bool is_byte_store = type.size() == 1;
925935
LiftoffRegList pinned =
926936
LiftoffRegList::ForRegs(dst_addr, value_reg, expected_reg);
@@ -934,13 +944,6 @@ void LiftoffAssembler::AtomicCompareExchange(
934944
pinned.clear(LiftoffRegister(value_reg));
935945
}
936946

937-
// The cmpxchg instruction uses eax to store the old value of the
938-
// compare-exchange primitive. Therefore we have to spill the register and
939-
// move any use to another register.
940-
ClearRegister(eax, {&dst_addr, &value_reg}, pinned);
941-
if (expected_reg != eax) {
942-
mov(eax, expected_reg);
943-
}
944947

945948
Operand dst_op = Operand(dst_addr, offset_imm);
946949

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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: --wasm-staging
6+
7+
load('test/mjsunit/wasm/wasm-module-builder.js');
8+
9+
const builder = new WasmModuleBuilder();
10+
builder.addMemory(16, 32, false, true);
11+
builder.addType(makeSig([], []));
12+
builder.addFunction(undefined, 0 /* sig */)
13+
.addBodyWithEnd([
14+
// signature: v_v
15+
// body:
16+
kExprI32Const, 0x00,
17+
kExprI32Const, 0x00,
18+
kExprI32Const, 0x00,
19+
kAtomicPrefix, kExprI32AtomicCompareExchange8U, 0x00, 0xc3, 0x01,
20+
kExprDrop,
21+
kExprEnd, // end @193
22+
]);
23+
builder.addExport('main', 0);
24+
const instance = builder.instantiate();
25+
print(instance.exports.main(1, 2, 3));

0 commit comments

Comments
 (0)