[Lldb-commits] [lldb] [lldb] Use TargetParser for AMDGPU architectures (PR #223192)

satyanarayana reddy janga via lldb-commits lldb-commits at lists.llvm.org
Sat Sep 12 16:52:21 PDT 2026


https://github.com/satyajanga created https://github.com/llvm/llvm-project/pull/223192

Fixes #218864

  Replace LLDB's manually maintained AMDGPU target list with TargetParser GPU and subarchitecture information.

  Tests:
  - UtilityTests
  - ObjectFileELFTests

>From 2b7a68c60282d64efb2af7cb9005f53a487068c2 Mon Sep 17 00:00:00 2001
From: satya janga <satyajanga at fb.com>
Date: Sat, 12 Sep 2026 08:36:10 -0700
Subject: [PATCH] [lldb] Use TargetParser for AMDGPU architectures

---
 lldb/include/lldb/Utility/ArchSpec.h          |  87 +--
 lldb/source/Utility/ArchSpec.cpp              | 525 +++---------------
 .../ObjectFile/ELF/TestObjectFileELF.cpp      |  49 +-
 lldb/unittests/Utility/ArchSpecTest.cpp       |  97 +++-
 4 files changed, 176 insertions(+), 582 deletions(-)

diff --git a/lldb/include/lldb/Utility/ArchSpec.h b/lldb/include/lldb/Utility/ArchSpec.h
index 3d7d10d061a54..13f20f3f6fd95 100644
--- a/lldb/include/lldb/Utility/ArchSpec.h
+++ b/lldb/include/lldb/Utility/ArchSpec.h
@@ -240,85 +240,7 @@ class ArchSpec {
 
     eCore_wasm32,
 
-    eCore_amd_gpu_r600_R600,
-    eCore_amd_gpu_r600_R630,
-    eCore_amd_gpu_r600_RS880,
-    eCore_amd_gpu_r600_RV670,
-    eCore_amd_gpu_r600_RV710,
-    eCore_amd_gpu_r600_RV730,
-    eCore_amd_gpu_r600_RV770,
-    eCore_amd_gpu_r600_CEDAR,
-    eCore_amd_gpu_r600_CYPRESS,
-    eCore_amd_gpu_r600_JUNIPER,
-    eCore_amd_gpu_r600_REDWOOD,
-    eCore_amd_gpu_r600_SUMO,
-    eCore_amd_gpu_r600_BARTS,
-    eCore_amd_gpu_r600_CAICOS,
-    eCore_amd_gpu_r600_CAYMAN,
-    eCore_amd_gpu_r600_TURKS,
-    eCore_amd_gpu_gcn_GFX600,
-    eCore_amd_gpu_gcn_GFX601,
-    eCore_amd_gpu_gcn_GFX602,
-    eCore_amd_gpu_gcn_GFX700,
-    eCore_amd_gpu_gcn_GFX701,
-    eCore_amd_gpu_gcn_GFX702,
-    eCore_amd_gpu_gcn_GFX703,
-    eCore_amd_gpu_gcn_GFX704,
-    eCore_amd_gpu_gcn_GFX705,
-    eCore_amd_gpu_gcn_GFX801,
-    eCore_amd_gpu_gcn_GFX802,
-    eCore_amd_gpu_gcn_GFX803,
-    eCore_amd_gpu_gcn_GFX805,
-    eCore_amd_gpu_gcn_GFX810,
-    eCore_amd_gpu_gcn_GFX900,
-    eCore_amd_gpu_gcn_GFX902,
-    eCore_amd_gpu_gcn_GFX904,
-    eCore_amd_gpu_gcn_GFX906,
-    eCore_amd_gpu_gcn_GFX908,
-    eCore_amd_gpu_gcn_GFX909,
-    eCore_amd_gpu_gcn_GFX90A,
-    eCore_amd_gpu_gcn_GFX90C,
-    eCore_amd_gpu_gcn_GFX942,
-    eCore_amd_gpu_gcn_GFX950,
-    eCore_amd_gpu_gcn_GFX1010,
-    eCore_amd_gpu_gcn_GFX1011,
-    eCore_amd_gpu_gcn_GFX1012,
-    eCore_amd_gpu_gcn_GFX1013,
-    eCore_amd_gpu_gcn_GFX1030,
-    eCore_amd_gpu_gcn_GFX1031,
-    eCore_amd_gpu_gcn_GFX1032,
-    eCore_amd_gpu_gcn_GFX1033,
-    eCore_amd_gpu_gcn_GFX1034,
-    eCore_amd_gpu_gcn_GFX1035,
-    eCore_amd_gpu_gcn_GFX1036,
-    eCore_amd_gpu_gcn_GFX1100,
-    eCore_amd_gpu_gcn_GFX1101,
-    eCore_amd_gpu_gcn_GFX1102,
-    eCore_amd_gpu_gcn_GFX1103,
-    eCore_amd_gpu_gcn_GFX1150,
-    eCore_amd_gpu_gcn_GFX1151,
-    eCore_amd_gpu_gcn_GFX1152,
-    eCore_amd_gpu_gcn_GFX1153,
-    eCore_amd_gpu_gcn_GFX1154,
-    eCore_amd_gpu_gcn_GFX1170,
-    eCore_amd_gpu_gcn_GFX1171,
-    eCore_amd_gpu_gcn_GFX1172,
-    eCore_amd_gpu_gcn_GFX1200,
-    eCore_amd_gpu_gcn_GFX1201,
-    eCore_amd_gpu_gcn_GFX1250_STRICT,
-    eCore_amd_gpu_gcn_GFX1250,
-    eCore_amd_gpu_gcn_GFX1251,
-    eCore_amd_gpu_gcn_GFX1310,
-    eCore_amd_gpu_gcn_GFX9_GENERIC,
-    eCore_amd_gpu_gcn_GFX9_4_GENERIC,
-    eCore_amd_gpu_gcn_GFX10_1_GENERIC,
-    eCore_amd_gpu_gcn_GFX10_3_GENERIC,
-    eCore_amd_gpu_gcn_GFX11_GENERIC,
-    eCore_amd_gpu_gcn_GFX12_GENERIC,
-    eCore_amd_gpu_gcn_GFX12_5_GENERIC,
-    eCore_amd_gpu_gcn_GFX11_7_GENERIC,
-    eCore_amd_gpu_gcn_GFX13_GENERIC,
-    eCore_amd_gpu_unknown,
+    eCore_amd_gpu,
 
     kNumCores,
 
@@ -366,10 +288,7 @@ class ArchSpec {
     kCore_mips64el_last = eCore_mips64r6el,
 
     kCore_mips_first = eCore_mips32,
-    kCore_mips_last = eCore_mips64r6el,
-
-    kCore_amd_gpu_first = eCore_amd_gpu_r600_R600,
-    kCore_amd_gpu_last = eCore_amd_gpu_unknown
+    kCore_mips_last = eCore_mips64r6el
 
   };
 
@@ -537,8 +456,6 @@ class ArchSpec {
 
   uint32_t GetMachOCPUSubType() const;
 
-  uint32_t GetElfCPUSubType() const;
-
   /// Architecture triple accessor.
   ///
   /// \return A triple describing this ArchSpec.
diff --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp
index af2299e3c7480..5d5d0933e47da 100644
--- a/lldb/source/Utility/ArchSpec.cpp
+++ b/lldb/source/Utility/ArchSpec.cpp
@@ -13,12 +13,12 @@
 #include "lldb/Utility/StringList.h"
 #include "lldb/lldb-defines.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringSwitch.h"
 #include "llvm/BinaryFormat/COFF.h"
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/BinaryFormat/MachO.h"
 #include "llvm/BinaryFormat/XCOFF.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/AMDGPUTargetParser.h"
 #include "llvm/TargetParser/ARMTargetParser.h"
 
 using namespace lldb;
@@ -41,22 +41,6 @@ struct CoreDefinition {
 
 } // namespace lldb_private
 
-#define AMD_GPU_CORE_DEF_R600(sub)                                             \
-  {eByteOrderLittle,                                                           \
-   4,                                                                          \
-   4,                                                                          \
-   16,                                                                         \
-   llvm::Triple::r600,                                                         \
-   ArchSpec::eCore_amd_gpu_r600_##sub,                                         \
-   "r600"}
-#define AMD_GPU_CORE_DEF_GCN(sub)                                              \
-  {eByteOrderLittle,                                                           \
-   8,                                                                          \
-   4,                                                                          \
-   16,                                                                         \
-   llvm::Triple::amdgpu,                                                       \
-   ArchSpec::eCore_amd_gpu_gcn_##sub,                                          \
-   "amdgpu"}
 // This core information can be looked using the ArchSpec::Core as the index
 static constexpr const CoreDefinition g_core_definitions[] = {
     {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_generic,
@@ -271,86 +255,8 @@ static constexpr const CoreDefinition g_core_definitions[] = {
 
     {eByteOrderLittle, 4, 1, 4, llvm::Triple::wasm32, ArchSpec::eCore_wasm32,
      "wasm32"},
-    AMD_GPU_CORE_DEF_R600(R600),
-    AMD_GPU_CORE_DEF_R600(R630),
-    AMD_GPU_CORE_DEF_R600(RS880),
-    AMD_GPU_CORE_DEF_R600(RV670),
-    AMD_GPU_CORE_DEF_R600(RV710),
-    AMD_GPU_CORE_DEF_R600(RV730),
-    AMD_GPU_CORE_DEF_R600(RV770),
-    AMD_GPU_CORE_DEF_R600(CEDAR),
-    AMD_GPU_CORE_DEF_R600(CYPRESS),
-    AMD_GPU_CORE_DEF_R600(JUNIPER),
-    AMD_GPU_CORE_DEF_R600(REDWOOD),
-    AMD_GPU_CORE_DEF_R600(SUMO),
-    AMD_GPU_CORE_DEF_R600(BARTS),
-    AMD_GPU_CORE_DEF_R600(CAICOS),
-    AMD_GPU_CORE_DEF_R600(CAYMAN),
-    AMD_GPU_CORE_DEF_R600(TURKS),
-    AMD_GPU_CORE_DEF_GCN(GFX600),
-    AMD_GPU_CORE_DEF_GCN(GFX601),
-    AMD_GPU_CORE_DEF_GCN(GFX602),
-    AMD_GPU_CORE_DEF_GCN(GFX700),
-    AMD_GPU_CORE_DEF_GCN(GFX701),
-    AMD_GPU_CORE_DEF_GCN(GFX702),
-    AMD_GPU_CORE_DEF_GCN(GFX703),
-    AMD_GPU_CORE_DEF_GCN(GFX704),
-    AMD_GPU_CORE_DEF_GCN(GFX705),
-    AMD_GPU_CORE_DEF_GCN(GFX801),
-    AMD_GPU_CORE_DEF_GCN(GFX802),
-    AMD_GPU_CORE_DEF_GCN(GFX803),
-    AMD_GPU_CORE_DEF_GCN(GFX805),
-    AMD_GPU_CORE_DEF_GCN(GFX810),
-    AMD_GPU_CORE_DEF_GCN(GFX900),
-    AMD_GPU_CORE_DEF_GCN(GFX902),
-    AMD_GPU_CORE_DEF_GCN(GFX904),
-    AMD_GPU_CORE_DEF_GCN(GFX906),
-    AMD_GPU_CORE_DEF_GCN(GFX908),
-    AMD_GPU_CORE_DEF_GCN(GFX909),
-    AMD_GPU_CORE_DEF_GCN(GFX90A),
-    AMD_GPU_CORE_DEF_GCN(GFX90C),
-    AMD_GPU_CORE_DEF_GCN(GFX942),
-    AMD_GPU_CORE_DEF_GCN(GFX950),
-    AMD_GPU_CORE_DEF_GCN(GFX1010),
-    AMD_GPU_CORE_DEF_GCN(GFX1011),
-    AMD_GPU_CORE_DEF_GCN(GFX1012),
-    AMD_GPU_CORE_DEF_GCN(GFX1013),
-    AMD_GPU_CORE_DEF_GCN(GFX1030),
-    AMD_GPU_CORE_DEF_GCN(GFX1031),
-    AMD_GPU_CORE_DEF_GCN(GFX1032),
-    AMD_GPU_CORE_DEF_GCN(GFX1033),
-    AMD_GPU_CORE_DEF_GCN(GFX1034),
-    AMD_GPU_CORE_DEF_GCN(GFX1035),
-    AMD_GPU_CORE_DEF_GCN(GFX1036),
-    AMD_GPU_CORE_DEF_GCN(GFX1100),
-    AMD_GPU_CORE_DEF_GCN(GFX1101),
-    AMD_GPU_CORE_DEF_GCN(GFX1102),
-    AMD_GPU_CORE_DEF_GCN(GFX1103),
-    AMD_GPU_CORE_DEF_GCN(GFX1150),
-    AMD_GPU_CORE_DEF_GCN(GFX1151),
-    AMD_GPU_CORE_DEF_GCN(GFX1152),
-    AMD_GPU_CORE_DEF_GCN(GFX1153),
-    AMD_GPU_CORE_DEF_GCN(GFX1154),
-    AMD_GPU_CORE_DEF_GCN(GFX1170),
-    AMD_GPU_CORE_DEF_GCN(GFX1171),
-    AMD_GPU_CORE_DEF_GCN(GFX1172),
-    AMD_GPU_CORE_DEF_GCN(GFX1200),
-    AMD_GPU_CORE_DEF_GCN(GFX1201),
-    AMD_GPU_CORE_DEF_GCN(GFX1250_STRICT),
-    AMD_GPU_CORE_DEF_GCN(GFX1250),
-    AMD_GPU_CORE_DEF_GCN(GFX1251),
-    AMD_GPU_CORE_DEF_GCN(GFX1310),
-    AMD_GPU_CORE_DEF_GCN(GFX9_GENERIC),
-    AMD_GPU_CORE_DEF_GCN(GFX9_4_GENERIC),
-    AMD_GPU_CORE_DEF_GCN(GFX10_1_GENERIC),
-    AMD_GPU_CORE_DEF_GCN(GFX10_3_GENERIC),
-    AMD_GPU_CORE_DEF_GCN(GFX11_GENERIC),
-    AMD_GPU_CORE_DEF_GCN(GFX12_GENERIC),
-    AMD_GPU_CORE_DEF_GCN(GFX12_5_GENERIC),
-    AMD_GPU_CORE_DEF_GCN(GFX11_7_GENERIC),
-    AMD_GPU_CORE_DEF_GCN(GFX13_GENERIC),
-    {eByteOrderLittle, 8, 4, 16, llvm::Triple::amdgpu,
-     ArchSpec::eCore_amd_gpu_unknown, "amdgpu"},
+    {eByteOrderLittle, 8, 4, 16, llvm::Triple::amdgpu, ArchSpec::eCore_amd_gpu,
+     "amdgpu"},
 };
 
 // Ensure that we have an entry in the g_core_definitions for each core. If you
@@ -480,12 +386,6 @@ static const ArchDefinition g_macho_arch_def = {eArchTypeMachO,
                                                 std::size(g_macho_arch_entries),
                                                 g_macho_arch_entries, "mach-o"};
 
-#define AMD_GPU_ARCH_DEF_R600(sub)                                             \
-  {ArchSpec::eCore_amd_gpu_r600_##sub, llvm::ELF::EM_AMDGPU,                   \
-   llvm::ELF::EF_AMDGPU_MACH_R600_##sub}
-#define AMD_GPU_ARCH_DEF_GCN(sub)                                              \
-  {ArchSpec::eCore_amd_gpu_gcn_##sub, llvm::ELF::EM_AMDGPU,                    \
-   llvm::ELF::EF_AMDGPU_MACH_AMDGCN_##sub}
 //===----------------------------------------------------------------------===//
 // A table that gets searched linearly for matches. This table is used to
 // convert cpu type and subtypes to architecture names, and to convert
@@ -524,86 +424,7 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = {
     {ArchSpec::eCore_riscv64,         llvm::ELF::EM_RISCV,      ArchSpec::eRISCVSubType_riscv64}, // riscv64
     {ArchSpec::eCore_loongarch32,     llvm::ELF::EM_LOONGARCH,  ArchSpec::eLoongArchSubType_loongarch32}, // loongarch32
     {ArchSpec::eCore_loongarch64,     llvm::ELF::EM_LOONGARCH,  ArchSpec::eLoongArchSubType_loongarch64}, // loongarch64
-    AMD_GPU_ARCH_DEF_R600(R600),
-    AMD_GPU_ARCH_DEF_R600(R630),
-    AMD_GPU_ARCH_DEF_R600(RS880),
-    AMD_GPU_ARCH_DEF_R600(RV670),
-    AMD_GPU_ARCH_DEF_R600(RV710),
-    AMD_GPU_ARCH_DEF_R600(RV730),
-    AMD_GPU_ARCH_DEF_R600(RV770),
-    AMD_GPU_ARCH_DEF_R600(CEDAR),
-    AMD_GPU_ARCH_DEF_R600(CYPRESS),
-    AMD_GPU_ARCH_DEF_R600(JUNIPER),
-    AMD_GPU_ARCH_DEF_R600(REDWOOD),
-    AMD_GPU_ARCH_DEF_R600(SUMO),
-    AMD_GPU_ARCH_DEF_R600(BARTS),
-    AMD_GPU_ARCH_DEF_R600(CAICOS),
-    AMD_GPU_ARCH_DEF_R600(CAYMAN),
-    AMD_GPU_ARCH_DEF_R600(TURKS),
-    AMD_GPU_ARCH_DEF_GCN(GFX600),
-    AMD_GPU_ARCH_DEF_GCN(GFX601),
-    AMD_GPU_ARCH_DEF_GCN(GFX602),
-    AMD_GPU_ARCH_DEF_GCN(GFX700),
-    AMD_GPU_ARCH_DEF_GCN(GFX701),
-    AMD_GPU_ARCH_DEF_GCN(GFX702),
-    AMD_GPU_ARCH_DEF_GCN(GFX703),
-    AMD_GPU_ARCH_DEF_GCN(GFX704),
-    AMD_GPU_ARCH_DEF_GCN(GFX705),
-    AMD_GPU_ARCH_DEF_GCN(GFX801),
-    AMD_GPU_ARCH_DEF_GCN(GFX802),
-    AMD_GPU_ARCH_DEF_GCN(GFX803),
-    AMD_GPU_ARCH_DEF_GCN(GFX805),
-    AMD_GPU_ARCH_DEF_GCN(GFX810),
-    AMD_GPU_ARCH_DEF_GCN(GFX900),
-    AMD_GPU_ARCH_DEF_GCN(GFX902),
-    AMD_GPU_ARCH_DEF_GCN(GFX904),
-    AMD_GPU_ARCH_DEF_GCN(GFX906),
-    AMD_GPU_ARCH_DEF_GCN(GFX908),
-    AMD_GPU_ARCH_DEF_GCN(GFX909),
-    AMD_GPU_ARCH_DEF_GCN(GFX90A),
-    AMD_GPU_ARCH_DEF_GCN(GFX90C),
-    AMD_GPU_ARCH_DEF_GCN(GFX942),
-    AMD_GPU_ARCH_DEF_GCN(GFX950),
-    AMD_GPU_ARCH_DEF_GCN(GFX1010),
-    AMD_GPU_ARCH_DEF_GCN(GFX1011),
-    AMD_GPU_ARCH_DEF_GCN(GFX1012),
-    AMD_GPU_ARCH_DEF_GCN(GFX1013),
-    AMD_GPU_ARCH_DEF_GCN(GFX1030),
-    AMD_GPU_ARCH_DEF_GCN(GFX1031),
-    AMD_GPU_ARCH_DEF_GCN(GFX1032),
-    AMD_GPU_ARCH_DEF_GCN(GFX1033),
-    AMD_GPU_ARCH_DEF_GCN(GFX1034),
-    AMD_GPU_ARCH_DEF_GCN(GFX1035),
-    AMD_GPU_ARCH_DEF_GCN(GFX1036),
-    AMD_GPU_ARCH_DEF_GCN(GFX1100),
-    AMD_GPU_ARCH_DEF_GCN(GFX1101),
-    AMD_GPU_ARCH_DEF_GCN(GFX1102),
-    AMD_GPU_ARCH_DEF_GCN(GFX1103),
-    AMD_GPU_ARCH_DEF_GCN(GFX1150),
-    AMD_GPU_ARCH_DEF_GCN(GFX1151),
-    AMD_GPU_ARCH_DEF_GCN(GFX1152),
-    AMD_GPU_ARCH_DEF_GCN(GFX1153),
-    AMD_GPU_ARCH_DEF_GCN(GFX1154),
-    AMD_GPU_ARCH_DEF_GCN(GFX1170),
-    AMD_GPU_ARCH_DEF_GCN(GFX1171),
-    AMD_GPU_ARCH_DEF_GCN(GFX1172),
-    AMD_GPU_ARCH_DEF_GCN(GFX1200),
-    AMD_GPU_ARCH_DEF_GCN(GFX1201),
-    AMD_GPU_ARCH_DEF_GCN(GFX1250_STRICT),
-    AMD_GPU_ARCH_DEF_GCN(GFX1250),
-    AMD_GPU_ARCH_DEF_GCN(GFX1251),
-    AMD_GPU_ARCH_DEF_GCN(GFX1310),
-    AMD_GPU_ARCH_DEF_GCN(GFX9_GENERIC),
-    AMD_GPU_ARCH_DEF_GCN(GFX9_4_GENERIC),
-    AMD_GPU_ARCH_DEF_GCN(GFX10_1_GENERIC),
-    AMD_GPU_ARCH_DEF_GCN(GFX10_3_GENERIC),
-    AMD_GPU_ARCH_DEF_GCN(GFX11_GENERIC),
-    AMD_GPU_ARCH_DEF_GCN(GFX12_GENERIC),
-    AMD_GPU_ARCH_DEF_GCN(GFX12_5_GENERIC),
-    AMD_GPU_ARCH_DEF_GCN(GFX11_7_GENERIC),
-    AMD_GPU_ARCH_DEF_GCN(GFX13_GENERIC),
-    // Any AMDGPU object with no recognized model resolves here.
-    {ArchSpec::eCore_amd_gpu_unknown, llvm::ELF::EM_AMDGPU},
+    {ArchSpec::eCore_amd_gpu,         llvm::ELF::EM_AMDGPU,     0,  UINT32_MAX, 0},
 };
 // clang-format on
 
@@ -838,11 +659,8 @@ std::string ArchSpec::GetClangTargetCPU() const {
   if (GetTriple().isARM())
     cpu = llvm::ARM::getARMCPUForArch(GetTriple(), "").str();
 
-  if (GetTriple().isAMDGPU()) {
-    uint32_t sub = GetElfCPUSubType();
-    if (sub != LLDB_INVALID_CPUTYPE)
-      cpu = GetAMDGPUVariantName(sub);
-  }
+  if (GetTriple().getArch() == llvm::Triple::amdgpu)
+    cpu = llvm::AMDGPU::getArchNameFromSubArch(GetTriple().getSubArch());
   return cpu;
 }
 
@@ -876,10 +694,6 @@ uint32_t ArchSpec::GetMachOCPUSubType() const {
   return GetCPUSubType(&g_macho_arch_def, m_core);
 }
 
-uint32_t ArchSpec::GetElfCPUSubType() const {
-  return GetCPUSubType(&g_elf_arch_def, m_core);
-}
-
 llvm::Triple::ArchType ArchSpec::GetMachine() const {
   const CoreDefinition *core_def = FindCoreDefinition(m_core);
   if (core_def)
@@ -1031,6 +845,17 @@ void ArchSpec::MergeFrom(const ArchSpec &other) {
     if (other.GetCore() != eCore_uknownMach64)
       UpdateCore();
   }
+  if (GetTriple().getArch() == llvm::Triple::amdgpu &&
+      other.GetTriple().getArch() == llvm::Triple::amdgpu) {
+    llvm::Triple::SubArchType sub_arch = GetTriple().getSubArch();
+    llvm::Triple::SubArchType other_sub_arch = other.GetTriple().getSubArch();
+    if (other_sub_arch != llvm::Triple::NoSubArch &&
+        sub_arch != other_sub_arch &&
+        llvm::AMDGPU::isSubArchCompatible(sub_arch, other_sub_arch) &&
+        (sub_arch == llvm::Triple::NoSubArch ||
+         sub_arch == llvm::AMDGPU::getMajorSubArch(sub_arch)))
+      GetTriple().setArch(llvm::Triple::amdgpu, other_sub_arch);
+  }
   if (!TripleEnvironmentWasSpecified() &&
       other.TripleEnvironmentWasSpecified()) {
     GetTriple().setEnvironment(other.GetTriple().getEnvironment());
@@ -1052,254 +877,14 @@ void ArchSpec::MergeFrom(const ArchSpec &other) {
 
 static llvm::StringRef GetAMDGPUVariantName(uint32_t sub) {
   switch (sub) {
-  case llvm::ELF::EF_AMDGPU_MACH_R600_R600:
-    return "r600";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_R630:
-    return "r630";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_RS880:
-    return "rs880";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_RV670:
-    return "rv670";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_RV710:
-    return "rv710";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_RV730:
-    return "rv730";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_RV770:
-    return "rv770";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_CEDAR:
-    return "cedar";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_CYPRESS:
-    return "cypress";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_JUNIPER:
-    return "juniper";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_REDWOOD:
-    return "redwood";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_SUMO:
-    return "sumo";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_BARTS:
-    return "barts";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_CAICOS:
-    return "caicos";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_CAYMAN:
-    return "cayman";
-  case llvm::ELF::EF_AMDGPU_MACH_R600_TURKS:
-    return "turks";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX600:
-    return "gfx600";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX601:
-    return "gfx601";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX602:
-    return "gfx602";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX700:
-    return "gfx700";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX701:
-    return "gfx701";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX702:
-    return "gfx702";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX703:
-    return "gfx703";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX704:
-    return "gfx704";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX705:
-    return "gfx705";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX801:
-    return "gfx801";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX802:
-    return "gfx802";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX803:
-    return "gfx803";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX805:
-    return "gfx805";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX810:
-    return "gfx810";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX900:
-    return "gfx900";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX902:
-    return "gfx902";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX904:
-    return "gfx904";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX906:
-    return "gfx906";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX908:
-    return "gfx908";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX909:
-    return "gfx909";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX90A:
-    return "gfx90a";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX90C:
-    return "gfx90c";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX942:
-    return "gfx942";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX950:
-    return "gfx950";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010:
-    return "gfx1010";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011:
-    return "gfx1011";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012:
-    return "gfx1012";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1013:
-    return "gfx1013";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030:
-    return "gfx1030";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1031:
-    return "gfx1031";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1032:
-    return "gfx1032";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1033:
-    return "gfx1033";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1034:
-    return "gfx1034";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1035:
-    return "gfx1035";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1036:
-    return "gfx1036";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1100:
-    return "gfx1100";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1101:
-    return "gfx1101";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1102:
-    return "gfx1102";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1103:
-    return "gfx1103";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1150:
-    return "gfx1150";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1151:
-    return "gfx1151";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1152:
-    return "gfx1152";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1153:
-    return "gfx1153";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1154:
-    return "gfx1154";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1170:
-    return "gfx1170";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1171:
-    return "gfx1171";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1172:
-    return "gfx1172";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1200:
-    return "gfx1200";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1201:
-    return "gfx1201";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1250_STRICT:
-    return "gfx1250-strict";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1250:
-    return "gfx1250";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1251:
-    return "gfx1251";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX1310:
-    return "gfx1310";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC:
-    return "gfx9-generic";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX9_4_GENERIC:
-    return "gfx9-4-generic";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC:
-    return "gfx10-1-generic";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC:
-    return "gfx10-3-generic";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC:
-    return "gfx11-generic";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC:
-    return "gfx12-generic";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX12_5_GENERIC:
-    return "gfx12-5-generic";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX11_7_GENERIC:
-    return "gfx11-7-generic";
-  case llvm::ELF::EF_AMDGPU_MACH_AMDGCN_GFX13_GENERIC:
-    return "gfx13-generic";
+#define X(NUM, ENUM, NAME)                                                     \
+  case llvm::ELF::ENUM:                                                        \
+    return NAME;
+    AMDGPU_MACH_LIST(X)
+#undef X
   default:
-    break;
+    return {};
   }
-  return llvm::StringRef("unknown");
-}
-
-static ArchSpec::Core GetAMDGPUVariantToCoreR600(llvm::StringRef core_name) {
-  return llvm::StringSwitch<ArchSpec::Core>(core_name)
-      .Case("r600", ArchSpec::eCore_amd_gpu_r600_R600)
-      .Case("r630", ArchSpec::eCore_amd_gpu_r600_R630)
-      .Case("rs880", ArchSpec::eCore_amd_gpu_r600_RS880)
-      .Case("rv670", ArchSpec::eCore_amd_gpu_r600_RV670)
-      .Case("rv710", ArchSpec::eCore_amd_gpu_r600_RV710)
-      .Case("rv730", ArchSpec::eCore_amd_gpu_r600_RV730)
-      .Case("rv770", ArchSpec::eCore_amd_gpu_r600_RV770)
-      .Case("cedar", ArchSpec::eCore_amd_gpu_r600_CEDAR)
-      .Case("cypress", ArchSpec::eCore_amd_gpu_r600_CYPRESS)
-      .Case("juniper", ArchSpec::eCore_amd_gpu_r600_JUNIPER)
-      .Case("redwood", ArchSpec::eCore_amd_gpu_r600_REDWOOD)
-      .Case("sumo", ArchSpec::eCore_amd_gpu_r600_SUMO)
-      .Case("barts", ArchSpec::eCore_amd_gpu_r600_BARTS)
-      .Case("caicos", ArchSpec::eCore_amd_gpu_r600_CAICOS)
-      .Case("cayman", ArchSpec::eCore_amd_gpu_r600_CAYMAN)
-      .Case("turks", ArchSpec::eCore_amd_gpu_r600_TURKS)
-      .Default(ArchSpec::eCore_amd_gpu_unknown);
-}
-
-static ArchSpec::Core GetAMDGPUVariantToCoreGCN(llvm::StringRef core_name) {
-  return llvm::StringSwitch<ArchSpec::Core>(core_name)
-      .Case("gfx600", ArchSpec::eCore_amd_gpu_gcn_GFX600)
-      .Case("gfx601", ArchSpec::eCore_amd_gpu_gcn_GFX601)
-      .Case("gfx602", ArchSpec::eCore_amd_gpu_gcn_GFX602)
-      .Case("gfx700", ArchSpec::eCore_amd_gpu_gcn_GFX700)
-      .Case("gfx701", ArchSpec::eCore_amd_gpu_gcn_GFX701)
-      .Case("gfx702", ArchSpec::eCore_amd_gpu_gcn_GFX702)
-      .Case("gfx703", ArchSpec::eCore_amd_gpu_gcn_GFX703)
-      .Case("gfx704", ArchSpec::eCore_amd_gpu_gcn_GFX704)
-      .Case("gfx705", ArchSpec::eCore_amd_gpu_gcn_GFX705)
-      .Case("gfx801", ArchSpec::eCore_amd_gpu_gcn_GFX801)
-      .Case("gfx802", ArchSpec::eCore_amd_gpu_gcn_GFX802)
-      .Case("gfx803", ArchSpec::eCore_amd_gpu_gcn_GFX803)
-      .Case("gfx805", ArchSpec::eCore_amd_gpu_gcn_GFX805)
-      .Case("gfx810", ArchSpec::eCore_amd_gpu_gcn_GFX810)
-      .Case("gfx900", ArchSpec::eCore_amd_gpu_gcn_GFX900)
-      .Case("gfx902", ArchSpec::eCore_amd_gpu_gcn_GFX902)
-      .Case("gfx904", ArchSpec::eCore_amd_gpu_gcn_GFX904)
-      .Case("gfx906", ArchSpec::eCore_amd_gpu_gcn_GFX906)
-      .Case("gfx908", ArchSpec::eCore_amd_gpu_gcn_GFX908)
-      .Case("gfx909", ArchSpec::eCore_amd_gpu_gcn_GFX909)
-      .Case("gfx90a", ArchSpec::eCore_amd_gpu_gcn_GFX90A)
-      .Case("gfx90c", ArchSpec::eCore_amd_gpu_gcn_GFX90C)
-      .Case("gfx942", ArchSpec::eCore_amd_gpu_gcn_GFX942)
-      .Case("gfx950", ArchSpec::eCore_amd_gpu_gcn_GFX950)
-      .Case("gfx1010", ArchSpec::eCore_amd_gpu_gcn_GFX1010)
-      .Case("gfx1011", ArchSpec::eCore_amd_gpu_gcn_GFX1011)
-      .Case("gfx1012", ArchSpec::eCore_amd_gpu_gcn_GFX1012)
-      .Case("gfx1013", ArchSpec::eCore_amd_gpu_gcn_GFX1013)
-      .Case("gfx1030", ArchSpec::eCore_amd_gpu_gcn_GFX1030)
-      .Case("gfx1031", ArchSpec::eCore_amd_gpu_gcn_GFX1031)
-      .Case("gfx1032", ArchSpec::eCore_amd_gpu_gcn_GFX1032)
-      .Case("gfx1033", ArchSpec::eCore_amd_gpu_gcn_GFX1033)
-      .Case("gfx1034", ArchSpec::eCore_amd_gpu_gcn_GFX1034)
-      .Case("gfx1035", ArchSpec::eCore_amd_gpu_gcn_GFX1035)
-      .Case("gfx1036", ArchSpec::eCore_amd_gpu_gcn_GFX1036)
-      .Case("gfx1100", ArchSpec::eCore_amd_gpu_gcn_GFX1100)
-      .Case("gfx1101", ArchSpec::eCore_amd_gpu_gcn_GFX1101)
-      .Case("gfx1102", ArchSpec::eCore_amd_gpu_gcn_GFX1102)
-      .Case("gfx1103", ArchSpec::eCore_amd_gpu_gcn_GFX1103)
-      .Case("gfx1150", ArchSpec::eCore_amd_gpu_gcn_GFX1150)
-      .Case("gfx1151", ArchSpec::eCore_amd_gpu_gcn_GFX1151)
-      .Case("gfx1152", ArchSpec::eCore_amd_gpu_gcn_GFX1152)
-      .Case("gfx1153", ArchSpec::eCore_amd_gpu_gcn_GFX1153)
-      .Case("gfx1154", ArchSpec::eCore_amd_gpu_gcn_GFX1154)
-      .Case("gfx1170", ArchSpec::eCore_amd_gpu_gcn_GFX1170)
-      .Case("gfx1171", ArchSpec::eCore_amd_gpu_gcn_GFX1171)
-      .Case("gfx1172", ArchSpec::eCore_amd_gpu_gcn_GFX1172)
-      .Case("gfx1200", ArchSpec::eCore_amd_gpu_gcn_GFX1200)
-      .Case("gfx1201", ArchSpec::eCore_amd_gpu_gcn_GFX1201)
-      .Case("gfx1250-strict", ArchSpec::eCore_amd_gpu_gcn_GFX1250_STRICT)
-      .Case("gfx1250", ArchSpec::eCore_amd_gpu_gcn_GFX1250)
-      .Case("gfx1251", ArchSpec::eCore_amd_gpu_gcn_GFX1251)
-      .Case("gfx1310", ArchSpec::eCore_amd_gpu_gcn_GFX1310)
-      .Case("gfx9-generic", ArchSpec::eCore_amd_gpu_gcn_GFX9_GENERIC)
-      .Case("gfx9-4-generic", ArchSpec::eCore_amd_gpu_gcn_GFX9_4_GENERIC)
-      .Case("gfx10-1-generic", ArchSpec::eCore_amd_gpu_gcn_GFX10_1_GENERIC)
-      .Case("gfx10-3-generic", ArchSpec::eCore_amd_gpu_gcn_GFX10_3_GENERIC)
-      .Case("gfx11-generic", ArchSpec::eCore_amd_gpu_gcn_GFX11_GENERIC)
-      .Case("gfx12-generic", ArchSpec::eCore_amd_gpu_gcn_GFX12_GENERIC)
-      .Case("gfx12-5-generic", ArchSpec::eCore_amd_gpu_gcn_GFX12_5_GENERIC)
-      .Case("gfx11-7-generic", ArchSpec::eCore_amd_gpu_gcn_GFX11_7_GENERIC)
-      .Case("gfx13-generic", ArchSpec::eCore_amd_gpu_gcn_GFX13_GENERIC)
-      .Default(ArchSpec::eCore_amd_gpu_unknown);
 }
 
 bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
@@ -1374,13 +959,17 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
           // failed...
           m_triple.setArch(core_def->machine);
           break;
-        case llvm::Triple::r600:
         case llvm::Triple::amdgpu: {
-          // AMDGPU arches are special: they append a 5th element to the triple
-          // that comes after the environment and contains the sub type name.
-          std::string environment("-");
-          environment += GetAMDGPUVariantName(arch_def_entry->sub);
-          m_triple.setEnvironmentName(environment);
+          llvm::StringRef gpu = GetAMDGPUVariantName(sub);
+          if (!gpu.empty()) {
+            llvm::Triple::SubArchType sub_arch =
+                llvm::AMDGPU::getSubArchFromGPUName(gpu);
+            if (sub_arch == llvm::Triple::NoSubArch) {
+              Clear();
+              return false;
+            }
+            m_triple.setArch(llvm::Triple::amdgpu, sub_arch);
+          }
           break;
         }
         default:
@@ -1452,6 +1041,16 @@ bool ArchSpec::IsMatch(const ArchSpec &rhs, MatchType match) const {
   const llvm::Triple &lhs_triple = GetTriple();
   const llvm::Triple &rhs_triple = rhs.GetTriple();
 
+  if (lhs_triple.getArch() == llvm::Triple::amdgpu &&
+      rhs_triple.getArch() == llvm::Triple::amdgpu) {
+    bool sub_arches_match =
+        match == ExactMatch
+            ? lhs_triple.getSubArch() == rhs_triple.getSubArch()
+            : llvm::AMDGPU::isSubArchCompatible(lhs_triple, rhs_triple);
+    if (!sub_arches_match)
+      return false;
+  }
+
   const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
   const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
 
@@ -1528,24 +1127,31 @@ bool ArchSpec::IsMatch(const ArchSpec &rhs, MatchType match) const {
 }
 
 void ArchSpec::UpdateCore() {
-  llvm::StringRef arch_name(m_triple.getArchName());
-  const CoreDefinition *core_def = FindCoreDefinition(arch_name);
+  const CoreDefinition *core_def;
+  if (m_triple.getArch() == llvm::Triple::amdgpu) {
+    core_def = FindCoreDefinition(eCore_amd_gpu);
+    if (m_triple.getSubArch() == llvm::Triple::NoSubArch) {
+      llvm::StringRef arch_name = m_triple.getArchName();
+      if (arch_name != "amdgpu" && arch_name != "amdgcn") {
+        Clear();
+        return;
+      }
+      llvm::StringRef gpu = m_triple.getEnvironmentName().split('-').second;
+      llvm::Triple::SubArchType sub_arch =
+          llvm::AMDGPU::getSubArchFromGPUName(gpu);
+      if (sub_arch != llvm::Triple::NoSubArch)
+        m_triple.setArch(llvm::Triple::amdgpu, sub_arch);
+    }
+  } else {
+    core_def = FindCoreDefinition(m_triple.getArchName());
+  }
+
   if (core_def) {
     m_core = core_def->core;
     // Set the byte order to the default byte order for an architecture. This
     // can be modified if needed for cases when cores handle both big and
     // little endian
     m_byte_order = core_def->default_byte_order;
-
-    // amdgpu/r600 match their first table entry (GFX600/R600), so refine the
-    // core from the model in the triple environment.
-    if (m_core == eCore_amd_gpu_gcn_GFX600) {
-      m_core = GetAMDGPUVariantToCoreGCN(
-          m_triple.getEnvironmentName().split('-').second);
-    } else if (m_core == eCore_amd_gpu_r600_R600) {
-      m_core = GetAMDGPUVariantToCoreR600(
-          m_triple.getEnvironmentName().split('-').second);
-    }
   } else {
     Clear();
   }
@@ -1882,11 +1488,16 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
 bool lldb_private::operator<(const ArchSpec &lhs, const ArchSpec &rhs) {
   const ArchSpec::Core lhs_core = lhs.GetCore();
   const ArchSpec::Core rhs_core = rhs.GetCore();
+  if (lhs_core == rhs_core && lhs_core == ArchSpec::eCore_amd_gpu)
+    return lhs.GetTriple().getSubArch() < rhs.GetTriple().getSubArch();
   return lhs_core < rhs_core;
 }
 
 bool lldb_private::operator==(const ArchSpec &lhs, const ArchSpec &rhs) {
-  return lhs.GetCore() == rhs.GetCore();
+  if (lhs.GetCore() != rhs.GetCore())
+    return false;
+  return lhs.GetCore() != ArchSpec::eCore_amd_gpu ||
+         lhs.GetTriple().getSubArch() == rhs.GetTriple().getSubArch();
 }
 
 bool lldb_private::operator!=(const ArchSpec &lhs, const ArchSpec &rhs) {
diff --git a/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp b/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
index 4126fbbbab156..d998a3d92a8c2 100644
--- a/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
+++ b/lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
@@ -25,8 +25,10 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/AMDGPUTargetParser.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
+#include <vector>
 
 using namespace lldb_private;
 using namespace lldb;
@@ -194,9 +196,8 @@ TEST_F(ObjectFileELFTest, GetModuleSpecifications_OffsetSizeWithOffsetFile) {
   EXPECT_EQ(FileSystem::Instance().GetByteSize(FileSpec(SO)), 4640UL);
 }
 
-// Verify an AMDGPU ELF header decodes to its exact GPU model.
-// An AMDGPU object with no decodable model resolves to the generic "unknown"
-// catch-all.
+// Verify that an AMDGPU ELF header without a decodable model still resolves to
+// the generic AMDGPU architecture.
 TEST_F(ObjectFileELFTest, GPUArchitectureUnknownAMDGPUModel) {
   // No model byte is parsed unless the OS ABI is AMDGPU HSA.
   {
@@ -220,7 +221,9 @@ TEST_F(ObjectFileELFTest, GPUArchitectureUnknownAMDGPUModel) {
     auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
     const ArchSpec &arch = module_sp->GetArchitecture();
     ASSERT_TRUE(arch.IsValid());
-    EXPECT_EQ(ArchSpec::eCore_amd_gpu_unknown, arch.GetCore());
+    EXPECT_EQ(ArchSpec::eCore_amd_gpu, arch.GetCore());
+    EXPECT_EQ(llvm::Triple::NoSubArch, arch.GetTriple().getSubArch());
+    EXPECT_TRUE(arch.GetClangTargetCPU().empty());
   }
 
   // HSA code-object v2 (ABIVersion 0) carries no model byte, so even a
@@ -248,7 +251,9 @@ TEST_F(ObjectFileELFTest, GPUArchitectureUnknownAMDGPUModel) {
     auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
     const ArchSpec &arch = module_sp->GetArchitecture();
     ASSERT_TRUE(arch.IsValid());
-    EXPECT_EQ(ArchSpec::eCore_amd_gpu_unknown, arch.GetCore());
+    EXPECT_EQ(ArchSpec::eCore_amd_gpu, arch.GetCore());
+    EXPECT_EQ(llvm::Triple::NoSubArch, arch.GetTriple().getSubArch());
+    EXPECT_TRUE(arch.GetClangTargetCPU().empty());
   }
 }
 
@@ -259,13 +264,21 @@ struct AMDGPUModel {
   const char *name; // Canonical model name, e.g. "gfx942".
 };
 
-// Every AMD GPU model, taken from llvm's AMDGPU_MACH_LIST so the tests track
-// the authoritative list instead of duplicating it.
-const AMDGPUModel kAMDGPUModels[] = {
+static std::vector<AMDGPUModel> GetAMDGPUModels() {
+  static constexpr AMDGPUModel all_models[] = {
 #define AMDGPU_MODEL(NUM, ENUM, NAME) {NUM, #ENUM, NAME},
-    AMDGPU_MACH_LIST(AMDGPU_MODEL)
+      AMDGPU_MACH_LIST(AMDGPU_MODEL)
 #undef AMDGPU_MODEL
-};
+  };
+
+  std::vector<AMDGPUModel> models;
+  for (const AMDGPUModel &model : all_models)
+    if (llvm::AMDGPU::parseArchAMDGCN(model.name) != llvm::AMDGPU::GK_NONE)
+      models.push_back(model);
+  return models;
+}
+
+const std::vector<AMDGPUModel> kAMDGPUModels = GetAMDGPUModels();
 
 std::string AMDGPUModelName(const testing::TestParamInfo<AMDGPUModel> &info) {
   // Test names allow only [A-Za-z0-9_]; the generic models contain dashes.
@@ -281,10 +294,13 @@ class ObjectFileELFAMDGPUTest
     : public ObjectFileELFTest,
       public ::testing::WithParamInterface<AMDGPUModel> {};
 
-// Every AMD GPU model must decode from an ELF header (built from YAML) to the
-// right arch and core. The model is the EF_AMDGPU_MACH value in e_flags.
+// Every AMDGPU model must decode from an ELF header (built from YAML) to the
+// right target-parser subarchitecture. The model is the EF_AMDGPU_MACH value
+// in e_flags.
 TEST_P(ObjectFileELFAMDGPUTest, DecodesAMDGPUModel) {
   const AMDGPUModel &model = GetParam();
+  llvm::AMDGPU::GPUKind kind = llvm::AMDGPU::parseArchAMDGCN(model.name);
+  ASSERT_NE(llvm::AMDGPU::GK_NONE, kind);
   const char *yaml_template = R"(--- !ELF
 FileHeader:
   Class:           ELFCLASS64
@@ -308,11 +324,10 @@ TEST_P(ObjectFileELFAMDGPUTest, DecodesAMDGPUModel) {
   auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
   const ArchSpec &arch = module_sp->GetArchitecture();
   ASSERT_TRUE(arch.IsValid());
-  EXPECT_NE(ArchSpec::eCore_amd_gpu_unknown, arch.GetCore());
-  EXPECT_EQ(model.name, arch.GetClangTargetCPU());
-  bool is_gcn = llvm::StringRef(model.name).starts_with("gfx");
-  EXPECT_EQ(is_gcn ? llvm::Triple::amdgpu : llvm::Triple::r600,
-            arch.GetTriple().getArch());
+  EXPECT_EQ(ArchSpec::eCore_amd_gpu, arch.GetCore());
+  EXPECT_EQ(llvm::AMDGPU::getArchNameAMDGCN(kind), arch.GetClangTargetCPU());
+  EXPECT_EQ(llvm::Triple::amdgpu, arch.GetTriple().getArch());
+  EXPECT_EQ(llvm::AMDGPU::getSubArch(kind), arch.GetTriple().getSubArch());
   EXPECT_EQ(llvm::Triple::AMD, arch.GetTriple().getVendor());
   EXPECT_EQ(llvm::Triple::AMDHSA, arch.GetTriple().getOS());
 }
diff --git a/lldb/unittests/Utility/ArchSpecTest.cpp b/lldb/unittests/Utility/ArchSpecTest.cpp
index 25ce85dd7f9f7..50f51fe63705b 100644
--- a/lldb/unittests/Utility/ArchSpecTest.cpp
+++ b/lldb/unittests/Utility/ArchSpecTest.cpp
@@ -12,6 +12,8 @@
 #include "lldb/lldb-defines.h"
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/BinaryFormat/MachO.h"
+#include "llvm/TargetParser/AMDGPUTargetParser.h"
+#include <vector>
 
 using namespace lldb;
 using namespace lldb_private;
@@ -162,13 +164,21 @@ struct AMDGPUModel {
   const char *name; // Canonical model name, e.g. "gfx942".
 };
 
-// Every AMD GPU model, taken from llvm's AMDGPU_MACH_LIST so the tests track
-// the authoritative list instead of duplicating it.
-const AMDGPUModel kAMDGPUModels[] = {
+static std::vector<AMDGPUModel> GetAMDGPUModels() {
+  static constexpr AMDGPUModel all_models[] = {
 #define AMDGPU_MODEL(NUM, ENUM, NAME) {NUM, #ENUM, NAME},
-    AMDGPU_MACH_LIST(AMDGPU_MODEL)
+      AMDGPU_MACH_LIST(AMDGPU_MODEL)
 #undef AMDGPU_MODEL
-};
+  };
+
+  std::vector<AMDGPUModel> models;
+  for (const AMDGPUModel &model : all_models)
+    if (llvm::AMDGPU::parseArchAMDGCN(model.name) != llvm::AMDGPU::GK_NONE)
+      models.push_back(model);
+  return models;
+}
+
+const std::vector<AMDGPUModel> kAMDGPUModels = GetAMDGPUModels();
 
 std::string AMDGPUModelName(const testing::TestParamInfo<AMDGPUModel> &info) {
   // Test names allow only [A-Za-z0-9_]; the generic models contain dashes.
@@ -182,44 +192,85 @@ std::string AMDGPUModelName(const testing::TestParamInfo<AMDGPUModel> &info) {
 
 class ArchSpecAMDGPUTest : public ::testing::TestWithParam<AMDGPUModel> {};
 
-// SetTriple() must resolve every AMD GPU triple to the right arch and core.
-// This exercises ArchSpec::UpdateCore(), which refines the core from the GPU
-// model in the triple environment.
+// SetTriple() must resolve every AMDGPU triple using TargetParser.
 TEST_P(ArchSpecAMDGPUTest, SetTriple) {
   const AMDGPUModel &model = GetParam();
-  bool is_gcn = llvm::StringRef(model.name).starts_with("gfx");
-  std::string triple =
-      (is_gcn ? "amdgpu" : "r600") + std::string("-amd-amdhsa--") + model.name;
+  llvm::AMDGPU::GPUKind kind = llvm::AMDGPU::parseArchAMDGCN(model.name);
+  ASSERT_NE(llvm::AMDGPU::GK_NONE, kind);
+  std::string triple = "amdgpu-amd-amdhsa--" + std::string(model.name);
 
   ArchSpec AS;
   EXPECT_TRUE(AS.SetTriple(triple));
-  EXPECT_EQ(is_gcn ? llvm::Triple::amdgpu : llvm::Triple::r600,
-            AS.GetTriple().getArch());
-  EXPECT_NE(ArchSpec::eCore_amd_gpu_unknown, AS.GetCore());
-  EXPECT_EQ(model.name, AS.GetClangTargetCPU());
+  EXPECT_EQ(llvm::Triple::amdgpu, AS.GetTriple().getArch());
+  EXPECT_EQ(llvm::AMDGPU::getSubArch(kind), AS.GetTriple().getSubArch());
+  EXPECT_EQ(ArchSpec::eCore_amd_gpu, AS.GetCore());
+  EXPECT_EQ(llvm::AMDGPU::getArchNameAMDGCN(kind), AS.GetClangTargetCPU());
+
+  std::string canonical_triple =
+      llvm::AMDGPU::getSubArchName(llvm::AMDGPU::getSubArch(kind)).str();
+  canonical_triple += "-amd-amdhsa";
+  ArchSpec canonical(canonical_triple);
+  EXPECT_TRUE(canonical.IsValid());
+  EXPECT_EQ(llvm::AMDGPU::getSubArch(kind), canonical.GetTriple().getSubArch());
+  EXPECT_EQ(llvm::AMDGPU::getArchNameAMDGCN(kind),
+            canonical.GetClangTargetCPU());
 }
 
-// SetArchitecture() from an ELF header must resolve every AMD GPU model to the
-// right arch, vendor, OS, sub type and core.
+// SetArchitecture() from an ELF header must resolve every AMDGPU model to the
+// right arch, vendor, OS, subarch and core.
 TEST_P(ArchSpecAMDGPUTest, SetArchitectureFromELF) {
   const AMDGPUModel &model = GetParam();
-  bool is_gcn = llvm::StringRef(model.name).starts_with("gfx");
+  llvm::AMDGPU::GPUKind kind = llvm::AMDGPU::parseArchAMDGCN(model.name);
+  ASSERT_NE(llvm::AMDGPU::GK_NONE, kind);
 
   ArchSpec AS;
   EXPECT_TRUE(AS.SetArchitecture(eArchTypeELF, llvm::ELF::EM_AMDGPU, model.mach,
                                  llvm::ELF::ELFOSABI_AMDGPU_HSA));
-  EXPECT_EQ(is_gcn ? llvm::Triple::amdgpu : llvm::Triple::r600,
-            AS.GetTriple().getArch());
+  EXPECT_EQ(llvm::Triple::amdgpu, AS.GetTriple().getArch());
+  EXPECT_EQ(llvm::AMDGPU::getSubArch(kind), AS.GetTriple().getSubArch());
   EXPECT_EQ(llvm::Triple::AMD, AS.GetTriple().getVendor());
   EXPECT_EQ(llvm::Triple::AMDHSA, AS.GetTriple().getOS());
-  EXPECT_EQ(model.mach, AS.GetElfCPUSubType());
-  EXPECT_NE(ArchSpec::eCore_amd_gpu_unknown, AS.GetCore());
-  EXPECT_EQ(model.name, AS.GetClangTargetCPU());
+  EXPECT_EQ(ArchSpec::eCore_amd_gpu, AS.GetCore());
+  EXPECT_EQ(llvm::AMDGPU::getArchNameAMDGCN(kind), AS.GetClangTargetCPU());
 }
 
 INSTANTIATE_TEST_SUITE_P(AMDGPU, ArchSpecAMDGPUTest,
                          ::testing::ValuesIn(kAMDGPUModels), AMDGPUModelName);
 
+TEST(ArchSpecTest, AMDGPUSubArchMatching) {
+  ArchSpec gfx9_4("amdgpu9.4-amd-amdhsa");
+  ArchSpec gfx942("amdgpu9.42-amd-amdhsa");
+  ArchSpec gfx950("amdgpu9.50-amd-amdhsa");
+  ArchSpec gfx1250("amdgpu12.50-amd-amdhsa");
+  ArchSpec gfx1250_strict("amdgpu12.50s-amd-amdhsa");
+  ArchSpec legacy_gfx942("amdgcn-amd-amdhsa--gfx942");
+
+  EXPECT_TRUE(gfx9_4.IsCompatibleMatch(gfx942));
+  EXPECT_TRUE(gfx9_4.IsCompatibleMatch(gfx950));
+  EXPECT_FALSE(gfx942.IsCompatibleMatch(gfx950));
+  EXPECT_FALSE(gfx942.IsExactMatch(gfx950));
+  EXPECT_FALSE(gfx1250.IsCompatibleMatch(gfx1250_strict));
+  EXPECT_NE(gfx1250, gfx1250_strict);
+  EXPECT_TRUE(legacy_gfx942.IsExactMatch(gfx942));
+
+  gfx9_4.MergeFrom(gfx942);
+  EXPECT_EQ(llvm::Triple::AMDGPUSubArch942, gfx9_4.GetTriple().getSubArch());
+  EXPECT_EQ("gfx942", gfx9_4.GetClangTargetCPU());
+}
+
+TEST(ArchSpecTest, R600IsUnsupported) {
+  ArchSpec AS;
+  EXPECT_FALSE(AS.SetTriple("r600-amd-amdhsa--r600"));
+  EXPECT_FALSE(AS.SetArchitecture(eArchTypeELF, llvm::ELF::EM_AMDGPU,
+                                  llvm::ELF::EF_AMDGPU_MACH_R600_R600,
+                                  llvm::ELF::ELFOSABI_AMDGPU_HSA));
+}
+
+TEST(ArchSpecTest, InvalidAMDGPUSubArchIsRejected) {
+  ArchSpec AS;
+  EXPECT_FALSE(AS.SetTriple("amdgpu999-amd-amdhsa"));
+}
+
 TEST(ArchSpecTest, MergeFrom) {
   {
     ArchSpec A;



More information about the lldb-commits mailing list