[llvm] RegAllocGreedy: Fix subrange based instruction split logic (PR #120199)

Quentin Colombet via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 17 02:31:52 PST 2024


================
@@ -1387,18 +1357,34 @@ static bool readsLaneSubset(const MachineRegisterInfo &MRI,
       DestSrc->Destination->getSubReg() == DestSrc->Source->getSubReg())
     return false;
 
+  Register Reg = VirtReg.reg();
+
   // FIXME: We're only considering uses, but should be consider defs too?
-  LaneBitmask ReadMask = getInstReadLaneMask(MRI, *TRI, *MI, VirtReg.reg());
+  LaneBitmask UseMask;
+  SmallVector<std::pair<MachineInstr *, unsigned>, 8> Ops;
+  (void)AnalyzeVirtRegInBundle(const_cast<MachineInstr &>(*MI), Reg, &Ops);
 
-  LaneBitmask LiveAtMask;
-  for (const LiveInterval::SubRange &S : VirtReg.subranges()) {
-    if (S.liveAt(Use))
-      LiveAtMask |= S.LaneMask;
+  for (auto [MI, OpIdx] : Ops) {
+    const MachineOperand &MO = MI->getOperand(OpIdx);
+    assert(MO.isReg() && MO.getReg() == Reg);
+    unsigned SubReg = MO.getSubReg();
+    if (SubReg == 0 && MO.isUse()) {
+      if (MO.isUndef())
+        continue;
+      return false;
+    }
+
+    LaneBitmask SubRegMask = TRI->getSubRegIndexLaneMask(SubReg);
+    if (MO.isDef()) {
+      if (!MO.isUndef())
+        UseMask |= ~SubRegMask;
+    } else
+      UseMask |= SubRegMask;
   }
 
   // If the live lanes aren't different from the lanes used by the instruction,
   // this doesn't help.
-  return (ReadMask & ~(LiveAtMask & TRI->getCoveringLanes())).any();
+  return MRI.getMaxLaneMaskForVReg(VirtReg.reg()) != UseMask;
----------------
qcolombet wrote:

Instead of an exact match, shouldn't we check for an overlap?
The comment of this method says "reads a subset of the lanes". So any lane read should return `true`.

https://github.com/llvm/llvm-project/pull/120199


More information about the llvm-commits mailing list