From 31c46246131ee81fed14b7f5ba1633fc7e42e112 Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Wed, 9 Jul 2025 15:45:42 -0700 Subject: [PATCH] [Driver][SYCL] Update sycl lib linking with -fms-runtime-lib The usage of `-fms-runtime-lib=val` will pull in the default libraries for MSVC linking as well as the dependent SYCL libraries when using the Linux based driver with the MSVC target triple. There are special interactions with the --dependent-lib=msvcrtd library we have that control the inclusion of sycl.lib to prevent linktime problems. Extend these behaviors to usage of `-fms-runtime-lib=dll_dbg`, preventing duplicate instances of the sycl.lib in the --dependent-lib usage as well as when performing the final link. --- clang/lib/Driver/ToolChains/Clang.cpp | 26 +++++++++------------- clang/lib/Driver/ToolChains/MSVC.cpp | 9 +++++--- clang/test/Driver/sycl-offload-old-model.c | 4 ++++ clang/test/Driver/sycl-offload.c | 12 ++++++++++ 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index f439c3a7aaf9e..7498c9987fa7b 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5428,19 +5428,13 @@ static void ProcessVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, // Add SYCL dependent library if (Args.hasArg(options::OPT_fsycl) && !Args.hasArg(options::OPT_nolibsycl)) { - if (RTOptionID == options::OPT__SLASH_MDd) { - if (Args.hasArg(options::OPT_fpreview_breaking_changes)) - CmdArgs.push_back("--dependent-lib=sycl" SYCL_MAJOR_VERSION - "-previewd"); - else - CmdArgs.push_back("--dependent-lib=sycl" SYCL_MAJOR_VERSION "d"); - } else { - if (Args.hasArg(options::OPT_fpreview_breaking_changes)) - CmdArgs.push_back("--dependent-lib=sycl" SYCL_MAJOR_VERSION - "-preview"); - else - CmdArgs.push_back("--dependent-lib=sycl" SYCL_MAJOR_VERSION); - } + SmallString<128> SYCLLibName("sycl" SYCL_MAJOR_VERSION); + if (Args.hasArg(options::OPT_fpreview_breaking_changes)) + SYCLLibName += "-preview"; + if (RTOptionID == options::OPT__SLASH_MDd) + SYCLLibName += "d"; + CmdArgs.push_back( + Args.MakeArgString(Twine("--dependent-lib=") + SYCLLibName)); CmdArgs.push_back("--dependent-lib=sycl-devicelib-host"); } } @@ -7045,11 +7039,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Add the sycld debug library when --dependent-lib=msvcrtd is used from // the command line. This is to allow for CMake based builds using the // Linux based driver on Windows to correctly pull in the expected debug - // library. + // library. Do not add when -fms-runtime-lib is used, as that pulls in the + // libraries separately. if (Args.hasArg(options::OPT_fsycl) && !Args.hasArg(options::OPT_nolibsycl) && !D.IsCLMode()) { if (TC.getTriple().isWindowsMSVCEnvironment()) { - if (isDependentLibAdded(Args, "msvcrtd")) { + if (isDependentLibAdded(Args, "msvcrtd") && + !Args.hasArg(options::OPT_fms_runtime_lib_EQ)) { if (Args.hasArg(options::OPT_fpreview_breaking_changes)) CmdArgs.push_back("--dependent-lib=sycl" SYCL_MAJOR_VERSION "-previewd"); diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index cf0510d8b5f24..e9a9c8b3246d1 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -99,9 +99,12 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.hasArg(options::OPT_fsycl_host_compiler_EQ)) { CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") + TC.getDriver().Dir + "/../lib")); - // When msvcrtd is added via --dependent-lib, we add the sycld - // equivalent. Do not add the -defaultlib as it conflicts. - if (!isDependentLibAdded(Args, "msvcrtd")) { + // When msvcrtd is added via --dependent-lib or -fms-runtime-lib=dll_dbg we + // add the sycld equivalent. Do not add the -defaultlib as it conflicts. + StringRef RuntimeVal; + if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) + RuntimeVal = A->getValue(); + if (!isDependentLibAdded(Args, "msvcrtd") && RuntimeVal != "dll_dbg") { if (Args.hasArg(options::OPT_fpreview_breaking_changes)) CmdArgs.push_back("-defaultlib:sycl" SYCL_MAJOR_VERSION "-preview.lib"); else diff --git a/clang/test/Driver/sycl-offload-old-model.c b/clang/test/Driver/sycl-offload-old-model.c index ec12e833447a7..a0f1017f1baaa 100644 --- a/clang/test/Driver/sycl-offload-old-model.c +++ b/clang/test/Driver/sycl-offload-old-model.c @@ -503,6 +503,10 @@ // RUN: %clangxx -fsycl --no-offload-new-driver -Xclang --dependent-lib=msvcrtd \ // RUN: -target x86_64-unknown-windows-msvc -### %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-LINK-SYCL-DEBUG %s +/// Check sycld is pulled in when -fms-runtime-lib=dll_dbg +// RUN: %clangxx -fsycl --no-offload-new-driver -fms-runtime-lib=dll_dbg \ +// RUN: -target x86_64-unknown-windows-msvc -### %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-LINK-SYCL-DEBUG %s // CHECK-LINK-SYCL-DEBUG: "--dependent-lib=sycl{{[0-9]*}}d" // CHECK-LINK-SYCL-DEBUG-NOT: "-defaultlib:sycl{{[0-9]*}}.lib" diff --git a/clang/test/Driver/sycl-offload.c b/clang/test/Driver/sycl-offload.c index 56d44faa1efa3..f29fa402716e1 100644 --- a/clang/test/Driver/sycl-offload.c +++ b/clang/test/Driver/sycl-offload.c @@ -292,9 +292,21 @@ // RUN: %clangxx -fsycl --offload-new-driver -Xclang --dependent-lib=msvcrtd \ // RUN: -target x86_64-unknown-windows-msvc -### %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-LINK-SYCL-DEBUG %s +/// Check sycld.lib is pulled in with -fms-runtime-lib=dll_dbg +// RUN: %clangxx -fsycl --offload-new-driver -fms-runtime-lib=dll_dbg \ +// RUN: -target x86_64-unknown-windows-msvc -### %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-LINK-SYCL-DEBUG %s // CHECK-LINK-SYCL-DEBUG: "--dependent-lib=sycl{{[0-9]*}}d" // CHECK-LINK-SYCL-DEBUG-NOT: "-defaultlib:sycl{{[0-9]*}}.lib" +/// Only a single instance of sycld should be pulled in when both the +/// -Xclang --dependent-lib=msvcrtd and -fms-runtime-lib=dll_dbg is used. +// RUN: %clangxx -fsycl --offload-new-driver -fms-runtime-lib=dll_dbg -Xclang \ +// RUN: --dependent-lib=msvcrtd --target=x86_64-unknown-windows-msvc -### %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-LINK-SYCLD %s +// CHECK-LINK-SYCLD: "--dependent-lib=sycl{{[0-9]*}}d" +// CHECK-LINK-SYCLD-NOT: "--dependent-lib=sycl{{[0-9]*}}d" + /// ########################################################################### /// Check -Xsycl-target-frontend does not trigger an error when no -fsycl-targets is specified