From e98b10731f3b046ee85ef0706b18db30f565e62d Mon Sep 17 00:00:00 2001 From: "Yaxun (Sam) Liu" Date: Wed, 7 May 2025 22:38:21 -0400 Subject: [PATCH] [HIP] change default offload archs Currently, HIP uses gfx906 as the default offload arch, which only works on systems with gfx906. For non-interactive uses, this is less of a concern since they all set explicit offload archs for supported GPU's. The only use of default offload arch is when the clang wrapper hipcc is used as a C++ compiler during compiler detection of cmake, where the default offload arch is used to compile a C++ program as HIP program and executed. However since there is no kernel, the default offload arch just works. However, gfx906 as default offload arch is very inconenient for interactive users since in most cases they would like to compile for the GPU on the system. With this patch, if AMD GPU's are detected on the system, they will be used as default offload archs for HIP. Otherwise, if amd-llvm-spirv is found and executable, amdgcnspirv will be used as the default offload arch, since it works for all AMD GPU's supporting HIP. Otherwise, the original default offload arch is used, which is gfx906. --- clang/include/clang/Driver/ToolChain.h | 4 ++++ clang/lib/Driver/Driver.cpp | 6 ++++- clang/lib/Driver/ToolChain.cpp | 26 ++++++++++++++++++++++ clang/test/Driver/hip-default-gpu-arch.hip | 2 +- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 58edf2b3887b0..46771c450ef71 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -780,6 +780,10 @@ class ToolChain { virtual Expected> getSystemGPUArchs(const llvm::opt::ArgList &Args) const; + /// getHIPDefaultOffloadArchs - Get the default offload arch's for HIP. + virtual SmallVector + getHIPDefaultOffloadArchs(const llvm::opt::ArgList &Args) const; + /// addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass /// a suitable profile runtime library to the linker. virtual void addProfileRTLibs(const llvm::opt::ArgList &Args, diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index e844f0d6d5400..d746c8c77a99d 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3503,6 +3503,9 @@ class OffloadingActionBuilder final { GpuArchList.push_back(OffloadArch::AMDGCNSPIRV); else GpuArchList.push_back(OffloadArch::Generic); + } else if (AssociatedOffloadKind == Action::OFK_HIP) { + for (auto A : ToolChains.front()->getHIPDefaultOffloadArchs(Args)) + GpuArchList.push_back(A.data()); } else { GpuArchList.push_back(DefaultOffloadArch); } @@ -4825,7 +4828,8 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, if (Kind == Action::OFK_Cuda) { Archs.insert(OffloadArchToString(OffloadArch::CudaDefault)); } else if (Kind == Action::OFK_HIP) { - Archs.insert(OffloadArchToString(OffloadArch::HIPDefault)); + for (auto A : TC->getHIPDefaultOffloadArchs(Args)) + Archs.insert(A); } else if (Kind == Action::OFK_SYCL) { Archs.insert(StringRef()); } else if (Kind == Action::OFK_OpenMP) { diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 3c52abb0ab78e..2b6db476118c4 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1574,6 +1574,32 @@ ToolChain::getSystemGPUArchs(const llvm::opt::ArgList &Args) const { return SmallVector(); } +SmallVector +ToolChain::getHIPDefaultOffloadArchs(const llvm::opt::ArgList &Args) const { + if (getTriple().isSPIRV()) { + if (getTriple().getVendor() == llvm::Triple::AMD) + return {OffloadArchToString(OffloadArch::AMDGCNSPIRV)}; + return {OffloadArchToString(OffloadArch::Generic)}; + } + + if (!getTriple().isAMDGPU()) + return {}; + + SmallVector GpuArchList; + auto GPUsOrErr = getSystemGPUArchs(Args); + if (GPUsOrErr) { + for (auto &G : *GPUsOrErr) + GpuArchList.push_back(Args.MakeArgString(G)); + return GpuArchList; + } + llvm::consumeError(GPUsOrErr.takeError()); + auto Prog = GetProgramPath("amd-llvm-spirv"); + if (!Prog.empty() && llvm::sys::fs::can_execute(Prog)) + return {OffloadArchToString(OffloadArch::AMDGCNSPIRV)}; + + return {OffloadArchToString(OffloadArch::HIPDefault)}; +} + SanitizerMask ToolChain::getSupportedSanitizers() const { // Return sanitizers which don't require runtime support and are not // platform dependent. diff --git a/clang/test/Driver/hip-default-gpu-arch.hip b/clang/test/Driver/hip-default-gpu-arch.hip index d55a3ea151f9a..b68e738ccc345 100644 --- a/clang/test/Driver/hip-default-gpu-arch.hip +++ b/clang/test/Driver/hip-default-gpu-arch.hip @@ -1,3 +1,3 @@ // RUN: %clang -### -nogpulib -nogpuinc -c %s 2>&1 | FileCheck %s -// CHECK: {{.*}}clang{{.*}}"-target-cpu" "gfx906" +// CHECK: {{.*}}clang{{.*}}"-triple" "{{amdgcn|spirv64}}-amd-amdhsa"{{.*}} "-target-cpu" "{{amdgcnspirv|gfx.*}}"