[clang] 51ade31 - [HIP] Support device sanitizer

Yaxun Liu via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 18 20:33:15 PST 2021


Author: Yaxun (Sam) Liu
Date: 2021-02-18T23:30:25-05:00
New Revision: 51ade31e67897bbd6f363f26d9110ec4d6ddaa7f

URL: https://github.com/llvm/llvm-project/commit/51ade31e67897bbd6f363f26d9110ec4d6ddaa7f
DIFF: https://github.com/llvm/llvm-project/commit/51ade31e67897bbd6f363f26d9110ec4d6ddaa7f.diff

LOG: [HIP] Support device sanitizer

Add option -fgpu-sanitize to enable sanitizer for AMDGPU target.

Since it is experimental, it is off by default.

Reviewed by: Artem Belevich

Differential Revision: https://reviews.llvm.org/D96835

Added: 
    clang/test/Driver/Inputs/rocm-invalid/README
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/hip.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/ockl.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_correctly_rounded_sqrt_off.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_correctly_rounded_sqrt_on.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_daz_opt_off.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_daz_opt_on.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_finite_only_off.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_finite_only_on.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_1010.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_1011.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_1012.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_803.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_900.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_908.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_unsafe_math_off.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_unsafe_math_on.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_wavefrontsize64_off.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_wavefrontsize64_on.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/ocml.bc
    clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/opencl.bc
    clang/test/Driver/Inputs/rocm-invalid/bin/.hipVersion
    clang/test/Driver/Inputs/rocm-invalid/include/hip/hip_runtime.h
    clang/test/Driver/Inputs/rocm/amdgcn/bitcode/asanrtl.bc

Modified: 
    clang/include/clang/Driver/Options.td
    clang/include/clang/Driver/ToolChain.h
    clang/lib/Driver/Driver.cpp
    clang/lib/Driver/SanitizerArgs.cpp
    clang/lib/Driver/ToolChain.cpp
    clang/lib/Driver/ToolChains/AMDGPU.cpp
    clang/lib/Driver/ToolChains/HIP.cpp
    clang/lib/Driver/ToolChains/HIP.h
    clang/lib/Driver/ToolChains/ROCm.h
    clang/test/Driver/hip-sanitize-options.hip

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index c7003437472e..17eb0ade2493 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -930,6 +930,9 @@ def gpu_max_threads_per_block_EQ : Joined<["--"], "gpu-max-threads-per-block=">,
 def gpu_instrument_lib_EQ : Joined<["--"], "gpu-instrument-lib=">,
   HelpText<"Instrument device library for HIP, which is a LLVM bitcode containing "
   "__cyg_profile_func_enter and __cyg_profile_func_exit">;
+defm gpu_sanitize : BoolFOption<"gpu-sanitize", EmptyKPM, DefaultFalse,
+  PosFlag<SetTrue, [], "Enable sanitizer for AMDGPU target">,
+  NegFlag<SetFalse>>;
 def cuid_EQ : Joined<["-"], "cuid=">, Flags<[CC1Option]>,
   HelpText<"An ID for compilation unit, which should be the same for the same "
            "compilation unit but 
diff erent for 
diff erent compilation units. "

diff  --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index fed688c0f1ce..df4848d9e134 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -663,6 +663,10 @@ class ToolChain {
   virtual VersionTuple computeMSVCVersion(const Driver *D,
                                           const llvm::opt::ArgList &Args) const;
 
+  /// Get paths of HIP device libraries.
+  virtual llvm::SmallVector<std::string, 12>
+  getHIPDeviceLibs(const llvm::opt::ArgList &Args) const;
+
   /// Return sanitizers which are available in this toolchain.
   virtual SanitizerMask getSupportedSanitizers() const;
 

diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index f684ea7c93f7..566fd63e8478 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2844,12 +2844,15 @@ class OffloadingActionBuilder final {
   class HIPActionBuilder final : public CudaActionBuilderBase {
     /// The linker inputs obtained for each device arch.
     SmallVector<ActionList, 8> DeviceLinkerInputs;
+    bool GPUSanitize;
 
   public:
     HIPActionBuilder(Compilation &C, DerivedArgList &Args,
                      const Driver::InputList &Inputs)
         : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP) {
       DefaultCudaArch = CudaArch::GFX803;
+      GPUSanitize = Args.hasFlag(options::OPT_fgpu_sanitize,
+                                 options::OPT_fno_gpu_sanitize, false);
     }
 
     bool canUseBundlerUnbundler() const override { return true; }
@@ -2898,17 +2901,33 @@ class OffloadingActionBuilder final {
         // a fat binary containing all the code objects for 
diff erent GPU's.
         // The fat binary is then an input to the host action.
         for (unsigned I = 0, E = GpuArchList.size(); I != E; ++I) {
-          auto BackendAction = C.getDriver().ConstructPhaseAction(
-              C, Args, phases::Backend, CudaDeviceActions[I],
-              AssociatedOffloadKind);
-          auto AssembleAction = C.getDriver().ConstructPhaseAction(
-              C, Args, phases::Assemble, BackendAction, AssociatedOffloadKind);
-          // Create a link action to link device IR with device library
-          // and generate ISA.
-          ActionList AL;
-          AL.push_back(AssembleAction);
-          CudaDeviceActions[I] =
-              C.MakeAction<LinkJobAction>(AL, types::TY_Image);
+          if (GPUSanitize) {
+            // When GPU sanitizer is enabled, since we need to link in the
+            // the sanitizer runtime library after the sanitize pass, we have
+            // to skip the backend and assemble phases and use lld to link
+            // the bitcode.
+            ActionList AL;
+            AL.push_back(CudaDeviceActions[I]);
+            // Create a link action to link device IR with device library
+            // and generate ISA.
+            CudaDeviceActions[I] =
+                C.MakeAction<LinkJobAction>(AL, types::TY_Image);
+          } else {
+            // When GPU sanitizer is not enabled, we follow the conventional
+            // compiler phases, including backend and assemble phases.
+            ActionList AL;
+            auto BackendAction = C.getDriver().ConstructPhaseAction(
+                C, Args, phases::Backend, CudaDeviceActions[I],
+                AssociatedOffloadKind);
+            auto AssembleAction = C.getDriver().ConstructPhaseAction(
+                C, Args, phases::Assemble, BackendAction,
+                AssociatedOffloadKind);
+            AL.push_back(AssembleAction);
+            // Create a link action to link device IR with device library
+            // and generate ISA.
+            CudaDeviceActions[I] =
+                C.MakeAction<LinkJobAction>(AL, types::TY_Image);
+          }
 
           // OffloadingActionBuilder propagates device arch until an offload
           // action. Since the next action for creating fatbin does

diff  --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 5c275353b679..d9c04f9d91f5 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -931,10 +931,15 @@ static bool hasTargetFeatureMTE(const llvm::opt::ArgStringList &CmdArgs) {
 void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
                             llvm::opt::ArgStringList &CmdArgs,
                             types::ID InputType) const {
-  // NVPTX/AMDGPU doesn't currently support sanitizers.  Bailing out here means
+  // NVPTX doesn't currently support sanitizers.  Bailing out here means
   // that e.g. -fsanitize=address applies only to host code, which is what we
   // want for now.
-  if (TC.getTriple().isNVPTX() || TC.getTriple().isAMDGPU())
+  //
+  // AMDGPU sanitizer support is experimental and controlled by -fgpu-sanitize.
+  if (TC.getTriple().isNVPTX() ||
+      (TC.getTriple().isAMDGPU() &&
+       !Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,
+                     false)))
     return;
 
   // Translate available CoverageFeatures to corresponding clang-cc1 flags.

diff  --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index d0f404d8cbaa..372be613b795 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -1127,6 +1127,11 @@ void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
 void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
                                   ArgStringList &CC1Args) const {}
 
+llvm::SmallVector<std::string, 12>
+ToolChain::getHIPDeviceLibs(const ArgList &DriverArgs) const {
+  return {};
+}
+
 void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
                                     ArgStringList &CC1Args) const {}
 

diff  --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 0971a2da62a3..83d3014a7db5 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -50,6 +50,8 @@ void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) {
       OpenCL = FilePath;
     } else if (BaseName == "hip") {
       HIP = FilePath;
+    } else if (BaseName == "asanrtl") {
+      AsanRTL = FilePath;
     } else if (BaseName == "oclc_finite_only_off") {
       FiniteOnly.Off = FilePath;
     } else if (BaseName == "oclc_finite_only_on") {
@@ -605,47 +607,40 @@ void ROCMToolChain::addClangTargetOptions(
       DriverArgs.hasArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt);
 
   // Add the OpenCL specific bitcode library.
-  CC1Args.push_back("-mlink-builtin-bitcode");
-  CC1Args.push_back(DriverArgs.MakeArgString(RocmInstallation.getOpenCLPath()));
+  llvm::SmallVector<std::string, 12> BCLibs;
+  BCLibs.push_back(RocmInstallation.getOpenCLPath().str());
 
   // Add the generic set of libraries.
-  RocmInstallation.addCommonBitcodeLibCC1Args(
-      DriverArgs, CC1Args, LibDeviceFile, Wave64, DAZ, FiniteOnly,
-      UnsafeMathOpt, FastRelaxedMath, CorrectSqrt);
+  BCLibs.append(RocmInstallation.getCommonBitcodeLibs(
+      DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
+      FastRelaxedMath, CorrectSqrt));
+
+  llvm::for_each(BCLibs, [&](StringRef BCFile) {
+    CC1Args.push_back("-mlink-builtin-bitcode");
+    CC1Args.push_back(DriverArgs.MakeArgString(BCFile));
+  });
 }
 
-void RocmInstallationDetector::addCommonBitcodeLibCC1Args(
-    const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
-    StringRef LibDeviceFile, bool Wave64, bool DAZ, bool FiniteOnly,
-    bool UnsafeMathOpt, bool FastRelaxedMath, bool CorrectSqrt) const {
-  static const char LinkBitcodeFlag[] = "-mlink-builtin-bitcode";
-
-  CC1Args.push_back(LinkBitcodeFlag);
-  CC1Args.push_back(DriverArgs.MakeArgString(getOCMLPath()));
-
-  CC1Args.push_back(LinkBitcodeFlag);
-  CC1Args.push_back(DriverArgs.MakeArgString(getOCKLPath()));
-
-  CC1Args.push_back(LinkBitcodeFlag);
-  CC1Args.push_back(DriverArgs.MakeArgString(getDenormalsAreZeroPath(DAZ)));
-
-  CC1Args.push_back(LinkBitcodeFlag);
-  CC1Args.push_back(DriverArgs.MakeArgString(
-      getUnsafeMathPath(UnsafeMathOpt || FastRelaxedMath)));
+llvm::SmallVector<std::string, 12>
+RocmInstallationDetector::getCommonBitcodeLibs(
+    const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, bool Wave64,
+    bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, bool FastRelaxedMath,
+    bool CorrectSqrt) const {
 
-  CC1Args.push_back(LinkBitcodeFlag);
-  CC1Args.push_back(DriverArgs.MakeArgString(
-      getFiniteOnlyPath(FiniteOnly || FastRelaxedMath)));
+  llvm::SmallVector<std::string, 12> BCLibs;
 
-  CC1Args.push_back(LinkBitcodeFlag);
-  CC1Args.push_back(
-      DriverArgs.MakeArgString(getCorrectlyRoundedSqrtPath(CorrectSqrt)));
+  auto AddBCLib = [&](StringRef BCFile) { BCLibs.push_back(BCFile.str()); };
 
-  CC1Args.push_back(LinkBitcodeFlag);
-  CC1Args.push_back(DriverArgs.MakeArgString(getWavefrontSize64Path(Wave64)));
+  AddBCLib(getOCMLPath());
+  AddBCLib(getOCKLPath());
+  AddBCLib(getDenormalsAreZeroPath(DAZ));
+  AddBCLib(getUnsafeMathPath(UnsafeMathOpt || FastRelaxedMath));
+  AddBCLib(getFiniteOnlyPath(FiniteOnly || FastRelaxedMath));
+  AddBCLib(getCorrectlyRoundedSqrtPath(CorrectSqrt));
+  AddBCLib(getWavefrontSize64Path(Wave64));
+  AddBCLib(LibDeviceFile);
 
-  CC1Args.push_back(LinkBitcodeFlag);
-  CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
+  return BCLibs;
 }
 
 bool AMDGPUToolChain::shouldSkipArgument(const llvm::opt::Arg *A) const {

diff  --git a/clang/lib/Driver/ToolChains/HIP.cpp b/clang/lib/Driver/ToolChains/HIP.cpp
index 12aaecad7fab..1c4eab91d693 100644
--- a/clang/lib/Driver/ToolChains/HIP.cpp
+++ b/clang/lib/Driver/ToolChains/HIP.cpp
@@ -35,23 +35,6 @@ using namespace llvm::opt;
 
 namespace {
 const unsigned HIPCodeObjectAlign = 4096;
-
-static void addBCLib(const Driver &D, const ArgList &Args,
-                     ArgStringList &CmdArgs, ArgStringList LibraryPaths,
-                     StringRef BCName) {
-  StringRef FullName;
-  for (std::string LibraryPath : LibraryPaths) {
-    SmallString<128> Path(LibraryPath);
-    llvm::sys::path::append(Path, BCName);
-    FullName = Path;
-    if (llvm::sys::fs::exists(FullName)) {
-      CmdArgs.push_back("-mlink-builtin-bitcode");
-      CmdArgs.push_back(Args.MakeArgString(FullName));
-      return;
-    }
-  }
-  D.Diag(diag::err_drv_no_such_file) << BCName;
-}
 } // namespace
 
 void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA,
@@ -96,6 +79,13 @@ void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA,
   LldArgs.append({"-o", Output.getFilename()});
   for (auto Input : Inputs)
     LldArgs.push_back(Input.getFilename());
+
+  if (Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,
+                   false))
+    llvm::for_each(TC.getHIPDeviceLibs(Args), [&](StringRef BCFile) {
+      LldArgs.push_back(Args.MakeArgString(BCFile));
+    });
+
   const char *Lld = Args.MakeArgString(getToolChain().GetProgramPath("lld"));
   C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
                                          Lld, LldArgs, Inputs, Output));
@@ -247,13 +237,8 @@ void HIPToolChain::addClangTargetOptions(
     Action::OffloadKind DeviceOffloadingKind) const {
   HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind);
 
-  StringRef GpuArch = getGPUArch(DriverArgs);
-  assert(!GpuArch.empty() && "Must have an explicit GPU arch.");
-  (void) GpuArch;
   assert(DeviceOffloadingKind == Action::OFK_HIP &&
          "Only HIP offloading kinds are supported for GPUs.");
-  auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch);
-  const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind);
 
   CC1Args.push_back("-fcuda-is-device");
 
@@ -283,66 +268,10 @@ void HIPToolChain::addClangTargetOptions(
     CC1Args.push_back("-fapply-global-visibility-to-externs");
   }
 
-  if (DriverArgs.hasArg(options::OPT_nogpulib))
-    return;
-  ArgStringList LibraryPaths;
-
-  // Find in --hip-device-lib-path and HIP_LIBRARY_PATH.
-  for (auto Path : RocmInstallation.getRocmDeviceLibPathArg())
-    LibraryPaths.push_back(DriverArgs.MakeArgString(Path));
-
-  addDirectoryList(DriverArgs, LibraryPaths, "", "HIP_DEVICE_LIB_PATH");
-
-  // Maintain compatability with --hip-device-lib.
-  auto BCLibs = DriverArgs.getAllArgValues(options::OPT_hip_device_lib_EQ);
-  if (!BCLibs.empty()) {
-    for (auto Lib : BCLibs)
-      addBCLib(getDriver(), DriverArgs, CC1Args, LibraryPaths, Lib);
-  } else {
-    if (!RocmInstallation.hasDeviceLibrary()) {
-      getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
-      return;
-    }
-
-    std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch);
-    if (LibDeviceFile.empty()) {
-      getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 1 << GpuArch;
-      return;
-    }
-
-    // If --hip-device-lib is not set, add the default bitcode libraries.
-    // TODO: There are way too many flags that change this. Do we need to check
-    // them all?
-    bool DAZ = DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero,
-                                  options::OPT_fno_cuda_flush_denormals_to_zero,
-                                  getDefaultDenormsAreZeroForTarget(Kind));
-    // TODO: Check standard C++ flags?
-    bool FiniteOnly = false;
-    bool UnsafeMathOpt = false;
-    bool FastRelaxedMath = false;
-    bool CorrectSqrt = true;
-    bool Wave64 = isWave64(DriverArgs, Kind);
-
-    // Add the HIP specific bitcode library.
+  llvm::for_each(getHIPDeviceLibs(DriverArgs), [&](StringRef BCFile) {
     CC1Args.push_back("-mlink-builtin-bitcode");
-    CC1Args.push_back(DriverArgs.MakeArgString(RocmInstallation.getHIPPath()));
-
-    // Add the generic set of libraries.
-    RocmInstallation.addCommonBitcodeLibCC1Args(
-      DriverArgs, CC1Args, LibDeviceFile, Wave64, DAZ, FiniteOnly,
-      UnsafeMathOpt, FastRelaxedMath, CorrectSqrt);
-
-    // Add instrument lib.
-    auto InstLib =
-        DriverArgs.getLastArgValue(options::OPT_gpu_instrument_lib_EQ);
-    if (InstLib.empty())
-      return;
-    if (llvm::sys::fs::exists(InstLib)) {
-      CC1Args.push_back("-mlink-builtin-bitcode");
-      CC1Args.push_back(DriverArgs.MakeArgString(InstLib));
-    } else
-      getDriver().Diag(diag::err_drv_no_such_file) << InstLib;
-  }
+    CC1Args.push_back(DriverArgs.MakeArgString(BCFile));
+  });
 }
 
 llvm::opt::DerivedArgList *
