https://github.com/bader updated 
https://github.com/llvm/llvm-project/pull/200096

>From 1e79dde1493ea29e293d576e9861c501ef77a775 Mon Sep 17 00:00:00 2001
From: Alexey Bader <[email protected]>
Date: Wed, 27 May 2026 10:26:39 -0700
Subject: [PATCH 1/5] [clang-sycl-linker] Fix --version exit code and
 empty-input error

- --version now returns EXIT_SUCCESS immediately after printing; previously
  it fell through into the rest of main.
- Report an error early when no input files are provided rather than
  hitting the assert inside linkDeviceCode.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---
 .../OffloadTools/clang-sycl-linker/options.ll | 40 +++++++++++++++++++
 .../clang-sycl-linker/ClangSYCLLinker.cpp     |  7 +++-
 2 files changed, 46 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/OffloadTools/clang-sycl-linker/options.ll

diff --git a/clang/test/OffloadTools/clang-sycl-linker/options.ll 
b/clang/test/OffloadTools/clang-sycl-linker/options.ll
new file mode 100644
index 0000000000000..55b691187028f
--- /dev/null
+++ b/clang/test/OffloadTools/clang-sycl-linker/options.ll
@@ -0,0 +1,40 @@
+; Tests non-functional command line options of the clang-sycl-linker tool.
+;
+; REQUIRES: spirv-registered-target
+;
+; Test --help
+; RUN: clang-sycl-linker --help | FileCheck %s --check-prefix=HELP
+; HELP: OVERVIEW: A utility that wraps around several steps required to link 
SYCL device files.
+; HELP: USAGE: clang-sycl-linker
+; HELP: OPTIONS:
+;
+; Test --version
+; RUN: clang-sycl-linker --version | FileCheck %s --check-prefix=VERSION
+; VERSION: clang-sycl-linker version
+;
+; Test missing input files
+; RUN: not clang-sycl-linker --dry-run -triple=spirv64 -o %t.out 2>&1 | 
FileCheck %s --check-prefix=NO-INPUT
+; NO-INPUT: No input files provided
+;
+; Create a simple bitcode file for subsequent tests
+; RUN: llvm-as %s -o %t.bc
+;
+; Test --print-linked-module
+; RUN: clang-sycl-linker --dry-run -triple=spirv64 %t.bc --print-linked-module 
-o %t.out > %t.ll
+; RUN: FileCheck %s --check-prefix=PRINT-LINKED < %t.ll
+; PRINT-LINKED: target triple = "spirv64"
+;
+; Test --save-temps
+; RUN: rm -rf %t.dir && mkdir -p %t.dir
+; RUN: cd %t.dir && clang-sycl-linker --dry-run -triple=spirv64 %t.bc 
--save-temps -o out.spv
+; RUN: ls %t.dir/out.spv-*.bc | count 1
+;
+; Test --spirv-dump-device-code (should parse without error)
+; RUN: clang-sycl-linker --dry-run -triple=spirv64 %t.bc 
--spirv-dump-device-code=%t.dir -o %t.out
+;
+; Test --spirv-dump-device-code with no value (fallback to ./)
+; RUN: clang-sycl-linker --dry-run -triple=spirv64 %t.bc 
--spirv-dump-device-code= -o %t.out
+
+target datalayout = 
"e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
+target triple = "spirv64"
+
diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp 
b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index 88a09d0a3ecc7..0d83c93065e3f 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -786,8 +786,10 @@ int main(int argc, char **argv) {
     return EXIT_SUCCESS;
   }
 
-  if (Args.hasArg(OPT_version))
+  if (Args.hasArg(OPT_version)) {
     printVersion(outs());
+    return EXIT_SUCCESS;
+  }
 
   Verbose = Args.hasArg(OPT_verbose);
   DryRun = Args.hasArg(OPT_dry_run);
