[Clang] Force link user-provided library with -fsycl-allow-device-image-dependencies#22621
[Clang] Force link user-provided library with -fsycl-allow-device-image-dependencies#22621uditagarwal97 wants to merge 5 commits into
-fsycl-allow-device-image-dependencies#22621Conversation
…ge-dependencies is used (#21929)" This reverts commit 2aa7914. /OPT:NOREF is too broad — it disables dead-stripping for the entire link, which can bloat the final binary and mask other unused references. The follow-up commit replaces this with targeted /INCLUDE: directives that force-load only user-provided import libraries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…encies Instead of the blunt /OPT:NOREF (which disables dead-stripping globally), parse each user-provided .lib at driver time and emit /INCLUDE:<sym> for one symbol from each archive. This forces the linker to pull in the DLL import entry — preserving device image dependencies — without disabling optimizations for the rest of the link. System libraries (VC runtime, Windows SDK, UCRT, compiler-rt) and the SYCL runtime lib are excluded from force-loading. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR addresses a Windows-specific SYCL linking issue where device image dependencies living in a DLL can be dropped at higher optimization levels because the host link has no referenced host-side symbols from the DLL/import library. The fix changes the MSVC linker invocation behavior under -fsycl-allow-device-image-dependencies to retain user-provided import libraries without globally disabling linker ref-elimination.
Changes:
- Update the MSVC toolchain linker job to force-link user
.libinputs by injecting/INCLUDE:for an import symbol (instead of adding/OPT:NOREF). - Add a SYCL end-to-end regression test covering the
-O2Windows dynamic-link scenario. - Update the Clang driver test expectations to ensure
/OPT:NOREFis not added for this flag on Windows.
Impact on profiling/debug info: the control-flow change is limited to driver-side linker argument construction; it does not alter code generation decisions that would typically affect debug info for branches/calls or performance profiling instrumentation.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
sycl/test-e2e/DeviceImageDependencies/dynamic_link_opt_win.cpp |
Adds an e2e regression to ensure DLL device image deps are preserved at -O2 on Windows. |
clang/test/Driver/sycl-allow-device-image-deps-win.cpp |
Updates the driver test to reflect that /OPT:NOREF is no longer added for the flag. |
clang/lib/Driver/ToolChains/MSVC.cpp |
Implements /INCLUDE: injection by scanning user .lib inputs for an __imp_ symbol to force retention. |
| auto BufOrErr = llvm::MemoryBuffer::getFile(LibPath); | ||
| if (!BufOrErr) | ||
| return; | ||
| auto ArchiveOrErr = | ||
| llvm::object::Archive::create(BufOrErr.get()->getMemBufferRef()); | ||
| if (!ArchiveOrErr) { |
| for (const auto &Input : Inputs) { | ||
| if (!Input.isFilename()) | ||
| continue; | ||
| StringRef Path(Input.getFilename()); | ||
| if (!Path.ends_with_insensitive(".lib")) | ||
| continue; | ||
| if (IsSystemLib(Path)) | ||
| continue; | ||
|
|
| /// Check that /OPT:NOREF is NOT passed even when both -fsycl and | ||
| /// -fsycl-allow-device-image-dependencies are specified. | ||
| // RUN: %clang_cl -fsycl --offload-new-driver /clang:--sysroot=%S/Inputs/SYCL \ | ||
| // RUN: -fsycl-allow-device-image-dependencies /O2 -### -- %s 2>&1 \ | ||
| // RUN: | FileCheck -check-prefix CHECK_OPT_NOREF %s | ||
| // CHECK_OPT_NOREF: link.exe{{.*}} "/OPT:NOREF" | ||
|
|
||
| /// Check that /OPT:NOREF is NOT passed when -fsycl-allow-device-image-dependencies | ||
| /// is not set (even with -fsycl present). | ||
| // RUN: %clang_cl -fsycl --offload-new-driver /clang:--sysroot=%S/Inputs/SYCL \ | ||
| // RUN: /O2 -### -- %s 2>&1 | FileCheck -check-prefix CHECK_NO_OPT_NOREF %s | ||
| // RUN: | FileCheck -check-prefix CHECK_NO_OPT_NOREF %s | ||
| // CHECK_NO_OPT_NOREF-NOT: "/OPT:NOREF" |
No description provided.