Author: Matt Arsenault Date: 2026-08-01T06:14:04Z New Revision: 3c3a18e239fcb79ad780cc95ac7554046876da2a
URL: https://github.com/llvm/llvm-project/commit/3c3a18e239fcb79ad780cc95ac7554046876da2a DIFF: https://github.com/llvm/llvm-project/commit/3c3a18e239fcb79ad780cc95ac7554046876da2a.diff LOG: clang: Store vendor GPU kinds in OffloadArch instead of re-listing GPUs (#213362) OffloadArch was a flat enum that hand-duplicated every AMDGPU and NVPTX target, plus a few edge cases. This was yet another place that needed updating every time a new target is added, which should now be avoided. Replace with a tagged union-like scheme. Co-authored-by: Claude (Claude-Opus-4.8) <[email protected]> Added: Modified: clang/include/clang/Basic/OffloadArch.h clang/include/clang/Driver/CudaInstallationDetector.h clang/lib/Basic/Cuda.cpp clang/lib/Basic/OffloadArch.cpp clang/lib/Basic/Targets/NVPTX.cpp clang/lib/Basic/Targets/NVPTX.h clang/lib/Driver/Driver.cpp clang/lib/Driver/OffloadBundler.cpp clang/lib/Driver/ToolChains/Cuda.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/test/Misc/target-invalid-cpu-note/nvptx.c clang/unittests/Basic/OffloadArchTest.cpp llvm/include/llvm/TargetParser/AMDGPUTargetParser.h llvm/include/llvm/TargetParser/NVPTXTargetParser.h Removed: ################################################################################ diff --git a/clang/include/clang/Basic/OffloadArch.h b/clang/include/clang/Basic/OffloadArch.h index 552f1b0316ccf..069352ea37f89 100644 --- a/clang/include/clang/Basic/OffloadArch.h +++ b/clang/include/clang/Basic/OffloadArch.h @@ -10,161 +10,121 @@ #define LLVM_CLANG_BASIC_OFFLOADARCH_H #include "llvm/ADT/StringRef.h" +#include <cstdint> #include <tuple> namespace llvm { class Triple; +template <typename T> class SmallVectorImpl; +namespace NVPTX { +enum GPUKind : uint8_t; +} +namespace AMDGPU { +enum GPUKind : uint8_t; +} } // namespace llvm namespace clang { -enum class OffloadArch { - Unused, - Unknown, - // TODO: Deprecate and remove GPU architectures older than sm_52. - SM_20, - SM_21, - SM_30, - // This has a name conflict with sys/mac.h on AIX, rename it as a workaround. - SM_32_, - SM_35, - SM_37, - SM_50, - SM_52, - SM_53, - SM_60, - SM_61, - SM_62, - SM_70, - SM_72, - SM_75, - SM_80, - SM_86, - SM_87, - SM_88, - SM_89, - SM_90, - SM_90a, - SM_100, - SM_100a, - SM_100f, - SM_101, - SM_101a, - SM_101f, - SM_103, - SM_103a, - SM_103f, - SM_110, - SM_110a, - SM_110f, - SM_120, - SM_120a, - SM_120f, - SM_121, - SM_121a, - SM_121f, - GFX600, - GFX601, - GFX602, - GFX700, - GFX701, - GFX702, - GFX703, - GFX704, - GFX705, - GFX801, - GFX802, - GFX803, - GFX805, - GFX810, - GFX9_GENERIC, - GFX900, - GFX902, - GFX904, - GFX906, - GFX908, - GFX909, - GFX90a, - GFX90c, - GFX9_4_GENERIC, - GFX942, - GFX950, - GFX10_1_GENERIC, - GFX1010, - GFX1011, - GFX1012, - GFX1013, - GFX10_3_GENERIC, - GFX1030, - GFX1031, - GFX1032, - GFX1033, - GFX1034, - GFX1035, - GFX1036, - GFX11_GENERIC, - GFX1100, - GFX1101, - GFX1102, - GFX1103, - GFX1150, - GFX1151, - GFX1152, - GFX1153, - GFX1154, - GFX11_7_GENERIC, - GFX1170, - GFX1171, - GFX1172, - GFX12_GENERIC, - GFX1200, - GFX1201, - GFX12_5_GENERIC, - GFX1250, - GFX1251, - GFX13_GENERIC, - GFX1310, - AMDGCNSPIRV, - Generic, // A processor model named 'generic' if the target backend defines a - // public one. - // Intel CPUs - GRANITERAPIDS, - // Intel GPUs - BMG_G21, - LAST = BMG_G21, - - CudaDefault = OffloadArch::SM_52, - HIPDefault = OffloadArch::GFX906, -}; - -static inline bool IsNVIDIAOffloadArch(OffloadArch A) { - return A >= OffloadArch::SM_20 && A < OffloadArch::GFX600; -} - -static inline bool IsAMDOffloadArch(OffloadArch A) { - // Generic processor model is for testing only. - return A >= OffloadArch::GFX600 && A < OffloadArch::Generic; -} +/// A processor an offloading action can target. This is a tagged handle pairing +/// a TargetArch with the matching TargetParser GPU kind; it does not enumerate +/// individual GPUs, so new targets are added in the TargetParser data alone. +class OffloadArch { +public: + enum class TargetArch : uint8_t { + Unused, // Default-constructed; no architecture bound. + Unknown, // A name that matched no known architecture. + NVPTX, // Kind is an llvm::NVPTX::GPUKind. + AMDGPU, // Kind is an llvm::AMDGPU::GPUKind. + SPIRV, // The 'amdgcnspirv' pseudo target. + IntelCPU, // Kind is an IntelArch. + IntelGPU, // Kind is an IntelArch. + Generic, // The 'generic' processor model. + }; + + // Intel architectures, which have no TargetParser list yet. + enum class IntelArch : uint32_t { + GRANITERAPIDS, + BMG_G21, + }; + +private: + // Interpreted according to V; unused for the tagless TargetArch values. + uint32_t Kind = 0; + TargetArch V = TargetArch::Unused; + + constexpr OffloadArch(TargetArch V, uint32_t Kind) : Kind(Kind), V(V) {} + +public: + constexpr OffloadArch() = default; + + static OffloadArch getNVPTX(llvm::NVPTX::GPUKind K) { + return {TargetArch::NVPTX, static_cast<uint32_t>(K)}; + } + static OffloadArch getAMDGPU(llvm::AMDGPU::GPUKind K) { + return {TargetArch::AMDGPU, static_cast<uint32_t>(K)}; + } + static constexpr OffloadArch getIntel(TargetArch V, IntelArch A) { + return {V, static_cast<uint32_t>(A)}; + } + static constexpr OffloadArch getUnused() { return {TargetArch::Unused, 0}; } + static constexpr OffloadArch getUnknown() { return {TargetArch::Unknown, 0}; } + static constexpr OffloadArch getSPIRV() { return {TargetArch::SPIRV, 0}; } + static constexpr OffloadArch getGeneric() { return {TargetArch::Generic, 0}; } + + /// Default architectures used when the user does not specify one. + static OffloadArch CudaDefault(); + static OffloadArch HIPDefault(); + + TargetArch targetArch() const { return V; } + + bool isNVPTX() const { return V == TargetArch::NVPTX; } + bool isAMDGPU() const { return V == TargetArch::AMDGPU; } + bool isSPIRV() const { return V == TargetArch::SPIRV; } + bool isIntelCPU() const { return V == TargetArch::IntelCPU; } + bool isIntelGPU() const { return V == TargetArch::IntelGPU; } + bool isIntel() const { return isIntelCPU() || isIntelGPU(); } + bool isGeneric() const { return V == TargetArch::Generic; } + bool isUnused() const { return V == TargetArch::Unused; } + bool isUnknown() const { return V == TargetArch::Unknown; } + + // Only valid when isNVPTX() / isAMDGPU() respectively. + llvm::NVPTX::GPUKind nvptxKind() const { + return static_cast<llvm::NVPTX::GPUKind>(Kind); + } + llvm::AMDGPU::GPUKind amdgpuKind() const { + return static_cast<llvm::AMDGPU::GPUKind>(Kind); + } -static inline bool IsIntelCPUOffloadArch(OffloadArch Arch) { - return Arch >= OffloadArch::GRANITERAPIDS && Arch < OffloadArch::BMG_G21; -} + bool operator==(const OffloadArch &Other) const { + return V == Other.V && Kind == Other.Kind; + } + bool operator!=(const OffloadArch &Other) const { return !(*this == Other); } -static inline bool IsIntelGPUOffloadArch(OffloadArch Arch) { - return Arch >= OffloadArch::BMG_G21 && Arch <= OffloadArch::LAST; -} + bool operator<(const OffloadArch &Other) const { + return std::tie(V, Kind) < std::tie(Other.V, Other.Kind); + } +}; -static inline bool IsIntelOffloadArch(OffloadArch Arch) { - return IsIntelCPUOffloadArch(Arch) || IsIntelGPUOffloadArch(Arch); +inline bool IsNVIDIAOffloadArch(OffloadArch A) { return A.isNVPTX(); } +inline bool IsAMDOffloadArch(OffloadArch A) { + // amdgcnspirv is compiled through the AMDGPU toolchain. + return A.isAMDGPU() || A.isSPIRV(); } +inline bool IsIntelCPUOffloadArch(OffloadArch A) { return A.isIntelCPU(); } +inline bool IsIntelGPUOffloadArch(OffloadArch A) { return A.isIntelGPU(); } +inline bool IsIntelOffloadArch(OffloadArch A) { return A.isIntel(); } const char *OffloadArchToString(OffloadArch A); const char *OffloadArchToVirtualArchString(OffloadArch A); -// Convert a string to an OffloadArch enum value. Returns -// OffloadArch::Unknown if the string is not recognized. +// Convert a string to an OffloadArch. Returns an Unknown OffloadArch if the +// string is not recognized. OffloadArch StringToOffloadArch(llvm::StringRef S); +/// Append the canonical names of all NVIDIA and AMDGPU GPUs. +void fillValidOffloadArchList(llvm::SmallVectorImpl<llvm::StringRef> &Values); + llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple, OffloadArch ID); @@ -173,19 +133,19 @@ llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple, struct BoundArch { llvm::StringRef ArchName; - /// The parsed offload architecture enum. - /// Will be OffloadArch::Unknown if ArchName not recognized. - OffloadArch Arch = OffloadArch::Unused; + /// The parsed offload architecture. + /// Will be an Unknown OffloadArch if ArchName is not recognized. + OffloadArch Arch = OffloadArch::getUnused(); BoundArch() = default; explicit BoundArch(llvm::StringRef Name) - : ArchName(Name), - Arch(Name.empty() ? OffloadArch::Unknown : StringToOffloadArch(Name)) {} + : ArchName(Name), Arch(Name.empty() ? OffloadArch::getUnknown() + : StringToOffloadArch(Name)) {} BoundArch(llvm::StringRef Name, OffloadArch A) : ArchName(Name), Arch(A) {} bool empty() const { return ArchName.empty(); } - explicit operator bool() const { return Arch != OffloadArch::Unused; } + explicit operator bool() const { return !Arch.isUnused(); } bool operator==(const BoundArch &Other) const { return Arch == Other.Arch && ArchName == Other.ArchName; diff --git a/clang/include/clang/Driver/CudaInstallationDetector.h b/clang/include/clang/Driver/CudaInstallationDetector.h index 0fecbfe069ca4..98abec7d924bb 100644 --- a/clang/include/clang/Driver/CudaInstallationDetector.h +++ b/clang/include/clang/Driver/CudaInstallationDetector.h @@ -11,6 +11,7 @@ #include "clang/Basic/Cuda.h" #include "clang/Driver/Driver.h" +#include "llvm/TargetParser/NVPTXTargetParser.h" #include <bitset> namespace clang { @@ -28,9 +29,9 @@ class CudaInstallationDetector { std::string IncludePath; llvm::StringMap<std::string> LibDeviceMap; - // CUDA architectures for which we have raised an error in - // CheckCudaVersionSupportsArch. - mutable std::bitset<(int)OffloadArch::LAST> ArchsWithBadVersion; + // NVIDIA architectures (indexed by GPUKind) for which we have raised an error + // in CheckCudaVersionSupportsArch. + mutable std::bitset<llvm::NVPTX::GK_LAST + 1> ArchsWithBadVersion; public: CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, diff --git a/clang/lib/Basic/Cuda.cpp b/clang/lib/Basic/Cuda.cpp index b61d890e23dfe..06c02bd541df3 100644 --- a/clang/lib/Basic/Cuda.cpp +++ b/clang/lib/Basic/Cuda.cpp @@ -4,6 +4,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/VersionTuple.h" #include "llvm/TargetParser/NVPTXTargetParser.h" +#include <cassert> namespace clang { @@ -78,16 +79,16 @@ CudaVersion ToCudaVersion(llvm::VersionTuple Version) { } CudaVersion MinVersionForOffloadArch(OffloadArch A) { - if (A == OffloadArch::Unknown) + if (A.isUnknown()) return CudaVersion::UNKNOWN; // AMD GPUs do not depend on CUDA versions. if (IsAMDOffloadArch(A)) return CudaVersion::CUDA_70; - switch (A) { + switch (A.nvptxKind()) { #define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \ - case OffloadArch::KIND: \ + case llvm::NVPTX::GK_##KIND: \ return CudaVersion::MIN_VER; #include "llvm/TargetParser/NVPTXTargetParser.def" default: @@ -100,11 +101,12 @@ CudaVersion MaxVersionForOffloadArch(OffloadArch A) { if (IsAMDOffloadArch(A)) return CudaVersion::NEW; - switch (A) { - case OffloadArch::Unknown: + if (!A.isNVPTX()) return CudaVersion::UNKNOWN; + + switch (A.nvptxKind()) { #define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \ - case OffloadArch::KIND: \ + case llvm::NVPTX::GK_##KIND: \ return CudaVersion::MAX_VER; #include "llvm/TargetParser/NVPTXTargetParser.def" default: @@ -127,33 +129,15 @@ bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) { } unsigned CudaArchToID(OffloadArch Arch) { - switch (Arch) { -#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \ - case OffloadArch::KIND: \ - return SM_ID; -#include "llvm/TargetParser/NVPTXTargetParser.def" - default: - break; - } - llvm_unreachable("invalid NVIDIA GPU architecture"); -} - -static llvm::NVPTX::GPUKind OffloadArchToNVPTXKind(OffloadArch Arch) { - switch (Arch) { -#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \ - case OffloadArch::KIND: \ - return llvm::NVPTX::GK_##KIND; -#include "llvm/TargetParser/NVPTXTargetParser.def" - default: - return llvm::NVPTX::GK_NONE; - } + assert(Arch.isNVPTX() && "invalid NVIDIA GPU architecture"); + return llvm::NVPTX::getSmVersion(Arch.nvptxKind()); } bool IsNVIDIAAcceleratedOffloadArch(OffloadArch Arch) { - return llvm::NVPTX::isAcceleratedArch(OffloadArchToNVPTXKind(Arch)); + return Arch.isNVPTX() && llvm::NVPTX::isAcceleratedArch(Arch.nvptxKind()); } bool IsNVIDIAFamilySpecificOffloadArch(OffloadArch Arch) { - return llvm::NVPTX::isFamilySpecificArch(OffloadArchToNVPTXKind(Arch)); + return Arch.isNVPTX() && llvm::NVPTX::isFamilySpecificArch(Arch.nvptxKind()); } } // namespace clang diff --git a/clang/lib/Basic/OffloadArch.cpp b/clang/lib/Basic/OffloadArch.cpp index 5d12f257f3680..55a0564cff89d 100644 --- a/clang/lib/Basic/OffloadArch.cpp +++ b/clang/lib/Basic/OffloadArch.cpp @@ -7,164 +7,101 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/OffloadArch.h" -#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/TargetParser/AMDGPUTargetParser.h" +#include "llvm/TargetParser/NVPTXTargetParser.h" #include "llvm/TargetParser/Triple.h" namespace clang { -namespace { -struct OffloadArchToStringMap { - OffloadArch Arch; - const char *ArchName; - const char *VirtualArchName; -}; -} // namespace +OffloadArch OffloadArch::CudaDefault() { + return getNVPTX(llvm::NVPTX::parseArch("sm_52")); +} -#define SM(sm) {OffloadArch::SM_##sm, "sm_" #sm, "compute_" #sm} -#define GFX(gpu) {OffloadArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn"} -static const OffloadArchToStringMap ArchNames[] = { - // clang-format off - {OffloadArch::Unused, "", ""}, - SM(20), {OffloadArch::SM_21, "sm_21", "compute_20"}, // Fermi - SM(30), {OffloadArch::SM_32_, "sm_32", "compute_32"}, SM(35), SM(37), // Kepler - SM(50), SM(52), SM(53), // Maxwell - SM(60), SM(61), SM(62), // Pascal - SM(70), SM(72), // Volta - SM(75), // Turing - SM(80), SM(86), // Ampere - SM(87), // Jetson/Drive AGX Orin - SM(88), // Ampere - SM(89), // Ada Lovelace - SM(90), // Hopper - SM(90a), // Hopper - SM(100), // Blackwell - SM(100a), // Blackwell - SM(100f), // Blackwell - SM(101), // Blackwell - SM(101a), // Blackwell - SM(101f), // Blackwell - SM(103), // Blackwell - SM(103a), // Blackwell - SM(103f), // Blackwell - SM(110), // Blackwell - SM(110a), // Blackwell - SM(110f), // Blackwell - SM(120), // Blackwell - SM(120a), // Blackwell - SM(120f), // Blackwell - SM(121), // Blackwell - SM(121a), // Blackwell - SM(121f), // Blackwell - GFX(600), // gfx600 - GFX(601), // gfx601 - GFX(602), // gfx602 - GFX(700), // gfx700 - GFX(701), // gfx701 - GFX(702), // gfx702 - GFX(703), // gfx703 - GFX(704), // gfx704 - GFX(705), // gfx705 - GFX(801), // gfx801 - GFX(802), // gfx802 - GFX(803), // gfx803 - GFX(805), // gfx805 - GFX(810), // gfx810 - {OffloadArch::GFX9_GENERIC, "gfx9-generic", "compute_amdgcn"}, - GFX(900), // gfx900 - GFX(902), // gfx902 - GFX(904), // gfx903 - GFX(906), // gfx906 - GFX(908), // gfx908 - GFX(909), // gfx909 - GFX(90a), // gfx90a - GFX(90c), // gfx90c - {OffloadArch::GFX9_4_GENERIC, "gfx9-4-generic", "compute_amdgcn"}, - GFX(942), // gfx942 - GFX(950), // gfx950 - {OffloadArch::GFX10_1_GENERIC, "gfx10-1-generic", "compute_amdgcn"}, - GFX(1010), // gfx1010 - GFX(1011), // gfx1011 - GFX(1012), // gfx1012 - GFX(1013), // gfx1013 - {OffloadArch::GFX10_3_GENERIC, "gfx10-3-generic", "compute_amdgcn"}, - GFX(1030), // gfx1030 - GFX(1031), // gfx1031 - GFX(1032), // gfx1032 - GFX(1033), // gfx1033 - GFX(1034), // gfx1034 - GFX(1035), // gfx1035 - GFX(1036), // gfx1036 - {OffloadArch::GFX11_GENERIC, "gfx11-generic", "compute_amdgcn"}, - GFX(1100), // gfx1100 - GFX(1101), // gfx1101 - GFX(1102), // gfx1102 - GFX(1103), // gfx1103 - GFX(1150), // gfx1150 - GFX(1151), // gfx1151 - GFX(1152), // gfx1152 - GFX(1153), // gfx1153 - GFX(1154), // gfx1154 - {OffloadArch::GFX11_7_GENERIC, "gfx11-7-generic", "compute_amdgcn"}, - GFX(1170), // gfx1170 - GFX(1171), // gfx1171 - GFX(1172), // gfx1172 - {OffloadArch::GFX12_GENERIC, "gfx12-generic", "compute_amdgcn"}, - GFX(1200), // gfx1200 - GFX(1201), // gfx1201 - {OffloadArch::GFX12_5_GENERIC, "gfx12-5-generic", "compute_amdgcn"}, - GFX(1250), // gfx1250 - GFX(1251), // gfx1251 - {OffloadArch::GFX13_GENERIC, "gfx13-generic", "compute_amdgcn"}, - GFX(1310), // gfx1310 - {OffloadArch::AMDGCNSPIRV, "amdgcnspirv", "compute_amdgcn"}, - // Intel CPUs - {OffloadArch::GRANITERAPIDS, "graniterapids", ""}, - // Intel GPUS - {OffloadArch::BMG_G21, "bmg_g21", ""}, - {OffloadArch::Generic, "generic", ""}, - // clang-format on -}; -#undef SM -#undef GFX +OffloadArch OffloadArch::HIPDefault() { + return getAMDGPU(llvm::AMDGPU::parseArchAMDGCN("gfx906")); +} const char *OffloadArchToString(OffloadArch A) { - auto Result = - llvm::find_if(ArchNames, [A](const OffloadArchToStringMap &Map) { - return A == Map.Arch; - }); - if (Result == std::end(ArchNames)) + switch (A.targetArch()) { + case OffloadArch::TargetArch::Unused: + return ""; + case OffloadArch::TargetArch::Unknown: return "unknown"; - return Result->ArchName; + case OffloadArch::TargetArch::NVPTX: + return llvm::NVPTX::getArchName(A.nvptxKind()).data(); + case OffloadArch::TargetArch::AMDGPU: + return llvm::AMDGPU::getArchNameAMDGCN(A.amdgpuKind()).data(); + case OffloadArch::TargetArch::SPIRV: + return "amdgcnspirv"; + case OffloadArch::TargetArch::IntelCPU: + return "graniterapids"; + case OffloadArch::TargetArch::IntelGPU: + return "bmg_g21"; + case OffloadArch::TargetArch::Generic: + return "generic"; + } + return "unknown"; } const char *OffloadArchToVirtualArchString(OffloadArch A) { - auto Result = - llvm::find_if(ArchNames, [A](const OffloadArchToStringMap &Map) { - return A == Map.Arch; - }); - if (Result == std::end(ArchNames)) + switch (A.targetArch()) { + case OffloadArch::TargetArch::NVPTX: + return llvm::NVPTX::getVirtualArch(A.nvptxKind()).data(); + case OffloadArch::TargetArch::AMDGPU: + case OffloadArch::TargetArch::SPIRV: + return "compute_amdgcn"; + case OffloadArch::TargetArch::Unknown: return "unknown"; - return Result->VirtualArchName; + case OffloadArch::TargetArch::Unused: + case OffloadArch::TargetArch::IntelCPU: + case OffloadArch::TargetArch::IntelGPU: + case OffloadArch::TargetArch::Generic: + return ""; + } + return "unknown"; } OffloadArch StringToOffloadArch(llvm::StringRef S) { - auto Result = - llvm::find_if(ArchNames, [S](const OffloadArchToStringMap &Map) { - return S == Map.ArchName; - }); - if (Result == std::end(ArchNames)) - return OffloadArch::Unknown; - return Result->Arch; + // The empty string denotes the "unused" architecture. + if (S.empty()) + return OffloadArch::getUnused(); + + // Non-GPU-table pseudo/sentinel architectures. + if (S == "amdgcnspirv") + return OffloadArch::getSPIRV(); + if (S == "generic") + return OffloadArch::getGeneric(); + if (S == "graniterapids") + return OffloadArch::getIntel(OffloadArch::TargetArch::IntelCPU, + OffloadArch::IntelArch::GRANITERAPIDS); + if (S == "bmg_g21") + return OffloadArch::getIntel(OffloadArch::TargetArch::IntelGPU, + OffloadArch::IntelArch::BMG_G21); + + // Otherwise defer to the vendor TargetParser GPU lists. + if (llvm::NVPTX::GPUKind NV = llvm::NVPTX::parseArch(S)) + return OffloadArch::getNVPTX(NV); + if (llvm::AMDGPU::GPUKind AK = llvm::AMDGPU::parseArchAMDGCN(S)) + return OffloadArch::getAMDGPU(AK); + return OffloadArch::getUnknown(); +} + +void fillValidOffloadArchList(llvm::SmallVectorImpl<llvm::StringRef> &Values) { +#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \ + Values.push_back(NAME); +#include "llvm/TargetParser/NVPTXTargetParser.def" + llvm::AMDGPU::fillValidArchListAMDGCN(Values, llvm::Triple::NoSubArch); } llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple, OffloadArch ID) { - if (ID == OffloadArch::AMDGCNSPIRV) + if (ID.isSPIRV()) return llvm::Triple(llvm::Triple::spirv64, llvm::Triple::NoSubArch, llvm::Triple::AMD, llvm::Triple::AMDHSA); - if (IsNVIDIAOffloadArch(ID)) { + if (ID.isNVPTX()) { llvm::Triple::ArchType Arch = DefaultToolchainTriple.isArch64Bit() ? llvm::Triple::nvptx64 : llvm::Triple::nvptx; @@ -172,7 +109,7 @@ llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple, llvm::Triple::CUDA); } - if (IsAMDOffloadArch(ID)) + if (ID.isAMDGPU()) return llvm::Triple("amdgcn-amd-amdhsa"); return {}; diff --git a/clang/lib/Basic/Targets/NVPTX.cpp b/clang/lib/Basic/Targets/NVPTX.cpp index 2e1d9abac8320..d2fed6a2f9787 100644 --- a/clang/lib/Basic/Targets/NVPTX.cpp +++ b/clang/lib/Basic/Targets/NVPTX.cpp @@ -64,7 +64,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, // Define available target features // These must be defined in sorted order! NoAsmVariants = true; - GPU = OffloadArch::Unused; + GPU = OffloadArch::getUnused(); // PTX supports f16 as a fundamental type. HasFastHalfType = true; diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index 72941fd65fda8..996b1a9730606 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -72,7 +72,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo { initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const override { - if (GPU != OffloadArch::Unused) + if (!GPU.isUnused()) Features[OffloadArchToString(GPU)] = true; // Only add PTX feature if explicitly requested. Otherwise, let the backend // use the minimum required PTX version for the target SM. @@ -131,18 +131,16 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo { } bool isValidCPUName(StringRef Name) const override { - return StringToOffloadArch(Name) != OffloadArch::Unknown; + return !StringToOffloadArch(Name).isUnknown(); } void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override { - for (int i = static_cast<int>(OffloadArch::SM_20); - i < static_cast<int>(OffloadArch::Generic); ++i) - Values.emplace_back(OffloadArchToString(static_cast<OffloadArch>(i))); + fillValidOffloadArchList(Values); } bool setCPU(StringRef Name) override { GPU = StringToOffloadArch(Name); - return GPU != OffloadArch::Unknown; + return !GPU.isUnknown(); } void setSupportedOpenCLOpts() override { diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 38795f7c2ae7a..5bd46db170d96 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -961,7 +961,7 @@ static TripleSet inferOffloadToolchains(Compilation &C, TripleSet Triples; for (llvm::StringRef Arch : Archs) { OffloadArch ID = StringToOffloadArch(Arch); - if (ID == OffloadArch::Unknown) + if (ID.isUnknown()) ID = StringToOffloadArch( getProcessorFromTargetID(llvm::Triple("amdgcn-amd-amdhsa"), Arch)); @@ -975,13 +975,12 @@ static TripleSet inferOffloadToolchains(Compilation &C, << "CUDA" << Arch; return {}; } - if (Kind == Action::OFK_OpenMP && - (ID == OffloadArch::Unknown || ID == OffloadArch::Unused)) { + if (Kind == Action::OFK_OpenMP && (ID.isUnknown() || ID.isUnused())) { C.getDriver().Diag(clang::diag::err_drv_failed_to_deduce_target_from_arch) << Arch; return {}; } - if (ID == OffloadArch::Unknown || ID == OffloadArch::Unused) { + if (ID.isUnknown() || ID.isUnused()) { C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) << "offload" << Arch; return {}; @@ -3466,7 +3465,7 @@ class OffloadingActionBuilder final { bool Relocatable = false; /// Default GPU architecture if there's no one specified. - OffloadArch DefaultOffloadArch = OffloadArch::Unknown; + OffloadArch DefaultOffloadArch = OffloadArch::getUnknown(); /// Compilation unit ID specified by option '-fuse-cuid=' or'-cuid='. const CUIDOptions &CUIDOpts; @@ -3644,7 +3643,7 @@ class OffloadingActionBuilder final { CudaActionBuilder(Compilation &C, DerivedArgList &Args, const InputList &Inputs) : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_Cuda) { - DefaultOffloadArch = OffloadArch::CudaDefault; + DefaultOffloadArch = OffloadArch::CudaDefault(); } ActionBuilderReturnCode @@ -3769,7 +3768,7 @@ class OffloadingActionBuilder final { const InputList &Inputs) : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP) { - DefaultOffloadArch = OffloadArch::HIPDefault; + DefaultOffloadArch = OffloadArch::HIPDefault(); if (Args.hasArg(options::OPT_fhip_emit_relocatable, options::OPT_fno_hip_emit_relocatable)) { @@ -4882,13 +4881,12 @@ static StringRef getCanonicalArchString(Compilation &C, // expecting the triple to be only NVPTX / AMDGPU. OffloadArch Arch = StringToOffloadArch(getProcessorFromTargetID(Triple, ArchStr)); - if (Triple.isNVPTX() && - (Arch == OffloadArch::Unknown || !IsNVIDIAOffloadArch(Arch))) { + if (Triple.isNVPTX() && (Arch.isUnknown() || !IsNVIDIAOffloadArch(Arch))) { C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) << "CUDA" << ArchStr; return StringRef(); } else if (Triple.isAMDGPU() && - (Arch == OffloadArch::Unknown || !IsAMDOffloadArch(Arch))) { + (Arch.isUnknown() || !IsAMDOffloadArch(Arch))) { C.getDriver().Diag(clang::diag::err_drv_offload_bad_gpu_arch) << "HIP" << ArchStr; return StringRef(); @@ -4992,12 +4990,12 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, if (Archs.empty()) { if (Kind == Action::OFK_Cuda) { Archs.insert(OffloadArchToString(TC.getTriple().isSPIRV() - ? OffloadArch::Unused - : OffloadArch::CudaDefault)); + ? OffloadArch::getUnused() + : OffloadArch::CudaDefault())); } else if (Kind == Action::OFK_HIP) { Archs.insert(OffloadArchToString(TC.getTriple().isSPIRV() - ? OffloadArch::Generic - : OffloadArch::HIPDefault)); + ? OffloadArch::getGeneric() + : OffloadArch::HIPDefault())); } else if (Kind == Action::OFK_SYCL) { Archs.insert(StringRef()); } else if (Kind == Action::OFK_OpenMP) { diff --git a/clang/lib/Driver/OffloadBundler.cpp b/clang/lib/Driver/OffloadBundler.cpp index 8e4d44071ef55..b397ee4c5b075 100644 --- a/clang/lib/Driver/OffloadBundler.cpp +++ b/clang/lib/Driver/OffloadBundler.cpp @@ -83,8 +83,7 @@ OffloadTargetInfo::OffloadTargetInfo(const StringRef Target, StringRef TargetIdWithFeature = Components.size() == 6 ? Components.back() : ""; StringRef TargetId = TargetIdWithFeature.split(':').first; - if (!TargetId.empty() && - clang::StringToOffloadArch(TargetId) != clang::OffloadArch::Unknown) + if (!TargetId.empty() && !clang::StringToOffloadArch(TargetId).isUnknown()) this->TargetID = TargetIdWithFeature; else this->TargetID = ""; diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index b7e257b2c0207..93e335ca8bb82 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -235,14 +235,12 @@ CudaInstallationDetector::CudaInstallationDetector( // CUDA-9+ uses single libdevice file for all GPU variants. std::string FilePath = LibDevicePath + "/libdevice.10.bc"; if (FS.exists(FilePath)) { - for (int Arch = (int)OffloadArch::SM_30, E = (int)OffloadArch::LAST; - Arch < E; ++Arch) { - OffloadArch OA = static_cast<OffloadArch>(Arch); - if (!IsNVIDIAOffloadArch(OA)) - continue; - std::string OffloadArchName(OffloadArchToString(OA)); - LibDeviceMap[OffloadArchName] = FilePath; - } + // CUDA-9+ uses a single libdevice file for every NVIDIA GPU variant + // (sm_30 and newer). +#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \ + if ((SM_ID) >= 300) \ + LibDeviceMap[NAME] = FilePath; +#include "llvm/TargetParser/NVPTXTargetParser.def" } } else { std::error_code EC; @@ -326,14 +324,15 @@ void CudaInstallationDetector::AddCudaIncludeArgs( void CudaInstallationDetector::CheckCudaVersionSupportsArch( OffloadArch Arch) const { - if (Arch == OffloadArch::Unknown || Version == CudaVersion::UNKNOWN || - ArchsWithBadVersion[(int)Arch]) + // Only NVIDIA architectures depend on the CUDA toolkit version. + if (!Arch.isNVPTX() || Version == CudaVersion::UNKNOWN || + ArchsWithBadVersion[Arch.nvptxKind()]) return; auto MinVersion = MinVersionForOffloadArch(Arch); auto MaxVersion = MaxVersionForOffloadArch(Arch); if (Version < MinVersion || Version > MaxVersion) { - ArchsWithBadVersion[(int)Arch] = true; + ArchsWithBadVersion[Arch.nvptxKind()] = true; D.Diag(diag::err_drv_cuda_version_unsupported) << OffloadArchToString(Arch) << CudaVersionToString(MinVersion) << CudaVersionToString(MaxVersion) << InstallPath @@ -414,7 +413,7 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, } // Obtain architecture from the action. - assert(GPUArch.Arch != OffloadArch::Unknown && + assert(!GPUArch.Arch.isUnknown() && "Device action expected to have an architecture."); // Check that our installation's ptxas supports gpu_arch. @@ -778,7 +777,7 @@ NVPTXToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, if (!DAL->hasArg(options::OPT_march_EQ) && OffloadKind != Action::OFK_None) { DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), - OffloadArchToString(OffloadArch::CudaDefault)); + OffloadArchToString(OffloadArch::CudaDefault())); } else if (DAL->getLastArgValue(options::OPT_march_EQ) == "generic" && OffloadKind == Action::OFK_None) { DAL->eraseArg(options::OPT_march_EQ); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 492b125587344..690821a8e9ef9 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -72,6 +72,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/NVPTXTargetParser.h" #include "llvm/TargetParser/Triple.h" #include <optional> @@ -6129,8 +6130,8 @@ Sema::CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads, // launch bounds attribute within ompx_attribute to support other archs. if (!IgnoreArch) { // '.maxclusterrank' ptx directive requires .target sm_90 or higher. - auto SM = getOffloadArch(Context.getTargetInfo()); - if (SM == OffloadArch::Unknown || SM < OffloadArch::SM_90) { + OffloadArch SM = getOffloadArch(Context.getTargetInfo()); + if (SM.isUnknown() || llvm::NVPTX::getSmVersion(SM.nvptxKind()) < 900) { Diag(MaxBlocks->getBeginLoc(), diag::warn_cuda_maxclusterrank_sm_90) << OffloadArchToString(SM) << CI << MaxBlocks->getSourceRange(); // Ignore it by setting MaxBlocks to null; @@ -6244,7 +6245,8 @@ void Sema::addNoClusterAttr(Decl *D, const AttributeCommonInfo &CI) { static void handleClusterDimsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { const TargetInfo &TTI = S.Context.getTargetInfo(); OffloadArch Arch = StringToOffloadArch(TTI.getTargetOpts().CPU); - if ((TTI.getTriple().isNVPTX() && Arch < clang::OffloadArch::SM_90) || + if ((TTI.getTriple().isNVPTX() && + llvm::NVPTX::getSmVersion(Arch.nvptxKind()) < 900) || (TTI.getTriple().isAMDGPU() && !TTI.hasFeatureEnabled(TTI.getTargetOpts().FeatureMap, "clusters"))) { S.Diag(AL.getLoc(), diag::err_cluster_attr_not_supported) << AL; @@ -6263,7 +6265,8 @@ static void handleClusterDimsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { static void handleNoClusterAttr(Sema &S, Decl *D, const ParsedAttr &AL) { const TargetInfo &TTI = S.Context.getTargetInfo(); OffloadArch Arch = StringToOffloadArch(TTI.getTargetOpts().CPU); - if ((TTI.getTriple().isNVPTX() && Arch < clang::OffloadArch::SM_90) || + if ((TTI.getTriple().isNVPTX() && + llvm::NVPTX::getSmVersion(Arch.nvptxKind()) < 900) || (TTI.getTriple().isAMDGPU() && !TTI.hasFeatureEnabled(TTI.getTargetOpts().FeatureMap, "clusters"))) { S.Diag(AL.getLoc(), diag::err_cluster_attr_not_supported) << AL; diff --git a/clang/test/Misc/target-invalid-cpu-note/nvptx.c b/clang/test/Misc/target-invalid-cpu-note/nvptx.c index decbdfd44d6eb..922a2eb1d8c3a 100644 --- a/clang/test/Misc/target-invalid-cpu-note/nvptx.c +++ b/clang/test/Misc/target-invalid-cpu-note/nvptx.c @@ -59,7 +59,6 @@ // CHECK-SAME: {{^}}, gfx803 // CHECK-SAME: {{^}}, gfx805 // CHECK-SAME: {{^}}, gfx810 -// CHECK-SAME: {{^}}, gfx9-generic // CHECK-SAME: {{^}}, gfx900 // CHECK-SAME: {{^}}, gfx902 // CHECK-SAME: {{^}}, gfx904 @@ -68,15 +67,12 @@ // CHECK-SAME: {{^}}, gfx909 // CHECK-SAME: {{^}}, gfx90a // CHECK-SAME: {{^}}, gfx90c -// CHECK-SAME: {{^}}, gfx9-4-generic // CHECK-SAME: {{^}}, gfx942 // CHECK-SAME: {{^}}, gfx950 -// CHECK-SAME: {{^}}, gfx10-1-generic // CHECK-SAME: {{^}}, gfx1010 // CHECK-SAME: {{^}}, gfx1011 // CHECK-SAME: {{^}}, gfx1012 // CHECK-SAME: {{^}}, gfx1013 -// CHECK-SAME: {{^}}, gfx10-3-generic // CHECK-SAME: {{^}}, gfx1030 // CHECK-SAME: {{^}}, gfx1031 // CHECK-SAME: {{^}}, gfx1032 @@ -84,7 +80,6 @@ // CHECK-SAME: {{^}}, gfx1034 // CHECK-SAME: {{^}}, gfx1035 // CHECK-SAME: {{^}}, gfx1036 -// CHECK-SAME: {{^}}, gfx11-generic // CHECK-SAME: {{^}}, gfx1100 // CHECK-SAME: {{^}}, gfx1101 // CHECK-SAME: {{^}}, gfx1102 @@ -94,17 +89,39 @@ // CHECK-SAME: {{^}}, gfx1152 // CHECK-SAME: {{^}}, gfx1153 // CHECK-SAME: {{^}}, gfx1154 -// CHECK-SAME: {{^}}, gfx11-7-generic // CHECK-SAME: {{^}}, gfx1170 // CHECK-SAME: {{^}}, gfx1171 // CHECK-SAME: {{^}}, gfx1172 -// CHECK-SAME: {{^}}, gfx12-generic // CHECK-SAME: {{^}}, gfx1200 // CHECK-SAME: {{^}}, gfx1201 -// CHECK-SAME: {{^}}, gfx12-5-generic // CHECK-SAME: {{^}}, gfx1250 // CHECK-SAME: {{^}}, gfx1251 -// CHECK-SAME: {{^}}, gfx13-generic // CHECK-SAME: {{^}}, gfx1310 -// CHECK-SAME: {{^}}, amdgcnspirv +// CHECK-SAME: {{^}}, gfx9-generic +// CHECK-SAME: {{^}}, gfx9-4-generic +// CHECK-SAME: {{^}}, gfx10-1-generic +// CHECK-SAME: {{^}}, gfx10-3-generic +// CHECK-SAME: {{^}}, gfx11-generic +// CHECK-SAME: {{^}}, gfx11-7-generic +// CHECK-SAME: {{^}}, gfx12-generic +// CHECK-SAME: {{^}}, gfx12-5-generic +// CHECK-SAME: {{^}}, gfx13-generic +// CHECK-SAME: {{^}}, tahiti +// CHECK-SAME: {{^}}, pitcairn +// CHECK-SAME: {{^}}, verde +// CHECK-SAME: {{^}}, hainan +// CHECK-SAME: {{^}}, oland +// CHECK-SAME: {{^}}, kaveri +// CHECK-SAME: {{^}}, hawaii +// CHECK-SAME: {{^}}, kabini +// CHECK-SAME: {{^}}, mullins +// CHECK-SAME: {{^}}, bonaire +// CHECK-SAME: {{^}}, carrizo +// CHECK-SAME: {{^}}, iceland +// CHECK-SAME: {{^}}, tonga +// CHECK-SAME: {{^}}, fiji +// CHECK-SAME: {{^}}, polaris10 +// CHECK-SAME: {{^}}, polaris11 +// CHECK-SAME: {{^}}, tongapro +// CHECK-SAME: {{^}}, stoney // CHECK-SAME: {{$}} diff --git a/clang/unittests/Basic/OffloadArchTest.cpp b/clang/unittests/Basic/OffloadArchTest.cpp index c19ad0043d774..36dd958f0d896 100644 --- a/clang/unittests/Basic/OffloadArchTest.cpp +++ b/clang/unittests/Basic/OffloadArchTest.cpp @@ -11,26 +11,49 @@ using namespace clang; -TEST(OffloadArchTest, basic) { - EXPECT_TRUE(IsNVIDIAOffloadArch(OffloadArch::SM_20)); - EXPECT_TRUE(IsNVIDIAOffloadArch(OffloadArch::SM_120a)); - EXPECT_FALSE(IsNVIDIAOffloadArch(OffloadArch::GFX600)); - - EXPECT_FALSE(IsAMDOffloadArch(OffloadArch::SM_120a)); - EXPECT_TRUE(IsAMDOffloadArch(OffloadArch::GFX600)); - EXPECT_TRUE(IsAMDOffloadArch(OffloadArch::GFX1201)); - EXPECT_TRUE(IsAMDOffloadArch(OffloadArch::GFX12_GENERIC)); - EXPECT_TRUE(IsAMDOffloadArch(OffloadArch::AMDGCNSPIRV)); - EXPECT_FALSE(IsAMDOffloadArch(OffloadArch::GRANITERAPIDS)); - - EXPECT_TRUE(IsIntelOffloadArch(OffloadArch::GRANITERAPIDS)); - EXPECT_TRUE(IsIntelCPUOffloadArch(OffloadArch::GRANITERAPIDS)); - EXPECT_FALSE(IsIntelGPUOffloadArch(OffloadArch::GRANITERAPIDS)); - EXPECT_TRUE(IsIntelOffloadArch(OffloadArch::BMG_G21)); - EXPECT_FALSE(IsIntelCPUOffloadArch(OffloadArch::BMG_G21)); - EXPECT_TRUE(IsIntelGPUOffloadArch(OffloadArch::BMG_G21)); - - EXPECT_FALSE(IsNVIDIAOffloadArch(OffloadArch::Generic)); - EXPECT_FALSE(IsAMDOffloadArch(OffloadArch::Generic)); - EXPECT_FALSE(IsIntelOffloadArch(OffloadArch::Generic)); +static OffloadArch parse(llvm::StringRef S) { return StringToOffloadArch(S); } + +TEST(OffloadArchTest, VendorClassification) { + EXPECT_TRUE(IsNVIDIAOffloadArch(parse("sm_20"))); + EXPECT_TRUE(IsNVIDIAOffloadArch(parse("sm_120a"))); + EXPECT_FALSE(IsNVIDIAOffloadArch(parse("gfx600"))); + + EXPECT_FALSE(IsAMDOffloadArch(parse("sm_120a"))); + EXPECT_TRUE(IsAMDOffloadArch(parse("gfx600"))); + EXPECT_TRUE(IsAMDOffloadArch(parse("gfx1201"))); + EXPECT_TRUE(IsAMDOffloadArch(parse("gfx12-generic"))); + EXPECT_TRUE(IsAMDOffloadArch(parse("amdgcnspirv"))); + EXPECT_FALSE(IsAMDOffloadArch(parse("graniterapids"))); + + EXPECT_TRUE(IsIntelOffloadArch(parse("graniterapids"))); + EXPECT_TRUE(IsIntelCPUOffloadArch(parse("graniterapids"))); + EXPECT_FALSE(IsIntelGPUOffloadArch(parse("graniterapids"))); + EXPECT_TRUE(IsIntelOffloadArch(parse("bmg_g21"))); + EXPECT_FALSE(IsIntelCPUOffloadArch(parse("bmg_g21"))); + EXPECT_TRUE(IsIntelGPUOffloadArch(parse("bmg_g21"))); + + EXPECT_FALSE(IsNVIDIAOffloadArch(parse("generic"))); + EXPECT_FALSE(IsAMDOffloadArch(parse("generic"))); + EXPECT_FALSE(IsIntelOffloadArch(parse("generic"))); +} + +TEST(OffloadArchTest, Unknown) { + EXPECT_TRUE(parse("not-a-real-arch").isUnknown()); + EXPECT_TRUE(parse("").isUnused()); +} + +// Names must round-trip through parse -> string. +TEST(OffloadArchTest, RoundTrip) { + for (const char *Name : + {"sm_52", "sm_90a", "gfx906", "gfx1201", "gfx12-generic", "amdgcnspirv", + "graniterapids", "bmg_g21", "generic"}) { + OffloadArch A = parse(Name); + EXPECT_FALSE(A.isUnknown()) << Name; + EXPECT_STREQ(OffloadArchToString(A), Name); + } +} + +TEST(OffloadArchTest, Defaults) { + EXPECT_STREQ(OffloadArchToString(OffloadArch::CudaDefault()), "sm_52"); + EXPECT_STREQ(OffloadArchToString(OffloadArch::HIPDefault()), "gfx906"); } diff --git a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h index fd0072c89be23..c2e394d82292f 100644 --- a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h +++ b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h @@ -31,7 +31,7 @@ class Triple; namespace AMDGPU { /// GPU kinds supported by the AMDGPU target. -enum GPUKind : uint32_t { +enum GPUKind : uint8_t { // Not specified processor. GK_NONE = 0, diff --git a/llvm/include/llvm/TargetParser/NVPTXTargetParser.h b/llvm/include/llvm/TargetParser/NVPTXTargetParser.h index a49130b99ba76..446f5c47aeaf3 100644 --- a/llvm/include/llvm/TargetParser/NVPTXTargetParser.h +++ b/llvm/include/llvm/TargetParser/NVPTXTargetParser.h @@ -17,11 +17,15 @@ namespace llvm { namespace NVPTX { /// GPU kinds supported by the NVPTX target. -enum GPUKind : uint32_t { +enum GPUKind : uint8_t { GK_NONE = 0, #define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \ GK_##KIND, #include "llvm/TargetParser/NVPTXTargetParser.def" + + // Alias for the last GPUKind. Keep in sync with the final .def row. + // FIXME: Should be generated once the GPU list moves to TableGen. + GK_LAST = GK_SM_121f, }; /// Suffix class of an NVPTX architecture name. Enumerator spellings match the _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
