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
