[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