[llvm] [AMDGPU] Move getVGPREncodingGranule to TargetParser (PR #226817)

Chinmay Deshpande via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 27 11:24:47 PDT 2026


https://github.com/chinmaydd created https://github.com/llvm/llvm-project/pull/226817

Add GPUKind and SubArch encoding-granule queries with an explicit wave size. Remove the BaseInfo counterpart and update codegen, assembler, and disassembler callers, preserving kernel descriptor wave-size overrides.

>From e975ae3962a15484dba8df32af8181782f39451b Mon Sep 17 00:00:00 2001
From: Chinmay Deshpande <chdeshpa at amd.com>
Date: Sun, 27 Sep 2026 14:11:21 -0400
Subject: [PATCH] [AMDGPU] Move getVGPREncodingGranule to TargetParser

Add GPUKind and SubArch encoding-granule queries with an explicit wave size.
Remove the BaseInfo counterpart and update codegen, assembler, and
disassembler callers, preserving kernel descriptor wave-size overrides.

Cover encoding granules across GPU generations and both wave sizes.

Change-Id: I1982fef776e5a0b7c613c274e544ba3e3f86f136
---
 .../llvm/TargetParser/AMDGPUTargetParser.h    |  8 ++++++
 llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp   |  2 +-
 .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp      |  7 +++--
 .../Disassembler/AMDGPUDisassembler.cpp       |  4 ++-
 llvm/lib/Target/AMDGPU/GCNSubtarget.h         |  3 +-
 .../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp    | 20 +++----------
 llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h |  8 ------
 llvm/lib/TargetParser/AMDGPUTargetParser.cpp  | 14 ++++++++++
 .../TargetParser/TargetParserTest.cpp         | 28 +++++++++++++++++++
 9 files changed, 64 insertions(+), 30 deletions(-)

diff --git a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
index 042542ced349d..b611e5cbcc4fe 100644
--- a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
+++ b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
@@ -180,6 +180,14 @@ LLVM_ABI unsigned getVGPRAllocGranule(GPUKind AK, bool IsWave32);
 LLVM_ABI unsigned getVGPRAllocGranule(Triple::SubArchType SubArch,
                                       bool IsWave32);
 
+/// \returns VGPR encoding granularity for \p AK, in registers. \p IsWave32
+/// selects the wavefront size encoded in the kernel descriptor. This can
+/// differ from the allocation granularity and is independent of dynamic
+/// VGPR mode.
+LLVM_ABI unsigned getVGPREncodingGranule(GPUKind AK, bool IsWave32);
+LLVM_ABI unsigned getVGPREncodingGranule(Triple::SubArchType SubArch,
+                                         bool IsWave32);
+
 /// \returns Number of physical VGPRs, i.e. the size of the register file a
 /// work-group's waves share. \p IsWave32 selects the wavefront size.
 LLVM_ABI unsigned getTotalNumVGPRs(GPUKind AK, bool IsWave32);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index c18b840c36791..89105a78c4e80 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -1431,7 +1431,7 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
                                           IsaInfo::getSGPREncodingGranule(STM));
   }
   ProgInfo.VGPRBlocks = GetNumGPRBlocks(ProgInfo.NumVGPRsForWavesPerEU,
-                                        IsaInfo::getVGPREncodingGranule(STM));
+                                        STM.getVGPREncodingGranule());
 
   const SIModeRegisterDefaults Mode = MFI->getMode();
 
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 812acc8f8be85..3a7213e52d5f5 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -6193,9 +6193,10 @@ bool AMDGPUAsmParser::calculateGPRBlocks(
     return SubGPR;
   };
 
