[llvm] 07897c2 - AMDGPU: TableGen the subarch triple name table (#212627)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 30 01:22:11 PDT 2026


Author: Matt Arsenault
Date: 2026-07-30T08:22:06Z
New Revision: 07897c2bde598dc4c42b159472bbb70057f3388b

URL: https://github.com/llvm/llvm-project/commit/07897c2bde598dc4c42b159472bbb70057f3388b
DIFF: https://github.com/llvm/llvm-project/commit/07897c2bde598dc4c42b159472bbb70057f3388b.diff

LOG: AMDGPU: TableGen the subarch triple name table (#212627)

Co-authored-by: Claude (Claude-Opus-4.8)

Added: 
    

Modified: 
    llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
    llvm/lib/TargetParser/AMDGPUTargetParser.cpp
    llvm/lib/TargetParser/Triple.cpp
    llvm/test/TableGen/AMDGPUTargetDefErrors.td
    llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
index 8f8decdb373ce..fd0072c89be23 100644
--- a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
+++ b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
@@ -144,6 +144,10 @@ LLVM_ABI StringRef getArchNameR600(GPUKind AK);
 /// subarch. The major-only subarches map to their generic/lowest
 /// representative, matching the default subtarget for an unspecified -mcpu.
 LLVM_ABI StringRef getArchNameFromSubArch(Triple::SubArchType SubArch);
+
+/// Returns the triple subarch name for an AMDGPU subarch, e.g.
+/// AMDGPUSubArch900 -> "amdgpu9.00". Returns "amdgpu" for NoSubArch.
+LLVM_ABI StringRef getSubArchName(Triple::SubArchType SubArch);
 LLVM_ABI StringRef getCanonicalArchName(const Triple &T, StringRef Arch);
 LLVM_ABI GPUKind parseArchAMDGCN(StringRef CPU);
 LLVM_ABI GPUKind parseArchR600(StringRef CPU);

diff  --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
index f866a092d6697..6e16bc8dc9507 100644
--- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
+++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 #include <array>
+#include <cassert>
 
 using namespace llvm;
 using namespace AMDGPU;
@@ -142,6 +143,17 @@ constexpr std::array<StringTable::Offset, NumAMDGPUSubArches>
         Map[Entry.SubArch - Triple::FirstAMDGPUSubArch] = Entry.NameOffset;
       return Map;
     }();
+
+// SubArch -> triple-name-offset (e.g. "amdgpu9.00"), like
+// AMDGPUSubArchNameOffsets.
+constexpr std::array<StringTable::Offset, NumAMDGPUSubArches>
+    AMDGPUSubArchTripleNameOffsets = [] {
+      std::array<StringTable::Offset, NumAMDGPUSubArches> Map{};
+      for (const AMDGPUSubArchNameEntry &Entry : AMDGPUSubArchNames)
+        Map[Entry.SubArch - Triple::FirstAMDGPUSubArch] =
+            Entry.TripleNameOffset;
+      return Map;
+    }();
 } // namespace
 
 StringRef llvm::AMDGPU::getArchFamilyNameAMDGCN(GPUKind AK) {
@@ -264,6 +276,17 @@ StringRef llvm::AMDGPU::getArchNameFromSubArch(Triple::SubArchType SubArch) {
                                                    Triple::FirstAMDGPUSubArch]];
 }
 
