From 93296970ac814ddab6c81b1e80e15f829008fa30 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Thu, 18 Sep 2025 14:49:50 +0000 Subject: [PATCH 1/9] [SYCL] Fix handling of comma separated arch value when calling clang-offload-packager --- clang/lib/Driver/ToolChains/Clang.cpp | 18 ++++++++++++++++-- .../test/Driver/sycl-ftarget-compile-fast.cpp | 8 +++++++- clang/test/Driver/sycl-offload-new-driver.c | 17 ++++++++++++++++- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 70e849d37986a..c5267a83a7853 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -10314,9 +10314,21 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, File = C.getArgs().MakeArgString("@" + File); StringRef Arch; + std::string TransformedArch; if (OffloadAction->getOffloadingArch()) { if (TC->getTripleString() == "spir64_gen-unknown-unknown") { - Arch = mapIntelGPUArchName(OffloadAction->getOffloadingArch()); + // When compiling like -fsycl-targets=spir64_gen -Xsycl-target-backend + // "-device pvc,bdw", the offloading arch will be "pvc,bdw", which + // contains a comma. We need to transform it to "arch=pvc,arch=bdw" when + // passing to clang-offload-packager. + Arch = OffloadAction->getOffloadingArch(); + SmallVector Archs; + Arch.split(Archs, ','); + for (StringRef &A : Archs) { + A = mapIntelGPUArchName(A); + } + TransformedArch = llvm::join(Archs, ",arch="); + Arch = TransformedArch; } else { Arch = OffloadAction->getOffloadingArch(); } @@ -10366,7 +10378,9 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, AL += " "; AL += A; } - Parts.emplace_back(C.getArgs().MakeArgString(Twine(Opt) + AL)); + for (StringRef Split : llvm::split(AL, ',')) { + Parts.emplace_back(C.getArgs().MakeArgString(Twine(Opt) + Split)); + } }; const ArgList &Args = C.getArgsForToolChain(nullptr, StringRef(), Action::OFK_SYCL); diff --git a/clang/test/Driver/sycl-ftarget-compile-fast.cpp b/clang/test/Driver/sycl-ftarget-compile-fast.cpp index f9ba300a9a821..5f5bfa91f289c 100644 --- a/clang/test/Driver/sycl-ftarget-compile-fast.cpp +++ b/clang/test/Driver/sycl-ftarget-compile-fast.cpp @@ -7,8 +7,14 @@ // RUN: -fsycl-targets=spir64_gen -ftarget-compile-fast %s 2>&1 \ // RUN: | FileCheck -check-prefix=TARGET_COMPILE_FAST_GEN %s + +// Due to how clang-offload-packager works, if we want a value in a key-value pair to +// have a comma, we need to specify the key twice, once for each part of the value +// separated by the comma. clang-offload-packager will then combine the two parts into a single +// value with a comma in between. // TARGET_COMPILE_FAST_GEN: clang-offload-packager -// TARGET_COMPILE_FAST_GEN: compile-opts={{.*}}-options -igc_opts 'PartitionUnit=1,SubroutineThreshold=50000' +// TARGET_COMPILE_FAST_GEN: compile-opts={{.*}}-options -igc_opts 'PartitionUnit=1 +// TARGET_COMPILE_FAST_GEN-SAME: compile-opts=SubroutineThreshold=50000' // RUN: %clang -### -target x86_64-unknown-linux-gnu -fsycl --offload-new-driver \ // RUN: -ftarget-compile-fast %s 2>&1 \ diff --git a/clang/test/Driver/sycl-offload-new-driver.c b/clang/test/Driver/sycl-offload-new-driver.c index 51585ec738516..943f17a1dc366 100644 --- a/clang/test/Driver/sycl-offload-new-driver.c +++ b/clang/test/Driver/sycl-offload-new-driver.c @@ -187,7 +187,7 @@ // RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ // RUN: -Xsycl-target-backend=spir64_gen "-device pvc,bdw" %s 2>&1 \ // RUN: | FileCheck -check-prefix COMMA_FILE %s -// COMMA_FILE: clang-offload-packager{{.*}} "--image=file={{.*}}pvc@bdw{{.*}},triple=spir64_gen-unknown-unknown,arch=pvc,bdw,kind=sycl,compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode" +// COMMA_FILE: clang-offload-packager{{.*}} "--image=file={{.*}}pvc@bdw{{.*}},triple=spir64_gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl,compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode" /// Verify the arch value for the packager is populated with different /// scenarios for spir64_gen @@ -211,6 +211,21 @@ // RUN: | FileCheck -check-prefix ARCH_CHECK %s // ARCH_CHECK: clang-offload-packager{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=bdw,kind=sycl{{.*}}" +// Verify when a comma-separated list of architectures is provided in -device, they are +// passed to clang-offload-packager correctly +// RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ +// RUN: -Xsycl-target-backend "-device pvc,bdw" %s 2>&1 \ +// RUN: | FileCheck -check-prefix MULTI_ARCH %s +// MULTI_ARCH: clang-offload-packager{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl +// MULTI_ARCH-SAME: compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode -device pvc,compile-opts=bdw" + +// Verify that the driver correctly handles link-opt and compile-opt values with commas +// RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ +// RUN: -Xsycl-target-backend "-device bdw -FOO a,b" \ +// RUN: -Xsycl-target-linker "-BAR x,y" %s 2>&1 \ +// RUN: | FileCheck -check-prefix COMMA_OPTS %s +// COMMA_OPTS: clang-offload-packager{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=bdw,kind=sycl,compile-opts=-device bdw -FOO a,compile-opts=b,link-opts=-BAR x,link-opts=y" + /// Verify that --cuda-path is passed to clang-linker-wrapper for SYCL offload // RUN: %clangxx -fsycl -### -fsycl-targets=nvptx64-nvidia-cuda -fno-sycl-libspirv \ // RUN: --cuda-gpu-arch=sm_20 --cuda-path=%S/Inputs/CUDA_80/usr/local/cuda %s \ From 3c38506e87cb1fdeabcab7e5b6ec5f2de5fa2e31 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Thu, 2 Oct 2025 16:21:09 +0000 Subject: [PATCH 2/9] Address review comments --- clang/lib/Driver/ToolChains/Clang.cpp | 14 ++++++++++++-- clang/test/Driver/sycl-offload-new-driver.c | 10 ++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c5267a83a7853..a02f7c8c9124a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -10355,6 +10355,16 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, "kind=" + Kind.str(), }; + // When compiling like -fsycl-targets=spir64_gen -Xsycl-target-backend + // "-device pvc,bdw", the offloading arch will be "pvc,bdw", which + // contains a comma. We need to transform it to "arch=pvc,arch=bdw" when + // passing to clang-offload-packager. + SmallVector Archs; + Arch.split(Archs, ','); + if (Archs.size() > 1) { + Parts[2] = "arch=" + llvm::join(Archs, ",arch"); + } + if (TC->getDriver().isUsingOffloadLTO()) for (StringRef Feature : FeatureArgs) Parts.emplace_back("feature=" + Feature.str()); @@ -10389,10 +10399,10 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, static_cast(*TC); SYCLTC.AddImpliedTargetArgs(TC->getTriple(), Args, BuildArgs, JA, *HostTC, Arch); - SYCLTC.TranslateBackendTargetArgs(TC->getTriple(), Args, BuildArgs, Arch); + SYCLTC.TranslateBackendTargetArgs(TC->getTriple(), Args, BuildArgs); createArgString("compile-opts="); BuildArgs.clear(); - SYCLTC.TranslateLinkerTargetArgs(TC->getTriple(), Args, BuildArgs, Arch); + SYCLTC.TranslateLinkerTargetArgs(TC->getTriple(), Args, BuildArgs); createArgString("link-opts="); } diff --git a/clang/test/Driver/sycl-offload-new-driver.c b/clang/test/Driver/sycl-offload-new-driver.c index 943f17a1dc366..1831b00944aa9 100644 --- a/clang/test/Driver/sycl-offload-new-driver.c +++ b/clang/test/Driver/sycl-offload-new-driver.c @@ -219,6 +219,16 @@ // MULTI_ARCH: clang-offload-packager{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl // MULTI_ARCH-SAME: compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode -device pvc,compile-opts=bdw" +// RUN: %clangxx -fsycl -### --offload-new-driver \ +// RUN: -fsycl-targets=nvptx64-nvidia-cuda,amdgcn-amd-amdhsa,spir64_gen \ +// RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx908,gfx1010 \ +// RUN: -Xsycl-target-backend=nvptx64-nvidia-cuda --offload-arch=sm_86,sm_87,sm_89 \ +// RUN: -Xsycl-target-backend=spir64_gen "-device pvc,bdw" \ +// RUN: -nogpulib %s 2>&1 | FileCheck -check-prefix=MULTI_ARCH2 %s +// MULTI_ARCH2: clang-offload-packager{{.*}} "--image=file={{.*}}triple=amdgcn-amd-amdhsa,arch=gfx1010,kind=sycl,compile-opts=--offload-arch=gfx908,compile-opts=gfx1010" +// MULTI_ARCH2-SAME: "--image=file={{.*}}triple=nvptx64-nvidia-cuda,arch=sm_86,arch=sm_87,arch=sm_89,kind=sycl,compile-opts=--offload-arch=sm_86,compile-opts=sm_87,compile-opts=sm_89" +// MULTI_ARCH2-SAME: "--image=file={{.*}}triple=spir64-gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl,compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode -device pvc,compile-opts=bdw" + // Verify that the driver correctly handles link-opt and compile-opt values with commas // RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ // RUN: -Xsycl-target-backend "-device bdw -FOO a,b" \ From c8c9cb60ff2f1680f2e47f76b56b2967c529b218 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Thu, 2 Oct 2025 17:43:08 +0000 Subject: [PATCH 3/9] Add -Xsycl-target-linker to test --- clang/test/Driver/sycl-offload-new-driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/test/Driver/sycl-offload-new-driver.c b/clang/test/Driver/sycl-offload-new-driver.c index 661be81d3a3ca..178ad9bcfac64 100644 --- a/clang/test/Driver/sycl-offload-new-driver.c +++ b/clang/test/Driver/sycl-offload-new-driver.c @@ -224,13 +224,14 @@ // RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx908,gfx1010 \ // RUN: -Xsycl-target-backend=nvptx64-nvidia-cuda --offload-arch=sm_86,sm_87,sm_89 \ // RUN: -Xsycl-target-backend=spir64_gen "-device pvc,bdw" \ +// RUN: -Xsycl-target-linker=spir64_gen "-DFOO,BAR" \ // RUN: -nogpulib %s 2>&1 | FileCheck -check-prefix=MULTI_ARCH2 %s // MULTI_ARCH2: clang-offload-packager{{.*}} "--image=file={{.*}}triple=amdgcn-amd-amdhsa,arch=gfx1010,kind=sycl,compile-opts=--offload-arch=gfx908,compile-opts=gfx1010" // MULTI_ARCH2-SAME: "--image=file={{.*}}triple=amdgcn-amd-amdhsa,arch=gfx908,kind=sycl,compile-opts=--offload-arch=gfx908,compile-opts=gfx1010" // MULTI_ARCH2-SAME: "--image=file={{.*}}triple=nvptx64-nvidia-cuda,arch=sm_86,kind=sycl,compile-opts=--offload-arch=sm_86,compile-opts=sm_87,compile-opts=sm_89" // MULTI_ARCH2-SAME: "--image=file={{.*}}triple=nvptx64-nvidia-cuda,arch=sm_87,kind=sycl,compile-opts=--offload-arch=sm_86,compile-opts=sm_87,compile-opts=sm_89" // MULTI_ARCH2-SAME: "--image=file={{.*}}triple=nvptx64-nvidia-cuda,arch=sm_89,kind=sycl,compile-opts=--offload-arch=sm_86,compile-opts=sm_87,compile-opts=sm_89" -// MULTI_ARCH2-SAME: "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl,compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode -device pvc,compile-opts=bdw" +// MULTI_ARCH2-SAME: "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl,compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode -device pvc,compile-opts=bdw,link-opts=-DFOO,link-opts=BAR" // Verify that the driver correctly handles link-opt and compile-opt values with commas // RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ From 30d218e8b7e52dee12ddc3dba9b6f2b14254d22b Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Thu, 6 Nov 2025 23:19:18 +0000 Subject: [PATCH 4/9] Address review comments --- clang/lib/Driver/ToolChains/Clang.cpp | 11 ++++++++--- clang/test/Driver/sycl-offload-new-driver.c | 18 +++++++++++++++++- .../ClangLinkerWrapper.cpp | 5 ++--- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 05680d99d454a..05c2931d0231a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -10235,7 +10235,6 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, File = C.getArgs().MakeArgString("@" + File); StringRef Arch; - std::string TransformedArch; if (OffloadAction->getOffloadingArch()) { if (TC->getTripleString() == "spir64_gen-unknown-unknown") { Arch = mapIntelGPUArchName(OffloadAction->getOffloadingArch()); @@ -10267,8 +10266,10 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, // When compiling like -fsycl-targets=spir64_gen -Xsycl-target-backend // "-device pvc,bdw", the offloading arch will be "pvc,bdw", which - // contains a comma. We need to transform it to "arch=pvc,arch=bdw" when - // passing to clang-offload-packager. + // contains a comma. Because the comma is used to separate fields + // within the --image option, we cannot pass arch=pvc,bdw directly. + // Instead, we if we pass it like arch=pvc,arch=bdw when, then + // clang-offload-packager joins them back to arch=pvc,bdw. SmallVector Archs; Arch.split(Archs, ','); if (Archs.size() > 1) { @@ -10298,6 +10299,10 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, AL += " "; AL += A; } + // As mentioned earlier, we cannot pass a value with commas directly, + // but clang-offload-packager joins multiple occurrences of the same + // option separated by commas, so we split the value on + // all commas and pass them as separate arguments. for (StringRef Split : llvm::split(AL, ',')) { Parts.emplace_back(C.getArgs().MakeArgString(Twine(Opt) + Split)); } diff --git a/clang/test/Driver/sycl-offload-new-driver.c b/clang/test/Driver/sycl-offload-new-driver.c index a86565202f830..a000c1ee1fd29 100644 --- a/clang/test/Driver/sycl-offload-new-driver.c +++ b/clang/test/Driver/sycl-offload-new-driver.c @@ -213,13 +213,29 @@ // ARCH_CHECK: clang-offload-packager{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=bdw,kind=sycl{{.*}}" // Verify when a comma-separated list of architectures is provided in -device, they are -// passed to clang-offload-packager correctly +// passed to clang-offload-packager correctly. // RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ // RUN: -Xsycl-target-backend "-device pvc,bdw" %s 2>&1 \ // RUN: | FileCheck -check-prefix MULTI_ARCH %s +// RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ +// RUN: -Xsycl-target-backend=spir64_gen "-device pvc,bdw" %s 2>&1 \ +// RUN: | FileCheck -check-prefix MULTI_ARCH %s +// RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ +// RUN: -Xs "-device pvc,bdw" %s 2>&1 \ +// RUN: | FileCheck -check-prefix MULTI_ARCH %s // MULTI_ARCH: clang-offload-packager{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl // MULTI_ARCH-SAME: compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode -device pvc,compile-opts=bdw" +// Verify that when an object produced by clang-offload-packager with multiple Intel GPU architectures +// clang-linker-wrapper will call ocloc with -device listing all architectures. +// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen --offload-new-driver \ +// RUN: -Xsycl-target-backend=spir64_gen "-device pvc,bdw" -c %s -o %t_multiarch_test.o +// RUN: clang-linker-wrapper --dry-run --linker-path=/usr/bin/ld \ +// RUN: --host-triple=x86_64-unknown-linux-gnu %t_multiarch_test.o 2>&1 \ +// RUN: | FileCheck -check-prefix=OCLOC_MULTI_ARCH %s +// OCLOC_MULTI_ARCH: ocloc{{.*}}-device pvc,bdw + +// Verify for multiple targets with comma separated // RUN: %clangxx -fsycl -### --offload-new-driver \ // RUN: -fsycl-targets=nvptx64-nvidia-cuda,amdgcn-amd-amdhsa,spir64_gen \ // RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx908,gfx1010 \ diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 63a36e3d7c446..b399405fb0d8f 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1457,9 +1457,8 @@ static Expected linkDevice(ArrayRef InputFiles, if (ExtractedDeviceLibFiles.empty()) { // TODO: Add NVPTX when ready if (Triple.isSPIROrSPIRV()) - return createStringError( - inconvertibleErrorCode(), - " SYCL device library file list cannot be empty."); + WithColor::warning(errs(), LinkerExecutable) + << "SYCL device library file is empty\n"; return *LinkedFile; } From 1dc41be0e613a2f857539a1972b1cb164807ec3e Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Thu, 6 Nov 2025 23:38:23 +0000 Subject: [PATCH 5/9] Update comment --- clang/test/Driver/sycl-offload-new-driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/test/Driver/sycl-offload-new-driver.c b/clang/test/Driver/sycl-offload-new-driver.c index a000c1ee1fd29..35ac6ec06fbd1 100644 --- a/clang/test/Driver/sycl-offload-new-driver.c +++ b/clang/test/Driver/sycl-offload-new-driver.c @@ -235,7 +235,8 @@ // RUN: | FileCheck -check-prefix=OCLOC_MULTI_ARCH %s // OCLOC_MULTI_ARCH: ocloc{{.*}}-device pvc,bdw -// Verify for multiple targets with comma separated +// Verify for multiple targets with -Xsycl-target-backend= with commas in the values +// are passed correctly to clang-offload-packager. // RUN: %clangxx -fsycl -### --offload-new-driver \ // RUN: -fsycl-targets=nvptx64-nvidia-cuda,amdgcn-amd-amdhsa,spir64_gen \ // RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx908,gfx1010 \ From 73babfa18d82f99e43e36f1a4cc07521158c3f75 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Mon, 10 Nov 2025 19:21:29 +0000 Subject: [PATCH 6/9] add Yixing's change --- .../ClangLinkerWrapper.cpp | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index b399405fb0d8f..1b6ba20f0ea4b 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -945,24 +945,29 @@ static void addBackendOptions(const ArgList &Args, if (IsCPU) { OptC.split(CmdArgs, " ", /*MaxSplit=*/-1, /*KeepEmpty=*/false); } else { - // ocloc -options args need to be comma separated, e.g. `-options - // "-g,-cl-opt-disable"`. Otherwise, only the first arg is processed by - // ocloc as an arg for -options, and the rest are processed as standalone - // flags, possibly leading to errors. + // ocloc -options takes arguments in the form of '-options "-g + // -cl-opt-disable"' where each argument is separated with spaces. // split function here returns a pair with everything before the separator // ("-options") in the first member of the pair, and everything after the // separator in the second part of the pair. The separator is not included // in any of them. auto [BeforeOptions, AfterOptions] = OptC.split("-options "); // Only add if not empty, an empty arg can lead to ocloc errors. - if (!BeforeOptions.empty()) - CmdArgs.push_back(BeforeOptions); + if (!BeforeOptions.empty()) { + SmallVector BeforeArgs; + BeforeOptions.split(BeforeArgs, " ", /*MaxSplit=*/-1, + /*KeepEmpty=*/false); + for (const auto &string : BeforeArgs) { + CmdArgs.push_back(string); + } + } if (!AfterOptions.empty()) { - // Separator not included by the split function, so explicitly added here. CmdArgs.push_back("-options"); - std::string Replace = AfterOptions.str(); - std::replace(Replace.begin(), Replace.end(), ' ', ','); - CmdArgs.push_back(Args.MakeArgString(Replace)); + // Split the options string by spaces and rejoin to normalize whitespace + SmallVector AfterArgs; + AfterOptions.split(AfterArgs, " ", /*MaxSplit=*/-1, /*KeepEmpty=*/false); + std::string JoinedOptions = llvm::join(AfterArgs, " "); + CmdArgs.push_back(Args.MakeArgString(JoinedOptions)); } } StringRef OptL = From 30e02002f7427967778326a893692c33a21cfb9b Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Wed, 12 Nov 2025 19:27:40 +0000 Subject: [PATCH 7/9] fix missed merge conflict --- clang/test/Driver/sycl-ftarget-compile-fast.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/clang/test/Driver/sycl-ftarget-compile-fast.cpp b/clang/test/Driver/sycl-ftarget-compile-fast.cpp index 2d97266276791..e63801cdf2ecd 100644 --- a/clang/test/Driver/sycl-ftarget-compile-fast.cpp +++ b/clang/test/Driver/sycl-ftarget-compile-fast.cpp @@ -7,19 +7,8 @@ // RUN: -fsycl-targets=spir64_gen -ftarget-compile-fast %s 2>&1 \ // RUN: | FileCheck -check-prefix=TARGET_COMPILE_FAST_GEN %s -<<<<<<< HEAD - -// Due to how clang-offload-packager works, if we want a value in a key-value pair to -// have a comma, we need to specify the key twice, once for each part of the value -// separated by the comma. clang-offload-packager will then combine the two parts into a single -// value with a comma in between. -// TARGET_COMPILE_FAST_GEN: clang-offload-packager -// TARGET_COMPILE_FAST_GEN: compile-opts={{.*}}-options -igc_opts 'PartitionUnit=1 -// TARGET_COMPILE_FAST_GEN-SAME: compile-opts=SubroutineThreshold=50000' -======= // TARGET_COMPILE_FAST_GEN: llvm-offload-binary // TARGET_COMPILE_FAST_GEN: compile-opts={{.*}}-options -igc_opts 'PartitionUnit=1,SubroutineThreshold=50000' ->>>>>>> intel/sycl // RUN: %clang -### -target x86_64-unknown-linux-gnu -fsycl --offload-new-driver \ // RUN: -ftarget-compile-fast %s 2>&1 \ From fc02714b4b379e06a5f7d3401454bc50adfdd0d7 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Thu, 13 Nov 2025 17:52:00 +0000 Subject: [PATCH 8/9] fix lit --- .../test/Driver/sycl-ftarget-compile-fast.cpp | 2 +- clang/test/Driver/sycl-offload-new-driver.c | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/clang/test/Driver/sycl-ftarget-compile-fast.cpp b/clang/test/Driver/sycl-ftarget-compile-fast.cpp index e63801cdf2ecd..3a8c795676a9c 100644 --- a/clang/test/Driver/sycl-ftarget-compile-fast.cpp +++ b/clang/test/Driver/sycl-ftarget-compile-fast.cpp @@ -8,7 +8,7 @@ // RUN: | FileCheck -check-prefix=TARGET_COMPILE_FAST_GEN %s // TARGET_COMPILE_FAST_GEN: llvm-offload-binary -// TARGET_COMPILE_FAST_GEN: compile-opts={{.*}}-options -igc_opts 'PartitionUnit=1,SubroutineThreshold=50000' +// TARGET_COMPILE_FAST_GEN: compile-opts={{.*}}-options -igc_opts 'PartitionUnit=1,compile-opts=SubroutineThreshold=50000' // RUN: %clang -### -target x86_64-unknown-linux-gnu -fsycl --offload-new-driver \ // RUN: -ftarget-compile-fast %s 2>&1 \ diff --git a/clang/test/Driver/sycl-offload-new-driver.c b/clang/test/Driver/sycl-offload-new-driver.c index 9957d2633a008..e06633f5446e5 100644 --- a/clang/test/Driver/sycl-offload-new-driver.c +++ b/clang/test/Driver/sycl-offload-new-driver.c @@ -188,11 +188,7 @@ // RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ // RUN: -Xsycl-target-backend=spir64_gen "-device pvc,bdw" %s 2>&1 \ // RUN: | FileCheck -check-prefix COMMA_FILE %s -<<<<<<< HEAD -// COMMA_FILE: clang-offload-packager{{.*}} "--image=file={{.*}}pvc@bdw{{.*}},triple=spir64_gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl,compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode -device pvc,compile-opts=bdw" -======= -// COMMA_FILE: llvm-offload-binary{{.*}} "--image=file={{.*}}pvc@bdw{{.*}},triple=spir64_gen-unknown-unknown,arch=pvc,bdw,kind=sycl,compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode" ->>>>>>> intel/sycl +// COMMA_FILE: llvm-offload-binary{{.*}} "--image=file={{.*}}pvc@bdw{{.*}},triple=spir64_gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl,compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode -device pvc,compile-opts=bdw" /// Verify the arch value for the packager is populated with different /// scenarios for spir64_gen @@ -217,7 +213,7 @@ // ARCH_CHECK: llvm-offload-binary{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=bdw,kind=sycl{{.*}}" // Verify when a comma-separated list of architectures is provided in -device, they are -// passed to clang-offload-packager correctly. +// passed to llvm-offload-binary correctly. // RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ // RUN: -Xsycl-target-backend "-device pvc,bdw" %s 2>&1 \ // RUN: | FileCheck -check-prefix MULTI_ARCH %s @@ -227,10 +223,10 @@ // RUN: %clangxx -fsycl -### -fsycl-targets=spir64_gen --offload-new-driver \ // RUN: -Xs "-device pvc,bdw" %s 2>&1 \ // RUN: | FileCheck -check-prefix MULTI_ARCH %s -// MULTI_ARCH: clang-offload-packager{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl +// MULTI_ARCH: llvm-offload-binary{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=pvc,arch=bdw,kind=sycl // MULTI_ARCH-SAME: compile-opts=-device_options pvc -ze-intel-enable-auto-large-GRF-mode -device pvc,compile-opts=bdw" -// Verify that when an object produced by clang-offload-packager with multiple Intel GPU architectures +// Verify that when an object produced by llvm-offload-binary with multiple Intel GPU architectures // clang-linker-wrapper will call ocloc with -device listing all architectures. // RUN: %clangxx -fsycl -fsycl-targets=spir64_gen --offload-new-driver \ // RUN: -Xsycl-target-backend=spir64_gen "-device pvc,bdw" -c %s -o %t_multiarch_test.o @@ -240,7 +236,7 @@ // OCLOC_MULTI_ARCH: ocloc{{.*}}-device pvc,bdw // Verify for multiple targets with -Xsycl-target-backend= with commas in the values -// are passed correctly to clang-offload-packager. +// are passed correctly to llvm-offload-binary. // RUN: %clangxx -fsycl -### --offload-new-driver \ // RUN: -fsycl-targets=nvptx64-nvidia-cuda,amdgcn-amd-amdhsa,spir64_gen \ // RUN: -Xsycl-target-backend=amdgcn-amd-amdhsa --offload-arch=gfx908,gfx1010 \ @@ -248,7 +244,7 @@ // RUN: -Xsycl-target-backend=spir64_gen "-device pvc,bdw" \ // RUN: -Xsycl-target-linker=spir64_gen "-DFOO,BAR" \ // RUN: -nogpulib %s 2>&1 | FileCheck -check-prefix=MULTI_ARCH2 %s -// MULTI_ARCH2: clang-offload-packager{{.*}} "--image=file={{.*}}triple=amdgcn-amd-amdhsa,arch=gfx1010,kind=sycl,compile-opts=--offload-arch=gfx908,compile-opts=gfx1010" +// MULTI_ARCH2: llvm-offload-binary{{.*}} "--image=file={{.*}}triple=amdgcn-amd-amdhsa,arch=gfx1010,kind=sycl,compile-opts=--offload-arch=gfx908,compile-opts=gfx1010" // MULTI_ARCH2-SAME: "--image=file={{.*}}triple=amdgcn-amd-amdhsa,arch=gfx908,kind=sycl,compile-opts=--offload-arch=gfx908,compile-opts=gfx1010" // MULTI_ARCH2-SAME: "--image=file={{.*}}triple=nvptx64-nvidia-cuda,arch=sm_86,kind=sycl,compile-opts=--offload-arch=sm_86,compile-opts=sm_87,compile-opts=sm_89" // MULTI_ARCH2-SAME: "--image=file={{.*}}triple=nvptx64-nvidia-cuda,arch=sm_87,kind=sycl,compile-opts=--offload-arch=sm_86,compile-opts=sm_87,compile-opts=sm_89" @@ -260,7 +256,7 @@ // RUN: -Xsycl-target-backend "-device bdw -FOO a,b" \ // RUN: -Xsycl-target-linker "-BAR x,y" %s 2>&1 \ // RUN: | FileCheck -check-prefix COMMA_OPTS %s -// COMMA_OPTS: clang-offload-packager{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=bdw,kind=sycl,compile-opts=-device bdw -FOO a,compile-opts=b,link-opts=-BAR x,link-opts=y" +// COMMA_OPTS: llvm-offload-binary{{.*}} "--image=file={{.*}}triple=spir64_gen-unknown-unknown,arch=bdw,kind=sycl,compile-opts=-device bdw -FOO a,compile-opts=b,link-opts=-BAR x,link-opts=y" /// Verify that --cuda-path is passed to clang-linker-wrapper for SYCL offload // RUN: %clangxx -fsycl -### -fsycl-targets=nvptx64-nvidia-cuda -fno-sycl-libspirv \ From 8cee995c4adbc6e18cd08cbfa0554558f291ab22 Mon Sep 17 00:00:00 2001 From: "Cai, Justin" Date: Fri, 14 Nov 2025 17:35:05 +0000 Subject: [PATCH 9/9] address review comments --- clang/lib/Driver/ToolChains/Clang.cpp | 6 +++--- clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index a1d840b6c98b8..371f2460f5ee3 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -10261,8 +10261,8 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, // "-device pvc,bdw", the offloading arch will be "pvc,bdw", which // contains a comma. Because the comma is used to separate fields // within the --image option, we cannot pass arch=pvc,bdw directly. - // Instead, we if we pass it like arch=pvc,arch=bdw when, then - // clang-offload-packager joins them back to arch=pvc,bdw. + // Instead, we pass it like arch=pvc,arch=bdw, then + // llvm-offload-binary joins them back to arch=pvc,bdw. SmallVector Archs; Arch.split(Archs, ','); if (Archs.size() > 1) { @@ -10293,7 +10293,7 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, AL += A; } // As mentioned earlier, we cannot pass a value with commas directly, - // but clang-offload-packager joins multiple occurrences of the same + // but llvm-offload-binary joins multiple occurrences of the same // option separated by commas, so we split the value on // all commas and pass them as separate arguments. for (StringRef Split : llvm::split(AL, ',')) { diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 887a341bcaa11..1132996da575e 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1447,7 +1447,7 @@ static Expected linkDevice(ArrayRef InputFiles, // TODO: Add NVPTX when ready if (Triple.isSPIROrSPIRV()) WithColor::warning(errs(), LinkerExecutable) - << "SYCL device library file is empty\n"; + << "SYCL device library file list is empty\n"; return *LinkedFile; }