[clang] fd67f99 - clang/AMDGPU: Fix handling of subarch triples with no -mcpu (#211467)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 23 04:39:21 PDT 2026
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:
More information about the cfe-commits
mailing list