[clang] [clang][Driver][HIP] Add support for mixing AMDGCNSPIRV & concrete `offload-arch`s. (PR #113509)
Alex Voicu via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 23 17:22:20 PDT 2024
https://github.com/AlexVlx updated https://github.com/llvm/llvm-project/pull/113509
>From 4a18bbc256051f30805620f65a4db037ea2fe96c Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Thu, 24 Oct 2024 01:14:28 +0100
Subject: [PATCH 1/2] Add support for mixing AMDGCNSPIRV & concrete
`offload-arch`s.
---
clang/lib/Driver/Driver.cpp | 19 ++++++++----------
clang/lib/Driver/ToolChain.cpp | 6 ++++++
clang/lib/Driver/ToolChains/HIPAMD.cpp | 23 +++++++++++-----------
clang/lib/Driver/ToolChains/HIPUtility.cpp | 10 +++++++---
clang/test/Driver/hip-toolchain-no-rdc.hip | 18 +++++++++++++++++
5 files changed, 51 insertions(+), 25 deletions(-)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 9878a9dad78d40..1590fbad5e4949 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -149,13 +149,9 @@ static std::optional<llvm::Triple>
getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) {
if (!Args.hasArg(options::OPT_offload_EQ)) {
auto OffloadArchs = Args.getAllArgValues(options::OPT_offload_arch_EQ);
- if (llvm::is_contained(OffloadArchs, "amdgcnspirv")) {
- if (OffloadArchs.size() == 1)
- return llvm::Triple("spirv64-amd-amdhsa");
- // Mixing specific & SPIR-V compilation is not supported for now.
- D.Diag(diag::err_drv_only_one_offload_target_supported);
- return std::nullopt;
- }
+ if (llvm::is_contained(OffloadArchs, "amdgcnspirv") &&
+ OffloadArchs.size() == 1)
+ return llvm::Triple("spirv64-amd-amdhsa");
return llvm::Triple("amdgcn-amd-amdhsa"); // Default HIP triple.
}
auto TT = getOffloadTargetTriple(D, Args);
@@ -3477,9 +3473,10 @@ class OffloadingActionBuilder final {
llvm::StringMap<bool> Features;
// getHIPOffloadTargetTriple() is known to return valid value as it has
// been called successfully in the CreateOffloadingDeviceToolChains().
- auto ArchStr = parseTargetID(
- *getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs()), IdStr,
- &Features);
+ auto T = (IdStr == "amdgcnspirv") ?
+ llvm::Triple("spirv64-amd-amdhsa") :
+ *getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs());
+ auto ArchStr = parseTargetID(T, IdStr, &Features);
if (!ArchStr) {
C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
C.setContainsError();
@@ -5750,7 +5747,7 @@ InputInfoList Driver::BuildJobsForActionNoCache(
// We only have to generate a prefix for the host if this is not a top-level
// action.
std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix(
- A->getOffloadingDeviceKind(), TC->getTriple().normalize(),
+ A->getOffloadingDeviceKind(), EffectiveTriple.normalize(),
/*CreatePrefixForHost=*/isa<OffloadPackagerJobAction>(A) ||
!(A->getOffloadingHostActiveKinds() == Action::OFK_None ||
AtTopLevel));
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 4df31770950858..b3c2fe84e177c8 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -1095,6 +1095,12 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
}
case llvm::Triple::aarch64_32:
return getTripleString();
+ case llvm::Triple::amdgcn: {
+ llvm::Triple Triple = getTriple();
+ if (Args.getLastArgValue(options::OPT_mcpu_EQ) == "amdgcnspirv")
+ Triple.setArch(llvm::Triple::ArchType::spirv64);
+ return Triple.getTriple();
+ }
case llvm::Triple::arm:
case llvm::Triple::armeb:
case llvm::Triple::thumb:
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index bae05cc0bb7353..4eb8c4f58923fd 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -205,7 +205,7 @@ void AMDGCN::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (JA.getType() == types::TY_LLVM_BC)
return constructLlvmLinkCommand(C, JA, Inputs, Output, Args);
- if (getToolChain().getTriple().isSPIRV())
+ if (getToolChain().getEffectiveTriple().isSPIRV())
return constructLinkAndEmitSpirvCommand(C, JA, Inputs, Output, Args);
return constructLldCommand(C, JA, Inputs, Output, Args);
@@ -264,12 +264,14 @@ void HIPAMDToolChain::addClangTargetOptions(
CC1Args.push_back("-fapply-global-visibility-to-externs");
}
- // For SPIR-V we embed the command-line into the generated binary, in order to
- // retrieve it at JIT time and be able to do target specific compilation with
- // options that match the user-supplied ones.
- if (getTriple().isSPIRV() &&
- !DriverArgs.hasArg(options::OPT_fembed_bitcode_marker))
- CC1Args.push_back("-fembed-bitcode=marker");
+ if (getEffectiveTriple().isSPIRV()) {
+ // For SPIR-V we embed the command-line into the generated binary, in order
+ // to retrieve it at JIT time and be able to do target specific compilation
+ // with options that match the user-supplied ones.
+ if (!DriverArgs.hasArg(options::OPT_fembed_bitcode_marker))
+ CC1Args.push_back("-fembed-bitcode=marker");
+ return; // No DeviceLibs for SPIR-V.
+ }
for (auto BCFile : getDeviceLibs(DriverArgs)) {
CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"
@@ -361,8 +363,7 @@ llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const {
llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs;
if (DriverArgs.hasArg(options::OPT_nogpulib) ||
- (getTriple().getArch() == llvm::Triple::spirv64 &&
- getTriple().getVendor() == llvm::Triple::AMD))
+ getGPUArch(DriverArgs) == "amdgcnspirv")
return {};
ArgStringList LibraryPaths;
@@ -437,8 +438,8 @@ HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const {
void HIPAMDToolChain::checkTargetID(
const llvm::opt::ArgList &DriverArgs) const {
auto PTID = getParsedTargetID(DriverArgs);
- if (PTID.OptionalTargetID && !PTID.OptionalGPUArch) {
+ if (PTID.OptionalTargetID && !PTID.OptionalGPUArch &&
+ PTID.OptionalTargetID != "amdgcnspirv")
getDriver().Diag(clang::diag::err_drv_bad_target_id)
<< *PTID.OptionalTargetID;
- }
}
diff --git a/clang/lib/Driver/ToolChains/HIPUtility.cpp b/clang/lib/Driver/ToolChains/HIPUtility.cpp
index 9fe4f1e0e20965..c8075cbfe36b35 100644
--- a/clang/lib/Driver/ToolChains/HIPUtility.cpp
+++ b/clang/lib/Driver/ToolChains/HIPUtility.cpp
@@ -304,10 +304,14 @@ void HIP::constructHIPFatbinCommand(Compilation &C, const JobAction &JA,
for (const auto &II : Inputs) {
const auto *A = II.getAction();
auto ArchStr = llvm::StringRef(A->getOffloadingArch());
- BundlerTargetArg +=
- "," + OffloadKind + "-" + normalizeForBundler(TT, !ArchStr.empty());
+ BundlerTargetArg += ',' + OffloadKind + '-';
+ if (ArchStr == "amdgcnspirv")
+ BundlerTargetArg +=
+ normalizeForBundler(llvm::Triple("spirv64-amd-amdhsa"), true);
+ else
+ BundlerTargetArg += normalizeForBundler(TT, !ArchStr.empty());
if (!ArchStr.empty())
- BundlerTargetArg += "-" + ArchStr.str();
+ BundlerTargetArg += '-' + ArchStr.str();
}
BundlerArgs.push_back(Args.MakeArgString(BundlerTargetArg));
diff --git a/clang/test/Driver/hip-toolchain-no-rdc.hip b/clang/test/Driver/hip-toolchain-no-rdc.hip
index 0cdc82ead65408..047617350222d9 100644
--- a/clang/test/Driver/hip-toolchain-no-rdc.hip
+++ b/clang/test/Driver/hip-toolchain-no-rdc.hip
@@ -36,6 +36,11 @@
// RUN: %t/a.o %t/b.o \
// RUN: 2>&1 | FileCheck -check-prefixes=LKONLY %s
+// RUN: %clang -### --target=x86_64-linux-gnu \
+// RUN: --offload-arch=amdgcnspirv --offload-arch=gfx900 \
+// RUN: %s -nogpuinc -nogpulib \
+// RUN: 2>&1 | FileCheck -check-prefixes=AMDGCNSPIRV %s
+
//
// Compile device code in a.cu to code object for gfx803.
//
@@ -177,3 +182,16 @@
// LKONLY-NOT: {{".*/llc"}}
// LKONLY: [[LD:".*ld.*"]] {{.*}} "{{.*/a.o}}" "{{.*/b.o}}"
// LKONLY-NOT: "-T" "{{.*}}.lk"
+
+//
+// Check mixed AMDGCNSPIRV and concrete GPU arch.
+//
+
+// AMDGCNSPIRV: "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}}"-emit-obj" {{.*}} "-o" "[[AMDGCNSPV_OBJ:.*o]]"
+// AMDGCNSPIRV: {{".*llvm-link"}} "-o" "[[AMDGCNSPV_TMP:.*out]]" "[[AMDGCNSPV_OBJ]]"
+// AMDGCNSPIRV: {{".*llvm-spirv"}} "--spirv-max-version=1.6" "--spirv-ext=+all" {{.*}} "[[AMDGCNSPV_TMP]]" {{.*}}"-o" "[[AMDGCNSPV_CO:.*out]]"
+// AMDGCNSPIRV: "-cc1" "-triple" "amdgcn-amd-amdhsa" {{.*}}"-emit-obj" {{.*}}"-target-cpu" "gfx900"{{.*}} "-o" "[[GFX900_OBJ:.*o]]"
+// AMDGCNSPIRV: {{".*lld"}} {{.*}}"-plugin-opt=mcpu=gfx900" {{.*}} "-o" "[[GFX900_CO:.*out]]" {{.*}}"[[GFX900_OBJ]]"
+// AMDGCNSPIRV: {{".*clang-offload-bundler"}} "-type=o"
+// AMDGCNSPIRV-SAME: "-targets={{.*}}hipv4-spirv64-amd-amdhsa--amdgcnspirv,hipv4-amdgcn-amd-amdhsa--gfx900"
+// AMDGCNSPIRV-SAME: "-input=[[AMDGCNSPV_CO]]" "-input=[[GFX900_CO]]"
>From 1a4ab229e0069e7bda300ae565dfcb74d5d0ac39 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Thu, 24 Oct 2024 01:22:08 +0100
Subject: [PATCH 2/2] Fix formatting.
---
clang/lib/Driver/Driver.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 1590fbad5e4949..a24168306fa8b9 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -3473,9 +3473,10 @@ class OffloadingActionBuilder final {
llvm::StringMap<bool> Features;
// getHIPOffloadTargetTriple() is known to return valid value as it has
// been called successfully in the CreateOffloadingDeviceToolChains().
- auto T = (IdStr == "amdgcnspirv") ?
- llvm::Triple("spirv64-amd-amdhsa") :
- *getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs());
+ auto T =
+ (IdStr == "amdgcnspirv")
+ ? llvm::Triple("spirv64-amd-amdhsa")
+ : *getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs());
auto ArchStr = parseTargetID(T, IdStr, &Features);
if (!ArchStr) {
C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
More information about the cfe-commits
mailing list