Skip to content

Commit dc62edf

Browse files
authored
[clang][Driver][HIP] Add support for mixing AMDGCNSPIRV & concrete offload-archs. (#113509)
This removes the temporary ban on mixing AMDGCN flavoured SPIR-V and concrete targets (e.g. `gfx900`) in the same HIPAMD compilation. This is done primarily by tweaking the effective / observable triple when the target is `amdgcnspirv`, which seamlessly composes with the existing infra. The test is stolen from #75357.
1 parent d084bc2 commit dc62edf

File tree

5 files changed

+52
-25
lines changed

5 files changed

+52
-25
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,9 @@ static std::optional<llvm::Triple>
149149
getHIPOffloadTargetTriple(const Driver &D, const ArgList &Args) {
150150
if (!Args.hasArg(options::OPT_offload_EQ)) {
151151
auto OffloadArchs = Args.getAllArgValues(options::OPT_offload_arch_EQ);
152-
if (llvm::is_contained(OffloadArchs, "amdgcnspirv")) {
153-
if (OffloadArchs.size() == 1)
154-
return llvm::Triple("spirv64-amd-amdhsa");
155-
// Mixing specific & SPIR-V compilation is not supported for now.
156-
D.Diag(diag::err_drv_only_one_offload_target_supported);
157-
return std::nullopt;
158-
}
152+
if (llvm::is_contained(OffloadArchs, "amdgcnspirv") &&
153+
OffloadArchs.size() == 1)
154+
return llvm::Triple("spirv64-amd-amdhsa");
159155
return llvm::Triple("amdgcn-amd-amdhsa"); // Default HIP triple.
160156
}
161157
auto TT = getOffloadTargetTriple(D, Args);
@@ -3477,9 +3473,11 @@ class OffloadingActionBuilder final {
34773473
llvm::StringMap<bool> Features;
34783474
// getHIPOffloadTargetTriple() is known to return valid value as it has
34793475
// been called successfully in the CreateOffloadingDeviceToolChains().
3480-
auto ArchStr = parseTargetID(
3481-
*getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs()), IdStr,
3482-
&Features);
3476+
auto T =
3477+
(IdStr == "amdgcnspirv")
3478+
? llvm::Triple("spirv64-amd-amdhsa")
3479+
: *getHIPOffloadTargetTriple(C.getDriver(), C.getInputArgs());
3480+
auto ArchStr = parseTargetID(T, IdStr, &Features);
34833481
if (!ArchStr) {
34843482
C.getDriver().Diag(clang::diag::err_drv_bad_target_id) << IdStr;
34853483
C.setContainsError();
@@ -5755,7 +5753,7 @@ InputInfoList Driver::BuildJobsForActionNoCache(
57555753
// We only have to generate a prefix for the host if this is not a top-level
57565754
// action.
57575755
std::string OffloadingPrefix = Action::GetOffloadingFileNamePrefix(
5758-
A->getOffloadingDeviceKind(), TC->getTriple().normalize(),
5756+
A->getOffloadingDeviceKind(), EffectiveTriple.normalize(),
57595757
/*CreatePrefixForHost=*/isa<OffloadPackagerJobAction>(A) ||
57605758
!(A->getOffloadingHostActiveKinds() == Action::OFK_None ||
57615759
AtTopLevel));

clang/lib/Driver/ToolChain.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,12 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
10991099
}
11001100
case llvm::Triple::aarch64_32:
11011101
return getTripleString();
1102+
case llvm::Triple::amdgcn: {
1103+
llvm::Triple Triple = getTriple();
1104+
if (Args.getLastArgValue(options::OPT_mcpu_EQ) == "amdgcnspirv")
1105+
Triple.setArch(llvm::Triple::ArchType::spirv64);
1106+
return Triple.getTriple();
1107+
}
11021108
case llvm::Triple::arm:
11031109
case llvm::Triple::armeb:
11041110
case llvm::Triple::thumb:

clang/lib/Driver/ToolChains/HIPAMD.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ void AMDGCN::Linker::ConstructJob(Compilation &C, const JobAction &JA,
205205
if (JA.getType() == types::TY_LLVM_BC)
206206
return constructLlvmLinkCommand(C, JA, Inputs, Output, Args);
207207

208-
if (getToolChain().getTriple().isSPIRV())
208+
if (getToolChain().getEffectiveTriple().isSPIRV())
209209
return constructLinkAndEmitSpirvCommand(C, JA, Inputs, Output, Args);
210210

211211
return constructLldCommand(C, JA, Inputs, Output, Args);
@@ -264,12 +264,14 @@ void HIPAMDToolChain::addClangTargetOptions(
264264
CC1Args.push_back("-fapply-global-visibility-to-externs");
265265
}
266266

267-
// For SPIR-V we embed the command-line into the generated binary, in order to
268-
// retrieve it at JIT time and be able to do target specific compilation with
269-
// options that match the user-supplied ones.
270-
if (getTriple().isSPIRV() &&
271-
!DriverArgs.hasArg(options::OPT_fembed_bitcode_marker))
272-
CC1Args.push_back("-fembed-bitcode=marker");
267+
if (getEffectiveTriple().isSPIRV()) {
268+
// For SPIR-V we embed the command-line into the generated binary, in order
269+
// to retrieve it at JIT time and be able to do target specific compilation
270+
// with options that match the user-supplied ones.
271+
if (!DriverArgs.hasArg(options::OPT_fembed_bitcode_marker))
272+
CC1Args.push_back("-fembed-bitcode=marker");
273+
return; // No DeviceLibs for SPIR-V.
274+
}
273275

274276
for (auto BCFile : getDeviceLibs(DriverArgs)) {
275277
CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"
@@ -361,8 +363,7 @@ llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
361363
HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const {
362364
llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs;
363365
if (DriverArgs.hasArg(options::OPT_nogpulib) ||
364-
(getTriple().getArch() == llvm::Triple::spirv64 &&
365-
getTriple().getVendor() == llvm::Triple::AMD))
366+
getGPUArch(DriverArgs) == "amdgcnspirv")
366367
return {};
367368
ArgStringList LibraryPaths;
368369

@@ -437,8 +438,8 @@ HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const {
437438
void HIPAMDToolChain::checkTargetID(
438439
const llvm::opt::ArgList &DriverArgs) const {
439440
auto PTID = getParsedTargetID(DriverArgs);
440-
if (PTID.OptionalTargetID && !PTID.OptionalGPUArch) {
441+
if (PTID.OptionalTargetID && !PTID.OptionalGPUArch &&
442+
PTID.OptionalTargetID != "amdgcnspirv")
441443
getDriver().Diag(clang::diag::err_drv_bad_target_id)
442444
<< *PTID.OptionalTargetID;
443-
}
444445
}

clang/lib/Driver/ToolChains/HIPUtility.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,14 @@ void HIP::constructHIPFatbinCommand(Compilation &C, const JobAction &JA,
304304
for (const auto &II : Inputs) {
305305
const auto *A = II.getAction();
306306
auto ArchStr = llvm::StringRef(A->getOffloadingArch());
307-
BundlerTargetArg +=
308-
"," + OffloadKind + "-" + normalizeForBundler(TT, !ArchStr.empty());
307+
BundlerTargetArg += ',' + OffloadKind + '-';
308+
if (ArchStr == "amdgcnspirv")
309+
BundlerTargetArg +=
310+
normalizeForBundler(llvm::Triple("spirv64-amd-amdhsa"), true);
311+
else
312+
BundlerTargetArg += normalizeForBundler(TT, !ArchStr.empty());
309313
if (!ArchStr.empty())
310-
BundlerTargetArg += "-" + ArchStr.str();
314+
BundlerTargetArg += '-' + ArchStr.str();
311315
}
312316
BundlerArgs.push_back(Args.MakeArgString(BundlerTargetArg));
313317

clang/test/Driver/hip-toolchain-no-rdc.hip

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
// RUN: %t/a.o %t/b.o \
3737
// RUN: 2>&1 | FileCheck -check-prefixes=LKONLY %s
3838

39+
// RUN: %clang -### --target=x86_64-linux-gnu \
40+
// RUN: --offload-arch=amdgcnspirv --offload-arch=gfx900 \
41+
// RUN: %s -nogpuinc -nogpulib \
42+
// RUN: 2>&1 | FileCheck -check-prefixes=AMDGCNSPIRV %s
43+
3944
//
4045
// Compile device code in a.cu to code object for gfx803.
4146
//
@@ -177,3 +182,16 @@
177182
// LKONLY-NOT: {{".*/llc"}}
178183
// LKONLY: [[LD:".*ld.*"]] {{.*}} "{{.*/a.o}}" "{{.*/b.o}}"
179184
// LKONLY-NOT: "-T" "{{.*}}.lk"
185+
186+
//
187+
// Check mixed AMDGCNSPIRV and concrete GPU arch.
188+
//
189+
190+
// AMDGCNSPIRV: "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}}"-emit-obj" {{.*}} "-o" "[[AMDGCNSPV_OBJ:.*o]]"
191+
// AMDGCNSPIRV: {{".*llvm-link.*"}} "-o" "[[AMDGCNSPV_TMP:.*out]]" "[[AMDGCNSPV_OBJ]]"
192+
// AMDGCNSPIRV: {{".*llvm-spirv.*"}} "--spirv-max-version=1.6" "--spirv-ext=+all" {{.*}} "[[AMDGCNSPV_TMP]]" {{.*}}"-o" "[[AMDGCNSPV_CO:.*out]]"
193+
// AMDGCNSPIRV: "-cc1" "-triple" "amdgcn-amd-amdhsa" {{.*}}"-emit-obj" {{.*}}"-target-cpu" "gfx900"{{.*}} "-o" "[[GFX900_OBJ:.*o]]"
194+
// AMDGCNSPIRV: {{".*lld.*"}} {{.*}}"-plugin-opt=mcpu=gfx900" {{.*}} "-o" "[[GFX900_CO:.*out]]" {{.*}}"[[GFX900_OBJ]]"
195+
// AMDGCNSPIRV: {{".*clang-offload-bundler.*"}} "-type=o"
196+
// AMDGCNSPIRV-SAME: "-targets={{.*}}hipv4-spirv64-amd-amdhsa--amdgcnspirv,hipv4-amdgcn-amd-amdhsa--gfx900"
197+
// AMDGCNSPIRV-SAME: "-input=[[AMDGCNSPV_CO]]" "-input=[[GFX900_CO]]"

0 commit comments

Comments
 (0)