From ccd561d90c098fe3d897c23d84280f0df958c3dc Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Thu, 9 Oct 2025 10:45:38 -0700 Subject: [PATCH 1/8] [SYCL][clang-linker-wrapper] Add -sycl-bc-device-libraries option for linking bitcode device libraries --- clang/lib/Driver/ToolChains/Clang.cpp | 91 +++++++++++-------- .../test/Driver/sycl-bc-device-libraries.cpp | 63 +++++++++++++ .../ClangLinkerWrapper.cpp | 29 +++--- .../clang-linker-wrapper/LinkerWrapperOpts.td | 8 +- 4 files changed, 133 insertions(+), 58 deletions(-) create mode 100644 clang/test/Driver/sycl-bc-device-libraries.cpp diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 90cad2bdbe6a5..35c4f9b8b33d8 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -11266,43 +11266,6 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fsycl_link_EQ)) CmdArgs.push_back(Args.MakeArgString("--sycl-device-link")); - // -sycl-device-libraries= contains all of the SYCL - // device specific libraries that are needed. This generic list will be - // 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); @@ -11327,6 +11290,60 @@ 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; + + auto appendToList = [](SmallString<256> &List, const Twine &Arg) { + if (List.size() > 0) + List += ","; + List += Arg.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); + appendToList(BCLibList, + StringRef(TC->getTriple().str()) + "=" + LibPath); + continue; + } + + appendToList(LibList, AddLib); + } + + if (TC->getTriple().isNVPTX()) + if (const char *LibSpirvFile = SYCLInstallation.findLibspirvPath( + TC->getTriple(), Args, *TC->getAuxTriple())) + appendToList(BCLibList, + StringRef(TC->getTriple().str()) + "=" + 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)); + CmdArgs.push_back(Args.MakeArgString( Twine("-sycl-device-library-location=") + DeviceLibDir)); diff --git a/clang/test/Driver/sycl-bc-device-libraries.cpp b/clang/test/Driver/sycl-bc-device-libraries.cpp new file mode 100644 index 0000000000000..181749aa35e7d --- /dev/null +++ b/clang/test/Driver/sycl-bc-device-libraries.cpp @@ -0,0 +1,63 @@ +/// Test that SYCL bitcode device libraries are properly separated for NVIDIA and AMD targets + +/// Check devicelib and libspirv are linked for nvptx +// RUN: %clang -### -fsycl --offload-new-driver \ +// RUN: -fsycl-targets=nvptx64-nvidia-cuda \ +// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-NVPTX-BC %s + +// CHECK-NVPTX-BC: clang-linker-wrapper +// CHECK-NVPTX-BC-SAME: "-sycl-bc-device-libraries={{.*}}nvptx64-nvidia-cuda={{.*}}devicelib-nvptx64-nvidia-cuda.bc{{.*}}nvptx64-nvidia-cuda={{.*}}libspirv-nvptx64-nvidia-cuda.bc" + +/// Check devicelib is linked for amdgcn +// RUN: %clang -### -fsycl --offload-new-driver \ +// RUN: -fsycl-targets=amdgcn-amd-amdhsa \ +// RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 \ +// RUN: --rocm-path=%S/Inputs/rocm \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-AMD-BC %s + +// CHECK-AMD-BC: clang-linker-wrapper +// CHECK-AMD-BC-SAME: "-sycl-bc-device-libraries=amdgcn-amd-amdhsa={{.*}}devicelib-amdgcn-amd-amdhsa.bc" + +/// Check linking with multiple targets +// RUN: %clang -### -fsycl --offload-new-driver \ +// RUN: -fsycl-targets=amdgcn-amd-amdhsa,nvptx64-nvidia-cuda \ +// RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 \ +// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ +// RUN: --rocm-path=%S/Inputs/rocm \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-MULTI-TARGET %s + +// CHECK-MULTI-TARGET: clang-linker-wrapper +// CHECK-MULTI-TARGET-SAME: "-sycl-bc-device-libraries={{.*}}amdgcn-amd-amdhsa={{.*}}devicelib-amdgcn-amd-amdhsa.bc{{.*}}nvptx64-nvidia-cuda={{.*}}devicelib-nvptx64-nvidia-cuda.bc{{.*}}nvptx64-nvidia-cuda={{.*}}libspirv-nvptx64-nvidia-cuda.bc" + +/// Test -sycl-bc-device-libraries with nvptx dummy libraries +// RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.nvptx.devicelib.bc +// RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.nvptx.libspirv.bc +// RUN: %clang++ -fsycl -fsycl-targets=nvptx64-nvidia-cuda --offload-new-driver -c %s -o %t.nvptx.o -nocudalib +// RUN: clang-linker-wrapper -sycl-bc-device-libraries=nvptx64-nvidia-cuda=%t.nvptx.devicelib.bc,nvptx64-nvidia-cuda=%t.nvptx.libspirv.bc \ +// RUN: --host-triple=x86_64-unknown-linux-gnu --dry-run \ +// RUN: --linker-path=/usr/bin/ld %t.nvptx.o -o a.out 2>&1 | FileCheck -check-prefix=CHECK-WRAPPER-NVPTX %s + +// CHECK-WRAPPER-NVPTX: llvm-link{{.*}} {{.*}}.nvptx.devicelib.bc {{.*}}.nvptx.libspirv.bc + +/// Test -sycl-bc-device-libraries with amdgcn dummy library +// RUN: %clang -cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm-bc -o %t.amd.devicelib.bc +// RUN: %clang++ -fsycl -fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 --offload-new-driver -c %s -o %t.amd.o -nogpulib +// RUN: clang-linker-wrapper -sycl-bc-device-libraries=amdgcn-amd-amdhsa=%t.amd.devicelib.bc \ +// RUN: --host-triple=x86_64-unknown-linux-gnu --dry-run \ +// RUN: --linker-path=/usr/bin/ld %t.amd.o -o a.out 2>&1 | FileCheck -check-prefix=CHECK-WRAPPER-AMD %s + +// CHECK-WRAPPER-AMD: llvm-link{{.*}} {{.*}}.amd.devicelib.bc + +/// Test clang-linker-wrapper directly with multi-target bc libraries +// RUN: %clang++ -fsycl -fsycl-targets=amdgcn-amd-amdhsa,nvptx64-nvidia-cuda \ +// RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 \ +// RUN: --offload-new-driver -c %s -o %t.multi.o -nocudalib -nogpulib +// RUN: clang-linker-wrapper -sycl-bc-device-libraries=amdgcn-amd-amdhsa=%t.amd.devicelib.bc,nvptx64-nvidia-cuda=%t.nvptx.devicelib.bc,nvptx64-nvidia-cuda=%t.nvptx.libspirv.bc \ +// RUN: --host-triple=x86_64-unknown-linux-gnu --dry-run \ +// RUN: --linker-path=/usr/bin/ld %t.multi.o -o a.out 2>&1 | FileCheck -check-prefix=CHECK-WRAPPER-MULTI %s + +// CHECK-WRAPPER-MULTI: llvm-link{{.*}} {{.*}}.amd.devicelib.bc +// CHECK-WRAPPER-MULTI: llvm-link{{.*}} {{.*}}.nvptx.devicelib.bc {{.*}}.nvptx.libspirv.bc + +int main() { return 0; } diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 7efcecc358e7e..0f73aeba69786 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1417,24 +1417,17 @@ 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; + + 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 : From e14ec16bf4be56a8ba7af662e8ef58a8e6342a3d Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Thu, 30 Oct 2025 10:45:25 -0700 Subject: [PATCH 2/8] use --bitcode-library --- clang/lib/Driver/ToolChains/Clang.cpp | 15 +++++++------- .../test/Driver/sycl-bc-device-libraries.cpp | 20 +++++++++---------- .../ClangLinkerWrapper.cpp | 9 +-------- sycl/test-e2e/DeviceLib/rand_test.cpp | 2 ++ 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 35c4f9b8b33d8..dd18fbdce25ce 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -11293,7 +11293,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, // Create a comma separated list to pass along to the linker wrapper. SmallString<256> LibList; - SmallString<256> BCLibList; + SmallVector BCLibList; auto appendToList = [](SmallString<256> &List, const Twine &Arg) { if (List.size() > 0) @@ -11320,8 +11320,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, if (llvm::sys::path::extension(AddLib) == ".bc") { SmallString<256> LibPath(DeviceLibDir); llvm::sys::path::append(LibPath, AddLib); - appendToList(BCLibList, - StringRef(TC->getTriple().str()) + "=" + LibPath); + BCLibList.push_back((Twine(TC->getTriple().str()) + "=" + LibPath).str()); continue; } @@ -11331,8 +11330,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, if (TC->getTriple().isNVPTX()) if (const char *LibSpirvFile = SYCLInstallation.findLibspirvPath( TC->getTriple(), Args, *TC->getAuxTriple())) - appendToList(BCLibList, - StringRef(TC->getTriple().str()) + "=" + LibSpirvFile); + BCLibList.push_back((Twine(TC->getTriple().str()) + "=" + LibSpirvFile).str()); } // -sycl-device-libraries= provides a comma separate list of // libraries to add to the device linking step. @@ -11340,9 +11338,10 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back( Args.MakeArgString(Twine("-sycl-device-libraries=") + LibList)); - if (BCLibList.size()) - CmdArgs.push_back( - Args.MakeArgString(Twine("-sycl-bc-device-libraries=") + BCLibList)); + if (BCLibList.size()) { + for (const std::string &Lib : BCLibList) + CmdArgs.push_back(Args.MakeArgString(Twine("--bitcode-library=") + Lib)); + } CmdArgs.push_back(Args.MakeArgString( Twine("-sycl-device-library-location=") + DeviceLibDir)); diff --git a/clang/test/Driver/sycl-bc-device-libraries.cpp b/clang/test/Driver/sycl-bc-device-libraries.cpp index 181749aa35e7d..3a65adc5a117b 100644 --- a/clang/test/Driver/sycl-bc-device-libraries.cpp +++ b/clang/test/Driver/sycl-bc-device-libraries.cpp @@ -7,7 +7,7 @@ // RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-NVPTX-BC %s // CHECK-NVPTX-BC: clang-linker-wrapper -// CHECK-NVPTX-BC-SAME: "-sycl-bc-device-libraries={{.*}}nvptx64-nvidia-cuda={{.*}}devicelib-nvptx64-nvidia-cuda.bc{{.*}}nvptx64-nvidia-cuda={{.*}}libspirv-nvptx64-nvidia-cuda.bc" +// CHECK-NVPTX-BC-SAME: "--bitcode-library=nvptx64-nvidia-cuda={{.*}}devicelib-nvptx64-nvidia-cuda.bc" "--bitcode-library=nvptx64-nvidia-cuda={{.*}}libspirv-nvptx64-nvidia-cuda.bc" /// Check devicelib is linked for amdgcn // RUN: %clang -### -fsycl --offload-new-driver \ @@ -17,7 +17,7 @@ // RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-AMD-BC %s // CHECK-AMD-BC: clang-linker-wrapper -// CHECK-AMD-BC-SAME: "-sycl-bc-device-libraries=amdgcn-amd-amdhsa={{.*}}devicelib-amdgcn-amd-amdhsa.bc" +// CHECK-AMD-BC-SAME: "--bitcode-library=amdgcn-amd-amdhsa={{.*}}devicelib-amdgcn-amd-amdhsa.bc" /// Check linking with multiple targets // RUN: %clang -### -fsycl --offload-new-driver \ @@ -28,36 +28,34 @@ // RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-MULTI-TARGET %s // CHECK-MULTI-TARGET: clang-linker-wrapper -// CHECK-MULTI-TARGET-SAME: "-sycl-bc-device-libraries={{.*}}amdgcn-amd-amdhsa={{.*}}devicelib-amdgcn-amd-amdhsa.bc{{.*}}nvptx64-nvidia-cuda={{.*}}devicelib-nvptx64-nvidia-cuda.bc{{.*}}nvptx64-nvidia-cuda={{.*}}libspirv-nvptx64-nvidia-cuda.bc" +// CHECK-MULTI-TARGET-SAME: "--bitcode-library=amdgcn-amd-amdhsa={{.*}}devicelib-amdgcn-amd-amdhsa.bc" "--bitcode-library=nvptx64-nvidia-cuda={{.*}}devicelib-nvptx64-nvidia-cuda.bc" "--bitcode-library=nvptx64-nvidia-cuda={{.*}}libspirv-nvptx64-nvidia-cuda.bc" -/// Test -sycl-bc-device-libraries with nvptx dummy libraries +/// Test --bitcode-library with nvptx dummy libraries // RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.nvptx.devicelib.bc // RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.nvptx.libspirv.bc // RUN: %clang++ -fsycl -fsycl-targets=nvptx64-nvidia-cuda --offload-new-driver -c %s -o %t.nvptx.o -nocudalib -// RUN: clang-linker-wrapper -sycl-bc-device-libraries=nvptx64-nvidia-cuda=%t.nvptx.devicelib.bc,nvptx64-nvidia-cuda=%t.nvptx.libspirv.bc \ +// RUN: clang-linker-wrapper --bitcode-library=nvptx64-nvidia-cuda=%t.nvptx.devicelib.bc --bitcode-library=nvptx64-nvidia-cuda=%t.nvptx.libspirv.bc \ // RUN: --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.nvptx.o -o a.out 2>&1 | FileCheck -check-prefix=CHECK-WRAPPER-NVPTX %s // CHECK-WRAPPER-NVPTX: llvm-link{{.*}} {{.*}}.nvptx.devicelib.bc {{.*}}.nvptx.libspirv.bc -/// Test -sycl-bc-device-libraries with amdgcn dummy library +/// Test --bitcode-library with amdgcn dummy library // RUN: %clang -cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm-bc -o %t.amd.devicelib.bc // RUN: %clang++ -fsycl -fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 --offload-new-driver -c %s -o %t.amd.o -nogpulib -// RUN: clang-linker-wrapper -sycl-bc-device-libraries=amdgcn-amd-amdhsa=%t.amd.devicelib.bc \ +// RUN: clang-linker-wrapper --bitcode-library=amdgcn-amd-amdhsa=%t.amd.devicelib.bc \ // RUN: --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.amd.o -o a.out 2>&1 | FileCheck -check-prefix=CHECK-WRAPPER-AMD %s // CHECK-WRAPPER-AMD: llvm-link{{.*}} {{.*}}.amd.devicelib.bc -/// Test clang-linker-wrapper directly with multi-target bc libraries +/// Test --bitcode-library with multi-target bc libraries // RUN: %clang++ -fsycl -fsycl-targets=amdgcn-amd-amdhsa,nvptx64-nvidia-cuda \ // RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 \ // RUN: --offload-new-driver -c %s -o %t.multi.o -nocudalib -nogpulib -// RUN: clang-linker-wrapper -sycl-bc-device-libraries=amdgcn-amd-amdhsa=%t.amd.devicelib.bc,nvptx64-nvidia-cuda=%t.nvptx.devicelib.bc,nvptx64-nvidia-cuda=%t.nvptx.libspirv.bc \ +// RUN: clang-linker-wrapper --bitcode-library=amdgcn-amd-amdhsa=%t.amd.devicelib.bc --bitcode-library=nvptx64-nvidia-cuda=%t.nvptx.devicelib.bc --bitcode-library=nvptx64-nvidia-cuda=%t.nvptx.libspirv.bc \ // RUN: --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.multi.o -o a.out 2>&1 | FileCheck -check-prefix=CHECK-WRAPPER-MULTI %s // CHECK-WRAPPER-MULTI: llvm-link{{.*}} {{.*}}.amd.devicelib.bc // CHECK-WRAPPER-MULTI: llvm-link{{.*}} {{.*}}.nvptx.devicelib.bc {{.*}}.nvptx.libspirv.bc - -int main() { return 0; } diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 7cdb781b2ed92..3dad20a226a57 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1432,7 +1432,7 @@ static Expected linkDevice(ArrayRef InputFiles, << "Compatible SYCL device library binary not found\n"; } - for (StringRef Library : Args.getAllArgValues(OPT_sycl_bc_device_lib_EQ)) { + for (StringRef Library : Args.getAllArgValues(OPT_bitcode_library_EQ)) { auto [LibraryTriple, LibraryPath] = Library.split('='); if (llvm::Triple(LibraryTriple) != Triple) continue; @@ -2508,13 +2508,6 @@ getDeviceInput(const ArgList &Args) { } } - for (StringRef Library : Args.getAllArgValues(OPT_bitcode_library_EQ)) { - auto FileOrErr = getInputBitcodeLibrary(Library); - if (!FileOrErr) - return FileOrErr.takeError(); - InputFiles[*FileOrErr].push_back(std::move(*FileOrErr)); - } - SmallVector> InputsForTarget; for (auto &[ID, Input] : InputFiles) InputsForTarget.emplace_back(std::move(Input)); diff --git a/sycl/test-e2e/DeviceLib/rand_test.cpp b/sycl/test-e2e/DeviceLib/rand_test.cpp index 082e62914340c..347b492abefa4 100644 --- a/sycl/test-e2e/DeviceLib/rand_test.cpp +++ b/sycl/test-e2e/DeviceLib/rand_test.cpp @@ -1,5 +1,7 @@ // RUN: %{build} -o %t.out // RUN: %{run} %t.out +// RUN: %{build} -o %t.out --offload-new-driver +// RUN: %{run} %t.out // XFAIL: target-native_cpu // XFAIL-TRACKER: https://github.com/intel/llvm/issues/20142 From b565678dbf1dd2d8b37cae0deb4d8e241d4cc647 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Tue, 4 Nov 2025 15:35:53 +0000 Subject: [PATCH 3/8] address review comments --- clang/lib/Driver/ToolChains/Clang.cpp | 16 +++++++++------- clang/test/Driver/sycl-bc-device-libraries.cpp | 12 ++++++------ sycl/test-e2e/DeviceLib/rand_test.cpp | 2 -- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index dd18fbdce25ce..f61aec9ce2aa3 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -11301,13 +11301,11 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, List += Arg.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; + llvm::Triple TargetTriple = TC->getTriple(); bool IsSPIR = TargetTriple.isSPIROrSPIRV(); bool IsSpirvAOT = TargetTriple.isSPIRAOT(); bool UseJitLink = @@ -11315,12 +11313,14 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, 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); + SmallVector 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); - BCLibList.push_back((Twine(TC->getTriple().str()) + "=" + LibPath).str()); + BCLibList.push_back( + (Twine(TC->getTriple().str()) + "=" + LibPath).str()); continue; } @@ -11330,7 +11330,8 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, if (TC->getTriple().isNVPTX()) if (const char *LibSpirvFile = SYCLInstallation.findLibspirvPath( TC->getTriple(), Args, *TC->getAuxTriple())) - BCLibList.push_back((Twine(TC->getTriple().str()) + "=" + LibSpirvFile).str()); + BCLibList.push_back( + (Twine(TC->getTriple().str()) + "=" + LibSpirvFile).str()); } // -sycl-device-libraries= provides a comma separate list of // libraries to add to the device linking step. @@ -11340,7 +11341,8 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, if (BCLibList.size()) { for (const std::string &Lib : BCLibList) - CmdArgs.push_back(Args.MakeArgString(Twine("--bitcode-library=") + Lib)); + CmdArgs.push_back( + Args.MakeArgString(Twine("--bitcode-library=") + Lib)); } CmdArgs.push_back(Args.MakeArgString( diff --git a/clang/test/Driver/sycl-bc-device-libraries.cpp b/clang/test/Driver/sycl-bc-device-libraries.cpp index 3a65adc5a117b..92c8f0fda8795 100644 --- a/clang/test/Driver/sycl-bc-device-libraries.cpp +++ b/clang/test/Driver/sycl-bc-device-libraries.cpp @@ -1,4 +1,4 @@ -/// Test that SYCL bitcode device libraries are properly separated for NVIDIA and AMD targets +/// Test that SYCL bitcode device libraries are properly separated for NVIDIA and AMD targets. /// Check devicelib and libspirv are linked for nvptx // RUN: %clang -### -fsycl --offload-new-driver \ @@ -9,7 +9,7 @@ // CHECK-NVPTX-BC: clang-linker-wrapper // CHECK-NVPTX-BC-SAME: "--bitcode-library=nvptx64-nvidia-cuda={{.*}}devicelib-nvptx64-nvidia-cuda.bc" "--bitcode-library=nvptx64-nvidia-cuda={{.*}}libspirv-nvptx64-nvidia-cuda.bc" -/// Check devicelib is linked for amdgcn +/// Check devicelib is linked for amdgcn. // RUN: %clang -### -fsycl --offload-new-driver \ // RUN: -fsycl-targets=amdgcn-amd-amdhsa \ // RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 \ @@ -19,7 +19,7 @@ // CHECK-AMD-BC: clang-linker-wrapper // CHECK-AMD-BC-SAME: "--bitcode-library=amdgcn-amd-amdhsa={{.*}}devicelib-amdgcn-amd-amdhsa.bc" -/// Check linking with multiple targets +/// Check linking with multiple targets. // RUN: %clang -### -fsycl --offload-new-driver \ // RUN: -fsycl-targets=amdgcn-amd-amdhsa,nvptx64-nvidia-cuda \ // RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 \ @@ -30,7 +30,7 @@ // CHECK-MULTI-TARGET: clang-linker-wrapper // CHECK-MULTI-TARGET-SAME: "--bitcode-library=amdgcn-amd-amdhsa={{.*}}devicelib-amdgcn-amd-amdhsa.bc" "--bitcode-library=nvptx64-nvidia-cuda={{.*}}devicelib-nvptx64-nvidia-cuda.bc" "--bitcode-library=nvptx64-nvidia-cuda={{.*}}libspirv-nvptx64-nvidia-cuda.bc" -/// Test --bitcode-library with nvptx dummy libraries +/// Test --bitcode-library with nvptx dummy libraries. // RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.nvptx.devicelib.bc // RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.nvptx.libspirv.bc // RUN: %clang++ -fsycl -fsycl-targets=nvptx64-nvidia-cuda --offload-new-driver -c %s -o %t.nvptx.o -nocudalib @@ -40,7 +40,7 @@ // CHECK-WRAPPER-NVPTX: llvm-link{{.*}} {{.*}}.nvptx.devicelib.bc {{.*}}.nvptx.libspirv.bc -/// Test --bitcode-library with amdgcn dummy library +/// Test --bitcode-library with amdgcn dummy library. // RUN: %clang -cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm-bc -o %t.amd.devicelib.bc // RUN: %clang++ -fsycl -fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 --offload-new-driver -c %s -o %t.amd.o -nogpulib // RUN: clang-linker-wrapper --bitcode-library=amdgcn-amd-amdhsa=%t.amd.devicelib.bc \ @@ -49,7 +49,7 @@ // CHECK-WRAPPER-AMD: llvm-link{{.*}} {{.*}}.amd.devicelib.bc -/// Test --bitcode-library with multi-target bc libraries +/// Test --bitcode-library with multi-target bc libraries. // RUN: %clang++ -fsycl -fsycl-targets=amdgcn-amd-amdhsa,nvptx64-nvidia-cuda \ // RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 \ // RUN: --offload-new-driver -c %s -o %t.multi.o -nocudalib -nogpulib diff --git a/sycl/test-e2e/DeviceLib/rand_test.cpp b/sycl/test-e2e/DeviceLib/rand_test.cpp index 347b492abefa4..082e62914340c 100644 --- a/sycl/test-e2e/DeviceLib/rand_test.cpp +++ b/sycl/test-e2e/DeviceLib/rand_test.cpp @@ -1,7 +1,5 @@ // RUN: %{build} -o %t.out // RUN: %{run} %t.out -// RUN: %{build} -o %t.out --offload-new-driver -// RUN: %{run} %t.out // XFAIL: target-native_cpu // XFAIL-TRACKER: https://github.com/intel/llvm/issues/20142 From fe223ca78a355fd3576937456174eaed233a1eff Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Tue, 4 Nov 2025 15:50:48 +0000 Subject: [PATCH 4/8] removed now unused option --- clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td | 5 ----- 1 file changed, 5 deletions(-) diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td index 7c3d8f7ce96fe..79f7b1d7bbbc6 100644 --- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td +++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td @@ -156,11 +156,6 @@ 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_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 : From b5dcfbbda63fc92907b93a4b9dd09d54194089d8 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Tue, 4 Nov 2025 17:59:59 +0000 Subject: [PATCH 5/8] clang++ -> clangxx --- clang/test/Driver/sycl-bc-device-libraries.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/test/Driver/sycl-bc-device-libraries.cpp b/clang/test/Driver/sycl-bc-device-libraries.cpp index 92c8f0fda8795..4e238af44abbc 100644 --- a/clang/test/Driver/sycl-bc-device-libraries.cpp +++ b/clang/test/Driver/sycl-bc-device-libraries.cpp @@ -33,7 +33,7 @@ /// Test --bitcode-library with nvptx dummy libraries. // RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.nvptx.devicelib.bc // RUN: %clang -cc1 %s -triple nvptx64-nvidia-cuda -emit-llvm-bc -o %t.nvptx.libspirv.bc -// RUN: %clang++ -fsycl -fsycl-targets=nvptx64-nvidia-cuda --offload-new-driver -c %s -o %t.nvptx.o -nocudalib +// RUN: %clangxx -fsycl -fsycl-targets=nvptx64-nvidia-cuda --offload-new-driver -c %s -o %t.nvptx.o -nocudalib // RUN: clang-linker-wrapper --bitcode-library=nvptx64-nvidia-cuda=%t.nvptx.devicelib.bc --bitcode-library=nvptx64-nvidia-cuda=%t.nvptx.libspirv.bc \ // RUN: --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.nvptx.o -o a.out 2>&1 | FileCheck -check-prefix=CHECK-WRAPPER-NVPTX %s @@ -42,7 +42,7 @@ /// Test --bitcode-library with amdgcn dummy library. // RUN: %clang -cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm-bc -o %t.amd.devicelib.bc -// RUN: %clang++ -fsycl -fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 --offload-new-driver -c %s -o %t.amd.o -nogpulib +// RUN: %clangxx -fsycl -fsycl-targets=amdgcn-amd-amdhsa -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 --offload-new-driver -c %s -o %t.amd.o -nogpulib // RUN: clang-linker-wrapper --bitcode-library=amdgcn-amd-amdhsa=%t.amd.devicelib.bc \ // RUN: --host-triple=x86_64-unknown-linux-gnu --dry-run \ // RUN: --linker-path=/usr/bin/ld %t.amd.o -o a.out 2>&1 | FileCheck -check-prefix=CHECK-WRAPPER-AMD %s @@ -50,7 +50,7 @@ // CHECK-WRAPPER-AMD: llvm-link{{.*}} {{.*}}.amd.devicelib.bc /// Test --bitcode-library with multi-target bc libraries. -// RUN: %clang++ -fsycl -fsycl-targets=amdgcn-amd-amdhsa,nvptx64-nvidia-cuda \ +// RUN: %clangxx -fsycl -fsycl-targets=amdgcn-amd-amdhsa,nvptx64-nvidia-cuda \ // RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 \ // RUN: --offload-new-driver -c %s -o %t.multi.o -nocudalib -nogpulib // RUN: clang-linker-wrapper --bitcode-library=amdgcn-amd-amdhsa=%t.amd.devicelib.bc --bitcode-library=nvptx64-nvidia-cuda=%t.nvptx.devicelib.bc --bitcode-library=nvptx64-nvidia-cuda=%t.nvptx.libspirv.bc \ From 2e79f561c4a8f3e1a6cca3615c482a8c270ee834 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Wed, 5 Nov 2025 16:10:03 -0800 Subject: [PATCH 6/8] Address review comments --- clang/lib/Driver/ToolChains/Clang.cpp | 24 ++++++++++++------- .../test/Driver/sycl-bc-device-libraries.cpp | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 64148d4d62959..e3d42f2d3a282 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -11247,7 +11247,16 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, } } - // Create a comma separated list to pass along to the linker wrapper. + // -sycl-device-libraries= contains a list of + // file names for fat object files that contain SYCL device library bitcode necessary for + // SYCL offloading that will be linked to the user's device code. + // clang-linker-wrapper uses the value provided to -sycl-device-library-location= + // to construct the full paths of the device libraries. + + // On the other hand, --bitcode-library== specifies + // one bitcode library to link in for a specific triple. Additionally, the + // path is *not* relative to the -sycl-device-library-location - the full + // path must be provided. SmallString<256> LibList; SmallVector BCLibList; @@ -11258,17 +11267,16 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, }; auto ToolChainRange = C.getOffloadToolChains(); - for (auto &I : + for (const auto &[Kind, TC] : llvm::make_range(ToolChainRange.first, ToolChainRange.second)) { - const ToolChain *TC = I.second; llvm::Triple TargetTriple = TC->getTriple(); bool IsSPIR = TargetTriple.isSPIROrSPIRV(); - bool IsSpirvAOT = TargetTriple.isSPIRAOT(); + bool IsSpirAOT = 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); + bool UseAOTLink = IsSPIR && (IsSpirAOT || !UseJitLink); SmallVector SYCLDeviceLibs = SYCL::getDeviceLibraries(C, TargetTriple, UseAOTLink); for (const auto &AddLib : SYCLDeviceLibs) { @@ -11289,17 +11297,15 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, BCLibList.push_back( (Twine(TC->getTriple().str()) + "=" + LibSpirvFile).str()); } - // -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()) { + if (BCLibList.size()) for (const std::string &Lib : BCLibList) CmdArgs.push_back( Args.MakeArgString(Twine("--bitcode-library=") + Lib)); - } CmdArgs.push_back(Args.MakeArgString( Twine("-sycl-device-library-location=") + DeviceLibDir)); diff --git a/clang/test/Driver/sycl-bc-device-libraries.cpp b/clang/test/Driver/sycl-bc-device-libraries.cpp index 4e238af44abbc..1208a0ddba442 100644 --- a/clang/test/Driver/sycl-bc-device-libraries.cpp +++ b/clang/test/Driver/sycl-bc-device-libraries.cpp @@ -1,6 +1,6 @@ /// Test that SYCL bitcode device libraries are properly separated for NVIDIA and AMD targets. -/// Check devicelib and libspirv are linked for nvptx +/// Check devicelib and libspirv are linked for nvptx. // RUN: %clang -### -fsycl --offload-new-driver \ // RUN: -fsycl-targets=nvptx64-nvidia-cuda \ // RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ From 2bd11b1c7bc08a1db3e67532ce34a44bb5516b57 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Thu, 6 Nov 2025 00:18:00 +0000 Subject: [PATCH 7/8] clang-format --- clang/lib/Driver/ToolChains/Clang.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index e3d42f2d3a282..9292f9df9a6ee 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -11248,10 +11248,11 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, } // -sycl-device-libraries= contains a list of - // file names for fat object files that contain SYCL device library bitcode necessary for - // SYCL offloading that will be linked to the user's device code. - // clang-linker-wrapper uses the value provided to -sycl-device-library-location= - // to construct the full paths of the device libraries. + // file names for fat object files that contain SYCL device library bitcode + // necessary for SYCL offloading that will be linked to the user's device + // code. clang-linker-wrapper uses the value provided to + // -sycl-device-library-location= to construct the full paths of the + // device libraries. // On the other hand, --bitcode-library== specifies // one bitcode library to link in for a specific triple. Additionally, the From 9476a7fc09d59c8cf7cd8155230696377362e3f1 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Thu, 6 Nov 2025 07:50:19 -0800 Subject: [PATCH 8/8] Add clang_cl tests --- clang/test/Driver/sycl-bc-device-libraries.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/clang/test/Driver/sycl-bc-device-libraries.cpp b/clang/test/Driver/sycl-bc-device-libraries.cpp index 1208a0ddba442..34c926dff69da 100644 --- a/clang/test/Driver/sycl-bc-device-libraries.cpp +++ b/clang/test/Driver/sycl-bc-device-libraries.cpp @@ -6,6 +6,11 @@ // RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ // RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-NVPTX-BC %s +// RUN: %clang_cl -### -fsycl --offload-new-driver \ +// RUN: -fsycl-targets=nvptx64-nvidia-cuda \ +// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-NVPTX-BC %s + // CHECK-NVPTX-BC: clang-linker-wrapper // CHECK-NVPTX-BC-SAME: "--bitcode-library=nvptx64-nvidia-cuda={{.*}}devicelib-nvptx64-nvidia-cuda.bc" "--bitcode-library=nvptx64-nvidia-cuda={{.*}}libspirv-nvptx64-nvidia-cuda.bc" @@ -16,6 +21,12 @@ // RUN: --rocm-path=%S/Inputs/rocm \ // RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-AMD-BC %s +// RUN: %clang_cl -### -fsycl --offload-new-driver \ +// RUN: -fsycl-targets=amdgcn-amd-amdhsa \ +// RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 \ +// RUN: --rocm-path=%S/Inputs/rocm \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-AMD-BC %s + // CHECK-AMD-BC: clang-linker-wrapper // CHECK-AMD-BC-SAME: "--bitcode-library=amdgcn-amd-amdhsa={{.*}}devicelib-amdgcn-amd-amdhsa.bc" @@ -27,6 +38,13 @@ // RUN: --rocm-path=%S/Inputs/rocm \ // RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-MULTI-TARGET %s +// RUN: %clang_cl -### -fsycl --offload-new-driver \ +// RUN: -fsycl-targets=amdgcn-amd-amdhsa,nvptx64-nvidia-cuda \ +// RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx900 \ +// RUN: --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda \ +// RUN: --rocm-path=%S/Inputs/rocm \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-MULTI-TARGET %s + // CHECK-MULTI-TARGET: clang-linker-wrapper // CHECK-MULTI-TARGET-SAME: "--bitcode-library=amdgcn-amd-amdhsa={{.*}}devicelib-amdgcn-amd-amdhsa.bc" "--bitcode-library=nvptx64-nvidia-cuda={{.*}}devicelib-nvptx64-nvidia-cuda.bc" "--bitcode-library=nvptx64-nvidia-cuda={{.*}}libspirv-nvptx64-nvidia-cuda.bc"