diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index f573f5a06ceb5..f8143651cd3c1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5055,6 +5055,9 @@ def nogpulib : Flag<["-"], "nogpulib">, MarshallingInfoFlag Visibility<[ClangOption, CC1Option]>, HelpText<"Do not link device library for CUDA/HIP device compilation">; def : Flag<["-"], "nocudalib">, Alias; +def gpulibc : Flag<["-"], "gpulibc">, Visibility<[ClangOption, CC1Option]>, + HelpText<"Link the LLVM C Library for GPUs">; +def nogpulibc : Flag<["-"], "nogpulibc">, Visibility<[ClangOption, CC1Option]>; def nodefaultlibs : Flag<["-"], "nodefaultlibs">; def nodriverkitlib : Flag<["-"], "nodriverkitlib">; def nofixprebinding : Flag<["-"], "nofixprebinding">; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 9777672ac1f44..483ecd0ae592a 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -869,6 +869,26 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, /*IsLTO=*/true, PluginOptPrefix); } +/// Adds the '-lcgpu' and '-lmgpu' libraries to the compilation to include the +/// LLVM C library for GPUs. +static void addOpenMPDeviceLibC(const ToolChain &TC, const ArgList &Args, + ArgStringList &CmdArgs) { + if (Args.hasArg(options::OPT_nogpulib) || Args.hasArg(options::OPT_nolibc)) + return; + + // Check the resource directory for the LLVM libc GPU declarations. If it's + // found we can assume that LLVM was built with support for the GPU libc. + SmallString<256> LibCDecls(TC.getDriver().ResourceDir); + llvm::sys::path::append(LibCDecls, "include", "llvm_libc_wrappers", + "llvm-libc-decls"); + bool HasLibC = llvm::sys::fs::exists(LibCDecls) && + llvm::sys::fs::is_directory(LibCDecls); + if (Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC)) { + CmdArgs.push_back("-lcgpu"); + CmdArgs.push_back("-lmgpu"); + } +} + void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { @@ -939,6 +959,9 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, if (IsOffloadingHost && !Args.hasArg(options::OPT_nogpulib)) CmdArgs.push_back("-lomptarget.devicertl"); + if (IsOffloadingHost) + addOpenMPDeviceLibC(TC, Args, CmdArgs); + addArchSpecificRPath(TC, Args, CmdArgs); addOpenMPRuntimeLibraryPath(TC, Args, CmdArgs); diff --git a/clang/test/Driver/openmp-offload-gpu.c b/clang/test/Driver/openmp-offload-gpu.c index 98202d7f8e863..bccc5fd9483ac 100644 --- a/clang/test/Driver/openmp-offload-gpu.c +++ b/clang/test/Driver/openmp-offload-gpu.c @@ -387,3 +387,20 @@ // RUN: | FileCheck --check-prefix=XARCH-DEVICE %s // XARCH-DEVICE: "-cc1" "-triple" "nvptx64-nvidia-cuda"{{.*}}"-O3" // XARCH-DEVICE-NOT: "-cc1" "-triple" "x86_64-unknown-linux-gnu"{{.*}}"-O3" + +// +// Check that `-gpulibc` includes the LLVM C libraries for the GPU. +// +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp \ +// RUN: --libomptarget-nvptx-bc-path=%S/Inputs/libomptarget/libomptarget-nvptx-test.bc \ +// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ +// RUN: --offload-arch=sm_52 -gpulibc -nogpuinc %s 2>&1 \ +// RUN: | FileCheck --check-prefix=LIBC-GPU %s +// LIBC-GPU: "-lcgpu"{{.*}}"-lmgpu" + +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp \ +// RUN: --libomptarget-nvptx-bc-path=%S/Inputs/libomptarget/libomptarget-nvptx-test.bc \ +// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ +// RUN: --offload-arch=sm_52 -nogpulibc -nogpuinc %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NO-LIBC-GPU %s +// NO-LIBC-GPU-NOT: "-lcgpu"{{.*}}"-lmgpu"