@@ -812,6 +814,9 @@ int main(int argc, char **argv) {
   if (!FilesOrErr)
     reportError(FilesOrErr.takeError());
 
+  if (FilesOrErr->empty())
+    reportError(createStringError("No input files provided"));
+
   // Run SYCL linking process on the generated inputs.
   if (Error Err = runSYCLLink(*FilesOrErr, Args))
     reportError(std::move(Err));

>From 288b27251a5d80cb9dc152a22daaed7189904166 Mon Sep 17 00:00:00 2001
From: Alexey Bader <[email protected]>
Date: Thu, 28 May 2026 16:06:56 -0700
Subject: [PATCH 2/5] [clang-sycl-linker] Implement --spirv-dump-device-code
 and fix tests

Implement the previously unfinished --spirv-dump-device-code option by
copying each generated .spv file into the requested directory after code
generation; SPIRVDumpDir was set but never consumed before this change.

Fix the options.ll tests: drop --dry-run (tests now exercise real code
paths), verify that dump/save-temps output files actually exist, and
isolate each test into its own subdirectory to prevent interference.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---
 .../OffloadTools/clang-sycl-linker/options.ll | 21 ++++++++++++-------
 .../clang-sycl-linker/ClangSYCLLinker.cpp     |  7 +++++++
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/clang/test/OffloadTools/clang-sycl-linker/options.ll 
b/clang/test/OffloadTools/clang-sycl-linker/options.ll
index 55b691187028f..c3712c927624d 100644
--- a/clang/test/OffloadTools/clang-sycl-linker/options.ll
+++ b/clang/test/OffloadTools/clang-sycl-linker/options.ll
@@ -13,27 +13,32 @@
 ; VERSION: clang-sycl-linker version
 ;
 ; Test missing input files
-; RUN: not clang-sycl-linker --dry-run -triple=spirv64 -o %t.out 2>&1 | 
FileCheck %s --check-prefix=NO-INPUT
+; RUN: not clang-sycl-linker -triple=spirv64 -o %t.out 2>&1 | FileCheck %s 
--check-prefix=NO-INPUT
 ; NO-INPUT: No input files provided
 ;
 ; Create a simple bitcode file for subsequent tests
 ; RUN: llvm-as %s -o %t.bc
 ;
 ; Test --print-linked-module
-; RUN: clang-sycl-linker --dry-run -triple=spirv64 %t.bc --print-linked-module 
-o %t.out > %t.ll
+; RUN: clang-sycl-linker -triple=spirv64 %t.bc --print-linked-module -o %t.out 
> %t.ll
 ; RUN: FileCheck %s --check-prefix=PRINT-LINKED < %t.ll
 ; PRINT-LINKED: target triple = "spirv64"
 ;
-; Test --save-temps
 ; RUN: rm -rf %t.dir && mkdir -p %t.dir
-; RUN: cd %t.dir && clang-sycl-linker --dry-run -triple=spirv64 %t.bc 
--save-temps -o out.spv
-; RUN: ls %t.dir/out.spv-*.bc | count 1
 ;
-; Test --spirv-dump-device-code (should parse without error)
-; RUN: clang-sycl-linker --dry-run -triple=spirv64 %t.bc 
--spirv-dump-device-code=%t.dir -o %t.out
+; Test --spirv-dump-device-code (copies SPIR-V output to given directory)
+; RUN: clang-sycl-linker -triple=spirv64 %t.bc --spirv-dump-device-code=%t.dir 
-o out.spv
+; RUN: ls %t.dir/out_0.spv | count 1
 ;
 ; Test --spirv-dump-device-code with no value (fallback to ./)
-; RUN: clang-sycl-linker --dry-run -triple=spirv64 %t.bc 
--spirv-dump-device-code= -o %t.out
+; RUN: mkdir -p %t.dir/fallback
+; RUN: cd %t.dir/fallback && clang-sycl-linker -triple=spirv64 %t.bc 
--spirv-dump-device-code= -o out.spv
+; RUN: ls %t.dir/fallback/out_0.spv | count 1
+;
+; Test --save-temps (keeps intermediate .bc files in current directory)
+; RUN: mkdir -p %t.dir/save-temps
+; RUN: cd %t.dir/save-temps && clang-sycl-linker -triple=spirv64 %t.bc 
--save-temps -o out.spv
+; RUN: ls %t.dir/save-temps/out.spv-*.bc | count 1
 
 target datalayout = 
"e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
 target triple = "spirv64"
diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp 
b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index 0d83c93065e3f..c2080a5468529 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -712,6 +712,13 @@ Error runSYCLLink(ArrayRef<std::string> Files, const 
ArgList &Args) {
                                Result.TargetTriple, Args, CodeGenFile, C))
       return Err;
 
