[llvm] [AMDGPU] Move EU and Wave Queries into TargetParser (PR #215681)

Chinmay Deshpande via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 14:56:42 PDT 2026


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

This also updates the APIs to use the terms `halfSIMD` and `fullSIMD`. General terminology is up for a debate.

Supersedes: https://github.com/llvm/llvm-project/pull/211312

>From 28f47d05ea2137ef1277b4213d6ca2e0343df864 Mon Sep 17 00:00:00 2001
From: Chinmay Deshpande <chdeshpa at amd.com>
Date: Tue, 11 Aug 2026 17:33:44 -0400
Subject: [PATCH] [AMDGPU] Move EU and Wave Queries into TargetParser

Change-Id: I32b24e6fd7c676d7ca99bdcaa7f9baf351ff4f7f
---
 .../llvm/TargetParser/AMDGPUTargetParser.h    | 13 ++++
 llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp   |  2 +-
 llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp    |  9 +--
 llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h      | 10 +--
 llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td  | 11 +++
 llvm/lib/Target/AMDGPU/GCNProcessors.td       | 71 +++++++++++++++++++
 llvm/lib/Target/AMDGPU/GCNSubtarget.cpp       |  6 +-
 llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp   |  3 +-
 .../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp    | 50 ++++---------
 llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h |  8 ---
 llvm/lib/TargetParser/AMDGPUTargetParser.cpp  | 24 +++++++
 llvm/test/TableGen/AMDGPUTargetDefErrors.td   | 18 +++++
 .../llvm-calc-occupancy.cpp                   | 12 ++--
 .../TargetParser/TargetParserTest.cpp         | 37 ++++++++++
 .../TableGen/Basic/AMDGPUTargetDefEmitter.cpp |  5 +-
 15 files changed, 213 insertions(+), 66 deletions(-)

diff --git a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
index f8e283db55fec..e610fbe020803 100644
--- a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
+++ b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h
@@ -194,6 +194,19 @@ LLVM_ABI unsigned getAddressableNumSGPRs(Triple::SubArchType SubArch);
 LLVM_ABI unsigned getSGPRAllocGranule(GPUKind AK);
 LLVM_ABI unsigned getSGPRAllocGranule(Triple::SubArchType SubArch);
 
+/// \returns Number of SIMDs (execution units) a work-group's waves run on. In
+/// full-SIMD mode that is every SIMD of the functional block; otherwise the
+/// work-group is confined to half of them. Hardware that cannot split the
+/// block reports the same count either way.
+LLVM_ABI unsigned getWorkGroupSIMDs(GPUKind AK, bool FullSIMDMode);
+LLVM_ABI unsigned getWorkGroupSIMDs(Triple::SubArchType SubArch,
+                                    bool FullSIMDMode);
+
+/// \returns Maximum number of waves per execution unit without any kind of
+/// limitation.
+LLVM_ABI unsigned getMaxWavesPerEU(GPUKind AK);
+LLVM_ABI unsigned getMaxWavesPerEU(Triple::SubArchType SubArch);
+
 /// Fills Features map with default values for given target GPU.
 /// \p Features contains overriding target features and this function returns
 /// default target features with entries overridden by \p Features.
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index 3d337a466a75e..4a6fcb70c62e4 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -419,7 +419,7 @@ const AMDGPUMCExpr *createOccupancy(unsigned InitOcc, const MCExpr *NumSGPRs,
                                     const MCExpr *NumVGPRs,
                                     unsigned DynamicVGPRBlockSize,
                                     const GCNSubtarget &STM, MCContext &Ctx) {
-  unsigned MaxWaves = IsaInfo::getMaxWavesPerEU(STM);
+  unsigned MaxWaves = STM.getMaxWavesPerEU();
   unsigned Granule = IsaInfo::getVGPRAllocGranule(STM, DynamicVGPRBlockSize);
   unsigned TargetTotalNumVGPRs = IsaInfo::getTotalNumVGPRs(STM);
 
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp b/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp
index 87515d22ed422..97ca03955acda 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp
@@ -44,7 +44,7 @@ AMDGPUSubtarget::getMaxLocalMemSizeWithWaveCount(unsigned NWaves,
       std::max(1u, (WorkGroupSize + WaveSize - 1) / WaveSize);
 
   const unsigned WorkGroupsPerCU =
-      std::max(1u, (NWaves * getEUsPerCU()) / WavesPerWorkgroup);
+      std::max(1u, (NWaves * getWorkGroupSIMDs()) / WavesPerWorkgroup);
 
   return getLocalMemorySize() / WorkGroupsPerCU;
 }
@@ -88,7 +88,7 @@ std::pair<unsigned, unsigned> AMDGPUSubtarget::getOccupancyWithWorkGroupSizes(
   if (MinWavesPerCU >= MaxWavesPerCU) {
     std::swap(MinWavesPerCU, MaxWavesPerCU);
   } else {
-    const unsigned WaveSlotsPerCU = WavesPerEU * getEUsPerCU();
+    const unsigned WaveSlotsPerCU = WavesPerEU * getWorkGroupSIMDs();
 
     // Look for a potential smaller group size than the maximum which decreases
     // the concurrent number of waves on the CU for the same number of
@@ -128,8 +128,9 @@ std::pair<unsigned, unsigned> AMDGPUSubtarget::getOccupancyWithWorkGroupSizes(
 
   // Return the minimum/maximum number of waves on any EU, assuming that all
   // wavefronts are spread across all EUs as evenly as possible.
-  return {std::clamp(MinWavesPerCU / getEUsPerCU(), 1U, WavesPerEU),
-          std::clamp(divideCeil(MaxWavesPerCU, getEUsPerCU()), 1U, WavesPerEU)};
+  return {std::clamp(MinWavesPerCU / getWorkGroupSIMDs(), 1U, WavesPerEU),
+          std::clamp(divideCeil(MaxWavesPerCU, getWorkGroupSIMDs()), 1U,
+                     WavesPerEU)};
 }
 
 std::pair<unsigned, unsigned> AMDGPUSubtarget::getOccupancyWithWorkGroupSizes(
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h b/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h
index 71a8f064ffa11..e135531f2b935 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUSubtarget.h
@@ -54,7 +54,7 @@ class AMDGPUSubtarget {
   bool HasSMulHi = false;
   bool HasFminFmaxLegacy = true;
 
-  unsigned EUsPerCU = 4;
+  unsigned WorkGroupSIMDs = 4;
   unsigned MaxWavesPerEU = 10;
   unsigned LocalMemorySize = 0;
   unsigned AddressableLocalMemorySize = 0;
@@ -237,10 +237,10 @@ class AMDGPUSubtarget {
     return AddressableLocalMemorySize;
   }
 
-  /// Number of SIMDs/EUs (execution units) per "CU" ("compute unit"), where the
-  /// "CU" is the unit onto which workgroups are mapped. This takes WGP mode vs.
-  /// CU mode into account.
-  unsigned getEUsPerCU() const { return EUsPerCU; }
+  /// Number of SIMDs (execution units) a work-group's waves run on: all four
+  /// of the block's SIMDs in full-SIMD mode, two when the work-group is
+  /// confined to half of them.
+  unsigned getWorkGroupSIMDs() const { return WorkGroupSIMDs; }
 
   Align getAlignmentForImplicitArgPtr() const {
     return isAmdHsaOS() ? Align(8) : Align(4);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
index e6ea319017436..8454ee392c5bc 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td
@@ -47,6 +47,17 @@ class AMDGPUGPUInfo<list<int> isa = []> {
   // A pseudo target ("generic"/"generic-hsa") that represents no
   // hardware.
   bit IsPseudoTarget = false;
+
+  // Maximum number of waves an execution unit can hold, ignoring any resource
+  // limit.
+  int MaxWavesPerEU = 10;
+
+  // Number of execution units (SIMDs) whose waves a workgroup must share: the
+  // full set of SIMDs of the functional block, and the count when a workgroup
+  // is restricted to half of them. Hardware that cannot split the block has
+  // the same count for both.
+  int FullSIMDs = 4;
+  int HalfSIMDs = 4;
 }
 
 // An R600 processor that is also a canonical TargetParser GPU.
diff --git a/llvm/lib/Target/AMDGPU/GCNProcessors.td b/llvm/lib/Target/AMDGPU/GCNProcessors.td
index 47dc1f182c7b4..bc93a957039b6 100644
--- a/llvm/lib/Target/AMDGPU/GCNProcessors.td
+++ b/llvm/lib/Target/AMDGPU/GCNProcessors.td
@@ -171,6 +171,7 @@ def GFX909 : AMDGPUProcessorModel<"gfx909", SIQuarterSpeedModel,
 def GFX90A : AMDGPUProcessorModel<"gfx90a", SIDPFullSpeedModel,
   FeatureISAVersion9_0_A.Features, [9, 0, 0xa]> {
   let ArchFeatures = ArchFeaturesW64XnackSramEcc;
+  let MaxWavesPerEU = 8;
 }
 
 def GFX90C : AMDGPUProcessorModel<"gfx90c", SIQuarterSpeedModel,
@@ -181,11 +182,13 @@ def GFX90C : AMDGPUProcessorModel<"gfx90c", SIQuarterSpeedModel,
 def GFX942 : AMDGPUProcessorModel<"gfx942", SIDPGFX942FullSpeedModel,
   FeatureISAVersion9_4_2.Features, [9, 4, 2]> {
   let ArchFeatures = ArchFeaturesW64XnackSramEcc;
+  let MaxWavesPerEU = 8;
 }
 
 def GFX950 : AMDGPUProcessorModel<"gfx950", SIDPGFX950FullSpeedModel,
   FeatureISAVersion9_5_0.Features, [9, 5, 0]> {
   let ArchFeatures = ArchFeaturesW64XnackSramEcc;
+  let MaxWavesPerEU = 8;
 }
 
 def GFX9_GENERIC : AMDGPUProcessorModel<"gfx9-generic", SIQuarterSpeedModel,
@@ -198,6 +201,7 @@ def GFX9_4_GENERIC : AMDGPUProcessorModel<"gfx9-4-generic", SIDPGFX942FullSpeedM
   FeatureISAVersion9_4_Generic.Features, [9, 4, 0]> {
   let ArchFeatures = ArchFeaturesW64XnackSramEcc;
   let CoveredGPUs = [GFX942, GFX950];
+  let MaxWavesPerEU = 8;
 }
 
 //===----------------------------------------------------------------------===//
@@ -207,68 +211,94 @@ def GFX9_4_GENERIC : AMDGPUProcessorModel<"gfx9-4-generic", SIDPGFX942FullSpeedM
 def GFX1010 : AMDGPUProcessorModel<"gfx1010", GFX10SpeedModel,
   FeatureISAVersion10_1_0.Features, [10, 1, 0]> {
   let ArchFeatures = ArchFeaturesW32XnackWgp;
+  let MaxWavesPerEU = 20;
+  let HalfSIMDs = 2;
 }
 
 def GFX1011 : AMDGPUProcessorModel<"gfx1011", GFX10SpeedModel,
   FeatureISAVersion10_1_1.Features, [10, 1, 1]> {
   let ArchFeatures = ArchFeaturesW32XnackWgp;
+  let MaxWavesPerEU = 20;
+  let HalfSIMDs = 2;
 }
 
 def GFX1012 : AMDGPUProcessorModel<"gfx1012", GFX10SpeedModel,
   FeatureISAVersion10_1_2.Features, [10, 1, 2]> {
   let ArchFeatures = ArchFeaturesW32XnackWgp;
+  let MaxWavesPerEU = 20;
+  let HalfSIMDs = 2;
 }
 
 def GFX1013 : AMDGPUProcessorModel<"gfx1013", GFX10SpeedModel,
   FeatureISAVersion10_1_3.Features, [10, 1, 3]> {
   let ArchFeatures = ArchFeaturesW32XnackWgp;
+  let MaxWavesPerEU = 20;
+  let HalfSIMDs = 2;
 }
 
 def GFX1030 : AMDGPUProcessorModel<"gfx1030", GFX10SpeedModel,
   FeatureISAVersion10_3_0.Features, [10, 3, 0]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1031 : AMDGPUProcessorModel<"gfx1031", GFX10SpeedModel,
   FeatureISAVersion10_3_0.Features, [10, 3, 1]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1032 : AMDGPUProcessorModel<"gfx1032", GFX10SpeedModel,
   FeatureISAVersion10_3_0.Features, [10, 3, 2]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1033 : AMDGPUProcessorModel<"gfx1033", GFX10SpeedModel,
   FeatureISAVersion10_3_0.Features, [10, 3, 3]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1034 : AMDGPUProcessorModel<"gfx1034", GFX10SpeedModel,
   FeatureISAVersion10_3_0.Features, [10, 3, 4]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1035 : AMDGPUProcessorModel<"gfx1035", GFX10SpeedModel,
   FeatureISAVersion10_3_0.Features, [10, 3, 5]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1036 : AMDGPUProcessorModel<"gfx1036", GFX10SpeedModel,
   FeatureISAVersion10_3_0.Features, [10, 3, 6]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX10_1_GENERIC : AMDGPUProcessorModel<"gfx10-1-generic", GFX10SpeedModel,
   FeatureISAVersion10_1_Generic.Features, [10, 1, 0]> {
   let ArchFeatures = ArchFeaturesW32XnackWgp;
   let CoveredGPUs = [GFX1010, GFX1011, GFX1012, GFX1013];
+  let MaxWavesPerEU = 20;
+  let HalfSIMDs = 2;
 }
 
 def GFX10_3_GENERIC : AMDGPUProcessorModel<"gfx10-3-generic", GFX10SpeedModel,
   FeatureISAVersion10_3_Generic.Features, [10, 3, 0]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
   let CoveredGPUs = [GFX1030, GFX1031, GFX1032, GFX1033, GFX1034, GFX1035, GFX1036];
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 //===----------------------------------------------------------------------===//
@@ -278,61 +308,85 @@ def GFX10_3_GENERIC : AMDGPUProcessorModel<"gfx10-3-generic", GFX10SpeedModel,
 def GFX1100 : AMDGPUProcessorModel<"gfx1100", GFX11SpeedModel,
   FeatureISAVersion11_0_0.Features, [11, 0, 0]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1101 : AMDGPUProcessorModel<"gfx1101", GFX11SpeedModel,
   FeatureISAVersion11_0_1.Features, [11, 0, 1]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1102 : AMDGPUProcessorModel<"gfx1102", GFX11SpeedModel,
   FeatureISAVersion11_0_2.Features, [11, 0, 2]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1103 : AMDGPUProcessorModel<"gfx1103", GFX11SpeedModel,
   FeatureISAVersion11_0_3.Features, [11, 0, 3]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1150 : AMDGPUProcessorModel<"gfx1150", GFX11SpeedModel,
   FeatureISAVersion11_5_0.Features, [11, 5, 0]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1151 : AMDGPUProcessorModel<"gfx1151", GFX11SpeedModel,
   FeatureISAVersion11_5_1.Features, [11, 5, 1]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1152 : AMDGPUProcessorModel<"gfx1152", GFX11SpeedModel,
   FeatureISAVersion11_5_2.Features, [11, 5, 2]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1153 : AMDGPUProcessorModel<"gfx1153", GFX11SpeedModel,
   FeatureISAVersion11_5_Common.Features, [11, 5, 3]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1154 : AMDGPUProcessorModel<"gfx1154", GFX11SpeedModel,
   FeatureISAVersion11_5_Common.Features, [11, 5, 4]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1170 : AMDGPUProcessorModel<"gfx1170", GFX11SpeedModel,
   FeatureISAVersion11_7_Common.Features, [11, 7, 0]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1171 : AMDGPUProcessorModel<"gfx1171", GFX11SpeedModel,
   FeatureISAVersion11_7_Common.Features, [11, 7, 1]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1172 : AMDGPUProcessorModel<"gfx1172", GFX11SpeedModel,
   FeatureISAVersion11_7_Common.Features, [11, 7, 2]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX11_GENERIC : AMDGPUProcessorModel<"gfx11-generic", GFX11SpeedModel,
@@ -340,12 +394,16 @@ def GFX11_GENERIC : AMDGPUProcessorModel<"gfx11-generic", GFX11SpeedModel,
   let ArchFeatures = ArchFeaturesW32Wgp;
   let CoveredGPUs = [GFX1100, GFX1101, GFX1102, GFX1103, GFX1150, GFX1151, GFX1152, GFX1153,
                      GFX1154];
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX11_7_GENERIC : AMDGPUProcessorModel<"gfx11-7-generic", GFX11SpeedModel,
   FeatureISAVersion11_7_Generic.Features, [11, 7, 0]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
   let CoveredGPUs = [GFX1170, GFX1171, GFX1172];
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 //===----------------------------------------------------------------------===//
@@ -355,33 +413,42 @@ def GFX11_7_GENERIC : AMDGPUProcessorModel<"gfx11-7-generic", GFX11SpeedModel,
 def GFX1200 : AMDGPUProcessorModel<"gfx1200", GFX12SpeedModel,
   FeatureISAVersion12.Features, [12, 0, 0]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1201 : AMDGPUProcessorModel<"gfx1201", GFX12SpeedModel,
   FeatureISAVersion12.Features, [12, 0, 1]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX12_GENERIC : AMDGPUProcessorModel<"gfx12-generic", GFX12SpeedModel,
   FeatureISAVersion12_Generic.Features, [12, 0, 0]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
   let CoveredGPUs = [GFX1200, GFX1201];
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX1250 : AMDGPUProcessorModel<"gfx1250", GFX1250SpeedModel,
   FeatureISAVersion12_50.Features, [12, 5, 0]> {
   let ArchFeatures = [FEATURE_FAST_FMA_F32, FEATURE_FAST_DENORMAL_F32, FEATURE_WAVE32, FEATURE_XNACK, FEATURE_SRAMECC];
+  let MaxWavesPerEU = 16;
 }
 
 def GFX1251 : AMDGPUProcessorModel<"gfx1251", GFX1251SpeedModel,
   FeatureISAVersion12_51.Features, [12, 5, 1]> {
   let ArchFeatures = [FEATURE_FAST_FMA_F32, FEATURE_FAST_DENORMAL_F32, FEATURE_WAVE32, FEATURE_XNACK, FEATURE_SRAMECC];
+  let MaxWavesPerEU = 16;
 }
 
 def GFX12_5_GENERIC : AMDGPUProcessorModel<"gfx12-5-generic", GFX125xGenericSpeedModel,
   FeatureISAVersion12_5_Generic.Features, [12, 5, 0]> {
   let ArchFeatures = [FEATURE_FAST_FMA_F32, FEATURE_FAST_DENORMAL_F32, FEATURE_WAVE32, FEATURE_XNACK, FEATURE_SRAMECC];
   let CoveredGPUs = [GFX1250, GFX1251];
+  let MaxWavesPerEU = 16;
 }
 
 //===----------------------------------------------------------------------===//
@@ -391,12 +458,16 @@ def GFX12_5_GENERIC : AMDGPUProcessorModel<"gfx12-5-generic", GFX125xGenericSpee
 def GFX1310 : AMDGPUProcessorModel<"gfx1310", GFX12SpeedModel,
   FeatureISAVersion13.Features, [13, 1, 0]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 def GFX13_GENERIC : AMDGPUProcessorModel<"gfx13-generic", GFX12SpeedModel,
   FeatureISAVersion13_Generic.Features, [13, 1, 0]> {
   let ArchFeatures = ArchFeaturesW32Wgp;
   let CoveredGPUs = [GFX1310];
+  let MaxWavesPerEU = 16;
+  let HalfSIMDs = 2;
 }
 
 // The gfx6/gfx7/gfx8 families have no "gfxN-generic" target, so their major
diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp b/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
index 1c0e718bd8d97..08667d3d70e95 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.cpp
@@ -245,8 +245,10 @@ GCNSubtarget::GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
   LLVM_DEBUG(dbgs() << "sramecc setting for subtarget: "
                     << TargetID.getSramEccSetting() << '\n');
 
-  MaxWavesPerEU = AMDGPU::IsaInfo::getMaxWavesPerEU(*this);
-  EUsPerCU = AMDGPU::IsaInfo::getEUsPerCU(*this);
+  MaxWavesPerEU = AMDGPU::getMaxWavesPerEU(TargetID.getGPUKind());
+  // CU mode confines a work-group to half of the block's SIMDs.
+  WorkGroupSIMDs = AMDGPU::getWorkGroupSIMDs(
+      TargetID.getGPUKind(), /*FullSIMDMode=*/!isCuModeEnabled());
 
   TSInfo = std::make_unique<AMDGPUSelectionDAGInfo>();
 
diff --git a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
index 16743201d9ee3..3a22bc739ba23 100644
--- a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
@@ -3688,8 +3688,7 @@ bool SIInsertWaitcnts::run() {
              (MF.getFrameInfo().hasCalls() ||
               ST.getOccupancyWithNumVGPRs(
                   TRI.getNumUsedPhysRegs(MRI, AMDGPU::VGPR_32RegClass),
-                  /*IsDynamicVGPR=*/false) <
-                  AMDGPU::IsaInfo::getMaxWavesPerEU(ST))) {
+                  /*IsDynamicVGPR=*/false) < ST.getMaxWavesPerEU())) {
     for (auto [MI, Flag] : EndPgmInsts) {
       if (Flag) {
         if (ST.requiresNopBeforeDeallocVGPRs()) {
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index b2b1e4237367d..bc16aa88c40d4 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -1200,32 +1200,15 @@ unsigned getAddressableLocalMemorySize(const MCSubtargetInfo &STI) {
   return 32768;
 }
 
-unsigned getEUsPerCU(const MCSubtargetInfo &STI) {
-  // "Per CU" really means "per whatever functional block the waves of a
-  // workgroup must share".
-
-  // GFX12.5 only supports CU mode, which contains four SIMDs.
-  if (isGFX1250(STI)) {
-    assert(STI.getFeatureBits().test(FeatureCuMode));
-    return 4;
-  }
-
-  // For gfx10 in CU mode the functional block is the CU, which contains
-  // two SIMDs.
-  if (isGFX10Plus(STI) && STI.getFeatureBits().test(FeatureCuMode))
-    return 2;
-
-  // Pre-gfx10 a CU contains four SIMDs. For gfx10 in WGP mode the WGP
-  // contains two CUs, so a total of four SIMDs.
-  return 4;
-}
-
 unsigned getMaxWorkGroupsPerCU(const MCSubtargetInfo &STI,
                                unsigned FlatWorkGroupSize) {
   assert(FlatWorkGroupSize != 0);
   if (!STI.getTargetTriple().isAMDGCN())
     return 8;
-  unsigned MaxWaves = getMaxWavesPerEU(STI) * getEUsPerCU(STI);
+  GPUKind Kind = parseArchAMDGCN(STI.getCPU());
+  bool FullSIMDMode = !STI.getFeatureBits().test(FeatureCuMode);
+  unsigned MaxWaves =
+      getMaxWavesPerEU(Kind) * getWorkGroupSIMDs(Kind, FullSIMDMode);
   unsigned N = getWavesPerWorkGroup(STI, FlatWorkGroupSize);
   if (N == 1) {
     // Single-wave workgroups don't consume barrier resources.
@@ -1241,19 +1224,12 @@ unsigned getMaxWorkGroupsPerCU(const MCSubtargetInfo &STI,
 
 unsigned getMinWavesPerEU(const MCSubtargetInfo &STI) { return 1; }
 
-unsigned getMaxWavesPerEU(const MCSubtargetInfo &STI) {
-  // FIXME: Need to take scratch memory into account.
-  if (isGFX90A(STI))
-    return 8;
-  if (!isGFX10Plus(STI))
-    return 10;
-  return hasGFX10_3Insts(STI) ? 16 : 20;
-}
-
 unsigned getWavesPerEUForWorkGroup(const MCSubtargetInfo &STI,
                                    unsigned FlatWorkGroupSize) {
+  GPUKind Kind = parseArchAMDGCN(STI.getCPU());
+  bool FullSIMDMode = !STI.getFeatureBits().test(FeatureCuMode);
   return divideCeil(getWavesPerWorkGroup(STI, FlatWorkGroupSize),
-                    getEUsPerCU(STI));
+                    getWorkGroupSIMDs(Kind, FullSIMDMode));
 }
 
 unsigned getMinFlatWorkGroupSize(const MCSubtargetInfo &STI) { return 1; }
@@ -1291,10 +1267,10 @@ unsigned getMinNumSGPRs(const MCSubtargetInfo &STI, unsigned WavesPerEU) {
   if (Version.Major >= 10)
     return 0;
 
-  if (WavesPerEU >= getMaxWavesPerEU(STI))
+  GPUKind Kind = parseArchAMDGCN(STI.getCPU());
+  if (WavesPerEU >= getMaxWavesPerEU(Kind))
     return 0;
 
-  GPUKind Kind = parseArchAMDGCN(STI.getCPU());
   unsigned MinNumSGPRs =
       getSGPRBudgetPerWave(getTotalNumSGPRs(Kind), WavesPerEU + 1,
                            getSGPRTrapHandlerReserve(STI),
@@ -1444,7 +1420,7 @@ unsigned getNumWavesPerEUWithNumVGPRs(const MCSubtargetInfo &STI,
                                       unsigned DynamicVGPRBlockSize) {
   return getNumWavesPerEUWithNumVGPRs(
       NumVGPRs, getVGPRAllocGranule(STI, DynamicVGPRBlockSize),
-      getMaxWavesPerEU(STI), getTotalNumVGPRs(STI));
+      getMaxWavesPerEU(parseArchAMDGCN(STI.getCPU())), getTotalNumVGPRs(STI));
 }
 
 unsigned getNumWavesPerEUWithNumVGPRs(unsigned NumVGPRs, unsigned Granule,
@@ -1467,12 +1443,12 @@ unsigned getOccupancyWithNumSGPRs(unsigned SGPRs, unsigned MaxWaves,
 }
 
 unsigned getOccupancyWithNumSGPRs(const MCSubtargetInfo &STI, unsigned SGPRs) {
-  unsigned MaxWaves = getMaxWavesPerEU(STI);
+  GPUKind Kind = parseArchAMDGCN(STI.getCPU());
+  unsigned MaxWaves = getMaxWavesPerEU(Kind);
 
   if (!isSGPROccupancyLimited(STI))
     return MaxWaves;
 
-  GPUKind Kind = parseArchAMDGCN(STI.getCPU());
   return getOccupancyWithNumSGPRs(SGPRs, MaxWaves, getTotalNumSGPRs(Kind),
                                   getSGPRAllocGranule(Kind),
                                   getSGPRTrapHandlerReserve(STI));
@@ -1490,7 +1466,7 @@ unsigned getMinNumVGPRs(const MCSubtargetInfo &STI, unsigned WavesPerEU,
   if (DynamicVGPREnabled)
     return 0;
 
-  unsigned MaxWavesPerEU = getMaxWavesPerEU(STI);
+  unsigned MaxWavesPerEU = getMaxWavesPerEU(parseArchAMDGCN(STI.getCPU()));
   if (WavesPerEU >= MaxWavesPerEU)
     return 0;
 
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index 7d0bdbc661bc1..3e5f8d6cd744d 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -183,10 +183,6 @@ unsigned getLocalMemorySize(const MCSubtargetInfo &STI);
 /// \p STI.
 unsigned getAddressableLocalMemorySize(const MCSubtargetInfo &STI);
 
-/// \returns Number of execution units per compute unit for given subtarget \p
-/// STI.
-unsigned getEUsPerCU(const MCSubtargetInfo &STI);
-
 /// \returns Maximum number of work groups per compute unit for given subtarget
 /// \p STI and limited by given \p FlatWorkGroupSize.
 unsigned getMaxWorkGroupsPerCU(const MCSubtargetInfo &STI,
@@ -196,10 +192,6 @@ unsigned getMaxWorkGroupsPerCU(const MCSubtargetInfo &STI,
 /// STI.
 unsigned getMinWavesPerEU(const MCSubtargetInfo &STI);
 
-/// \returns Maximum number of waves per execution unit for given subtarget \p
-/// STI without any kind of limitation.
-unsigned getMaxWavesPerEU(const MCSubtargetInfo &STI);
-
 /// \returns Number of waves per execution unit required to support the given \p
 /// FlatWorkGroupSize.
 unsigned getWavesPerEUForWorkGroup(const MCSubtargetInfo &STI,
diff --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
index d8abaf7474cd6..45cb2863fa743 100644
--- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
+++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
@@ -41,6 +41,9 @@ struct GPUInfo {
   AMDGPUFeatureBitset Features;
   IsaVersion Version;
   StringTable::Offset FamilyName;
+  uint8_t MaxWavesPerEU;
+  uint8_t FullSIMDs;
+  uint8_t HalfSIMDs;
 };
 
 // Per-GPU data for the R600 GPUKinds.
@@ -422,6 +425,27 @@ unsigned AMDGPU::getSGPRAllocGranule(Triple::SubArchType SubArch) {
   return 8;
 }
 
+unsigned AMDGPU::getWorkGroupSIMDs(GPUKind AK, bool FullSIMDMode) {
+  const GPUInfo *Info = getAMDGPUInfo(AK);
+  if (!Info)
+    return 4;
+  return FullSIMDMode ? Info->FullSIMDs : Info->HalfSIMDs;
+}
+
+unsigned AMDGPU::getWorkGroupSIMDs(Triple::SubArchType SubArch,
+                                   bool FullSIMDMode) {
+  return getWorkGroupSIMDs(getGPUKindFromSubArch(SubArch), FullSIMDMode);
+}
+
+unsigned AMDGPU::getMaxWavesPerEU(GPUKind AK) {
+  const GPUInfo *Info = getAMDGPUInfo(AK);
+  return Info ? Info->MaxWavesPerEU : 10;
+}
+
+unsigned AMDGPU::getMaxWavesPerEU(Triple::SubArchType SubArch) {
+  return getMaxWavesPerEU(getGPUKindFromSubArch(SubArch));
+}
+
 StringRef AMDGPU::getCanonicalArchName(const Triple &T, StringRef Arch) {
   assert(T.isAMDGPU());
   auto ProcKind = T.isAMDGCN() ? parseArchAMDGCN(Arch) : parseArchR600(Arch);
diff --git a/llvm/test/TableGen/AMDGPUTargetDefErrors.td b/llvm/test/TableGen/AMDGPUTargetDefErrors.td
index 106b168917676..1d94725625665 100644
--- a/llvm/test/TableGen/AMDGPUTargetDefErrors.td
+++ b/llvm/test/TableGen/AMDGPUTargetDefErrors.td
@@ -23,6 +23,9 @@ class AMDGPUGPUInfo<list<int> isa = []> {
   list<int> IsaVersion = isa;
   list<Processor> CoveredGPUs = [];
   bit IsPseudoTarget = false;
+  int MaxWavesPerEU = 10;
+  int FullSIMDs = 4;
+  int HalfSIMDs = 4;
 }
 
 def : ProcessorModel<"gfx900", NoSchedModel, []>, AMDGPUGPUInfo<[9, 0, 0]>;
@@ -39,6 +42,9 @@ class AMDGPUGPUInfo<list<int> isa = []> {
   list<int> IsaVersion = isa;
   list<Processor> CoveredGPUs = [];
   bit IsPseudoTarget = false;
+  int MaxWavesPerEU = 10;
+  int FullSIMDs = 4;
+  int HalfSIMDs = 4;
 }
 
 def DupA : ProcessorModel<"gfx900", NoSchedModel, []>, AMDGPUGPUInfo<[9, 0, 0]>;
@@ -55,6 +61,9 @@ class AMDGPUGPUInfo<list<int> isa = []> {
   list<int> IsaVersion = isa;
   list<Processor> CoveredGPUs = [];
   bit IsPseudoTarget = false;
+  int MaxWavesPerEU = 10;
+  int FullSIMDs = 4;
+  int HalfSIMDs = 4;
 }
 
 def : ProcessorModel<"gfx900", NoSchedModel, []>, AMDGPUGPUInfo<[9, 0, 0]>;
@@ -71,6 +80,9 @@ class AMDGPUGPUInfo<list<int> isa = []> {
   list<int> IsaVersion = isa;
   list<Processor> CoveredGPUs = [];
   bit IsPseudoTarget = false;
+  int MaxWavesPerEU = 10;
+  int FullSIMDs = 4;
+  int HalfSIMDs = 4;
 }
 // A malformed IsaVersion is reported (not asserted), so this stays a clean
 // diagnostic in release builds.
@@ -86,6 +98,9 @@ class AMDGPUGPUInfo<list<int> isa = []> {
   list<int> IsaVersion = isa;
   list<Processor> CoveredGPUs = [];
   bit IsPseudoTarget = false;
+  int MaxWavesPerEU = 10;
+  int FullSIMDs = 4;
+  int HalfSIMDs = 4;
 }
 // The stepping must fit in a single hex digit so it can be spelled in the
 // triple subarch name (e.g. "amdgpu9.0c").
@@ -101,6 +116,9 @@ class AMDGPUGPUInfo<list<int> isa = []> {
   list<int> IsaVersion = isa;
   list<Processor> CoveredGPUs = [];
   bit IsPseudoTarget = false;
+  int MaxWavesPerEU = 10;
+  int FullSIMDs = 4;
+  int HalfSIMDs = 4;
 }
 
 def FeatureFoo : SubtargetFeature<"foo", "HasFoo", "true", "Foo">;
diff --git a/llvm/tools/llvm-calc-occupancy/llvm-calc-occupancy.cpp b/llvm/tools/llvm-calc-occupancy/llvm-calc-occupancy.cpp
index ed44d7531640e..5952cfc4fa36a 100644
--- a/llvm/tools/llvm-calc-occupancy/llvm-calc-occupancy.cpp
+++ b/llvm/tools/llvm-calc-occupancy/llvm-calc-occupancy.cpp
@@ -220,8 +220,8 @@ int main(int argc, char **argv) {
 
   // Hardware characteristics.
   unsigned WaveSize = AMDGPU::IsaInfo::getWavefrontSize(STI);
-  unsigned MaxWaves = AMDGPU::IsaInfo::getMaxWavesPerEU(STI);
-  unsigned EUsPerCU = AMDGPU::IsaInfo::getEUsPerCU(STI);
+  unsigned MaxWaves = ST.getMaxWavesPerEU();
+  unsigned WorkGroupSIMDs = ST.getWorkGroupSIMDs();
   unsigned LocalMemSize = AMDGPU::IsaInfo::getLocalMemorySize(STI);
   unsigned AddrLocalMem = AMDGPU::IsaInfo::getAddressableLocalMemorySize(STI);
   unsigned AddrVGPRs =
@@ -264,7 +264,7 @@ int main(int argc, char **argv) {
   outs() << format("  %-20s %u\n", "Wavefront size:", WaveSize);
   outs() << format("  %-20s %u (waves per SIMD, hardware limit)\n",
                    "Max waves/EU:", MaxWaves);
-  outs() << format("  %-20s %u\n", "EUs (SIMDs) per CU:", EUsPerCU);
+  outs() << format("  %-20s %u\n", "SIMDs per work-group:", WorkGroupSIMDs);
   outs() << format("  %-20s %s\n",
                    "LDS per CU:", formatBytes(LocalMemSize).c_str());
   outs() << format("  %-20s %s\n", "Addressable LDS:",
@@ -332,11 +332,11 @@ int main(int argc, char **argv) {
   outs() << "\nResult\n";
   if (MinOcc == MaxOcc)
     outs() << format("  %-20s %u waves/EU (%u waves/CU)\n",
-                     "Occupancy:", MaxOcc, MaxOcc * EUsPerCU);
+                     "Occupancy:", MaxOcc, MaxOcc * WorkGroupSIMDs);
   else
     outs() << format("  %-20s %u .. %u waves/EU (%u .. %u waves/CU)\n",
-                     "Occupancy:", MinOcc, MaxOcc, MinOcc * EUsPerCU,
-                     MaxOcc * EUsPerCU);
+                     "Occupancy:", MinOcc, MaxOcc, MinOcc * WorkGroupSIMDs,
+                     MaxOcc * WorkGroupSIMDs);
   outs() << format("  %-20s %s\n",
                    "Limited by:", join(LimitedBy, ", ").c_str());
 
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 8939c0e7a162c..aa447bddfad41 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -3027,6 +3027,43 @@ TEST(TargetParserTest, testAMDGPUgetSGPRAllocGranule) {
   EXPECT_EQ(AMDGPU::getSGPRAllocGranule(AMDGPU::GK_GFX1030), 106u);
 }
 
+TEST(TargetParserTest, testAMDGPUgetWorkGroupSIMDs) {
+  // The functional block has four SIMDs everywhere. A target that can split it
+  // runs a work-group on two of them outside full-SIMD mode; one that cannot -
+  // pre-GFX10, and GFX10+ targets such as GFX12.5 - runs on four either way.
+  // The second argument is the full-SIMD-mode flag.
+  EXPECT_EQ(AMDGPU::getWorkGroupSIMDs(Triple::AMDGPUSubArch900, true), 4u);
+  EXPECT_EQ(AMDGPU::getWorkGroupSIMDs(Triple::AMDGPUSubArch908, true), 4u);
+  EXPECT_EQ(AMDGPU::getWorkGroupSIMDs(Triple::AMDGPUSubArch942, true), 4u);
+  EXPECT_EQ(AMDGPU::getWorkGroupSIMDs(Triple::AMDGPUSubArch950, true), 4u);
+  EXPECT_EQ(AMDGPU::getWorkGroupSIMDs(Triple::AMDGPUSubArch1030, true), 4u);
+  EXPECT_EQ(AMDGPU::getWorkGroupSIMDs(Triple::AMDGPUSubArch1030, false), 2u);
+  EXPECT_EQ(AMDGPU::getWorkGroupSIMDs(Triple::AMDGPUSubArch1250, false), 4u);
+
+  // The GPUKind overload resolves to the same values.
+  EXPECT_EQ(AMDGPU::getWorkGroupSIMDs(AMDGPU::GK_GFX900, true), 4u);
+  EXPECT_EQ(AMDGPU::getWorkGroupSIMDs(AMDGPU::GK_GFX1030, true), 4u);
+  EXPECT_EQ(AMDGPU::getWorkGroupSIMDs(AMDGPU::GK_GFX1030, false), 2u);
+}
+
+TEST(TargetParserTest, testAMDGPUgetMaxWavesPerEU) {
+  // GFX90A+ -> 8, other pre-GFX10 -> 10, GFX10.1 -> 20, GFX10.3 and every
+  // later generation -> 16.
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(Triple::AMDGPUSubArch900), 10u);
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(Triple::AMDGPUSubArch908), 10u);
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(Triple::AMDGPUSubArch90A), 8u);
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(Triple::AMDGPUSubArch942), 8u);
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(Triple::AMDGPUSubArch950), 8u);
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(Triple::AMDGPUSubArch1010), 20u);
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(Triple::AMDGPUSubArch1030), 16u);
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(Triple::AMDGPUSubArch1250), 16u);
+
+  // The GPUKind overload resolves to the same values.
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(AMDGPU::GK_GFX908), 10u);
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(AMDGPU::GK_GFX90A), 8u);
+  EXPECT_EQ(AMDGPU::getMaxWavesPerEU(AMDGPU::GK_GFX1030), 16u);
+}
+
 TEST(TargetParserTest, testAMDGPUParseTargetIDString) {
   using AMDGPU::TargetID;
   using AMDGPU::TargetIDSetting;
diff --git a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
index d077178f98526..34b883042a647 100644
--- a/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/AMDGPUTargetDefEmitter.cpp
@@ -534,7 +534,10 @@ emitAMDGPUTable(raw_ostream &OS, const RecordKeeper &RK,
     emitFeatureBitset(OS, R, FeatureIdx);
     OS << ", ";
     emitIsaVersion(OS, R, '{', '}');
-    OS << ", " << Names.GetOrAddStringOffset(getArchFamily(R)) << "},\n";
+    OS << ", " << Names.GetOrAddStringOffset(getArchFamily(R)) << ", "
+       << R->getValueAsInt("MaxWavesPerEU") << ", "
+       << R->getValueAsInt("FullSIMDs") << ", " << R->getValueAsInt("HalfSIMDs")
+       << "},\n";
   }
   OS << "};\n"
         "#endif // GET_AMDGPU_GPU_TABLE\n\n";



More information about the llvm-commits mailing list