[llvm] [AMDGPU] Move stress options into getMaxNumVectorRegs/getBaseMaxNumSGPRs (PR #214762)

Romanov Vlad via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 05:38:30 PDT 2026


https://github.com/romanovvlad updated https://github.com/llvm/llvm-project/pull/214762

>From 5c0c2e51b9b49814e5b18235fd00caaf30a64ef1 Mon Sep 17 00:00:00 2001
From: Vlad <Vladislav.Romanov at amd.com>
Date: Fri, 7 Aug 2026 05:40:32 -0500
Subject: [PATCH 1/2] [AMDGPU] Move stress options into
 getMaxNumVectorRegs/getBaseMaxNumSGPRs

Move -amdgpu-stress-{vgpr,agpr,sgpr} options from
SIRegisterInfo::getReservedRegs into GCNSubtarget functions so that all
downstream consumers (NSA reassign, MFMA rewrite, scheduler) see the
stress limits, not just the reserved-reg path.

The function hierarchy is refactored so getMaxNumVectorRegs is the
primary computation point: it computes the occupancy budget, applies any
amdgpu-num-vgpr attribute override, splits VGPRs/AGPRs, then applies
stress overrides last.
---
 llvm/lib/Target/AMDGPU/GCNSubtarget.cpp   | 45 ++++++++++++++++++-----
 llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp | 20 ----------
 2 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp b/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
index 1c0e718bd8d97..8f3955b4346ab 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
@@ -53,6 +53,18 @@ static cl::opt<unsigned>
                  cl::desc("Number of addresses from which to enable MIMG NSA."),
                  cl::init(2), cl::Hidden);
 
