https://github.com/srividya-sundaram updated 
https://github.com/llvm/llvm-project/pull/194744

>From c83935594b5bcdd2a7744fcd0d4527b7e8734e4f Mon Sep 17 00:00:00 2001
From: srividya sundaram <[email protected]>
Date: Tue, 28 Apr 2026 15:01:38 -0700
Subject: [PATCH 1/8] [Driver][SYCL][Windows] Add runtime library linking with
 CRT validation, phase1

---
 .../clang/Basic/DiagnosticDriverKinds.td      |   5 +
 clang/include/clang/Options/Options.td        |   2 +
 clang/lib/Driver/ToolChains/MSVC.cpp          | 108 +++++++++++++++++-
 3 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td 
b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 469045948a47c..690228317e2be 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -93,6 +93,11 @@ def err_drv_hipspv_no_hip_path : Error<
   "'--hip-path' must be specified when offloading to SPIR-V unless '-nogpuinc' 
"
   "is given">;
 
+// SYCL Windows-specific diagnostics
+def err_drv_sycl_requires_dynamic_crt : Error<
+  "SYCL requires dynamic C++ runtime (/MD or /MDd); "
+  "static C++ runtime (/MT or /MTd) is not supported">;
+
 def err_drv_no_spv_tools : Error<"cannot find SPIR-V Tools binary '%0', which "
                                  "is required for SPIR-V compilation. "
                                  "It can be obtained from your system package "
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index c16c41ad4057d..9bc8c981cb014 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -7566,6 +7566,8 @@ def fsycl : Flag<["-"], "fsycl">,
   HelpText<"Enable SYCL C++ extensions">;
 def fno_sycl : Flag<["-"], "fno-sycl">,
   HelpText<"Disable SYCL C++ extensions">;
+def nolibsycl : Flag<["-"], "nolibsycl">,
+  HelpText<"Do not link the SYCL runtime library">;
 def fsycl_device_only : Flag<["-"], "fsycl-device-only">,
   Alias<offload_device_only>, HelpText<"Compile SYCL code for device only">;
 def fsycl_host_only : Flag<["-"], "fsycl-host-only">,
diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp 
b/clang/lib/Driver/ToolChains/MSVC.cpp
index f57440855fce4..2e052f6e282b1 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -85,9 +85,109 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
       CmdArgs.push_back(Args.MakeArgString("--dependent-lib=amath"));
   }
 
+  // ==========================================================================
+  // SYCL: Auto-add /MD if no C++ runtime specified
+  // SYCL requires dynamic C++ runtime because STL objects cross DLL boundaries
+  // This must happen BEFORE other CRT handling logic
+  // ==========================================================================
+  if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
+      !Args.hasArg(options::OPT_nolibsycl) &&
+      !Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+
+    bool HasExplicitCRT = false;
+
+    // Check if user already specified a CRT flag
+    if (Args.hasArg(options::OPT__SLASH_MT) ||
+        Args.hasArg(options::OPT__SLASH_MTd) ||
+        Args.hasArg(options::OPT__SLASH_MD) ||
+        Args.hasArg(options::OPT__SLASH_MDd) ||
+        Args.hasArg(options::OPT_fms_runtime_lib_EQ))
+      HasExplicitCRT = true;
+
+    // Auto-add /MD if no CRT specified (makes dynamic CRT the default for 
SYCL)
+    if (!HasExplicitCRT) {
+      CmdArgs.push_back("/MD");
+    }
+  }
+
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
       !C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) {
-    CmdArgs.push_back("-defaultlib:libcmt");
+
+    // ========================================================================
+    // SYCL: Validate CRT compatibility and add SYCL runtime libraries
+    // ========================================================================
+    if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
+        !Args.hasArg(options::OPT_nolibsycl)) {
+
+      // ----------------------------------------------------------------------
+      // STEP 1: Validate that static CRT is not being used
+      // ----------------------------------------------------------------------
+      bool HasStaticCRT = false;
+
+      // Check for explicit /MT or /MTd flags
+      if (Args.hasArg(options::OPT__SLASH_MT) ||
+          Args.hasArg(options::OPT__SLASH_MTd)) {
+        HasStaticCRT = true;
+      }
+
+      // Check -fms-runtime-lib flag
+      if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
+        StringRef RuntimeLib = A->getValue();
+        if (RuntimeLib == "static" || RuntimeLib == "static_dbg") {
+          HasStaticCRT = true;
+        }
+      }
+
+      // Reject static CRT with SYCL
+      if (HasStaticCRT) {
+        TC.getDriver().Diag(diag::err_drv_sycl_requires_dynamic_crt);
+        // Continue to show other potential errors, but skip SYCL library
+        // linking
+      } else {
+        // --------------------------------------------------------------------
+        // STEP 2: Add SYCL library search path
+        // --------------------------------------------------------------------
+        CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
+                                             TC.getDriver().Dir + "/../lib"));
+
+        // --------------------------------------------------------------------
+        // STEP 3: Determine if this is a debug build
+        // Only check DYNAMIC CRT flags (/MDd), never static (/MTd)
+        // --------------------------------------------------------------------
+        bool IsDebugBuild = false;
+
+        // Method 1: Check -fms-runtime-lib=dll_dbg
+        if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
+          StringRef RuntimeVal = A->getValue();
+          if (RuntimeVal == "dll_dbg")
+            IsDebugBuild = true;
+        }
+
+        // Method 2: Check for /MDd flag (dynamic debug CRT)
+        if (Args.hasArg(options::OPT__SLASH_MDd))
+          IsDebugBuild = true;
+
+        // --------------------------------------------------------------------
+        // STEP 4: Add appropriate SYCL runtime library
+        // Using LLVMSYCL for LLVM naming convention
+        // --------------------------------------------------------------------
+        if (IsDebugBuild) {
+          // Debug build: link debug SYCL runtime
+          CmdArgs.push_back("-defaultlib:LLVMSYCLd.lib");
+        } else {
+          // Release build: link release SYCL runtime
+          CmdArgs.push_back("-defaultlib:LLVMSYCL.lib");
+        }
+
+        // Add msvcrt for SYCL (dynamic CRT)
+        CmdArgs.push_back("-defaultlib:msvcrt");
+      }
+    } else {
+      // Original logic for non-SYCL builds
+      CmdArgs.push_back("-defaultlib:libcmt");
+    }
+
     CmdArgs.push_back("-defaultlib:oldnames");
   }
 
