@@ -10443,12 +10443,48 @@ static void getSPIRVBackendOpts(const llvm::opt::ArgList &TCArgs,
1044310443 TCArgs.MakeArgString (" --avoid-spirv-capabilities=Shader" ));
1044410444 BackendArgs.push_back (
1044510445 TCArgs.MakeArgString (" --translator-compatibility-mode" ));
10446- // TODO: A list of SPIR-V extensions that are supported by the SPIR-V backend
10447- // is growing. Let's postpone the decision on which extensions to enable until
10448- // - the list is stable, and
10449- // - we decide on a mapping of user requested extensions into backend's ones.
10450- // Meanwhile we enable all the SPIR-V backend extensions.
10451- BackendArgs.push_back (TCArgs.MakeArgString (" --spirv-ext=all" ));
10446+
10447+ // SPIR-V backend recently started to support extensions not supported by
10448+ // drivers (e.g. SPV_KHR_float_controls2). At the same time, SPIR-V backend
10449+ // doesn't support the syntax for disabling specific extensions (i.e.
10450+ // --spirv-ext=-<extension>). We need to come up with a list of SPIR-V
10451+ // extensions that are supported by the backend, but also by the driver. Below
10452+ // is the first approach for such a list.
10453+ // FIXME: A priori, we wouldn't expect
10454+ // SPV_EXT_relaxed_printf_string_address_space to be required, but without
10455+ // it, some SYCL E2E tests fail. Let's keep it until we figure out what's
10456+ // the problem.
10457+ std::string ExtArg (" -spirv-ext=" );
10458+ std::string DefaultExtArg = " +SPV_EXT_relaxed_printf_string_address_space"
10459+ " ,+SPV_EXT_shader_atomic_float16_add"
10460+ " ,+SPV_EXT_shader_atomic_float_add"
10461+ " ,+SPV_EXT_shader_atomic_float_min_max" ;
10462+ std::string IntelExtArg = " ,+SPV_INTEL_2d_block_io"
10463+ " ,+SPV_INTEL_arbitrary_precision_integers"
10464+ " ,+SPV_INTEL_bfloat16_conversion"
10465+ " ,+SPV_INTEL_bindless_images"
10466+ " ,+SPV_INTEL_cache_controls"
10467+ " ,+SPV_INTEL_float_controls2"
10468+ " ,+SPV_INTEL_fp_max_error"
10469+ " ,+SPV_INTEL_function_pointers"
10470+ " ,+SPV_INTEL_inline_assembly"
10471+ " ,+SPV_INTEL_joint_matrix"
10472+ " ,+SPV_INTEL_long_composites"
10473+ " ,+SPV_INTEL_subgroups"
10474+ " ,+SPV_INTEL_tensor_float32_conversion"
10475+ " ,+SPV_INTEL_variable_length_array" ;
10476+ std::string KHRExtArg = " ,+SPV_KHR_16bit_storage"
10477+ " ,+SPV_KHR_cooperative_matrix"
10478+ " ,+SPV_KHR_expect_assume"
10479+ " ,+SPV_KHR_float_controls"
10480+ " ,+SPV_KHR_linkonce_odr"
10481+ " ,+SPV_KHR_no_integer_wrap_decoration"
10482+ " ,+SPV_KHR_non_semantic_info"
10483+ " ,+SPV_KHR_shader_clock"
10484+ " ,+SPV_KHR_uniform_group_instructions" ;
10485+ ExtArg = ExtArg + DefaultExtArg + IntelExtArg + KHRExtArg;
10486+ BackendArgs.push_back (TCArgs.MakeArgString (ExtArg));
10487+
1045210488 // TODO:
1045310489 // - handle -Xspirv-translator option to avoid "argument unused during
1045410490 // compilation" error
@@ -11228,43 +11264,6 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
1122811264 if (Args.hasArg (options::OPT_fsycl_link_EQ))
1122911265 CmdArgs.push_back (Args.MakeArgString (" --sycl-device-link" ));
1123011266
11231- // -sycl-device-libraries=<comma separated list> contains all of the SYCL
11232- // device specific libraries that are needed. This generic list will be
11233- // populated with device binaries for all target triples in the current
11234- // compilation flow.
11235-
11236- // Create a comma separated list to pass along to the linker wrapper.
11237- SmallString<256 > LibList;
11238- llvm::Triple TargetTriple;
11239- auto ToolChainRange = C.getOffloadToolChains <Action::OFK_SYCL>();
11240- for (auto &I :
11241- llvm::make_range (ToolChainRange.first , ToolChainRange.second )) {
11242- const ToolChain *TC = I.second ;
11243- // Note: For AMD targets, we do not pass any SYCL device libraries.
11244- if (TC->getTriple ().isSPIROrSPIRV () || TC->getTriple ().isNVPTX ()) {
11245- TargetTriple = TC->getTriple ();
11246- SmallVector<std::string, 8 > SYCLDeviceLibs;
11247- bool IsSPIR = TargetTriple.isSPIROrSPIRV ();
11248- bool IsSpirvAOT = TargetTriple.isSPIRAOT ();
11249- bool UseJitLink =
11250- IsSPIR &&
11251- Args.hasFlag (options::OPT_fsycl_device_lib_jit_link,
11252- options::OPT_fno_sycl_device_lib_jit_link, false );
11253- bool UseAOTLink = IsSPIR && (IsSpirvAOT || !UseJitLink);
11254- SYCLDeviceLibs = SYCL::getDeviceLibraries (C, TargetTriple, UseAOTLink);
11255- for (const auto &AddLib : SYCLDeviceLibs) {
11256- if (LibList.size () > 0 )
11257- LibList += " ," ;
11258- LibList += AddLib;
11259- }
11260- }
11261- }
11262- // -sycl-device-libraries=<libs> provides a comma separate list of
11263- // libraries to add to the device linking step.
11264- if (LibList.size ())
11265- CmdArgs.push_back (
11266- Args.MakeArgString (Twine (" -sycl-device-libraries=" ) + LibList));
11267-
1126811267 // -sycl-device-library-location=<dir> provides the location in which the
1126911268 // SYCL device libraries can be found.
1127011269 SmallString<128 > DeviceLibDir (D.Dir );
@@ -11289,6 +11288,68 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
1128911288 break ;
1129011289 }
1129111290 }
11291+
11292+ // -sycl-device-libraries=<comma separated list> contains a list of
11293+ // file names for fat object files that contain SYCL device library bitcode
11294+ // necessary for SYCL offloading that will be linked to the user's device
11295+ // code. clang-linker-wrapper uses the value provided to
11296+ // -sycl-device-library-location=<dir> to construct the full paths of the
11297+ // device libraries.
11298+
11299+ // On the other hand, --bitcode-library=<triple>=<path to bc file> specifies
11300+ // one bitcode library to link in for a specific triple. Additionally, the
11301+ // path is *not* relative to the -sycl-device-library-location - the full
11302+ // path must be provided.
11303+ SmallString<256 > LibList;
11304+ SmallVector<std::string, 4 > BCLibList;
11305+
11306+ auto appendToList = [](SmallString<256 > &List, const Twine &Arg) {
11307+ if (List.size () > 0 )
11308+ List += " ," ;
11309+ List += Arg.str ();
11310+ };
11311+
11312+ auto ToolChainRange = C.getOffloadToolChains <Action::OFK_SYCL>();
11313+ for (const auto &[Kind, TC] :
11314+ llvm::make_range (ToolChainRange.first , ToolChainRange.second )) {
11315+ llvm::Triple TargetTriple = TC->getTriple ();
11316+ bool IsSPIR = TargetTriple.isSPIROrSPIRV ();
11317+ bool IsSpirAOT = TargetTriple.isSPIRAOT ();
11318+ bool UseJitLink =
11319+ IsSPIR &&
11320+ Args.hasFlag (options::OPT_fsycl_device_lib_jit_link,
11321+ options::OPT_fno_sycl_device_lib_jit_link, false );
11322+ bool UseAOTLink = IsSPIR && (IsSpirAOT || !UseJitLink);
11323+ SmallVector<std::string, 8 > SYCLDeviceLibs =
11324+ SYCL::getDeviceLibraries (C, TargetTriple, UseAOTLink);
11325+ for (const auto &AddLib : SYCLDeviceLibs) {
11326+ if (llvm::sys::path::extension (AddLib) == " .bc" ) {
11327+ SmallString<256 > LibPath (DeviceLibDir);
11328+ llvm::sys::path::append (LibPath, AddLib);
11329+ BCLibList.push_back (
11330+ (Twine (TC->getTriple ().str ()) + " =" + LibPath).str ());
11331+ continue ;
11332+ }
11333+
11334+ appendToList (LibList, AddLib);
11335+ }
11336+
11337+ if (TC->getTriple ().isNVPTX ())
11338+ if (const char *LibSpirvFile = SYCLInstallation.findLibspirvPath (
11339+ TC->getTriple (), Args, *TC->getAuxTriple ()))
11340+ BCLibList.push_back (
11341+ (Twine (TC->getTriple ().str ()) + " =" + LibSpirvFile).str ());
11342+ }
11343+
11344+ if (LibList.size ())
11345+ CmdArgs.push_back (
11346+ Args.MakeArgString (Twine (" -sycl-device-libraries=" ) + LibList));
11347+
11348+ if (BCLibList.size ())
11349+ for (const std::string &Lib : BCLibList)
11350+ CmdArgs.push_back (
11351+ Args.MakeArgString (Twine (" --bitcode-library=" ) + Lib));
11352+
1129211353 CmdArgs.push_back (Args.MakeArgString (
1129311354 Twine (" -sycl-device-library-location=" ) + DeviceLibDir));
1129411355
0 commit comments