[regalloc] Fix issue in mid-tier register allocator

A SIMD register can "block" more than one FP register. In that case, no
virtual register will be assigned for one of the FP registers. This is
fine, we just need to detect and handle that case correctly.

R=thibaudm@chromium.org
CC=​leszeks@chromium.org

Bug: chromium:1271538, v8:12330
Change-Id: I7ec19229445c5ace0782f63945acb89322816540
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3293082
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78400}
This commit is contained in:
Clemens Backes 2021-12-15 17:24:22 +01:00 committed by V8 LUCI CQ
parent b5fabce811
commit d2b4292ca7
2 changed files with 48 additions and 0 deletions

View File

@ -2098,6 +2098,10 @@ RegisterIndex SinglePassRegisterAllocator::ChooseRegisterToSpill(
for (RegisterIndex reg : *register_state()) {
// Skip if register is in use, or not valid for representation.
if (!IsValidForRep(reg, rep) || in_use.Contains(reg, rep)) continue;
// With non-simple FP aliasing, a SIMD register might block more than one FP
// register.
DCHECK_IMPLIES(kSimpleFPAliasing, register_state()->IsAllocated(reg));
if (!kSimpleFPAliasing && !register_state()->IsAllocated(reg)) continue;
VirtualRegisterData& vreg_data =
VirtualRegisterDataFor(VirtualRegisterForRegister(reg));

View File

@ -0,0 +1,44 @@
// 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.addMemory(16, 32, false, true);
builder.addFunction('main', makeSig([], [kWasmS128]))
.addBody([
kExprI32Const, 0, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kExprI32Const, 2, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kExprI32Const, 3, // i32.const
kSimdPrefix, kExprI16x8ShrS, 0x01, // i16x8.shr_s
kExprI32Const, 0xc4, 0x88, 0x91, 0xa2, 0x04, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kSimdPrefix, kExprI16x8ExtAddPairwiseI8x16S, // i16x8.extadd_pairwise_i8x6_s
kSimdPrefix, kExprI16x8AddSatU, 0x01, // i16x8.add_sat_u
kExprI32Const, 0xac, 0x92, 0x01, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kExprF32Const, 0x2b, 0x2b, 0x2b, 0x49, // f32.const
kSimdPrefix, kExprF32x4ReplaceLane, 0x00, // f32x4.replace_lane
kSimdPrefix, kExprI16x8ExtAddPairwiseI8x16S, // i16x8.extadd_pairwise_i8x6_s
kSimdPrefix, kExprI16x8RoundingAverageU, 0x01, // i16x8.avgr_u
kExprI32Const, 0, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kSimdPrefix, kExprI64x2UConvertI32x4High, 0x01, // i64x2.convert_i32x4_high_u
kSimdPrefix, kExprI64x2SConvertI32x4High, 0x01, // i64x2.convert_i32x4_high_s
kExprI32Const, 0, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kExprF32Const, 0, 0, 0, 0, // f32.const
kSimdPrefix, kExprF32x4ReplaceLane, 0x00, // f32x4.replace_lane
kExprI32Const, 0, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kSimdPrefix, kExprI16x8ExtMulLowI8x16U, 0x01, // i16x8.extmul_low_i8x16_u
kSimdPrefix, kExprI16x8LeU, // i16x8.le_u
kSimdPrefix, kExprI8x16GtS, // i8x16.gt_s
kSimdPrefix, kExprI32x4Ne, // i32x4.ne
]);
builder.toModule();