[llvm] AMDGPU: Add SubArchSpelling override to the TargetParser TableGen (PR #218500)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 12:52:01 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
Add an optional SubArchSpelling field for targets where the subarch name isn't
trivially derivable from it's gfxNMK name.
Co-Authored-By: Claude <noreply@<!-- -->anthropic.com>
---
Full diff: https://github.com/llvm/llvm-project/pull/218500.diff
5 Files Affected:
- (modified) llvm/include/llvm/TargetParser/AMDGPUTargetParser.h (+4)
- (modified) llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td (+4)
- (modified) llvm/lib/TargetParser/AMDGPUTargetParser.cpp (+6)
- (added) llvm/test/TableGen/AMDGPUTargetDefSubArchSpelling.td (+44)
- (modified) llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp (+64-23)
``````````diff
diff --git a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
index f8e283db55fec..5b4093b2536a5 100644
--- a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
+++ b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
@@ -108,6 +108,10 @@ enum FeatureError : uint32_t {
};
LLVM_ABI StringRef getArchFamilyNameAMDGCN(GPUKind AK);
+
+/// The canonical GPU name for a variant name.
+LLVM_ABI StringRef getBaseArchNameAMDGCN(GPUKind AK);
+
LLVM_ABI Triple::SubArchType getSubArch(GPUKind AK);
LLVM_ABI Triple::SubArchType getMajorSubArch(Triple::SubArchType SubArch);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
index e6ea319017436..7e4b7ee75bdaf 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
@@ -47,6 +47,10 @@ class AMDGPUGPUInfo<list<int> isa = []> {
// A pseudo target ("generic"/"generic-hsa") that represents no
// hardware.
bit IsPseudoTarget = false;
+
+ // An explicit triple subarch spelling (e.g. "12.50"). If unset,
+ // this will be guessed from the device name.
+ string SubArchSpelling;
}
// An R600 processor that is also a canonical TargetParser GPU.
diff --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
index 98affe3e0d7bd..b3cd0a9c26942 100644
--- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
+++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
@@ -41,6 +41,7 @@ struct GPUInfo {
AMDGPUFeatureBitset Features;
IsaVersion Version;
StringTable::Offset FamilyName;
+ StringTable::Offset BaseName; // The canonical device name for a variant.
};
// Per-GPU data for the R600 GPUKinds.
@@ -168,6 +169,11 @@ Triple::SubArchType llvm::AMDGPU::getSubArch(GPUKind AK) {
return Info ? Info->SubArch : Triple::SubArchType::NoSubArch;
}
+StringRef llvm::AMDGPU::getBaseArchNameAMDGCN(GPUKind AK) {
+ const GPUInfo *Info = getAMDGPUInfo(AK);
+ return Info ? AMDGPUNameStrTab[Info->BaseName] : "";
+}
+
AMDGPU::GPUKind
llvm::AMDGPU::getGPUKindFromSubArch(Triple::SubArchType SubArch) {
if (SubArch < Triple::FirstAMDGPUSubArch ||
diff --git a/llvm/test/TableGen/AMDGPUTargetDefSubArchSpelling.td b/llvm/test/TableGen/AMDGPUTargetDefSubArchSpelling.td
new file mode 100644
index 0000000000000..e0c4b82ba0469
--- /dev/null
+++ b/llvm/test/TableGen/AMDGPUTargetDefSubArchSpelling.td
@@ -0,0 +1,44 @@
+// RUN: llvm-tblgen -gen-amdgpu-target-def -I %p/../../include %s 2>&1 | FileCheck %s
+
+// Verify the -gen-amdgpu-target-def backend's handling of SubArchSpelling.
+
+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;
+ string SubArchSpelling;
+}
+
+def GFX888 : ProcessorModel<"gfx888", NoSchedModel, []>, AMDGPUGPUInfo<[8, 8, 8]>;
+
+// A variant CPU: its subarch, triple name, family, and base name come from the
+// spelling / ISA version, not its own name.
+def GFX888_AMAZING : ProcessorModel<"gfx888-amazing", NoSchedModel, []>,
+ AMDGPUGPUInfo<[8, 8, 8]> {
+ let SubArchSpelling = "8.88a";
+}
+
+// The variant contributes a distinct GPUKind.
+// CHECK: GK_GFX888
+// CHECK: GK_GFX888_AMAZING
+
+// The variant is its own major subarch, so it produces no override entry.
+// CHECK: AMDGPUMajorSubArchEntry, 0>{{ }}AMDGPUMajorSubArch
+
+// The name pool holds the variant's name, its gfx8 family, and its base name.
+// CHECK: "gfx888\0"
+// CHECK: "gfx8\0"
+// CHECK: "gfx888-amazing\0"
+// CHECK: "amdgpu8.88a\0"
+
+// The GPU table: the base GPU has no base name (offset 0); the variant uses
+// AMDGPUSubArch8_88A and records "gfx888" as its base name.
+// CHECK: {[[#]], Triple::AMDGPUSubArch888, {{.*}}, {8, 8, 8}, [[FAM:[0-9]+]], 0},
+// CHECK: {[[#]], Triple::AMDGPUSubArch8_88A, {{.*}}, {8, 8, 8}, [[FAM]], [[#]]},
+
+// The subarch-name table maps the variant's own subarch to its triple name.
+// CHECK: {Triple::AMDGPUSubArch8_88A, [[#]], [[#]]},
diff --git a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
index d077178f98526..65d6add20a01a 100644
--- a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
@@ -64,14 +64,34 @@ static void emitSubArchForName(raw_ostream &OS, StringRef Name) {
emitSubArchSuffix(OS, Name);
}
+// The explicit subarch spelling for a GPU whose subarch is not derivable from
+// its name, or empty. Optional so test stubs may omit it.
+static std::optional<StringRef> getSubArchSpelling(const Record *Rec) {
+ return Rec->getValueAsOptionalString("SubArchSpelling");
+}
+
+// Emit a subarch enumerator suffix for a spelling, converting '.' to '_' and
+// upcasing, e.g. "4.67q" -> "4_67Q".
+static void emitSpellingSuffix(raw_ostream &OS, StringRef Spelling) {
+ for (char C : Spelling)
+ OS << static_cast<char>((C == '.') ? '_' : toUpper(C));
+}
+
// Derive the Triple::SubArchType for a canonical GPU record. A pseudo target
-// represents no hardware and maps to Triple::NoSubArch; otherwise the subarch
-// is derived from the name.
+// maps to Triple::NoSubArch; an explicit SubArchSpelling maps to that (e.g.
+// "4.67q" -> AMDGPUSubArch4_67Q); otherwise it is derived from the name.
static void emitSubArch(raw_ostream &OS, const Record *Rec) {
if (Rec->getValueAsBit("IsPseudoTarget")) {
OS << "Triple::NoSubArch";
return;
}
+
+ if (std::optional<StringRef> Spelling = getSubArchSpelling(Rec)) {
+ OS << "Triple::AMDGPUSubArch";
+ emitSpellingSuffix(OS, *Spelling);
+ return;
+ }
+
emitSubArchForName(OS, Rec->getValueAsString("Name"));
}
@@ -82,17 +102,21 @@ static bool isGenericTarget(const Record *Rec) {
return !Rec->getValueAsListOfDefs("CoveredGPUs").empty();
}
-// The gfx family for a canonical GPU record: the "-generic" family prefix (e.g.
-// "gfx9-4-generic" -> "gfx9"), or the name with its last two chars dropped for
-// a concrete GPU (e.g. "gfx90a" -> "gfx9", "gfx1030" -> "gfx10"). Empty for a
-// pseudo target.
-static StringRef getArchFamily(const Record *Rec) {
+// Emit the gfx family for a canonical GPU record: "gfx" + the ISA major version
+// (e.g. "gfx90a"/[9,0,10] -> "gfx9", "gfx1250"/[12,5,0] -> "gfx12").
+// Nothing for a pseudo target.
+static void emitArchFamily(raw_ostream &OS, const Record *Rec) {
if (Rec->getValueAsBit("IsPseudoTarget"))
- return "";
- StringRef Name = Rec->getValueAsString("Name");
- if (isGenericTarget(Rec))
- return Name.take_front(Name.find('-'));
- return Name.drop_back(2);
+ return;
+ OS << "gfx" << Rec->getValueAsListOfInts("IsaVersion")[0];
+}
+
+// Emit the canonical GPU name for a variant (empty for a non-variant GPU).
+static void emitBaseName(raw_ostream &OS, const Record *Rec) {
+ if (!getSubArchSpelling(Rec))
+ return;
+ std::vector<int64_t> V = Rec->getValueAsListOfInts("IsaVersion");
+ OS << "gfx" << V[0] << V[1] << hexdigit(V[2], /*LowerCase=*/true);
}
// Emit the ISA version tuple as "major, minor, stepping" wrapped in \p Open and
@@ -534,7 +558,14 @@ emitAMDGPUTable(raw_ostream &OS, const RecordKeeper &RK,
emitFeatureBitset(OS, R, FeatureIdx);
OS << ", ";
emitIsaVersion(OS, R, '{', '}');
- OS << ", " << Names.GetOrAddStringOffset(getArchFamily(R)) << "},\n";
+ SmallString<16> Family;
+ raw_svector_ostream FamilyOS(Family);
+ emitArchFamily(FamilyOS, R);
+ OS << ", " << Names.GetOrAddStringOffset(Family) << ", ";
+ SmallString<16> BaseName;
+ raw_svector_ostream BaseNameOS(BaseName);
+ emitBaseName(BaseNameOS, R);
+ OS << Names.GetOrAddStringOffset(BaseName) << "},\n";
}
OS << "};\n"
"#endif // GET_AMDGPU_GPU_TABLE\n\n";
@@ -612,19 +643,29 @@ static void emitAMDGPUSubArchNames(raw_ostream &OS, const RecordKeeper &RK,
continue;
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);
+
+ // An explicit subarch spelling supplies the enumerator suffix and triple
+ // name, rather than the name/ISA version.
+ if (std::optional<StringRef> Spelling = getSubArchSpelling(E.Rec)) {
+ raw_svector_ostream SubArchOS(Entry.Suffix);
+ emitSpellingSuffix(SubArchOS, *Spelling);
+ TripleOS << "amdgpu" << *Spelling;
+ } else {
+ {
+ 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.
+ if (isGenericTarget(E.Rec))
+ emitFamilySubArchTripleName(TripleOS, Entry.Suffix);
+ else
+ emitConcreteSubArchTripleName(TripleOS, E.Rec);
+ }
Entry.TripleNameOffset = Names.GetOrAddStringOffset(TripleName);
Entries.push_back(std::move(Entry));
``````````
</details>
https://github.com/llvm/llvm-project/pull/218500
More information about the llvm-commits
mailing list