Skip to content

Commit 3a899ba

Browse files
committed
land [Driver][ASan] Refactor Clang-Driver "Sanitizer Bitcode" linking. (llvm#123922)
1 parent 52ae76b commit 3a899ba

9 files changed

+113
-190
lines changed

clang/lib/Driver/ToolChains/AMDGPU.cpp

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -721,9 +721,10 @@ void amdgpu::getAMDGPUTargetFeatures(const Driver &D,
721721
options::OPT_m_amdgpu_Features_Group);
722722
}
723723

724-
llvm::SmallVector<std::string, 12> amdgpu::dlr::getCommonDeviceLibNames(
725-
const llvm::opt::ArgList &DriverArgs, const Driver &D,
726-
const std::string &GPUArch, bool isOpenMP,
724+
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
725+
amdgpu::dlr::getCommonDeviceLibNames(
726+
const llvm::opt::ArgList &DriverArgs, const SanitizerArgs &SanArgs,
727+
const Driver &D, const std::string &GPUArch, bool isOpenMP,
727728
const RocmInstallationDetector &RocmInstallation) {
728729
auto Kind = llvm::AMDGPU::parseArchAMDGCN(GPUArch);
729730
const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind);
@@ -732,13 +733,17 @@ llvm::SmallVector<std::string, 12> amdgpu::dlr::getCommonDeviceLibNames(
732733
auto ABIVer = DeviceLibABIVersion::fromCodeObjectVersion(
733734
getAMDGPUCodeObjectVersion(D, DriverArgs));
734735
bool noGPULib = DriverArgs.hasArg(options::OPT_nogpulib);
735-
if (!RocmInstallation.checkCommonBitcodeLibs(CanonArch, LibDeviceFile,
736-
ABIVer, noGPULib))
736+
if (!RocmInstallation.checkCommonBitcodeLibs(CanonArch, LibDeviceFile, ABIVer,
737+
noGPULib))
737738
return {};
738739

739740
// If --hip-device-lib is not set, add the default bitcode libraries.
740741
// TODO: There are way too many flags that change this. Do we need to check
741742
// them all?
743+
std::tuple<bool, const SanitizerArgs> GPUSan(
744+
DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
745+
options::OPT_fno_gpu_sanitize, true),
746+
SanArgs);
742747
bool DAZ = DriverArgs.hasFlag(
743748
options::OPT_fgpu_flush_denormals_to_zero,
744749
options::OPT_fno_gpu_flush_denormals_to_zero,
@@ -757,7 +762,7 @@ llvm::SmallVector<std::string, 12> amdgpu::dlr::getCommonDeviceLibNames(
757762

758763
return RocmInstallation.getCommonBitcodeLibs(
759764
DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
760-
FastRelaxedMath, CorrectSqrt, ABIVer, isOpenMP);
765+
FastRelaxedMath, CorrectSqrt, ABIVer, GPUSan, isOpenMP);
761766
}
762767

763768
/// AMDGPU Toolchain
@@ -1003,6 +1008,11 @@ void ROCMToolChain::addClangTargetOptions(
10031008
ABIVer, noGPULib))
10041009
return;
10051010

1011+
std::tuple<bool, const SanitizerArgs> GPUSan(
1012+
DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
1013+
options::OPT_fno_gpu_sanitize, true),
1014+
getSanitizerArgs((DriverArgs)));
1015+
10061016
bool Wave64 = isWave64(DriverArgs, Kind);
10071017

10081018
// TODO: There are way too many flags that change this. Do we need to check
@@ -1018,21 +1028,19 @@ void ROCMToolChain::addClangTargetOptions(
10181028
DriverArgs.hasArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt);
10191029

10201030
// Add the OpenCL specific bitcode library.
1021-
llvm::SmallVector<std::string, 12> BCLibs;
1022-
BCLibs.push_back(RocmInstallation->getOpenCLPath().str());
1031+
llvm::SmallVector<BitCodeLibraryInfo, 12> BCLibs;
1032+
BCLibs.emplace_back(RocmInstallation->getOpenCLPath().str());
10231033

10241034
// Add the generic set of libraries.
10251035
BCLibs.append(RocmInstallation->getCommonBitcodeLibs(
10261036
DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
1027-
FastRelaxedMath, CorrectSqrt, ABIVer, false));
1037+
FastRelaxedMath, CorrectSqrt, ABIVer, GPUSan, false));
10281038

1029-
if (getSanitizerArgs(DriverArgs).needsAsanRt()) {
1030-
CC1Args.push_back("-mlink-bitcode-file");
1031-
CC1Args.push_back(
1032-
DriverArgs.MakeArgString(RocmInstallation->getAsanRTLPath()));
1033-
}
1034-
for (StringRef BCFile : BCLibs) {
1035-
CC1Args.push_back("-mlink-builtin-bitcode");
1039+
for (auto [BCFile, Internalize] : BCLibs) {
1040+
if (Internalize)
1041+
CC1Args.push_back("-mlink-builtin-bitcode");
1042+
else
1043+
CC1Args.push_back("-mlink-bitcode-file");
10361044
CC1Args.push_back(DriverArgs.MakeArgString(BCFile));
10371045
}
10381046
}
@@ -1058,15 +1066,31 @@ bool RocmInstallationDetector::checkCommonBitcodeLibs(
10581066
return true;
10591067
}
10601068

1061-
llvm::SmallVector<std::string, 12>
1069+
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
10621070
RocmInstallationDetector::getCommonBitcodeLibs(
10631071
const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, bool Wave64,
10641072
bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, bool FastRelaxedMath,
1065-
bool CorrectSqrt, DeviceLibABIVersion ABIVer, bool isOpenMP = false) const {
1066-
llvm::SmallVector<std::string, 12> BCLibs;
1067-
1068-
auto AddBCLib = [&](StringRef BCFile) { BCLibs.push_back(BCFile.str()); };
1073+
bool CorrectSqrt, DeviceLibABIVersion ABIVer,
1074+
const std::tuple<bool, const SanitizerArgs> &GPUSan,
1075+
bool isOpenMP = false) const {
1076+
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> BCLibs;
1077+
1078+
auto GPUSanEnabled = [GPUSan]() {
1079+
return std::get<bool>(GPUSan) &&
1080+
std::get<const SanitizerArgs>(GPUSan).needsAsanRt();
1081+
};
1082+
auto AddBCLib = [&](ToolChain::BitCodeLibraryInfo BCLib,
1083+
bool Internalize = true) {
1084+
BCLib.ShouldInternalize = Internalize;
1085+
BCLibs.push_back(BCLib);
1086+
};
1087+
auto AddSanBCLibs = [&]() {
1088+
if (GPUSanEnabled()) {
1089+
AddBCLib(getAsanRTLPath(), false);
1090+
}
1091+
};
10691092

1093+
AddSanBCLibs();
10701094
AddBCLib(getOCMLPath());
10711095
// FIXME: OpenMP has ockl and ocml contained in libomptarget.bc. However,
10721096
// we cannot exclude ocml here because of the crazy always-compile clang
@@ -1076,6 +1100,8 @@ RocmInstallationDetector::getCommonBitcodeLibs(
10761100
// __BUILD_MATH_BUILTINS_LIB__ turning static libm functions to extern.
10771101
if (!isOpenMP)
10781102
AddBCLib(getOCKLPath());
1103+
else if (GPUSanEnabled() && isOpenMP)
1104+
AddBCLib(getOCKLPath(), false);
10791105
AddBCLib(getDenormalsAreZeroPath(DAZ));
10801106
AddBCLib(getUnsafeMathPath(UnsafeMathOpt || FastRelaxedMath));
10811107
AddBCLib(getFiniteOnlyPath(FiniteOnly || FastRelaxedMath));
@@ -1096,14 +1122,15 @@ bool AMDGPUToolChain::shouldSkipArgument(const llvm::opt::Arg *A) const {
10961122
return false;
10971123
}
10981124

1099-
llvm::SmallVector<std::string, 12>
1125+
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
11001126
ROCMToolChain::getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs,
11011127
const std::string &GPUArch,
11021128
bool isOpenMP) const {
11031129
RocmInstallationDetector RocmInstallation(getDriver(), getTriple(),
11041130
DriverArgs, true, true);
1105-
return amdgpu::dlr::getCommonDeviceLibNames(DriverArgs, getDriver(), GPUArch,
1106-
isOpenMP, RocmInstallation);
1131+
return amdgpu::dlr::getCommonDeviceLibNames(
1132+
DriverArgs, getSanitizerArgs(DriverArgs), getDriver(), GPUArch, isOpenMP,
1133+
RocmInstallation);
11071134
}
11081135

11091136
bool AMDGPUToolChain::shouldSkipSanitizeOption(
@@ -1117,7 +1144,7 @@ bool AMDGPUToolChain::shouldSkipSanitizeOption(
11171144
return false;
11181145

11191146
if (!DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
1120-
options::OPT_fno_gpu_sanitize, false))
1147+
options::OPT_fno_gpu_sanitize, true))
11211148
return true;
11221149

11231150
auto &Diags = TC.getDriver().getDiags();

clang/lib/Driver/ToolChains/AMDGPU.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ void getAMDGPUTargetFeatures(const Driver &D, const llvm::Triple &Triple,
4343
StringRef TcTargetID = StringRef());
4444

4545
namespace dlr {
46-
llvm::SmallVector<std::string, 12>
47-
getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs, const Driver &D,
46+
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
47+
getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs,
48+
const SanitizerArgs &SanArgs, const Driver &D,
4849
const std::string &GPUArch, bool isOpenMP,
4950
const RocmInstallationDetector &RocmInstallation);
5051

@@ -188,7 +189,7 @@ class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain {
188189
Action::OffloadKind DeviceOffloadKind) const override;
189190

190191
// Returns a list of device library names shared by different languages
191-
llvm::SmallVector<std::string, 12>
192+
llvm::SmallVector<BitCodeLibraryInfo, 12>
192193
getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs,
193194
const std::string &GPUArch,
194195
bool isOpenMP = false) const;

clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
#include "AMDGPU.h"
1111
#include "CommonArgs.h"
1212
#include "HIPUtility.h"
13-
#include "ToolChains/ROCm.h"
13+
#include "ROCm.h"
1414
#include "clang/Basic/DiagnosticDriver.h"
15+
#include "clang/Config/config.h"
1516
#include "clang/Driver/Compilation.h"
1617
#include "clang/Driver/Driver.h"
1718
#include "clang/Driver/DriverDiagnostic.h"
@@ -20,14 +21,13 @@
2021
#include "clang/Driver/SanitizerArgs.h"
2122
#include "clang/Driver/Tool.h"
2223
#include "llvm/ADT/STLExtras.h"
23-
#include "llvm/ADT/StringExtras.h"
24+
#include "llvm/ADT/StringExtras.h"
2425
#include "llvm/Support/FileSystem.h"
2526
#include "llvm/Support/FormatAdapters.h"
2627
#include "llvm/Support/FormatVariadic.h"
2728
#include "llvm/Support/Path.h"
2829
#include "llvm/Support/Process.h"
2930
#include "llvm/TargetParser/TargetParser.h"
30-
#include "clang/Config/config.h"
3131

3232
using namespace clang::driver;
3333
using namespace clang::driver::toolchains;
@@ -232,20 +232,7 @@ const char *amdgpu::dlr::getLinkCommandArgs(
232232
LibSuffix.append("/asan");
233233
}
234234

