@@ -785,6 +785,8 @@ static bool addSYCLDefaultTriple(Compilation &C,
785
785
// / Returns true if a triple is added to SYCLTriples, false otherwise
786
786
if (!C.getDriver ().isSYCLDefaultTripleImplied ())
787
787
return false ;
788
+ if (C.getInputArgs ().hasArg (options::OPT_fsycl_force_target_EQ))
789
+ return false ;
788
790
for (const auto &SYCLTriple : SYCLTriples) {
789
791
if (SYCLTriple.getSubArch () == llvm::Triple::NoSubArch &&
790
792
SYCLTriple.isSPIR ())
@@ -1057,6 +1059,14 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
1057
1059
C.getInputArgs ().getLastArg (options::OPT_fsycl_device_code_split_EQ),
1058
1060
{" per_kernel" , " per_source" , " auto" , " off" });
1059
1061
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
+ }
1060
1070
bool HasSYCLTargetsOption = SYCLTargets || SYCLLinkTargets || SYCLAddTargets;
1061
1071
llvm::StringMap<StringRef> FoundNormalizedTriples;
1062
1072
llvm::SmallVector<llvm::Triple, 4 > UniqueSYCLTriplesVec;
@@ -1066,6 +1076,15 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
1066
1076
Arg *SYCLTargetsValues = SYCLTargets ? SYCLTargets : SYCLLinkTargets;
1067
1077
if (SYCLTargetsValues) {
1068
1078
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
+
1069
1088
for (StringRef Val : SYCLTargetsValues->getValues ()) {
1070
1089
llvm::Triple TT (MakeSYCLDeviceTriple (Val));
1071
1090
if (!isValidSYCLTriple (TT)) {
@@ -4661,6 +4680,9 @@ class OffloadingActionBuilder final {
4661
4680
// / List of static archives to extract FPGA dependency info from
4662
4681
ActionList FPGAArchiveInputs;
4663
4682
4683
+ // SYCLInstallation is needed in order to link SYCLDeviceLibs
4684
+ SYCLInstallationDetector SYCLInstallation;
4685
+
4664
4686
// / List of GPU architectures to use in this compilation with NVPTX/AMDGCN
4665
4687
// / targets.
4666
4688
SmallVector<std::pair<llvm::Triple, const char *>, 8 > GpuArchList;
@@ -4701,7 +4723,8 @@ class OffloadingActionBuilder final {
4701
4723
SYCLActionBuilder (Compilation &C, DerivedArgList &Args,
4702
4724
const Driver::InputList &Inputs,
4703
4725
OffloadingActionBuilder &OAB)
4704
- : DeviceActionBuilder(C, Args, Inputs, Action::OFK_SYCL, OAB) {}
4726
+ : DeviceActionBuilder(C, Args, Inputs, Action::OFK_SYCL, OAB),
4727
+ SYCLInstallation (C.getDriver()) {}
4705
4728
4706
4729
void withBoundArchForToolChain (const ToolChain *TC,
4707
4730
llvm::function_ref<void (const char *)> Op) {
@@ -5080,10 +5103,8 @@ class OffloadingActionBuilder final {
5080
5103
}
5081
5104
}
5082
5105
5083
- const toolchains::SYCLToolChain *SYCLTC =
5084
- static_cast <const toolchains::SYCLToolChain *>(TC);
5085
5106
SmallVector<SmallString<128 >, 4 > LibLocCandidates;
5086
- SYCLTC-> SYCLInstallation .getSYCLDeviceLibPath (LibLocCandidates);
5107
+ SYCLInstallation.getSYCLDeviceLibPath (LibLocCandidates);
5087
5108
StringRef LibSuffix = isMSVCEnv ? " .obj" : " .o" ;
5088
5109
using SYCLDeviceLibsList = SmallVector<DeviceLibOptInfo, 5 >;
5089
5110
@@ -5136,20 +5157,100 @@ class OffloadingActionBuilder final {
5136
5157
auto *SYCLDeviceLibsUnbundleAction =
5137
5158
C.MakeAction <OffloadUnbundlingJobAction>(
5138
5159
SYCLDeviceLibsInputAction);
5139
- addDeviceDepences (SYCLDeviceLibsUnbundleAction);
5140
- DeviceLinkObjects.push_back (SYCLDeviceLibsUnbundleAction);
5160
+
5161
+ // We are using BoundArch="" here since the NVPTX bundles in
5162
+ // the devicelib .o files do not contain any arch information
5163
+ SYCLDeviceLibsUnbundleAction->registerDependentActionInfo (
5164
+ TC, /* BoundArch=*/ " " , Action::OFK_SYCL);
5165
+ OffloadAction::DeviceDependences Dep;
5166
+ Dep.add (*SYCLDeviceLibsUnbundleAction, *TC, /* BoundArch=*/ " " ,
5167
+ Action::OFK_SYCL);
5168
+ auto *SYCLDeviceLibsDependenciesAction =
5169
+ C.MakeAction <OffloadAction>(
5170
+ Dep, SYCLDeviceLibsUnbundleAction->getType ());
5171
+
5172
+ DeviceLinkObjects.push_back (SYCLDeviceLibsDependenciesAction);
5141
5173
if (!LibLocSelected)
5142
5174
LibLocSelected = !LibLocSelected;
5143
5175
}
5144
5176
}
5145
5177
}
5146
5178
};
5179
+
5147
5180
addInputs (sycl_device_wrapper_libs);
5148
- if (isSpirvAOT)
5181
+ if (isSpirvAOT || TC-> getTriple (). isNVPTX () )
5149
5182
addInputs (sycl_device_fallback_libs);
5150
5183
if (Args.hasFlag (options::OPT_fsycl_instrument_device_code,
5151
5184
options::OPT_fno_sycl_instrument_device_code, true ))
5152
5185
addInputs (sycl_device_annotation_libs);
5186
+
5187
+ // For NVPTX backend we need to also link libclc and CUDA libdevice
5188
+ // at the same stage that we link all of the unbundled SYCL libdevice
5189
+ // objects together.
5190
+ if (TC->getTriple ().isNVPTX () && NumOfDeviceLibLinked) {
5191
+ std::string LibSpirvFile;
5192
+ if (Args.hasArg (options::OPT_fsycl_libspirv_path_EQ)) {
5193
+ auto ProvidedPath =
5194
+ Args.getLastArgValue (options::OPT_fsycl_libspirv_path_EQ).str ();
5195
+ if (llvm::sys::fs::exists (ProvidedPath))
5196
+ LibSpirvFile = ProvidedPath;
5197
+ } else {
5198
+ SmallVector<StringRef, 8 > LibraryPaths;
5199
+
5200
+ // Expected path w/out install.
5201
+ SmallString<256 > WithoutInstallPath (C.getDriver ().ResourceDir );
5202
+ llvm::sys::path::append (WithoutInstallPath, Twine (" ../../clc" ));
5203
+ LibraryPaths.emplace_back (WithoutInstallPath.c_str ());
5204
+
5205
+ // Expected path w/ install.
5206
+ SmallString<256 > WithInstallPath (C.getDriver ().ResourceDir );
5207
+ llvm::sys::path::append (WithInstallPath, Twine (" ../../../share/clc" ));
5208
+ LibraryPaths.emplace_back (WithInstallPath.c_str ());
5209
+
5210
+ // Select remangled libclc variant
5211
+ std::string LibSpirvTargetName =
5212
+ (TC->getAuxTriple ()->isOSWindows ())
5213
+ ? " remangled-l32-signed_char.libspirv-nvptx64--nvidiacl."
5214
+ " bc"
5215
+ : " remangled-l64-signed_char.libspirv-nvptx64--nvidiacl."
5216
+ " bc" ;
5217
+
5218
+ for (StringRef LibraryPath : LibraryPaths) {
5219
+ SmallString<128 > LibSpirvTargetFile (LibraryPath);
5220
+ llvm::sys::path::append (LibSpirvTargetFile, LibSpirvTargetName);
5221
+ if (llvm::sys::fs::exists (LibSpirvTargetFile) ||
5222
+ Args.hasArg (options::OPT__HASH_HASH_HASH)) {
5223
+ LibSpirvFile = std::string (LibSpirvTargetFile.str ());
5224
+ break ;
5225
+ }
5226
+ }
5227
+ }
5228
+
5229
+ if (!LibSpirvFile.empty ()) {
5230
+ Arg *LibClcInputArg = MakeInputArg (Args, C.getDriver ().getOpts (),
5231
+ Args.MakeArgString (LibSpirvFile));
5232
+ auto *SYCLLibClcInputAction =
5233
+ C.MakeAction <InputAction>(*LibClcInputArg, types::TY_LLVM_BC);
5234
+ DeviceLinkObjects.push_back (SYCLLibClcInputAction);
5235
+ }
5236
+
5237
+ const toolchains::CudaToolChain *CudaTC =
5238
+ static_cast <const toolchains::CudaToolChain *>(TC);
5239
+ for (auto LinkInputEnum : enumerate(DeviceLinkerInputs)) {
5240
+ const char *BoundArch =
5241
+ SYCLTargetInfoList[LinkInputEnum.index ()].BoundArch ;
5242
+ std::string LibDeviceFile =
5243
+ CudaTC->CudaInstallation .getLibDeviceFile (BoundArch);
5244
+ if (!LibDeviceFile.empty ()) {
5245
+ Arg *CudaDeviceLibInputArg =
5246
+ MakeInputArg (Args, C.getDriver ().getOpts (),
5247
+ Args.MakeArgString (LibDeviceFile));
5248
+ auto *SYCLDeviceLibInputAction = C.MakeAction <InputAction>(
5249
+ *CudaDeviceLibInputArg, types::TY_LLVM_BC);
5250
+ DeviceLinkObjects.push_back (SYCLDeviceLibInputAction);
5251
+ }
5252
+ }
5253
+ }
5153
5254
return NumOfDeviceLibLinked != 0 ;
5154
5255
}
5155
5256
@@ -5299,11 +5400,12 @@ class OffloadingActionBuilder final {
5299
5400
// When spv online link is supported by all backends, the fallback
5300
5401
// device libraries are only needed when current toolchain is using
5301
5402
// AOT compilation.
5302
- if (isSPIR) {
5403
+ if (isSPIR || isNVPTX ) {
5303
5404
bool UseJitLink =
5405
+ isSPIR &&
5304
5406
Args.hasFlag (options::OPT_fsycl_device_lib_jit_link,
5305
5407
options::OPT_fno_sycl_device_lib_jit_link, false );
5306
- bool UseAOTLink = isSpirvAOT || !UseJitLink;
5408
+ bool UseAOTLink = isSPIR && ( isSpirvAOT || !UseJitLink) ;
5307
5409
SYCLDeviceLibLinked = addSYCLDeviceLibs (
5308
5410
TC, FullLinkObjects, UseAOTLink,
5309
5411
C.getDefaultToolChain ().getTriple ().isWindowsMSVCEnvironment ());
0 commit comments