[PATCH] D43478: [LiveIntervals] Handle moving up dead partial write

Tim Renouf via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 26 06:44:31 PST 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rL326087: [LiveIntervals] Handle moving up dead partial write (authored by tpr, committed by ).

Repository:
  rL LLVM

https://reviews.llvm.org/D43478

Files:
  llvm/trunk/lib/CodeGen/LiveIntervals.cpp
  llvm/trunk/unittests/MI/LiveIntervalTest.cpp


Index: llvm/trunk/lib/CodeGen/LiveIntervals.cpp
===================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervals.cpp
+++ llvm/trunk/lib/CodeGen/LiveIntervals.cpp
@@ -1291,6 +1291,36 @@
           if (OldIdxIn != E && SlotIndex::isEarlierInstr(NewIdx, OldIdxIn->end))
             OldIdxIn->end = NewIdx.getRegSlot();
         }
+      } else if (OldIdxIn != E
+          && SlotIndex::isEarlierInstr(NewIdxOut->start, NewIdx)
+          && SlotIndex::isEarlierInstr(NewIdx, NewIdxOut->end)) {
+        // OldIdxVNI is a dead def that has been moved into the middle of
+        // another value in LR. That can happen when LR is a whole register,
+        // but the dead def is a write to a subreg that is dead at NewIdx.
+        // The dead def may have been moved across other values
+        // in LR, so move OldIdxOut up to NewIdxOut. Slide [NewIdxOut;OldIdxOut)
+        // down one position.
+        //    |- X0/NewIdxOut -| ... |- Xn-1 -| |- Xn/OldIdxOut -| |- next - |
+        // => |- X0/NewIdxOut -| |- X0 -| ... |- Xn-1 -| |- next -|
+        std::copy_backward(NewIdxOut, OldIdxOut, std::next(OldIdxOut));
+        // Modify the segment at NewIdxOut and the following segment to meet at
+        // the point of the dead def, with the following segment getting
+        // OldIdxVNI as its value number.
+        *NewIdxOut = LiveRange::Segment(
+            NewIdxOut->start, NewIdxDef.getRegSlot(), NewIdxOut->valno);
+        *(NewIdxOut + 1) = LiveRange::Segment(
+            NewIdxDef.getRegSlot(), (NewIdxOut + 1)->end, OldIdxVNI);
+        OldIdxVNI->def = NewIdxDef;
+        // Modify subsequent segments to be defined by the moved def OldIdxVNI.
+        for (auto Idx = NewIdxOut + 2; Idx <= OldIdxOut; ++Idx)
+          Idx->valno = OldIdxVNI;
+        // Aggressively remove all dead flags from the former dead definition.
+        // Kill/dead flags shouldn't be used while live intervals exist; they
+        // will be reinserted by VirtRegRewriter.
+        if (MachineInstr *KillMI = LIS.getInstructionFromIndex(NewIdx))
+          for (MIBundleOperands MO(*KillMI); MO.isValid(); ++MO)
+            if (MO->isReg() && !MO->isUse())
+              MO->setIsDead(false);
       } else {
         // OldIdxVNI is a dead def. It may have been moved across other values
         // in LR, so move OldIdxOut up to NewIdxOut. Slide [NewIdxOut;OldIdxOut)
Index: llvm/trunk/unittests/MI/LiveIntervalTest.cpp
===================================================================
--- llvm/trunk/unittests/MI/LiveIntervalTest.cpp
+++ llvm/trunk/unittests/MI/LiveIntervalTest.cpp
@@ -395,6 +395,31 @@
   });
 }
 
+TEST(LiveIntervalTest, DeadSubRegMoveUp) {
+  // handleMoveUp had a bug where moving a dead subreg def into the middle of
+  // an earlier segment resulted in an invalid live range.
+  liveIntervalTest(R"MIR(
+    undef %125.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
+    %125.sub1:vreg_128 = COPY %125.sub0
+    %125.sub2:vreg_128 = COPY %125.sub0
+    undef %51.sub0:vreg_128 = V_MOV_B32_e32 898625526, implicit $exec
+    %51.sub1:vreg_128 = COPY %51.sub0
+    %51.sub2:vreg_128 = COPY %51.sub0
+    %52:vgpr_32 = V_MOV_B32_e32 986714345, implicit $exec
+    %54:vgpr_32 = V_MOV_B32_e32 1742342378, implicit $exec
+    %57:vgpr_32 = V_MOV_B32_e32 3168768712, implicit $exec
+    %59:vgpr_32 = V_MOV_B32_e32 1039972644, implicit $exec
+    %60:vgpr_32 = V_MAD_F32 0, %52, 0, undef %61:vgpr_32, 0, %59, 0, 0, implicit $exec
+    %63:vgpr_32 = V_ADD_F32_e32 %51.sub3, undef %64:vgpr_32, implicit $exec
+    dead %66:vgpr_32 = V_MAD_F32 0, %60, 0, undef %67:vgpr_32, 0, %125.sub2, 0, 0, implicit $exec
+    undef %124.sub1:vreg_128 = V_MAD_F32 0, %57, 0, undef %70:vgpr_32, 0, %125.sub1, 0, 0, implicit $exec
+    %124.sub0:vreg_128 = V_MAD_F32 0, %54, 0, undef %73:vgpr_32, 0, %125.sub0, 0, 0, implicit $exec
+    dead undef %125.sub3:vreg_128 = V_MAC_F32_e32 %63, undef %76:vgpr_32, %125.sub3, implicit $exec
+)MIR", [](MachineFunction &MF, LiveIntervals &LIS) {
+    testHandleMove(MF, LIS, 15, 12);
+  });
+}
+
 int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
   initLLVM();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43478.135894.patch
Type: text/x-patch
Size: 4192 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180226/53eca688/attachment.bin>


More information about the llvm-commits mailing list