Commit 5183aaf2 authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[compiler] Fix spilling of SIMD registers

Without simple FP aliasing, a SIMD register will overlap with two
floating-point registers. If we spill an FP register to use it for a
SIMD operation, we need to make sure to also spill the "sibling" FP
register.

R=leszeks@chromium.org

Bug: v8:12330, chromium:1271244
Change-Id: I7fdc6cb8da35d66b4862a8a913ba4ff906cf05aa
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3347576Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78414}
parent d7aaa6d7
......@@ -1459,6 +1459,8 @@ class SinglePassRegisterAllocator final {
MachineRepresentation rep, InstructionOperand* operand,
UsePosition pos);
void SpillRegister(RegisterIndex reg);
void SpillRegisterAndPotentialSimdSibling(RegisterIndex reg,
MachineRepresentation rep);
void SpillRegisterForVirtualRegister(int virtual_register);
// Pre-emptively spill the register at the exit of deferred blocks such that
......@@ -2017,7 +2019,7 @@ RegisterIndex SinglePassRegisterAllocator::ChooseRegisterFor(
RegisterIndex reg = ChooseFreeRegister(rep, pos);
if (!reg.is_valid() && must_use_register) {
reg = ChooseRegisterToSpill(rep, pos);
SpillRegister(reg);
SpillRegisterAndPotentialSimdSibling(reg, rep);
}
return reg;
}
......@@ -2149,6 +2151,18 @@ void SinglePassRegisterAllocator::SpillRegister(RegisterIndex reg) {
FreeRegister(reg, virtual_register, rep);
}
void SinglePassRegisterAllocator::SpillRegisterAndPotentialSimdSibling(
RegisterIndex reg, MachineRepresentation rep) {
SpillRegister(reg);
if (!kSimpleFPAliasing && rep == MachineRepresentation::kSimd128) {
// Two FP registers {2N, 2N+1} alias the same SIMD register. We compute {2N}
// from {2N+1} and vice versa in a single computation.
RegisterIndex siblingSimdReg{reg.ToInt() + 1 - 2 * (reg.ToInt() & 1)};
SpillRegister(siblingSimdReg);
}
}
void SinglePassRegisterAllocator::SpillAllRegisters() {
if (!HasRegisterState()) return;
......@@ -2533,7 +2547,7 @@ void SinglePassRegisterAllocator::ReserveFixedRegister(
// If register is in-use by a different virtual register, spill it now.
// TODO(rmcilroy): Consider moving to a unconstrained register instead of
// spilling.
SpillRegister(reg);
SpillRegisterAndPotentialSimdSibling(reg, rep);
}
MarkRegisterUse(reg, rep, pos);
}
......
......@@ -1462,6 +1462,7 @@
'regress/wasm/regress-1242300': [SKIP],
'regress/wasm/regress-1242689': [SKIP],
'regress/wasm/regress-1264462': [SKIP],
'regress/wasm/regress-1271244': [SKIP],
'regress/wasm/regress-1271538': [SKIP],
}], # no_simd_hardware == True
......
// 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.
// Flags: --no-liftoff --turbo-force-mid-tier-regalloc
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
builder.addFunction('main', makeSig([], [kWasmI32, kWasmF64, kWasmF64]))
.addBody([
kExprI32Const, 1, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kSimdPrefix, kExprF64x2PromoteLowF32x4, // f64x2.promote_low_f32x4
kSimdPrefix, kExprI8x16ExtractLaneS, 0, // i8x16.extract_lane_s
...wasmF64Const(2), // f64.const
...wasmF64Const(1), // f64.const
]);
builder.toModule();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment