[SystemZ] Fix modelling of composed subreg indices.

A rare case where coalescing resulted in a hh32 (high32 of high64 of vector
register) subreg usage caused getSubReg() to fail as the vector reg does not
have that subreg in its subregs list, but rather h32 which was expected to
also act as hh32. See link below for the discussion when solving this.

Patch By: critson

Reviewed By: uweigand

Fixes: https://github.com/llvm/llvm-project/issues/61390
This commit is contained in:
Carl Ritson 2023-03-21 16:13:51 +01:00 committed by Jonas Paulsson
parent 01d05bd407
commit e7c1b4b64c
7 changed files with 21 additions and 21 deletions

View File

@ -191,7 +191,7 @@ let Uses = [FPC], mayRaiseFPException = 1 in {
let Predicates = [FeatureNoVectorEnhancements1] in {
def : Pat<(f32 (any_fpround FP128:$src)),
(EXTRACT_SUBREG (LEXBR FP128:$src), subreg_hh32)>;
(EXTRACT_SUBREG (LEXBR FP128:$src), subreg_h32)>;
def : Pat<(f64 (any_fpround FP128:$src)),
(EXTRACT_SUBREG (LDXBR FP128:$src), subreg_h64)>;
}

View File

@ -30,12 +30,12 @@ static const TargetRegisterClass *getRC32(MachineOperand &MO,
const TargetRegisterClass *RC = MRI->getRegClass(MO.getReg());
if (SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
MO.getSubReg() == SystemZ::subreg_l32 ||
MO.getSubReg() == SystemZ::subreg_hl32)
MO.getSubReg() == SystemZ::subreg_ll32 ||
MO.getSubReg() == SystemZ::subreg_l32)
return &SystemZ::GR32BitRegClass;
if (SystemZ::GRH32BitRegClass.hasSubClassEq(RC) ||
MO.getSubReg() == SystemZ::subreg_h32 ||
MO.getSubReg() == SystemZ::subreg_hh32)
MO.getSubReg() == SystemZ::subreg_lh32 ||
MO.getSubReg() == SystemZ::subreg_h32)
return &SystemZ::GRH32BitRegClass;
if (VRM && VRM->hasPhys(MO.getReg())) {

View File

@ -24,10 +24,10 @@ namespace SystemZ {
// Return the subreg to use for referring to the even and odd registers
// in a GR128 pair. Is32Bit says whether we want a GR32 or GR64.
inline unsigned even128(bool Is32bit) {
return Is32bit ? subreg_hl32 : subreg_h64;
return Is32bit ? subreg_l32 : subreg_h64;
}
inline unsigned odd128(bool Is32bit) {
return Is32bit ? subreg_l32 : subreg_l64;
return Is32bit ? subreg_ll32 : subreg_l64;
}
// Reg should be a 32-bit GPR. Return true if it is a high register rather

View File

@ -20,12 +20,12 @@ class SystemZRegWithSubregs<string n, list<Register> subregs>
}
let Namespace = "SystemZ" in {
def subreg_l32 : SubRegIndex<32, 0>; // Also acts as subreg_ll32.
def subreg_h32 : SubRegIndex<32, 32>; // Also acts as subreg_lh32.
def subreg_l32 : SubRegIndex<32, 0>; // Also acts as subreg_hl32.
def subreg_h32 : SubRegIndex<32, 32>; // Also acts as subreg_hh32.
def subreg_l64 : SubRegIndex<64, 0>;
def subreg_h64 : SubRegIndex<64, 64>;
def subreg_hh32 : ComposedSubRegIndex<subreg_h64, subreg_h32>;
def subreg_hl32 : ComposedSubRegIndex<subreg_h64, subreg_l32>;
def subreg_lh32 : ComposedSubRegIndex<subreg_l64, subreg_h32>;
def subreg_ll32 : ComposedSubRegIndex<subreg_l64, subreg_l32>;
}
// Define a register class that contains values of types TYPES and an
@ -73,9 +73,9 @@ class GPR64<bits<16> num, string n, GPR32 low, GPR32 high>
// 8 even-odd pairs of GPR64s.
class GPR128<bits<16> num, string n, GPR64 low, GPR64 high>
: SystemZRegWithSubregs<n, [low, high]> {
: SystemZRegWithSubregs<n, [high, low]> {
let HWEncoding = num;
let SubRegIndices = [subreg_l64, subreg_h64];
let SubRegIndices = [subreg_h64, subreg_l64];
let CoveredBySubRegs = 1;
}
@ -215,9 +215,9 @@ class FPR64<bits<16> num, string n, FPR32 high>
// 8 pairs of FPR64s, with a one-register gap inbetween.
class FPR128<bits<16> num, string n, FPR64 low, FPR64 high>
: SystemZRegWithSubregs<n, [low, high]> {
: SystemZRegWithSubregs<n, [high, low]> {
let HWEncoding = num;
let SubRegIndices = [subreg_l64, subreg_h64];
let SubRegIndices = [subreg_h64, subreg_l64];
let CoveredBySubRegs = 1;
}

View File

@ -248,9 +248,9 @@ body: |
bb.9:
%82 = VLVGP %67.subreg_h64, %67.subreg_h64
%82 = VLVGH %82, %58.subreg_hl32, $noreg, 0
%82 = VLVGH %82, %80.subreg_hl32, $noreg, 1
dead %82 = VLVGH %82, %90.subreg_hl32, $noreg, 2
%82 = VLVGH %82, %58.subreg_l32, $noreg, 0
%82 = VLVGH %82, %80.subreg_l32, $noreg, 1
dead %82 = VLVGH %82, %90.subreg_l32, $noreg, 2
%96 = AFIMux %96, 1879048192, implicit-def dead $cc
%96 = SRL %96, $noreg, 31
dead %11 = VLVGF %11, %96, $noreg, 1

View File

@ -67,8 +67,8 @@ body: |
undef %3.subreg_l64:gr128bit = LGHI 1
%3.subreg_h64:gr128bit = LLILL 0
%3:gr128bit = DLGR %3, %0
CLFIMux %3.subreg_hl32, 3631842929, implicit-def $cc
%6:grx32bit = LOCRMux undef %6, %3.subreg_hl32, 14, 4, implicit killed $cc
CLFIMux %3.subreg_l32, 3631842929, implicit-def $cc
%6:grx32bit = LOCRMux undef %6, %3.subreg_l32, 14, 4, implicit killed $cc
CHIMux %6, 0, implicit-def $cc
BRC 14, 8, %bb.2.for.inc591.1.i.i, implicit killed $cc
J %bb.1.cleanup584.i.i

View File

@ -22,7 +22,7 @@ tracksRegLiveness: true
body: |
bb.0:
%0 : gr128bit = IMPLICIT_DEF
%0.subreg_hl32 = COPY %0.subreg_l32
%0.subreg_l32 = COPY %0.subreg_ll32
%1 : gr64bit = COPY %0.subreg_l64
%2 : addr64bit = LARL @g_167
STC %1.subreg_l32, %2, 8, $noreg