235-
llvm::SmallVector<std::string, 12> BCLibs;
236-
237-
std::string AsanRTL;
238-
if (Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,
239-
true) &&
240-
TC.getSanitizerArgs(Args).needsAsanRt()) {
241-
if (!Args.hasArg(options::OPT_nogpulib)){
242-
AsanRTL = RocmInstallation.getAsanRTLPath();
243-
if(AsanRTL.empty())
244-
TC.getDriver().Diag(diag::err_drv_no_asan_rt_lib);
245-
else
246-
BCLibs.push_back(AsanRTL);
247-
}
248-
}
235+
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> BCLibs;
249236
StringRef GPUArch = getProcessorFromTargetID(Triple, TargetID);
250237

251238
// When the base lib directory is called `lib` we enable
@@ -261,7 +248,7 @@ const char *amdgpu::dlr::getLinkCommandArgs(
261248
std::string EnvOmpLibDevice = EnvLibraryPath + LibDeviceName;
262249
if (llvm::sys::fs::exists(EnvOmpLibDevice)) {
263250
EnvOmpLibDeviceFound = true;
264-
BCLibs.push_back(EnvOmpLibDevice);
251+
BCLibs.emplace_back(EnvOmpLibDevice);
265252
break;
266253
}
267254
}
@@ -273,33 +260,23 @@ const char *amdgpu::dlr::getLinkCommandArgs(
273260
StringRef bc_file_lib =
274261
Args.MakeArgString(C.getDriver().Dir + "/../lib" + LibDeviceName);
275262
if (llvm::sys::fs::exists(bc_file_suf))
276-
BCLibs.push_back(Args.MakeArgString(bc_file_suf));
263+
BCLibs.emplace_back(Args.MakeArgString(bc_file_suf));
277264
else if (llvm::sys::fs::exists(bc_file_lib))
278265
// In case a LibSuffix version not found, use suffix "lib"
279-
BCLibs.push_back(Args.MakeArgString(bc_file_lib));
266+
BCLibs.emplace_back(Args.MakeArgString(bc_file_lib));
280267
else
281268
TC.getDriver().Diag(diag::err_drv_omp_offload_target_bcruntime_not_found)
282269
<< "libomptarget-amdgpu.bc";
283270
}
284271

285-
if (!AsanRTL.empty()) {
286-
// asanrtl is dependent on ockl so for every asanrtl bitcode linking
287-
// requires ockl but viceversa is not true.
288-
std::string OcklRTL(RocmInstallation.getOCKLPath());
289-
if (OcklRTL.empty())
290-
TC.getDriver().Diag(diag::err_drv_no_rocm_device_lib);
291-
else
292-
BCLibs.push_back(OcklRTL);
293-
}
294-
295272
// Add the generic set of libraries, OpenMP subset only
296273
BCLibs.append(amdgpu::dlr::getCommonDeviceLibNames(
297-
C.getArgs(), C.getDriver(), GPUArch.str(), /* isOpenMP=*/true,
298-
RocmInstallation));
274+
C.getArgs(), TC.getSanitizerArgs(C.getArgs()), C.getDriver(),
275+
GPUArch.str(), /* isOpenMP=*/true, RocmInstallation));
299276
}
300277

