[clang] [clang-sycl-linker] Make JIT/AOT temp files land relative to cwd with unique names (PR #224506)
Wenju He via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 18 22:39:00 PDT 2026
https://github.com/wenju-he updated https://github.com/llvm/llvm-project/pull/224506
>From f5d87ef6e00a7266be4e7a1e7d2a36ef32067c18 Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Fri, 18 Sep 2026 05:32:51 +0200
Subject: [PATCH 1/3] [clang-sycl-linker] Make AOT temp files land relative to
cwd, not -o's dir
Derive the CodeGen/AOT Stem from -o's basename instead of its full
path. Previously the full path put .spv/.out in -o's directory while
.bc (via createTempFile's cwd-relative prefix) landed in cwd,
splitting a single run's -save-temps intermediates across two
locations. This aligns CodeGen/AOT with the cwd-relative convention
.bc already uses.
Co-Authored-By: Claude Sonnet 5 <noreply at anthropic.com>
---
clang/test/OffloadTools/clang-sycl-linker/basic.ll | 8 ++++++++
clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/clang/test/OffloadTools/clang-sycl-linker/basic.ll b/clang/test/OffloadTools/clang-sycl-linker/basic.ll
index 00e3bba8d297e..09eced37fb894 100644
--- a/clang/test/OffloadTools/clang-sycl-linker/basic.ll
+++ b/clang/test/OffloadTools/clang-sycl-linker/basic.ll
@@ -135,6 +135,14 @@
; AOT-INTEL-CPU-NEXT: sycl-bundle: image kind: o, triple: spirv64, arch: graniterapids
; AOT-INTEL-CPU-NOT: {{.+}}
;
+; Test that AOT temp file names ("<stem>_<index>.spv"/".out") are derived from
+; -o's basename only, not its full path, so they land in the current directory.
+; RUN: mkdir -p %t/outdir
+; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit -arch=bmg_g21 %t/input1.bc -o %t/outdir/nested.out 2>&1 \
+; RUN: | FileCheck %s --check-prefix=AOT-STEM-BASENAME
+; AOT-STEM-BASENAME: LLVM backend: input: {{.*}}.bc, output: nested_0.spv
+; AOT-STEM-BASENAME-NEXT: "{{.*}}ocloc{{.*}}" {{.*}}-output nested_0.out -file nested_0.spv
+;
; Check that the output file must be specified.
; RUN: not clang-sycl-linker --dry-run %t/input1.bc %t/input2.bc 2>&1 \
; RUN: | FileCheck %s --check-prefix=NOOUTPUT
diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index 70afc6d6c4cea..a63c30b6262c3 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -985,7 +985,7 @@ static Error runSYCLLink(ArrayRef<std::unique_ptr<MemoryBuffer>> Inputs,
// Code generation step.
for (size_t I = 0, E = SplitModules.size(); I != E; ++I) {
- StringRef Stem = OutputFile.rsplit('.').first;
+ StringRef Stem = sys::path::filename(OutputFile).rsplit('.').first;
std::string CodeGenFile = (Stem + "_" + Twine(I) + OutputFileNameExt).str();
if (Error Err = runCodeGen(SplitModules[I].ModuleFilePath,
>From 32e8db1af6dbb7945f1372998200f53b2b00ad52 Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Fri, 18 Sep 2026 06:49:37 +0200
Subject: [PATCH 2/3] [clang-sycl-linker] Give AOT/SPV temp files
per-invocation uniqueness
Route the SPIR-V translation and AOT compile outputs through
createTempFile instead of building "<stem>_<index>.ext" directly, so
parallel invocations that share an output basename (but differ in
output directory) don't collide on the same cwd-relative intermediate
files. The --spirv-dump-device-code copy still uses the clean stem
name for readability.
Co-Authored-By: Claude Sonnet 5 <noreply at anthropic.com>
---
.../OffloadTools/clang-sycl-linker/basic.ll | 22 ++++++++++---------
.../clang-sycl-linker/split-mode.ll | 12 +++++-----
.../clang-sycl-linker/ClangSYCLLinker.cpp | 15 ++++++++++---
3 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/clang/test/OffloadTools/clang-sycl-linker/basic.ll b/clang/test/OffloadTools/clang-sycl-linker/basic.ll
index 09eced37fb894..a9e62bbbd82bb 100644
--- a/clang/test/OffloadTools/clang-sycl-linker/basic.ll
+++ b/clang/test/OffloadTools/clang-sycl-linker/basic.ll
@@ -29,7 +29,7 @@
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit %t/input1.bc %t/input2.bc -o %t/spirv.out 2>&1 \
; RUN: | FileCheck %s --check-prefix=SIMPLE-FO
; SIMPLE-FO: link: inputs: {{.*}}.bc, {{.*}}.bc output: [[LLVMLINKOUT:.*]].bc
-; SIMPLE-FO-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}_0.spv
+; SIMPLE-FO-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}_0{{.*}}.spv
; SIMPLE-FO-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SIMPLE-FO-NOT: {{.+}}
;
@@ -41,7 +41,7 @@
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit %t/input1.bc %t/input2.bc --library-path=%t/libs --whole-archive -l device -o /dev/null 2>&1 \
; RUN: | FileCheck %s --check-prefix=DEVLIBS
; DEVLIBS: link: inputs: {{.*}}.bc, {{.*}}.bc, {{.*}}libdevice.a(lib1.bc), {{.*}}libdevice.a(lib2.bc) output: [[LLVMLINKOUT:.*]].bc
-; DEVLIBS-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}_0.spv
+; DEVLIBS-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}_0{{.*}}.spv
; DEVLIBS-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; DEVLIBS-NOT: {{.+}}
;
@@ -113,8 +113,8 @@
; RUN: --ocloc-options="-a -b" \
; RUN: | FileCheck %s --check-prefix=AOT-INTEL-GPU
; AOT-INTEL-GPU: link: inputs: {{.*}}.bc, {{.*}}.bc output: [[LLVMLINKOUT:.*]].bc
-; AOT-INTEL-GPU-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: [[SPIRVTRANSLATIONOUT:.*]]_0.spv
-; AOT-INTEL-GPU-NEXT: "{{.*}}ocloc{{.*}}" {{.*}}-device bmg_g21 -a -b {{.*}}-output [[SPIRVTRANSLATIONOUT]]_0.out -file [[SPIRVTRANSLATIONOUT]]_0.spv
+; AOT-INTEL-GPU-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: [[SPIRVTRANSLATIONOUT:.*]]_0{{.*}}.spv
+; AOT-INTEL-GPU-NEXT: "{{.*}}ocloc{{.*}}" {{.*}}-device bmg_g21 -a -b {{.*}}-output [[SPIRVTRANSLATIONOUT]]_0{{.*}}.out -file [[SPIRVTRANSLATIONOUT]]_0{{.*}}.spv
; AOT-INTEL-GPU-NEXT: sycl-bundle: image kind: o, triple: spirv64, arch: bmg_g21
; AOT-INTEL-GPU-NOT: {{.+}}
;
@@ -130,18 +130,20 @@
; RUN: --opencl-aot-options="-a -b" \
; RUN: | FileCheck %s --check-prefix=AOT-INTEL-CPU
; AOT-INTEL-CPU: link: inputs: {{.*}}.bc, {{.*}}.bc output: [[LLVMLINKOUT:.*]].bc
-; AOT-INTEL-CPU-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: [[SPIRVTRANSLATIONOUT:.*]]_0.spv
-; AOT-INTEL-CPU-NEXT: "{{.*}}opencl-aot{{.*}}" {{.*}}--device=cpu -a -b {{.*}}-o [[SPIRVTRANSLATIONOUT]]_0.out [[SPIRVTRANSLATIONOUT]]_0.spv
+; AOT-INTEL-CPU-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: [[SPIRVTRANSLATIONOUT:.*]]_0{{.*}}.spv
+; AOT-INTEL-CPU-NEXT: "{{.*}}opencl-aot{{.*}}" {{.*}}--device=cpu -a -b {{.*}}-o [[SPIRVTRANSLATIONOUT]]_0{{.*}}.out [[SPIRVTRANSLATIONOUT]]_0{{.*}}.spv
; AOT-INTEL-CPU-NEXT: sycl-bundle: image kind: o, triple: spirv64, arch: graniterapids
; AOT-INTEL-CPU-NOT: {{.+}}
;
-; Test that AOT temp file names ("<stem>_<index>.spv"/".out") are derived from
-; -o's basename only, not its full path, so they land in the current directory.
+; Test that AOT temp file names ("<stem>_<index>-<unique>.spv"/".out") are
+; derived from -o's basename only, not its full path, so they land in the
+; current directory (with a unique suffix to avoid collisions between
+; concurrent invocations sharing an output basename).
; RUN: mkdir -p %t/outdir
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit -arch=bmg_g21 %t/input1.bc -o %t/outdir/nested.out 2>&1 \
; RUN: | FileCheck %s --check-prefix=AOT-STEM-BASENAME
-; AOT-STEM-BASENAME: LLVM backend: input: {{.*}}.bc, output: nested_0.spv
-; AOT-STEM-BASENAME-NEXT: "{{.*}}ocloc{{.*}}" {{.*}}-output nested_0.out -file nested_0.spv
+; AOT-STEM-BASENAME: LLVM backend: input: {{.*}}.bc, output: [[STEM:nested_0]]{{.*}}.spv
+; AOT-STEM-BASENAME-NEXT: "{{.*}}ocloc{{.*}}" {{.*}}-output [[STEM]]{{.*}}.out -file [[STEM]]{{.*}}.spv
;
; Check that the output file must be specified.
; RUN: not clang-sycl-linker --dry-run %t/input1.bc %t/input2.bc 2>&1 \
diff --git a/clang/test/OffloadTools/clang-sycl-linker/split-mode.ll b/clang/test/OffloadTools/clang-sycl-linker/split-mode.ll
index 6aa05fa9b8a50..f3af0e53fd3d5 100644
--- a/clang/test/OffloadTools/clang-sycl-linker/split-mode.ll
+++ b/clang/test/OffloadTools/clang-sycl-linker/split-mode.ll
@@ -13,7 +13,7 @@
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit %t.bc -o %t-none.out 2>&1 \
; RUN: | FileCheck %s --check-prefix=SPLIT-NONE
; SPLIT-NONE: link: inputs: {{.*}}.bc output: [[LLVMLINKOUT:.*]].bc
-; SPLIT-NONE-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}_0.spv
+; SPLIT-NONE-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}_0{{.*}}.spv
; SPLIT-NONE-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SPLIT-NONE-NOT: {{.+}}
;
@@ -25,9 +25,9 @@
; SPLIT-KERNEL-NEXT: [[SPLIT0:.*]].bc [kernel_c ]
; SPLIT-KERNEL-NEXT: [[SPLIT1:.*]].bc [kernel_b ]
; SPLIT-KERNEL-NEXT: [[SPLIT2:.*]].bc [kernel_a ]
-; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT0]].bc, output: {{.*}}_0.spv
-; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT1]].bc, output: {{.*}}_1.spv
-; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT2]].bc, output: {{.*}}_2.spv
+; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT0]].bc, output: {{.*}}_0{{.*}}.spv
+; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT1]].bc, output: {{.*}}_1{{.*}}.spv
+; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT2]].bc, output: {{.*}}_2{{.*}}.spv
; SPLIT-KERNEL-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SPLIT-KERNEL-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SPLIT-KERNEL-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
@@ -47,8 +47,8 @@
; SPLIT-SRC-NEXT: sycl-module-split: input: [[LLVMLINKOUT]].bc, mode: translation_unit
; SPLIT-SRC-NEXT: [[S0:.*]].bc [kernel_b kernel_c ]
; SPLIT-SRC-NEXT: [[S1:.*]].bc [kernel_a ]
-; SPLIT-SRC-NEXT: LLVM backend: input: [[S0]].bc, output: {{.*}}_0.spv
-; SPLIT-SRC-NEXT: LLVM backend: input: [[S1]].bc, output: {{.*}}_1.spv
+; SPLIT-SRC-NEXT: LLVM backend: input: [[S0]].bc, output: {{.*}}_0{{.*}}.spv
+; SPLIT-SRC-NEXT: LLVM backend: input: [[S1]].bc, output: {{.*}}_1{{.*}}.spv
; SPLIT-SRC-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SPLIT-SRC-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SPLIT-SRC-NOT: {{.+}}
diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index a63c30b6262c3..8604c3c26d98c 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -986,7 +986,13 @@ static Error runSYCLLink(ArrayRef<std::unique_ptr<MemoryBuffer>> Inputs,
// Code generation step.
for (size_t I = 0, E = SplitModules.size(); I != E; ++I) {
StringRef Stem = sys::path::filename(OutputFile).rsplit('.').first;
- std::string CodeGenFile = (Stem + "_" + Twine(I) + OutputFileNameExt).str();
+ SmallString<64> Prefix;
+ (Stem + "_" + Twine(I)).toVector(Prefix);
+ auto CodeGenFileOrErr =
+ createTempFile(Args, Prefix, OutputFileNameExt.drop_front());
+ if (!CodeGenFileOrErr)
+ return CodeGenFileOrErr.takeError();
+ StringRef CodeGenFile = *CodeGenFileOrErr;
if (Error Err = runCodeGen(SplitModules[I].ModuleFilePath,
Result.TargetTriple, Args, CodeGenFile, C))
@@ -994,14 +1000,17 @@ static Error runSYCLLink(ArrayRef<std::unique_ptr<MemoryBuffer>> Inputs,
if (!SPIRVDumpDir.empty() && !DryRun) {
SmallString<128> DumpFile(SPIRVDumpDir);
- sys::path::append(DumpFile, sys::path::filename(CodeGenFile));
+ sys::path::append(DumpFile, Twine(Prefix) + OutputFileNameExt);
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();
+ auto AOTFileOrErr = createTempFile(Args, Prefix, "out");
+ if (!AOTFileOrErr)
+ return AOTFileOrErr.takeError();
+ StringRef AOTFile = *AOTFileOrErr;
if (Error Err = runAOTCompile(CodeGenFile, AOTFile, Args))
return Err;
SplitModules[I].ModuleFilePath = AOTFile;
>From a5e80e11bd8eb75bd1f56e1117ca5de3a7b9b3ec Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Sat, 19 Sep 2026 07:38:42 +0200
Subject: [PATCH 3/3] [clang-sycl-linker] Drop redundant per-split index from
temp file names
The random suffix createTempFile() already adds makes the "_<index>"
prefix unnecessary for CodeGen/AOT temp files, so drop it there. Keep
it for --spirv-dump-device-code output, which has no random suffix and
still needs the index to avoid one split's dump overwriting another's.
Also rm -rf a reused %t/outdir test directory before recreating it.
Co-Authored-By: Claude Sonnet 5 <noreply at anthropic.com>
---
.../OffloadTools/clang-sycl-linker/basic.ll | 20 +++++++++----------
.../clang-sycl-linker/split-mode.ll | 12 +++++------
.../clang-sycl-linker/ClangSYCLLinker.cpp | 13 ++++++------
3 files changed, 23 insertions(+), 22 deletions(-)
diff --git a/clang/test/OffloadTools/clang-sycl-linker/basic.ll b/clang/test/OffloadTools/clang-sycl-linker/basic.ll
index a9e62bbbd82bb..8db9c797d860c 100644
--- a/clang/test/OffloadTools/clang-sycl-linker/basic.ll
+++ b/clang/test/OffloadTools/clang-sycl-linker/basic.ll
@@ -29,7 +29,7 @@
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit %t/input1.bc %t/input2.bc -o %t/spirv.out 2>&1 \
; RUN: | FileCheck %s --check-prefix=SIMPLE-FO
; SIMPLE-FO: link: inputs: {{.*}}.bc, {{.*}}.bc output: [[LLVMLINKOUT:.*]].bc
-; SIMPLE-FO-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}_0{{.*}}.spv
+; SIMPLE-FO-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}.spv
; SIMPLE-FO-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SIMPLE-FO-NOT: {{.+}}
;
@@ -41,7 +41,7 @@
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit %t/input1.bc %t/input2.bc --library-path=%t/libs --whole-archive -l device -o /dev/null 2>&1 \
; RUN: | FileCheck %s --check-prefix=DEVLIBS
; DEVLIBS: link: inputs: {{.*}}.bc, {{.*}}.bc, {{.*}}libdevice.a(lib1.bc), {{.*}}libdevice.a(lib2.bc) output: [[LLVMLINKOUT:.*]].bc
-; DEVLIBS-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}_0{{.*}}.spv
+; DEVLIBS-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}.spv
; DEVLIBS-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; DEVLIBS-NOT: {{.+}}
;
@@ -113,8 +113,8 @@
; RUN: --ocloc-options="-a -b" \
; RUN: | FileCheck %s --check-prefix=AOT-INTEL-GPU
; AOT-INTEL-GPU: link: inputs: {{.*}}.bc, {{.*}}.bc output: [[LLVMLINKOUT:.*]].bc
-; AOT-INTEL-GPU-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: [[SPIRVTRANSLATIONOUT:.*]]_0{{.*}}.spv
-; AOT-INTEL-GPU-NEXT: "{{.*}}ocloc{{.*}}" {{.*}}-device bmg_g21 -a -b {{.*}}-output [[SPIRVTRANSLATIONOUT]]_0{{.*}}.out -file [[SPIRVTRANSLATIONOUT]]_0{{.*}}.spv
+; AOT-INTEL-GPU-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: [[STEM:.*]]-{{[0-9a-f]+}}.spv
+; AOT-INTEL-GPU-NEXT: "{{.*}}ocloc{{.*}}" {{.*}}-device bmg_g21 -a -b {{.*}}-output [[STEM]]-{{[0-9a-f]+}}.out -file [[STEM]]-{{[0-9a-f]+}}.spv
; AOT-INTEL-GPU-NEXT: sycl-bundle: image kind: o, triple: spirv64, arch: bmg_g21
; AOT-INTEL-GPU-NOT: {{.+}}
;
@@ -130,19 +130,19 @@
; RUN: --opencl-aot-options="-a -b" \
; RUN: | FileCheck %s --check-prefix=AOT-INTEL-CPU
; AOT-INTEL-CPU: link: inputs: {{.*}}.bc, {{.*}}.bc output: [[LLVMLINKOUT:.*]].bc
-; AOT-INTEL-CPU-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: [[SPIRVTRANSLATIONOUT:.*]]_0{{.*}}.spv
-; AOT-INTEL-CPU-NEXT: "{{.*}}opencl-aot{{.*}}" {{.*}}--device=cpu -a -b {{.*}}-o [[SPIRVTRANSLATIONOUT]]_0{{.*}}.out [[SPIRVTRANSLATIONOUT]]_0{{.*}}.spv
+; AOT-INTEL-CPU-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: [[STEM:.*]]-{{[0-9a-f]+}}.spv
+; AOT-INTEL-CPU-NEXT: "{{.*}}opencl-aot{{.*}}" {{.*}}--device=cpu -a -b {{.*}}-o [[STEM]]-{{[0-9a-f]+}}.out [[STEM]]-{{[0-9a-f]+}}.spv
; AOT-INTEL-CPU-NEXT: sycl-bundle: image kind: o, triple: spirv64, arch: graniterapids
; AOT-INTEL-CPU-NOT: {{.+}}
;
-; Test that AOT temp file names ("<stem>_<index>-<unique>.spv"/".out") are
-; derived from -o's basename only, not its full path, so they land in the
+; Test that AOT temp file names ("<stem>-<unique>.spv"/"<stem>-<unique>.out")
+; are derived from -o's basename only, not its full path, so they land in the
; current directory (with a unique suffix to avoid collisions between
; concurrent invocations sharing an output basename).
-; RUN: mkdir -p %t/outdir
+; RUN: rm -rf %t/outdir && mkdir -p %t/outdir
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit -arch=bmg_g21 %t/input1.bc -o %t/outdir/nested.out 2>&1 \
; RUN: | FileCheck %s --check-prefix=AOT-STEM-BASENAME
-; AOT-STEM-BASENAME: LLVM backend: input: {{.*}}.bc, output: [[STEM:nested_0]]{{.*}}.spv
+; AOT-STEM-BASENAME: LLVM backend: input: {{.*}}.bc, output: [[STEM:nested]]{{.*}}.spv
; AOT-STEM-BASENAME-NEXT: "{{.*}}ocloc{{.*}}" {{.*}}-output [[STEM]]{{.*}}.out -file [[STEM]]{{.*}}.spv
;
; Check that the output file must be specified.
diff --git a/clang/test/OffloadTools/clang-sycl-linker/split-mode.ll b/clang/test/OffloadTools/clang-sycl-linker/split-mode.ll
index f3af0e53fd3d5..7bc227aafc007 100644
--- a/clang/test/OffloadTools/clang-sycl-linker/split-mode.ll
+++ b/clang/test/OffloadTools/clang-sycl-linker/split-mode.ll
@@ -13,7 +13,7 @@
; RUN: clang-sycl-linker --dry-run -v --module-split-mode=link_unit %t.bc -o %t-none.out 2>&1 \
; RUN: | FileCheck %s --check-prefix=SPLIT-NONE
; SPLIT-NONE: link: inputs: {{.*}}.bc output: [[LLVMLINKOUT:.*]].bc
-; SPLIT-NONE-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}_0{{.*}}.spv
+; SPLIT-NONE-NEXT: LLVM backend: input: [[LLVMLINKOUT]].bc, output: {{.*}}.spv
; SPLIT-NONE-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SPLIT-NONE-NOT: {{.+}}
;
@@ -25,9 +25,9 @@
; SPLIT-KERNEL-NEXT: [[SPLIT0:.*]].bc [kernel_c ]
; SPLIT-KERNEL-NEXT: [[SPLIT1:.*]].bc [kernel_b ]
; SPLIT-KERNEL-NEXT: [[SPLIT2:.*]].bc [kernel_a ]
-; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT0]].bc, output: {{.*}}_0{{.*}}.spv
-; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT1]].bc, output: {{.*}}_1{{.*}}.spv
-; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT2]].bc, output: {{.*}}_2{{.*}}.spv
+; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT0]].bc, output: {{.*}}.spv
+; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT1]].bc, output: {{.*}}.spv
+; SPLIT-KERNEL-NEXT: LLVM backend: input: [[SPLIT2]].bc, output: {{.*}}.spv
; SPLIT-KERNEL-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SPLIT-KERNEL-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SPLIT-KERNEL-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
@@ -47,8 +47,8 @@
; SPLIT-SRC-NEXT: sycl-module-split: input: [[LLVMLINKOUT]].bc, mode: translation_unit
; SPLIT-SRC-NEXT: [[S0:.*]].bc [kernel_b kernel_c ]
; SPLIT-SRC-NEXT: [[S1:.*]].bc [kernel_a ]
-; SPLIT-SRC-NEXT: LLVM backend: input: [[S0]].bc, output: {{.*}}_0{{.*}}.spv
-; SPLIT-SRC-NEXT: LLVM backend: input: [[S1]].bc, output: {{.*}}_1{{.*}}.spv
+; SPLIT-SRC-NEXT: LLVM backend: input: [[S0]].bc, output: {{.*}}.spv
+; SPLIT-SRC-NEXT: LLVM backend: input: [[S1]].bc, output: {{.*}}.spv
; SPLIT-SRC-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SPLIT-SRC-NEXT: sycl-bundle: image kind: spv, triple: spirv64, arch: {{$}}
; SPLIT-SRC-NOT: {{.+}}
diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
index 8604c3c26d98c..7cfe6200783ef 100644
--- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
+++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp
@@ -984,12 +984,10 @@ static Error runSYCLLink(ArrayRef<std::unique_ptr<MemoryBuffer>> Inputs,
StringRef OutputFileNameExt = ".spv";
// Code generation step.
+ StringRef Stem = sys::path::filename(OutputFile).rsplit('.').first;
for (size_t I = 0, E = SplitModules.size(); I != E; ++I) {
- StringRef Stem = sys::path::filename(OutputFile).rsplit('.').first;
- SmallString<64> Prefix;
- (Stem + "_" + Twine(I)).toVector(Prefix);
auto CodeGenFileOrErr =
- createTempFile(Args, Prefix, OutputFileNameExt.drop_front());
+ createTempFile(Args, Stem, OutputFileNameExt.drop_front());
if (!CodeGenFileOrErr)
return CodeGenFileOrErr.takeError();
StringRef CodeGenFile = *CodeGenFileOrErr;
@@ -999,15 +997,18 @@ static Error runSYCLLink(ArrayRef<std::unique_ptr<MemoryBuffer>> Inputs,
return Err;
if (!SPIRVDumpDir.empty() && !DryRun) {
+ // The dumped file doesn't get the unique suffix that createTempFile()
+ // adds, so index it explicitly to avoid one split's dump overwriting
+ // another's.
SmallString<128> DumpFile(SPIRVDumpDir);
- sys::path::append(DumpFile, Twine(Prefix) + OutputFileNameExt);
+ sys::path::append(DumpFile, Stem + "_" + Twine(I) + OutputFileNameExt);
if (std::error_code EC = sys::fs::copy_file(CodeGenFile, DumpFile))
return createFileError(DumpFile, EC);
}
SplitModules[I].ModuleFilePath = CodeGenFile;
if (IsAOTCompileNeeded) {
- auto AOTFileOrErr = createTempFile(Args, Prefix, "out");
+ auto AOTFileOrErr = createTempFile(Args, Stem, "out");
if (!AOTFileOrErr)
return AOTFileOrErr.takeError();
StringRef AOTFile = *AOTFileOrErr;
More information about the cfe-commits
mailing list