]> granicus.if.org Git - llvm/commitdiff
LiveIntervalAnalysis: findLastUseBefore() must ignore undef uses.
authorMatthias Braun <matze@braunis.de>
Sat, 11 Jun 2016 00:31:28 +0000 (00:31 +0000)
committerMatthias Braun <matze@braunis.de>
Sat, 11 Jun 2016 00:31:28 +0000 (00:31 +0000)
undef uses are no real uses of a register and must be ignored by
findLastUseBefore() so that handleMove() does not produce invalid live
intervals in some cases.

This fixed http://llvm.org/PR28083

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272446 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/LiveIntervalAnalysis.cpp
unittests/MI/LiveIntervalTest.cpp

index 622b9c25d0e05d40da35aa5b64fc16698fc2a0e1..1a8360b226b6d4767ae82a94431e4a5f1cff5a22 100644 (file)
@@ -1314,6 +1314,8 @@ private:
     if (TargetRegisterInfo::isVirtualRegister(Reg)) {
       SlotIndex LastUse = Before;
       for (MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
+        if (MO.isUndef())
+          continue;
         unsigned SubReg = MO.getSubReg();
         if (SubReg != 0 && LaneMask != 0
             && (TRI.getSubRegIndexLaneMask(SubReg) & LaneMask) == 0)
@@ -1353,7 +1355,7 @@ private:
 
       // Check if MII uses Reg.
       for (MIBundleOperands MO(*MII); MO.isValid(); ++MO)
-        if (MO->isReg() &&
+        if (MO->isReg() && !MO->isUndef() &&
             TargetRegisterInfo::isPhysicalRegister(MO->getReg()) &&
             TRI.hasRegUnit(MO->getReg(), Reg))
           return Idx.getRegSlot();
index e4567363d39ac7d5c079be85655b5cf37539f587..e0b3d5529afbfcccee2a2d6fb74550df9f903e41 100644 (file)
@@ -329,6 +329,30 @@ TEST(LiveIntervalTest, MoveUpValNos) {
   });
 }
 
+TEST(LiveIntervalTest, MoveOverUndefUse0) {
+  // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
+  liveIntervalTest(
+"    %0 = IMPLICIT_DEF\n"
+"    NOOP\n"
+"    NOOP implicit undef %0\n"
+"    %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n",
+  [](MachineFunction &MF, LiveIntervals &LIS) {
+    testHandleMove(MF, LIS, 3, 1);
+  });
+}
+
+TEST(LiveIntervalTest, MoveOverUndefUse1) {
+  // findLastUseBefore() used by handleMoveUp() must ignore undef operands.
+  liveIntervalTest(
+"    %rax = IMPLICIT_DEF\n"
+"    NOOP\n"
+"    NOOP implicit undef %rax\n"
+"    %rax = IMPLICIT_DEF implicit %rax(tied-def 0)\n",
+  [](MachineFunction &MF, LiveIntervals &LIS) {
+    testHandleMove(MF, LIS, 3, 1);
+  });
+}
+
 int main(int argc, char **argv) {
   ::testing::InitGoogleTest(&argc, argv);
   initLLVM();