301-
llvm::for_each(BCLibs, [&](StringRef BCFile) {
302-
LastLinkArgs.push_back(Args.MakeArgString(BCFile));
278+
llvm::for_each(BCLibs, [&](auto BCLib) {
279+
LastLinkArgs.push_back(Args.MakeArgString(BCLib.Path));
303280
});
304281

305282
LastLinkArgs.push_back("-o");
@@ -481,7 +458,7 @@ llvm::opt::DerivedArgList *AMDGPUOpenMPToolChain::TranslateArgs(
481458

482459
DerivedArgList *DAL =
483460
HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind);
484-
if (!DAL)
461+
if (!DAL || Args.hasArg(options::OPT_fsanitize_EQ))
485462
DAL = new DerivedArgList(Args.getBaseArgs());
486463

487464
const OptTable &Opts = getDriver().getOpts();
@@ -602,11 +579,6 @@ AMDGPUOpenMPToolChain::getDeviceLibs(const llvm::opt::ArgList &Args) const {
602579
if (Args.hasArg(options::OPT_nogpulib))
603580
return {};
604581

605-
if (!RocmInstallation->hasDeviceLibrary()) {
606-
getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
607-
return {};
608-
}
609-
610582
StringRef GpuArch = getProcessorFromTargetID(
611583
getTriple(), Args.getLastArgValue(options::OPT_march_EQ));
612584

clang/lib/Driver/ToolChains/HIPAMD.cpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const {
387387
llvm::sys::path::append(Path, BCName);
388388
FullName = Path;
389389
if (llvm::sys::fs::exists(FullName)) {
390-
BCLibs.push_back(FullName);
390+
BCLibs.emplace_back(FullName);
391391
return;
392392
}
393393
}
@@ -402,22 +402,11 @@ HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const {
402402
assert(!GpuArch.empty() && "Must have an explicit GPU arch.");
403403

404404
// If --hip-device-lib is not set, add the default bitcode libraries.
405-
if (DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
406-
options::OPT_fno_gpu_sanitize, true) &&
407-
getSanitizerArgs(DriverArgs).needsAsanRt()) {
408-
auto AsanRTL = RocmInstallation->getAsanRTLPath();
409-
if (AsanRTL.empty()) {
410-
getDriver().Diag(diag::err_drv_no_asan_rt_lib);
411-
return {};
412-
} else
413-
BCLibs.emplace_back(AsanRTL, /*ShouldInternalize=*/false);
414-
}
415-
416405
// Add the HIP specific bitcode library.
417-
BCLibs.push_back(RocmInstallation->getHIPPath());
406+
BCLibs.emplace_back(RocmInstallation->getHIPPath());
418407

419408
// Add common device libraries like ocml etc.
420-
for (StringRef N : getCommonDeviceLibNames(DriverArgs, GpuArch.str()))
409+
for (auto N : getCommonDeviceLibNames(DriverArgs, GpuArch.str()))
421410
BCLibs.emplace_back(N);
422411

423412
// Add instrument lib.

clang/lib/Driver/ToolChains/ROCm.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "clang/Basic/LLVM.h"
1414
#include "clang/Driver/Driver.h"
1515
#include "clang/Driver/Options.h"
16+
#include "clang/Driver/SanitizerArgs.h"
1617
#include "llvm/ADT/SmallString.h"
1718
#include "llvm/ADT/StringMap.h"
1819
#include "llvm/Option/ArgList.h"
@@ -173,12 +174,12 @@ class RocmInstallationDetector {
173174

174175
/// Get file paths of default bitcode libraries common to AMDGPU based
175176
/// toolchains.
176-
llvm::SmallVector<std::string, 12>
177-
getCommonBitcodeLibs(const llvm::opt::ArgList &DriverArgs,
178-
StringRef LibDeviceFile, bool Wave64, bool DAZ,
179-
bool FiniteOnly, bool UnsafeMathOpt,
180-
bool FastRelaxedMath, bool CorrectSqrt,
181-
DeviceLibABIVersion ABIVer, bool isOpenMP) const;
177+
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> getCommonBitcodeLibs(
178+
const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile,
179+
bool Wave64, bool DAZ, bool FiniteOnly, bool UnsafeMathOpt,
180+
bool FastRelaxedMath, bool CorrectSqrt, DeviceLibABIVersion ABIVer,
181+
const std::tuple<bool, const SanitizerArgs> &GPUSan, bool isOpenMP) const;
182+
182183
/// Check file paths of default bitcode libraries common to AMDGPU based
183184
/// toolchains. \returns false if there are invalid or missing files.
184185
bool checkCommonBitcodeLibs(StringRef GPUArch, StringRef LibDeviceFile,

0 commit comments

Comments
 (0)