-  VGPRBlocks = GetNumGPRBlocks(
-      NextFreeVGPR,
-      IsaInfo::getVGPREncodingGranule(getSTI(), EnableWavefrontSize32));
+  bool IsWave32 = EnableWavefrontSize32.value_or(
+      getSTI().getFeatureBits().test(FeatureWavefrontSize32));
+  VGPRBlocks = GetNumGPRBlocks(NextFreeVGPR,
+                               AMDGPU::getVGPREncodingGranule(Gfx, IsWave32));
   SGPRBlocks =
       GetNumGPRBlocks(NumSGPRs, IsaInfo::getSGPREncodingGranule(getSTI()));
 
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 3b200d412eb0d..8d930b3761859 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -2594,9 +2594,11 @@ Expected<bool> AMDGPUDisassembler::decodeCOMPUTE_PGM_RSRC1(
   uint32_t GranulatedWorkitemVGPRCount =
       GET_FIELD(COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT);
 
+  bool IsWave32 = EnableWavefrontSize32.value_or(
+      STI.getFeatureBits().test(AMDGPU::FeatureWavefrontSize32));
   uint32_t NextFreeVGPR =
       (GranulatedWorkitemVGPRCount + 1) *
-      AMDGPU::IsaInfo::getVGPREncodingGranule(STI, EnableWavefrontSize32);
+      AMDGPU::getVGPREncodingGranule(TargetID.getGPUKind(), IsWave32);
 
   KdStream << Indent << ".amdhsa_next_free_vgpr " << NextFreeVGPR << '\n';
 
diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.h b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
index 2e09f1f1fda39..c344367b460f4 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.h
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
@@ -853,7 +853,8 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
 
   /// \returns VGPR encoding granularity supported by the subtarget.
   unsigned getVGPREncodingGranule() const {
-    return AMDGPU::IsaInfo::getVGPREncodingGranule(*this);
+    return AMDGPU::getVGPREncodingGranule(getTargetID().getGPUKind(),
+                                          isWave32());
   }
 
   /// \returns Total number of VGPRs supported by the subtarget.
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index e45359719d6c9..baaef6293b9b0 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -1320,21 +1320,6 @@ unsigned getVGPRAllocGranule(const MCSubtargetInfo &STI,
   return IsWave32 ? 8 : 4;
 }
 
-unsigned getVGPREncodingGranule(const MCSubtargetInfo &STI,
-                                std::optional<bool> EnableWavefrontSize32) {
-  if (STI.getFeatureBits().test(FeatureGFX90AInsts))
-    return 8;
-
-  bool IsWave32 = EnableWavefrontSize32
-                      ? *EnableWavefrontSize32
-                      : STI.getFeatureBits().test(FeatureWavefrontSize32);
-
-  if (STI.getFeatureBits().test(Feature1024AddressableVGPRs))
-    return IsWave32 ? 16 : 8;
-
-  return IsWave32 ? 8 : 4;
-}
-
 unsigned getArchVGPRAllocGranule() { return 4; }
 
 unsigned getAddressableNumArchVGPRs(const MCSubtargetInfo &STI) {
@@ -1458,8 +1443,11 @@ unsigned getMaxNumVGPRs(const MCSubtargetInfo &STI, unsigned WavesPerEU,
 
 unsigned getEncodedNumVGPRBlocks(const MCSubtargetInfo &STI, unsigned NumVGPRs,
                                  std::optional<bool> EnableWavefrontSize32) {
+  bool IsWave32 = EnableWavefrontSize32.value_or(
+      STI.getFeatureBits().test(FeatureWavefrontSize32));
   return getGranulatedNumRegisterBlocks(
-             NumVGPRs, getVGPREncodingGranule(STI, EnableWavefrontSize32)) -
+             NumVGPRs, AMDGPU::getVGPREncodingGranule(
+                           parseArchAMDGCN(STI.getCPU()), IsWave32)) -
          1;
 }
 
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index bce059a0c18a7..564d77b0ad938 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -241,14 +241,6 @@ unsigned
 getVGPRAllocGranule(const MCSubtargetInfo &STI, unsigned DynamicVGPRBlockSize,
                     std::optional<bool> EnableWavefrontSize32 = std::nullopt);
 
-/// \returns VGPR encoding granularity for given subtarget \p STI.
-///
-/// For subtargets which support it, \p EnableWavefrontSize32 should match
-/// the ENABLE_WAVEFRONT_SIZE32 kernel descriptor field.
-unsigned getVGPREncodingGranule(
-    const MCSubtargetInfo &STI,
-    std::optional<bool> EnableWavefrontSize32 = std::nullopt);
-
 /// For subtargets with a unified VGPR file and mixed ArchVGPR/AGPR usage,
 /// returns the allocation granule for ArchVGPRs.
 unsigned getArchVGPRAllocGranule();
diff --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
index 756d665353c45..359b65363f2d1 100644
--- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
+++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
@@ -438,6 +438,20 @@ unsigned AMDGPU::getVGPRAllocGranule(Triple::SubArchType SubArch,
   return getVGPRAllocGranule(getGPUKindFromSubArch(SubArch), IsWave32);
 }
 
+unsigned AMDGPU::getVGPREncodingGranule(GPUKind AK, bool IsWave32) {
+  const AMDGPUFeatureBitset &Features = getFeatureBitset(AK);
+  if (Features.test(FEAT_GFX90A_INSTS))
+    return 8;
+  if (Features.test(FEAT_1024_ADDRESSABLE_VGPRS))
+    return IsWave32 ? 16 : 8;
+  return IsWave32 ? 8 : 4;
+}
+
+unsigned AMDGPU::getVGPREncodingGranule(Triple::SubArchType SubArch,
+                                        bool IsWave32) {
+  return getVGPREncodingGranule(getGPUKindFromSubArch(SubArch), IsWave32);
+}
+
 unsigned AMDGPU::getTotalNumVGPRs(GPUKind AK, bool IsWave32) {
   const AMDGPUFeatureBitset &Features = getFeatureBitset(AK);
   if (Features.test(FEAT_GFX90A_INSTS))
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 62d6f3a4c955b..2c963026a6a45 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -3226,6 +3226,34 @@ TEST(TargetParserTest, testAMDGPUgetVGPRAllocGranule) {
   EXPECT_EQ(AMDGPU::getVGPRAllocGranule(Triple::AMDGPUSubArch1100, true), 24u);
 }
 
+TEST(TargetParserTest, testAMDGPUgetVGPREncodingGranule) {
+  for (auto Kind :
+       {AMDGPU::GK_NONE, AMDGPU::GK_GFX600, AMDGPU::GK_GFX1030,
+        AMDGPU::GK_GFX1100, AMDGPU::GK_GFX1200, AMDGPU::GK_GFX1310}) {
+    SCOPED_TRACE(AMDGPU::getArchNameAMDGCN(Kind).str());
+    EXPECT_EQ(AMDGPU::getVGPREncodingGranule(Kind, false), 4u);
+    EXPECT_EQ(AMDGPU::getVGPREncodingGranule(Kind, true), 8u);
+  }
+  for (auto Kind : {AMDGPU::GK_GFX90A, AMDGPU::GK_GFX942, AMDGPU::GK_GFX950}) {
+    SCOPED_TRACE(AMDGPU::getArchNameAMDGCN(Kind).str());
+    EXPECT_EQ(AMDGPU::getVGPREncodingGranule(Kind, false), 8u);
+    EXPECT_EQ(AMDGPU::getVGPREncodingGranule(Kind, true), 8u);
+  }
+  EXPECT_EQ(AMDGPU::getVGPREncodingGranule(AMDGPU::GK_GFX1250, false), 8u);
+  EXPECT_EQ(AMDGPU::getVGPREncodingGranule(AMDGPU::GK_GFX1250, true), 16u);
+
+  // Encoding granules can be smaller than allocation granules.
+  EXPECT_EQ(AMDGPU::getVGPREncodingGranule(Triple::AMDGPUSubArch1030, true),
+            8u);
+  EXPECT_EQ(AMDGPU::getVGPREncodingGranule(Triple::AMDGPUSubArch1100, false),
+            4u);
+  EXPECT_EQ(AMDGPU::getVGPREncodingGranule(Triple::AMDGPUSubArch90A, false),
+            8u);
+  EXPECT_EQ(AMDGPU::getVGPREncodingGranule(Triple::AMDGPUSubArch1250, true),
+            16u);
+  EXPECT_EQ(AMDGPU::getVGPREncodingGranule(Triple::NoSubArch, false), 4u);
+}
+
 TEST(TargetParserTest, testAMDGPUgetTotalNumVGPRs) {
   // Pre-gfx10 the file is 256 registers, and gfx90a doubles it by unifying the
   // AGPRs. From gfx10 on it is split between the waves of a wave64 kernel.



More information about the llvm-commits mailing list