Author: Matt Arsenault
Date: 2026-07-23T13:39:16+02:00
New Revision: fd67f99275f586c48ae6432bca2623a29c82bf8c

URL: 
https://github.com/llvm/llvm-project/commit/fd67f99275f586c48ae6432bca2623a29c82bf8c
DIFF: 
https://github.com/llvm/llvm-project/commit/fd67f99275f586c48ae6432bca2623a29c82bf8c.diff

LOG: clang/AMDGPU: Fix handling of subarch triples with no -mcpu (#211467)

Added: 
    clang/test/CodeGenOpenCL/amdgpu-wavefront-size-from-subarch.cl
    clang/test/Preprocessor/amdgpu-subarch-cc1-target-cpu.cl

Modified: 
    clang/lib/Basic/Targets/AMDGPU.cpp
    llvm/lib/TargetParser/AMDGPUTargetParser.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Basic/Targets/AMDGPU.cpp 
b/clang/lib/Basic/Targets/AMDGPU.cpp
index c789fd8f94afb..487c1949e7c83 100644
--- a/clang/lib/Basic/Targets/AMDGPU.cpp
+++ b/clang/lib/Basic/Targets/AMDGPU.cpp
@@ -191,8 +191,11 @@ void AMDGPUTargetInfo::fillValidCPUList(
 AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,
                                    const TargetOptions &Opts)
     : TargetInfo(Triple),
-      GPUKind(Triple.isAMDGCN() ? llvm::AMDGPU::parseArchAMDGCN(Opts.CPU)
-                                : llvm::AMDGPU::parseArchR600(Opts.CPU)),
+      GPUKind(Triple.isAMDGCN()
+                  ? (Opts.CPU.empty() ? llvm::AMDGPU::getGPUKindFromSubArch(
+                                            Triple.getSubArch())
+                                      : 
llvm::AMDGPU::parseArchAMDGCN(Opts.CPU))
+                  : llvm::AMDGPU::parseArchR600(Opts.CPU)),
       GPUFeatures(Triple.isAMDGCN() ? llvm::AMDGPU::getArchAttrAMDGCN(GPUKind)
                                     : llvm::AMDGPU::getArchAttrR600(GPUKind)) {
   resetDataLayout();

diff  --git a/clang/test/CodeGenOpenCL/amdgpu-wavefront-size-from-subarch.cl 
b/clang/test/CodeGenOpenCL/amdgpu-wavefront-size-from-subarch.cl
new file mode 100644
index 0000000000000..576569592a69d
--- /dev/null
+++ b/clang/test/CodeGenOpenCL/amdgpu-wavefront-size-from-subarch.cl
@@ -0,0 +1,37 @@
+// REQUIRES: amdgpu-registered-target
+
+// Check that the default wavefront size is determined by the triple's subarch
+// alone, with no -target-cpu. Clang only emits a wavefrontsize target-feature
+// when it 
diff ers from the target default, so passing -target-feature
+// +wavefrontsizeN shows up in the IR target-features attribute exactly when N 
is
+// NOT the subarch default. gfx9 defaults to wave64; gfx10/gfx11/gfx12 default 
to
+// wave32.
+
+// gfx9 default is wave64: +wavefrontsize64 matches the default and is elided,
+// while +wavefrontsize32 is rejected because gfx9 is wave64 only.
+// RUN: %clang_cc1 -triple amdgpu9.00 -target-feature +wavefrontsize64 
-emit-llvm -o - %s | FileCheck --check-prefix=NO-DELTA %s
+// RUN: not %clang_cc1 -triple amdgpu9.00 -target-feature +wavefrontsize32 
-emit-llvm -o /dev/null %s 2>&1 | FileCheck --check-prefix=ERR-WAVE32 %s
+// The gfx9 major-family subarch behaves the same as its members.
+// RUN: %clang_cc1 -triple amdgpu9 -target-feature +wavefrontsize64 -emit-llvm 
-o - %s | FileCheck --check-prefix=NO-DELTA %s
+
+// gfx11 default is wave32: +wavefrontsize64 is a delta and is emitted, while
+// +wavefrontsize32 matches the default and is elided.
+// RUN: %clang_cc1 -triple amdgpu11.00 -target-feature +wavefrontsize64 
-emit-llvm -o - %s | FileCheck --check-prefix=WAVE64-DELTA %s
+// RUN: %clang_cc1 -triple amdgpu11.00 -target-feature +wavefrontsize32 
-emit-llvm -o - %s | FileCheck --check-prefix=NO-DELTA %s
+// RUN: %clang_cc1 -triple amdgpu11 -target-feature +wavefrontsize64 
-emit-llvm -o - %s | FileCheck --check-prefix=WAVE64-DELTA %s
+
+// gfx1250 is wave32 only: +wavefrontsize64 is rejected.
+// RUN: not %clang_cc1 -triple amdgpu12.50 -target-feature +wavefrontsize64 
-emit-llvm -o /dev/null %s 2>&1 | FileCheck --check-prefix=ERR-WAVE64 %s
+
+// A amdgpu triple with no subarch and no -target-cpu has no default wave size,
+// so both overrides are accepted and emitted verbatim.
+// RUN: %clang_cc1 -triple amdgpu -target-feature +wavefrontsize64 -emit-llvm 
-o - %s | FileCheck --check-prefix=WAVE64-DELTA %s
+// RUN: %clang_cc1 -triple amdgpu -target-feature +wavefrontsize32 -emit-llvm 
-o - %s | FileCheck --check-prefix=WAVE32-DELTA %s
+
+kernel void foo() {}
+
+// NO-DELTA-NOT: "target-features"
+// WAVE64-DELTA: "target-features"="{{[^"]*}}+wavefrontsize64{{[^"]*}}"
+// WAVE32-DELTA: "target-features"="{{[^"]*}}+wavefrontsize32{{[^"]*}}"
+// ERR-WAVE32: error: option '+wavefrontsize32' cannot be specified on this 
target
+// ERR-WAVE64: error: option '+wavefrontsize64' cannot be specified on this 
target

diff  --git a/clang/test/Preprocessor/amdgpu-subarch-cc1-target-cpu.cl 
b/clang/test/Preprocessor/amdgpu-subarch-cc1-target-cpu.cl
new file mode 100644
index 0000000000000..7008e53a34c6a
--- /dev/null
+++ b/clang/test/Preprocessor/amdgpu-subarch-cc1-target-cpu.cl
@@ -0,0 +1,24 @@
+// Test the behavior of -target-cpu for cc1 with amdgpu subarches. -target-cpu
+// usage is an edge case, typical invocations should use a subarch in the 
triple
+// and omit the -target-cpu argument. If -target-cpu is used, it should still 
be
+// respected (particularly in the case where the triple is a major subarch
+// covering the -target-cpu).
+
+// Specific subarch, no -target-cpu: GPU implied by the subarch.
+// RUN: %clang_cc1 -triple amdgpu9.0a-amd-amdhsa -E -dM %s 2>&1 | \
+// RUN:   FileCheck --check-prefix=GFX90A %s
+// GFX90A-DAG: #define __amdgcn_processor__ "gfx90a"
+// GFX90A-DAG: #define __gfx90a__ 1
+// GFX90A-DAG: #define __GFX9__ 1
+
+// Generic-family subarch, no -target-cpu: GPU is the generic target.
+// RUN: %clang_cc1 -triple amdgpu9-amd-amdhsa -E -dM %s 2>&1 | \
+// RUN:   FileCheck --check-prefix=GFX9-GENERIC %s
+// GFX9-GENERIC-DAG: #define __amdgcn_processor__ "gfx9_generic"
+// GFX9-GENERIC-DAG: #define __gfx9_generic__ 1
+
+// An explicit -target-cpu overrides the subarch (manual cc1 invocation).
+// RUN: %clang_cc1 -triple amdgpu9-amd-amdhsa -target-cpu gfx900 -E -dM %s 
2>&1 | \
+// RUN:   FileCheck --check-prefix=OVERRIDE %s
+// OVERRIDE-DAG: #define __amdgcn_processor__ "gfx900"
+// OVERRIDE-DAG: #define __gfx900__ 1

diff  --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp 
b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
index 31cb07d67fbdc..23d67cd95696a 100644
--- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
+++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp
@@ -427,7 +427,10 @@ static std::pair<FeatureError, StringRef>
 insertWaveSizeFeature(StringRef GPU, const Triple &T,
                       const StringMap<bool> &DefaultFeatures,
                       StringMap<bool> &Features) {
-  const bool IsNullGPU = GPU.empty();
+  // A bare subarch triple (no -target-cpu) still pins down the target, so it 
is
+  // not a null GPU: DefaultFeatures has already been populated from the
+  // subarch.
+  const bool IsNullGPU = T.getSubArch() == Triple::NoSubArch && GPU.empty();
   const bool TargetHasWave32 = DefaultFeatures.count("wavefrontsize32");
   const bool TargetHasWave64 = DefaultFeatures.count("wavefrontsize64");
 
@@ -484,7 +487,10 @@ insertWaveSizeFeature(StringRef GPU, const Triple &T,
 /// default target features with entries overridden by \p Features.
 static void fillAMDGCNFeatureMap(StringRef GPU, const Triple &T,
                                  StringMap<bool> &Features) {
-  AMDGPU::GPUKind Kind = parseArchAMDGCN(GPU);
+  // With no explicit GPU, the triple's subarch identifies the target.
+  AMDGPU::GPUKind Kind = GPU.empty() && T.getSubArch() != Triple::NoSubArch
+                             ? getGPUKindFromSubArch(T.getSubArch())
+                             : parseArchAMDGCN(GPU);
   switch (Kind) {
   case GK_GFX1310:
   case GK_GFX13_GENERIC:


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to