diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 73e3cc556c0fd..d17b3ed441bd2 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2190,7 +2190,8 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { TranslatedArgs->hasFlag(options::OPT_fopenmp_new_driver, options::OPT_no_offload_new_driver, true)) || TranslatedArgs->hasFlag(options::OPT_offload_new_driver, - options::OPT_no_offload_new_driver, false)) + options::OPT_no_offload_new_driver, + C->isOffloadingHostKind(Action::OFK_SYCL))) setUseNewOffloadingDriver(); // Construct the list of abstract actions to perform for this compilation. On @@ -7080,7 +7081,8 @@ void Driver::BuildDefaultActions(Compilation &C, DerivedArgList &Args, options::OPT_fno_offload_via_llvm, false) || Args.hasFlag(options::OPT_offload_new_driver, options::OPT_no_offload_new_driver, - C.isOffloadingHostKind(Action::OFK_Cuda)); + C.isOffloadingHostKind(Action::OFK_Cuda) || + C.isOffloadingHostKind(Action::OFK_SYCL)); bool HIPNoRDC = C.isOffloadingHostKind(Action::OFK_HIP) && @@ -8207,9 +8209,11 @@ Action *Driver::ConstructPhaseAction( (TargetDeviceOffloadKind == Action::OFK_None || offloadDeviceOnly() || (TargetDeviceOffloadKind == Action::OFK_HIP && - !Args.hasFlag(options::OPT_offload_new_driver, - options::OPT_no_offload_new_driver, - C.isOffloadingHostKind(Action::OFK_Cuda)))) + !Args.hasFlag( + options::OPT_offload_new_driver, + options::OPT_no_offload_new_driver, + C.isOffloadingHostKind(Action::OFK_Cuda) || + C.isOffloadingHostKind(Action::OFK_SYCL)))) ? types::TY_LLVM_IR : types::TY_LLVM_BC; return C.MakeAction(Input, Output); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 90cad2bdbe6a5..6db991024019e 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5289,7 +5289,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, (JA.isHostOffloading(C.getActiveOffloadKinds()) && Args.hasFlag(options::OPT_offload_new_driver, options::OPT_no_offload_new_driver, - C.isOffloadingHostKind(Action::OFK_Cuda))); + C.isOffloadingHostKind(Action::OFK_Cuda) || + C.isOffloadingHostKind(Action::OFK_SYCL))); bool IsRDCMode = Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, IsSYCL); @@ -5976,9 +5977,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-emit-llvm-uselists"); if (IsUsingLTO) { - bool IsUsingOffloadNewDriver = - Args.hasFlag(options::OPT_offload_new_driver, - options::OPT_no_offload_new_driver, false); + bool IsUsingOffloadNewDriver = Args.hasFlag( + options::OPT_offload_new_driver, options::OPT_no_offload_new_driver, + C.isOffloadingHostKind(Action::OFK_SYCL)); Arg *SYCLSplitMode = Args.getLastArg(options::OPT_fsycl_device_code_split_EQ); bool IsDeviceCodeSplitDisabled = @@ -7556,7 +7557,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.append({"--offload-new-driver", "-foffload-via-llvm"}); } else if (Args.hasFlag(options::OPT_offload_new_driver, options::OPT_no_offload_new_driver, - C.isOffloadingHostKind(Action::OFK_Cuda))) { + C.isOffloadingHostKind(Action::OFK_Cuda) || + C.isOffloadingHostKind(Action::OFK_SYCL))) { CmdArgs.push_back("--offload-new-driver"); } @@ -11271,40 +11273,6 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, // populated with device binaries for all target triples in the current // compilation flow. - // Create a comma separated list to pass along to the linker wrapper. - SmallString<256> LibList; - llvm::Triple TargetTriple; - auto ToolChainRange = C.getOffloadToolChains(); - for (auto &I : - llvm::make_range(ToolChainRange.first, ToolChainRange.second)) { - const ToolChain *TC = I.second; - // Note: For AMD targets, we do not pass any SYCL device libraries. - if (TC->getTriple().isSPIROrSPIRV() || TC->getTriple().isNVPTX()) { - TargetTriple = TC->getTriple(); - SmallVector SYCLDeviceLibs; - bool IsSPIR = TargetTriple.isSPIROrSPIRV(); - bool IsSpirvAOT = TargetTriple.isSPIRAOT(); - bool UseJitLink = - IsSPIR && - Args.hasFlag(options::OPT_fsycl_device_lib_jit_link, - options::OPT_fno_sycl_device_lib_jit_link, false); - bool UseAOTLink = IsSPIR && (IsSpirvAOT || !UseJitLink); - SYCLDeviceLibs = SYCL::getDeviceLibraries(C, TargetTriple, UseAOTLink); - for (const auto &AddLib : SYCLDeviceLibs) { - if (LibList.size() > 0) - LibList += ","; - LibList += AddLib; - } - } - } - // -sycl-device-libraries= provides a comma separate list of - // libraries to add to the device linking step. - if (LibList.size()) - CmdArgs.push_back( - Args.MakeArgString(Twine("-sycl-device-libraries=") + LibList)); - - // -sycl-device-library-location= provides the location in which the - // SYCL device libraries can be found. SmallString<128> DeviceLibDir(D.Dir); llvm::sys::path::append(DeviceLibDir, "..", "lib"); // Check the library location candidates for the the libsycl-crt library @@ -11327,6 +11295,66 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, break; } } + + // Create a comma separated list to pass along to the linker wrapper. + SmallString<256> LibList; + SmallString<256> BCLibList; + + // Lambda to append items to BCLibList with comma separation + auto appendToBCLibList = [&BCLibList](const llvm::Triple &Triple, + const Twine &Path) { + if (BCLibList.size() > 0) + BCLibList += ","; + BCLibList += (Twine(Triple.str()) + "=" + Path).str(); + }; + + llvm::Triple TargetTriple; + auto ToolChainRange = C.getOffloadToolChains(); + for (auto &I : + llvm::make_range(ToolChainRange.first, ToolChainRange.second)) { + const ToolChain *TC = I.second; + TargetTriple = TC->getTriple(); + SmallVector SYCLDeviceLibs; + bool IsSPIR = TargetTriple.isSPIROrSPIRV(); + bool IsSpirvAOT = TargetTriple.isSPIRAOT(); + bool UseJitLink = + IsSPIR && + Args.hasFlag(options::OPT_fsycl_device_lib_jit_link, + options::OPT_fno_sycl_device_lib_jit_link, false); + bool UseAOTLink = IsSPIR && (IsSpirvAOT || !UseJitLink); + SYCLDeviceLibs = SYCL::getDeviceLibraries(C, TargetTriple, UseAOTLink); + for (const auto &AddLib : SYCLDeviceLibs) { + if (llvm::sys::path::extension(AddLib) == ".bc") { + SmallString<256> LibPath(DeviceLibDir); + llvm::sys::path::append(LibPath, AddLib); + appendToBCLibList(TC->getTriple(), LibPath); + continue; + } + + if (LibList.size() > 0) + LibList += ","; + LibList += AddLib; + } + + if (TC->getTriple().isNVPTX()) { + if (const char *LibSpirvFile = SYCLInstallation.findLibspirvPath( + TC->getTriple(), Args, *TC->getAuxTriple())) { + appendToBCLibList(TC->getTriple(), LibSpirvFile); + } + } + } + // -sycl-device-libraries= provides a comma separate list of + // libraries to add to the device linking step. + if (LibList.size()) + CmdArgs.push_back( + Args.MakeArgString(Twine("-sycl-device-libraries=") + LibList)); + + if (BCLibList.size()) + CmdArgs.push_back( + Args.MakeArgString(Twine("-sycl-bc-device-libraries=") + BCLibList)); + + // -sycl-device-library-location= provides the location in which the + // SYCL device libraries can be found. CmdArgs.push_back(Args.MakeArgString( Twine("-sycl-device-library-location=") + DeviceLibDir)); diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 9648635dc0d38..6d3236970c86b 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1417,24 +1417,22 @@ static Expected linkDevice(ArrayRef InputFiles, << "Compatible SYCL device library binary not found\n"; } - // For NVPTX backend we need to also link libclc and CUDA libdevice. - if (Triple.isNVPTX()) { - if (Arg *A = Args.getLastArg(OPT_sycl_nvptx_device_lib_EQ)) { - if (A->getValues().size() == 0) - return createStringError( - inconvertibleErrorCode(), - "Number of device library files cannot be zero."); - for (StringRef Val : A->getValues()) { - SmallString<128> LibName(Val); - if (llvm::sys::fs::exists(LibName)) - ExtractedDeviceLibFiles.emplace_back(std::string(LibName)); - else - return createStringError( - inconvertibleErrorCode(), - std::string(LibName) + - " SYCL device library file for NVPTX is not found."); - } + for (StringRef Library : Args.getAllArgValues(OPT_sycl_bc_device_lib_EQ)) { + auto [LibraryTriple, LibraryPath] = Library.split('='); + if (llvm::Triple(LibraryTriple) != Triple) + continue; + // StringRef DeviceLibraryDir(""); + // if (Arg *DeviceLibDirArg = + // Args.getLastArg(OPT_sycl_device_library_location_EQ)) + // DeviceLibraryDir = DeviceLibDirArg->getValue(); + // SmallString<128> DeviceLibPath(DeviceLibraryDir); + // llvm::sys::path::append(DeviceLibPath, LibraryName); + if (!llvm::sys::fs::exists(LibraryPath)) { + return createStringError(inconvertibleErrorCode(), + "The specified device library " + LibraryPath + + " does not exist."); } + ExtractedDeviceLibFiles.emplace_back(LibraryPath.str()); } // Make sure that SYCL device library files are available. diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td index 1e7cd060278cb..7c3d8f7ce96fe 100644 --- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td +++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td @@ -156,9 +156,11 @@ def sycl_device_lib_EQ : CommaJoined<["--", "-"], "sycl-device-libraries=">, def sycl_device_library_location_EQ : Joined<["--", "-"], "sycl-device-library-location=">, Flags<[WrapperOnlyOption]>, HelpText<"Location of SYCL device library files">; -def sycl_nvptx_device_lib_EQ : CommaJoined<["--", "-"], "sycl-nvptx-device-libraries=">, - Flags<[WrapperOnlyOption]>, - HelpText<"A comma separated list of nvptx-specific device libraries that are linked during the device link.">; +def sycl_bc_device_lib_EQ + : CommaJoined<["--", "-"], "sycl-bc-device-libraries=">, + Flags<[WrapperOnlyOption]>, + HelpText<"A comma separated list of bitcode device libraries that are " + "linked during SYCL device link.">; // Options for SYCL backends and linker options for shared libraries. def sycl_backend_compile_options_EQ :