[compiler] Fix merging with register aliasing

Similar to the case of fixed registers, we need to consider both cases:
A SIMD register might collide with either the low or high FP register,
or the FP register might collide with a previously allocated SIMD
register. We did only consider the first case so far.

R=thibaudm@chromium.org

Bug: chromium:1286253, v8:12330
Change-Id: Id4c995586cc8b97a2e131ee9d3417525e409bcef
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3380597
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78633}
This commit is contained in:
Clemens Backes 2022-01-14 21:07:27 +01:00 committed by V8 LUCI CQ
parent 010fcac11e
commit 8de607d5b0
3 changed files with 52 additions and 4 deletions

View File

@ -1782,10 +1782,31 @@ void SinglePassRegisterAllocator::MergeStateFrom(
if (processed_regs.Contains(reg, rep)) continue;
processed_regs.Add(reg, rep);
bool reg_in_use =
register_state_->IsAllocated(reg) ||
(!kSimpleFPAliasing && rep == MachineRepresentation::kSimd128 &&
register_state_->IsAllocated(simdSibling(reg)));
bool reg_in_use = register_state_->IsAllocated(reg);
// For non-simple FP aliasing, the register is also "in use" if the
// FP register for the upper half is allocated.
if (!kSimpleFPAliasing && rep == MachineRepresentation::kSimd128) {
reg_in_use |= register_state_->IsAllocated(simdSibling(reg));
}
// Similarly (but the other way around), the register might be the upper
// half of a SIMD register that is allocated.
if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat64 ||
rep == MachineRepresentation::kFloat32)) {
int simd_reg_code;
CHECK_EQ(1, data_->config()->GetAliases(
rep, ToRegCode(reg, rep),
MachineRepresentation::kSimd128, &simd_reg_code));
// Sanity check: The SIMD reg code should be the shifted FP reg code.
DCHECK_EQ(simd_reg_code,
ToRegCode(reg, rep) >>
(rep == MachineRepresentation::kFloat64 ? 1 : 2));
RegisterIndex simd_reg =
FromRegCode(simd_reg_code, MachineRepresentation::kSimd128);
reg_in_use |=
simd_reg.is_valid() && register_state_->IsAllocated(simd_reg) &&
VirtualRegisterDataFor(VirtualRegisterForRegister(simd_reg))
.rep() == MachineRepresentation::kSimd128;
}
if (!reg_in_use) {
DCHECK(successor_registers->IsAllocated(reg));

View File

@ -1568,6 +1568,7 @@
'regress/wasm/regress-1282224': [SKIP],
'regress/wasm/regress-1283042': [SKIP],
'regress/wasm/regress-1284980': [SKIP],
'regress/wasm/regress-1286253': [SKIP],
}], # no_simd_hardware == True
##############################################################################

View File

@ -0,0 +1,26 @@
// Copyright 2022 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(undefined, kSig_i_iii)
.addBody([
...wasmS128Const(new Array(16).fill(0)), // s128.const
kSimdPrefix, kExprI8x16ExtractLaneU, 0x00, // i8x16.extract_lane_u
...wasmS128Const(new Array(16).fill(0)), // s128.const
kSimdPrefix, kExprF32x4ExtractLane, 0x00, // f32x4.extract_lane
kNumericPrefix, kExprI64SConvertSatF32, // i64.trunc_sat_f32_s
kExprF32Const, 0x13, 0x00, 0x00, 0x00, // f32.const
kNumericPrefix, kExprI64SConvertSatF32, // i64.trunc_sat_f32_s
kExprI64Ior, // i64.or
kExprI32ConvertI64, // i32.wrap_i64
...wasmF32Const(0), // f32.const
kNumericPrefix, kExprI64SConvertSatF32, // i64.trunc_sat_f32_s
kExprI32ConvertI64, // i32.wrap_i64
kExprSelect, // select
]);
builder.toModule();