]> granicus.if.org Git - llvm/commitdiff
Fix regalloc assignment of overlapping registers
authorStanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com>
Wed, 1 Feb 2017 01:18:36 +0000 (01:18 +0000)
committerStanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com>
Wed, 1 Feb 2017 01:18:36 +0000 (01:18 +0000)
SplitEditor::defFromParent() can create a register copy.
If register is a tuple of other registers and not all lanes are used
a copy will be done on a full tuple regardless. Later register unit
for an unused lane will be considered free and another overlapping
register tuple can be assigned to a different value even though first
register is live at that point. That is because interference only look at
liveness info, while full register copy clobbers all lanes, even unused.

This patch fixes copy to only cover used lanes.

Differential Revision: https://reviews.llvm.org/D29105

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

lib/CodeGen/SplitKit.cpp

index 1c6a84e539440df857cb32a0fa497bd5ea454e47..6899924035502a5ad42cabd492b433626db7a816 100644 (file)
@@ -522,6 +522,27 @@ VNInfo *SplitEditor::defFromParent(unsigned RegIdx,
     Def = LIS.getSlotIndexes()
               ->insertMachineInstrInMaps(*CopyMI, Late)
               .getRegSlot();
+    if (LI->hasSubRanges()) {
+      LaneBitmask LM = LaneBitmask::getNone();
+      for (LiveInterval::SubRange &S : LI->subranges())
+        LM |= S.LaneMask;
+
+      if (MRI.getMaxLaneMaskForVReg(LI->reg) != LM) {
+        // Find subreg for the lane mask.
+        unsigned SubIdx = 0;
+        for (unsigned I = 1, E = TRI.getNumSubRegIndices(); I < E; ++I) {
+          if (TRI.getSubRegIndexLaneMask(I) == LM) {
+            SubIdx = I;
+            break;
+          }
+        }
+        if (SubIdx == 0)
+          report_fatal_error("Cannot find subreg index to cover all alive lanes");
+        CopyMI->getOperand(0).setSubReg(SubIdx);
+        CopyMI->getOperand(1).setSubReg(SubIdx);
+        CopyMI->getOperand(0).setIsUndef(true);
+      }
+    }
     ++NumCopies;
   }