@@ -421,3 +350,99 @@ VersionTuple HIPToolChain::computeMSVCVersion(const Driver *D,
                                                const ArgList &Args) const {
   return HostTC.computeMSVCVersion(D, Args);
 }
+
+llvm::SmallVector<std::string, 12>
+HIPToolChain::getHIPDeviceLibs(const llvm::opt::ArgList &DriverArgs) const {
+  llvm::SmallVector<std::string, 12> BCLibs;
+  if (DriverArgs.hasArg(options::OPT_nogpulib))
+    return {};
+  ArgStringList LibraryPaths;
+
+  // Find in --hip-device-lib-path and HIP_LIBRARY_PATH.
+  for (auto Path : RocmInstallation.getRocmDeviceLibPathArg())
+    LibraryPaths.push_back(DriverArgs.MakeArgString(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()) {
+    llvm::for_each(BCLibArgs, [&](StringRef BCName) {
+      StringRef FullName;
+      for (std::string LibraryPath : LibraryPaths) {
+        SmallString<128> Path(LibraryPath);
+        llvm::sys::path::append(Path, BCName);
+        FullName = Path;
+        if (llvm::sys::fs::exists(FullName)) {
+          BCLibs.push_back(FullName.str());
+          return;
+        }
+      }
+      getDriver().Diag(diag::err_drv_no_such_file) << BCName;
+    });
+  } else {
+    if (!RocmInstallation.hasDeviceLibrary()) {
+      getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
+      return {};
+    }
+    StringRef GpuArch = getGPUArch(DriverArgs);
+    assert(!GpuArch.empty() && "Must have an explicit GPU arch.");
+    (void)GpuArch;
+    auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch);
+    const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind);
+
+    std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch);
+    if (LibDeviceFile.empty()) {
+      getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 1 << GpuArch;
+      return {};
+    }
+
+    // If --hip-device-lib is not set, add the default bitcode libraries.
+    // TODO: There are way too many flags that change this. Do we need to check
+    // them all?
+    bool DAZ = DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero,
+                                  options::OPT_fno_cuda_flush_denormals_to_zero,
+                                  getDefaultDenormsAreZeroForTarget(Kind));
+    // TODO: Check standard C++ flags?
+    bool FiniteOnly = false;
+    bool UnsafeMathOpt = false;
+    bool FastRelaxedMath = false;
+    bool CorrectSqrt = true;
+    bool Wave64 = isWave64(DriverArgs, Kind);
+
+    if (DriverArgs.hasFlag(options::OPT_fgpu_sanitize,
+                           options::OPT_fno_gpu_sanitize, false)) {
+      auto AsanRTL = RocmInstallation.getAsanRTLPath();
+      if (AsanRTL.empty()) {
+        unsigned DiagID = getDriver().getDiags().getCustomDiagID(
+            DiagnosticsEngine::Error,
+            "AMDGPU address sanitizer runtime library (asanrtl) is not found. "
+            "Please install ROCm device library which supports address "
+            "sanitizer");
+        getDriver().Diag(DiagID);
+        return {};
+      } else
+        BCLibs.push_back(AsanRTL.str());
+    }
+
+    // Add the HIP specific bitcode library.
+    BCLibs.push_back(RocmInstallation.getHIPPath().str());
+
+    // Add the generic set of libraries.
+    BCLibs.append(RocmInstallation.getCommonBitcodeLibs(
+        DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
+        FastRelaxedMath, CorrectSqrt));
+
+    // 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.push_back(InstLib.str());
+    else
+      getDriver().Diag(diag::err_drv_no_such_file) << InstLib;
+  }
+
+  return BCLibs;
+}