@@ -162,6 +262,12 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
   if (TC.getVFS().exists(CRTPath))
     CmdArgs.push_back(Args.MakeArgString("-libpath:" + CRTPath));
 
+  // ==========================================================================
+  // SYCL: Suppress LNK4078 warning (multiple .llvm.offloading sections)
+  // ==========================================================================
+  if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false))
+    CmdArgs.push_back("/IGNORE:4078");
+
   CmdArgs.push_back("-nologo");
 
   if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7))

>From 0e6636be0f146b5f0eaa09823b4cd8592235b97c Mon Sep 17 00:00:00 2001
From: srividya sundaram <[email protected]>
Date: Tue, 28 Apr 2026 15:28:43 -0700
Subject: [PATCH 2/8] Add SYCL RT lib path for windows and test.

---
 clang/lib/Driver/ToolChains/SYCL.cpp | 65 ++++++++++++++++++++--------
 clang/test/Driver/sycl-windows.cpp   | 65 ++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+), 19 deletions(-)
 create mode 100644 clang/test/Driver/sycl-windows.cpp

diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp 
b/clang/lib/Driver/ToolChains/SYCL.cpp
index 55a697df5081e..7e7c1d6a31d6a 100644
--- a/clang/lib/Driver/ToolChains/SYCL.cpp
+++ b/clang/lib/Driver/ToolChains/SYCL.cpp
@@ -23,25 +23,52 @@ SYCLInstallationDetector::SYCLInstallationDetector(
   // directory in SYCLRTLibPath for use by the linker.
   StringRef SysRoot = D.SysRoot;
   SmallString<128> DriverDir(D.Dir);
-  SmallString<128> LibPath(DriverDir);
-  llvm::sys::path::append(LibPath, "..", "lib", HostTriple.str(),
-                          "libLLVMSYCL.so");
-  // Flat lib path for LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF builds,
-  // where the library is installed directly in lib/ with no triple subdir.
-  SmallString<128> FlatLibPath(DriverDir);
-  llvm::sys::path::append(FlatLibPath, "..", "lib", "libLLVMSYCL.so");
-
-  if (DriverDir.starts_with(SysRoot) &&
-      Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
-    // LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON: library is in lib/<triple>/
-    if (D.getVFS().exists(LibPath))
-      llvm::sys::path::append(DriverDir, "..", "lib", HostTriple.str());
-    // LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF: library is in lib/
-    else if (D.getVFS().exists(FlatLibPath))
-      llvm::sys::path::append(DriverDir, "..", "lib");
-    else
-      return; // Neither path exists : broken install, leave SYCLRTLibPath 
unset
-    SYCLRTLibPath = DriverDir;
+
+  if (HostTriple.isOSWindows()) {
+    // ========================================================================
+    // Windows: Check for LLVMSYCL.lib
+    // NOTE: Only checks for release library; debug variant is selected via
+    //       CRT flags in MSVC.cpp, not filesystem detection
+    // ========================================================================
+    if (DriverDir.starts_with(SysRoot) &&
+        Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
+      SmallString<128> LibDir(DriverDir);
+      llvm::sys::path::append(LibDir, "..", "lib");
+
+      // Verify SYCL runtime library exists
+      SmallString<256> SYCLLibPath(LibDir);
+      llvm::sys::path::append(SYCLLibPath, "LLVMSYCL.lib");
+
+      if (D.getVFS().exists(SYCLLibPath)) {
+        SYCLRTLibPath = LibDir;
+      }
+    }
+  } else {
+    // ========================================================================
+    // Linux/Unix: Check for libLLVMSYCL.so (existing logic)
+    // ========================================================================
+    SmallString<128> LibPath(DriverDir);
+    llvm::sys::path::append(LibPath, "..", "lib", HostTriple.str(),
+                            "libLLVMSYCL.so");
+    // Flat lib path for LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF builds,
+    // where the library is installed directly in lib/ with no triple subdir.
+    SmallString<128> FlatLibPath(DriverDir);
+    llvm::sys::path::append(FlatLibPath, "..", "lib", "libLLVMSYCL.so");
+
+    if (DriverDir.starts_with(SysRoot) &&
+        Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
+      // LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON: library is in lib/<triple>/
+      if (D.getVFS().exists(LibPath))
+        llvm::sys::path::append(DriverDir, "..", "lib", HostTriple.str());
+      // LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF: library is in lib/
+      else if (D.getVFS().exists(FlatLibPath))
+        llvm::sys::path::append(DriverDir, "..", "lib");
+      else
+        return; // Neither path exists : broken install, leave SYCLRTLibPath
+                // unset
+
+      SYCLRTLibPath = DriverDir;
+    }
   }
 }
 
diff --git a/clang/test/Driver/sycl-windows.cpp 
b/clang/test/Driver/sycl-windows.cpp
new file mode 100644
index 0000000000000..4fae8da6d0f37
--- /dev/null
+++ b/clang/test/Driver/sycl-windows.cpp
@@ -0,0 +1,65 @@
+/// Windows SYCL runtime library linking tests
+
+
+/// Test 1: Auto-/MD is added when no CRT specified
+// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-AUTO-MD %s
+// CHECK-AUTO-MD: "/MD"
+// CHECK-AUTO-MD: "-defaultlib:LLVMSYCL.lib"
+
+/// Test 2: /MT is rejected with clear error
+// RUN: not %clang_cl -fsycl /MT --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-MT-ERROR %s
+// CHECK-MT-ERROR: error: SYCL requires dynamic C++ runtime
+
+/// Test 3: /MTd is also rejected
+// RUN: not %clang_cl -fsycl /MTd --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-MTD-ERROR %s
+// CHECK-MTD-ERROR: error: SYCL requires dynamic C++ runtime
+
+/// Test 4: /MD uses release library
+// RUN: %clang_cl -### -fsycl /MD --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-RELEASE %s
+// CHECK-RELEASE: "-defaultlib:LLVMSYCL.lib"
+// CHECK-RELEASE-NOT: LLVMSYCLd.lib
+
+/// Test 5: /MDd uses debug library
+// RUN: %clang_cl -### -fsycl /MDd --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-DEBUG %s
+// CHECK-DEBUG: "-defaultlib:LLVMSYCLd.lib"
+// CHECK-DEBUG-NOT: "-defaultlib:LLVMSYCL.lib"
+
+/// Test 6: -fms-runtime-lib=static is rejected
+// RUN: not %clang_cl -fsycl -fms-runtime-lib=static \
+// RUN:   --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-STATIC-ERROR %s
+// CHECK-STATIC-ERROR: error: SYCL requires dynamic C++ runtime
+
+/// Test 7: -fms-runtime-lib=dll_dbg uses debug library
+// RUN: %clang_cl -### -fsycl -fms-runtime-lib=dll_dbg \
+// RUN:   --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-FLAG-DEBUG %s
+// CHECK-FLAG-DEBUG: "-defaultlib:LLVMSYCLd.lib"
+
+/// Test 8: LNK4078 warning is suppressed
+// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-IGNORE %s
+// CHECK-IGNORE: "/IGNORE:4078"
+
+/// Test 9: -nolibsycl skips library linking and CRT check
+// RUN: %clang_cl -### -fsycl -nolibsycl /MT \
+// RUN:   --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-NOLIBSYCL %s
+// CHECK-NOLIBSYCL-NOT: error:
+// CHECK-NOLIBSYCL-NOT: "-defaultlib:LLVMSYCL
+
+/// Test 10: Explicit /MD doesn't cause duplicate flag
+// RUN: %clang_cl -### -fsycl /MD --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-NO-DUP %s
+// CHECK-NO-DUP: "/MD"
+// CHECK-NO-DUP-NOT: "/MD"{{.*}}"/MD"
+
+/// Test 11: Library search path is added
+// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-LIBPATH %s
+// CHECK-LIBPATH: "-libpath:{{.*}}{{[/\\]+}}lib"

>From 4479f02c843373eb3dc7c11f1215124dec3328d4 Mon Sep 17 00:00:00 2001
From: srividya sundaram <[email protected]>
Date: Tue, 28 Apr 2026 15:51:35 -0700
Subject: [PATCH 3/8] Update test.

---
 clang/lib/Driver/ToolChains/MSVC.cpp | 124 +++++++++++++--------------
 clang/test/Driver/sycl-windows.cpp   |   9 +-
 2 files changed, 66 insertions(+), 67 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp 
b/clang/lib/Driver/ToolChains/MSVC.cpp
index 2e052f6e282b1..4b0fa4627980f 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -111,83 +111,81 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
     }
   }
 
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
-      !C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) {
+  // ==========================================================================
+  // SYCL: Validate CRT compatibility and add SYCL runtime libraries
+  // This needs to run for both CL mode and regular mode
+  // ==========================================================================
+  if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
+      !Args.hasArg(options::OPT_nolibsycl) &&
+      !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
 
-    // ========================================================================
-    // SYCL: Validate CRT compatibility and add SYCL runtime libraries
-    // ========================================================================
-    if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
-        !Args.hasArg(options::OPT_nolibsycl)) {
+    // ------------------------------------------------------------------------
+    // STEP 1: Validate that static CRT is not being used
+    // ------------------------------------------------------------------------
+    bool HasStaticCRT = false;
 
-      // ----------------------------------------------------------------------
-      // STEP 1: Validate that static CRT is not being used
-      // ----------------------------------------------------------------------
-      bool HasStaticCRT = false;
+    // Check for explicit /MT or /MTd flags
+    if (Args.hasArg(options::OPT__SLASH_MT) ||
+        Args.hasArg(options::OPT__SLASH_MTd)) {
+      HasStaticCRT = true;
+    }
 
-      // Check for explicit /MT or /MTd flags
-      if (Args.hasArg(options::OPT__SLASH_MT) ||
-          Args.hasArg(options::OPT__SLASH_MTd)) {
+    // Check -fms-runtime-lib flag
+    if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
+      StringRef RuntimeLib = A->getValue();
+      if (RuntimeLib == "static" || RuntimeLib == "static_dbg") {
         HasStaticCRT = true;
       }
+    }
 
-      // Check -fms-runtime-lib flag
-      if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
-        StringRef RuntimeLib = A->getValue();
-        if (RuntimeLib == "static" || RuntimeLib == "static_dbg") {
-          HasStaticCRT = true;
-        }
-      }
+    // Reject static CRT with SYCL
+    if (HasStaticCRT) {
+      TC.getDriver().Diag(diag::err_drv_sycl_requires_dynamic_crt);
+      // Continue to show other potential errors, but skip SYCL library linking
+    } else {
+      // ----------------------------------------------------------------------
+      // STEP 2: Add SYCL library search path
+      // ----------------------------------------------------------------------
+      CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
+                                           TC.getDriver().Dir + "/../lib"));
 
-      // Reject static CRT with SYCL
-      if (HasStaticCRT) {
-        TC.getDriver().Diag(diag::err_drv_sycl_requires_dynamic_crt);
-        // Continue to show other potential errors, but skip SYCL library
-        // linking
-      } else {
-        // --------------------------------------------------------------------
-        // STEP 2: Add SYCL library search path
-        // --------------------------------------------------------------------
-        CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
-                                             TC.getDriver().Dir + "/../lib"));
-
-        // --------------------------------------------------------------------
-        // STEP 3: Determine if this is a debug build
-        // Only check DYNAMIC CRT flags (/MDd), never static (/MTd)
-        // --------------------------------------------------------------------
-        bool IsDebugBuild = false;
-
-        // Method 1: Check -fms-runtime-lib=dll_dbg
-        if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
-          StringRef RuntimeVal = A->getValue();
-          if (RuntimeVal == "dll_dbg")
-            IsDebugBuild = true;
-        }
+      // ----------------------------------------------------------------------
+      // STEP 3: Determine if this is a debug build
+      // Only check DYNAMIC CRT flags (/MDd), never static (/MTd)
+      // ----------------------------------------------------------------------
+      bool IsDebugBuild = false;
 
-        // Method 2: Check for /MDd flag (dynamic debug CRT)
-        if (Args.hasArg(options::OPT__SLASH_MDd))
+      // Method 1: Check -fms-runtime-lib=dll_dbg
+      if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
+        StringRef RuntimeVal = A->getValue();
+        if (RuntimeVal == "dll_dbg")
           IsDebugBuild = true;
+      }
 
-        // --------------------------------------------------------------------
-        // STEP 4: Add appropriate SYCL runtime library
-        // Using LLVMSYCL for LLVM naming convention
-        // --------------------------------------------------------------------
-        if (IsDebugBuild) {
-          // Debug build: link debug SYCL runtime
-          CmdArgs.push_back("-defaultlib:LLVMSYCLd.lib");
-        } else {
-          // Release build: link release SYCL runtime
-          CmdArgs.push_back("-defaultlib:LLVMSYCL.lib");
-        }
+      // Method 2: Check for /MDd flag (dynamic debug CRT)
+      if (Args.hasArg(options::OPT__SLASH_MDd))
+        IsDebugBuild = true;
 
-        // Add msvcrt for SYCL (dynamic CRT)
-        CmdArgs.push_back("-defaultlib:msvcrt");
+      // ----------------------------------------------------------------------
+      // STEP 4: Add appropriate SYCL runtime library
+      // Using LLVMSYCL for LLVM naming convention
+      // ----------------------------------------------------------------------
+      if (IsDebugBuild) {
+        // Debug build: link debug SYCL runtime
+        CmdArgs.push_back("-defaultlib:LLVMSYCLd.lib");
+      } else {
+        // Release build: link release SYCL runtime
+        CmdArgs.push_back("-defaultlib:LLVMSYCL.lib");
       }
-    } else {
-      // Original logic for non-SYCL builds
-      CmdArgs.push_back("-defaultlib:libcmt");
+
+      // Add msvcrt for SYCL (dynamic CRT)
+      CmdArgs.push_back("-defaultlib:msvcrt");
     }
+  }
 
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
+      !C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) {
+    CmdArgs.push_back("-defaultlib:libcmt");
     CmdArgs.push_back("-defaultlib:oldnames");
   }
 
diff --git a/clang/test/Driver/sycl-windows.cpp 
b/clang/test/Driver/sycl-windows.cpp
index 4fae8da6d0f37..86c09c4014cff 100644
--- a/clang/test/Driver/sycl-windows.cpp
+++ b/clang/test/Driver/sycl-windows.cpp
@@ -53,11 +53,12 @@
 // CHECK-NOLIBSYCL-NOT: error:
 // CHECK-NOLIBSYCL-NOT: "-defaultlib:LLVMSYCL
 
-/// Test 10: Explicit /MD doesn't cause duplicate flag
+/// Test 10: Explicit /MD results in correct libraries
 // RUN: %clang_cl -### -fsycl /MD --target=x86_64-pc-windows-msvc %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=CHECK-NO-DUP %s
-// CHECK-NO-DUP: "/MD"
-// CHECK-NO-DUP-NOT: "/MD"{{.*}}"/MD"
+// RUN:   | FileCheck -check-prefix=CHECK-EXPLICIT-MD %s
+// CHECK-EXPLICIT-MD: clang-linker-wrapper"
+// CHECK-EXPLICIT-MD-SAME: "-defaultlib:LLVMSYCL.lib"
+// CHECK-EXPLICIT-MD-SAME: "-defaultlib:msvcrt"
 
 /// Test 11: Library search path is added
 // RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc %s 2>&1 \

>From 5472767ebbcce78ba79912c4be36d336140548fb Mon Sep 17 00:00:00 2001
From: srividya sundaram <[email protected]>
Date: Tue, 5 May 2026 15:39:42 -0700
Subject: [PATCH 4/8] Embeds SYCL library dependency via `--dependent-lib` at
 compiler stage.

---
 clang/lib/Driver/ToolChains/Clang.cpp | 26 +++++++++
 clang/lib/Driver/ToolChains/MSVC.cpp  | 76 ++++++---------------------
 clang/lib/Driver/ToolChains/SYCL.cpp  |  6 +--
 clang/test/Driver/sycl-windows.cpp    | 65 +++++++++++++----------
 4 files changed, 80 insertions(+), 93 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index cfa3031431498..be6803c2c3b09 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4911,6 +4911,32 @@ static void ProcessVSRuntimeLibrary(const ToolChain &TC, 
const ArgList &Args,
     CmdArgs.push_back("--dependent-lib=oldnames");
   }
 
+  // SYCL: Add SYCL runtime library dependency
+  // SYCL runtime is a required dependency similar to CRT, so we use
+  // --dependent-lib to embed it in the object file metadata
+  if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
+      !Args.hasArg(options::OPT_nolibsycl) &&
+      !Args.hasArg(options::OPT_fms_omit_default_lib)) {
+
+    // Determine debug vs release based on CRT flags
+    bool IsDebugBuild = false;
+
+    // Check -fms-runtime-lib=dll_dbg
+    if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
+      StringRef RuntimeVal = A->getValue();
+      if (RuntimeVal == "dll_dbg")
+        IsDebugBuild = true;
+    }
+
+    // Check for /MDd flag (dynamic debug CRT)
+    if (Args.hasArg(options::OPT__SLASH_MDd))
+      IsDebugBuild = true;
+
+    // Add appropriate SYCL runtime library dependency
+    CmdArgs.push_back(IsDebugBuild ? "--dependent-lib=LLVMSYCLd"
+                                   : "--dependent-lib=LLVMSYCL");
+  }
+
   // All Arm64EC object files implicitly add softintrin.lib. This is necessary
   // even if the file doesn't actually refer to any of the routines because
   // the CRT itself has incomplete dependency markings.
diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp 
b/clang/lib/Driver/ToolChains/MSVC.cpp
index 4b0fa4627980f..8af89949da7cf 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -85,11 +85,9 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
       CmdArgs.push_back(Args.MakeArgString("--dependent-lib=amath"));
   }
 
-  // ==========================================================================
   // SYCL: Auto-add /MD if no C++ runtime specified
   // SYCL requires dynamic C++ runtime because STL objects cross DLL boundaries
   // This must happen BEFORE other CRT handling logic
-  // ==========================================================================
   if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
       !Args.hasArg(options::OPT_nolibsycl) &&
       !Args.hasArg(options::OPT_nostdlib) &&
@@ -111,75 +109,31 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
     }
   }
 
-  // ==========================================================================
-  // SYCL: Validate CRT compatibility and add SYCL runtime libraries
-  // This needs to run for both CL mode and regular mode
-  // ==========================================================================
+  // SYCL requires dynamic CRT because STL objects cross DLL boundaries.
+  // Library dependency is added via --dependent-lib at compiler stage.
+  // Here we validate CRT compatibility and add the library search path.
   if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
       !Args.hasArg(options::OPT_nolibsycl) &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
 
