[llvm] 40abb28 - RegAllocGreedy: Fix subranges when rematerializing dead subreg defs

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 24 08:52:03 PDT 2022


Author: Matt Arsenault
Date: 2022-07-24T11:51:59-04:00
New Revision: 40abb28f616ee3ea3f12488a8c5d934f55016725

URL: https://github.com/llvm/llvm-project/commit/40abb28f616ee3ea3f12488a8c5d934f55016725
DIFF: https://github.com/llvm/llvm-project/commit/40abb28f616ee3ea3f12488a8c5d934f55016725.diff

LOG: RegAllocGreedy: Fix subranges when rematerializing dead subreg defs

This would create a new interval missing the subrange and hit this
verifier error:

*** Bad machine code: Live interval for subreg operand has no subranges ***
- function:    test_remat_subreg_def
- basic block: %bb.0  (0xa568758) [0B;128B)
- instruction: 32B	dead undef %4.sub0:vreg_64 = V_MOV_B32_e32 2, implicit $exec

Added: 
    

Modified: 
    llvm/lib/CodeGen/LiveRangeEdit.cpp
    llvm/test/CodeGen/AMDGPU/remat-vop.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/LiveRangeEdit.cpp b/llvm/lib/CodeGen/LiveRangeEdit.cpp
index 2aafb746aa2c..abf36b3f4c67 100644
--- a/llvm/lib/CodeGen/LiveRangeEdit.cpp
+++ b/llvm/lib/CodeGen/LiveRangeEdit.cpp
@@ -300,13 +300,15 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
   SmallVector<unsigned, 8> RegsToErase;
   bool ReadsPhysRegs = false;
   bool isOrigDef = false;
-  unsigned Dest;
+  Register Dest;
+  unsigned DestSubReg;
   // Only optimize rematerialize case when the instruction has one def, since
   // otherwise we could leave some dead defs in the code.  This case is
   // extremely rare.
   if (VRM && MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
       MI->getDesc().getNumDefs() == 1) {
     Dest = MI->getOperand(0).getReg();
+    DestSubReg = MI->getOperand(0).getSubReg();
     unsigned Original = VRM->getOriginal(Dest);
     LiveInterval &OrigLI = LIS.getInterval(Original);
     VNInfo *OrigVNI = OrigLI.getVNInfoAt(Idx);
@@ -384,8 +386,18 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
     if (isOrigDef && DeadRemats && !HasLiveVRegUses &&
         TII.isTriviallyReMaterializable(*MI)) {
       LiveInterval &NewLI = createEmptyIntervalFrom(Dest, false);
-      VNInfo *VNI = NewLI.getNextValue(Idx, LIS.getVNInfoAllocator());
+      VNInfo::Allocator &Alloc = LIS.getVNInfoAllocator();
+      VNInfo *VNI = NewLI.getNextValue(Idx, Alloc);
       NewLI.addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(), VNI));
+
+      if (DestSubReg) {
+        const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
+        auto *SR = NewLI.createSubRange(
+            Alloc, TRI->getSubRegIndexLaneMask(DestSubReg));
+        SR->addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(),
+                                             SR->getNextValue(Idx, Alloc)));
+      }
+
       pop_back();
       DeadRemats->insert(MI);
       const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();

diff  --git a/llvm/test/CodeGen/AMDGPU/remat-vop.mir b/llvm/test/CodeGen/AMDGPU/remat-vop.mir
index 001799cb3056..248a9e2ddb63 100644
--- a/llvm/test/CodeGen/AMDGPU/remat-vop.mir
+++ b/llvm/test/CodeGen/AMDGPU/remat-vop.mir
@@ -1,5 +1,5 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -verify-machineinstrs --stress-regalloc=2 -start-before=greedy,0 -stop-after=virtregrewriter,1 -o - %s | FileCheck -check-prefix=GCN %s
+# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -verify-regalloc --stress-regalloc=2 -start-before=greedy,0 -stop-after=virtregrewriter,1 -o - %s | FileCheck -check-prefix=GCN %s
 
 ---
 name:            test_remat_v_mov_b32_e32
@@ -5385,3 +5385,28 @@ body:             |
     S_NOP 0, implicit %3
     S_ENDPGM 0, implicit %0
 ...
+
+# Make sure there's no verifier error after making a subregister def dead. The
+# dead interval still needs a subrange.
+
+---
+name:            test_remat_subreg_def
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    ; GCN-LABEL: name: test_remat_subreg_def
+    ; GCN: renamable $vgpr1 = V_MOV_B32_e32 1, implicit $exec
+    ; GCN-NEXT: renamable $vgpr0 = V_MOV_B32_e32 3, implicit $exec
+    ; GCN-NEXT: S_NOP 0, implicit killed renamable $vgpr1
+    ; GCN-NEXT: S_NOP 0, implicit killed renamable $vgpr0
+    ; GCN-NEXT: renamable $vgpr0 = V_MOV_B32_e32 2, implicit $exec
+    ; GCN-NEXT: S_NOP 0, implicit renamable $vgpr0_vgpr1
+    ; GCN-NEXT: S_ENDPGM 0
+    %0:vgpr_32 = V_MOV_B32_e32 1, implicit $exec
+    undef %1.sub0:vreg_64 = V_MOV_B32_e32 2, implicit $exec
+    %2:vgpr_32 = V_MOV_B32_e32 3, implicit $exec
+    S_NOP 0, implicit %0
+    S_NOP 0, implicit %2
+    S_NOP 0, implicit %1
+    S_ENDPGM 0
+...


        


More information about the llvm-commits mailing list