[llvm-branch-commits] [clang] clang/AMDGPU: Merge toolchain subclasses (PR #204863)
Matt Arsenault via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Jun 19 12:23:07 PDT 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/204863
>From 013dffeb52bfe55e32eebc25112e4411eb4521c6 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 19 Jun 2026 10:27:47 +0200
Subject: [PATCH] clang/AMDGPU: Merge toolchain subclasses
Simplify the toolchain implementations by collapsing
them into one. Previously we had a confusing split. The
AMDGPUToolChain base class implemented much of the base
support. It was subclassed by ROCMToolChain, which would
have been more accurately described as the offloading subclass.
That was further subclassed into HIP and OpenMP specific subclasses.
Deleting those two is the important part of this change. There was
code duplication, and features arbitrarily handled in one but not
the other. The offload kind is passed in almost everywhere if you
really need to know the original language. However, I consider
this an antifeature, and it is really poor QoI to have the HIP
and OpenMP toolchains behave differently in any way. The platform
should be consistent and the driver behaviors should not depend
on the language.
There is additional mess in the handling of spirv, which this
only partially addresses. There are two different spirv toolchain
paths, which for some reason is keyed off of the amdhsa OS, which
is not the property that should change this. I think it will
ultimately be simplier to just merge all spirv handling into HIPSPV.
The copy-paste machine did most of the work here, and I manually
applied some logical fixups that became apparent after the merge.
Co-Authored-By: Claude <noreply at anthropic.com>
---
clang/lib/Driver/CMakeLists.txt | 1 -
clang/lib/Driver/Driver.cpp | 30 +-
clang/lib/Driver/ToolChains/AMDGPU.cpp | 387 ++++++++++++------
clang/lib/Driver/ToolChains/AMDGPU.h | 71 ++--
clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp | 94 -----
clang/lib/Driver/ToolChains/AMDGPUOpenMP.h | 68 ---
clang/lib/Driver/ToolChains/HIPAMD.cpp | 195 +--------
clang/lib/Driver/ToolChains/HIPAMD.h | 51 +--
.../test/Driver/hip-device-libs-llvm-env.hip | 7 +
clang/test/Driver/hip-toolchain-no-rdc.hip | 2 +-
10 files changed, 340 insertions(+), 566 deletions(-)
delete mode 100644 clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
delete mode 100644 clang/lib/Driver/ToolChains/AMDGPUOpenMP.h
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index cd410899c450f..81ccb31f499c5 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -53,7 +53,6 @@ add_clang_library(clangDriver
ToolChains/Arch/X86.cpp
ToolChains/AIX.cpp
ToolChains/AMDGPU.cpp
- ToolChains/AMDGPUOpenMP.cpp
ToolChains/AVR.cpp
ToolChains/BareMetal.cpp
ToolChains/Clang.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 6fa924f9ad6ed..d5fff3b857670 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -9,7 +9,6 @@
#include "clang/Driver/Driver.h"
#include "ToolChains/AIX.h"
#include "ToolChains/AMDGPU.h"
-#include "ToolChains/AMDGPUOpenMP.h"
#include "ToolChains/AVR.h"
#include "ToolChains/Arch/RISCV.h"
#include "ToolChains/BareMetal.h"
@@ -6974,12 +6973,12 @@ const ToolChain &Driver::getOffloadToolChain(
Args);
break;
case llvm::Triple::AMDHSA:
- if (Kind == Action::OFK_HIP)
- TC = std::make_unique<toolchains::HIPAMDToolChain>(*this, Target,
- *HostTC, Args);
- else if (Kind == Action::OFK_OpenMP)
- TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*this, Target,
- *HostTC, Args);
+ // For AMDHSA offloading (HIP, OpenMP), use the unified AMDGPUToolChain
+ // This handles both amdgcn-amd-amdhsa and spirv64-amd-amdhsa
+ // FIXME: This should not key off language or OS.
+ if (Kind == Action::OFK_HIP || Kind == Action::OFK_OpenMP)
+ TC = std::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args,
+ HostTC.get(), Kind);
break;
default:
break;
@@ -6988,6 +6987,11 @@ const ToolChain &Driver::getOffloadToolChain(
if (!TC) {
// Detect the toolchain based off of the target architecture if that failed.
switch (Target.getArch()) {
+ case llvm::Triple::amdgcn:
+ case llvm::Triple::r600:
+ TC = std::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args,
+ HostTC.get(), Kind);
+ break;
case llvm::Triple::spir:
case llvm::Triple::spir64:
case llvm::Triple::spirv:
@@ -7105,12 +7109,12 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
TC = std::make_unique<toolchains::SPIRVAMDToolChain>(*this, Target,
Args);
} else {
- bool DL = usesInput(Args, types::isOpenCL) ||
- usesInput(Args, types::isLLVMIR);
- TC = DL ? std::make_unique<toolchains::ROCMToolChain>(*this, Target,
- Args)
- : std::make_unique<toolchains::AMDGPUToolChain>(*this, Target,
- Args);
+ // Only link device libraries for OpenCL and LLVM IR inputs
+ bool ShouldLinkDeviceLibs = usesInput(Args, types::isOpenCL) ||
+ usesInput(Args, types::isLLVMIR);
+ TC = std::make_unique<toolchains::AMDGPUToolChain>(
+ *this, Target, Args, nullptr, Action::OFK_None,
+ ShouldLinkDeviceLibs);
}
break;
}
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 419926cb42aa0..6611b133057f5 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "AMDGPU.h"
+#include "HIPAMD.h"
#include "clang/Basic/TargetID.h"
#include "clang/Config/config.h"
#include "clang/Driver/CommonArgs.h"
@@ -672,10 +673,14 @@ void amdgpu::getAMDGPUTargetFeatures(const Driver &D,
/// AMDGPU Toolchain
AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args)
+ const ArgList &Args, const ToolChain *HostTC_,
+ Action::OffloadKind Kind,
+ bool ShouldLinkDeviceLibs_)
: Generic_ELF(D, Triple, Args),
OptionsDefault(
- {{options::OPT_O, "3"}, {options::OPT_cl_std_EQ, "CL1.2"}}) {
+ {{options::OPT_O, "3"}, {options::OPT_cl_std_EQ, "CL1.2"}}),
+ HostTC(HostTC_), UseHIPLinker(Kind == Action::OFK_HIP),
+ ShouldLinkDeviceLibs(ShouldLinkDeviceLibs_) {
loadMultilibsFromYAML(Args, D);
// Check code object version options. Emit warnings for legacy options
@@ -683,9 +688,19 @@ AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
// It is done here to avoid repeated warning or error messages for
// each tool invocation.
checkAMDGPUCodeObjectVersion(D, Args);
+
+ if (Triple.getOS() == llvm::Triple::AMDHSA &&
+ Triple.getEnvironment() != llvm::Triple::LLVM)
+ RocmInstallation->detectDeviceLibrary();
+
+ if (HostTC)
+ getProgramPaths().push_back(getDriver().Dir);
}
Tool *AMDGPUToolChain::buildLinker() const {
+ // FIXME: Should not have 2 linker paths.
+ if (UseHIPLinker)
+ return new tools::AMDGCN::Linker(*this);
return new tools::amdgpu::Linker(*this);
}
@@ -735,24 +750,41 @@ AMDGPUToolChain::TranslateArgs(const DerivedArgList &Args, BoundArch BA,
BA.ArchName);
}
- AMDGPUToolChain::ParsedTargetIDType PTID = checkTargetID(*DAL);
+ if (!getTriple().isSPIRV()) {
+ AMDGPUToolChain::ParsedTargetIDType PTID = checkTargetID(*DAL);
- // Synthesize feature flags for target ID modifiers (xnack, sramecc).
- if (PTID.OptionalFeatureMap) {
- const llvm::StringMap<bool> &FeatureMap = *PTID.OptionalFeatureMap;
+ // Synthesize feature flags for target ID modifiers (xnack, sramecc).
+ if (PTID.OptionalFeatureMap) {
+ const llvm::StringMap<bool> &FeatureMap = *PTID.OptionalFeatureMap;
+
+ auto XnackIt = FeatureMap.find("xnack");
+ if (XnackIt != FeatureMap.end()) {
+ DAL->AddFlagArg(nullptr, Opts.getOption(XnackIt->second
+ ? options::OPT_mxnack
+ : options::OPT_mno_xnack));
+ }
- auto XnackIt = FeatureMap.find("xnack");
- if (XnackIt != FeatureMap.end()) {
- DAL->AddFlagArg(nullptr,
- Opts.getOption(XnackIt->second ? options::OPT_mxnack
- : options::OPT_mno_xnack));
+ auto SrameccIt = FeatureMap.find("sramecc");
+ if (SrameccIt != FeatureMap.end()) {
+ DAL->AddFlagArg(nullptr,
+ Opts.getOption(SrameccIt->second
+ ? options::OPT_msramecc
+ : options::OPT_mno_sramecc));
+ }
}
+ }
- auto SrameccIt = FeatureMap.find("sramecc");
- if (SrameccIt != FeatureMap.end()) {
- DAL->AddFlagArg(nullptr, Opts.getOption(SrameccIt->second
- ? options::OPT_msramecc
- : options::OPT_mno_sramecc));
+ // Filter out sanitizer coverage options that are not supported for AMDGPU.
+ for (Arg *A : Args) {
+ // Sanitizer coverage is currently not supported for AMDGPU.
+ if (A->getOption().matches(options::OPT_fsan_cov_Group)) {
+ // Upgrade to error if the option was explicitly specified for device
+ bool IsExplicitDevice =
+ A->getBaseArg().getOption().matches(options::OPT_Xarch_device);
+ getDriver().Diag(IsExplicitDevice
+ ? diag::err_drv_unsupported_option_for_target
+ : diag::warn_drv_unsupported_option_for_target)
+ << A->getAsString(Args) << getTriple().str();
}
}
@@ -834,41 +866,28 @@ bool AMDGPUToolChain::isWave64(const llvm::opt::ArgList &DriverArgs,
options::OPT_mwavefrontsize64, options::OPT_mno_wavefrontsize64, false);
}
+void AMDGPUToolChain::addClangTargetOptions(
+ const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
+ BoundArch BA, Action::OffloadKind DeviceOffloadingKind) const {
+ if (DeviceOffloadingKind == Action::OFK_HIP) {
+ CC1Args.append({"-fcuda-is-device", "-fno-threadsafe-statics"});
+
+ if (!DriverArgs.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
+ false)) {
+ CC1Args.append({"-mllvm", "-amdgpu-internalize-symbols"});
+ if (DriverArgs.hasArgNoClaim(options::OPT_hipstdpar))
+ CC1Args.append({"-mllvm", "-amdgpu-enable-hipstdpar"});
+ }
-/// ROCM Toolchain
-ROCMToolChain::ROCMToolChain(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args)
- : AMDGPUToolChain(D, Triple, Args) {
- if (Triple.getEnvironment() != llvm::Triple::LLVM)
- RocmInstallation->detectDeviceLibrary();
-}
-
-DerivedArgList *
-ROCMToolChain::TranslateArgs(const DerivedArgList &Args, BoundArch BA,
- Action::OffloadKind DeviceOffloadKind) const {
- DerivedArgList *DAL =
- AMDGPUToolChain::TranslateArgs(Args, BA, DeviceOffloadKind);
-
- // Filter out sanitizer coverage options that are not supported for AMDGPU.
- for (Arg *A : Args) {
- // Sanitizer coverage is currently not supported for AMDGPU.
- if (A->getOption().matches(options::OPT_fsan_cov_Group)) {
- // Upgrade to error if the option was explicitly specified for device
- bool IsExplicitDevice =
- A->getBaseArg().getOption().matches(options::OPT_Xarch_device);
- getDriver().Diag(IsExplicitDevice
- ? diag::err_drv_unsupported_option_for_target
- : diag::warn_drv_unsupported_option_for_target)
- << A->getAsString(Args) << getTriple().str();
+ // FIXME: This should not depend on HIP
+ StringRef MaxThreadsPerBlock =
+ DriverArgs.getLastArgValue(options::OPT_gpu_max_threads_per_block_EQ);
+ if (!MaxThreadsPerBlock.empty()) {
+ CC1Args.push_back(DriverArgs.MakeArgString(
+ Twine("--gpu-max-threads-per-block=") + MaxThreadsPerBlock));
}
}
- return DAL;
-}
-
-void AMDGPUToolChain::addClangTargetOptions(
- const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
- BoundArch BA, Action::OffloadKind DeviceOffloadingKind) const {
// Default to "hidden" visibility, as object level linking will not be
// supported for the foreseeable future.
// TODO: remove the SPIR-V bypass once it can encode (hidden) visibility.
@@ -879,22 +898,54 @@ void AMDGPUToolChain::addClangTargetOptions(
CC1Args.push_back("-fapply-global-visibility-to-externs");
}
- // For SPIR-V we want to retain the pristine output of Clang CodeGen, since
- // optimizations might lose structure / information that is necessary for
- // generating optimal concrete AMDGPU code.
- // TODO: using the below option is a temporary placeholder until Clang
- // provides the required functionality, which essentially boils down to
- // -O0 being refactored / reworked to not imply optnone / remove TBAA.
- // Once that is added, we should pivot to that functionality, being
- // mindful to not corrupt the user provided and subsequently embedded
- // command-line (i.e. if the user asks for -O3 this is what the
- // finalisation should use).
- if (getTriple().isSPIRV() &&
- !DriverArgs.hasArg(options::OPT_disable_llvm_optzns))
- CC1Args.push_back("-disable-llvm-optzns");
-
- if (DeviceOffloadingKind == Action::OFK_None)
+ if (getEffectiveTriple().isSPIRV()) {
+ // For HIP + SPIRV, embed the command-line into the generated binary
+ if (DeviceOffloadingKind == Action::OFK_HIP &&
+ !DriverArgs.hasArg(options::OPT_fembed_bitcode_marker))
+ CC1Args.push_back("-fembed-bitcode=marker");
+
+ // For SPIR-V we want to retain the pristine output of Clang CodeGen, since
+ // optimizations might lose structure / information that is necessary for
+ // generating optimal concrete AMDGPU code.
+ //
+ // For standalone SPIR-V, use -disable-llvm-optzns
+ // TODO: using the below option is a temporary placeholder until Clang
+ // provides the required functionality, which essentially boils down
+ // to -O0 being refactored / reworked to not imply optnone / remove
+ // TBAA. Once that is added, we should pivot to that functionality,
+ // being mindful to not corrupt the user provided and subsequently
+ // embedded command-line (i.e. if the user asks for -O3 this is what
+ // the finalisation should use).
+ if (!DriverArgs.hasArg(options::OPT_disable_llvm_optzns))
+ CC1Args.push_back("-disable-llvm-optzns");
+
+ return; // No DeviceLibs for SPIR-V.
+ }
+
+ if (DeviceOffloadingKind == Action::OFK_None) {
+ // For the OpenCL case where there is no offload target, accept -nostdlib to
+ // disable bitcode linking.
+ if (DriverArgs.hasArg(options::OPT_nostdlib))
+ return;
+
addOpenCLBuiltinsLib(getDriver(), getTriple(), DriverArgs, CC1Args);
+ }
+
+ if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib,
+ true))
+ return;
+
+ // With an LLVM environment, only use libraries provided by the resource
+ // directory.
+ if (getEffectiveTriple().getEnvironment() == llvm::Triple::LLVM)
+ return;
+
+ // Link device libraries for OpenCL, HIP, and OpenMP
+ for (auto BCFile : getDeviceLibs(DriverArgs, BA, DeviceOffloadingKind)) {
+ CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"
+ : "-mlink-bitcode-file");
+ CC1Args.push_back(DriverArgs.MakeArgStringRef(BCFile.Path));
+ }
}
void AMDGPUToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {
@@ -980,66 +1031,6 @@ AMDGPUToolChain::getSystemGPUArchs(const ArgList &Args) const {
return std::move(GPUArchs);
}
-void ROCMToolChain::addClangTargetOptions(
- const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
- BoundArch BA, Action::OffloadKind DeviceOffloadingKind) const {
- AMDGPUToolChain::addClangTargetOptions(DriverArgs, CC1Args, BA,
- DeviceOffloadingKind);
-
- // For the OpenCL case where there is no offload target, accept -nostdlib to
- // disable bitcode linking.
- if (DeviceOffloadingKind == Action::OFK_None &&
- DriverArgs.hasArg(options::OPT_nostdlib))
- return;
-
- if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib,
- true))
- return;
-
- // For SPIR-V (SPIRVAMDToolChain) we must not link any device libraries so we
- // skip it.
- const llvm::Triple &TT = this->getEffectiveTriple();
- if (TT.isSPIRV())
- return;
-
- // With an LLVM environment, only use libraries provided by the resource
- // directory.
- if (TT.getEnvironment() == llvm::Triple::LLVM)
- return;
-
- // Get the device name and canonicalize it. For offload compilation,
- // BoundArch contains the full target ID. For non-offload (OpenCL),
- // fall back to -mcpu.
- StringRef TargetID =
- BA ? BA.ArchName : DriverArgs.getLastArgValue(options::OPT_mcpu_EQ);
- StringRef GpuArch = getProcessorFromTargetID(getTriple(), TargetID);
-
- StringRef LibDeviceFile = RocmInstallation->getLibDeviceFile(GpuArch);
-
- auto ABIVer = DeviceLibABIVersion::fromCodeObjectVersion(
- getAMDGPUCodeObjectVersion(getDriver(), DriverArgs));
- if (!RocmInstallation->checkCommonBitcodeLibs(GpuArch, LibDeviceFile, ABIVer))
- return;
-
- // Add the OpenCL specific bitcode library.
- llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs;
- BCLibs.emplace_back(RocmInstallation->getOpenCLPath().str());
-
- // Add the generic set of libraries.
- BCLibs.append(RocmInstallation->getCommonBitcodeLibs(
- DriverArgs, LibDeviceFile, GpuArch, DeviceOffloadingKind,
- getSanitizerArgs(DriverArgs, BoundArch{TargetID}, DeviceOffloadingKind)
- .needsAsanRt()));
-
- for (auto [BCFile, Internalize] : BCLibs) {
- if (Internalize)
- CC1Args.push_back("-mlink-builtin-bitcode");
- else
- CC1Args.push_back("-mlink-bitcode-file");
- CC1Args.push_back(DriverArgs.MakeArgString(BCFile));
- }
-}
-
bool RocmInstallationDetector::checkCommonBitcodeLibs(
StringRef GPUArch, StringRef LibDeviceFile,
DeviceLibABIVersion ABIVer) const {
@@ -1104,7 +1095,7 @@ RocmInstallationDetector::getCommonBitcodeLibs(
}
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
-ROCMToolChain::getCommonDeviceLibNames(
+AMDGPUToolChain::getCommonDeviceLibNames(
const llvm::opt::ArgList &DriverArgs, llvm::StringRef TargetID,
llvm::StringRef GPUArch, Action::OffloadKind DeviceOffloadingKind) const {
auto Kind = llvm::AMDGPU::parseArchAMDGCN(GPUArch);
@@ -1123,6 +1114,156 @@ ROCMToolChain::getCommonDeviceLibNames(
.needsAsanRt());
}
+llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
+AMDGPUToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs,
+ BoundArch BA,
+ Action::OffloadKind DeviceOffloadKind) const {
+ assert(getEffectiveTriple().isAMDGPU() &&
+ "spirv should not try to link device libs");
+
+ if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib,
+ true) ||
+ getEffectiveTriple().getEnvironment() == llvm::Triple::LLVM)
+ return {};
+
+ if (getTriple().getOS() != llvm::Triple::AMDHSA)
+ return {};
+
+ StringRef GpuArch;
+ StringRef TargetID;
+ if (DeviceOffloadKind == Action::OFK_None) {
+ TargetID = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ);
+ GpuArch = getProcessorFromTargetID(getTriple(), TargetID);
+ } else {
+ TargetID = BA.ArchName;
+ GpuArch = getProcessorFromTargetID(getTriple(), BA.ArchName);
+ }
+
+ llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs;
+
+ // HIP-specific handling
+ if (DeviceOffloadKind == Action::OFK_HIP) {
+ // Handle --hip-device-lib manual override
+ auto BCLibArgs = DriverArgs.getAllArgValues(options::OPT_hip_device_lib_EQ);
+ if (!BCLibArgs.empty()) {
+ ArgStringList LibraryPaths;
+ for (StringRef Path : RocmInstallation->getRocmDeviceLibPathArg())
+ LibraryPaths.push_back(DriverArgs.MakeArgStringRef(Path));
+ addDirectoryList(DriverArgs, LibraryPaths, "", "HIP_DEVICE_LIB_PATH");
+
+ for (StringRef BCName : BCLibArgs) {
+ bool Found = false;
+ for (StringRef LibraryPath : LibraryPaths) {
+ SmallString<128> Path(LibraryPath);
+ llvm::sys::path::append(Path, BCName);
+ if (llvm::sys::fs::exists(Path)) {
+ BCLibs.emplace_back(Path);
+ Found = true;
+ break;
+ }
+ }
+ if (!Found)
+ getDriver().Diag(diag::err_drv_no_such_file) << BCName;
+ }
+ return BCLibs;
+ }
+
+ if (!RocmInstallation->hasDeviceLibrary()) {
+ getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
+ return {};
+ }
+
+ // Add common device libraries
+ for (auto N : getCommonDeviceLibNames(DriverArgs, TargetID, GpuArch,
+ DeviceOffloadKind))
+ BCLibs.emplace_back(N);
+
+ // Add instrument lib for HIP
+ auto InstLib =
+ DriverArgs.getLastArgValue(options::OPT_gpu_instrument_lib_EQ);
+ if (!InstLib.empty()) {
+ if (llvm::sys::fs::exists(InstLib))
+ BCLibs.emplace_back(InstLib);
+ else
+ getDriver().Diag(diag::err_drv_no_such_file) << InstLib;
+ }
+
+ return BCLibs;
+ }
+
+ // OpenMP handling
+ if (DeviceOffloadKind == Action::OFK_OpenMP) {
+ for (auto BCLib : getCommonDeviceLibNames(DriverArgs, TargetID, GpuArch,
+ DeviceOffloadKind))
+ BCLibs.emplace_back(BCLib);
+ return BCLibs;
+ }
+
+ // The libraries are currently only built for amdhsa.
+ if (getTriple().getOS() != llvm::Triple::AMDHSA)
+ return {};
+
+ // Only link device libraries if requested (set by Driver based on input type)
+ if (!ShouldLinkDeviceLibs)
+ return {};
+
+ StringRef LibDeviceFile = RocmInstallation->getLibDeviceFile(GpuArch);
+
+ auto ABIVer = DeviceLibABIVersion::fromCodeObjectVersion(
+ getAMDGPUCodeObjectVersion(getDriver(), DriverArgs));
+ if (!RocmInstallation->checkCommonBitcodeLibs(GpuArch, LibDeviceFile, ABIVer))
+ return {};
+
+ // Add the OpenCL specific bitcode library
+ BCLibs.emplace_back(RocmInstallation->getOpenCLPath().str());
+
+ // Add the generic set of libraries
+ BCLibs.append(RocmInstallation->getCommonBitcodeLibs(
+ DriverArgs, LibDeviceFile, GpuArch, DeviceOffloadKind,
+ getSanitizerArgs(DriverArgs, BoundArch{TargetID}, DeviceOffloadKind)
+ .needsAsanRt()));
+
+ return BCLibs;
+}
+
+ToolChain::CXXStdlibType
+AMDGPUToolChain::GetCXXStdlibType(const ArgList &Args) const {
+ if (HostTC)
+ return HostTC->GetCXXStdlibType(Args);
+ return ToolChain::GetCXXStdlibType(Args);
+}
+
+void AMDGPUToolChain::AddClangCXXStdlibIncludeArgs(
+ const ArgList &Args, ArgStringList &CC1Args) const {
+ if (HostTC)
+ HostTC->AddClangCXXStdlibIncludeArgs(Args, CC1Args);
+ else
+ ToolChain::AddClangCXXStdlibIncludeArgs(Args, CC1Args);
+}
+
+void AMDGPUToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
+ ArgStringList &CC1Args) const {
+ if (HostTC)
+ HostTC->AddIAMCUIncludeArgs(Args, CC1Args);
+}
+
+void AMDGPUToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args);
+}
+
+VersionTuple AMDGPUToolChain::computeMSVCVersion(const Driver *D,
+ const ArgList &Args) const {
+ if (HostTC)
+ return HostTC->computeMSVCVersion(D, Args);
+ return ToolChain::computeMSVCVersion(D, Args);
+}
+
+LTOKind AMDGPUToolChain::getDefaultLTOMode() const {
+ // Offload toolchains use full LTO by default.
+ return HostTC == nullptr ? LTOK_None : LTOK_Full;
+}
+
static bool isXnackAvailable(const llvm::Triple &TT, llvm::StringRef TargetID) {
// Arch-specific check - only report as supported if arch has xnack+
llvm::StringRef Processor = getProcessorFromTargetID(TT, TargetID);
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h
index 4aa9402458b38..0e1158fb22272 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.h
+++ b/clang/lib/Driver/ToolChains/AMDGPU.h
@@ -18,6 +18,7 @@
#include "llvm/TargetParser/AMDGPUTargetParser.h"
#include <map>
+#include <string>
namespace clang {
namespace driver {
@@ -49,7 +50,17 @@ namespace toolchains {
class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
protected:
- const std::map<options::ID, const StringRef> OptionsDefault;
+ const std::map<options::ID, StringRef> OptionsDefault;
+
+ // Optional host toolchain for offloading modes.
+ const ToolChain *HostTC = nullptr;
+
+ /// FIXME: Should merge 2 linkers.
+ const bool UseHIPLinker = false;
+
+ // Whether to link device libraries (for standalone OpenCL/LLVM IR
+ // compilation)
+ bool ShouldLinkDeviceLibs = false;
Tool *buildLinker() const override;
StringRef getOptionDefault(options::ID OptID) const {
@@ -60,7 +71,10 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
public:
AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
- const llvm::opt::ArgList &Args);
+ const llvm::opt::ArgList &Args,
+ const ToolChain *HostTC = nullptr,
+ Action::OffloadKind Kind = Action::OFK_None,
+ bool ShouldLinkDeviceLibs = false);
unsigned GetDefaultDwarfVersion() const override { return 5; }
bool IsMathErrnoDefault() const override { return false; }
@@ -108,6 +122,38 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
virtual Expected<SmallVector<std::string>>
getSystemGPUArchs(const llvm::opt::ArgList &Args) const override;
+ const llvm::Triple *getAuxTriple() const override {
+ return HostTC ? &HostTC->getTriple() : nullptr;
+ }
+
+ llvm::SmallVector<BitCodeLibraryInfo, 12>
+ getDeviceLibs(const llvm::opt::ArgList &Args, BoundArch BA,
+ Action::OffloadKind DeviceOffloadKind) const override;
+
+ CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+
+ void AddClangCXXStdlibIncludeArgs(
+ const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CC1Args) const override;
+
+ void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+
+ void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+
+ VersionTuple
+ computeMSVCVersion(const Driver *D,
+ const llvm::opt::ArgList &Args) const override;
+
+ LTOKind getDefaultLTOMode() const override;
+
+ // Returns a list of device library names shared by different languages
+ llvm::SmallVector<BitCodeLibraryInfo, 12>
+ getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs,
+ llvm::StringRef TargetID, llvm::StringRef GPUArch,
+ Action::OffloadKind DeviceOffloadingKind) const;
+
protected:
/// The struct type returned by getParsedTargetID.
struct ParsedTargetIDType {
@@ -138,27 +184,6 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
Action::OffloadKind DeviceOffloadKind) const override;
};
-class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain {
-public:
- ROCMToolChain(const Driver &D, const llvm::Triple &Triple,
- const llvm::opt::ArgList &Args);
-
- llvm::opt::DerivedArgList *
- TranslateArgs(const llvm::opt::DerivedArgList &Args, BoundArch BA,
- Action::OffloadKind DeviceOffloadKind) const override;
-
- void
- addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args, BoundArch BA,
- Action::OffloadKind DeviceOffloadKind) const override;
-
- // Returns a list of device library names shared by different languages
- llvm::SmallVector<BitCodeLibraryInfo, 12>
- getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs,
- llvm::StringRef TargetID, llvm::StringRef GPUArch,
- Action::OffloadKind DeviceOffloadingKind) const;
-};
-
} // end namespace toolchains
} // end namespace driver
} // end namespace clang
diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
deleted file mode 100644
index c9e724bced9f0..0000000000000
--- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-//===- AMDGPUOpenMP.cpp - AMDGPUOpenMP ToolChain Implementation -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "AMDGPUOpenMP.h"
-#include "AMDGPU.h"
-#include "clang/Driver/Compilation.h"
-#include "clang/Driver/Driver.h"
-#include "clang/Driver/Tool.h"
-#include "clang/Options/Options.h"
-#include "llvm/ADT/STLExtras.h"
-
-using namespace clang::driver;
-using namespace clang::driver::toolchains;
-using namespace clang::driver::tools;
-using namespace clang;
-using namespace llvm::opt;
-
-AMDGPUOpenMPToolChain::AMDGPUOpenMPToolChain(const Driver &D,
- const llvm::Triple &Triple,
- const ToolChain &HostTC,
- const ArgList &Args)
- : ROCMToolChain(D, Triple, Args), HostTC(HostTC) {
- // Lookup binaries into the driver directory, this is used to
- // discover the 'amdgpu-arch' executable.
- getProgramPaths().push_back(getDriver().Dir);
-}
-
-void AMDGPUOpenMPToolChain::addClangTargetOptions(
- const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
- BoundArch BA, Action::OffloadKind DeviceOffloadingKind) const {
- assert(DeviceOffloadingKind == Action::OFK_OpenMP &&
- "Only OpenMP offloading kinds are supported.");
-
- if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib,
- true))
- return;
-
- for (auto BCFile : getDeviceLibs(DriverArgs, BA, DeviceOffloadingKind)) {
- CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"
- : "-mlink-bitcode-file");
- CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path));
- }
-
- // Link the bitcode library late if we're using device LTO.
- if (isUsingLTO(DriverArgs, DeviceOffloadingKind))
- return;
-}
-
-ToolChain::CXXStdlibType
-AMDGPUOpenMPToolChain::GetCXXStdlibType(const ArgList &Args) const {
- return HostTC.GetCXXStdlibType(Args);
-}
-
-void AMDGPUOpenMPToolChain::AddClangCXXStdlibIncludeArgs(
- const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args) const {
- HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args);
-}
-
-void AMDGPUOpenMPToolChain::AddClangSystemIncludeArgs(
- const ArgList &DriverArgs, ArgStringList &CC1Args) const {
- HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
-}
-
-void AMDGPUOpenMPToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
- ArgStringList &CC1Args) const {
- HostTC.AddIAMCUIncludeArgs(Args, CC1Args);
-}
-
-VersionTuple
-AMDGPUOpenMPToolChain::computeMSVCVersion(const Driver *D,
- const ArgList &Args) const {
- return HostTC.computeMSVCVersion(D, Args);
-}
-
-llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
-AMDGPUOpenMPToolChain::getDeviceLibs(
- const llvm::opt::ArgList &Args, BoundArch BA,
- const Action::OffloadKind DeviceOffloadingKind) const {
- if (!Args.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib, true))
- return {};
-
- StringRef GpuArch = getProcessorFromTargetID(getTriple(), BA.ArchName);
- SmallVector<BitCodeLibraryInfo, 12> BCLibs;
- for (auto BCLib : getCommonDeviceLibNames(Args, BA.ArchName, GpuArch,
- DeviceOffloadingKind))
- BCLibs.emplace_back(BCLib);
-
- return BCLibs;
-}
diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.h b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.h
deleted file mode 100644
index 2d5b9e751895f..0000000000000
--- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//===- AMDGPUOpenMP.h - AMDGPUOpenMP ToolChain Implementation -*- C++ -*---===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPUOPENMP_H
-#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPUOPENMP_H
-
-#include "AMDGPU.h"
-#include "clang/Driver/Tool.h"
-#include "clang/Driver/ToolChain.h"
-
-namespace clang {
-namespace driver {
-
-namespace toolchains {
-class AMDGPUOpenMPToolChain;
-}
-
-namespace toolchains {
-
-class LLVM_LIBRARY_VISIBILITY AMDGPUOpenMPToolChain final
- : public ROCMToolChain {
-public:
- AMDGPUOpenMPToolChain(const Driver &D, const llvm::Triple &Triple,
- const ToolChain &HostTC,
- const llvm::opt::ArgList &Args);
-
- const llvm::Triple *getAuxTriple() const override {
- return &HostTC.getTriple();
- }
-
- void
- addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args, BoundArch BA,
- Action::OffloadKind DeviceOffloadKind) const override;
- CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
- void AddClangCXXStdlibIncludeArgs(
- const llvm::opt::ArgList &Args,
- llvm::opt::ArgStringList &CC1Args) const override;
- void
- AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const override;
- void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const override;
-
- VersionTuple
- computeMSVCVersion(const Driver *D,
- const llvm::opt::ArgList &Args) const override;
-
- llvm::SmallVector<BitCodeLibraryInfo, 12>
- getDeviceLibs(const llvm::opt::ArgList &Args, BoundArch BA,
- const Action::OffloadKind DeviceOffloadKind) const override;
-
- /// OpenMP uses LTO by default to link device bitcode.
- LTOKind getDefaultLTOMode() const override { return LTOK_Full; }
-
- const ToolChain &HostTC;
-};
-
-} // end namespace toolchains
-} // end namespace driver
-} // end namespace clang
-
-#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPUOPENMP_H
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp
index ac5fc708c0b11..bc73539a19ba4 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.cpp
+++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp
@@ -224,202 +224,11 @@ void AMDGCN::Linker::ConstructJob(Compilation &C, const JobAction &JA,
return constructLldCommand(C, JA, Inputs, Output, Args);
}
-HIPAMDToolChain::HIPAMDToolChain(const Driver &D, const llvm::Triple &Triple,
- const ToolChain &HostTC, const ArgList &Args)
- : ROCMToolChain(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);
-}
-
-void HIPAMDToolChain::addClangTargetOptions(
- const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
- BoundArch BA, Action::OffloadKind DeviceOffloadingKind) const {
- assert(DeviceOffloadingKind == Action::OFK_HIP &&
- "Only HIP offloading kinds are supported for GPUs.");
-
- CC1Args.append({"-fcuda-is-device", "-fno-threadsafe-statics"});
-
- if (!DriverArgs.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
- false)) {
- CC1Args.append({"-mllvm", "-amdgpu-internalize-symbols"});
- if (DriverArgs.hasArgNoClaim(options::OPT_hipstdpar))
- CC1Args.append({"-mllvm", "-amdgpu-enable-hipstdpar"});
- }
-
- StringRef MaxThreadsPerBlock =
- DriverArgs.getLastArgValue(options::OPT_gpu_max_threads_per_block_EQ);
- if (!MaxThreadsPerBlock.empty()) {
- CC1Args.push_back(DriverArgs.MakeArgString(
- Twine("--gpu-max-threads-per-block=") + MaxThreadsPerBlock));
- }
-
- // Default to "hidden" visibility, as object level linking will not be
- // supported for the foreseeable future.
- // TODO: remove the SPIR-V bypass once it can encode (hidden) visibility.
- if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,
- options::OPT_fvisibility_ms_compat) &&
- !getEffectiveTriple().isSPIRV() && !getDriver().IsFlangMode()) {
- CC1Args.append({"-fvisibility=hidden"});
- CC1Args.push_back("-fapply-global-visibility-to-externs");
- }
-
- 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");
- // For SPIR-V we want to retain the pristine output of Clang CodeGen, since
- // optimizations might lose structure / information that is necessary for
- // generating optimal concrete AMDGPU code. We duplicate this because the
- // HIP TC doesn't invoke the base AMDGPU TC addClangTargetOptions.
- if (!DriverArgs.hasArg(options::OPT_disable_llvm_passes))
- CC1Args.push_back("-disable-llvm-passes");
- return; // No DeviceLibs for SPIR-V.
- }
-
- for (auto BCFile : getDeviceLibs(DriverArgs, BA, DeviceOffloadingKind)) {
- CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"
- : "-mlink-bitcode-file");
- CC1Args.push_back(DriverArgs.MakeArgStringRef(BCFile.Path));
- }
-}
-
-llvm::opt::DerivedArgList *
-HIPAMDToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
- BoundArch BA,
- Action::OffloadKind DeviceOffloadKind) const {
- llvm::opt::DerivedArgList *DAL =
- ROCMToolChain::TranslateArgs(Args, BA, DeviceOffloadKind);
-
- return DAL;
-}
-
-Tool *HIPAMDToolChain::buildLinker() const {
- assert(getTriple().isAMDGCN() ||
- getTriple().getArch() == llvm::Triple::spirv64);
- return new tools::AMDGCN::Linker(*this);
-}
-
-ToolChain::CXXStdlibType
-HIPAMDToolChain::GetCXXStdlibType(const ArgList &Args) const {
- return HostTC.GetCXXStdlibType(Args);
-}
-
-void HIPAMDToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
- ArgStringList &CC1Args) const {
- HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
-}
-
-void HIPAMDToolChain::AddClangCXXStdlibIncludeArgs(
- const ArgList &Args, ArgStringList &CC1Args) const {
- HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args);
-}
-
-void HIPAMDToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
- ArgStringList &CC1Args) const {
- HostTC.AddIAMCUIncludeArgs(Args, CC1Args);
-}
-
-void HIPAMDToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
- ArgStringList &CC1Args) const {
- RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args);
-}
-
-VersionTuple HIPAMDToolChain::computeMSVCVersion(const Driver *D,
- const ArgList &Args) const {
- return HostTC.computeMSVCVersion(D, Args);
-}
-
-llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
-HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs,
- BoundArch BA,
- Action::OffloadKind DeviceOffloadingKind) const {
- assert(BA && "Must have an explicit GPU arch.");
-
- llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs;
- const llvm::Triple &TT = getEffectiveTriple();
-
- if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib,
- true) ||
- TT.getEnvironment() == llvm::Triple::LLVM)
- return {};
-
- StringRef GpuArch = getProcessorFromTargetID(getTriple(), BA.ArchName);
- if (GpuArch == "amdgcnspirv")
- return {};
-
- ArgStringList LibraryPaths;
-
- // Find in --hip-device-lib-path and HIP_LIBRARY_PATH.
- for (StringRef Path : RocmInstallation->getRocmDeviceLibPathArg())
- LibraryPaths.push_back(DriverArgs.MakeArgStringRef(Path));
-
- addDirectoryList(DriverArgs, LibraryPaths, "", "HIP_DEVICE_LIB_PATH");
-
- // Maintain compatability with --hip-device-lib.
- auto BCLibArgs = DriverArgs.getAllArgValues(options::OPT_hip_device_lib_EQ);
- if (!BCLibArgs.empty()) {
- for (StringRef BCName : BCLibArgs) {
- StringRef FullName;
- bool Found = false;
- for (StringRef LibraryPath : LibraryPaths) {
- SmallString<128> Path(LibraryPath);
- llvm::sys::path::append(Path, BCName);
- FullName = Path;
- if (llvm::sys::fs::exists(FullName)) {
- BCLibs.emplace_back(FullName);
- Found = true;
- break;
- }
- }
- if (!Found)
- getDriver().Diag(diag::err_drv_no_such_file) << BCName;
- }
- } else {
- if (!RocmInstallation->hasDeviceLibrary()) {
- getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
- return {};
- }
-
- // Add common device libraries like ocml etc.
- for (auto N : getCommonDeviceLibNames(DriverArgs, BA.ArchName, GpuArch,
- DeviceOffloadingKind))
- BCLibs.emplace_back(N);
-
- // Add instrument lib.
- auto InstLib =
- DriverArgs.getLastArgValue(options::OPT_gpu_instrument_lib_EQ);
- if (InstLib.empty())
- return BCLibs;
- if (llvm::sys::fs::exists(InstLib))
- BCLibs.emplace_back(InstLib);
- else
- getDriver().Diag(diag::err_drv_no_such_file) << InstLib;
- }
-
- return BCLibs;
-}
-
-HIPAMDToolChain::ParsedTargetIDType
-HIPAMDToolChain::checkTargetID(const llvm::opt::ArgList &DriverArgs) const {
- auto PTID = getParsedTargetID(DriverArgs);
- if (PTID.OptionalTargetID && !PTID.OptionalGPUArch &&
- PTID.OptionalTargetID != "amdgcnspirv")
- getDriver().Diag(clang::diag::err_drv_bad_target_id)
- << *PTID.OptionalTargetID;
- return PTID;
-}
-
SPIRVAMDToolChain::SPIRVAMDToolChain(const Driver &D,
const llvm::Triple &Triple,
- const ArgList &Args)
- : ROCMToolChain(D, Triple, Args) {
- getProgramPaths().push_back(getDriver().Dir);
-}
+ const llvm::opt::ArgList &Args)
+ : AMDGPUToolChain(D, Triple, Args) {}
Tool *SPIRVAMDToolChain::buildLinker() const {
- assert(getTriple().getArch() == llvm::Triple::spirv64);
return new tools::AMDGCN::Linker(*this);
}
diff --git a/clang/lib/Driver/ToolChains/HIPAMD.h b/clang/lib/Driver/ToolChains/HIPAMD.h
index a156f9144f7a8..2565e2e0d4424 100644
--- a/clang/lib/Driver/ToolChains/HIPAMD.h
+++ b/clang/lib/Driver/ToolChains/HIPAMD.h
@@ -52,56 +52,7 @@ class LLVM_LIBRARY_VISIBILITY Linker final : public Tool {
namespace toolchains {
-class LLVM_LIBRARY_VISIBILITY HIPAMDToolChain final : public ROCMToolChain {
-public:
- HIPAMDToolChain(const Driver &D, const llvm::Triple &Triple,
- const ToolChain &HostTC, const llvm::opt::ArgList &Args);
-
- const llvm::Triple *getAuxTriple() const override {
- return &HostTC.getTriple();
- }
-
- llvm::opt::DerivedArgList *
- TranslateArgs(const llvm::opt::DerivedArgList &Args, BoundArch BA,
- Action::OffloadKind DeviceOffloadKind) const override;
-
- void
- addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args, BoundArch BA,
- Action::OffloadKind DeviceOffloadKind) const override;
- CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
- void
- AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const override;
- void AddClangCXXStdlibIncludeArgs(
- const llvm::opt::ArgList &Args,
- llvm::opt::ArgStringList &CC1Args) const override;
- void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const override;
- void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args) const override;
- llvm::SmallVector<BitCodeLibraryInfo, 12>
- getDeviceLibs(const llvm::opt::ArgList &Args, BoundArch BA,
- Action::OffloadKind DeviceOffloadKind) const override;
-
- VersionTuple
- computeMSVCVersion(const Driver *D,
- const llvm::opt::ArgList &Args) const override;
-
- unsigned GetDefaultDwarfVersion() const override { return 5; }
-
- /// HIP uses LTO by default to link device bitcode.
- LTOKind getDefaultLTOMode() const override { return LTOK_Full; }
-
- const ToolChain &HostTC;
- ParsedTargetIDType
- checkTargetID(const llvm::opt::ArgList &DriverArgs) const override;
-
-protected:
- Tool *buildLinker() const override;
-};
-
-class LLVM_LIBRARY_VISIBILITY SPIRVAMDToolChain final : public ROCMToolChain {
+class LLVM_LIBRARY_VISIBILITY SPIRVAMDToolChain final : public AMDGPUToolChain {
public:
SPIRVAMDToolChain(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
diff --git a/clang/test/Driver/hip-device-libs-llvm-env.hip b/clang/test/Driver/hip-device-libs-llvm-env.hip
index 7f3c4c9b7af10..052e2ff0d3cd2 100644
--- a/clang/test/Driver/hip-device-libs-llvm-env.hip
+++ b/clang/test/Driver/hip-device-libs-llvm-env.hip
@@ -5,6 +5,13 @@
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
// RUN: 2>&1 | FileCheck --check-prefix=LLVMENV %s
+// Verify no error when device libs cannot be found with llvm environment
+// RUN: %clang -### --target=x86_64-linux-gnu -nogpuinc \
+// RUN: --offload-targets=amdgcn-amd-amdhsa-llvm --offload-arch=gfx90a \
+// RUN: -resource-dir=%S/Inputs/nonexistent_rocm \
+// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck --check-prefix=LLVMENV %s
+
// LLVMENV-NOT: -mlink-builtin-bitcode
// LLVMENV-NOT: oclc
// LLVMENV-NOT: ocml
diff --git a/clang/test/Driver/hip-toolchain-no-rdc.hip b/clang/test/Driver/hip-toolchain-no-rdc.hip
index 21e1da6ab36fa..cfa3992e9ca02 100644
--- a/clang/test/Driver/hip-toolchain-no-rdc.hip
+++ b/clang/test/Driver/hip-toolchain-no-rdc.hip
@@ -232,7 +232,7 @@
// AMDGCNSPIRV: "-cc1" "-triple" "amdgcn-amd-amdhsa" {{.*}}"-emit-llvm-bc" {{.*}}"-flto=full"{{.*}} "-target-cpu" "gfx900"{{.*}} "-o" "[[GFX900_BC:.*bc]]"
// AMDGCNSPIRV: {{".*lld.*"}} {{.*}}"-plugin-opt=mcpu=gfx900" {{.*}} "-o" "[[GFX900_CO:.*out]]" {{.*}}"[[GFX900_BC]]"
-// AMDGCNSPIRV: "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}}"-emit-llvm-bc" {{.*}}"-flto=full"{{.*}} "-fembed-bitcode=marker" "-disable-llvm-passes" {{.*}} "-o" "[[AMDGCNSPV_BC:.*bc]]"
+// AMDGCNSPIRV: "-cc1" "-triple" "spirv64-amd-amdhsa" {{.*}}"-emit-llvm-bc" {{.*}}"-flto=full"{{.*}} "-fembed-bitcode=marker" "-disable-llvm-optzns" {{.*}} "-o" "[[AMDGCNSPV_BC:.*bc]]"
// AMDGCNSPIRV: {{".*llvm-link.*"}} "-o" "[[AMDGCNSPV_TMP:.*bc]]" "[[AMDGCNSPV_BC]]"
// AMDGCNSPIRV: {{".*llvm-spirv.*"}} "--spirv-max-version=1.6" "--spirv-ext=+all" {{.*}} "[[AMDGCNSPV_TMP]]" {{.*}}"-o" "[[AMDGCNSPV_CO:.*out]]"
// AMDGCNSPIRV: {{".*clang-offload-bundler.*"}} "-type=o"
More information about the llvm-branch-commits
mailing list