+StringRef llvm::AMDGPU::getSubArchName(Triple::SubArchType SubArch) {
+  if (SubArch == Triple::NoSubArch)
+    return AMDGPUNameStrTab[AMDGPUNoSubArchNameOffset];
+
+  assert(SubArch >= Triple::FirstAMDGPUSubArch &&
+         SubArch <= Triple::LastAMDGPUSubArch &&
+         "expected an AMDGPU subarch or NoSubArch");
+  return AMDGPUNameStrTab
+      [AMDGPUSubArchTripleNameOffsets[SubArch - Triple::FirstAMDGPUSubArch]];
+}
+
 StringRef llvm::AMDGPU::getArchNameR600(GPUKind AK) {
   const R600Info *Info = getR600Info(AK);
   return Info ? R600NameStrTab[Info->Name] : "";

diff  --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 4710d1df40811..af15ab93b238c 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -246,51 +246,8 @@ StringRef Triple::getArchName(ArchType Kind, SubArchType SubArch) {
       break;
     }
     break;
-  case Triple::amdgpu: {
-    if (SubArch < Triple::FirstAMDGPUSubArch ||
-        SubArch > Triple::LastAMDGPUSubArch)
-      break;
-
-    static const StringLiteral AMDGPUSubArchNames[Triple::LastAMDGPUSubArch -
-                                                  Triple::FirstAMDGPUSubArch +
-                                                  1] = {
-        "amdgpu6",     "amdgpu6.00",  "amdgpu6.01",  "amdgpu6.02",
-
-        "amdgpu7",     "amdgpu7.00",  "amdgpu7.01",  "amdgpu7.02",
-        "amdgpu7.03",  "amdgpu7.04",  "amdgpu7.05",
-
-        "amdgpu8",     "amdgpu8.01",  "amdgpu8.02",  "amdgpu8.03",
-        "amdgpu8.05",
-
-        "amdgpu8.10",
-
-        "amdgpu9",     "amdgpu9.00",  "amdgpu9.02",  "amdgpu9.04",
-        "amdgpu9.06",  "amdgpu9.09",  "amdgpu9.0c",
-
-        "amdgpu9.08",  "amdgpu9.0a",
-
-        "amdgpu9.4",   "amdgpu9.42",  "amdgpu9.50",
-
-        "amdgpu10.1",  "amdgpu10.10", "amdgpu10.11", "amdgpu10.12",
-        "amdgpu10.13",
-
-        "amdgpu10.3",  "amdgpu10.30", "amdgpu10.31", "amdgpu10.32",
-        "amdgpu10.33", "amdgpu10.34", "amdgpu10.35", "amdgpu10.36",
-
-        "amdgpu11",    "amdgpu11.00", "amdgpu11.01", "amdgpu11.02",
-        "amdgpu11.03", "amdgpu11.50", "amdgpu11.51", "amdgpu11.52",
-        "amdgpu11.53", "amdgpu11.54",
-
-        "amdgpu11.7",  "amdgpu11.70", "amdgpu11.71", "amdgpu11.72",
-
-        "amdgpu12",    "amdgpu12.00", "amdgpu12.01",
-
-        "amdgpu12.5",  "amdgpu12.50", "amdgpu12.51",
-
-        "amdgpu13",    "amdgpu13.10"};
-
-    return AMDGPUSubArchNames[SubArch - Triple::FirstAMDGPUSubArch];
-  }
+  case Triple::amdgpu:
+    return AMDGPU::getSubArchName(SubArch);
   default:
     break;
   }

diff  --git a/llvm/test/TableGen/AMDGPUTargetDefErrors.td b/llvm/test/TableGen/AMDGPUTargetDefErrors.td
index cd9111a50743e..f7b2171210a0a 100644
--- a/llvm/test/TableGen/AMDGPUTargetDefErrors.td
+++ b/llvm/test/TableGen/AMDGPUTargetDefErrors.td
@@ -7,6 +7,8 @@
 // RUN:   | FileCheck %t/alias-shadows-processor.td -DFILE=%t/alias-shadows-processor.td --implicit-check-not="error:"
 // RUN: not llvm-tblgen -gen-amdgpu-target-def -I %p/../../include %t/bad-isa-version.td 2>&1 \
 // RUN:   | FileCheck %t/bad-isa-version.td -DFILE=%t/bad-isa-version.td --implicit-check-not="error:"
+// RUN: not llvm-tblgen -gen-amdgpu-target-def -I %p/../../include %t/bad-stepping.td 2>&1 \
+// RUN:   | FileCheck %t/bad-stepping.td -DFILE=%t/bad-stepping.td --implicit-check-not="error:"
 
 // Verify the validation performed by the -gen-amdgpu-target-def backend.
 
