diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -927,6 +927,8 @@ Alias; def hip_link : Flag<["--"], "hip-link">, HelpText<"Link clang-offload-bundler bundles for HIP">; +def no_hip_rt: Flag<["-"], "no-hip-rt">, + HelpText<"Do not link against HIP runtime libraries">; def no_offload_arch_EQ : Joined<["--"], "no-offload-arch=">, Flags<[NoXarchOption]>, HelpText<"Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. " "'all' resets the list to its default value.">; diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -696,6 +696,11 @@ virtual llvm::SmallVector getHIPDeviceLibs(const llvm::opt::ArgList &Args) const; + /// Add the system specific linker arguments to use + /// for the given HIP runtime library type. + virtual void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const {} + /// Return sanitizers which are available in this toolchain. virtual SanitizerMask getSupportedSanitizers() const; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -120,6 +120,9 @@ bool ForceStaticHostRuntime = false, bool IsOffloadingHost = false, bool GompNeedsRT = false); +void addHIPRuntimeLibArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs); + const char *getAsNeededOption(const ToolChain &TC, bool as_needed); llvm::opt::Arg *getLastProfileUseArg(const llvm::opt::ArgList &Args); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2089,3 +2089,17 @@ << LibOmpTargetName << ArchPrefix; } } +void tools::addHIPRuntimeLibArgs(const ToolChain &TC, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) { + if (Args.hasArg(options::OPT_hip_link) && + !Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_no_hip_rt)) { + TC.AddHIPRuntimeLibArgs(Args, CmdArgs); + } else { + // Claim "no HIP libraries" arguments if any + for (auto Arg : Args.filtered(options::OPT_no_hip_rt)) { + Arg->claim(); + } + } +} diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -580,6 +580,9 @@ bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs); AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); + + addHIPRuntimeLibArgs(ToolChain, Args, CmdArgs); + // The profile runtime also needs access to system libraries. getToolChain().addProfileRTLibs(Args, CmdArgs); diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -37,6 +37,8 @@ llvm::opt::ArgStringList &CC1Args) const override; void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; RuntimeLibType GetDefaultRuntimeLibType() const override; diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -676,6 +676,15 @@ RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); } +void Linux::AddHIPRuntimeLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + CmdArgs.append( + {Args.MakeArgString(StringRef("-L") + RocmInstallation.getLibPath()), + "-rpath", Args.MakeArgString(RocmInstallation.getLibPath())}); + + CmdArgs.push_back("-lamdhip64"); +} + void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { if (GCCInstallation.isValid()) { diff --git a/clang/lib/Driver/ToolChains/MSVC.h b/clang/lib/Driver/ToolChains/MSVC.h --- a/clang/lib/Driver/ToolChains/MSVC.h +++ b/clang/lib/Driver/ToolChains/MSVC.h @@ -96,6 +96,9 @@ void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + bool getWindowsSDKLibraryPath( const llvm::opt::ArgList &Args, std::string &path) const; bool getUniversalCRTLibraryPath(const llvm::opt::ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -286,6 +286,8 @@ A.renderAsInput(Args, CmdArgs); } + addHIPRuntimeLibArgs(TC, Args, CmdArgs); + TC.addProfileRTLibs(Args, CmdArgs); std::vector Environment; @@ -475,6 +477,13 @@ RocmInstallation.AddHIPIncludeArgs(DriverArgs, CC1Args); } +void MSVCToolChain::AddHIPRuntimeLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + CmdArgs.append({Args.MakeArgString(StringRef("-libpath:") + + RocmInstallation.getLibPath()), + "amdhip64.lib"}); +} + void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const { CudaInstallation.print(OS); RocmInstallation.print(OS); diff --git a/clang/test/Driver/hip-runtime-libs-linux.hip b/clang/test/Driver/hip-runtime-libs-linux.hip new file mode 100644 --- /dev/null +++ b/clang/test/Driver/hip-runtime-libs-linux.hip @@ -0,0 +1,43 @@ +// UNSUPPORTED: system-windows + +// RUN: touch %t.o + +// Test HIP runtime lib args specified by --rocm-path. +// RUN: %clang -### --hip-link -target x86_64-linux-gnu \ +// RUN: --rocm-path=%S/Inputs/rocm %t.o 2>&1 \ +// RUN: | FileCheck -check-prefixes=ROCM-PATH %s + +// Test HIP runtime lib args specified by environment variable ROCM_PATH. +// RUN: env ROCM_PATH=%S/Inputs/rocm %clang -### --hip-link \ +// RUN: -target x86_64-linux-gnu %t.o 2>&1 \ +// RUN: | FileCheck -check-prefixes=ROCM-PATH %s + +// Test detecting latest /opt/rocm-{release} directory. +// RUN: rm -rf %T/opt +// RUN: mkdir -p %T/opt +// RUN: cp -r %S/Inputs/rocm %T/opt/rocm-3.9.0-1234 +// RUN: cp -r %S/Inputs/rocm %T/opt/rocm-3.10.0 +// RUN: %clang -### --hip-link -target x86_64-linux-gnu \ +// RUN: --sysroot=%T %t.o 2>&1 \ +// RUN: | FileCheck -check-prefixes=ROCM-REL %s + +// Test HIP runtime lib is not linked without --hip-link. +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: --rocm-path=%S/Inputs/rocm %t.o 2>&1 \ +// RUN: | FileCheck -check-prefixes=NOHIPRT %s + +// Test HIP runtime lib is not linked with -nostdlib. +// RUN: %clang -### --hip-link -nostdlib -target x86_64-linux-gnu \ +// RUN: --rocm-path=%S/Inputs/rocm %t.o 2>&1 \ +// RUN: | FileCheck -check-prefixes=NOHIPRT %s + +// Test HIP runtime lib is not linked with -no-hip-rt. +// RUN: %clang -### --hip-link -no-hip-rt -target x86_64-linux-gnu \ +// RUN: --rocm-path=%S/Inputs/rocm %t.o 2>&1 \ +// RUN: | FileCheck -check-prefixes=NOHIPRT %s + +// ROCM-PATH: "-L[[HIPRT:.*/Inputs/rocm/lib]]" "-rpath" "[[HIPRT]]" "-lamdhip64" +// ROCM-REL: "-L[[HIPRT:.*/opt/rocm-3.10.0/lib]]" "-rpath" "[[HIPRT]]" "-lamdhip64" +// NOHIPRT-NOT: "-L{{.*/Inputs/rocm/lib}}" +// NOHIPRT-NOT: "-rpath" "{{.*/Inputs/rocm/lib}}" +// NOHIPRT-NOT: "-lamdhip64" diff --git a/clang/test/Driver/hip-runtime-libs-msvc.hip b/clang/test/Driver/hip-runtime-libs-msvc.hip new file mode 100644 --- /dev/null +++ b/clang/test/Driver/hip-runtime-libs-msvc.hip @@ -0,0 +1,10 @@ +// REQUIRES: system-windows + +// RUN: touch %t.o + +// Test HIP runtime lib args specified by --rocm-path. +// RUN: %clang -### --hip-link -target x86_64-pc-windows-msvc \ +// RUN: --rocm-path=%S/Inputs/rocm %t.o 2>&1 \ +// RUN: | FileCheck %s + +// CHECK: "-libpath:{{.*Inputs.*rocm.*lib}}" "amdhip64.lib"