diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index d69f54c563ae6..c3d3d93fd236c 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -5564,7 +5564,7 @@ class OffloadingActionBuilder final { SYCLDeviceLibLinked = addSYCLDeviceLibs( TC, SYCLDeviceLibs, UseAOTLink, C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment(), - IsSYCLNativeCPU, NativeCPULib); + IsSYCLNativeCPU, NativeCPULib, BoundArch); } JobAction *LinkSYCLLibs = C.MakeAction(SYCLDeviceLibs, types::TY_LLVM_BC); @@ -5842,7 +5842,7 @@ class OffloadingActionBuilder final { bool addSYCLDeviceLibs(const ToolChain *TC, ActionList &DeviceLinkObjects, bool isSpirvAOT, bool isMSVCEnv, bool isNativeCPU, - Action *&NativeCPULib) { + Action *&NativeCPULib, const char *BoundArch) { int NumOfDeviceLibLinked = 0; SmallVector, 4> LibLocCandidates; SYCLInstallation.getSYCLDeviceLibPath(LibLocCandidates); @@ -5852,14 +5852,10 @@ class OffloadingActionBuilder final { tools::SYCL::getDeviceLibraries(C, TC->getTriple(), isSpirvAOT); for (const auto &DeviceLib : DeviceLibraries) { - bool LibLocSelected = false; for (const auto &LLCandidate : LibLocCandidates) { - if (LibLocSelected) - break; SmallString<128> LibName(LLCandidate); llvm::sys::path::append(LibName, DeviceLib); if (llvm::sys::fs::exists(LibName)) { - // NativeCPU currently only needs libsycl-nativecpu_utils and // libclc, so temporarily skip other device libs in invocation. // Todo: remove once NativeCPU tests the other libraries. @@ -5897,8 +5893,6 @@ class OffloadingActionBuilder final { C.MakeAction(*InputArg, types::TY_LLVM_BC); DeviceLinkObjects.push_back(SYCLDeviceLibsInputAction); } - if (!LibLocSelected) - LibLocSelected = !LibLocSelected; // The device link stage may remove symbols not referenced in the // source code. Since libsycl-nativecpu_utils contains such symbols @@ -5909,14 +5903,18 @@ class OffloadingActionBuilder final { NativeCPULib = DeviceLinkObjects.back(); DeviceLinkObjects.pop_back(); } + + break; } } } - // For NVPTX backend we need to also link libclc and CUDA libdevice - // at the same stage that we link all of the unbundled SYCL libdevice - // objects together. - if ((TC->getTriple().isNVPTX() || isNativeCPU) && NumOfDeviceLibLinked) { + if (!NumOfDeviceLibLinked) + return false; + + // For NVPTX and NativeCPU we need to also link libclc at the same stage + // that we link all of the unbundled SYCL libdevice objects together. + if (TC->getTriple().isNVPTX() || isNativeCPU) { std::string LibSpirvFile; if (Args.hasArg(options::OPT_fsycl_libspirv_path_EQ)) { auto ProvidedPath = @@ -5924,7 +5922,7 @@ class OffloadingActionBuilder final { if (llvm::sys::fs::exists(ProvidedPath)) LibSpirvFile = ProvidedPath; } else { - SmallVector LibraryPaths; + SmallVector LibraryPaths; // Expected path w/out install. SmallString<256> WithoutInstallPath(C.getDriver().ResourceDir); @@ -5936,22 +5934,17 @@ class OffloadingActionBuilder final { llvm::sys::path::append(WithInstallPath, Twine("../../../share/clc")); LibraryPaths.emplace_back(WithInstallPath.c_str()); - // TODO: check if the isNVPTX() path can also use - // TC->getTripleString() so that the conditional could be removed - const std::string TrStr = - isNativeCPU ? TC->getTripleString() : "nvptx64-nvidia-cuda"; - // Select remangled libclc variant StringRef LibSpirvTargetNamePref = TC->getAuxTriple()->isOSWindows() ? "remangled-l32-signed_char.libspirv-" : "remangled-l64-signed_char.libspirv-"; - llvm::Twine LibSpirvTargetNameTemp = LibSpirvTargetNamePref + TrStr; - llvm::Twine LibSpirvTargetName = LibSpirvTargetNameTemp + ".bc"; for (StringRef LibraryPath : LibraryPaths) { SmallString<128> LibSpirvTargetFile(LibraryPath); - llvm::sys::path::append(LibSpirvTargetFile, LibSpirvTargetName); + llvm::sys::path::append(LibSpirvTargetFile, + LibSpirvTargetNamePref + + TC->getTripleString() + ".bc"); if (llvm::sys::fs::exists(LibSpirvTargetFile) || Args.hasArg(options::OPT__HASH_HASH_HASH)) { LibSpirvFile = std::string(LibSpirvTargetFile.str()); @@ -5966,30 +5959,24 @@ class OffloadingActionBuilder final { C.MakeAction(*LibClcInputArg, types::TY_LLVM_BC); DeviceLinkObjects.push_back(SYCLLibClcInputAction); } + } - if (isNativeCPU) { - // return here to not generate cuda actions - return NumOfDeviceLibLinked != 0; - } - + // For NVPTX we also need to link with the CUDA libdevice + if (TC->getTriple().isNVPTX() && !Args.hasArg(options::OPT_nogpulib)) { const toolchains::CudaToolChain *CudaTC = static_cast(TC); - for (const auto &LinkInputEnum : enumerate(DeviceLinkerInputs)) { - const char *BoundArch = - SYCLTargetInfoList[LinkInputEnum.index()].BoundArch; - std::string LibDeviceFile = - CudaTC->CudaInstallation.getLibDeviceFile(BoundArch); - if (!LibDeviceFile.empty()) { - Arg *CudaDeviceLibInputArg = - MakeInputArg(Args, C.getDriver().getOpts(), - Args.MakeArgString(LibDeviceFile)); - auto *SYCLDeviceLibInputAction = C.MakeAction( - *CudaDeviceLibInputArg, types::TY_LLVM_BC); - DeviceLinkObjects.push_back(SYCLDeviceLibInputAction); - } + std::string LibDeviceFile = + CudaTC->CudaInstallation.getLibDeviceFile(BoundArch); + if (!LibDeviceFile.empty()) { + Arg *CudaDeviceLibInputArg = MakeInputArg( + Args, C.getDriver().getOpts(), Args.MakeArgString(LibDeviceFile)); + auto *SYCLDeviceLibInputAction = C.MakeAction( + *CudaDeviceLibInputArg, types::TY_LLVM_BC); + DeviceLinkObjects.push_back(SYCLDeviceLibInputAction); } } - return NumOfDeviceLibLinked != 0; + + return true; } void appendLinkDependences(OffloadAction::DeviceDependences &DA) override { diff --git a/clang/test/Driver/sycl-nvptx-link.cpp b/clang/test/Driver/sycl-nvptx-link.cpp index 42d428d73fc13..092d0e0efd7d5 100644 --- a/clang/test/Driver/sycl-nvptx-link.cpp +++ b/clang/test/Driver/sycl-nvptx-link.cpp @@ -28,6 +28,12 @@ // RUN: --sysroot=%S/Inputs/SYCL --cuda-path=%S/Inputs/CUDA_90/usr/local/cuda %s 2>&1 \ // RUN: | FileCheck %s --check-prefixes=CHECK,LIBDEVICE10 +// Check also that -nocudalib is obeyed +// RUN: %clang -### -fsycl -fsycl-targets=nvptx64-nvidia-cuda -nocudalib \ +// RUN: -Xsycl-target-backend --cuda-gpu-arch=sm_35 \ +// RUN: --sysroot=%S/Inputs/SYCL --cuda-path=%S/Inputs/CUDA_90/usr/local/cuda %s 2>&1 \ +// RUN: | FileCheck %s --check-prefixes=CHECK,NOLIBDEVICE + // First link command: ignored // CHECK: llvm-link @@ -39,3 +45,4 @@ // LIBDEVICE30-SAME: libdevice.compute_30.10.bc // LIBDEVICE35-SAME: libdevice.compute_35.10.bc // LIBDEVICE50-SAME: libdevice.compute_50.10.bc +// NOLIBDEVICE-NOT: libdevice.{{.*}}.10.bc