[SystemZ] Fix modelling of composed subreg indices.
authorCarl Ritson <carl.ritson@amd.com>
Tue, 21 Mar 2023 15:13:51 +0000 (16:13 +0100)
committerJonas Paulsson <paulsson@linux.vnet.ibm.com>
Tue, 21 Mar 2023 15:39:22 +0000 (16:39 +0100)
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

llvm/lib/Target/SystemZ/SystemZInstrFP.td
llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
llvm/lib/Target/SystemZ/SystemZRegisterInfo.h
llvm/lib/Target/SystemZ/SystemZRegisterInfo.td
llvm/test/CodeGen/SystemZ/RAbasic-invalid-LR-update.mir
llvm/test/CodeGen/SystemZ/cond-move-05.mir
llvm/test/CodeGen/SystemZ/regalloc-fast-invalid-kill-flag.mir

index 7cbe125..ea62e99 100644 (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)>;
 }
index 7f3d8e8..e43787a 100644 (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())) {
index 19305d4..78abeb7 100644 (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
index 00005a6..5d66501 100644 (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;
 }
 
index 0c02c26..79fa84f 100644 (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
index 3ce98de..7cc69bc 100644 (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
index cf2c274..bcd7f51 100644 (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