[clang] [llvm] AMDGPU: Split R600 feature bitmask into separate enum from amdgcn (PR #212484)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 28 06:13:52 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

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

---
Full diff: https://github.com/llvm/llvm-project/pull/212484.diff


10 Files Affected:

- (modified) clang/lib/Basic/TargetID.cpp (+4-4) 
- (modified) clang/lib/Basic/Targets/AMDGPU.h (+5-3) 
- (modified) clang/lib/Driver/ToolChains/AMDGPU.cpp (+4-4) 
- (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+3-5) 
- (modified) llvm/include/llvm/TargetParser/AMDGPUTargetParser.h (+18-12) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td (+1-1) 
- (modified) llvm/lib/Target/AMDGPU/R600Processors.td (+2-2) 
- (modified) llvm/lib/TargetParser/AMDGPUTargetParser.cpp (+2-2) 
- (modified) llvm/unittests/TargetParser/TargetParserTest.cpp (+17-17) 
- (modified) llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp (+6-4) 


``````````diff
diff --git a/clang/lib/Basic/TargetID.cpp b/clang/lib/Basic/TargetID.cpp
index 67f429607ef27..29d5d4a5d2996 100644
--- a/clang/lib/Basic/TargetID.cpp
+++ b/clang/lib/Basic/TargetID.cpp
@@ -24,12 +24,12 @@ getAllPossibleAMDGPUTargetIDFeatures(const llvm::Triple &T,
                                      llvm::StringRef Proc) {
   // Entries in returned vector should be in alphabetical order.
   llvm::SmallVector<llvm::StringRef, 4> Ret;
-  auto ProcKind = T.isAMDGCN() ? llvm::AMDGPU::parseArchAMDGCN(Proc)
-                               : llvm::AMDGPU::parseArchR600(Proc);
+  if (!T.isAMDGCN())
+    return Ret;
+  llvm::AMDGPU::GPUKind ProcKind = llvm::AMDGPU::parseArchAMDGCN(Proc);
   if (ProcKind == llvm::AMDGPU::GK_NONE)
     return Ret;
-  auto Features = T.isAMDGCN() ? llvm::AMDGPU::getArchAttrAMDGCN(ProcKind)
-                               : llvm::AMDGPU::getArchAttrR600(ProcKind);
+  unsigned Features = llvm::AMDGPU::getArchAttrAMDGCN(ProcKind);
   if (Features & llvm::AMDGPU::FEATURE_SRAMECC)
     Ret.push_back("sramecc");
   // Only allow xnack in target ID if the processor supports on/off modes.
diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index 060df0b9b1b72..85cc1cd21619c 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -54,7 +54,8 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
 
   /// Has fast fma f32
   bool hasFastFMAF() const {
-    return !!(GPUFeatures & llvm::AMDGPU::FEATURE_FAST_FMA_F32);
+    return getTriple().isAMDGCN() &&
+           !!(GPUFeatures & llvm::AMDGPU::FEATURE_FAST_FMA_F32);
   }
 
   /// Has fast fma f64
@@ -62,11 +63,12 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
 
   bool hasFMAF() const {
     return getTriple().isAMDGCN() ||
-           !!(GPUFeatures & llvm::AMDGPU::FEATURE_FMA);
+           !!(GPUFeatures & llvm::AMDGPU::R600_FEATURE_FMA);
   }
 
   bool hasFullRateDenormalsF32() const {
-    return !!(GPUFeatures & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32);
+    return getTriple().isAMDGCN() &&
+           !!(GPUFeatures & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32);
   }
 
   bool hasLDEXPF() const { return getTriple().isAMDGCN(); }
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 5893f6f6b2915..67981cd55d5e8 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -1289,11 +1289,11 @@ LTOKind AMDGPUToolChain::getLTOMode(const ArgList &Args,
 
 static bool isXnackAvailable(const llvm::Triple &TT, llvm::StringRef TargetID) {
   // Arch-specific check - only report as supported if arch has xnack+
+  if (!TT.isAMDGCN())
+    return false;
   llvm::StringRef Processor = getProcessorFromTargetID(TT, TargetID);
-  auto ProcKind = TT.isAMDGCN() ? llvm::AMDGPU::parseArchAMDGCN(Processor)
-                                : llvm::AMDGPU::parseArchR600(Processor);
-  auto Features = TT.isAMDGCN() ? llvm::AMDGPU::getArchAttrAMDGCN(ProcKind)
-                                : llvm::AMDGPU::getArchAttrR600(ProcKind);
+  llvm::AMDGPU::GPUKind ProcKind = llvm::AMDGPU::parseArchAMDGCN(Processor);
+  unsigned Features = llvm::AMDGPU::getArchAttrAMDGCN(ProcKind);
 
   // If processor has xnack but doesn't support on/off modes, xnack is always on
   bool XnackAlwaysOn = (Features & llvm::AMDGPU::FEATURE_XNACK) &&
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 08c06951cf220..579e21d9c882f 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -379,12 +379,10 @@ static bool shouldIgnoreUnsupportedTargetFeature(const Arg &TargetFeatureArg,
                                                  llvm::Triple T,
                                                  StringRef Processor) {
   // Warn no-cumode for AMDGCN processors not supporing WGP mode.
-  if (!T.isAMDGPU())
+  if (!T.isAMDGCN())
     return false;
-  auto GPUKind = T.isAMDGCN() ? llvm::AMDGPU::parseArchAMDGCN(Processor)
-                              : llvm::AMDGPU::parseArchR600(Processor);
-  auto GPUFeatures = T.isAMDGCN() ? llvm::AMDGPU::getArchAttrAMDGCN(GPUKind)
-                                  : llvm::AMDGPU::getArchAttrR600(GPUKind);
+  llvm::AMDGPU::GPUKind GPUKind = llvm::AMDGPU::parseArchAMDGCN(Processor);
+  unsigned GPUFeatures = llvm::AMDGPU::getArchAttrAMDGCN(GPUKind);
   if (GPUFeatures & llvm::AMDGPU::FEATURE_WGP)
     return false;
   return TargetFeatureArg.getOption().matches(options::OPT_mno_cumode);
diff --git a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
index bb82252803c59..28d87be2eb648 100644
--- a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
+++ b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
@@ -58,33 +58,39 @@ struct IsaVersion {
 
 // This isn't comprehensive for now, just things that are needed from the
 // frontend driver.
+enum R600FeatureKind : uint32_t {
+  R600_FEATURE_NONE = 0,
+
+  // Has fma instructions.
+  R600_FEATURE_FMA = 1 << 0,
+};
+
+// GFX6+ features. This isn't comprehensive for now, just things that are needed
+// from the frontend driver.
 enum ArchFeatureKind : uint32_t {
   FEATURE_NONE = 0,
 
-  // This feature only exists for r600, and is implied true for amdgcn.
-  FEATURE_FMA = 1 << 0,
-
   // Common features.
-  FEATURE_FAST_FMA_F32 = 1 << 1,
-  FEATURE_FAST_DENORMAL_F32 = 1 << 2,
+  FEATURE_FAST_FMA_F32 = 1 << 0,
+  FEATURE_FAST_DENORMAL_F32 = 1 << 1,
 
   // Wavefront 32 is available.
-  FEATURE_WAVE32 = 1 << 3,
+  FEATURE_WAVE32 = 1 << 2,
 
   // Xnack is available.
-  FEATURE_XNACK = 1 << 4,
+  FEATURE_XNACK = 1 << 3,
 
   // Sram-ecc is available.
-  FEATURE_SRAMECC = 1 << 5,
+  FEATURE_SRAMECC = 1 << 4,
 
   // WGP mode is supported.
-  FEATURE_WGP = 1 << 6,
+  FEATURE_WGP = 1 << 5,
 
   // Xnack on/off modes are supported.
-  FEATURE_XNACK_ON_OFF_MODES = 1 << 7,
+  FEATURE_XNACK_ON_OFF_MODES = 1 << 6,
 
   // VI SGPR initialization bug requiring a fixed SGPR allocation size.
-  FEATURE_SGPR_INIT_BUG = 1 << 8
+  FEATURE_SGPR_INIT_BUG = 1 << 7
 };
 
 enum FeatureError : uint32_t {
@@ -135,7 +141,7 @@ LLVM_ABI GPUKind parseArchR600(StringRef CPU);
 LLVM_ABI GPUKind getGPUKindFromSubArch(Triple::SubArchType SubArch);
 LLVM_ABI unsigned getArchAttrAMDGCN(GPUKind AK);
 LLVM_ABI unsigned getArchAttrAMDGCN(Triple::SubArchType SubArch);
-LLVM_ABI unsigned getArchAttrR600(GPUKind AK);
+LLVM_ABI R600FeatureKind getArchAttrR600(GPUKind AK);
 
 /// Append the valid AMDGCN GPU names to \p Values. If \p SubArch is not
 /// NoSubArch, only GPUs compatible with that subarch (see isCPUValidForSubArch)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
index ffa3869e7151e..28385babdeba7 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
@@ -18,7 +18,7 @@ class AMDGPUArchFeature<string spelling> {
 }
 
 // R600-only.
-def FEATURE_FMA : AMDGPUArchFeature<"FEATURE_FMA">;
+def R600_FEATURE_FMA : AMDGPUArchFeature<"R600_FEATURE_FMA">;
 
 // Marks a Processor/ProcessorModel record as a canonical TargetParser GPU.
 class AMDGPUGPUInfo {
diff --git a/llvm/lib/Target/AMDGPU/R600Processors.td b/llvm/lib/Target/AMDGPU/R600Processors.td
index c893f4a11c952..7a5847a493d6f 100644
--- a/llvm/lib/Target/AMDGPU/R600Processors.td
+++ b/llvm/lib/Target/AMDGPU/R600Processors.td
@@ -127,7 +127,7 @@ def : ProcessorAlias<"palm", "cedar">;
 
 def : R600ProcessorModel<"cypress", R600_VLIW5_Itin,
   [FeatureEvergreen, FeatureWavefrontSize64, FeatureVertexCache, FeatureFMA]> {
-  let ArchFeatures = [FEATURE_FMA];
+  let ArchFeatures = [R600_FEATURE_FMA];
 }
 
 def : ProcessorAlias<"hemlock", "cypress">;
@@ -163,7 +163,7 @@ def : ProcessorAlias<"aruba", "cayman">;
 
 def : R600ProcessorModel<"cayman", R600_VLIW4_Itin,
   [FeatureNorthernIslands, FeatureCaymanISA, FeatureFMA]> {
-  let ArchFeatures = [FEATURE_FMA];
+  let ArchFeatures = [R600_FEATURE_FMA];
 }
 
 def : R600ProcessorModel<"turks", R600_VLIW5_Itin,
diff --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
index dbc3b59a0861b..bfa771b6625dc 100644
--- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
+++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
@@ -291,14 +291,14 @@ unsigned AMDGPU::getArchAttrAMDGCN(Triple::SubArchType SubArch) {
   }
 }
 
-unsigned AMDGPU::getArchAttrR600(GPUKind AK) {
+R600FeatureKind AMDGPU::getArchAttrR600(GPUKind AK) {
   switch (AK) {
 #define R600_GPU(NAME, ENUM, FEATURES)                                         \
   case ENUM:                                                                   \
     return FEATURES;
 #include "llvm/TargetParser/R600TargetParserDef.inc"
   default:
-    return FEATURE_NONE;
+    return R600_FEATURE_NONE;
   }
 }
 
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 54325fcc20141..827c5aafac857 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -2667,25 +2667,25 @@ TEST(TargetParserTest, testAMDGPUparseArchR600) {
   struct CanonicalGPU {
     StringRef Name;
     AMDGPU::GPUKind Kind;
-    unsigned Features;
+    AMDGPU::R600FeatureKind Features;
   };
   static const CanonicalGPU Canonicals[] = {
-      {"r600", AMDGPU::GK_R600, AMDGPU::FEATURE_NONE},
-      {"r630", AMDGPU::GK_R630, AMDGPU::FEATURE_NONE},
-      {"rs880", AMDGPU::GK_RS880, AMDGPU::FEATURE_NONE},
-      {"rv670", AMDGPU::GK_RV670, AMDGPU::FEATURE_NONE},
-      {"rv710", AMDGPU::GK_RV710, AMDGPU::FEATURE_NONE},
-      {"rv730", AMDGPU::GK_RV730, AMDGPU::FEATURE_NONE},
-      {"rv770", AMDGPU::GK_RV770, AMDGPU::FEATURE_NONE},
-      {"cedar", AMDGPU::GK_CEDAR, AMDGPU::FEATURE_NONE},
-      {"cypress", AMDGPU::GK_CYPRESS, AMDGPU::FEATURE_FMA},
-      {"juniper", AMDGPU::GK_JUNIPER, AMDGPU::FEATURE_NONE},
-      {"redwood", AMDGPU::GK_REDWOOD, AMDGPU::FEATURE_NONE},
-      {"sumo", AMDGPU::GK_SUMO, AMDGPU::FEATURE_NONE},
-      {"barts", AMDGPU::GK_BARTS, AMDGPU::FEATURE_NONE},
-      {"caicos", AMDGPU::GK_CAICOS, AMDGPU::FEATURE_NONE},
-      {"cayman", AMDGPU::GK_CAYMAN, AMDGPU::FEATURE_FMA},
-      {"turks", AMDGPU::GK_TURKS, AMDGPU::FEATURE_NONE},
+      {"r600", AMDGPU::GK_R600, AMDGPU::R600_FEATURE_NONE},
+      {"r630", AMDGPU::GK_R630, AMDGPU::R600_FEATURE_NONE},
+      {"rs880", AMDGPU::GK_RS880, AMDGPU::R600_FEATURE_NONE},
+      {"rv670", AMDGPU::GK_RV670, AMDGPU::R600_FEATURE_NONE},
+      {"rv710", AMDGPU::GK_RV710, AMDGPU::R600_FEATURE_NONE},
+      {"rv730", AMDGPU::GK_RV730, AMDGPU::R600_FEATURE_NONE},
+      {"rv770", AMDGPU::GK_RV770, AMDGPU::R600_FEATURE_NONE},
+      {"cedar", AMDGPU::GK_CEDAR, AMDGPU::R600_FEATURE_NONE},
+      {"cypress", AMDGPU::GK_CYPRESS, AMDGPU::R600_FEATURE_FMA},
+      {"juniper", AMDGPU::GK_JUNIPER, AMDGPU::R600_FEATURE_NONE},
+      {"redwood", AMDGPU::GK_REDWOOD, AMDGPU::R600_FEATURE_NONE},
+      {"sumo", AMDGPU::GK_SUMO, AMDGPU::R600_FEATURE_NONE},
+      {"barts", AMDGPU::GK_BARTS, AMDGPU::R600_FEATURE_NONE},
+      {"caicos", AMDGPU::GK_CAICOS, AMDGPU::R600_FEATURE_NONE},
+      {"cayman", AMDGPU::GK_CAYMAN, AMDGPU::R600_FEATURE_FMA},
+      {"turks", AMDGPU::GK_TURKS, AMDGPU::R600_FEATURE_NONE},
   };
   for (const CanonicalGPU &G : Canonicals) {
     EXPECT_EQ(AMDGPU::parseArchR600(G.Name), G.Kind) << G.Name;
diff --git a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
index e8a013227411a..d982fb45da9cc 100644
--- a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
@@ -37,8 +37,10 @@ struct GPUEntry {
 };
 } // namespace
 
-// Emit the ArchFeature spellings joined with '|', or FEATURE_NONE when empty.
-static void emitFeatureExpr(raw_ostream &OS, const Record *Rec) {
+// Emit the ArchFeature spellings joined with '|', or \p NoneSpelling when
+// empty.
+static void emitFeatureExpr(raw_ostream &OS, const Record *Rec,
+                            StringRef NoneSpelling) {
   ListSeparator LS("|");
   bool Any = false;
   for (const Record *F : Rec->getValueAsListOfDefs("ArchFeatures")) {
@@ -47,7 +49,7 @@ static void emitFeatureExpr(raw_ostream &OS, const Record *Rec) {
   }
 
   if (!Any)
-    OS << "FEATURE_NONE";
+    OS << NoneSpelling;
 }
 
 // Collect canonical GPUs and their aliases, in TableGen definition order.
@@ -116,7 +118,7 @@ static void emitR600(raw_ostream &OS, const RecordKeeper &RK) {
       OS << "R600_GPU(\"" << Name << "\", ";
       emitGPUKindEnum(OS, Name);
       OS << ", ";
-      emitFeatureExpr(OS, E.Rec);
+      emitFeatureExpr(OS, E.Rec, "R600_FEATURE_NONE");
       OS << ")\n";
     }
   }

``````````

</details>


https://github.com/llvm/llvm-project/pull/212484


More information about the cfe-commits mailing list