Skip to content
24 changes: 21 additions & 3 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10264,6 +10264,18 @@ 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. 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<StringRef> 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());
Expand All @@ -10287,7 +10299,13 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA,
AL += " ";
AL += A;
}
Parts.emplace_back(C.getArgs().MakeArgString(Twine(Opt) + AL));
// 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));
}
};
const ArgList &Args =
C.getArgsForToolChain(nullptr, StringRef(), Action::OFK_SYCL);
Expand All @@ -10296,10 +10314,10 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA,
static_cast<const toolchains::SYCLToolChain &>(*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=");
}

Expand Down
8 changes: 7 additions & 1 deletion clang/test/Driver/sycl-ftarget-compile-fast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
48 changes: 47 additions & 1 deletion clang/test/Driver/sycl-offload-new-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +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
// 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 -device pvc,compile-opts=bdw"

/// Verify the arch value for the packager is populated with different
/// scenarios for spir64_gen
Expand All @@ -212,6 +212,52 @@
// 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
// 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 -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 \
// 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,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 \
// 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 \
Expand Down
5 changes: 2 additions & 3 deletions clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1457,9 +1457,8 @@ static Expected<StringRef> linkDevice(ArrayRef<StringRef> 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;
}

Expand Down
Loading