+static cl::opt<unsigned> StressVGPRLimit(
+    "amdgpu-stress-vgpr", cl::Hidden, cl::init(0),
+    cl::desc("Limit VGPRs to N arch registers"));
+
+static cl::opt<unsigned> StressAGPRLimit(
+    "amdgpu-stress-agpr", cl::Hidden, cl::init(0),
+    cl::desc("Limit AGPRs to N registers"));
+
+static cl::opt<unsigned> StressSGPRLimit(
+    "amdgpu-stress-sgpr", cl::Hidden, cl::init(0),
+    cl::desc("Limit SGPRs to N registers"));
+
 GCNSubtarget::~GCNSubtarget() = default;
 
 static AMDGPUSubtarget::Generation computeDefaultGeneration(const Triple &TT) {
@@ -571,6 +583,10 @@ unsigned GCNSubtarget::getBaseMaxNumSGPRs(
       MaxNumSGPRs = Requested;
   }
 
+  // Stress test: override SGPR limit.
+  if (StressSGPRLimit.getNumOccurrences())
+    MaxNumSGPRs = StressSGPRLimit;
+
   if (hasSGPRInitBug())
     MaxNumSGPRs = AMDGPU::IsaInfo::FIXED_NUM_SGPRS_FOR_INIT_BUG;
 
@@ -630,6 +646,18 @@ unsigned GCNSubtarget::getBaseMaxNumVGPRs(
 }
 
 unsigned GCNSubtarget::getMaxNumVGPRs(const Function &F) const {
+  auto [VGPRs, AGPRs] = getMaxNumVectorRegs(F);
+  // On gfx90a+ VGPRs and AGPRs share a unified register file.
+  // On gfx908 they are independent, so only VGPRs count toward the budget.
+  return hasGFX90AInsts() ? VGPRs + AGPRs : VGPRs;
+}
+
+unsigned GCNSubtarget::getMaxNumVGPRs(const MachineFunction &MF) const {
+  return getMaxNumVGPRs(MF.getFunction());
+}
+
+std::pair<unsigned, unsigned>
+GCNSubtarget::getMaxNumVectorRegs(const Function &F) const {
   // Temporarily check both the attribute and the subtarget feature, until the
   // latter is removed.
   unsigned DynamicVGPRBlockSize = AMDGPU::getDynamicVGPRBlockSize(F);
@@ -637,18 +665,9 @@ unsigned GCNSubtarget::getMaxNumVGPRs(const Function &F) const {
     DynamicVGPRBlockSize = getDynamicVGPRBlockSize();
 
   std::pair<unsigned, unsigned> Waves = getWavesPerEU(F);
-  return getBaseMaxNumVGPRs(
+  const unsigned MaxVectorRegs = getBaseMaxNumVGPRs(
       F, {getMinNumVGPRs(Waves.second, DynamicVGPRBlockSize),
           getMaxNumVGPRs(Waves.first, DynamicVGPRBlockSize)});
-}
-
-unsigned GCNSubtarget::getMaxNumVGPRs(const MachineFunction &MF) const {
-  return getMaxNumVGPRs(MF.getFunction());
-}
-
-std::pair<unsigned, unsigned>
-GCNSubtarget::getMaxNumVectorRegs(const Function &F) const {
-  const unsigned MaxVectorRegs = getMaxNumVGPRs(F);
 
   unsigned MaxNumVGPRs = MaxVectorRegs;
   unsigned MaxNumAGPRs = 0;
@@ -700,6 +719,12 @@ GCNSubtarget::getMaxNumVectorRegs(const Function &F) const {
     MaxNumAGPRs = MaxNumVGPRs = MaxVectorRegs;
   }
 
+  // Stress test: override VGPR/AGPR limits.
+  if (StressVGPRLimit.getNumOccurrences())
+    MaxNumVGPRs = StressVGPRLimit;
+  if (StressAGPRLimit.getNumOccurrences())
+    MaxNumAGPRs = StressAGPRLimit;
+
   return std::pair(MaxNumVGPRs, MaxNumAGPRs);
 }
 
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index a3d6509628d50..12965056f6ec9 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -40,18 +40,6 @@ static cl::opt<bool> EnableSpillCFISavedRegs(
     cl::desc("Enable spilling the registers required for CFI emission"),
     cl::ReallyHidden, cl::init(false), cl::ZeroOrMore);
 
-static cl::opt<unsigned> StressVGPRLimit(
-    "amdgpu-stress-vgpr", cl::Hidden, cl::init(0),
-    cl::desc("Limit VGPRs to N registers by reserving the rest"));
-
-static cl::opt<unsigned> StressAGPRLimit(
-    "amdgpu-stress-agpr", cl::Hidden, cl::init(0),
-    cl::desc("Limit AGPRs to N registers by reserving the rest"));
-
-static cl::opt<unsigned> StressSGPRLimit(
-    "amdgpu-stress-sgpr", cl::Hidden, cl::init(0),
-    cl::desc("Limit SGPRs to N registers by reserving the rest"));
-
 std::array<std::vector<int16_t>, 32> SIRegisterInfo::RegSplitParts;
 std::array<std::array<uint16_t, 32>, 9> SIRegisterInfo::SubRegFromChannelTable;
 
@@ -656,8 +644,6 @@ BitVector SIRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
   // Reserve SGPRs.
   //
   unsigned MaxNumSGPRs = ST.getMaxNumSGPRs(MF);
-  if (StressSGPRLimit.getNumOccurrences() && StressSGPRLimit < MaxNumSGPRs)
-    MaxNumSGPRs = StressSGPRLimit;
   unsigned TotalNumSGPRs = AMDGPU::SGPR_32RegClass.getNumRegs();
   for (const TargetRegisterClass &RC : regclasses()) {
     if (RC.isBaseClass() && isSGPRClass(&RC)) {
@@ -715,12 +701,6 @@ BitVector SIRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
   //
   auto [MaxNumVGPRs, MaxNumAGPRs] = ST.getMaxNumVectorRegs(MF.getFunction());
 
-  // Stress test: override VGPR/AGPR limits.
-  if (StressVGPRLimit.getNumOccurrences() && StressVGPRLimit < MaxNumVGPRs)
-    MaxNumVGPRs = StressVGPRLimit;
-  if (StressAGPRLimit.getNumOccurrences() && StressAGPRLimit < MaxNumAGPRs)
-    MaxNumAGPRs = StressAGPRLimit;
-
   for (const TargetRegisterClass &RC : regclasses()) {
     if (RC.isBaseClass() && isVGPRClass(&RC)) {
       unsigned NumRegs = divideCeil(getRegSizeInBits(RC), 32);

>From c0b968af4fbc847960397afce7e78d639dccd276 Mon Sep 17 00:00:00 2001
From: Vlad <Vladislav.Romanov at amd.com>
Date: Tue, 11 Aug 2026 07:32:45 -0500
Subject: [PATCH 2/2] fix formatting

---
 llvm/lib/Target/AMDGPU/GCNSubtarget.cpp | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp b/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
index 8f3955b4346ab..25796e540ee03 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
@@ -53,17 +53,17 @@ static cl::opt<unsigned>
                  cl::desc("Number of addresses from which to enable MIMG NSA."),
                  cl::init(2), cl::Hidden);
 
-static cl::opt<unsigned> StressVGPRLimit(
-    "amdgpu-stress-vgpr", cl::Hidden, cl::init(0),
-    cl::desc("Limit VGPRs to N arch registers"));
+static cl::opt<unsigned>
+    StressVGPRLimit("amdgpu-stress-vgpr", cl::Hidden, cl::init(0),
+                    cl::desc("Limit VGPRs to N arch registers"));
 
-static cl::opt<unsigned> StressAGPRLimit(
-    "amdgpu-stress-agpr", cl::Hidden, cl::init(0),
-    cl::desc("Limit AGPRs to N registers"));
+static cl::opt<unsigned>
+    StressAGPRLimit("amdgpu-stress-agpr", cl::Hidden, cl::init(0),
+                    cl::desc("Limit AGPRs to N registers"));
 
-static cl::opt<unsigned> StressSGPRLimit(
-    "amdgpu-stress-sgpr", cl::Hidden, cl::init(0),
-    cl::desc("Limit SGPRs to N registers"));
+static cl::opt<unsigned>
+    StressSGPRLimit("amdgpu-stress-sgpr", cl::Hidden, cl::init(0),
+                    cl::desc("Limit SGPRs to N registers"));
 
 GCNSubtarget::~GCNSubtarget() = default;
 



More information about the llvm-commits mailing list