+    if (!SPIRVDumpDir.empty()) {
+      SmallString<256> DumpFile(SPIRVDumpDir);
+      sys::path::append(DumpFile, sys::path::filename(CodeGenFile));
+      if (std::error_code EC = sys::fs::copy_file(CodeGenFile, DumpFile))
+        return createFileError(DumpFile, EC);
+    }
+
     SplitModules[I].ModuleFilePath = CodeGenFile;
     if (IsAOTCompileNeeded) {
       std::string AOTFile = (Stem + "_" + Twine(I) + ".out").str();

>From 33d53947a856e336d6bbbb23e781f5386563e7bc Mon Sep 17 00:00:00 2001
From: Alexey Bader <[email protected]>
Date: Thu, 28 May 2026 16:32:56 -0700
Subject: [PATCH 3/5] [clang-sycl-linker] Address review feedback

- Create the SPIR-V dump directory up-front so users get a clear error
  instead of a low-level copy failure when the path doesn't exist.
- Move the empty-input check into getInput so main has a single error path.
- Drop -triple=spirv64 from the options test (the IR module already sets
  the triple) and unify SmallString sizing for the dump path.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
---
 .../OffloadTools/clang-sycl-linker/options.ll     | 15 ++++++++-------
 clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp | 11 +++++++----
 2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/clang/test/OffloadTools/clang-sycl-linker/options.ll 
b/clang/test/OffloadTools/clang-sycl-linker/options.ll
index c3712c927624d..b57a1b0515fa1 100644
--- a/clang/test/OffloadTools/clang-sycl-linker/options.ll
+++ b/clang/test/OffloadTools/clang-sycl-linker/options.ll
@@ -13,31 +13,32 @@
 ; VERSION: clang-sycl-linker version
 ;
 ; Test missing input files
-; RUN: not clang-sycl-linker -triple=spirv64 -o %t.out 2>&1 | FileCheck %s 
--check-prefix=NO-INPUT
+; RUN: not clang-sycl-linker -o %t.out 2>&1 | FileCheck %s 
--check-prefix=NO-INPUT
 ; NO-INPUT: No input files provided
 ;
 ; Create a simple bitcode file for subsequent tests
 ; RUN: llvm-as %s -o %t.bc
 ;
 ; Test --print-linked-module
-; RUN: clang-sycl-linker -triple=spirv64 %t.bc --print-linked-module -o %t.out 
> %t.ll
+; RUN: clang-sycl-linker %t.bc --print-linked-module -o %t.out > %t.ll
 ; RUN: FileCheck %s --check-prefix=PRINT-LINKED < %t.ll
 ; PRINT-LINKED: target triple = "spirv64"
 ;
 ; RUN: rm -rf %t.dir && mkdir -p %t.dir
 ;
-; Test --spirv-dump-device-code (copies SPIR-V output to given directory)
-; RUN: clang-sycl-linker -triple=spirv64 %t.bc --spirv-dump-device-code=%t.dir 
-o out.spv
-; RUN: ls %t.dir/out_0.spv | count 1
+; Test --spirv-dump-device-code (creates the directory if missing and copies
+; SPIR-V output into it)
+; RUN: clang-sycl-linker %t.bc --spirv-dump-device-code=%t.dir/nested -o 
out.spv
+; RUN: ls %t.dir/nested/out_0.spv | count 1
 ;
 ; Test --spirv-dump-device-code with no value (fallback to ./)
 ; RUN: mkdir -p %t.dir/fallback
-; RUN: cd %t.dir/fallback && clang-sycl-linker -triple=spirv64 %t.bc 
--spirv-dump-device-code= -o out.spv
+; RUN: cd %t.dir/fallback && clang-sycl-linker %t.bc --spirv-dump-device-code= 
-o out.spv
 ; RUN: ls %t.dir/fallback/out_0.spv | count 1
 ;
 ; Test --save-temps (keeps intermediate .bc files in current directory)
 ; RUN: mkdir -p %t.dir/save-temps
-; RUN: cd %t.dir/save-temps && clang-sycl-linker -triple=spirv64 %t.bc 
--save-temps -o out.spv
+; RUN: cd %t.dir/save-temps && clang-sycl-linker %t.bc --save-temps -o out.spv
 ; RUN: ls %t.dir/save-temps/out.spv-*.bc | count 1
 
 target datalayout = 
"e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp 
b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index c2080a5468529..66ac47cd4b2ac 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -200,6 +200,8 @@ Expected<SmallVector<std::string>> getInput(const ArgList 
&Args) {
       return createStringError("Unsupported file type");
     BitcodeFiles.push_back(*Filename);
   }
+  if (BitcodeFiles.empty())
+    return createStringError("No input files provided");
   return BitcodeFiles;
 }
 
