[clang] [Clang] Lift HIPSPV onto the new offload driver (WIP) (PR #168043)
Henry Linjamäki via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 28 01:21:46 PST 2025
https://github.com/linehill updated https://github.com/llvm/llvm-project/pull/168043
>From 9ed7d1b1d3313fe657432c1f93e6cd50b122ca57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henry=20Linjam=C3=A4ki?= <henry.linjamaki at tuni.fi>
Date: Tue, 11 Nov 2025 12:17:58 +0200
Subject: [PATCH 1/4] Lift HIPSPV onto the new offload driver
---
clang/include/clang/Options/Options.td | 4 ++
clang/lib/Driver/Driver.cpp | 15 +++++-
clang/lib/Driver/ToolChains/Clang.cpp | 14 ++++--
clang/lib/Driver/ToolChains/HIPSPV.cpp | 48 +++++++++++++++----
clang/lib/Driver/ToolChains/HIPSPV.h | 7 ++-
.../ClangLinkerWrapper.cpp | 30 ++++++++----
6 files changed, 91 insertions(+), 27 deletions(-)
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 756d6deed7130..41313439705cf 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -1003,6 +1003,10 @@ def Xthinlto_distributor_EQ : CommaJoined<["-"], "Xthinlto-distributor=">,
"multiple times or with comma-separated values.">,
MetaVarName<"<arg>">,
Group<Link_Group>;
+def Xoffload_compiler : JoinedAndSeparate<["-"], "Xoffload-compiler">,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Pass <arg> to the offload compilers or the ones identified by -<triple>">,
+ MetaVarName<"<triple> <arg>">, Group<Link_Group>;
def Xoffload_linker : JoinedAndSeparate<["-"], "Xoffload-linker">,
Visibility<[ClangOption, FlangOption]>,
HelpText<"Pass <arg> to the offload linkers or the ones identified by -<triple>">,
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 8644a271a04b5..0217336e34b02 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4991,6 +4991,12 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
// Compiling HIP in device-only non-RDC mode requires linking each action
// individually.
for (Action *&A : DeviceActions) {
+ auto OsName = A->getOffloadingToolChain()
+ ? A->getOffloadingToolChain()->getTriple().getOSName()
+ : StringRef();
+ bool IsHIPSPV = A->getOffloadingToolChain() &&
+ A->getOffloadingToolChain()->getTriple().isSPIRV() &&
+ (OsName == "hipspv" || OsName == "chipstar");
bool IsAMDGCNSPIRV = A->getOffloadingToolChain() &&
A->getOffloadingToolChain()->getTriple().getOS() ==
llvm::Triple::OSType::AMDHSA &&
@@ -4999,13 +5005,13 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
options::OPT_no_use_spirv_backend,
/*Default=*/false);
- // Special handling for the HIP SPIR-V toolchain in device-only.
+ // Special handling for the HIP SPIR-V toolchains in device-only.
// The translator path has a linking step, whereas the SPIR-V backend path
// does not to avoid any external dependency such as spirv-link. The
// linking step is skipped for the SPIR-V backend path.
bool IsAMDGCNSPIRVWithBackend = IsAMDGCNSPIRV && UseSPIRVBackend;
- if ((A->getType() != types::TY_Object && !IsAMDGCNSPIRV &&
+ if ((A->getType() != types::TY_Object && !IsAMDGCNSPIRV && !IsHIPSPV &&
A->getType() != types::TY_LTO_BC) ||
HIPRelocatableObj || !HIPNoRDC || !offloadDeviceOnly() ||
(IsAMDGCNSPIRVWithBackend && offloadDeviceOnly()))
@@ -7039,6 +7045,11 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
break;
case llvm::Triple::spirv32:
case llvm::Triple::spirv64:
+ if (Target.getOSName() == "hipspv") {
+ TC = std::make_unique<toolchains::HIPSPVToolChain>(*this, Target,
+ Args);
+ break;
+ }
TC = std::make_unique<toolchains::SPIRVToolChain>(*this, Target, Args);
break;
case llvm::Triple::csky:
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 0380568412e62..feb28e380ee2b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -9069,6 +9069,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
OPT_v,
OPT_cuda_path_EQ,
OPT_rocm_path_EQ,
+ OPT_hip_path_EQ,
OPT_O_Group,
OPT_g_Group,
OPT_g_flags_Group,
@@ -9198,18 +9199,21 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
Linker->ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput);
const auto &LinkCommand = C.getJobs().getJobs().back();
- // Forward -Xoffload-linker<-triple> arguments to the device link job.
- for (Arg *A : Args.filtered(options::OPT_Xoffload_linker)) {
+ for (Arg *A :
+ Args.filtered(options::OPT_Xoffload_compiler, OPT_Xoffload_linker)) {
StringRef Val = A->getValue(0);
+ bool IsLinkJob = A->getOption().getID() == OPT_Xoffload_linker;
+ auto WrapperOption =
+ IsLinkJob ? Twine("--device-linker=") : Twine("--device-compiler=");
if (Val.empty())
- CmdArgs.push_back(
- Args.MakeArgString(Twine("--device-linker=") + A->getValue(1)));
+ CmdArgs.push_back(Args.MakeArgString(WrapperOption + A->getValue(1)));
else
CmdArgs.push_back(Args.MakeArgString(
- "--device-linker=" +
+ WrapperOption +
ToolChain::getOpenMPTriple(Val.drop_front()).getTriple() + "=" +
A->getValue(1)));
}
+ Args.ClaimAllArgs(options::OPT_Xoffload_compiler);
Args.ClaimAllArgs(options::OPT_Xoffload_linker);
// Embed bitcode instead of an object in JIT mode.
diff --git a/clang/lib/Driver/ToolChains/HIPSPV.cpp b/clang/lib/Driver/ToolChains/HIPSPV.cpp
index be0f49d8e1497..4df241508f39e 100644
--- a/clang/lib/Driver/ToolChains/HIPSPV.cpp
+++ b/clang/lib/Driver/ToolChains/HIPSPV.cpp
@@ -119,7 +119,16 @@ void HIPSPV::Linker::ConstructJob(Compilation &C, const JobAction &JA,
HIPSPVToolChain::HIPSPVToolChain(const Driver &D, const llvm::Triple &Triple,
const ToolChain &HostTC, const ArgList &Args)
- : ToolChain(D, Triple, Args), HostTC(HostTC) {
+ : ToolChain(D, Triple, Args), HostTC(&HostTC) {
+ // Lookup binaries into the driver directory, this is used to
+ // discover the clang-offload-bundler executable.
+ getProgramPaths().push_back(getDriver().Dir);
+}
+
+// Non-offloading toolchain. Primaly used by clang-offload-linker.
+HIPSPVToolChain::HIPSPVToolChain(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args)
+ : ToolChain(D, Triple, Args), HostTC(nullptr) {
// Lookup binaries into the driver directory, this is used to
// discover the clang-offload-bundler executable.
getProgramPaths().push_back(getDriver().Dir);
@@ -128,7 +137,14 @@ HIPSPVToolChain::HIPSPVToolChain(const Driver &D, const llvm::Triple &Triple,
void HIPSPVToolChain::addClangTargetOptions(
const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
Action::OffloadKind DeviceOffloadingKind) const {
- HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind);
+
+ if (!HostTC) {
+ assert(DeviceOffloadingKind == Action::OFK_None &&
+ "Need host toolchain for offloading!");
+ return;
+ }
+
+ HostTC->addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind);
assert(DeviceOffloadingKind == Action::OFK_HIP &&
"Only HIP offloading kinds are supported for GPUs.");
@@ -159,27 +175,37 @@ Tool *HIPSPVToolChain::buildLinker() const {
}
void HIPSPVToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {
- HostTC.addClangWarningOptions(CC1Args);
+ if (HostTC)
+ HostTC->addClangWarningOptions(CC1Args);
+ ToolChain::addClangWarningOptions(CC1Args);
}
ToolChain::CXXStdlibType
HIPSPVToolChain::GetCXXStdlibType(const ArgList &Args) const {
- return HostTC.GetCXXStdlibType(Args);
+ if (HostTC)
+ return HostTC->GetCXXStdlibType(Args);
+ return ToolChain::GetCXXStdlibType(Args);
}
void HIPSPVToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
- HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
+ if (HostTC)
+ HostTC->AddClangSystemIncludeArgs(DriverArgs, CC1Args);
+ ToolChain::AddClangSystemIncludeArgs(DriverArgs, CC1Args);
}
void HIPSPVToolChain::AddClangCXXStdlibIncludeArgs(
const ArgList &Args, ArgStringList &CC1Args) const {
- HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args);
+ if (HostTC)
+ HostTC->AddClangCXXStdlibIncludeArgs(Args, CC1Args);
+ ToolChain::AddClangCXXStdlibIncludeArgs(Args, CC1Args);
}
void HIPSPVToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
ArgStringList &CC1Args) const {
- HostTC.AddIAMCUIncludeArgs(Args, CC1Args);
+ if (HostTC)
+ HostTC->AddIAMCUIncludeArgs(Args, CC1Args);
+ ToolChain::AddIAMCUIncludeArgs(Args, CC1Args);
}
void HIPSPVToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
@@ -273,12 +299,16 @@ SanitizerMask HIPSPVToolChain::getSupportedSanitizers() const {
// This behavior is necessary because the host and device toolchains
// invocations often share the command line, so the device toolchain must
// tolerate flags meant only for the host toolchain.
- return HostTC.getSupportedSanitizers();
+ if (HostTC)
+ return HostTC->getSupportedSanitizers();
+ return ToolChain::getSupportedSanitizers();
}
VersionTuple HIPSPVToolChain::computeMSVCVersion(const Driver *D,
const ArgList &Args) const {
- return HostTC.computeMSVCVersion(D, Args);
+ if (HostTC)
+ return HostTC->computeMSVCVersion(D, Args);
+ return ToolChain::computeMSVCVersion(D, Args);
}
void HIPSPVToolChain::adjustDebugInfoKind(
diff --git a/clang/lib/Driver/ToolChains/HIPSPV.h b/clang/lib/Driver/ToolChains/HIPSPV.h
index caf6924151446..068040ee4f491 100644
--- a/clang/lib/Driver/ToolChains/HIPSPV.h
+++ b/clang/lib/Driver/ToolChains/HIPSPV.h
@@ -47,9 +47,12 @@ class LLVM_LIBRARY_VISIBILITY HIPSPVToolChain final : public ToolChain {
public:
HIPSPVToolChain(const Driver &D, const llvm::Triple &Triple,
const ToolChain &HostTC, const llvm::opt::ArgList &Args);
+ HIPSPVToolChain(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args);
const llvm::Triple *getAuxTriple() const override {
- return &HostTC.getTriple();
+ assert(HostTC);
+ return &HostTC->getTriple();
}
void
@@ -90,7 +93,7 @@ class LLVM_LIBRARY_VISIBILITY HIPSPVToolChain final : public ToolChain {
bool isPICDefaultForced() const override { return false; }
bool SupportsProfiling() const override { return false; }
- const ToolChain &HostTC;
+ const ToolChain *HostTC = nullptr;
protected:
Tool *buildLinker() const override;
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index fcb6c591ec5ca..0c0294a38a3a9 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -409,8 +409,19 @@ fatbinary(ArrayRef<std::pair<StringRef, StringRef>> InputFiles,
} // namespace nvptx
namespace amdgcn {
+
+// Constructs a triple string for clang offload bundler.
+// NOTE: copied from HIPUtility.cpp.
+static std::string normalizeForBundler(const llvm::Triple &T,
+ bool HasTargetID) {
+ return HasTargetID ? (T.getArchName() + "-" + T.getVendorName() + "-" +
+ T.getOSName() + "-" + T.getEnvironmentName())
+ .str()
+ : T.normalize(llvm::Triple::CanonicalForm::FOUR_IDENT);
+}
+
Expected<StringRef>
-fatbinary(ArrayRef<std::pair<StringRef, StringRef>> InputFiles,
+fatbinary(ArrayRef<std::tuple<StringRef, StringRef, StringRef>> InputFiles,
const ArgList &Args) {
llvm::TimeTraceScope TimeScope("AMDGPU Fatbinary");
@@ -441,10 +452,10 @@ fatbinary(ArrayRef<std::pair<StringRef, StringRef>> InputFiles,
Args.MakeArgString(Twine("-compression-level=") + Arg->getValue()));
SmallVector<StringRef> Targets = {"-targets=host-x86_64-unknown-linux-gnu"};
- for (const auto &[File, Arch] : InputFiles) {
- Targets.push_back(Saver.save(Arch == "amdgcnspirv"
- ? "hip-spirv64-amd-amdhsa--" + Arch
- : "hip-amdgcn-amd-amdhsa--" + Arch));
+ for (const auto &[File, TripleRef, Arch] : InputFiles) {
+ std::string NormalizedTriple =
+ normalizeForBundler(Triple(TripleRef), !Arch.empty());
+ Targets.push_back(Saver.save("hip-" + NormalizedTriple + "-" + Arch));
}
CmdArgs.push_back(Saver.save(llvm::join(Targets, ",")));
@@ -453,7 +464,7 @@ fatbinary(ArrayRef<std::pair<StringRef, StringRef>> InputFiles,
#else
CmdArgs.push_back("-input=/dev/null");
#endif
- for (const auto &[File, Arch] : InputFiles)
+ for (const auto &[File, Triple, Arch] : InputFiles)
CmdArgs.push_back(Saver.save("-input=" + File));
CmdArgs.push_back(Saver.save("-output=" + *TempFileOrErr));
@@ -816,10 +827,11 @@ bundleCuda(ArrayRef<OffloadingImage> Images, const ArgList &Args) {
Expected<SmallVector<std::unique_ptr<MemoryBuffer>>>
bundleHIP(ArrayRef<OffloadingImage> Images, const ArgList &Args) {
- SmallVector<std::pair<StringRef, StringRef>, 4> InputFiles;
+ SmallVector<std::tuple<StringRef, StringRef, StringRef>, 4> InputFiles;
for (const OffloadingImage &Image : Images)
- InputFiles.emplace_back(std::make_pair(Image.Image->getBufferIdentifier(),
- Image.StringData.lookup("arch")));
+ InputFiles.emplace_back(std::make_tuple(Image.Image->getBufferIdentifier(),
+ Image.StringData.lookup("triple"),
+ Image.StringData.lookup("arch")));
auto FileOrErr = amdgcn::fatbinary(InputFiles, Args);
if (!FileOrErr)
>From a783638e82acef2bd97d7f794ddefd6e7ac5dc3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henry=20Linjam=C3=A4ki?= <henry.mikael.linjamaki at intel.com>
Date: Thu, 30 Nov 2023 14:42:23 +0200
Subject: [PATCH 2/4] HIPSPV: set allowed SPIR-V extensions for chipStar
---
clang/lib/Driver/Driver.cpp | 3 ++-
clang/lib/Driver/ToolChains/HIPSPV.cpp | 17 +++++++++++++++--
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 0217336e34b02..28c402d2cf6c8 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -7045,7 +7045,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
break;
case llvm::Triple::spirv32:
case llvm::Triple::spirv64:
- if (Target.getOSName() == "hipspv") {
+ if (Target.getOSName() == "hipspv" ||
+ Target.getOSName() == "chipstar") {
TC = std::make_unique<toolchains::HIPSPVToolChain>(*this, Target,
Args);
break;
diff --git a/clang/lib/Driver/ToolChains/HIPSPV.cpp b/clang/lib/Driver/ToolChains/HIPSPV.cpp
index 4df241508f39e..f9dc8c8bc39d7 100644
--- a/clang/lib/Driver/ToolChains/HIPSPV.cpp
+++ b/clang/lib/Driver/ToolChains/HIPSPV.cpp
@@ -93,9 +93,22 @@ void HIPSPV::Linker::constructLinkAndEmitSpirvCommand(
}
// Emit SPIR-V binary.
+ llvm::opt::ArgStringList TrArgs;
+ if (getToolChain().getTriple().getOSName() == "chipstar") {
+ // chipStar needs 1.2 for supporting warp-level primitivies via sub-group
+ // extensions. Strictly put we'd need 1.3 for the standard non-extension
+ // shuffle operations, but it's not supported by any backend driver of the
+ // chipStar.
+ TrArgs = {"--spirv-max-version=1.2",
+ "--spirv-ext=-all"
+ // Needed for experimental indirect call support.
+ ",+SPV_INTEL_function_pointers"
+ // Needed for shuffles below SPIR-V 1.3
+ ",+SPV_INTEL_subgroups"};
+ } else {
+ TrArgs = {"--spirv-max-version=1.1", "--spirv-ext=+all"};
+ }
- llvm::opt::ArgStringList TrArgs{"--spirv-max-version=1.1",
- "--spirv-ext=+all"};
InputInfo TrInput = InputInfo(types::TY_LLVM_BC, TempFile, "");
SPIRV::constructTranslateCommand(C, *this, JA, Output, TrInput, TrArgs);
}
>From 992e69a0dda392e7d9f8f4d458d1730b6ea7f885 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henry=20Linjam=C3=A4ki?= <henry.linjamaki at tuni.fi>
Date: Fri, 28 Nov 2025 11:08:01 +0200
Subject: [PATCH 3/4] HIPSPV: drop --spirv-max-version if subarch is defined
---
clang/lib/Driver/ToolChains/HIPSPV.cpp | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/HIPSPV.cpp b/clang/lib/Driver/ToolChains/HIPSPV.cpp
index f9dc8c8bc39d7..d16778d45af86 100644
--- a/clang/lib/Driver/ToolChains/HIPSPV.cpp
+++ b/clang/lib/Driver/ToolChains/HIPSPV.cpp
@@ -94,19 +94,24 @@ void HIPSPV::Linker::constructLinkAndEmitSpirvCommand(
// Emit SPIR-V binary.
llvm::opt::ArgStringList TrArgs;
- if (getToolChain().getTriple().getOSName() == "chipstar") {
+ auto T = getToolChain().getTriple();
+ bool HasNoSubArch = T.getSubArch() == llvm::Triple::NoSubArch;
+ if (T.getOSName() == "chipstar") {
// chipStar needs 1.2 for supporting warp-level primitivies via sub-group
// extensions. Strictly put we'd need 1.3 for the standard non-extension
// shuffle operations, but it's not supported by any backend driver of the
// chipStar.
- TrArgs = {"--spirv-max-version=1.2",
- "--spirv-ext=-all"
- // Needed for experimental indirect call support.
- ",+SPV_INTEL_function_pointers"
- // Needed for shuffles below SPIR-V 1.3
- ",+SPV_INTEL_subgroups"};
+ if (HasNoSubArch)
+ TrArgs.push_back("--spirv-max-version=1.2");
+ TrArgs.push_back("--spirv-ext=-all"
+ // Needed for experimental indirect call support.
+ ",+SPV_INTEL_function_pointers"
+ // Needed for shuffles below SPIR-V 1.3
+ ",+SPV_INTEL_subgroups");
} else {
- TrArgs = {"--spirv-max-version=1.1", "--spirv-ext=+all"};
+ if (HasNoSubArch)
+ TrArgs.push_back("--spirv-max-version=1.1");
+ TrArgs.push_back("--spirv-ext=+all");
}
InputInfo TrInput = InputInfo(types::TY_LLVM_BC, TempFile, "");
>From f488066839c22e9f74272c6e89e3212cb1cfdeb1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henry=20Linjam=C3=A4ki?= <henry.linjamaki at tuni.fi>
Date: Thu, 20 Nov 2025 13:02:40 +0200
Subject: [PATCH 4/4] HIPSPV: Add checks for --offload-new-driver
---
.../hipspv-spirv64-unknown-hipspv.bc | 0
.../Driver/hipspv-link-static-library.hip | 36 +++--
clang/test/Driver/hipspv-pass-plugin.hip | 42 ++++-
.../Driver/hipspv-toolchain-rdc-separate.hip | 66 ++++++++
clang/test/Driver/hipspv-toolchain-rdc.hip | 144 ++++++++++++------
clang/test/Driver/hipspv-toolchain.hip | 124 +++++++++++++--
6 files changed, 334 insertions(+), 78 deletions(-)
create mode 100644 clang/test/Driver/Inputs/hipspv/lib/hip-device-lib/hipspv-spirv64-unknown-hipspv.bc
create mode 100644 clang/test/Driver/hipspv-toolchain-rdc-separate.hip
diff --git a/clang/test/Driver/Inputs/hipspv/lib/hip-device-lib/hipspv-spirv64-unknown-hipspv.bc b/clang/test/Driver/Inputs/hipspv/lib/hip-device-lib/hipspv-spirv64-unknown-hipspv.bc
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/hipspv-link-static-library.hip b/clang/test/Driver/hipspv-link-static-library.hip
index 03126ae589a09..41895f3c936c1 100644
--- a/clang/test/Driver/hipspv-link-static-library.hip
+++ b/clang/test/Driver/hipspv-link-static-library.hip
@@ -4,25 +4,41 @@
// Create a dummy archive to test SDL linking
// RUN: rm -rf %t && mkdir %t
-// RUN: touch %t/dummy.bc
+// RUN: touch %t/dummy.bc
// RUN: llvm-ar cr %t/libSDL.a %t/dummy.bc
// Test that -l options are passed to llvm-link for --offload=spirv64
// RUN: %clang -### --target=x86_64-linux-gnu --offload=spirv64 \
// RUN: --hip-path=%S/Inputs/hipspv -nohipwrapperinc %s \
-// RUN: -L%t -lSDL \
-// RUN: 2>&1 | FileCheck -check-prefix=SDL-LINK %s
+// RUN: --no-offload-new-driver -L%t -lSDL \
+// RUN: 2>&1 | FileCheck -check-prefixes=ALL,SDL %s
-// Test that .a files are properly unbundled and passed to llvm-link
+// Test that .a files are properly unbundled and passed to llvm-link
// RUN: %clang -### --target=x86_64-linux-gnu --offload=spirv64 \
// RUN: --hip-path=%S/Inputs/hipspv -nohipwrapperinc %s \
-// RUN: %t/libSDL.a \
-// RUN: 2>&1 | FileCheck -check-prefix=SDL-ARCHIVE %s
+// RUN: --no-offload-new-driver %t/libSDL.a \
+// RUN: 2>&1 | FileCheck -check-prefixes=ALL,SDL %s
+
+// RUN: %clang --offload-new-driver -fgpu-rdc --offload=spirv64-unknown-hipspv \
+// RUN: -nogpuinc -nogpulib %s -c -o %t/tu0.o
+// RUN: %clang --offload-new-driver -fgpu-rdc --offload=spirv64-unknown-hipspv \
+// RUN: -nogpuinc -nogpulib %s -c -o %t/tu1.o
+// RUN: llvm-ar cr %t/libSDL2.a %t/tu1.o
+
+// RUN: %clang --offload-new-driver -fgpu-rdc \
+// RUN: -Xoffload-compiler-spirv64-unknown-hipspv \
+// RUN: --hip-path=%S/Inputs/hipspv -no-hip-rt %t/tu0.o %t/libSDL2.a \
+// A hacky trick to print clang commands invoked by clang-linker-wrapper
+// RUN: -v -Xlinker --emit-fatbin-only -Xoffload-compiler '-###' \
+// RUN: 2>&1 | FileCheck -check-prefixes=ALL,SDL-NEW %s
// Verify that the input files are added before the SDL files in llvm-link command
// This tests the ordering fix to match HIPAMD behavior
-// SDL-LINK: "{{.*}}clang-offload-bundler" "-unbundle" "-type=a" "-input={{.*}}libSDL.a" "-targets=hip-spirv64-unknown-unknown-unknown-generic" "-output=[[SDL_A:.*\.a]]" "-allow-missing-bundles"
-// SDL-LINK: "{{.*}}llvm-link" "{{.*}}.bc" "[[SDL_A]]" "-o"
+// SDL: "{{.*}}clang-offload-bundler" "-unbundle" "-type=a" "-input={{.*}}libSDL.a" "-targets=hip-spirv64-unknown-unknown-unknown-generic" "-output=[[SDL_A:.*\.a]]" "-allow-missing-bundles"
+// SDL: "{{.*}}llvm-link" "{{.*}}.bc" "[[SDL_A]]" "-o"
+// SDL-NEW: "{{.*}}clang-linker-wrapper"
+// SDL-NEW: "{{.*}}llvm-link" "{{.*}}.o" "{{.*}}.o"
-// SDL-ARCHIVE: "{{.*}}clang-offload-bundler" "-unbundle" "-type=a" "-input={{.*}}libSDL.a" "-targets=hip-spirv64-unknown-unknown-unknown-generic" "-output=[[SDL_A:.*\.a]]" "-allow-missing-bundles"
-// SDL-ARCHIVE: "{{.*}}llvm-link" "{{.*}}.bc" "[[SDL_A]]" "-o"
+// ALL: "{{.*}}opt"
+// ALL-SAME: "-load-pass-plugin" {{".*/hipspv/lib/libLLVMHipSpvPasses.so"}}
+// ALL-SAME: "-passes=hip-post-link-passes"
diff --git a/clang/test/Driver/hipspv-pass-plugin.hip b/clang/test/Driver/hipspv-pass-plugin.hip
index fc3c64b057352..c348fce15fa5e 100644
--- a/clang/test/Driver/hipspv-pass-plugin.hip
+++ b/clang/test/Driver/hipspv-pass-plugin.hip
@@ -1,20 +1,45 @@
// UNSUPPORTED: system-windows
// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
-// RUN: --hip-path=%S/Inputs/hipspv -nogpuinc %s \
-// RUN: 2>&1 | FileCheck --check-prefixes=FROM-HIP-PATH %s
+// RUN: --no-offload-new-driver --hip-path=%S/Inputs/hipspv -nogpuinc %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=ALL,FROM-HIP-PATH %s
// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
-// RUN: -nogpuinc -nogpulib --hipspv-pass-plugin=%S/Inputs/pass-plugin.so %s \
-// RUN: 2>&1 | FileCheck --check-prefixes=FROM-OPTION %s
+// RUN: --no-offload-new-driver -nogpuinc -nogpulib --hipspv-pass-plugin=%S/Inputs/pass-plugin.so %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=ALL,FROM-OPTION %s
// RUN: not %clang -### --target=x86_64-linux-gnu --offload=spirv64 \
-// RUN: -nogpuinc -nogpulib --hipspv-pass-plugin=foo.so %s \
-// RUN: 2>&1 | FileCheck --check-prefixes=FROM-OPTION-INVALID %s
+// RUN: --no-offload-new-driver -nogpuinc -nogpulib --hipspv-pass-plugin=foo.so %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=ALL,FROM-OPTION-INVALID %s
// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
-// RUN: -nogpuinc -nogpulib %s \
-// RUN: 2>&1 | FileCheck --check-prefixes=NO-PLUGIN %s
+// RUN: --no-offload-new-driver -nogpuinc -nogpulib %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=ALL,NO-PLUGIN %s
+
+// RUN: %clang --offload-new-driver -nogpuinc -nogpulib \
+// RUN: --offload=spirv64-unknown-hipspv \
+// RUN: --hip-path=%S/Inputs/hipspv -Xoffload-compiler \
+// RUN: '-###' -c %s -o /dev/null 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=ALL,FROM-HIP-PATH
+
+// RUN: %clang --offload-new-driver -nogpuinc -nogpulib \
+// RUN: --offload=spirv64-unknown-hipspv \
+// RUN: -Xoffload-compiler-spirv64-unknown-hipspv \
+// RUN: --hipspv-pass-plugin=%S/Inputs/pass-plugin.so -Xoffload-compiler \
+// RUN: '-###' -c %s -o /dev/null 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=ALL,FROM-OPTION
+
+// RUN: not %clang --offload-new-driver -nogpuinc -nogpulib \
+// RUN: --offload=spirv64-unknown-hipspv \
+// RUN: -Xoffload-compiler-spirv64-unknown-hipspv \
+// RUN: --hipspv-pass-plugin=foo.so -Xoffload-compiler \
+// RUN: '-###' -c %s -o /dev/null 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=ALL,FROM-OPTION-INVALID
+
+// RUN: %clang --offload-new-driver -nogpuinc -nogpulib \
+// RUN: --offload=spirv64-unknown-hipspv -Xoffload-compiler \
+// RUN: '-###' -c %s -o /dev/null 2>&1 \
+// RUN: | FileCheck %s --check-prefixes=ALL,NO-PLUGIN
// FROM-HIP-PATH: {{".*opt"}} {{".*.bc"}} "-load-pass-plugin"
// FROM-HIP-PATH-SAME: {{".*/Inputs/hipspv/lib/libLLVMHipSpvPasses.so"}}
@@ -23,3 +48,4 @@
// FROM-OPTION-INVALID: error: no such file or directory: 'foo.so'
// NO-PLUGIN-NOT: {{".*opt"}} {{".*.bc"}} "-load-pass-plugin"
// NO-PLUGIN-NOT: {{".*/Inputs/hipspv/lib/libLLVMHipSpvPasses.so"}}
+// ALL: {{".*llvm-spirv[^ ]*"}}
diff --git a/clang/test/Driver/hipspv-toolchain-rdc-separate.hip b/clang/test/Driver/hipspv-toolchain-rdc-separate.hip
new file mode 100644
index 0000000000000..1d269bec7d7a4
--- /dev/null
+++ b/clang/test/Driver/hipspv-toolchain-rdc-separate.hip
@@ -0,0 +1,66 @@
+// UNSUPPORTED: system-windows
+
+// RUN: %clang -### -x hip -target x86_64-linux-gnu \
+// RUN: --offload=spirv64-unknown-hipspv --offload-new-driver -fgpu-rdc -c \
+// RUN: --hip-path=%S/Inputs/hipspv -nohipwrapperinc \
+// RUN: %S/Inputs/hip_multiple_inputs/a.cu \
+// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck \
+// RUN: -DHIP_PATH=%S/Inputs/hipspv %s
+
+// CHECK: [[CLANG:".*clang[^ ]*"]] "-cc1" "-triple" "spirv64-unknown-hipspv"
+// CHECK-SAME: "-aux-triple" "[[HOST_TRIPLE:[^ ]*]]"
+// CHECK-SAME: "-emit-llvm-bc"
+// CHECK-SAME: "-fcuda-is-device" "-fcuda-allow-variadic-functions"
+// CHECK-SAME: "-fvisibility=hidden" "-fapply-global-visibility-to-externs"
+// CHECK-SAME: "-mlink-builtin-bitcode" "[[HIP_PATH]]/lib/hip-device-lib/hipspv-spirv64-unknown-hipspv.bc"
+// CHECK-SAME: "-fgpu-rdc"
+// CHECK-SAME: "-o" "[[A_DEV_BC:.*bc]]" "-x" "hip"
+// CHECK-SAME: "[[A_SRC:.*a.cu]]"
+
+// CHECK: "{{.*llvm-offload-binary[^ ]*}}" "-o" "[[A_BIN_PACKAGE:.*.out]]"
+// CHECK-SAME: "--image=file=[[A_DEV_BC]],triple=spirv64-unknown-hipspv,arch=generic,kind=hip"
+
+// CHECK: [[CLANG]] "-cc1" "-triple" "[[HOST_TRIPLE]]"
+// CHECK-SAME: "-aux-triple" "spirv64-unknown-hipspv"
+// CHECK-SAME: "-emit-obj"
+// CHECK-SAME: "-fgpu-rdc"
+// CHECK-SAME: "-fembed-offload-object=[[A_BIN_PACKAGE]]"
+// CHECK-SAME: "-o" "[[A_HOST_OBJ:.*o]]" "-x" "hip" "[[A_SRC]]"
+
+// CHECK: [[CLANG]] "-cc1" "-triple" "spirv64-unknown-hipspv"
+// CHECK-SAME: "-aux-triple" "[[HOST_TRIPLE]]"
+// CHECK-SAME: "-emit-llvm-bc"
+// CHECK-SAME: "-fcuda-is-device" "-fcuda-allow-variadic-functions"
+// CHECK-SAME: "-fvisibility=hidden" "-fapply-global-visibility-to-externs"
+// CHECK-SAME: "-mlink-builtin-bitcode" "[[HIP_PATH]]/lib/hip-device-lib/hipspv-spirv64-unknown-hipspv.bc"
+// CHECK-SAME: "-fgpu-rdc"
+// CHECK-SAME: "-o" "[[B_DEV_BC:.*bc]]" "-x" "hip"
+// CHECK-SAME: "[[B_SRC:.*b.hip]]"
+
+// CHECK: "{{.*llvm-offload-binary[^ ]*}}" "-o" "[[B_BIN_PACKAGE:.*.out]]"
+// CHECK-SAME: "--image=file=[[B_DEV_BC]],triple=spirv64-unknown-hipspv,arch=generic,kind=hip"
+
+// CHECK: [[CLANG]] "-cc1" "-triple" "[[HOST_TRIPLE]]"
+// CHECK-SAME: "-aux-triple" "spirv64-unknown-hipspv"
+// CHECK-SAME: "-emit-obj"
+// CHECK-SAME: "-fgpu-rdc"
+// CHECK-SAME: "-fembed-offload-object=[[B_BIN_PACKAGE]]"
+// CHECK-SAME: "-o" "[[B_HOST_OBJ:.*o]]" "-x" "hip"
+// CHECK-SAME: "[[B_SRC]]"
+
+// RUN: rm -rf %t && mkdir %t
+// RUN: touch %t/a.o %t/b.o
+// RUN: %clang -### -target x86_64-linux-gnu --offload-new-driver -fgpu-rdc \
+// RUN: -Xoffload-compiler-spirv64-unknown-hipspv \
+// RUN: --hip-path=%S/Inputs/hipspv \
+// RUN: -no-hip-rt %t/a.o %t/b.o \
+// RUN: 2>&1 | FileCheck -check-prefixes=LINK \
+// RUN: -DHIP_PATH=%S/Inputs/hipspv %s
+
+// LINK: "{{.*clang-linker-wrapper[^ ]*}}"
+// LINK-SAME: "--host-triple=x86_64-unknown-linux-gnu"
+// LINK-SAME: "--device-compiler=spirv64-unknown-hipspv=--hip-path=[[HIP_PATH]]"
+// LINK-SAME: "-o" "a.out"
+// LINK-SAME: "{{.*a[.]o}}" "{{.*b[.]o}}"
+// LINK-NOT: -lamdhip64
diff --git a/clang/test/Driver/hipspv-toolchain-rdc.hip b/clang/test/Driver/hipspv-toolchain-rdc.hip
index acdadacc49064..f2dfe6179bcf8 100644
--- a/clang/test/Driver/hipspv-toolchain-rdc.hip
+++ b/clang/test/Driver/hipspv-toolchain-rdc.hip
@@ -4,57 +4,113 @@
// RUN: --no-offload-new-driver -fgpu-rdc --hip-path=%S/Inputs/hipspv -nohipwrapperinc \
// RUN: %S/Inputs/hip_multiple_inputs/a.cu \
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
-// RUN: 2>&1 | FileCheck %s
+// RUN: 2>&1 | FileCheck --check-prefix=OLD %s
+
+// RUN: %clang -### -x hip -target x86_64-linux-gnu \
+// RUN: --offload=spirv64-unknown-hipspv --offload-new-driver -fgpu-rdc \
+// RUN: --hip-path=%S/Inputs/hipspv -nohipwrapperinc -no-hip-rt \
+// RUN: %S/Inputs/hip_multiple_inputs/a.cu \
+// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck --check-prefix=NEW \
+// RUN: -DOFFLOAD_TRIPLE=spirv64-unknown-hipspv -DHIP_PATH=%S/Inputs/hipspv %s
// Emit objects for host side path
-// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "x86_64-unknown-linux-gnu"
-// CHECK-SAME: "-aux-triple" "spirv64"
-// CHECK-SAME: "-emit-obj"
-// CHECK-SAME: "-fgpu-rdc"
-// CHECK-SAME: {{.*}} "-o" [[A_OBJ_HOST:".*o"]] "-x" "hip"
-// CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]]
-
-// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu"
-// CHECK-SAME: "-aux-triple" "spirv64"
-// CHECK-SAME: "-emit-obj"
-// CHECK-SAME: "-fgpu-rdc"
-// CHECK-SAME: {{.*}} "-o" [[B_OBJ_HOST:".*o"]] "-x" "hip"
-// CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]]
+// OLD: [[CLANG:".*clang.*"]] "-cc1" "-triple" "x86_64-unknown-linux-gnu"
+// OLD-SAME: "-aux-triple" "spirv64"
+// OLD-SAME: "-emit-obj"
+// OLD-SAME: "-fgpu-rdc"
+// OLD-SAME: {{.*}} "-o" [[A_OBJ_HOST:".*o"]] "-x" "hip"
+// OLD-SAME: {{.*}} [[A_SRC:".*a.cu"]]
+
+// OLD: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu"
+// OLD-SAME: "-aux-triple" "spirv64"
+// OLD-SAME: "-emit-obj"
+// OLD-SAME: "-fgpu-rdc"
+// OLD-SAME: {{.*}} "-o" [[B_OBJ_HOST:".*o"]] "-x" "hip"
+// OLD-SAME: {{.*}} [[B_SRC:".*b.hip"]]
// Emit code (LLVM BC) for device side path.
-// CHECK: [[CLANG]] "-cc1" "-triple" "spirv64"
-// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
-// CHECK-SAME: "-emit-llvm-bc"
-// CHECK-SAME: "-fcuda-is-device" "-fcuda-allow-variadic-functions"
-// CHECK-SAME: "-fvisibility=hidden" "-fapply-global-visibility-to-externs"
-// CHECK-SAME: "-fgpu-rdc"
-// CHECK-SAME: {{.*}} "-o" [[A_BC1:".*bc"]] "-x" "hip"
-// CHECK-SAME: {{.*}} [[A_SRC]]
-
-// CHECK: [[CLANG]] "-cc1" "-triple" "spirv64"
-// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
-// CHECK-SAME: "-emit-llvm-bc"
-// CHECK-SAME: "-fcuda-is-device" "-fcuda-allow-variadic-functions"
-// CHECK-SAME: "-fvisibility=hidden" "-fapply-global-visibility-to-externs"
-// CHECK-SAME: "-fgpu-rdc"
-// CHECK-SAME: {{.*}} "-o" [[B_BC1:".*bc"]] "-x" "hip"
-// CHECK-SAME: {{.*}} [[B_SRC]]
+// OLD: [[CLANG]] "-cc1" "-triple" "spirv64"
+// OLD-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// OLD-SAME: "-emit-llvm-bc"
+// OLD-SAME: "-fcuda-is-device" "-fcuda-allow-variadic-functions"
+// OLD-SAME: "-fvisibility=hidden" "-fapply-global-visibility-to-externs"
+// OLD-SAME: "-fgpu-rdc"
+// OLD-SAME: {{.*}} "-o" [[A_BC1:".*bc"]] "-x" "hip"
+// OLD-SAME: {{.*}} [[A_SRC]]
+
+// OLD: [[CLANG]] "-cc1" "-triple" "spirv64"
+// OLD-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// OLD-SAME: "-emit-llvm-bc"
+// OLD-SAME: "-fcuda-is-device" "-fcuda-allow-variadic-functions"
+// OLD-SAME: "-fvisibility=hidden" "-fapply-global-visibility-to-externs"
+// OLD-SAME: "-fgpu-rdc"
+// OLD-SAME: {{.*}} "-o" [[B_BC1:".*bc"]] "-x" "hip"
+// OLD-SAME: {{.*}} [[B_SRC]]
// Link device code, lower it with HIPSPV passes and emit SPIR-V binary.
-// CHECK: {{".*llvm-link.*"}} [[A_BC1]] [[B_BC1]] "-o" [[AB_LINK:".*bc"]]
-// CHECK: {{".*opt.*"}} [[AB_LINK]] "-load-pass-plugin"
-// CHECK-SAME: "{{.*}}/Inputs/hipspv/lib/libLLVMHipSpvPasses.so"
-// CHECK-SAME: "-o" [[AB_LOWER:".*bc"]]
-// CHECK: {{".*llvm-spirv"}} "--spirv-max-version=1.1" "--spirv-ext=+all"
-// CHECK-SAME: [[AB_LOWER]] "-o" "[[AB_SPIRV:.*out]]"
+// OLD: {{".*llvm-link.*"}} [[A_BC1]] [[B_BC1]] "-o" [[AB_LINK:".*bc"]]
+// OLD: {{".*opt.*"}} [[AB_LINK]] "-load-pass-plugin"
+// OLD-SAME: "{{.*}}/Inputs/hipspv/lib/libLLVMHipSpvPasses.so"
+// OLD-SAME: "-o" [[AB_LOWER:".*bc"]]
+// OLD: {{".*llvm-spirv"}} "--spirv-max-version=1.1" "--spirv-ext=+all"
+// OLD-SAME: [[AB_LOWER]] "-o" "[[AB_SPIRV:.*out]]"
// Construct fat binary object.
-// CHECK: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" "-bundle-align=4096"
-// CHECK-SAME: "-targets={{.*}},hip-spirv64----generic"
-// CHECK-SAME: "-input=/dev/null" "-input=[[AB_SPIRV]]"
-// CHECK-SAME: "-output=[[AB_FATBIN:.*hipfb]]"
-// CHECK: {{".*clang.*"}} "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin"
+// OLD: [[BUNDLER:".*clang-offload-bundler"]] "-type=o" "-bundle-align=4096"
+// OLD-SAME: "-targets={{.*}},hip-spirv64----generic"
+// OLD-SAME: "-input=/dev/null" "-input=[[AB_SPIRV]]"
+// OLD-SAME: "-output=[[AB_FATBIN:.*hipfb]]"
+// OLD: {{".*clang.*"}} "-o" [[OBJBUNDLE:".*o"]] "{{.*}}.mcin"
// Output the executable
-// CHECK: {{".*ld.*"}} {{.*}}"-o" "a.out" {{.*}} [[A_OBJ_HOST]] [[B_OBJ_HOST]]
-// CHECK-SAME: [[OBJBUNDLE]]
+// OLD: {{".*ld.*"}} {{.*}}"-o" "a.out" {{.*}} [[A_OBJ_HOST]] [[B_OBJ_HOST]]
+// OLD-SAME: [[OBJBUNDLE]]
+
+// NEW: [[CLANG:".*clang[^ ]*"]] "-cc1" "-triple" "[[OFFLOAD_TRIPLE]]"
+// NEW-SAME: "-aux-triple" "[[HOST_TRIPLE:[^ ]*]]"
+// NEW-SAME: "-emit-llvm-bc"
+// NEW-SAME: "-fcuda-is-device" "-fcuda-allow-variadic-functions"
+// NEW-SAME: "-fvisibility=hidden" "-fapply-global-visibility-to-externs"
+// NEW-SAME: "-mlink-builtin-bitcode" "[[HIP_PATH]]/lib/hip-device-lib/hipspv-spirv64-unknown-hipspv.bc"
+// NEW-SAME: "-fgpu-rdc"
+// NEW-SAME: "-o" "[[A_DEV_BC:.*bc]]" "-x" "hip"
+// NEW-SAME: "[[A_SRC:.*a.cu]]"
+
+// NEW: "{{.*llvm-offload-binary[^ ]*}}" "-o" "[[A_BIN_PACKAGE:.*.out]]"
+// NEW-SAME: "--image=file=[[A_DEV_BC]],triple=[[OFFLOAD_TRIPLE]],arch=generic,kind=hip"
+
+// NEW: [[CLANG]] "-cc1" "-triple" "[[HOST_TRIPLE]]"
+// NEW-SAME: "-aux-triple" "[[OFFLOAD_TRIPLE]]"
+// NEW-SAME: "-emit-obj"
+// NEW-SAME: "-fgpu-rdc"
+// NEW-SAME: "-fembed-offload-object=[[A_BIN_PACKAGE]]"
+// NEW-SAME: "-o" "[[A_HOST_OBJ:.*o]]" "-x" "hip" "[[A_SRC]]"
+
+// NEW: [[CLANG]] "-cc1" "-triple" "[[OFFLOAD_TRIPLE]]"
+// NEW-SAME: "-aux-triple" "[[HOST_TRIPLE]]"
+// NEW-SAME: "-emit-llvm-bc"
+// NEW-SAME: "-fcuda-is-device" "-fcuda-allow-variadic-functions"
+// NEW-SAME: "-fvisibility=hidden" "-fapply-global-visibility-to-externs"
+// NEW-SAME: "-mlink-builtin-bitcode" "[[HIP_PATH]]/lib/hip-device-lib/hipspv-spirv64-unknown-hipspv.bc"
+// NEW-SAME: "-fgpu-rdc"
+// NEW-SAME: "-o" "[[B_DEV_BC:.*bc]]" "-x" "hip"
+// NEW-SAME: "[[B_SRC:.*b.hip]]"
+
+// NEW: "{{.*llvm-offload-binary[^ ]*}}" "-o" "[[B_BIN_PACKAGE:.*.out]]"
+// NEW-SAME: "--image=file=[[B_DEV_BC]],triple=[[OFFLOAD_TRIPLE]],arch=generic,kind=hip"
+
+// NEW: [[CLANG]] "-cc1" "-triple" "[[HOST_TRIPLE]]"
+// NEW-SAME: "-aux-triple" "[[OFFLOAD_TRIPLE]]"
+// NEW-SAME: "-emit-obj"
+// NEW-SAME: "-fgpu-rdc"
+// NEW-SAME: "-fembed-offload-object=[[B_BIN_PACKAGE]]"
+// NEW-SAME: "-o" "[[B_HOST_OBJ:.*o]]" "-x" "hip"
+// NEW-SAME: "[[B_SRC]]"
+
+// NEW: "{{.*clang-linker-wrapper[^ ]*}}"
+// NEW-SAME: "--device-compiler=[[OFFLOAD_TRIPLE]]=--hip-path=[[HIP_PATH]]"
+// NEW-SAME: "--host-triple=[[HOST_TRIPLE]]"
+// NEW-SAME: "-o" "a.out"
+// NEW-SAME: "[[A_HOST_OBJ]]" "[[B_HOST_OBJ]]"
+// NEW-NOT: -lamdhip64
diff --git a/clang/test/Driver/hipspv-toolchain.hip b/clang/test/Driver/hipspv-toolchain.hip
index 3c175ebf433cc..ce759427fe69c 100644
--- a/clang/test/Driver/hipspv-toolchain.hip
+++ b/clang/test/Driver/hipspv-toolchain.hip
@@ -2,37 +2,123 @@
// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64 \
// RUN: --no-offload-new-driver --hip-path=%S/Inputs/hipspv -nohipwrapperinc %s \
-// RUN: 2>&1 | FileCheck %s
+// RUN: 2>&1 | FileCheck --check-prefixes=CHECK,OLD \
+// RUN: -DTRIPLE=spirv64 %s
-// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "spirv64"
+// RUN: %clang -### -target x86_64-linux-gnu --offload=spirv64-unknown-hipspv \
+// RUN: --offload-new-driver --hip-path=%S/Inputs/hipspv -nohipwrapperinc %s \
+// RUN: 2>&1 | FileCheck --check-prefixes=CHECK,NEW \
+// RUN: -DTRIPLE=spirv64-unknown-hipspv -DHIP_PATH=%S/Inputs/hipspv %s
+
+// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "[[TRIPLE]]"
// CHECK-SAME: "-aux-triple" "{{.*}}" "-emit-llvm-bc"
// CHECK-SAME: "-fcuda-is-device"
// CHECK-SAME: "-fcuda-allow-variadic-functions"
-// CHECK-SAME: "-mlink-builtin-bitcode" {{".*/hipspv/lib/hip-device-lib/hipspv-spirv64.bc"}}
+// CHECK-SAME: "-mlink-builtin-bitcode" {{".*/hipspv/lib/hip-device-lib/hipspv-}}[[TRIPLE]].bc"
// CHECK-SAME: "-isystem" {{".*/hipspv/include"}}
// CHECK-SAME: "-fhip-new-launch-api"
-// CHECK-SAME: "-o" [[DEV_BC:".*bc"]]
+// CHECK-SAME: "-o" "[[OBJ_DEV:.*(o|bc)]]"
// CHECK-SAME: "-x" "hip"
-// CHECK: {{".*llvm-link"}} [[DEV_BC]] "-o" [[LINK_BC:".*bc"]]
+// OLD: {{".*llvm-link"}} "[[OBJ_DEV]]" "-o" [[LINK_BC:".*bc"]]
+
+// OLD: {{".*opt"}} [[LINK_BC]] "-load-pass-plugin"
+// OLD-SAME: {{".*/hipspv/lib/libLLVMHipSpvPasses.so"}}
+// OLD-SAME: "-passes=hip-post-link-passes" "-o" [[LOWER_BC:".*bc"]]
+
+// OLD: {{".*llvm-spirv"}} "--spirv-max-version=1.1" "--spirv-ext=+all"
+// OLD-SAME: [[LOWER_BC]] "-o" "[[SPIRV_OUT:.*out]]"
-// CHECK: {{".*opt"}} [[LINK_BC]] "-load-pass-plugin"
-// CHECK-SAME: {{".*/hipspv/lib/libLLVMHipSpvPasses.so"}}
-// CHECK-SAME: "-passes=hip-post-link-passes" "-o" [[LOWER_BC:".*bc"]]
+// OLD: {{".*clang-offload-bundler"}} "-type=o" "-bundle-align=4096"
+// OLD-SAME: "-targets=host-x86_64-unknown-linux-gnu,hip-spirv64----generic"
+// OLD-SAME: "-input={{.*}}" "-input=[[SPIRV_OUT]]" "-output=[[BUNDLE:.*hipfb]]"
-// CHECK: {{".*llvm-spirv"}} "--spirv-max-version=1.1" "--spirv-ext=+all"
-// CHECK-SAME: [[LOWER_BC]] "-o" "[[SPIRV_OUT:.*out]]"
+// NEW: {{".*llvm-offload-binary"}} "-o" "[[PACKAGE:.*.out]]"
+// NEW-SAME: "--image=file=[[OBJ_DEV]],triple=[[TRIPLE]],arch=generic,kind=hip"
-// CHECK: {{".*clang-offload-bundler"}} "-type=o" "-bundle-align=4096"
-// CHECK-SAME: "-targets=host-x86_64-unknown-linux-gnu,hip-spirv64----generic"
-// CHECK-SAME: "-input={{.*}}" "-input=[[SPIRV_OUT]]" "-output=[[BUNDLE:.*hipfb]]"
+// NEW: {{".*clang-linker-wrapper"}} "--device-compiler=[[TRIPLE]]=--hip-path=[[HIP_PATH]]"
+// NEW-SAME: "--emit-fatbin-only" "-o" "[[BUNDLE:.*hipfb]]"
-// CHECK: [[CLANG]] "-cc1" "-triple" {{".*"}} "-aux-triple" "spirv64"
+// CHECK: [[CLANG]] "-cc1" "-triple" {{".*"}} "-aux-triple" "[[TRIPLE]]"
// CHECK-SAME: "-emit-obj"
// CHECK-SAME: "-fcuda-include-gpubinary" "[[BUNDLE]]"
// CHECK-SAME: "-o" [[OBJ_HOST:".*o"]] "-x" "hip"
-// CHECK: {{".*ld.*"}} {{.*}}[[OBJ_HOST]]
+// OLD: {{".*ld.*"}} {{.*}}[[OBJ_HOST]]
+
+// NEW: {{".*clang-linker-wrapper"}}
+// NEW-SAME: "--linker-path={{.*ld.*}}" "-o" "a.out"
+// NEW-SAME: [[OBJ_HOST]]
+
+//------------------------------------------------------------------------------
+// Check the clang command, invoked by the linker wrapper, selects the HIPSPV
+// toolchain.
+
+// RUN: %clang --offload-new-driver -nogpuinc -nogpulib \
+// RUN: --offload=spirv64-unknown-hipspv \
+// RUN: --hip-path=%S/Inputs/hipspv -Xoffload-compiler \
+// RUN: '-###' -c %s -o /dev/null 2>&1 \
+// RUN: | FileCheck %s --check-prefix=HIPSPV
+
+// HIPSPV: {{".*llvm-link"}}
+// HIPSPV-SAME: "{{[^ ]*.o}}" "-o" [[LINK_BC:".*bc"]]
+
+// HIPSPV: {{".*opt"}} [[LINK_BC]] "-load-pass-plugin"
+// HIPSPV-SAME: {{".*/hipspv/lib/libLLVMHipSpvPasses.so"}}
+// HIPSPV-SAME: "-passes=hip-post-link-passes" "-o" [[LOWER_BC:".*bc"]]
+
+// HIPSPV: {{".*llvm-spirv"}} "--spirv-max-version=1.1"
+// HIPSPV-SAME: "--spirv-ext=+all" [[LOWER_BC]] "-o" "[[SPIRV_OUT:.*img]]"
+
+// RUN: %clang --offload-new-driver -nogpuinc -nogpulib \
+// RUN: --offload=spirv64v1.3-unknown-hipspv \
+// RUN: --hip-path=%S/Inputs/hipspv -Xoffload-compiler \
+// RUN: '-###' -c %s -o /dev/null 2>&1 \
+// RUN: | FileCheck %s --check-prefix=HIPSPV_SUBARCH
+
+// HIPSPV_SUBARCH: {{".*llvm-link"}}
+// HIPSPV_SUBARCH-SAME: "{{[^ ]*.o}}" "-o" [[LINK_BC:".*bc"]]
+
+// HIPSPV_SUBARCH: {{".*opt"}} [[LINK_BC]] "-load-pass-plugin"
+// HIPSPV_SUBARCH-SAME: {{".*/hipspv/lib/libLLVMHipSpvPasses.so"}}
+// HIPSPV_SUBARCH-SAME: "-passes=hip-post-link-passes" "-o" [[LOWER_BC:".*bc"]]
+
+// HIPSPV_SUBARCH: {{".*llvm-spirv"}}
+// HIPSPV_SUBARCH-SAME: "--spirv-ext=+all" [[LOWER_BC]] "-o" "[[SPIRV_OUT:.*img]]"
+
+// RUN: %clang --offload-new-driver -nogpuinc -nogpulib \
+// RUN: --offload=spirv64-unknown-chipstar \
+// RUN: --hip-path=%S/Inputs/hipspv -Xoffload-compiler \
+// RUN: '-###' -c %s -o /dev/null 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHIPSTAR
+
+// CHIPSTAR: {{".*llvm-link"}}
+// CHIPSTAR-SAME: "{{[^ ]*.o}}" "-o" [[LINK_BC:".*bc"]]
+
+// CHIPSTAR: {{".*opt"}} [[LINK_BC]] "-load-pass-plugin"
+// CHIPSTAR-SAME: {{".*/hipspv/lib/libLLVMHipSpvPasses.so"}}
+// CHIPSTAR-SAME: "-passes=hip-post-link-passes" "-o" [[LOWER_BC:".*bc"]]
+
+// CHIPSTAR: {{".*llvm-spirv"}} "--spirv-max-version=1.2"
+// CHIPSTAR-SAME: "--spirv-ext=-all,+SPV_INTEL_function_pointers,+SPV_INTEL_subgroups"
+// CHIPSTAR-SAME: [[LOWER_BC]] "-o" "[[SPIRV_OUT:.*img]]"
+
+// RUN: %clang --offload-new-driver -nogpuinc -nogpulib \
+// RUN: --offload=spirv64v1.3-unknown-chipstar \
+// RUN: --hip-path=%S/Inputs/hipspv -Xoffload-compiler \
+// RUN: '-###' -c %s -o /dev/null 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHIPSTAR_SUBARCH
+
+// CHIPSTAR_SUBARCH: {{".*llvm-link"}}
+// CHIPSTAR_SUBARCH-SAME: "{{[^ ]*.o}}" "-o" [[LINK_BC:".*bc"]]
+
+// CHIPSTAR_SUBARCH: {{".*opt"}} [[LINK_BC]] "-load-pass-plugin"
+// CHIPSTAR_SUBARCH-SAME: {{".*/hipspv/lib/libLLVMHipSpvPasses.so"}}
+// CHIPSTAR_SUBARCH-SAME: "-passes=hip-post-link-passes" "-o" [[LOWER_BC:".*bc"]]
+
+// CHIPSTAR_SUBARCH: {{".*llvm-spirv"}}
+// CHIPSTAR_SUBARCH-SAME: "--spirv-ext=-all,+SPV_INTEL_function_pointers,+SPV_INTEL_subgroups"
+// CHIPSTAR_SUBARCH-SAME: [[LOWER_BC]] "-o" "[[SPIRV_OUT:.*img]]"
//-----------------------------------------------------------------------------
// Check llvm-spirv-<LLVM_VERSION_MAJOR> is used if it is found in PATH.
@@ -41,8 +127,14 @@
// RUN: && chmod +x %t/versioned/llvm-spirv-%llvm-version-major
// RUN: env "PATH=%t/versioned" %clang -### -target x86_64-linux-gnu \
// RUN: --offload=spirv64 --hip-path=%S/Inputs/hipspv -nohipwrapperinc \
-// RUN: %s 2>&1 \
+// RUN: --no-offload-new-driver %s 2>&1 \
// RUN: | FileCheck -DVERSION=%llvm-version-major \
// RUN: --check-prefix=VERSIONED %s
+// RUN: env "PATH=%t/versioned" %clang --offload-new-driver -nogpuinc \
+// RUN: -nogpulib --offload=spirv64-unknown-hipspv \
+// RUN: --hip-path=%S/Inputs/hipspv -Xoffload-compiler '-###' -c %s \
+// RUN: -o /dev/null 2>&1 \
+// RUN: | FileCheck -DVERSION=%llvm-version-major --check-prefix=VERSIONED %s
+
// VERSIONED: {{.*}}llvm-spirv-[[VERSION]]
More information about the cfe-commits
mailing list