@@ -72,3 +74,18 @@ class AMDGPUGPUInfo<list<int> isa = []> {
 // diagnostic in release builds.
 // CHECK: [[FILE]]:[[#@LINE+1]]:1: error: GPU 'gfx900' must have a 3-element [major, minor, stepping] IsaVersion
 def : ProcessorModel<"gfx900", NoSchedModel, []>, AMDGPUGPUInfo<[9, 0]>;
+
+//--- bad-stepping.td
+include "llvm/Target/Target.td"
+def MyTarget : Target;
+class AMDGPUArchFeature<string spelling> { string Spelling = spelling; }
+class AMDGPUGPUInfo<list<int> isa = []> {
+  list<AMDGPUArchFeature> ArchFeatures = [];
+  list<int> IsaVersion = isa;
+  list<Processor> CoveredGPUs = [];
+  bit IsPseudoTarget = false;
+}
+// The stepping must fit in a single hex digit so it can be spelled in the
+// triple subarch name (e.g. "amdgpu9.0c").
+// CHECK: [[FILE]]:[[#@LINE+1]]:1: error: GPU 'gfx900' stepping must be a single hex digit
+def : ProcessorModel<"gfx900", NoSchedModel, []>, AMDGPUGPUInfo<[9, 0, 16]>;

diff  --git a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
index 5588a74719428..b303a415521cb 100644
--- a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
@@ -12,6 +12,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/raw_ostream.h"
@@ -32,17 +34,22 @@ static void emitGPUKindEnum(raw_ostream &OS, StringRef Name) {
     OS << ((C == '-') ? '_' : toUpper(C));
 }
 
-// Derive the Triple::SubArchType from a "gfx..." GPU name, e.g. "gfx90a" ->
-// Triple::AMDGPUSubArch90A, "gfx9-generic" -> Triple::AMDGPUSubArch9 (the
-// family major). The name must be a real hardware GPU (not a pseudo target).
-static void emitSubArchForName(raw_ostream &OS, StringRef Name) {
+// Emit the Triple::AMDGPUSubArch enumerator suffix for a "gfx..." GPU name,
+// e.g. "gfx90a" -> "90A", "gfx9-generic" -> "9" (the family major).
+static void emitSubArchSuffix(raw_ostream &OS, StringRef Name) {
   StringRef Suffix = Name;
   Suffix.consume_front("gfx");
   Suffix.consume_back("-generic");
 
-  OS << "Triple::AMDGPUSubArch";
   for (char C : Suffix)
-    OS << ((C == '-') ? '_' : toUpper(C));
+    OS << static_cast<char>((C == '-') ? '_' : toUpper(C));
+}
+
+/// Derive the Triple::SubArchType from a "gfx..." GPU name, e.g. "gfx90a" ->
+/// Triple::AMDGPUSubArch90A
+static void emitSubArchForName(raw_ostream &OS, StringRef Name) {
+  OS << "Triple::AMDGPUSubArch";
+  emitSubArchSuffix(OS, Name);
 }
 
 // Derive the Triple::SubArchType for a canonical GPU record. A pseudo target
@@ -92,6 +99,29 @@ static void emitIsaVersion(raw_ostream &OS, const Record *Rec, char Open,
   OS << Open << V[0] << ", " << V[1] << ", " << V[2] << Close;
 }
 
+// Emit the triple subarch name for a concrete GPU, e.g. gfx90c / [9, 0, 12] ->
+// "amdgpu9.0c" (stepping is a single lowercase hex digit).
+static void emitConcreteSubArchTripleName(raw_ostream &OS, const Record *Rec) {
+  std::vector<int64_t> V = Rec->getValueAsListOfInts("IsaVersion");
+
+  // Assuming emitIsaVersion validated the number of elements.
+  if (V[2] < 0 || V[2] > 15) {
+    PrintFatalError(Rec->getLoc(), "GPU '" + Rec->getValueAsString("Name") +
+                                       "' stepping must be a single hex digit");
+  }
+
+  OS << "amdgpu" << V[0] << '.' << V[1] << hexdigit(V[2], /*LowerCase=*/true);
+}
+
+// Emit the triple subarch name for a major-family subarch, e.g. "9" ->
+// "amdgpu9", "9_4" -> "amdgpu9.4" (the enumerator suffix uses '_', the triple
+// name '.').
+static void emitFamilySubArchTripleName(raw_ostream &OS, StringRef Suffix) {
+  OS << "amdgpu";
+  for (char C : Suffix)
+    OS << static_cast<char>((C == '_') ? '.' : C);
+}
+
 // A canonical GPU or a ProcessorAlias.
 namespace {
 struct GPUEntry {
@@ -402,38 +432,75 @@ static void emitAMDGPUMajorSubArch(raw_ostream &OS, const RecordKeeper &RK) {
         "#endif // GET_AMDGPU_MAJOR_SUBARCH\n\n";
 }
 
-// Emit the canonical GPU name for each AMDGPU subarch.
+/// Emit the canonical GPU name for each AMDGPU subarch ("gfx900"), and it's
+/// corresponding subarch ("amdgpu9.00")
 static void emitAMDGPUSubArchNames(raw_ostream &OS, const RecordKeeper &RK,
                                    StringToOffsetTable &Names) {
-  // (subarch enumerator, name) pairs.
-  std::vector<std::pair<std::string, StringRef>> Pairs;
+  // A row of the generated table. \p Suffix is emitted verbatim after
+  // "Triple::AMDGPUSubArch"; the two name offsets index the shared string pool.
+  struct SubArchEntry {
+    SmallString<16> Suffix;
+    StringRef GPUName; // e.g. "gfx900".
+    unsigned TripleNameOffset;
+  };
+  std::vector<SubArchEntry> Entries;
+
   for (const GPUEntry &E : collectGPUs(RK, /*WantR600=*/false)) {
     if (E.IsAlias || E.Rec->getValueAsBit("IsPseudoTarget"))
       continue;
-    StringRef Name = E.Rec->getValueAsString("Name");
-    std::string SA;
-    raw_string_ostream SO(SA);
-    emitSubArchForName(SO, Name);
-    Pairs.emplace_back(std::move(SA), Name);
+    SubArchEntry Entry;
+    Entry.GPUName = E.Rec->getValueAsString("Name");
+    {
+      raw_svector_ostream SubArchOS(Entry.Suffix);
+      emitSubArchSuffix(SubArchOS, Entry.GPUName);
+    }
+
+    // A "gfxN-generic" target maps to the major-family subarch, so it takes the
+    // family triple name; a concrete GPU derives it from the ISA version.
+    SmallString<16> TripleName;
+    raw_svector_ostream TripleOS(TripleName);
+    if (isGenericTarget(E.Rec))
+      emitFamilySubArchTripleName(TripleOS, Entry.Suffix);
+    else
+      emitConcreteSubArchTripleName(TripleOS, E.Rec);
+    Entry.TripleNameOffset = Names.GetOrAddStringOffset(TripleName);
+
+    Entries.push_back(std::move(Entry));
   }
+
   for (const Record *F : RK.getAllDerivedDefinitionsIfDefined("AMDGPUFamily")) {
     std::vector<const Record *> Members = F->getValueAsListOfDefs("Members");
-    Pairs.emplace_back("Triple::AMDGPUSubArch" +
-                           F->getValueAsString("MajorSubArch").str(),
-                       Members.front()->getValueAsString("Name"));
+    StringRef Major = F->getValueAsString("MajorSubArch");
+    SubArchEntry Entry;
+    Entry.Suffix = Major;
+    Entry.GPUName = Members.front()->getValueAsString("Name");
+
+    SmallString<16> TripleName;
+    raw_svector_ostream TripleOS(TripleName);
+    emitFamilySubArchTripleName(TripleOS, Major);
+    Entry.TripleNameOffset = Names.GetOrAddStringOffset(TripleName);
+
+    Entries.push_back(std::move(Entry));
   }
-  if (Pairs.empty())
+
+  if (Entries.empty())
     return;
 
+  unsigned NoSubArchOffset = Names.GetOrAddStringOffset("amdgpu");
+
   OS << "#ifdef GET_AMDGPU_SUBARCH_NAME\n"
         "#undef GET_AMDGPU_SUBARCH_NAME\n";
+  OS << "static constexpr StringTable::Offset AMDGPUNoSubArchNameOffset = "
+     << NoSubArchOffset << ";\n";
   OS << "struct AMDGPUSubArchNameEntry {\n"
         "  Triple::SubArchType SubArch;\n"
         "  StringTable::Offset NameOffset;\n"
+        "  StringTable::Offset TripleNameOffset;\n"
         "};\n"
         "static constexpr AMDGPUSubArchNameEntry AMDGPUSubArchNames[] = {\n";
-  for (const auto &[SubArch, Name] : Pairs)
-    OS << "  {" << SubArch << ", " << Names.GetOrAddStringOffset(Name)
+  for (const SubArchEntry &E : Entries)
+    OS << "  {Triple::AMDGPUSubArch" << E.Suffix << ", "
+       << Names.GetOrAddStringOffset(E.GPUName) << ", " << E.TripleNameOffset
        << "},\n";
   OS << "};\n"
         "#endif // GET_AMDGPU_SUBARCH_NAME\n\n";


        


More information about the llvm-commits mailing list