-    // ------------------------------------------------------------------------
-    // STEP 1: Validate that static CRT is not being used
-    // ------------------------------------------------------------------------
-    bool HasStaticCRT = false;
+    // Check if static CRT is being used.
+    bool HasStaticCRT = Args.hasArg(options::OPT__SLASH_MT) ||
+                        Args.hasArg(options::OPT__SLASH_MTd);
 
-    // Check for explicit /MT or /MTd flags
-    if (Args.hasArg(options::OPT__SLASH_MT) ||
-        Args.hasArg(options::OPT__SLASH_MTd)) {
-      HasStaticCRT = true;
-    }
-
-    // Check -fms-runtime-lib flag
     if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
       StringRef RuntimeLib = A->getValue();
-      if (RuntimeLib == "static" || RuntimeLib == "static_dbg") {
+      if (RuntimeLib == "static" || RuntimeLib == "static_dbg")
         HasStaticCRT = true;
-      }
     }
 
-    // Reject static CRT with SYCL
     if (HasStaticCRT) {
       TC.getDriver().Diag(diag::err_drv_sycl_requires_dynamic_crt);
-      // Continue to show other potential errors, but skip SYCL library linking
     } else {
-      // ----------------------------------------------------------------------
-      // STEP 2: Add SYCL library search path
-      // ----------------------------------------------------------------------
-      CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
-                                           TC.getDriver().Dir + "/../lib"));
-
-      // ----------------------------------------------------------------------
-      // STEP 3: Determine if this is a debug build
-      // Only check DYNAMIC CRT flags (/MDd), never static (/MTd)
-      // ----------------------------------------------------------------------
-      bool IsDebugBuild = false;
-
-      // Method 1: Check -fms-runtime-lib=dll_dbg
-      if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
-        StringRef RuntimeVal = A->getValue();
-        if (RuntimeVal == "dll_dbg")
-          IsDebugBuild = true;
-      }
-
-      // Method 2: Check for /MDd flag (dynamic debug CRT)
-      if (Args.hasArg(options::OPT__SLASH_MDd))
-        IsDebugBuild = true;
-
-      // ----------------------------------------------------------------------
-      // STEP 4: Add appropriate SYCL runtime library
-      // Using LLVMSYCL for LLVM naming convention
-      // ----------------------------------------------------------------------
-      if (IsDebugBuild) {
-        // Debug build: link debug SYCL runtime
-        CmdArgs.push_back("-defaultlib:LLVMSYCLd.lib");
-      } else {
-        // Release build: link release SYCL runtime
-        CmdArgs.push_back("-defaultlib:LLVMSYCL.lib");
-      }
-
-      // Add msvcrt for SYCL (dynamic CRT)
-      CmdArgs.push_back("-defaultlib:msvcrt");
+      // Add library search path so linker can find LLVMSYCL[d].lib.
+      SmallString<128> LibPath(TC.getDriver().Dir);
+      llvm::sys::path::append(LibPath, "..", "lib");
+      CmdArgs.push_back(
+          Args.MakeArgString(Twine("-libpath:") + LibPath));
     }
   }
 
@@ -260,9 +214,9 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
   if (TC.getVFS().exists(CRTPath))
     CmdArgs.push_back(Args.MakeArgString("-libpath:" + CRTPath));
 
-  // ==========================================================================
-  // SYCL: Suppress LNK4078 warning (multiple .llvm.offloading sections)
-  // ==========================================================================
+  // SYCL offload compilation creates .llvm.offloading sections in each object
+  // file to store device code and metadata. Suppress linker warning about
+  // multiple sections with different attributes (LNK4078).
   if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false))
     CmdArgs.push_back("/IGNORE:4078");
 
diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp 
b/clang/lib/Driver/ToolChains/SYCL.cpp
index 7e7c1d6a31d6a..3398036f3b54a 100644
--- a/clang/lib/Driver/ToolChains/SYCL.cpp
+++ b/clang/lib/Driver/ToolChains/SYCL.cpp
@@ -25,18 +25,16 @@ SYCLInstallationDetector::SYCLInstallationDetector(
   SmallString<128> DriverDir(D.Dir);
 
   if (HostTriple.isOSWindows()) {
-    // ========================================================================
     // Windows: Check for LLVMSYCL.lib
     // NOTE: Only checks for release library; debug variant is selected via
     //       CRT flags in MSVC.cpp, not filesystem detection
-    // ========================================================================
     if (DriverDir.starts_with(SysRoot) &&
         Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
       SmallString<128> LibDir(DriverDir);
       llvm::sys::path::append(LibDir, "..", "lib");
 
       // Verify SYCL runtime library exists
-      SmallString<256> SYCLLibPath(LibDir);
+      SmallString<128> SYCLLibPath(LibDir);
       llvm::sys::path::append(SYCLLibPath, "LLVMSYCL.lib");
 
       if (D.getVFS().exists(SYCLLibPath)) {
@@ -44,9 +42,7 @@ SYCLInstallationDetector::SYCLInstallationDetector(
       }
     }
   } else {
-    // ========================================================================
     // Linux/Unix: Check for libLLVMSYCL.so (existing logic)
-    // ========================================================================
     SmallString<128> LibPath(DriverDir);
     llvm::sys::path::append(LibPath, "..", "lib", HostTriple.str(),
                             "libLLVMSYCL.so");
diff --git a/clang/test/Driver/sycl-windows.cpp 
b/clang/test/Driver/sycl-windows.cpp
index 86c09c4014cff..14ec16fe4f63e 100644
--- a/clang/test/Driver/sycl-windows.cpp
+++ b/clang/test/Driver/sycl-windows.cpp
@@ -1,66 +1,77 @@
 /// Windows SYCL runtime library linking tests
+//
+// NOTE: SYCL runtime library dependency is added at compiler stage via
+// --dependent-lib (embedded in object file), similar to CRT libraries.
+// Tests check for --dependent-lib in compiler (-cc1) output and
+// -libpath: in linker output.
 
-
-/// Test 1: Auto-/MD is added when no CRT specified
-// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc %s 2>&1 \
+/// Test 1: Auto-/MD and release library dependency
+// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-AUTO-MD %s
-// CHECK-AUTO-MD: "/MD"
-// CHECK-AUTO-MD: "-defaultlib:LLVMSYCL.lib"
+// CHECK-AUTO-MD: "-cc1"
+// CHECK-AUTO-MD: "--dependent-lib=LLVMSYCL"
+// CHECK-AUTO-MD: clang-linker-wrapper"
+// CHECK-AUTO-MD-SAME: "/MD"
+// CHECK-AUTO-MD-SAME: "-libpath:{{.*}}{{[/\\]+}}lib"
 
 /// Test 2: /MT is rejected with clear error
-// RUN: not %clang_cl -fsycl /MT --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN: not %clang_cl -fsycl /MT --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-MT-ERROR %s
 // CHECK-MT-ERROR: error: SYCL requires dynamic C++ runtime
 
 /// Test 3: /MTd is also rejected
-// RUN: not %clang_cl -fsycl /MTd --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN: not %clang_cl -fsycl /MTd --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-MTD-ERROR %s
 // CHECK-MTD-ERROR: error: SYCL requires dynamic C++ runtime
 
 /// Test 4: /MD uses release library
-// RUN: %clang_cl -### -fsycl /MD --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN: %clang_cl -### -fsycl /MD --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-RELEASE %s
-// CHECK-RELEASE: "-defaultlib:LLVMSYCL.lib"
-// CHECK-RELEASE-NOT: LLVMSYCLd.lib
+// CHECK-RELEASE: "-cc1"
+// CHECK-RELEASE: "--dependent-lib=LLVMSYCL"
+// CHECK-RELEASE-NOT: LLVMSYCLd
 
 /// Test 5: /MDd uses debug library
-// RUN: %clang_cl -### -fsycl /MDd --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN: %clang_cl -### -fsycl /MDd --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-DEBUG %s
-// CHECK-DEBUG: "-defaultlib:LLVMSYCLd.lib"
-// CHECK-DEBUG-NOT: "-defaultlib:LLVMSYCL.lib"
+// CHECK-DEBUG: "-cc1"
+// CHECK-DEBUG: "--dependent-lib=LLVMSYCLd"
+// CHECK-DEBUG-NOT: "--dependent-lib=LLVMSYCL"
 
 /// Test 6: -fms-runtime-lib=static is rejected
 // RUN: not %clang_cl -fsycl -fms-runtime-lib=static \
-// RUN:   --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-STATIC-ERROR %s
 // CHECK-STATIC-ERROR: error: SYCL requires dynamic C++ runtime
 
 /// Test 7: -fms-runtime-lib=dll_dbg uses debug library
 // RUN: %clang_cl -### -fsycl -fms-runtime-lib=dll_dbg \
-// RUN:   --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-FLAG-DEBUG %s
-// CHECK-FLAG-DEBUG: "-defaultlib:LLVMSYCLd.lib"
+// CHECK-FLAG-DEBUG: "-cc1"
+// CHECK-FLAG-DEBUG: "--dependent-lib=LLVMSYCLd"
 
 /// Test 8: LNK4078 warning is suppressed
-// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-IGNORE %s
+// CHECK-IGNORE: clang-linker-wrapper"
 // CHECK-IGNORE: "/IGNORE:4078"
 
-/// Test 9: -nolibsycl skips library linking and CRT check
+/// Test 9: -nolibsycl skips library dependency and CRT check
 // RUN: %clang_cl -### -fsycl -nolibsycl /MT \
-// RUN:   --target=x86_64-pc-windows-msvc %s 2>&1 \
+// RUN:   --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-NOLIBSYCL %s
 // CHECK-NOLIBSYCL-NOT: error:
-// CHECK-NOLIBSYCL-NOT: "-defaultlib:LLVMSYCL
+// CHECK-NOLIBSYCL-NOT: "--dependent-lib=LLVMSYCL"
 
-/// Test 10: Explicit /MD results in correct libraries
-// RUN: %clang_cl -### -fsycl /MD --target=x86_64-pc-windows-msvc %s 2>&1 \
+/// Test 10: Explicit /MD results in correct library
+// RUN: %clang_cl -### -fsycl /MD --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-EXPLICIT-MD %s
-// CHECK-EXPLICIT-MD: clang-linker-wrapper"
-// CHECK-EXPLICIT-MD-SAME: "-defaultlib:LLVMSYCL.lib"
-// CHECK-EXPLICIT-MD-SAME: "-defaultlib:msvcrt"
+// CHECK-EXPLICIT-MD: "-cc1"
+// CHECK-EXPLICIT-MD: "--dependent-lib=LLVMSYCL"
 
-/// Test 11: Library search path is added
-// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc %s 2>&1 \
+/// Test 11: Library search path is added at linker stage
+// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-LIBPATH %s
+// CHECK-LIBPATH: clang-linker-wrapper"
 // CHECK-LIBPATH: "-libpath:{{.*}}{{[/\\]+}}lib"

>From 5536e79a31d08d38de99abf6b7356f110f91806f Mon Sep 17 00:00:00 2001
From: srividya sundaram <[email protected]>
Date: Tue, 5 May 2026 15:45:23 -0700
Subject: [PATCH 5/8] Clang format.

---
 clang/lib/Driver/ToolChains/MSVC.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp 
b/clang/lib/Driver/ToolChains/MSVC.cpp
index 8af89949da7cf..66afcc45c0ed5 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -132,8 +132,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
       // Add library search path so linker can find LLVMSYCL[d].lib.
       SmallString<128> LibPath(TC.getDriver().Dir);
       llvm::sys::path::append(LibPath, "..", "lib");
-      CmdArgs.push_back(
-          Args.MakeArgString(Twine("-libpath:") + LibPath));
+      CmdArgs.push_back(Args.MakeArgString(Twine("-libpath:") + LibPath));
     }
   }
 

>From 9672d4b1bd1a410b434cb49a0ba98ca433df4fa0 Mon Sep 17 00:00:00 2001
From: srividya sundaram <[email protected]>
Date: Tue, 5 May 2026 19:26:18 -0700
Subject: [PATCH 6/8] clang with MSVC target: -defaultlib: at linker stage
 addition.

---
 clang/lib/Driver/ToolChains/Clang.cpp |  9 +++--
 clang/lib/Driver/ToolChains/MSVC.cpp  | 55 ++++++++++++++-------------
 clang/lib/Driver/ToolChains/SYCL.cpp  |  6 +--
 clang/test/Driver/sycl-windows.cpp    | 37 +++++++++++++-----
 4 files changed, 65 insertions(+), 42 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index be6803c2c3b09..984dc32b3d245 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4928,9 +4928,12 @@ static void ProcessVSRuntimeLibrary(const ToolChain &TC, 
const ArgList &Args,
         IsDebugBuild = true;
     }
 
-    // Check for /MDd flag (dynamic debug CRT)
-    if (Args.hasArg(options::OPT__SLASH_MDd))
-      IsDebugBuild = true;
+    // Check for /MDd flag (dynamic debug CRT), use getLastArg to handle
+    // overriding options (e.g., /MDd /MD -> /MD wins)
+    if (const Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) {
+      if (A->getOption().matches(options::OPT__SLASH_MDd))
+        IsDebugBuild = true;
+    }
 
     // Add appropriate SYCL runtime library dependency
     CmdArgs.push_back(IsDebugBuild ? "--dependent-lib=LLVMSYCLd"
diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp 
b/clang/lib/Driver/ToolChains/MSVC.cpp
index 66afcc45c0ed5..f1622bb07d037 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -85,30 +85,6 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
       CmdArgs.push_back(Args.MakeArgString("--dependent-lib=amath"));
   }
 
-  // SYCL: Auto-add /MD if no C++ runtime specified
-  // SYCL requires dynamic C++ runtime because STL objects cross DLL boundaries
-  // This must happen BEFORE other CRT handling logic
-  if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
-      !Args.hasArg(options::OPT_nolibsycl) &&
-      !Args.hasArg(options::OPT_nostdlib) &&
-      !Args.hasArg(options::OPT_nostartfiles)) {
-
-    bool HasExplicitCRT = false;
-
-    // Check if user already specified a CRT flag
-    if (Args.hasArg(options::OPT__SLASH_MT) ||
-        Args.hasArg(options::OPT__SLASH_MTd) ||
-        Args.hasArg(options::OPT__SLASH_MD) ||
-        Args.hasArg(options::OPT__SLASH_MDd) ||
-        Args.hasArg(options::OPT_fms_runtime_lib_EQ))
-      HasExplicitCRT = true;
-
-    // Auto-add /MD if no CRT specified (makes dynamic CRT the default for 
SYCL)
-    if (!HasExplicitCRT) {
-      CmdArgs.push_back("/MD");
-    }
-  }
-
   // SYCL requires dynamic CRT because STL objects cross DLL boundaries.
   // Library dependency is added via --dependent-lib at compiler stage.
   // Here we validate CRT compatibility and add the library search path.