diff  --git a/clang/lib/Driver/ToolChains/HIP.h b/clang/lib/Driver/ToolChains/HIP.h
index 88e18485f50f..a9e1ed9a4656 100644
--- a/clang/lib/Driver/ToolChains/HIP.h
+++ b/clang/lib/Driver/ToolChains/HIP.h
@@ -83,6 +83,8 @@ class LLVM_LIBRARY_VISIBILITY HIPToolChain final : public ROCMToolChain {
                            llvm::opt::ArgStringList &CC1Args) const override;
   void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
                          llvm::opt::ArgStringList &CC1Args) const override;
+  llvm::SmallVector<std::string, 12>
+  getHIPDeviceLibs(const llvm::opt::ArgList &Args) const override;
 
   SanitizerMask getSupportedSanitizers() const override;
 

diff  --git a/clang/lib/Driver/ToolChains/ROCm.h b/clang/lib/Driver/ToolChains/ROCm.h
index 21e62a465d7b..93707d3d1aaf 100644
--- a/clang/lib/Driver/ToolChains/ROCm.h
+++ b/clang/lib/Driver/ToolChains/ROCm.h
@@ -88,6 +88,9 @@ class RocmInstallationDetector {
   SmallString<0> OpenCL;
   SmallString<0> HIP;
 
+  // Asan runtime library
+  SmallString<0> AsanRTL;
+
   // Libraries swapped based on compile flags.
   ConditionalLibrary WavefrontSize64;
   ConditionalLibrary FiniteOnly;
@@ -112,12 +115,13 @@ class RocmInstallationDetector {
                            bool DetectHIPRuntime = true,
                            bool DetectDeviceLib = false);
 
-  /// Add arguments needed to link default bitcode libraries.
-  void addCommonBitcodeLibCC1Args(const llvm::opt::ArgList &DriverArgs,
-                                  llvm::opt::ArgStringList &CC1Args,
-                                  StringRef LibDeviceFile, bool Wave64,
-                                  bool DAZ, bool FiniteOnly, bool UnsafeMathOpt,
-                                  bool FastRelaxedMath, bool CorrectSqrt) const;
+  /// Get file paths of default bitcode libraries common to AMDGPU based
+  /// toolchains.
+  llvm::SmallVector<std::string, 12>
+  getCommonBitcodeLibs(const llvm::opt::ArgList &DriverArgs,
+                       StringRef LibDeviceFile, bool Wave64, bool DAZ,
+                       bool FiniteOnly, bool UnsafeMathOpt,
+                       bool FastRelaxedMath, bool CorrectSqrt) const;
 
   /// Check whether we detected a valid HIP runtime.
   bool hasHIPRuntime() const { return HasHIPRuntime; }
@@ -166,6 +170,9 @@ class RocmInstallationDetector {
     return HIP;
   }
 
+  /// Returns empty string of Asan runtime library is not available.
+  StringRef getAsanRTLPath() const { return AsanRTL; }
+
   StringRef getWavefrontSize64Path(bool Enabled) const {
     return WavefrontSize64.get(Enabled);
   }

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/README b/clang/test/Driver/Inputs/rocm-invalid/README
new file mode 100644
index 000000000000..67dc17cbf60a
--- /dev/null
+++ b/clang/test/Driver/Inputs/rocm-invalid/README
@@ -0,0 +1,4 @@
+This directory is for testing invalid ROCm installations.
+
+It is invalid for -fgpu-sanitize since the required Asan
+runtime library (asanrtl.bc) is missing.

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/hip.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/hip.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/ockl.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/ockl.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_correctly_rounded_sqrt_off.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_correctly_rounded_sqrt_off.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_correctly_rounded_sqrt_on.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_correctly_rounded_sqrt_on.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_daz_opt_off.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_daz_opt_off.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_daz_opt_on.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_daz_opt_on.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_finite_only_off.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_finite_only_off.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_finite_only_on.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_finite_only_on.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_1010.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_1010.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_1011.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_1011.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_1012.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_1012.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_803.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_803.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_900.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_900.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_908.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_isa_version_908.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_unsafe_math_off.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_unsafe_math_off.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_unsafe_math_on.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_unsafe_math_on.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_wavefrontsize64_off.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_wavefrontsize64_off.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_wavefrontsize64_on.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/oclc_wavefrontsize64_on.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/ocml.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/ocml.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/opencl.bc b/clang/test/Driver/Inputs/rocm-invalid/amdgcn/bitcode/opencl.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/bin/.hipVersion b/clang/test/Driver/Inputs/rocm-invalid/bin/.hipVersion
new file mode 100644
index 000000000000..7c66f8ff23d9
--- /dev/null
+++ b/clang/test/Driver/Inputs/rocm-invalid/bin/.hipVersion
@@ -0,0 +1,6 @@
+# Auto-generated by cmake
+# NOTE: The trailing whitespace is added on purpose to verify that these
+# whitespaces are trimmed before paring.
+HIP_VERSION_MAJOR=3
+HIP_VERSION_MINOR=6
+HIP_VERSION_PATCH=20214-a2917cd

diff  --git a/clang/test/Driver/Inputs/rocm-invalid/include/hip/hip_runtime.h b/clang/test/Driver/Inputs/rocm-invalid/include/hip/hip_runtime.h
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/rocm/amdgcn/bitcode/asanrtl.bc b/clang/test/Driver/Inputs/rocm/amdgcn/bitcode/asanrtl.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/hip-sanitize-options.hip b/clang/test/Driver/hip-sanitize-options.hip
index 908e02136cad..6c9a6cc31723 100644
--- a/clang/test/Driver/hip-sanitize-options.hip
+++ b/clang/test/Driver/hip-sanitize-options.hip
@@ -1,9 +1,40 @@
 // REQUIRES: clang-driver, x86-registered-target, amdgpu-registered-target
 
-// RUN: %clang -### -target x86_64-unknown-linux-gnu --offload-arch=gfx906 \
+// RUN: %clang -### -target x86_64-unknown-linux-gnu --offload-arch=gfx900 \
 // RUN:   -fsanitize=address \
-// RUN:   -nogpuinc -nogpulib \
+// RUN:   -nogpuinc --rocm-path=%S/Inputs/rocm \
 // RUN:   %s 2>&1 | FileCheck %s
 
+// RUN: %clang -### -target x86_64-unknown-linux-gnu --offload-arch=gfx900 \
+// RUN:   -fsanitize=address -fno-gpu-sanitize \
+// RUN:   -nogpuinc --rocm-path=%S/Inputs/rocm \
+// RUN:   %s 2>&1 | FileCheck %s
+
+// RUN: %clang -### -target x86_64-unknown-linux-gnu --offload-arch=gfx900 \
+// RUN:   -fsanitize=address -fgpu-sanitize \
+// RUN:   -nogpuinc --rocm-path=%S/Inputs/rocm \
+// RUN:   %s 2>&1 | FileCheck -check-prefixes=NORDC %s
+
+// RUN: %clang -### -target x86_64-unknown-linux-gnu --offload-arch=gfx900 \
+// RUN:   -fsanitize=address -fgpu-sanitize -fgpu-rdc \
+// RUN:   -nogpuinc --rocm-path=%S/Inputs/rocm \
+// RUN:   %s 2>&1 | FileCheck -check-prefixes=RDC %s
+
+// RUN: %clang -### -target x86_64-unknown-linux-gnu --offload-arch=gfx900 \
+// RUN:   -fsanitize=address -fgpu-sanitize \
+// RUN:   -nogpuinc --rocm-path=%S/Inputs/rocm-invalid \
+// RUN:   %s 2>&1 | FileCheck -check-prefixes=FAIL %s
+
 // CHECK-NOT: {{"[^"]*clang[^"]*".* "-fcuda-is-device".* "-fsanitize=address"}}
+// CHECK-NOT: {{"[^"]*lld[^"]*".* ".*hip.bc"}}
 // CHECK: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address"}}
+
+// NORDC: {{"[^"]*clang[^"]*".* "-fcuda-is-device".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.bc]]"
+// NORDC: {{"[^"]*lld[^"]*".*}} "[[OUT]]" {{".*asanrtl.bc" ".*hip.bc"}}
+// NORDC: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address"}}
+
+// RDC: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address"}}
+// RDC: {{"[^"]*clang[^"]*".* "-emit-llvm-bc".* "-fcuda-is-device".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.bc]]"
+// RDC: {{"[^"]*lld[^"]*".*}} "[[OUT]]" {{".*asanrtl.bc" ".*hip.bc"}}
+
+// FAIL: AMDGPU address sanitizer runtime library (asanrtl) is not found. Please install ROCm device library which supports address sanitizer


        


More information about the cfe-commits mailing list