[llvm] [AMDGPU] Overwrite shouldCoalesce to stop merging imm mov with virtual reg with large valnos (PR #209608)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 24 08:07:31 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Guo Chen (broxigarchen)

<details>
<summary>Changes</summary>

Isel pattern putting imm inside reg_sequence create side effects when register coalescer join these `copy` from imm
```
%1 = v_mov_b16_t16_e64 ...
%2.hi16 = copy %1
%2.lo16 = ....
...
%3.hi16 = copy %1
%3.lo16 = ....
....
%4.hi16 = copy %1
%4.lo16 = ....
```
to
```
%1 = v_mov_b16_t16_e64 ...
%2.hi16 = copy %1
%2.lo16 = ....
...
%2.lo16 = ... (reuse %2 and repeat)
....
```
When the number of copy increase this inserts a large number of WAR hazzards on the reused virutal reg, and the machine scheduler bail out getting higher reg pressure after sorting.

Overwrite the `shouldCoalsce` to add additional checks on merging copy with mov imms, and stop merging these copies when the size of valnos is too large.

---
Full diff: https://github.com/llvm/llvm-project/pull/209608.diff


2 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp (+62) 
- (modified) llvm/lib/Target/AMDGPU/SIRegisterInfo.h (+5) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index 358aa054b3a3f..cda81d0143a07 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -4339,3 +4339,65 @@ SIRegisterInfo::getVRegFlagsOfReg(Register Reg,
     RegFlags.push_back("WWM_REG");
   return RegFlags;
 }
+
+// Check if a VReg Def is a Mov Imm using LIS
+static bool IsVRegDefImm(Register VReg, LaneBitmask LaneMask,
+                         const LiveIntervals &LIS, SlotIndex UseIdx) {
+  if (!LIS.hasInterval(VReg))
+    return false;
+
+  const LiveInterval &LI = LIS.getInterval(VReg);
+  if (!LI.hasSubRanges()) {
+    const VNInfo *VNI = LI.getVNInfoBefore(UseIdx);
+    if (!VNI || VNI->isUnused() || VNI->isPHIDef())
+      return false;
+
+    MachineInstr *DefMI = LIS.getInstructionFromIndex(VNI->def);
+    if (DefMI && DefMI->isMoveImmediate())
+      return true;
+
+    return false;
+  }
+
+  for (const LiveInterval::SubRange &SR : LI.subranges()) {
+    const VNInfo *VNI = SR.getVNInfoBefore(UseIdx);
+    if (!VNI || VNI->isUnused() || VNI->isPHIDef())
+      return false;
+
+    MachineInstr *DefMI = LIS.getInstructionFromIndex(VNI->def);
+    if (DefMI && DefMI->isMoveImmediate())
+      return true;
+  }
+  return false;
+}
+
+bool SIRegisterInfo::shouldCoalesce(
+    MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg,
+    const TargetRegisterClass *DstRC, unsigned DstSubReg,
+    const TargetRegisterClass *NewRC, LiveIntervals &LIS) const {
+  assert(MI->isCopy() && "Only expecting COPY instructions");
+
+  // Do not coalesce if src is a constant while size of LI subrange sum is
+  // more than 100. Let RA decide if need to rematerialize
+  MachineFunction *MF = MI->getParent()->getParent();
+  MachineRegisterInfo &MRI = MF->getRegInfo();
+  auto *TRI = static_cast<const SIRegisterInfo *>(MRI.getTargetRegisterInfo());
+  Register DstReg = MI->getOperand(0).getReg();
+  Register SrcReg = MI->getOperand(1).getReg();
+
+  if (SrcReg.isVirtual() && DstReg.isVirtual()) {
+    LaneBitmask LaneMask =
+        TRI->getSubRegIndexLaneMask(MI->getOperand(1).getSubReg());
+    SlotIndex MIIdx = LIS.getInstructionIndex(*MI);
+    if (IsVRegDefImm(SrcReg, LaneMask, LIS, MIIdx)) {
+      LiveInterval &LIDst = LIS.getInterval(SrcReg);
+      LiveInterval &LISrc = LIS.getInterval(DstReg);
+      if (LISrc.valnos.size() + LIDst.valnos.size() > 100) {
+        return false;
+      }
+    }
+  }
+
+  return TargetRegisterInfo::shouldCoalesce(MI, SrcRC, SubReg, DstRC, DstSubReg,
+                                            NewRC, LIS);
+}
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
index e464c9334ffea..01a94f56382d7 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
@@ -506,6 +506,11 @@ class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
                 ? 2.0
                 : 1.0);
   }
+
+  bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC,
+                      unsigned SubReg, const TargetRegisterClass *DstRC,
+                      unsigned DstSubReg, const TargetRegisterClass *NewRC,
+                      LiveIntervals &LIS) const override;
 };
 
 } // End namespace llvm

``````````

</details>


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


More information about the llvm-commits mailing list