@@ -713,7 +715,7 @@ Error runSYCLLink(ArrayRef<std::string> Files, const 
ArgList &Args) {
       return Err;
 
     if (!SPIRVDumpDir.empty()) {
-      SmallString<256> DumpFile(SPIRVDumpDir);
+      SmallString<128> DumpFile(SPIRVDumpDir);
       sys::path::append(DumpFile, sys::path::filename(CodeGenFile));
       if (std::error_code EC = sys::fs::copy_file(CodeGenFile, DumpFile))
         return createFileError(DumpFile, EC);
@@ -813,6 +815,10 @@ int main(int argc, char **argv) {
     else
       Dir.append(llvm::sys::path::get_separator());
 
+    if (std::error_code EC = sys::fs::create_directories(Dir))
+      reportError(createStringError(
+          EC, "cannot create SPIR-V dump directory '" + Dir + "'"));
+
     SPIRVDumpDir = Dir;
   }
 
@@ -821,9 +827,6 @@ int main(int argc, char **argv) {
   if (!FilesOrErr)
     reportError(FilesOrErr.takeError());
 
-  if (FilesOrErr->empty())
-    reportError(createStringError("No input files provided"));
-
   // Run SYCL linking process on the generated inputs.
   if (Error Err = runSYCLLink(*FilesOrErr, Args))
     reportError(std::move(Err));

>From fa99331e07a73ecd1e1ff1dc8c4c22c1023d3a99 Mon Sep 17 00:00:00 2001
From: Alexey Bader <[email protected]>
Date: Thu, 28 May 2026 16:47:05 -0700
Subject: [PATCH 4/5] Simplify the code.

---
 .../tools/clang-sycl-linker/ClangSYCLLinker.cpp | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp 
b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index 66ac47cd4b2ac..a535b68e4f997 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -807,19 +807,12 @@ int main(int argc, char **argv) {
     reportError(createStringError("Output file must be specified"));
   OutputFile = Args.getLastArgValue(OPT_o);
 
-  if (Args.hasArg(OPT_spirv_dump_device_code_EQ)) {
-    Arg *A = Args.getLastArg(OPT_spirv_dump_device_code_EQ);
-    SmallString<128> Dir(A->getValue());
-    if (Dir.empty())
-      llvm::sys::path::native(Dir = "./");
-    else
-      Dir.append(llvm::sys::path::get_separator());
-
-    if (std::error_code EC = sys::fs::create_directories(Dir))
+  if (auto *A = Args.getLastArg(OPT_spirv_dump_device_code_EQ)) {
+    StringRef V = A->getValue();
+    SPIRVDumpDir = V.empty() ? "." : V;
+    if (std::error_code EC = sys::fs::create_directories(SPIRVDumpDir))
       reportError(createStringError(
-          EC, "cannot create SPIR-V dump directory '" + Dir + "'"));
-
-    SPIRVDumpDir = Dir;
+          EC, "cannot create SPIR-V dump directory '" + SPIRVDumpDir + "'"));
   }
 
   // Get the input files to pass to the linking stage.

>From 89e86b9a67052f6d509f48eeafa40d7604796fd4 Mon Sep 17 00:00:00 2001
From: Alexey Bader <[email protected]>
Date: Thu, 28 May 2026 16:56:33 -0700
Subject: [PATCH 5/5] [clang-sycl-linker] Tighten input diagnostics and harden
 --spirv-dump-device-code

- getInput: report missing/invalid input files explicitly instead of
  silently skipping them; reserve "No input files provided" for the
  no-INPUT-args case and include the offending path in the
  unsupported-file-type diagnostic.
- main: run getInput before setting up the SPIR-V dump directory so
  missing-input is reported first; skip create_directories and the
  per-module copy_file in --dry-run mode.
- Tests: split CLI-only checks (--help, --version, missing/non-existent/
  non-bitcode input) into cli.test so they run on configs without the
  SPIR-V backend; replace fragile "ls | count 1" with "test -f"; add a
  case for dump-dir creation failure; reorder IR header above RUN lines.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
---
 .../OffloadTools/clang-sycl-linker/cli.test   | 24 +++++++
 .../OffloadTools/clang-sycl-linker/options.ll | 64 +++++++++----------
 .../clang-sycl-linker/ClangSYCLLinker.cpp     | 44 +++++++------
 3 files changed, 79 insertions(+), 53 deletions(-)
 create mode 100644 clang/test/OffloadTools/clang-sycl-linker/cli.test

diff --git a/clang/test/OffloadTools/clang-sycl-linker/cli.test 
b/clang/test/OffloadTools/clang-sycl-linker/cli.test
new file mode 100644
index 0000000000000..f0e93be708d0d
--- /dev/null
+++ b/clang/test/OffloadTools/clang-sycl-linker/cli.test
@@ -0,0 +1,24 @@
+## Tests CLI handling that does not require a SPIR-V backend:
+## --help, --version, and missing-input diagnostics.
+
+# Test --help
+# RUN: clang-sycl-linker --help | FileCheck %s --check-prefix=HELP
+# HELP: OVERVIEW: A utility that wraps around several steps required to link 
SYCL device files.
+# HELP: USAGE: clang-sycl-linker
+# HELP: OPTIONS:
+
+# Test --version
+# RUN: clang-sycl-linker --version | FileCheck %s --check-prefix=VERSION
+# VERSION: clang-sycl-linker version
+
+# Test missing input files
+# RUN: not clang-sycl-linker -o %t.out 2>&1 | FileCheck %s 
--check-prefix=NO-INPUT
+# NO-INPUT: No input files provided
+
+# Test non-existent input file
+# RUN: not clang-sycl-linker %t-missing.bc -o %t.out 2>&1 | FileCheck %s 
--check-prefix=MISSING
+# MISSING: Input file '{{.*}}-missing.bc' does not exist
+
+# Test non-bitcode input file (use this test file itself, which is text)
+# RUN: not clang-sycl-linker %s -o %t.out 2>&1 | FileCheck %s 
--check-prefix=BAD-MAGIC
+# BAD-MAGIC: Unsupported file type for '{{.*}}cli.test'
diff --git a/clang/test/OffloadTools/clang-sycl-linker/options.ll 
b/clang/test/OffloadTools/clang-sycl-linker/options.ll
index b57a1b0515fa1..113881e18733e 100644
--- a/clang/test/OffloadTools/clang-sycl-linker/options.ll
+++ b/clang/test/OffloadTools/clang-sycl-linker/options.ll
@@ -1,46 +1,44 @@
-; Tests non-functional command line options of the clang-sycl-linker tool.
+; Tests command-line options of clang-sycl-linker that exercise the SPIR-V
+; backend (--print-linked-module, --spirv-dump-device-code, --save-temps).
+; CLI-only tests that do not need the SPIR-V backend live in cli.test.
 ;
 ; REQUIRES: spirv-registered-target
-;
-; Test --help
-; RUN: clang-sycl-linker --help | FileCheck %s --check-prefix=HELP
-; HELP: OVERVIEW: A utility that wraps around several steps required to link 
SYCL device files.
-; HELP: USAGE: clang-sycl-linker
-; HELP: OPTIONS:
-;
-; Test --version
-; RUN: clang-sycl-linker --version | FileCheck %s --check-prefix=VERSION
-; VERSION: clang-sycl-linker version
-;
-; Test missing input files
-; RUN: not clang-sycl-linker -o %t.out 2>&1 | FileCheck %s 
--check-prefix=NO-INPUT
-; NO-INPUT: No input files provided
-;
-; Create a simple bitcode file for subsequent tests
+
+target datalayout = 
"e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
+target triple = "spirv64"
+
+; Build a bitcode input used by every RUN line below.
 ; RUN: llvm-as %s -o %t.bc
-;
+
 ; Test --print-linked-module
 ; RUN: clang-sycl-linker %t.bc --print-linked-module -o %t.out > %t.ll
 ; RUN: FileCheck %s --check-prefix=PRINT-LINKED < %t.ll
 ; PRINT-LINKED: target triple = "spirv64"
-;
+
 ; RUN: rm -rf %t.dir && mkdir -p %t.dir
-;
-; Test --spirv-dump-device-code (creates the directory if missing and copies
-; SPIR-V output into it)
+
+; Test --spirv-dump-device-code: the linker creates the (nested) directory if
+; missing and copies the generated SPIR-V file there. Files are named
+; "<output-stem>_<index>.spv" and shared across split modules.
 ; RUN: clang-sycl-linker %t.bc --spirv-dump-device-code=%t.dir/nested -o 
out.spv
-; RUN: ls %t.dir/nested/out_0.spv | count 1
-;
-; Test --spirv-dump-device-code with no value (fallback to ./)
+; RUN: test -f %t.dir/nested/out_0.spv
+
+; Test --spirv-dump-device-code with an empty value: falls back to the current
+; working directory, so we cd into a scratch dir first to keep artifacts
+; isolated and avoid polluting %t.dir's parent.
 ; RUN: mkdir -p %t.dir/fallback
 ; RUN: cd %t.dir/fallback && clang-sycl-linker %t.bc --spirv-dump-device-code= 
-o out.spv
-; RUN: ls %t.dir/fallback/out_0.spv | count 1
-;
-; Test --save-temps (keeps intermediate .bc files in current directory)
-; RUN: mkdir -p %t.dir/save-temps
-; RUN: cd %t.dir/save-temps && clang-sycl-linker %t.bc --save-temps -o out.spv
-; RUN: ls %t.dir/save-temps/out.spv-*.bc | count 1
+; RUN: test -f %t.dir/fallback/out_0.spv
 
-target datalayout = 
"e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
-target triple = "spirv64"
+; Test --spirv-dump-device-code where the path cannot be created (a regular
+; file blocks it). Expect a clear diagnostic rather than a deeper failure.
+; RUN: rm -rf %t.blocker && touch %t.blocker
+; RUN: not clang-sycl-linker %t.bc --spirv-dump-device-code=%t.blocker/sub -o 
%t.out 2>&1 \
+; RUN:   | FileCheck %s --check-prefix=DUMP-DIR-ERR
+; DUMP-DIR-ERR: cannot create SPIR-V dump directory '{{.*}}.blocker/sub'
 
+; Test --save-temps: keeps intermediate .bc files in the current directory, so
+; cd into a scratch dir to make the resulting paths predictable.
+; RUN: mkdir -p %t.dir/save-temps
+; RUN: cd %t.dir/save-temps && clang-sycl-linker %t.bc --save-temps -o out.spv
+; RUN: ls %t.dir/save-temps/out.spv-*.bc
diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp 
b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index a535b68e4f997..8d8599c3a9eb8 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -186,22 +186,22 @@ Error executeCommands(StringRef ExecutablePath, 
ArrayRef<StringRef> Args) {
 Expected<SmallVector<std::string>> getInput(const ArgList &Args) {
   // Collect all input bitcode files to be passed to the device linking stage.
   SmallVector<std::string> BitcodeFiles;
-  for (const opt::Arg *Arg : Args.filtered(OPT_INPUT)) {
-    std::optional<std::string> Filename = std::string(Arg->getValue());
-    if (!Filename || !sys::fs::exists(*Filename) ||
-        sys::fs::is_directory(*Filename))
-      continue;
+  auto Inputs = Args.filtered(OPT_INPUT);
+  if (Inputs.empty())
+    return createStringError("No input files provided");
+  for (const opt::Arg *Arg : Inputs) {
+    StringRef Filename = Arg->getValue();
+    if (!sys::fs::exists(Filename) || sys::fs::is_directory(Filename))
+      return createStringError("Input file '" + Filename + "' does not exist");
     file_magic Magic;
-    if (auto EC = identify_magic(*Filename, Magic))
-      return createStringError("Failed to open file " + *Filename);
+    if (auto EC = identify_magic(Filename, Magic))
+      return createStringError("Failed to open file " + Filename);
     // TODO: Current use case involves LLVM IR bitcode files as input.
     // This will be extended to support SPIR-V IR files.
     if (Magic != file_magic::bitcode)
-      return createStringError("Unsupported file type");
-    BitcodeFiles.push_back(*Filename);
+      return createStringError("Unsupported file type for '" + Filename + "'");
+    BitcodeFiles.push_back(std::string(Filename));
   }
-  if (BitcodeFiles.empty())
-    return createStringError("No input files provided");
   return BitcodeFiles;
 }
 
@@ -714,7 +714,7 @@ Error runSYCLLink(ArrayRef<std::string> Files, const 
ArgList &Args) {
                                Result.TargetTriple, Args, CodeGenFile, C))
       return Err;
 
-    if (!SPIRVDumpDir.empty()) {
+    if (!SPIRVDumpDir.empty() && !DryRun) {
       SmallString<128> DumpFile(SPIRVDumpDir);
       sys::path::append(DumpFile, sys::path::filename(CodeGenFile));
       if (std::error_code EC = sys::fs::copy_file(CodeGenFile, DumpFile))
@@ -807,19 +807,23 @@ int main(int argc, char **argv) {
     reportError(createStringError("Output file must be specified"));
   OutputFile = Args.getLastArgValue(OPT_o);
 
-  if (auto *A = Args.getLastArg(OPT_spirv_dump_device_code_EQ)) {
-    StringRef V = A->getValue();
-    SPIRVDumpDir = V.empty() ? "." : V;
-    if (std::error_code EC = sys::fs::create_directories(SPIRVDumpDir))
-      reportError(createStringError(
-          EC, "cannot create SPIR-V dump directory '" + SPIRVDumpDir + "'"));
-  }
-
   // Get the input files to pass to the linking stage.
   auto FilesOrErr = getInput(Args);
   if (!FilesOrErr)
     reportError(FilesOrErr.takeError());
 
+  if (auto *A = Args.getLastArg(OPT_spirv_dump_device_code_EQ)) {
+    StringRef V = A->getValue();
+    SPIRVDumpDir = V.empty() ? "." : V;
+    // The directory is shared across all split modules, which use the
+    // "<output-stem>_<index>.spv" naming scheme. Concurrent invocations
+    // sharing a dump dir may overwrite each other's files.
+    if (!DryRun)
+      if (std::error_code EC = sys::fs::create_directories(SPIRVDumpDir))
+        reportError(createStringError(
+            EC, "cannot create SPIR-V dump directory '" + SPIRVDumpDir + "'"));
+  }
+
   // Run SYCL linking process on the generated inputs.
   if (Error Err = runSYCLLink(*FilesOrErr, Args))
     reportError(std::move(Err));

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

Reply via email to