[llvm-branch-commits] [llvm] Greedy: Take hints from copy to physical subreg (PR #160467)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Sep 26 08:48:27 PDT 2025


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/160467

>From f409ccc1223fc7965f52e522d260295cb6053e4f Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 24 Sep 2025 16:53:33 +0900
Subject: [PATCH 1/2] Greedy: Take hints from copy to physical subreg

Previously this took hints from subregister extract of physreg,
like  %vreg.sub = COPY $physreg

This now also handles the rarer case:
  $physreg_sub = COPY %vreg

Also make an accidental bug here before explicit; this was
only using the superregister as a hint if it was already
in the copy, and not if using the existing assignment. There are
a handful of regressions in that case, so leave that extension
for a future change.
---
 llvm/lib/CodeGen/RegAllocGreedy.cpp | 35 ++++++++++++++++-------------
 llvm/test/CodeGen/X86/shift-i128.ll |  3 +--
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 6e0585b2e9e55..0df8713dd892b 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -2439,25 +2439,28 @@ void RAGreedy::collectHintInfo(Register Reg, HintsInfo &Out) {
     unsigned SubReg = Opnd.getSubReg();
 
     // Get the current assignment.
-    MCRegister OtherPhysReg =
-        OtherReg.isPhysical() ? OtherReg.asMCReg() : VRM->getPhys(OtherReg);
-    if (OtherSubReg) {
-      if (OtherReg.isPhysical()) {
-        MCRegister Tuple =
-            TRI->getMatchingSuperReg(OtherPhysReg, OtherSubReg, RC);
-        if (!Tuple)
-          continue;
-        OtherPhysReg = Tuple;
-      } else {
-        // TODO: There should be a hinting mechanism for subregisters
-        if (SubReg != OtherSubReg)
-          continue;
-      }
+    MCRegister OtherPhysReg;
+    if (OtherReg.isPhysical()) {
+      if (OtherSubReg)
+        OtherPhysReg = TRI->getMatchingSuperReg(OtherReg, OtherSubReg, RC);
+      else if (SubReg)
+        OtherPhysReg = TRI->getMatchingSuperReg(OtherReg, SubReg, RC);
+      else
+        OtherPhysReg = OtherReg;
+    } else {
+      OtherPhysReg = VRM->getPhys(OtherReg);
+      // TODO: Should find matching superregister, but applying this in the
+      // non-hint case currently causes regressions
+
+      if (SubReg && OtherSubReg && SubReg != OtherSubReg)
+        continue;
     }
 
     // Push the collected information.
-    Out.push_back(HintInfo(MBFI->getBlockFreq(Instr.getParent()), OtherReg,
-                           OtherPhysReg));
+    if (OtherPhysReg) {
+      Out.push_back(HintInfo(MBFI->getBlockFreq(Instr.getParent()), OtherReg,
+                             OtherPhysReg));
+    }
   }
 }
 
diff --git a/llvm/test/CodeGen/X86/shift-i128.ll b/llvm/test/CodeGen/X86/shift-i128.ll
index 7462c77482827..049ee47af9681 100644
--- a/llvm/test/CodeGen/X86/shift-i128.ll
+++ b/llvm/test/CodeGen/X86/shift-i128.ll
@@ -613,8 +613,7 @@ define void @test_shl_v2i128(<2 x i128> %x, <2 x i128> %a, ptr nocapture %r) nou
 ; i686-NEXT:    shldl %cl, %esi, %ebx
 ; i686-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %edi # 4-byte Reload
 ; i686-NEXT:    movl %edi, %esi
-; i686-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload
-; i686-NEXT:    movl %eax, %ecx
+; i686-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
 ; i686-NEXT:    shll %cl, %esi
 ; i686-NEXT:    shldl %cl, %edi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
 ; i686-NEXT:    negl %edx

>From 0581982382d14b2451abfc6f2fc593d5d15e22a0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 24 Sep 2025 18:54:59 +0900
Subject: [PATCH 2/2] XXX scale block frequencies by subreg

---
 llvm/lib/CodeGen/RegAllocGreedy.cpp | 32 ++++++++++++++++++++++++++++-
 llvm/lib/CodeGen/RegAllocGreedy.h   | 13 +++++++++++-
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 0df8713dd892b..9d3165b790642 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -2458,7 +2458,28 @@ void RAGreedy::collectHintInfo(Register Reg, HintsInfo &Out) {
 
     // Push the collected information.
     if (OtherPhysReg) {
-      Out.push_back(HintInfo(MBFI->getBlockFreq(Instr.getParent()), OtherReg,
+      BlockFrequency Freq = MBFI->getBlockFreq(Instr.getParent());
+
+      if (OtherSubReg) {
+        const TargetRegisterClass *OtherRC = MRI->getRegClass(OtherReg);
+        unsigned FullRegCopyCost = OtherRC->getCopyCost();
+
+        const TargetRegisterClass *OtherSubRC = TRI->getSubRegisterClass(OtherRC, OtherSubReg);
+        unsigned SubRegCopyCost = OtherSubRC->getCopyCost();
+
+        BranchProbability Scaling(SubRegCopyCost, FullRegCopyCost);
+        Freq *= Scaling;
+      } else if (SubReg) {
+        unsigned FullRegCopyCost = RC->getCopyCost();
+        const TargetRegisterClass *SubRC = TRI->getSubRegisterClass(RC, SubReg);
+        unsigned SubRegCopyCost = SubRC->getCopyCost();
+
+        BranchProbability Scaling(SubRegCopyCost, FullRegCopyCost);
+        Freq *= Scaling;
+
+      }
+
+      Out.push_back(HintInfo(Freq, OtherReg,
                              OtherPhysReg));
     }
   }
@@ -2471,6 +2492,13 @@ BlockFrequency RAGreedy::getBrokenHintFreq(const HintsInfo &List,
                                            MCRegister PhysReg) {
   BlockFrequency Cost = BlockFrequency(0);
   for (const HintInfo &Info : List) {
+
+    if (!Info.PhysReg) {
+      // Apply subreg hint
+      continue;
+    }
+
+
     if (Info.PhysReg != PhysReg)
       Cost += Info.Freq;
   }
@@ -2536,6 +2564,8 @@ void RAGreedy::tryHintRecoloring(const LiveInterval &VirtReg) {
     // non-identity copies.
     if (CurrPhys != PhysReg) {
       LLVM_DEBUG(dbgs() << "Checking profitability:\n");
+
+      // TODO: Scale by copy cost
       BlockFrequency OldCopiesCost = getBrokenHintFreq(Info, CurrPhys);
       BlockFrequency NewCopiesCost = getBrokenHintFreq(Info, PhysReg);
       LLVM_DEBUG(dbgs() << "Old Cost: " << printBlockFreq(*MBFI, OldCopiesCost)
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h
index 7f013d1f1f726..e0bb26e63e323 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.h
+++ b/llvm/lib/CodeGen/RegAllocGreedy.h
@@ -385,12 +385,23 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public RegAllocBase,
     BlockFrequency Freq;
     /// The virtual register or physical register.
     Register Reg;
+    unsigned SubReg = 0;
+
+    Register HintReg;
+    unsigned HintSubReg = 0;
+
     /// Its currently assigned register.
     /// In case of a physical register Reg == PhysReg.
     MCRegister PhysReg;
 
     HintInfo(BlockFrequency Freq, Register Reg, MCRegister PhysReg)
-        : Freq(Freq), Reg(Reg), PhysReg(PhysReg) {}
+      : Freq(Freq), Reg(Reg), PhysReg(PhysReg) {}
+
+    HintInfo(BlockFrequency Freq,
+             Register Reg, unsigned SubReg,
+             Register HintReg, unsigned HintSubReg)
+      : Freq(Freq), Reg(Reg), SubReg(SubReg),
+      HintReg(HintReg), HintSubReg(HintSubReg) {}
   };
   using HintsInfo = SmallVector<HintInfo, 4>;
 



More information about the llvm-branch-commits mailing list