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
