Skip to content

Commit a617aad

Browse files
vmaksimosys-ce-bb
authored andcommitted
Implement SPV_INTEL_task_sequence extension (#2340)
Spec: KhronosGroup/SPIRV-Registry#192 Original commit: KhronosGroup/SPIRV-LLVM-Translator@fc9896b1fff0057
1 parent 4565039 commit a617aad

19 files changed

+527
-8
lines changed

llvm-spirv/include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,4 @@ EXT(SPV_INTEL_fpga_latency_control)
7070
EXT(SPV_INTEL_fp_max_error)
7171
EXT(SPV_INTEL_cache_controls)
7272
EXT(SPV_INTEL_subgroup_requirements)
73+
EXT(SPV_INTEL_task_sequence)

llvm-spirv/lib/SPIRV/OCLUtil.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,7 @@ SPIRAddressSpace getOCLOpaqueTypeAddrSpace(Op OpCode) {
900900
case internal::OpTypeJointMatrixINTEL:
901901
case internal::OpTypeJointMatrixINTELv2:
902902
case OpTypeCooperativeMatrixKHR:
903+
case internal::OpTypeTaskSequenceINTEL:
903904
return SPIRAS_Global;
904905
default:
905906
if (isSubgroupAvcINTELTypeOpCode(OpCode))

llvm-spirv/lib/SPIRV/SPIRVInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,7 @@ template <> inline void SPIRVMap<std::string, Op, SPIRVOpaqueType>::init() {
937937
_SPIRV_OP(CooperativeMatrixKHR)
938938
#undef _SPIRV_OP
939939
add("JointMatrixINTEL", internal::OpTypeJointMatrixINTEL);
940+
add("TaskSequenceINTEL", internal::OpTypeTaskSequenceINTEL);
940941
}
941942

942943
// Check if the module contains llvm.loop.* metadata

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ Type *SPIRVToLLVM::transType(SPIRVType *T, bool UseTPT) {
491491
return mapType(T, transType(static_cast<SPIRVType *>(
492492
BM->getEntry(FP->getPointerId()))));
493493
}
494+
case internal::OpTypeTaskSequenceINTEL:
495+
return mapType(
496+
T, llvm::TargetExtType::get(*Context, "spirv.TaskSequenceINTEL"));
494497

495498
default: {
496499
auto OC = T->getOpCode();
@@ -2292,6 +2295,7 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
22922295
}
22932296
case internal::OpTypeJointMatrixINTEL:
22942297
case OpTypeCooperativeMatrixKHR:
2298+
case internal::OpTypeTaskSequenceINTEL:
22952299
return mapValue(BV, transSPIRVBuiltinFromInst(CC, BB));
22962300
default:
22972301
llvm_unreachable("Unhandled type!");
@@ -3367,6 +3371,7 @@ Instruction *SPIRVToLLVM::transSPIRVBuiltinFromInst(SPIRVInstruction *BI,
33673371
case OpSUDotAccSatKHR:
33683372
case internal::OpJointMatrixLoadINTEL:
33693373
case OpCooperativeMatrixLoadKHR:
3374+
case internal::OpTaskSequenceCreateINTEL:
33703375
AddRetTypePostfix = true;
33713376
break;
33723377
default: {

llvm-spirv/lib/SPIRV/SPIRVUtil.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,8 @@ SPIR::TypePrimitiveEnum getOCLTypePrimitiveEnum(StringRef TyName) {
12541254
/// \param Signed indicates integer type should be translated as signed.
12551255
/// \param VoidPtr indicates i8* should be translated as void*.
12561256
static SPIR::RefParamType transTypeDesc(Type *Ty,
1257-
const BuiltinArgTypeMangleInfo &Info) {
1257+
const BuiltinArgTypeMangleInfo &Info,
1258+
StringRef InstName = "") {
12581259
bool Signed = Info.IsSigned;
12591260
unsigned Attr = Info.Attr;
12601261
bool VoidPtr = Info.IsVoidPtr;
@@ -1363,8 +1364,14 @@ static SPIR::RefParamType transTypeDesc(Type *Ty,
13631364
auto *ET = TPT->getElementType();
13641365
SPIR::ParamType *EPT = nullptr;
13651366
if (isa<FunctionType>(ET)) {
1366-
assert(isVoidFuncTy(cast<FunctionType>(ET)) && "Not supported");
1367-
EPT = new SPIR::BlockType;
1367+
FunctionType *FT = cast<FunctionType>(ET);
1368+
if (InstName.consume_front(kSPIRVName::Prefix) &&
1369+
InstName.starts_with("TaskSequence")) {
1370+
EPT = new SPIR::PointerType(transTypeDesc(FT->getReturnType(), Info));
1371+
} else {
1372+
assert((isVoidFuncTy(FT)) && "Not supported");
1373+
EPT = new SPIR::BlockType;
1374+
}
13681375
} else if (auto *StructTy = dyn_cast<StructType>(ET)) {
13691376
LLVM_DEBUG(dbgs() << "ptr to struct: " << *Ty << '\n');
13701377
auto TyName = StructTy->getStructName();
@@ -1692,7 +1699,7 @@ std::string mangleBuiltin(StringRef UniqName, ArrayRef<Type *> ArgTypes,
16921699
T = MangleInfo.PointerTy;
16931700
}
16941701
FD.Parameters.emplace_back(
1695-
transTypeDesc(T, BtnInfo->getTypeMangleInfo(I)));
1702+
transTypeDesc(T, BtnInfo->getTypeMangleInfo(I), UniqName));
16961703
}
16971704
}
16981705
// Ellipsis must be the last argument of any function

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,8 @@ SPIRVType *LLVMToSPIRVBase::transType(Type *T) {
621621
Args.emplace_back(transConstant(getUInt32(M, Op)));
622622
return mapType(T, BM->addCooperativeMatrixKHRType(ElemTy, Args));
623623
}
624+
case internal::OpTypeTaskSequenceINTEL:
625+
return mapType(T, BM->addTaskSequenceINTELType());
624626
default:
625627
if (isSubgroupAvcINTELTypeOpCode(Opcode))
626628
return mapType(T, BM->addSubgroupAvcINTELType(Opcode));

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ class SPIRVInstTemplateBase : public SPIRVInstruction {
226226
virtual void init() {}
227227
virtual void initImpl(Op OC, bool HasId = true, SPIRVWord WC = 0,
228228
bool VariWC = false, unsigned Lit1 = ~0U,
229-
unsigned Lit2 = ~0U, unsigned Lit3 = ~0U) {
229+
unsigned Lit2 = ~0U, unsigned Lit3 = ~0U,
230+
unsigned Lit4 = ~0U) {
230231
OpCode = OC;
231232
if (!HasId) {
232233
setHasNoId();
@@ -238,6 +239,7 @@ class SPIRVInstTemplateBase : public SPIRVInstruction {
238239
addLit(Lit1);
239240
addLit(Lit2);
240241
addLit(Lit3);
242+
addLit(Lit4);
241243
}
242244
bool isOperandLiteral(unsigned I) const override { return Lit.count(I); }
243245
void addLit(unsigned L) {
@@ -364,14 +366,16 @@ class SPIRVInstTemplateBase : public SPIRVInstruction {
364366

365367
template <typename BT = SPIRVInstTemplateBase, Op OC = OpNop, bool HasId = true,
366368
SPIRVWord WC = 0, bool HasVariableWC = false, unsigned Literal1 = ~0U,
367-
unsigned Literal2 = ~0U, unsigned Literal3 = ~0U>
369+
unsigned Literal2 = ~0U, unsigned Literal3 = ~0U,
370+
unsigned Literal4 = ~0U>
368371
class SPIRVInstTemplate : public BT {
369372
public:
370373
typedef BT BaseTy;
371374
SPIRVInstTemplate() { init(); }
372375
~SPIRVInstTemplate() override {}
373376
void init() override {
374-
this->initImpl(OC, HasId, WC, HasVariableWC, Literal1, Literal2, Literal3);
377+
this->initImpl(OC, HasId, WC, HasVariableWC, Literal1, Literal2, Literal3,
378+
Literal4);
375379
}
376380
};
377381

@@ -3854,5 +3858,85 @@ template <Op OC> class SPIRVReadClockKHRInstBase : public SPIRVUnaryInst<OC> {
38543858
_SPIRV_OP(ReadClockKHR)
38553859
#undef _SPIRV_OP
38563860

3861+
class SPIRVTaskSequenceINTELInstBase : public SPIRVInstTemplateBase {
3862+
public:
3863+
std::optional<ExtensionID> getRequiredExtension() const override {
3864+
return ExtensionID::SPV_INTEL_task_sequence;
3865+
}
3866+
};
3867+
3868+
class SPIRVTaskSequenceINTELInst : public SPIRVTaskSequenceINTELInstBase {
3869+
public:
3870+
SPIRVCapVec getRequiredCapability() const override {
3871+
return getVec(internal::CapabilityTaskSequenceINTEL);
3872+
}
3873+
};
3874+
3875+
class SPIRVTaskSequenceCreateINTELInst : public SPIRVTaskSequenceINTELInst {
3876+
protected:
3877+
void validate() const override {
3878+
SPIRVInstruction::validate();
3879+
std::string InstName = "TaskSequenceCreateINTEL";
3880+
SPIRVErrorLog &SPVErrLog = this->getModule()->getErrorLog();
3881+
3882+
SPIRVType *ResTy = this->getType();
3883+
SPVErrLog.checkError(
3884+
ResTy->isTypeTaskSequenceINTEL(), SPIRVEC_InvalidInstruction,
3885+
InstName + "\nResult must be TaskSequenceINTEL type\n");
3886+
3887+
SPIRVValue *Func =
3888+
const_cast<SPIRVTaskSequenceCreateINTELInst *>(this)->getOperand(0);
3889+
SPVErrLog.checkError(
3890+
Func->getOpCode() == OpFunction, SPIRVEC_InvalidInstruction,
3891+
InstName + "\nFirst argument is expected to be a function.\n");
3892+
3893+
SPIRVConstant *PipelinedConst = static_cast<SPIRVConstant *>(
3894+
const_cast<SPIRVTaskSequenceCreateINTELInst *>(this)->getOperand(1));
3895+
const int Pipelined = PipelinedConst->getZExtIntValue();
3896+
SPVErrLog.checkError(Pipelined >= -1, SPIRVEC_InvalidInstruction,
3897+
InstName + "\nPipeline must be a 32 bit integer with "
3898+
"the value bigger or equal to -1.\n");
3899+
3900+
const int ClusterMode =
3901+
static_cast<SPIRVConstant *>(
3902+
const_cast<SPIRVTaskSequenceCreateINTELInst *>(this)->getOperand(2))
3903+
->getZExtIntValue();
3904+
SPVErrLog.checkError(
3905+
ClusterMode >= -1 && ClusterMode <= 1, SPIRVEC_InvalidInstruction,
3906+
InstName + "\nClusterMode valid values are -1, 0, 1.\n");
3907+
3908+
const uint32_t GetCapacity =
3909+
static_cast<SPIRVConstant *>(
3910+
const_cast<SPIRVTaskSequenceCreateINTELInst *>(this)->getOperand(3))
3911+
->getZExtIntValue();
3912+
SPVErrLog.checkError(
3913+
GetCapacity, SPIRVEC_InvalidInstruction,
3914+
InstName + "\nGetCapacity must be unsigned 32 bit integer.\n");
3915+
3916+
const uint32_t AsyncCapacity =
3917+
static_cast<SPIRVConstant *>(
3918+
const_cast<SPIRVTaskSequenceCreateINTELInst *>(this)->getOperand(4))
3919+
->getZExtIntValue();
3920+
SPVErrLog.checkError(
3921+
AsyncCapacity, SPIRVEC_InvalidInstruction,
3922+
InstName + "\nAsyncCapacity must be unsigned 32 bit integer.\n");
3923+
}
3924+
};
3925+
3926+
#define _SPIRV_OP(x, ...) \
3927+
typedef SPIRVInstTemplate<SPIRVTaskSequenceINTELInst, \
3928+
internal::Op##x##INTEL, __VA_ARGS__> \
3929+
SPIRV##x##INTEL;
3930+
_SPIRV_OP(TaskSequenceAsync, false, 2, true)
3931+
_SPIRV_OP(TaskSequenceGet, true, 4, false)
3932+
_SPIRV_OP(TaskSequenceRelease, false, 2, false)
3933+
#undef _SPIRV_OP
3934+
#define _SPIRV_OP(x, ...) \
3935+
typedef SPIRVInstTemplate<SPIRVTaskSequenceCreateINTELInst, \
3936+
internal::Op##x##INTEL, __VA_ARGS__> \
3937+
SPIRV##x##INTEL;
3938+
_SPIRV_OP(TaskSequenceCreate, true, 8, false, 1, 2, 3, 4)
3939+
#undef _SPIRV_OP
3940+
38573941
} // namespace SPIRV
38583942
#endif // SPIRV_LIBSPIRV_SPIRVINSTRUCTION_H

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ class SPIRVModuleImpl : public SPIRVModule {
247247
addJointMatrixINTELType(SPIRVType *, std::vector<SPIRVValue *>) override;
248248
SPIRVTypeCooperativeMatrixKHR *
249249
addCooperativeMatrixKHRType(SPIRVType *, std::vector<SPIRVValue *>) override;
250+
SPIRVTypeTaskSequenceINTEL *addTaskSequenceINTELType() override;
250251
SPIRVType *addOpaqueGenericType(Op) override;
251252
SPIRVTypeDeviceEvent *addDeviceEventType() override;
252253
SPIRVTypeQueue *addQueueType() override;
@@ -1021,6 +1022,10 @@ SPIRVModuleImpl::addCooperativeMatrixKHRType(SPIRVType *CompType,
10211022
new SPIRVTypeCooperativeMatrixKHR(this, getId(), CompType, Args));
10221023
}
10231024

1025+
SPIRVTypeTaskSequenceINTEL *SPIRVModuleImpl::addTaskSequenceINTELType() {
1026+
return addType(new SPIRVTypeTaskSequenceINTEL(this, getId()));
1027+
}
1028+
10241029
SPIRVType *SPIRVModuleImpl::addOpaqueGenericType(Op TheOpCode) {
10251030
return addType(new SPIRVTypeOpaqueGeneric(TheOpCode, this, getId()));
10261031
}

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ class SPIRVTypeBufferSurfaceINTEL;
9797
class SPIRVTypeTokenINTEL;
9898
class SPIRVTypeJointMatrixINTEL;
9999
class SPIRVTypeCooperativeMatrixKHR;
100+
class SPIRVTypeTaskSequenceINTEL;
100101

101102
typedef SPIRVBasicBlock SPIRVLabel;
102103
struct SPIRVTypeImageDescriptor;
@@ -264,6 +265,7 @@ class SPIRVModule {
264265
addJointMatrixINTELType(SPIRVType *, std::vector<SPIRVValue *>) = 0;
265266
virtual SPIRVTypeCooperativeMatrixKHR *
266267
addCooperativeMatrixKHRType(SPIRVType *, std::vector<SPIRVValue *>) = 0;
268+
virtual SPIRVTypeTaskSequenceINTEL *addTaskSequenceINTELType() = 0;
267269
virtual SPIRVTypeVoid *addVoidType() = 0;
268270
virtual SPIRVType *addOpaqueGenericType(Op) = 0;
269271
virtual SPIRVTypeDeviceEvent *addDeviceEventType() = 0;

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ template <> inline void SPIRVMap<Capability, std::string>::init() {
686686
"CooperativeMatrixCheckedInstructionsINTEL");
687687
add(internal::CapabilitySubgroupRequirementsINTEL,
688688
"SubgroupRequirementsINTEL");
689+
add(internal::CapabilityTaskSequenceINTEL, "TaskSequenceINTEL");
689690
}
690691
SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap)
691692

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCode.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ inline bool isTypeOpCode(Op OpCode) {
221221
isVCOpCode(OpCode) || OC == internal::OpTypeTokenINTEL ||
222222
OC == internal::OpTypeJointMatrixINTEL ||
223223
OC == internal::OpTypeJointMatrixINTELv2 ||
224-
OC == OpTypeCooperativeMatrixKHR;
224+
OC == OpTypeCooperativeMatrixKHR ||
225+
OC == internal::OpTypeTaskSequenceINTEL;
225226
}
226227

227228
inline bool isSpecConstantOpCode(Op OpCode) {

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCodeEnumInternal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,9 @@ _SPIRV_OP_INTERNAL(ComplexFDivINTEL, internal::ComplexFDivINTEL)
3131
_SPIRV_OP_INTERNAL(MaskedGatherINTEL, internal::OpMaskedGatherINTEL)
3232
_SPIRV_OP_INTERNAL(MaskedScatterINTEL, internal::OpMaskedScatterINTEL)
3333
_SPIRV_OP_INTERNAL(RoundFToTF32INTEL, internal::RoundFToTF32INTEL)
34+
_SPIRV_OP_INTERNAL(TaskSequenceAsyncINTEL, internal::OpTaskSequenceAsyncINTEL)
35+
_SPIRV_OP_INTERNAL(TaskSequenceCreateINTEL, internal::OpTaskSequenceCreateINTEL)
36+
_SPIRV_OP_INTERNAL(TaskSequenceGetINTEL, internal::OpTaskSequenceGetINTEL)
37+
_SPIRV_OP_INTERNAL(TaskSequenceReleaseINTEL,
38+
internal::OpTaskSequenceReleaseINTEL)
39+
_SPIRV_OP_INTERNAL(TypeTaskSequenceINTEL, internal::OpTypeTaskSequenceINTEL)

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVType.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ bool SPIRVType::isTypeSubgroupAvcMceINTEL() const {
239239
OpCode == OpTypeAvcMceResultINTEL;
240240
}
241241

242+
bool SPIRVType::isTypeTaskSequenceINTEL() const {
243+
return OpCode == internal::OpTypeTaskSequenceINTEL;
244+
}
245+
242246
bool SPIRVType::isTypeVectorOrScalarInt() const {
243247
return isTypeInt() || isTypeVectorInt();
244248
}

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVType.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class SPIRVType : public SPIRVEntry {
106106
bool isTypeVectorPointer() const;
107107
bool isTypeSubgroupAvcINTEL() const;
108108
bool isTypeSubgroupAvcMceINTEL() const;
109+
bool isTypeTaskSequenceINTEL() const;
109110
};
110111

111112
class SPIRVTypeVoid : public SPIRVType {
@@ -1155,5 +1156,24 @@ class SPIRVTypeCooperativeMatrixKHR : public SPIRVType {
11551156
}
11561157
};
11571158

1159+
class SPIRVTypeTaskSequenceINTEL : public SPIRVType {
1160+
public:
1161+
// Complete constructor
1162+
SPIRVTypeTaskSequenceINTEL(SPIRVModule *M, SPIRVId TheId)
1163+
: SPIRVType(M, 2, internal::OpTypeTaskSequenceINTEL, TheId) {}
1164+
// Incomplete constructor
1165+
SPIRVTypeTaskSequenceINTEL() : SPIRVType(internal::OpTypeTaskSequenceINTEL) {}
1166+
// _SPIRV_DCL_ENCDEC
1167+
SPIRVCapVec getRequiredCapability() const override {
1168+
return getVec(internal::CapabilityTaskSequenceINTEL);
1169+
}
1170+
std::optional<ExtensionID> getRequiredExtension() const override {
1171+
return ExtensionID::SPV_INTEL_task_sequence;
1172+
}
1173+
1174+
protected:
1175+
_SPIRV_DEF_ENCDEC1(Id)
1176+
};
1177+
11581178
} // namespace SPIRV
11591179
#endif // SPIRV_LIBSPIRV_SPIRVTYPE_H

llvm-spirv/lib/SPIRV/libSPIRV/spirv_internal.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,16 @@ enum InternalOp {
6969
IOpJointMatrixUSMadINTEL = 6129,
7070
IOpJointMatrixUUMadINTEL = 6130,
7171
IOpArithmeticFenceINTEL = 6145,
72+
IOpTaskSequenceCreateINTEL = 6163,
73+
IOpTaskSequenceAsyncINTEL = 6164,
74+
IOpTaskSequenceGetINTEL = 6165,
75+
IOpTaskSequenceReleaseINTEL = 6166,
7276
IOpTypeJointMatrixINTELv2 = 6184,
7377
IOpCooperativeMatrixLoadCheckedINTEL = 6193,
7478
IOpCooperativeMatrixStoreCheckedINTEL = 6194,
7579
IOpCooperativeMatrixConstructCheckedINTEL = 6195,
7680
IOpJointMatrixWorkItemLengthINTEL = 6410,
81+
IOpTypeTaskSequenceINTEL = 6411,
7782
IOpComplexFMulINTEL = 6415,
7883
IOpComplexFDivINTEL = 6416,
7984
IOpRoundFToTF32INTEL = 6426,
@@ -108,6 +113,7 @@ enum InternalCapability {
108113
ICapabilityHWThreadQueryINTEL = 6134,
109114
ICapFPArithmeticFenceINTEL = 6144,
110115
ICapGlobalVariableDecorationsINTEL = 6146,
116+
ICapabilityTaskSequenceINTEL = 6162,
111117
ICapabilityCooperativeMatrixCheckedInstructionsINTEL = 6192,
112118
ICapabilityCooperativeMatrixPrefetchINTEL = 6411,
113119
ICapabilityComplexFloatMulDivINTEL = 6414,
@@ -217,6 +223,14 @@ _SPIRV_OP(Op, RoundFToTF32INTEL)
217223
_SPIRV_OP(Capability, CacheControlsINTEL)
218224

219225
_SPIRV_OP(Capability, SubgroupRequirementsINTEL)
226+
227+
_SPIRV_OP(Capability, TaskSequenceINTEL)
228+
_SPIRV_OP(Op, TaskSequenceCreateINTEL)
229+
_SPIRV_OP(Op, TaskSequenceAsyncINTEL)
230+
_SPIRV_OP(Op, TaskSequenceGetINTEL)
231+
_SPIRV_OP(Op, TaskSequenceReleaseINTEL)
232+
_SPIRV_OP(Op, TypeTaskSequenceINTEL)
233+
220234
#undef _SPIRV_OP
221235

222236
constexpr SourceLanguage SourceLanguagePython =

0 commit comments

Comments
 (0)