Skip to content

Commit 8867d44

Browse files
authored
[spir-v][clang] Allow spirv32/spirv64 as target triples for sycl offloading (#13083)
Based on discussions with various stakeholders, we concluded that spirv32/spirv64 are the best-suited strings for target architectures when user wants to generate JIT code for Intel backends using DPCPP compiler. This PR adds changes to allow the DPCPP compiler to accept spirv32/spirv64 as valid target architecture strings. spir/spir64 are also valid target architecture strings, but will be deprecated in a future commit. This change will help us to align with the SPIR-V backend behavior and ensure smoother SYCL upstreaming. Currently, only JIT triples using spirv32/spirv64 are supported. AOT triples using spirv32/spirv64 will be added soon. Thanks --------- Signed-off-by: Sudarsanam, Arvind <[email protected]>
1 parent 7d77f84 commit 8867d44

File tree

11 files changed

+128
-79
lines changed

11 files changed

+128
-79
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,10 +1138,10 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
11381138

11391139
// Add SPIRITTAnnotations pass to the pass manager if
11401140
// -fsycl-instrument-device-code option was passed. This option can be
1141-
// used only with spir triple.
1141+
// used only with spir or spirv triple.
11421142
if (CodeGenOpts.SPIRITTAnnotations) {
11431143
assert(
1144-
TargetTriple.isSPIR() &&
1144+
TargetTriple.isSPIROrSPIRV() &&
11451145
"ITT annotations can only be added to a module with spir target");
11461146
MPM.addPass(SPIRITTAnnotationsPass());
11471147
}

clang/lib/Driver/Driver.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -806,10 +806,10 @@ static bool isValidSYCLTriple(llvm::Triple T) {
806806
return true;
807807

808808
// Check for invalid SYCL device triple values.
809-
// Non-SPIR arch.
810-
if (!T.isSPIR())
809+
// Non-SPIR/SPIRV arch.
810+
if (!T.isSPIROrSPIRV())
811811
return false;
812-
// SPIR arch, but has invalid SubArch for AOT.
812+
// SPIR/SPIRV arch, but has invalid SubArch for AOT.
813813
StringRef A(T.getArchName());
814814
if (T.getSubArch() == llvm::Triple::NoSubArch &&
815815
((T.getArch() == llvm::Triple::spir && !A.equals("spir")) ||
@@ -833,7 +833,7 @@ static bool addSYCLDefaultTriple(Compilation &C,
833833
return false;
834834
for (const auto &SYCLTriple : SYCLTriples) {
835835
if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
836-
SYCLTriple.isSPIR())
836+
SYCLTriple.isSPIROrSPIRV())
837837
return false;
838838
// If we encounter a known non-spir* target, do not add the default triple.
839839
if (SYCLTriple.isNVPTX() || SYCLTriple.isAMDGCN())
@@ -2392,8 +2392,9 @@ void Driver::PrintHelp(bool ShowHidden) const {
23922392
}
23932393

23942394
llvm::Triple Driver::MakeSYCLDeviceTriple(StringRef TargetArch) const {
2395-
SmallVector<StringRef, 5> SYCLAlias = {"spir", "spir64", "spir64_fpga",
2396-
"spir64_x86_64", "spir64_gen"};
2395+
SmallVector<StringRef, 5> SYCLAlias = {
2396+
"spir", "spir64", "spir64_fpga", "spir64_x86_64",
2397+
"spir64_gen", "spirv32", "spirv64"};
23972398
if (std::find(SYCLAlias.begin(), SYCLAlias.end(), TargetArch) !=
23982399
SYCLAlias.end()) {
23992400
llvm::Triple TT;
@@ -3699,7 +3700,7 @@ bool Driver::checkForSYCLDefaultDevice(Compilation &C,
36993700
if (const Arg *A = Args.getLastArg(options::OPT_fsycl_targets_EQ)) {
37003701
for (const char *Val : A->getValues()) {
37013702
llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple(Val));
3702-
if (TT.isSPIR() && TT.getSubArch() == llvm::Triple::NoSubArch)
3703+
if ((TT.isSPIROrSPIRV()) && TT.getSubArch() == llvm::Triple::NoSubArch)
37033704
// Default triple found
37043705
return false;
37053706
}
@@ -4177,7 +4178,7 @@ class OffloadingActionBuilder final {
41774178
// supported GPUs. sm_20 code should work correctly, if
41784179
// suboptimally, on all newer GPUs.
41794180
if (GpuArchList.empty()) {
4180-
if (ToolChains.front()->getTriple().isSPIRV())
4181+
if (ToolChains.front()->getTriple().isSPIROrSPIRV())
41814182
GpuArchList.push_back(CudaArch::Generic);
41824183
else
41834184
GpuArchList.push_back(DefaultCudaArch);
@@ -4449,7 +4450,7 @@ class OffloadingActionBuilder final {
44494450
// compiler phases, including backend and assemble phases.
44504451
ActionList AL;
44514452
Action *BackendAction = nullptr;
4452-
if (ToolChains.front()->getTriple().isSPIRV()) {
4453+
if (ToolChains.front()->getTriple().isSPIROrSPIRV()) {
44534454
// Emit LLVM bitcode for SPIR-V targets. SPIR-V device tool chain
44544455
// (HIPSPVToolChain) runs post-link LLVM IR passes.
44554456
types::ID Output = Args.hasArg(options::OPT_S)
@@ -4770,7 +4771,7 @@ class OffloadingActionBuilder final {
47704771
DA->registerDependentActionInfo(
47714772
ToolChains[I], /*BoundArch=*/StringRef(), Action::OFK_OpenMP);
47724773

4773-
if (!ToolChains[I]->getTriple().isSPIR()) {
4774+
if (!ToolChains[I]->getTriple().isSPIROrSPIRV()) {
47744775
// Create object from the deps bitcode.
47754776
auto *BA = C.MakeAction<BackendJobAction>(DA, types::TY_PP_Asm);
47764777
auto *AA = C.MakeAction<AssembleJobAction>(BA, types::TY_Object);
@@ -5311,7 +5312,7 @@ class OffloadingActionBuilder final {
53115312
auto TargetTriple = TC->getTriple();
53125313
auto IsNVPTX = TargetTriple.isNVPTX();
53135314
auto IsAMDGCN = TargetTriple.isAMDGCN();
5314-
auto IsSPIR = TargetTriple.isSPIR();
5315+
auto IsSPIR = TargetTriple.isSPIROrSPIRV();
53155316
bool IsSpirvAOT = TargetTriple.isSPIRAOT();
53165317
const bool IsSYCLNativeCPU =
53175318
TC->getAuxTriple() &&
@@ -6167,7 +6168,7 @@ class OffloadingActionBuilder final {
61676168
// If any section found is an 'image' based object that was created
61686169
// with the intention of not requiring the matching SYCL target, do
61696170
// not emit the diagnostic.
6170-
if (SyclTarget.TC->getTriple().isSPIR()) {
6171+
if (SyclTarget.TC->getTriple().isSPIROrSPIRV()) {
61716172
bool SectionFound = false;
61726173
for (auto Section : UniqueSections) {
61736174
if (SectionFound)
@@ -6749,7 +6750,7 @@ class OffloadingActionBuilder final {
67496750
++TI) {
67506751
HasFPGATarget |= TI->second->getTriple().getSubArch() ==
67516752
llvm::Triple::SPIRSubArch_fpga;
6752-
HasSPIRTarget |= TI->second->getTriple().isSPIR();
6753+
HasSPIRTarget |= TI->second->getTriple().isSPIROrSPIRV();
67536754
}
67546755
bool isArchive = !(HostAction->getType() == types::TY_Object &&
67556756
isObjectFile(InputArg->getAsString(Args)));
@@ -9035,8 +9036,8 @@ InputInfoList Driver::BuildJobsForActionNoCache(
90359036
} else if (types::isFPGA(JA->getType())) {
90369037
std::string Ext(types::getTypeTempSuffix(JA->getType()));
90379038
types::ID TI = types::TY_Object;
9038-
if (EffectiveTriple.isSPIR()) {
9039-
if (!UI.DependentToolChain->getTriple().isSPIR())
9039+
if (EffectiveTriple.isSPIROrSPIRV()) {
9040+
if (!UI.DependentToolChain->getTriple().isSPIROrSPIRV())
90409041
continue;
90419042
// Output file from unbundle is FPGA device. Name the file
90429043
// accordingly.
@@ -10120,6 +10121,8 @@ const ToolChain &Driver::getOffloadingDeviceToolChain(
1012010121
switch (Target.getArch()) {
1012110122
case llvm::Triple::spir:
1012210123
case llvm::Triple::spir64:
10124+
case llvm::Triple::spirv32:
10125+
case llvm::Triple::spirv64:
1012310126
TC = std::make_unique<toolchains::SYCLToolChain>(*this, Target, HostTC,
1012410127
Args);
1012510128
break;

clang/lib/Driver/OffloadBundler.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,11 +614,11 @@ class ObjectFileHandler final : public FileHandler {
614614
// input is a bitcode for spir target we need to remove module-level
615615
// inline asm from it, if there is one, and recreate the buffer with new
616616
// contents.
617-
// TODO: remove this workaround once spir target gets asm parser.
617+
// TODO: remove this workaround once spir/spirv target gets asm parser.
618618
if (isBitcode((const unsigned char *)Buf->getBufferStart(),
619619
(const unsigned char *)Buf->getBufferEnd()))
620620
if (getTargetTriple(BundlerConfig.TargetNames[I], BundlerConfig)
621-
.isSPIR()) {
621+
.isSPIROrSPIRV()) {
622622
SMDiagnostic Err;
623623
std::unique_ptr<Module> Mod = parseIR(*Buf, Err, Context);
624624
if (!Mod)

clang/lib/Driver/SanitizerArgs.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,8 +1139,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
11391139
return;
11401140
GPUSanitize = true;
11411141
}
1142-
// SPIR sanitizer support is experimental and will pass a fixed set of flags
1143-
if (TC.getTriple().isSPIR()) {
1142+
// SPIR/SPIRV sanitizer support is experimental and will pass a fixed set of
1143+
// flags
1144+
if (TC.getTriple().isSPIROrSPIRV()) {
11441145
if (Sanitizers.has(SanitizerKind::Address)) {
11451146
CmdArgs.push_back("-fsanitize=address");
11461147
CmdArgs.push_back("-fsanitize-address-use-after-return=never");

clang/lib/Driver/ToolChain.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,8 +1537,8 @@ llvm::opt::DerivedArgList *ToolChain::TranslateOffloadTargetArgs(
15371537
DAL->append(A);
15381538
continue;
15391539
}
1540-
// SPIR-V special case for -mlong-double
1541-
if (getTriple().isSPIR() &&
1540+
// SPIR/SPIR-V special case for -mlong-double
1541+
if (getTriple().isSPIROrSPIRV() &&
15421542
A->getOption().matches(options::OPT_LongDouble_Group)) {
15431543
DAL->append(A);
15441544
continue;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4971,7 +4971,7 @@ static void ProcessVSRuntimeLibrary(const ArgList &Args,
49714971
const ToolChain &TC) {
49724972
unsigned RTOptionID = options::OPT__SLASH_MT;
49734973

4974-
bool isSPIR = TC.getTriple().isSPIR();
4974+
bool isSPIROrSPIRV = TC.getTriple().isSPIROrSPIRV();
49754975
bool isSYCL = Args.hasArg(options::OPT_fsycl);
49764976
// For SYCL Windows, /MD is the default.
49774977
if (isSYCL)
@@ -4997,23 +4997,23 @@ static void ProcessVSRuntimeLibrary(const ArgList &Args,
49974997
.Default(options::OPT__SLASH_MT);
49984998
SetArg = A;
49994999
}
5000-
if (isSYCL && !isSPIR && SetArg &&
5000+
if (isSYCL && !isSPIROrSPIRV && SetArg &&
50015001
(RTOptionID == options::OPT__SLASH_MT ||
50025002
RTOptionID == options::OPT__SLASH_MTd))
5003-
// Use of /MT or /MTd is not supported for SYCL.
5003+
// Use of /MT or /MTd is not supported for SYCL.
50045004
TC.getDriver().Diag(diag::err_drv_unsupported_opt_dpcpp)
50055005
<< SetArg->getOption().getName();
50065006

50075007
enum { addDEBUG = 0x1, addMT = 0x2, addDLL = 0x4 };
50085008
auto addPreDefines = [&](unsigned Defines) {
50095009
if (Defines & addDEBUG)
50105010
CmdArgs.push_back("-D_DEBUG");
5011-
if (Defines & addMT && !isSPIR)
5011+
if (Defines & addMT && !isSPIROrSPIRV)
50125012
CmdArgs.push_back("-D_MT");
5013-
if (Defines & addDLL && !isSPIR)
5013+
if (Defines & addDLL && !isSPIROrSPIRV)
50145014
CmdArgs.push_back("-D_DLL");
50155015
// for /MDd with spir targets
5016-
if ((Defines & addDLL) && (Defines & addDEBUG) && isSPIR) {
5016+
if ((Defines & addDLL) && (Defines & addDEBUG) && isSPIROrSPIRV) {
50175017
CmdArgs.push_back("-D_CONTAINER_DEBUG_LEVEL=0");
50185018
CmdArgs.push_back("-D_ITERATOR_DEBUG_LEVEL=0");
50195019
}
@@ -5282,8 +5282,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
52825282
options::OPT_fno_sycl_early_optimizations,
52835283
!IsFPGASYCLOffloadDevice))
52845284
CmdArgs.push_back("-fno-sycl-early-optimizations");
5285-
else if (RawTriple.isSPIR()) {
5286-
// Set `sycl-opt` option to configure LLVM passes for SPIR target
5285+
else if (RawTriple.isSPIROrSPIRV()) {
5286+
// Set `sycl-opt` option to configure LLVM passes for SPIR/SPIR-V target
52875287
CmdArgs.push_back("-mllvm");
52885288
CmdArgs.push_back("-sycl-opt");
52895289
}
@@ -5325,8 +5325,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
53255325
}
53265326

53275327
// Forward -fsycl-instrument-device-code option to cc1. This option will
5328-
// only be used for SPIR-V-based targets.
5329-
if (Triple.isSPIR())
5328+
// only be used for SPIR/SPIR-V based targets.
5329+
if (Triple.isSPIROrSPIRV())
53305330
if (Args.hasFlag(options::OPT_fsycl_instrument_device_code,
53315331
options::OPT_fno_sycl_instrument_device_code, true))
53325332
CmdArgs.push_back("-fsycl-instrument-device-code");
@@ -5412,8 +5412,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
54125412
CmdArgs.push_back("-fno-sycl-force-inline-kernel-lambda");
54135413

54145414
// Add -ffine-grained-bitfield-accesses option. This will be added
5415-
// only for SPIR based targets.
5416-
if (Triple.isSPIR()) {
5415+
// only for SPIR/SPIR-V based targets.
5416+
if (Triple.isSPIROrSPIRV()) {
54175417
// It cannot be enabled together with a sanitizer
54185418
if (!Args.getLastArg(options::OPT_fsanitize_EQ))
54195419
CmdArgs.push_back("-ffine-grained-bitfield-accesses");
@@ -5572,8 +5572,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
55725572
// are provided.
55735573
TC.addClangWarningOptions(CmdArgs);
55745574

5575-
// FIXME: Subclass ToolChain for SPIR and move this to addClangWarningOptions.
5576-
if (Triple.isSPIR() || Triple.isSPIRV())
5575+
// FIXME: Subclass ToolChain for SPIR/SPIR-V and move this to
5576+
// addClangWarningOptions.
5577+
if (Triple.isSPIROrSPIRV())
55775578
CmdArgs.push_back("-Wspir-compat");
55785579

55795580
// Select the appropriate action.
@@ -6353,9 +6354,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
63536354
if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
63546355
if (TC.getTriple().isX86())
63556356
A->render(Args, CmdArgs);
6356-
else if (TC.getTriple().isSPIR() &&
6357+
else if (TC.getTriple().isSPIROrSPIRV() &&
63576358
(A->getOption().getID() == options::OPT_mlong_double_64))
6358-
// Only allow for -mlong-double-64 for SPIR-V
6359+
// Only allow for -mlong-double-64 for SPIR/SPIR-V
63596360
A->render(Args, CmdArgs);
63606361
else if (TC.getTriple().isPPC() &&
63616362
(A->getOption().getID() != options::OPT_mlong_double_80))
@@ -9590,7 +9591,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
95909591
TypeArg = (InputType == types::TY_FPGA_AOCX) ? "aocx" : "aocr";
95919592
// When the output is a Tempfilelist, we know we are unbundling
95929593
// the .bc files from the archive.
9593-
if (!getToolChain().getTriple().isSPIR() ||
9594+
if (!getToolChain().getTriple().isSPIROrSPIRV() ||
95949595
JA.getType() == types::TY_Tempfilelist)
95959596
TypeArg = "aoo";
95969597
}
@@ -9604,7 +9605,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
96049605
auto SYCLTCRange = C.getOffloadToolChains<Action::OFK_SYCL>();
96059606
for (auto TI = SYCLTCRange.first, TE = SYCLTCRange.second; TI != TE; ++TI) {
96069607
llvm::Triple TT(TI->second->getTriple());
9607-
if (TT.isSPIR()) {
9608+
if (TT.isSPIROrSPIRV()) {
96089609
HasSPIRTarget = true;
96099610
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga)
96109611
HasFPGATarget = true;
@@ -9641,7 +9642,7 @@ void OffloadBundler::ConstructJobMultipleOutputs(
96419642
// aocx or aocr type bundles. Also, we only do a specific target
96429643
// unbundling, skipping the host side or device side.
96439644
if (types::isFPGA(InputType) || InputType == types::TY_Tempfilelist) {
9644-
if (getToolChain().getTriple().isSPIR()) {
9645+
if (getToolChain().getTriple().isSPIROrSPIRV()) {
96459646
if (Dep.DependentToolChain->getTriple().getSubArch() ==
96469647
llvm::Triple::SPIRSubArch_fpga) {
96479648
StringRef TypeName(types::getTypeName(InputType));
@@ -10470,7 +10471,7 @@ void SYCLPostLink::ConstructJob(Compilation &C, const JobAction &JA,
1047010471
addArgs(CmdArgs, TCArgs, {"-ir-output-only"});
1047110472
} else {
1047210473
assert(SYCLPostLink->getTrueType() == types::TY_Tempfiletable);
10473-
bool SplitEsimdByDefault = T.isSPIR();
10474+
bool SplitEsimdByDefault = T.isSPIROrSPIRV();
1047410475
bool SplitEsimd = TCArgs.hasFlag(
1047510476
options::OPT_fsycl_device_code_split_esimd,
1047610477
options::OPT_fno_sycl_device_code_split_esimd, SplitEsimdByDefault);
@@ -10766,12 +10767,6 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
1076610767
if (Args.hasArg(options::OPT_v))
1076710768
CmdArgs.push_back("--wrapper-verbose");
1076810769

10769-
// Pass the device triple to the linker wrapper tool for SYCL offload.
10770-
// Only spir64 is currently passed.
10771-
// TODO(NOM1): Support target triples in a more generic way.
10772-
// TODO(NOM3): Investigate why passing spir64-unknown-unknown does not work.
10773-
CmdArgs.push_back("--triple=spir64");
10774-
1077510770
// TODO(NOM2): Pass following options to clang-linker-wrapper.
1077610771
// Please refer to sycl/doc/design/OffloadDesign.md for details.
1077710772
// sycl-device-libraries
@@ -10814,20 +10809,30 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
1081410809
// device specific libraries that are needed. This provides the list of
1081510810
// files file only.
1081610811
// TODO: This generic list will be populated with only device binaries
10817-
// for spir64. Other targets (AOT and others) can represent a different
10812+
// for spir/spirv. Other targets (AOT and others) can represent a different
1081810813
// set of device libraries. We will cross that bridge when we begin to
1081910814
// enable the other possible targets.
1082010815
llvm::Triple TargetTriple;
1082110816
auto ToolChainRange = C.getOffloadToolChains<Action::OFK_SYCL>();
1082210817
for (auto &I :
1082310818
llvm::make_range(ToolChainRange.first, ToolChainRange.second)) {
1082410819
const ToolChain *TC = I.second;
10825-
if (TC->getTriple().isSPIR() &&
10820+
if (TC->getTriple().isSPIROrSPIRV() &&
1082610821
TC->getTriple().getSubArch() == llvm::Triple::NoSubArch) {
1082710822
TargetTriple = TC->getTriple();
1082810823
break;
1082910824
}
1083010825
}
10826+
// Pass the device triple to the linker wrapper tool for SYCL offload.
10827+
// Only spir64 or spirv64 is currently passed.
10828+
// TODO(NOM1): Support target triples in a more generic way.
10829+
// TODO(NOM3): Investigate why passing spirv64-unknown-unknown does not
10830+
// work.
10831+
if (TargetTriple.isSPIR())
10832+
CmdArgs.push_back("--triple=spir64");
10833+
else if (TargetTriple.isSPIRV())
10834+
CmdArgs.push_back("--triple=spirv64");
10835+
1083110836
SmallVector<std::string, 8> SYCLDeviceLibs;
1083210837
SYCLDeviceLibs = SYCL::getDeviceLibraries(C, TargetTriple,
1083310838
/*IsSpirvAOT=*/false);

0 commit comments

Comments
 (0)