Skip to content

Commit 1d95f2e

Browse files
authored
[Driver][SYCL] Add support for -fsycl-force-target (#6653)
Introduce -fsycl-force-target=arg support. This is used along with -fsycl to allow the user to override the target used to unbundle device objects from fat objects and archives. For example, object.o is built from -fsycl-targets=spir64. The user wants to build with -fsycl-targets=spir64_gen and object.o. Use of -fsycl-force-target=spir64 allows for this to be accomplished. Additional notes: - Only valid when used with a single triple from -fsycl-targets - Applies to all unbundled archives and objects
1 parent 4612880 commit 1d95f2e

File tree

6 files changed

+69
-1
lines changed

6 files changed

+69
-1
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,8 @@ def warn_drv_sycl_offload_target_duplicate : Warning<
345345
def warn_drv_sycl_target_missing : Warning<
346346
"linked binaries do not contain expected '%0' target; found targets: '%1'">,
347347
InGroup<SyclTarget>;
348+
def err_drv_multiple_target_with_forced_target : Error<
349+
"multiple target usage with '%0' is not supported with '%1'">;
348350
def err_drv_failed_to_deduce_target_from_arch : Error<
349351
"failed to deduce triple for target architecture '%0'; specify the triple "
350352
"using '-fopenmp-targets' and '-Xopenmp-target' instead.">;

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2848,6 +2848,10 @@ def fsycl_link_targets_EQ : CommaJoined<["-"], "fsycl-link-targets=">,
28482848
Flags<[NoXarchOption, CC1Option, CoreOption, Deprecated]>,
28492849
HelpText<"Specify comma-separated list of triples SYCL offloading targets "
28502850
"to produce linked device images (deprecated)">;
2851+
def fsycl_force_target_EQ : Joined<["-"], "fsycl-force-target=">,
2852+
Flags<[NoXarchOption, CoreOption]>,
2853+
HelpText<"Force the usage of the given triple when extracting device code "
2854+
"from any given objects on the command line">;
28512855
def fsycl_device_code_split_EQ : Joined<["-"], "fsycl-device-code-split=">,
28522856
Flags<[CC1Option, CoreOption]>, HelpText<"Perform SYCL device code split: per_kernel (device code module is "
28532857
"created for each SYCL kernel) | per_source (device code module is created for each source (translation unit)) | off (no device code split). | auto (use heuristic to select the best way of splitting device code). "

clang/lib/Driver/Driver.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,8 @@ static bool addSYCLDefaultTriple(Compilation &C,
785785
/// Returns true if a triple is added to SYCLTriples, false otherwise
786786
if (!C.getDriver().isSYCLDefaultTripleImplied())
787787
return false;
788+
if (C.getInputArgs().hasArg(options::OPT_fsycl_force_target_EQ))
789+
return false;
788790
for (const auto &SYCLTriple : SYCLTriples) {
789791
if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
790792
SYCLTriple.isSPIR())
@@ -1057,6 +1059,14 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
10571059
C.getInputArgs().getLastArg(options::OPT_fsycl_device_code_split_EQ),
10581060
{"per_kernel", "per_source", "auto", "off"});
10591061

1062+
Arg *SYCLForceTarget =
1063+
getArgRequiringSYCLRuntime(options::OPT_fsycl_force_target_EQ);
1064+
if (SYCLForceTarget) {
1065+
StringRef Val(SYCLForceTarget->getValue());
1066+
llvm::Triple TT(MakeSYCLDeviceTriple(Val));
1067+
if (!isValidSYCLTriple(TT))
1068+
Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
1069+
}
10601070
bool HasSYCLTargetsOption = SYCLTargets || SYCLLinkTargets || SYCLAddTargets;
10611071
llvm::StringMap<StringRef> FoundNormalizedTriples;
10621072
llvm::SmallVector<llvm::Triple, 4> UniqueSYCLTriplesVec;
@@ -1066,6 +1076,15 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
10661076
Arg *SYCLTargetsValues = SYCLTargets ? SYCLTargets : SYCLLinkTargets;
10671077
if (SYCLTargetsValues) {
10681078
if (SYCLTargetsValues->getNumValues()) {
1079+
1080+
// Multiple targets are currently not supported when using
1081+
// -fsycl-force-target as the bundler does not allow for multiple
1082+
// outputs of the same target.
1083+
if (SYCLForceTarget && SYCLTargetsValues->getNumValues() > 1)
1084+
Diag(clang::diag::err_drv_multiple_target_with_forced_target)
1085+
<< SYCLTargetsValues->getAsString(C.getInputArgs())
1086+
<< SYCLForceTarget->getAsString(C.getInputArgs());
1087+
10691088
for (StringRef Val : SYCLTargetsValues->getValues()) {
10701089
llvm::Triple TT(MakeSYCLDeviceTriple(Val));
10711090
if (!isValidSYCLTriple(TT)) {

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8916,7 +8916,16 @@ void OffloadBundler::ConstructJobMultipleOutputs(
89168916
Triples += ',';
89178917
Triples += Action::GetOffloadKindName(Dep.DependentOffloadKind);
89188918
Triples += '-';
8919-
Triples += Dep.DependentToolChain->getTriple().normalize();
8919+
// When -fsycl-force-target is used, this value overrides the expected
8920+
// output type we are unbundling.
8921+
if (Dep.DependentOffloadKind == Action::OFK_SYCL &&
8922+
TCArgs.hasArg(options::OPT_fsycl_force_target_EQ)) {
8923+
StringRef Val(
8924+
TCArgs.getLastArg(options::OPT_fsycl_force_target_EQ)->getValue());
8925+
llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple(Val));
8926+
Triples += TT.normalize();
8927+
} else
8928+
Triples += Dep.DependentToolChain->getTriple().normalize();
89208929
if ((Dep.DependentOffloadKind == Action::OFK_HIP ||
89218930
Dep.DependentOffloadKind == Action::OFK_OpenMP ||
89228931
Dep.DependentOffloadKind == Action::OFK_Cuda ||
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/// Verify the usage of -fsycl-force-target applies to all expected unbundlings
2+
// RUN: touch %t.o
3+
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -fsycl-force-target=spir64 \
4+
// RUN: %s --sysroot=%S/Inputs/SYCL %t.o -### 2>&1 \
5+
// RUN: | FileCheck %s -check-prefix=CHECK_FORCE_TARGET
6+
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen \
7+
// RUN: -fsycl-force-target=spir64-unknown-unknown \
8+
// RUN: %s --sysroot=%S/Inputs/SYCL %t.o -### 2>&1 \
9+
// RUN: | FileCheck %s -check-prefixes=CHECK_FORCE_TARGET,CHECK_FORCE_TARGET_GEN
10+
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64 \
11+
// RUN: -fsycl-force-target=spir64 %s \
12+
// RUN: --sysroot=%S/Inputs/SYCL %t.o -### 2>&1 \
13+
// RUN: | FileCheck %s -check-prefixes=CHECK_FORCE_TARGET,CHECK_FORCE_TARGET_CPU
14+
// CHECK_FORCE_TARGET: clang-offload-bundler{{.*}} "-type=o" "-targets=host-{{.*}},sycl-spir64-unknown-unknown" "-input={{.*}}" "-output={{.*}}" "-output=[[DEVICEOBJECTOUT:.+]]" "-unbundle" "-allow-missing-bundles"
15+
// CHECK_FORCE_TARGET: spirv-to-ir-wrapper{{.*}} "[[DEVICEOBJECTOUT]]" "-o" "[[DEVICEOBJECTBC:.+\.bc]]"
16+
// CHECK_FORCE_TARGET: llvm-link{{.*}} "[[DEVICEOBJECTBC]]"{{.*}} "-o" "[[DEVICEOBJLINKED:.+\.bc]]" "--suppress-warnings"
17+
// CHECK_FORCE_TARGET: clang-offload-bundler{{.*}} "-type=o" "-targets=sycl-spir64-unknown-unknown" "-input={{.*}}libsycl-complex{{.*}}" "-output={{.*}}libsycl-complex-{{.*}}" "-unbundle"
18+
// CHECK_FORCE_TARGET_GEN: llvm-foreach{{.*}} {{.*}}ocloc{{.*}}
19+
// CHECK_FORCE_TARGET_CPU: llvm-foreach{{.*}} {{.*}}opencl-aot{{.*}}
20+
21+
/// -fsycl-force-target is only valid with -fsycl-target with single targets
22+
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen,spir64_x86_64 \
23+
// RUN: -fsycl-force-target=spir64 %s -### 2>&1 \
24+
// RUN: | FileCheck %s -check-prefix=MULTIPLE_TARGET
25+
// MULTIPLE_TARGET: error: multiple target usage with '-fsycl-targets=spir64_gen,spir64_x86_64' is not supported with '-fsycl-force-target=spir64'
26+

sycl/doc/UsersManual.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,14 @@ and not recommended to use in production environment.
225225

226226
NOTE: This option is currently only supported on Linux.
227227

228+
**`-fsycl-force-target=<T>`**
229+
230+
When used along with '-fsycl-targets', force the device object being
231+
unbundled to match the target <T> given. This allows the user to override
232+
the expected unbundling type even though the target given does not match.
233+
The forced target applies to all objects, archives and default device
234+
libraries.
235+
228236
## Intel FPGA specific options
229237

230238
**`-fintelfpga`**

0 commit comments

Comments
 (0)