@@ -116,9 +92,9 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
       !Args.hasArg(options::OPT_nolibsycl) &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
 
-    // Check if static CRT is being used.
-    bool HasStaticCRT = Args.hasArg(options::OPT__SLASH_MT) ||
-                        Args.hasArg(options::OPT__SLASH_MTd);
+    // Check if static CRT is being used. Use getLastArg to handle overriding
+    // options (e.g., /MT /MD -> /MD wins).
+    bool HasStaticCRT = false;
 
     if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
       StringRef RuntimeLib = A->getValue();
@@ -126,6 +102,12 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
         HasStaticCRT = true;
     }
 
+    if (const Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) {
+      if (A->getOption().matches(options::OPT__SLASH_MT) ||
+          A->getOption().matches(options::OPT__SLASH_MTd))
+        HasStaticCRT = true;
+    }
+
     if (HasStaticCRT) {
       TC.getDriver().Diag(diag::err_drv_sycl_requires_dynamic_crt);
     } else {
@@ -140,6 +122,25 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
       !C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) {
     CmdArgs.push_back("-defaultlib:libcmt");
     CmdArgs.push_back("-defaultlib:oldnames");
+
+    // SYCL: Add runtime library for clang (non-clang-cl) with MSVC target.
+    // For clang-cl, --dependent-lib is used at compiler stage instead.
+    if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) &&
+        !Args.hasArg(options::OPT_nolibsycl)) {
+      bool IsDebugBuild = false;
+      if (const Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
+        StringRef RuntimeVal = A->getValue();
+        if (RuntimeVal == "dll_dbg")
+          IsDebugBuild = true;
+      }
+      // Check for /MDd flag, use getLastArg to handle overriding options
+      if (const Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) {
+        if (A->getOption().matches(options::OPT__SLASH_MDd))
+          IsDebugBuild = true;
+      }
+      CmdArgs.push_back(IsDebugBuild ? "-defaultlib:LLVMSYCLd"
+                                     : "-defaultlib:LLVMSYCL");
+    }
   }
 
   // If the VC environment hasn't been configured (perhaps because the user
diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp 
b/clang/lib/Driver/ToolChains/SYCL.cpp
index 3398036f3b54a..1d86a548fe4e5 100644
--- a/clang/lib/Driver/ToolChains/SYCL.cpp
+++ b/clang/lib/Driver/ToolChains/SYCL.cpp
@@ -26,8 +26,8 @@ SYCLInstallationDetector::SYCLInstallationDetector(
 
   if (HostTriple.isOSWindows()) {
     // Windows: Check for LLVMSYCL.lib
-    // NOTE: Only checks for release library; debug variant is selected via
-    //       CRT flags in MSVC.cpp, not filesystem detection
+    // NOTE: Only checks for LLVMSYCL.lib existence (release variant).
+    // Debug vs release library selection happens at link time based on CRT 
flags.
     if (DriverDir.starts_with(SysRoot) &&
         Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
       SmallString<128> LibDir(DriverDir);
@@ -42,7 +42,7 @@ SYCLInstallationDetector::SYCLInstallationDetector(
       }
     }
   } else {
-    // Linux/Unix: Check for libLLVMSYCL.so (existing logic)
+    // Linux/Unix: Check for libLLVMSYCL.so
     SmallString<128> LibPath(DriverDir);
     llvm::sys::path::append(LibPath, "..", "lib", HostTriple.str(),
                             "libLLVMSYCL.so");
diff --git a/clang/test/Driver/sycl-windows.cpp 
b/clang/test/Driver/sycl-windows.cpp
index 14ec16fe4f63e..d9431a9c3beaa 100644
--- a/clang/test/Driver/sycl-windows.cpp
+++ b/clang/test/Driver/sycl-windows.cpp
@@ -5,14 +5,13 @@
 // Tests check for --dependent-lib in compiler (-cc1) output and
 // -libpath: in linker output.
 
-/// Test 1: Auto-/MD and release library dependency
-// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc -- %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=CHECK-AUTO-MD %s
-// CHECK-AUTO-MD: "-cc1"
-// CHECK-AUTO-MD: "--dependent-lib=LLVMSYCL"
-// CHECK-AUTO-MD: clang-linker-wrapper"
-// CHECK-AUTO-MD-SAME: "/MD"
-// CHECK-AUTO-MD-SAME: "-libpath:{{.*}}{{[/\\]+}}lib"
+/// Test 1: /MD (explicit) and release library dependency
+// RUN: %clang_cl -### -fsycl /MD --target=x86_64-pc-windows-msvc -- %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-MD %s
+// CHECK-MD: "-cc1"
+// CHECK-MD: "--dependent-lib=LLVMSYCL"
+// CHECK-MD: clang-linker-wrapper"
+// CHECK-MD-SAME: "-libpath:{{.*}}{{[/\\]+}}lib"
 
 /// Test 2: /MT is rejected with clear error
 // RUN: not %clang_cl -fsycl /MT --target=x86_64-pc-windows-msvc -- %s 2>&1 \
@@ -71,7 +70,27 @@
 // CHECK-EXPLICIT-MD: "--dependent-lib=LLVMSYCL"
 
 /// Test 11: Library search path is added at linker stage
-// RUN: %clang_cl -### -fsycl --target=x86_64-pc-windows-msvc -- %s 2>&1 \
+// RUN: %clang_cl -### -fsycl /MD --target=x86_64-pc-windows-msvc -- %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-LIBPATH %s
 // CHECK-LIBPATH: clang-linker-wrapper"
 // CHECK-LIBPATH: "-libpath:{{.*}}{{[/\\]+}}lib"
+
+/// Test 12: clang (non-clang-cl) with MSVC target uses -defaultlib:
+// RUN: %clang -### -fsycl -fms-runtime-lib=dll 
--target=x86_64-pc-windows-msvc -- %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-CLANG-DEFAULTLIB %s
+// CHECK-CLANG-DEFAULTLIB: clang-linker-wrapper"
+// CHECK-CLANG-DEFAULTLIB: "-libpath:{{.*}}{{[/\\]+}}lib"
+// CHECK-CLANG-DEFAULTLIB: "-defaultlib:LLVMSYCL"
+
+/// Test 13: clang with -fms-runtime-lib=dll_dbg uses debug library via 
-defaultlib:
+// RUN: %clang -### -fsycl -fms-runtime-lib=dll_dbg 
--target=x86_64-pc-windows-msvc -- %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-CLANG-DEBUG %s
+// CHECK-CLANG-DEBUG: clang-linker-wrapper"
+// CHECK-CLANG-DEBUG: "-defaultlib:LLVMSYCLd"
+
+/// Test 14: Default CRT behavior - release library when no CRT flag specified
+// RUN: %clang -### -fsycl -fms-runtime-lib=dll 
--target=x86_64-pc-windows-msvc -- %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-DEFAULT-CRT %s
+// CHECK-DEFAULT-CRT: "-cc1"
+// CHECK-DEFAULT-CRT: "--dependent-lib=LLVMSYCL"
+// CHECK-DEFAULT-CRT-NOT: LLVMSYCLd

>From d4f202a0df39727a8d7996b8ef63c21b5a85e7e5 Mon Sep 17 00:00:00 2001
From: srividya sundaram <[email protected]>
Date: Tue, 5 May 2026 20:01:20 -0700
Subject: [PATCH 7/8] Fix clang format.

---
 clang/lib/Driver/ToolChains/SYCL.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp 
b/clang/lib/Driver/ToolChains/SYCL.cpp
index 1d86a548fe4e5..a03f99029b9bc 100644
--- a/clang/lib/Driver/ToolChains/SYCL.cpp
+++ b/clang/lib/Driver/ToolChains/SYCL.cpp
@@ -27,7 +27,8 @@ SYCLInstallationDetector::SYCLInstallationDetector(
   if (HostTriple.isOSWindows()) {
     // Windows: Check for LLVMSYCL.lib
     // NOTE: Only checks for LLVMSYCL.lib existence (release variant).
-    // Debug vs release library selection happens at link time based on CRT 
flags.
+    // Debug vs release library selection happens at link time based on CRT
+    // flags.
     if (DriverDir.starts_with(SysRoot) &&
         Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
       SmallString<128> LibDir(DriverDir);

>From 6e692290d3f5748c60e72aa749b3785b0fa2d415 Mon Sep 17 00:00:00 2001
From: srividya sundaram <[email protected]>
Date: Wed, 6 May 2026 10:52:54 -0700
Subject: [PATCH 8/8] Remove /M* checks and braces.

---
 clang/lib/Driver/ToolChains/MSVC.cpp | 5 -----
 clang/lib/Driver/ToolChains/SYCL.cpp | 3 +--
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp 
b/clang/lib/Driver/ToolChains/MSVC.cpp
index f1622bb07d037..c9c555d04ad11 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -133,11 +133,6 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
         if (RuntimeVal == "dll_dbg")
           IsDebugBuild = true;
       }
-      // Check for /MDd flag, use getLastArg to handle overriding options
-      if (const Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group)) {
-        if (A->getOption().matches(options::OPT__SLASH_MDd))
-          IsDebugBuild = true;
-      }
       CmdArgs.push_back(IsDebugBuild ? "-defaultlib:LLVMSYCLd"
                                      : "-defaultlib:LLVMSYCL");
     }
diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp 
b/clang/lib/Driver/ToolChains/SYCL.cpp
index a03f99029b9bc..7400924ab6bdd 100644
--- a/clang/lib/Driver/ToolChains/SYCL.cpp
+++ b/clang/lib/Driver/ToolChains/SYCL.cpp
@@ -38,9 +38,8 @@ SYCLInstallationDetector::SYCLInstallationDetector(
       SmallString<128> SYCLLibPath(LibDir);
       llvm::sys::path::append(SYCLLibPath, "LLVMSYCL.lib");
 
-      if (D.getVFS().exists(SYCLLibPath)) {
+      if (D.getVFS().exists(SYCLLibPath))
         SYCLRTLibPath = LibDir;
-      }
     }
   } else {
     // Linux/Unix: Check for libLLVMSYCL.so

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to