34#define DEBUG_TYPE "spirv-module-analysis"
38 cl::desc(
"Dump MIR with SPIR-V dependencies info"),
43 cl::desc(
"SPIR-V capabilities to avoid if there are "
44 "other options enabling a feature"),
47 "SPIR-V Shader capability")));
61 unsigned DefaultVal = 0) {
63 const auto &
Op = MdNode->getOperand(
OpIndex);
70getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category,
76 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
78 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
83 bool MinVerOK = SPIRVVersion.
empty() || SPIRVVersion >= ReqMinVer;
85 ReqMaxVer.
empty() || SPIRVVersion.
empty() || SPIRVVersion <= ReqMaxVer;
88 if (ReqCaps.
empty()) {
89 if (ReqExts.
empty()) {
90 if (MinVerOK && MaxVerOK)
91 return {
true, {}, {}, ReqMinVer, ReqMaxVer};
94 }
else if (MinVerOK && MaxVerOK) {
95 if (ReqCaps.
size() == 1) {
96 auto Cap = ReqCaps[0];
99 SPIRV::OperandCategory::CapabilityOperand, Cap));
100 return {
true, {Cap}, std::move(ReqExts), ReqMinVer, ReqMaxVer};
110 for (
auto Cap : ReqCaps)
113 for (
size_t i = 0, Sz = UseCaps.
size(); i < Sz; ++i) {
114 auto Cap = UseCaps[i];
115 if (i == Sz - 1 || !AvoidCaps.
S.
contains(Cap)) {
117 SPIRV::OperandCategory::CapabilityOperand, Cap));
118 return {
true, {Cap}, std::move(ReqExts), ReqMinVer, ReqMaxVer};
126 if (
llvm::all_of(ReqExts, [&ST](
const SPIRV::Extension::Extension &Ext) {
127 return ST.canUseExtension(Ext);
138void SPIRVModuleAnalysis::setBaseInfo(
const Module &M) {
142 MAI.RegisterAliasTable.clear();
143 MAI.InstrsToDelete.clear();
144 MAI.GlobalObjMap.clear();
145 MAI.GlobalVarList.clear();
146 MAI.ExtInstSetMap.clear();
148 MAI.Reqs.initAvailableCapabilities(*ST);
151 if (
auto MemModel =
M.getNamedMetadata(
"spirv.MemoryModel")) {
152 auto MemMD = MemModel->getOperand(0);
153 MAI.Addr =
static_cast<SPIRV::AddressingModel::AddressingModel
>(
154 getMetadataUInt(MemMD, 0));
156 static_cast<SPIRV::MemoryModel::MemoryModel
>(getMetadataUInt(MemMD, 1));
159 MAI.Mem = ST->isShader() ? SPIRV::MemoryModel::GLSL450
160 : SPIRV::MemoryModel::OpenCL;
161 if (
MAI.Mem == SPIRV::MemoryModel::OpenCL) {
162 unsigned PtrSize = ST->getPointerSize();
163 MAI.Addr = PtrSize == 32 ? SPIRV::AddressingModel::Physical32
164 : PtrSize == 64 ? SPIRV::AddressingModel::Physical64
165 : SPIRV::AddressingModel::Logical;
168 MAI.Addr = SPIRV::AddressingModel::Logical;
173 if (
auto VerNode =
M.getNamedMetadata(
"opencl.ocl.version")) {
174 MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_C;
177 assert(VerNode->getNumOperands() > 0 &&
"Invalid SPIR");
178 auto VersionMD = VerNode->getOperand(0);
179 unsigned MajorNum = getMetadataUInt(VersionMD, 0, 2);
180 unsigned MinorNum = getMetadataUInt(VersionMD, 1);
181 unsigned RevNum = getMetadataUInt(VersionMD, 2);
184 (std::max(1U, MajorNum) * 100 + MinorNum) * 1000 + RevNum;
187 if (
auto *CxxVerNode =
M.getNamedMetadata(
"opencl.cxx.version")) {
188 assert(CxxVerNode->getNumOperands() > 0 &&
"Invalid SPIR");
189 auto *CxxMD = CxxVerNode->getOperand(0);
191 (getMetadataUInt(CxxMD, 0) * 100 + getMetadataUInt(CxxMD, 1)) * 1000 +
192 getMetadataUInt(CxxMD, 2);
193 if ((
MAI.SrcLangVersion == 200000 && CxxVer == 100000) ||
194 (
MAI.SrcLangVersion == 300000 && CxxVer == 202100000)) {
195 MAI.SrcLang = SPIRV::SourceLanguage::CPP_for_OpenCL;
196 MAI.SrcLangVersion = CxxVer;
199 "opencl cxx version is not compatible with opencl c version!");
207 if (!ST->isShader()) {
208 MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_CPP;
209 MAI.SrcLangVersion = 100000;
211 MAI.SrcLang = SPIRV::SourceLanguage::Unknown;
212 MAI.SrcLangVersion = 0;
216 if (
auto ExtNode =
M.getNamedMetadata(
"opencl.used.extensions")) {
217 for (
unsigned I = 0,
E = ExtNode->getNumOperands();
I !=
E; ++
I) {
218 MDNode *MD = ExtNode->getOperand(
I);
228 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::MemoryModelOperand,
230 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::SourceLanguageOperand,
232 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::AddressingModelOperand,
235 if (
MAI.Mem == SPIRV::MemoryModel::VulkanKHR)
236 MAI.Reqs.addExtension(SPIRV::Extension::SPV_KHR_vulkan_memory_model);
238 if (!ST->isShader()) {
240 MAI.ExtInstSetMap[
static_cast<unsigned>(
241 SPIRV::InstructionSet::OpenCL_std)] =
MAI.getNextIDRegister();
252 if (
UseMI.getOpcode() != SPIRV::OpDecorate &&
253 UseMI.getOpcode() != SPIRV::OpMemberDecorate)
256 for (
unsigned I = 0;
I <
UseMI.getNumOperands(); ++
I) {
274 for (
unsigned i = 0; i <
MI.getNumOperands(); ++i) {
283 unsigned Opcode =
MI.getOpcode();
284 if ((Opcode == SPIRV::OpDecorate) && i >= 2) {
285 unsigned DecorationID =
MI.getOperand(1).getImm();
286 if (DecorationID != SPIRV::Decoration::FuncParamAttr &&
287 DecorationID != SPIRV::Decoration::UserSemantic &&
288 DecorationID != SPIRV::Decoration::CacheControlLoadINTEL &&
289 DecorationID != SPIRV::Decoration::CacheControlStoreINTEL)
295 if (!UseDefReg && MO.
isDef()) {
303 dbgs() <<
"Unexpectedly, no global id found for the operand ";
305 dbgs() <<
"\nInstruction: ";
324 appendDecorationsForReg(
MI.getMF()->getRegInfo(), DefReg, Signature);
331 unsigned Opcode =
MI.getOpcode();
333 case SPIRV::OpTypeForwardPointer:
336 case SPIRV::OpVariable:
337 return static_cast<SPIRV::StorageClass::StorageClass
>(
338 MI.getOperand(2).
getImm()) != SPIRV::StorageClass::Function;
339 case SPIRV::OpFunction:
340 case SPIRV::OpFunctionParameter:
343 if (GR->hasConstFunPtr() && Opcode == SPIRV::OpUndef) {
351 if (GR->getFunctionDefinitionByUse(&
MI.getOperand(0))) {
353 unsigned UseOp =
UseMI.getOpcode();
354 if (UseOp == SPIRV::OpConstantFunctionPointerINTEL ||
355 UseOp == SPIRV::OpEnqueueKernel) {
356 MAI.setSkipEmission(&
MI);
362 if (
UseMI.getOpcode() != SPIRV::OpConstantFunctionPointerINTEL)
368 MAI.setSkipEmission(&
MI);
372 return TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
373 TII->isInlineAsmDefInstr(
MI);
382void SPIRVModuleAnalysis::visitFunPtrUse(
385 std::map<const Value *, unsigned> &GlobalToGReg,
387 const MachineOperand *OpFunDef = GR->getFunctionDefinitionByUse(FunPtrOp);
390 const MachineInstr *OpDefMI = OpFunDef->
getParent();
393 const MachineRegisterInfo &FunDefMRI = FunDefMF->
getRegInfo();
395 visitDecl(FunDefMRI, SignatureToGReg, GlobalToGReg, FunDefMF, *OpDefMI);
397 }
while (OpDefMI && (OpDefMI->
getOpcode() == SPIRV::OpFunction ||
398 OpDefMI->
getOpcode() == SPIRV::OpFunctionParameter));
400 MCRegister GlobalFunDefReg =
401 MAI.getRegisterAlias(FunDefMF, OpFunDef->
getReg());
403 "Function definition must refer to a global register");
404 MAI.setRegisterAlias(MF, OpReg, GlobalFunDefReg);
409void SPIRVModuleAnalysis::visitDecl(
411 std::map<const Value *, unsigned> &GlobalToGReg,
const MachineFunction *MF,
413 unsigned Opcode =
MI.getOpcode();
416 for (
const MachineOperand &MO :
MI.operands()) {
421 if (Opcode == SPIRV::OpConstantFunctionPointerINTEL &&
423 visitFunPtrUse(OpReg, &
MI.getOperand(2), SignatureToGReg, GlobalToGReg,
428 if (
MAI.hasRegisterAlias(MF, MO.
getReg()))
432 if (isDeclSection(MRI, *OpDefMI))
433 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF, *OpDefMI);
439 dbgs() <<
"Unexpectedly, no unique definition for the operand ";
441 dbgs() <<
"\nInstruction: ";
446 "No unique definition is found for the virtual register");
450 bool IsFunDef =
false;
451 if (TII->isSpecConstantInstr(
MI)) {
452 GReg =
MAI.getNextIDRegister();
454 }
else if (Opcode == SPIRV::OpFunction ||
455 Opcode == SPIRV::OpFunctionParameter) {
456 GReg = handleFunctionOrParameter(MF,
MI, GlobalToGReg, IsFunDef);
457 }
else if (Opcode == SPIRV::OpTypeStruct ||
458 Opcode == SPIRV::OpConstantComposite) {
459 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
460 const MachineInstr *NextInstr =
MI.getNextNode();
462 ((Opcode == SPIRV::OpTypeStruct &&
463 NextInstr->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL) ||
464 (Opcode == SPIRV::OpConstantComposite &&
466 SPIRV::OpConstantCompositeContinuedINTEL))) {
467 MCRegister Tmp = handleTypeDeclOrConstant(*NextInstr, SignatureToGReg);
469 MAI.setSkipEmission(NextInstr);
472 }
else if (TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
473 TII->isInlineAsmDefInstr(
MI)) {
474 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
475 }
else if (Opcode == SPIRV::OpVariable) {
476 GReg = handleVariable(MF,
MI, GlobalToGReg);
479 dbgs() <<
"\nInstruction: ";
485 MAI.setRegisterAlias(MF,
MI.getOperand(0).getReg(), GReg);
487 MAI.setSkipEmission(&
MI);
490MCRegister SPIRVModuleAnalysis::handleFunctionOrParameter(
492 std::map<const Value *, unsigned> &GlobalToGReg,
bool &IsFunDef) {
493 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
494 assert(GObj &&
"Unregistered global definition");
498 assert(
F &&
"Expected a reference to a function or an argument");
499 IsFunDef = !
F->isDeclaration();
500 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
503 MCRegister GReg =
MAI.getNextIDRegister();
511SPIRVModuleAnalysis::handleTypeDeclOrConstant(
const MachineInstr &
MI,
514 auto [It,
Inserted] = SignatureToGReg.try_emplace(MISign);
517 MCRegister GReg =
MAI.getNextIDRegister();
523MCRegister SPIRVModuleAnalysis::handleVariable(
525 std::map<const Value *, unsigned> &GlobalToGReg) {
526 MAI.GlobalVarList.push_back(&
MI);
527 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
528 assert(GObj &&
"Unregistered global definition");
529 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
532 MCRegister GReg =
MAI.getNextIDRegister();
536 MAI.GlobalObjMap[GV] = GReg;
540void SPIRVModuleAnalysis::collectDeclarations(
const Module &M) {
542 std::map<const Value *, unsigned> GlobalToGReg;
543 for (
const Function &
F : M) {
544 MachineFunction *MF = MMI->getMachineFunction(
F);
547 const MachineRegisterInfo &MRI = MF->
getRegInfo();
548 unsigned PastHeader = 0;
549 for (MachineBasicBlock &
MBB : *MF) {
550 for (MachineInstr &
MI :
MBB) {
551 if (
MI.getNumOperands() == 0)
553 unsigned Opcode =
MI.getOpcode();
554 if (Opcode == SPIRV::OpFunction) {
555 if (PastHeader == 0) {
559 }
else if (Opcode == SPIRV::OpFunctionParameter) {
562 }
else if (PastHeader > 0) {
566 const MachineOperand &DefMO =
MI.getOperand(0);
568 case SPIRV::OpExtension:
569 MAI.Reqs.addExtension(SPIRV::Extension::Extension(DefMO.
getImm()));
570 MAI.setSkipEmission(&
MI);
572 case SPIRV::OpCapability:
573 MAI.Reqs.addCapability(SPIRV::Capability::Capability(DefMO.
getImm()));
574 MAI.setSkipEmission(&
MI);
579 if (DefMO.
isReg() && isDeclSection(MRI,
MI) &&
580 !
MAI.hasRegisterAlias(MF, DefMO.
getReg()))
581 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF,
MI);
585 if (Opcode == SPIRV::OpEnqueueKernel &&
MI.getNumOperands() > 8) {
586 const MachineOperand &InvokeMO =
MI.getOperand(8);
587 if (InvokeMO.
isReg()) {
589 if (!
MAI.hasRegisterAlias(MF, InvokeReg)) {
590 if (
const MachineInstr *
DefMI =
594 if (GR->getFunctionDefinitionByUse(FunPtrOp))
595 visitFunPtrUse(InvokeReg, FunPtrOp, SignatureToGReg,
614 if (
MI.getOpcode() == SPIRV::OpDecorate) {
616 auto Dec =
MI.getOperand(1).getImm();
617 if (Dec == SPIRV::Decoration::LinkageAttributes) {
618 auto Lnk =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
619 if (Lnk == SPIRV::LinkageType::Import) {
624 MAI.GlobalObjMap[ImportedFunc] =
625 MAI.getRegisterAlias(
MI.getMF(), Target);
628 }
else if (
MI.getOpcode() == SPIRV::OpFunction) {
631 MCRegister GlobalReg =
MAI.getRegisterAlias(
MI.getMF(),
Reg);
633 MAI.GlobalObjMap[
F] = GlobalReg;
645 auto FoundMI = IS.insert(std::move(MISign));
646 if (!FoundMI.second) {
647 if (
MI.getOpcode() == SPIRV::OpDecorate) {
649 "Decoration instructions must have at least 2 operands");
651 "Only OpDecorate instructions can be duplicates");
656 if (
MI.getOperand(1).getImm() != SPIRV::Decoration::FPFastMathMode)
661 if (instrToSignature(*OrigMI, MAI,
true) == MISign) {
662 assert(OrigMI->getNumOperands() ==
MI.getNumOperands() &&
663 "Original instruction must have the same number of operands");
665 OrigMI->getNumOperands() == 3 &&
666 "FPFastMathMode decoration must have 3 operands for OpDecorate");
667 unsigned OrigFlags = OrigMI->getOperand(2).getImm();
668 unsigned NewFlags =
MI.getOperand(2).getImm();
669 if (OrigFlags == NewFlags)
673 unsigned FinalFlags = OrigFlags | NewFlags;
675 <<
"Warning: Conflicting FPFastMathMode decoration flags "
677 << *OrigMI <<
"Original flags: " << OrigFlags
678 <<
", new flags: " << NewFlags
679 <<
". They will be merged on a best effort basis, but not "
680 "validated. Final flags: "
681 << FinalFlags <<
"\n";
688 assert(
false &&
"No original instruction found for the duplicate "
689 "OpDecorate, but we found one in IS.");
702void SPIRVModuleAnalysis::processOtherInstrs(
const Module &M) {
704 for (
const Function &
F : M) {
705 if (
F.isDeclaration())
707 MachineFunction *MF = MMI->getMachineFunction(
F);
710 for (MachineBasicBlock &
MBB : *MF)
711 for (MachineInstr &
MI :
MBB) {
712 if (
MAI.getSkipEmission(&
MI))
714 const unsigned OpCode =
MI.getOpcode();
715 if (OpCode == SPIRV::OpString) {
717 }
else if (OpCode == SPIRV::OpExtInst &&
MI.getOperand(2).isImm() &&
718 MI.getOperand(2).getImm() ==
719 SPIRV::InstructionSet::
720 NonSemantic_Shader_DebugInfo_100) {
727 MachineOperand Ins =
MI.getOperand(3);
728 namespace NS = SPIRV::NonSemanticExtInst;
729 static constexpr int64_t GlobalNonSemanticDITy[] = {
730 NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
731 NS::DebugTypeBasic, NS::DebugTypePointer};
732 bool IsGlobalDI =
false;
733 for (
unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
734 IsGlobalDI |= Ins.
getImm() == GlobalNonSemanticDITy[Idx];
737 }
else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
739 }
else if (OpCode == SPIRV::OpEntryPoint) {
741 }
else if (TII->isAliasingInstr(
MI)) {
743 }
else if (TII->isDecorationInstr(
MI)) {
745 collectFuncNames(
MI, &
F);
746 }
else if (TII->isConstantInstr(
MI)) {
750 }
else if (OpCode == SPIRV::OpFunction) {
751 collectFuncNames(
MI, &
F);
752 }
else if (OpCode == SPIRV::OpTypeForwardPointer) {
760 auto AliasingTier = [](
const MachineInstr *
MI) {
761 switch (
MI->getOpcode()) {
762 case SPIRV::OpAliasDomainDeclINTEL:
764 case SPIRV::OpAliasScopeDeclINTEL:
766 case SPIRV::OpAliasScopeListDeclINTEL:
773 [&](
const MachineInstr *
LHS,
const MachineInstr *
RHS) {
774 return AliasingTier(LHS) < AliasingTier(RHS);
781void SPIRVModuleAnalysis::numberRegistersGlobally(
const Module &M) {
782 for (
const Function &
F : M) {
783 if (
F.isDeclaration())
785 MachineFunction *MF = MMI->getMachineFunction(
F);
787 for (MachineBasicBlock &
MBB : *MF) {
788 for (MachineInstr &
MI :
MBB) {
789 for (MachineOperand &
Op :
MI.operands()) {
793 if (
MAI.hasRegisterAlias(MF,
Reg))
795 MCRegister NewReg =
MAI.getNextIDRegister();
796 MAI.setRegisterAlias(MF,
Reg, NewReg);
798 if (
MI.getOpcode() != SPIRV::OpExtInst)
800 auto Set =
MI.getOperand(2).getImm();
801 auto [It,
Inserted] =
MAI.ExtInstSetMap.try_emplace(Set);
803 It->second =
MAI.getNextIDRegister();
811 SPIRV::OperandCategory::OperandCategory Category, uint32_t i,
813 addRequirements(getSymbolicOperandRequirements(Category, i, ST, *
this));
816void SPIRV::RequirementHandler::recursiveAddCapabilities(
818 for (
const auto &Cap : ToPrune) {
822 recursiveAddCapabilities(ImplicitDecls);
827 for (
const auto &Cap : ToAdd) {
828 bool IsNewlyInserted = AllCaps.insert(Cap).second;
829 if (!IsNewlyInserted)
833 recursiveAddCapabilities(ImplicitDecls);
834 MinimalCaps.push_back(Cap);
839 const SPIRV::Requirements &Req) {
843 if (Req.
Cap.has_value())
844 addCapabilities({Req.
Cap.value()});
846 addExtensions(Req.
Exts);
849 if (!MaxVersion.empty() && Req.
MinVer > MaxVersion) {
851 <<
" and <= " << MaxVersion <<
"\n");
855 if (MinVersion.empty() || Req.
MinVer > MinVersion)
860 if (!MinVersion.empty() && Req.
MaxVer < MinVersion) {
862 <<
" and >= " << MinVersion <<
"\n");
866 if (MaxVersion.empty() || Req.
MaxVer < MaxVersion)
872 const SPIRVSubtarget &ST)
const {
874 bool IsSatisfiable =
true;
875 auto TargetVer =
ST.getSPIRVVersion();
877 if (!MaxVersion.empty() && !TargetVer.empty() && MaxVersion < TargetVer) {
879 dbgs() <<
"Target SPIR-V version too high for required features\n"
880 <<
"Required max version: " << MaxVersion <<
" target version "
881 << TargetVer <<
"\n");
882 IsSatisfiable =
false;
885 if (!MinVersion.empty() && !TargetVer.empty() && MinVersion > TargetVer) {
886 LLVM_DEBUG(
dbgs() <<
"Target SPIR-V version too low for required features\n"
887 <<
"Required min version: " << MinVersion
888 <<
" target version " << TargetVer <<
"\n");
889 IsSatisfiable =
false;
892 if (!MinVersion.empty() && !MaxVersion.empty() && MinVersion > MaxVersion) {
895 <<
"Version is too low for some features and too high for others.\n"
896 <<
"Required SPIR-V min version: " << MinVersion
897 <<
" required SPIR-V max version " << MaxVersion <<
"\n");
898 IsSatisfiable =
false;
901 AvoidCapabilitiesSet AvoidCaps;
903 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
905 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
907 for (
auto Cap : MinimalCaps) {
908 if (AvailableCaps.contains(Cap) && !AvoidCaps.
S.
contains(Cap))
912 OperandCategory::CapabilityOperand, Cap)
914 IsSatisfiable =
false;
917 for (
auto Ext : AllExtensions) {
918 if (
ST.canUseExtension(Ext))
922 OperandCategory::ExtensionOperand, Ext)
924 IsSatisfiable =
false;
933 for (
const auto Cap : ToAdd)
934 if (AvailableCaps.insert(Cap).second)
936 SPIRV::OperandCategory::CapabilityOperand, Cap));
940 const Capability::Capability
ToRemove,
941 const Capability::Capability IfPresent) {
942 if (AllCaps.contains(IfPresent))
950 addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8,
953 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
955 Capability::GroupNonUniformVote,
956 Capability::GroupNonUniformArithmetic,
957 Capability::GroupNonUniformBallot,
958 Capability::GroupNonUniformClustered,
959 Capability::GroupNonUniformShuffle,
960 Capability::GroupNonUniformShuffleRelative,
961 Capability::GroupNonUniformQuad});
963 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
965 Capability::DotProductInput4x8Bit,
966 Capability::DotProductInput4x8BitPacked,
967 Capability::DemoteToHelperInvocation});
970 for (
auto Extension :
ST.getAllAvailableExtensions()) {
976 if (!
ST.isShader()) {
977 initAvailableCapabilitiesForOpenCL(ST);
982 initAvailableCapabilitiesForVulkan(ST);
989void RequirementHandler::initAvailableCapabilitiesForOpenCL(
990 const SPIRVSubtarget &ST) {
993 Capability::Kernel, Capability::Vector16,
994 Capability::Groups, Capability::GenericPointer,
995 Capability::StorageImageWriteWithoutFormat,
996 Capability::StorageImageReadWithoutFormat});
997 if (
ST.hasOpenCLFullProfile())
999 if (
ST.hasOpenCLImageSupport()) {
1001 Capability::Image1D, Capability::SampledBuffer,
1002 Capability::ImageBuffer});
1003 if (
ST.isAtLeastOpenCLVer(VersionTuple(2, 0)))
1006 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) &&
1007 ST.isAtLeastOpenCLVer(VersionTuple(2, 2)))
1009 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 4)))
1010 addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
1011 Capability::SignedZeroInfNanPreserve,
1012 Capability::RoundingModeRTE,
1013 Capability::RoundingModeRTZ});
1020void RequirementHandler::initAvailableCapabilitiesForVulkan(
1021 const SPIRVSubtarget &ST) {
1025 Capability::Float16,
1026 Capability::Float64,
1027 Capability::GroupNonUniform,
1028 Capability::Image1D,
1029 Capability::SampledBuffer,
1030 Capability::ImageBuffer,
1031 Capability::UniformBufferArrayDynamicIndexing,
1032 Capability::SampledImageArrayDynamicIndexing,
1033 Capability::StorageBufferArrayDynamicIndexing,
1034 Capability::StorageImageArrayDynamicIndexing,
1035 Capability::DerivativeControl,
1037 Capability::ImageQuery,
1038 Capability::ImageGatherExtended,
1039 Capability::Addresses,
1040 Capability::VulkanMemoryModelKHR,
1041 Capability::StorageImageExtendedFormats,
1042 Capability::StorageImageMultisample,
1043 Capability::ImageMSArray});
1046 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
1048 {Capability::Int64Atomics, Capability::ShaderNonUniformEXT,
1049 Capability::RuntimeDescriptorArrayEXT,
1050 Capability::InputAttachmentArrayDynamicIndexingEXT,
1051 Capability::UniformTexelBufferArrayDynamicIndexingEXT,
1052 Capability::StorageTexelBufferArrayDynamicIndexingEXT,
1053 Capability::UniformBufferArrayNonUniformIndexingEXT,
1054 Capability::SampledImageArrayNonUniformIndexingEXT,
1055 Capability::StorageBufferArrayNonUniformIndexingEXT,
1056 Capability::StorageImageArrayNonUniformIndexingEXT,
1057 Capability::InputAttachmentArrayNonUniformIndexingEXT,
1058 Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
1059 Capability::StorageTexelBufferArrayNonUniformIndexingEXT});
1063 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
1065 Capability::StorageImageReadWithoutFormat});
1073static void addOpDecorateReqs(
const MachineInstr &
MI,
unsigned DecIndex,
1076 int64_t DecOp =
MI.getOperand(DecIndex).getImm();
1077 auto Dec =
static_cast<SPIRV::Decoration::Decoration
>(DecOp);
1079 SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
1081 if (Dec == SPIRV::Decoration::BuiltIn) {
1082 int64_t BuiltInOp =
MI.getOperand(DecIndex + 1).getImm();
1083 auto BuiltIn =
static_cast<SPIRV::BuiltIn::BuiltIn
>(BuiltInOp);
1085 SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
1086 }
else if (Dec == SPIRV::Decoration::LinkageAttributes) {
1087 int64_t LinkageOp =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
1088 SPIRV::LinkageType::LinkageType LnkType =
1089 static_cast<SPIRV::LinkageType::LinkageType
>(LinkageOp);
1090 if (LnkType == SPIRV::LinkageType::LinkOnceODR)
1091 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_linkonce_odr);
1092 else if (LnkType == SPIRV::LinkageType::WeakAMD) {
1093 Reqs.
addExtension(SPIRV::Extension::SPV_AMD_weak_linkage);
1096 }
else if (Dec == SPIRV::Decoration::CacheControlLoadINTEL ||
1097 Dec == SPIRV::Decoration::CacheControlStoreINTEL) {
1098 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_cache_controls);
1099 }
else if (Dec == SPIRV::Decoration::HostAccessINTEL) {
1100 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_global_variable_host_access);
1101 }
else if (Dec == SPIRV::Decoration::InitModeINTEL ||
1102 Dec == SPIRV::Decoration::ImplementInRegisterMapINTEL) {
1104 SPIRV::Extension::SPV_INTEL_global_variable_fpga_decorations);
1105 }
else if (Dec == SPIRV::Decoration::NonUniformEXT) {
1107 }
else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
1109 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_fp_max_error);
1110 }
else if (Dec == SPIRV::Decoration::FPFastMathMode) {
1111 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
1113 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_float_controls2);
1122 assert(
MI.getNumOperands() >= 8 &&
"Insufficient operands for OpTypeImage");
1125 int64_t ImgFormatOp =
MI.getOperand(7).getImm();
1126 auto ImgFormat =
static_cast<SPIRV::ImageFormat::ImageFormat
>(ImgFormatOp);
1130 bool IsArrayed =
MI.getOperand(4).getImm() == 1;
1131 bool IsMultisampled =
MI.getOperand(5).getImm() == 1;
1132 bool NoSampler =
MI.getOperand(6).getImm() == 2;
1135 switch (
MI.getOperand(2).getImm()) {
1136 case SPIRV::Dim::DIM_1D:
1138 : SPIRV::Capability::Sampled1D);
1140 case SPIRV::Dim::DIM_2D:
1141 if (IsMultisampled && NoSampler)
1143 if (IsMultisampled && IsArrayed)
1146 case SPIRV::Dim::DIM_3D:
1148 case SPIRV::Dim::DIM_Cube:
1152 : SPIRV::Capability::SampledCubeArray);
1154 case SPIRV::Dim::DIM_Rect:
1156 : SPIRV::Capability::SampledRect);
1158 case SPIRV::Dim::DIM_Buffer:
1160 : SPIRV::Capability::SampledBuffer);
1162 case SPIRV::Dim::DIM_SubpassData:
1174 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_image_int64);
1178 if (!
ST.isShader()) {
1179 if (
MI.getNumOperands() > 8 &&
1180 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
1189 TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
1195#define ATOM_FLT_REQ_EXT_MSG(ExtName) \
1196 "The atomic float instruction requires the following SPIR-V " \
1197 "extension: SPV_EXT_shader_atomic_float" ExtName
1198static void AddAtomicVectorFloatRequirements(
const MachineInstr &
MI,
1202 MI.getMF()->getRegInfo().getVRegDef(
MI.getOperand(1).getReg());
1205 if (Rank != 2 && Rank != 4)
1207 "must be a 2-component or 4 component vector");
1212 if (EltTypeDef->
getOpcode() != SPIRV::OpTypeFloat ||
1215 "The element type for the result type of an atomic vector float "
1216 "instruction must be a 16-bit floating-point scalar");
1220 if (isBFloat16Type(EltTypeDef) &&
1223 "The element type for the result type of an atomic vector float "
1224 "instruction cannot be a bfloat16 scalar");
1225 if (!
ST.canUseExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector))
1227 "The atomic float16 vector instruction requires the following SPIR-V "
1228 "extension: SPV_NV_shader_atomic_fp16_vector");
1230 Reqs.
addExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector);
1231 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16VectorNV);
1238 "Expect register operand in atomic float instruction");
1239 Register TypeReg =
MI.getOperand(1).getReg();
1242 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
1243 return AddAtomicVectorFloatRequirements(
MI, Reqs, ST);
1245 if (TypeDef->
getOpcode() != SPIRV::OpTypeFloat)
1247 "floating-point type scalar");
1250 unsigned Op =
MI.getOpcode();
1251 if (
Op == SPIRV::OpAtomicFAddEXT) {
1252 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add))
1254 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
1257 if (isBFloat16Type(TypeDef)) {
1258 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1260 "The atomic bfloat16 instruction requires the following SPIR-V "
1261 "extension: SPV_INTEL_16bit_atomics",
1263 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1264 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16AddINTEL);
1266 if (!
ST.canUseExtension(
1267 SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
1269 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
1281 "Unexpected floating-point type width in atomic float instruction");
1284 if (!
ST.canUseExtension(
1285 SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max))
1287 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
1290 if (isBFloat16Type(TypeDef)) {
1291 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1293 "The atomic bfloat16 instruction requires the following SPIR-V "
1294 "extension: SPV_INTEL_16bit_atomics",
1296 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1297 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16MinMaxINTEL);
1299 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
1303 Reqs.
addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
1306 Reqs.
addCapability(SPIRV::Capability::AtomicFloat64MinMaxEXT);
1310 "Unexpected floating-point type width in atomic float instruction");
1316 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1320 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
1324 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1328 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
1332 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1336 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
1340 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1344 return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
1348 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1352 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
1355bool isCombinedImageSampler(
MachineInstr *SampledImageInst) {
1356 if (SampledImageInst->
getOpcode() != SPIRV::OpTypeSampledImage)
1362 return isSampledImage(ImageInst);
1367 if (
MI.getOpcode() != SPIRV::OpDecorate)
1371 if (Dec == SPIRV::Decoration::NonUniformEXT)
1389 if (
StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
1390 StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
1391 StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
1396 hasNonUniformDecoration(
Instr.getOperand(0).getReg(), MRI);
1398 auto FirstIndexReg =
Instr.getOperand(3).getReg();
1399 bool FirstIndexIsConstant =
1402 if (
StorageClass == SPIRV::StorageClass::StorageClass::StorageBuffer) {
1405 SPIRV::Capability::StorageBufferArrayNonUniformIndexingEXT);
1406 else if (!FirstIndexIsConstant)
1408 SPIRV::Capability::StorageBufferArrayDynamicIndexing);
1414 if (PointeeType->
getOpcode() != SPIRV::OpTypeImage &&
1415 PointeeType->
getOpcode() != SPIRV::OpTypeSampledImage &&
1416 PointeeType->
getOpcode() != SPIRV::OpTypeSampler) {
1420 if (isUniformTexelBuffer(PointeeType)) {
1423 SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1424 else if (!FirstIndexIsConstant)
1426 SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
1427 }
else if (isInputAttachment(PointeeType)) {
1430 SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1431 else if (!FirstIndexIsConstant)
1433 SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
1434 }
else if (isStorageTexelBuffer(PointeeType)) {
1437 SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1438 else if (!FirstIndexIsConstant)
1440 SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
1441 }
else if (isSampledImage(PointeeType) ||
1442 isCombinedImageSampler(PointeeType) ||
1443 PointeeType->
getOpcode() == SPIRV::OpTypeSampler) {
1446 SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1447 else if (!FirstIndexIsConstant)
1449 SPIRV::Capability::SampledImageArrayDynamicIndexing);
1450 }
else if (isStorageImage(PointeeType)) {
1453 SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1454 else if (!FirstIndexIsConstant)
1456 SPIRV::Capability::StorageImageArrayDynamicIndexing);
1460static bool isImageTypeWithUnknownFormat(
SPIRVTypeInst TypeInst) {
1461 if (TypeInst->
getOpcode() != SPIRV::OpTypeImage)
1470 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product))
1471 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_integer_dot_product);
1475 assert(
MI.getOperand(2).isReg() &&
"Unexpected operand in dot");
1479 assert(
Input->getOperand(1).isReg() &&
"Unexpected operand in dot input");
1483 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1485 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8BitPacked);
1486 }
else if (TypeDef->
getOpcode() == SPIRV::OpTypeVector) {
1492 "Dot operand of 8-bit integer type requires 4 components");
1493 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8Bit);
1509 unsigned AddrSpace = ASOp.
getImm();
1510 if (AddrSpace != SPIRV::StorageClass::UniformConstant) {
1511 if (!
ST.canUseExtension(
1513 SPV_EXT_relaxed_printf_string_address_space)) {
1515 "required because printf uses a format string not "
1516 "in constant address space.",
1520 SPIRV::Extension::SPV_EXT_relaxed_printf_string_address_space);
1529 if (
MI.getNumOperands() <=
OpIdx)
1533 if (Mask & (1U <<
I))
1542 unsigned Op =
MI.getOpcode();
1544 case SPIRV::OpMemoryModel: {
1545 int64_t Addr =
MI.getOperand(0).getImm();
1548 int64_t Mem =
MI.getOperand(1).getImm();
1553 case SPIRV::OpEntryPoint: {
1554 int64_t
Exe =
MI.getOperand(0).getImm();
1559 case SPIRV::OpExecutionMode:
1560 case SPIRV::OpExecutionModeId: {
1561 int64_t
Exe =
MI.getOperand(1).getImm();
1566 case SPIRV::OpTypeMatrix:
1569 case SPIRV::OpTypeInt: {
1570 unsigned BitWidth =
MI.getOperand(1).getImm();
1578 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1582 if (!
ST.canUseExtension(
1583 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers))
1585 "OpTypeInt type with a width other than 8, 16, 32 or 64 bits "
1586 "requires the following SPIR-V extension: "
1587 "SPV_ALTERA_arbitrary_precision_integers");
1589 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
1590 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
1594 case SPIRV::OpDot: {
1597 if (isBFloat16Type(TypeDef))
1598 Reqs.
addCapability(SPIRV::Capability::BFloat16DotProductKHR);
1601 case SPIRV::OpTypeFloat: {
1602 unsigned BitWidth =
MI.getOperand(1).getImm();
1606 if (isBFloat16Type(&
MI)) {
1607 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bfloat16))
1609 "following SPIR-V extension: SPV_KHR_bfloat16",
1619 case SPIRV::OpTypeVector: {
1620 unsigned NumComponents =
MI.getOperand(2).getImm();
1621 if (NumComponents == 8 || NumComponents == 16)
1627 if (ElemTypeDef->
getOpcode() == SPIRV::OpTypePointer &&
1628 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
1629 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter);
1630 Reqs.
addCapability(SPIRV::Capability::MaskedGatherScatterINTEL);
1634 case SPIRV::OpTypePointer: {
1635 auto SC =
MI.getOperand(1).getImm();
1646 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1651 case SPIRV::OpExtInst: {
1652 if (
MI.getOperand(2).getImm() ==
1653 static_cast<int64_t
>(
1654 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1655 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1658 if (
MI.getOperand(3).getImm() ==
1659 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1660 addPrintfRequirements(
MI, Reqs, ST);
1667 case SPIRV::OpAliasDomainDeclINTEL:
1668 case SPIRV::OpAliasScopeDeclINTEL:
1669 case SPIRV::OpAliasScopeListDeclINTEL: {
1670 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1671 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1674 case SPIRV::OpBitReverse:
1675 case SPIRV::OpBitFieldInsert:
1676 case SPIRV::OpBitFieldSExtract:
1677 case SPIRV::OpBitFieldUExtract:
1678 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1682 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1685 case SPIRV::OpTypeRuntimeArray:
1688 case SPIRV::OpTypeOpaque:
1689 case SPIRV::OpTypeEvent:
1692 case SPIRV::OpTypePipe:
1693 case SPIRV::OpTypeReserveId:
1696 case SPIRV::OpTypeDeviceEvent:
1697 case SPIRV::OpTypeQueue:
1698 case SPIRV::OpBuildNDRange:
1699 case SPIRV::OpEnqueueKernel:
1702 case SPIRV::OpDecorate:
1703 case SPIRV::OpDecorateId:
1704 case SPIRV::OpDecorateString:
1705 addOpDecorateReqs(
MI, 1, Reqs, ST);
1707 case SPIRV::OpMemberDecorate:
1708 case SPIRV::OpMemberDecorateString:
1709 addOpDecorateReqs(
MI, 2, Reqs, ST);
1711 case SPIRV::OpInBoundsPtrAccessChain:
1714 case SPIRV::OpConstantSampler:
1717 case SPIRV::OpInBoundsAccessChain:
1718 case SPIRV::OpAccessChain:
1719 addOpAccessChainReqs(
MI, Reqs, ST);
1721 case SPIRV::OpTypeImage:
1722 addOpTypeImageReqs(
MI, Reqs, ST);
1724 case SPIRV::OpTypeSampler:
1725 if (!
ST.isShader()) {
1729 case SPIRV::OpTypeForwardPointer:
1733 case SPIRV::OpAtomicFlagTestAndSet:
1734 case SPIRV::OpAtomicLoad:
1735 case SPIRV::OpAtomicStore:
1736 case SPIRV::OpAtomicExchange:
1737 case SPIRV::OpAtomicCompareExchange:
1738 case SPIRV::OpAtomicIIncrement:
1739 case SPIRV::OpAtomicIDecrement:
1740 case SPIRV::OpAtomicIAdd:
1741 case SPIRV::OpAtomicISub:
1742 case SPIRV::OpAtomicUMin:
1743 case SPIRV::OpAtomicUMax:
1744 case SPIRV::OpAtomicSMin:
1745 case SPIRV::OpAtomicSMax:
1746 case SPIRV::OpAtomicAnd:
1747 case SPIRV::OpAtomicOr:
1748 case SPIRV::OpAtomicXor: {
1751 if (
Op == SPIRV::OpAtomicStore) {
1754 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1760 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1765 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1767 "16-bit integer atomic operations require the following SPIR-V "
1768 "extension: SPV_INTEL_16bit_atomics",
1770 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1772 case SPIRV::OpAtomicLoad:
1773 case SPIRV::OpAtomicStore:
1774 case SPIRV::OpAtomicExchange:
1775 case SPIRV::OpAtomicCompareExchange:
1776 case SPIRV::OpAtomicCompareExchangeWeak:
1778 SPIRV::Capability::AtomicInt16CompareExchangeINTEL);
1785 }
else if (isBFloat16Type(TypeDef)) {
1786 if (
is_contained({SPIRV::OpAtomicLoad, SPIRV::OpAtomicStore,
1787 SPIRV::OpAtomicExchange},
1789 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1791 "The atomic bfloat16 instruction requires the following SPIR-V "
1792 "extension: SPV_INTEL_16bit_atomics",
1794 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1795 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16LoadStoreINTEL);
1800 case SPIRV::OpGroupNonUniformIAdd:
1801 case SPIRV::OpGroupNonUniformFAdd:
1802 case SPIRV::OpGroupNonUniformIMul:
1803 case SPIRV::OpGroupNonUniformFMul:
1804 case SPIRV::OpGroupNonUniformSMin:
1805 case SPIRV::OpGroupNonUniformUMin:
1806 case SPIRV::OpGroupNonUniformFMin:
1807 case SPIRV::OpGroupNonUniformSMax:
1808 case SPIRV::OpGroupNonUniformUMax:
1809 case SPIRV::OpGroupNonUniformFMax:
1810 case SPIRV::OpGroupNonUniformBitwiseAnd:
1811 case SPIRV::OpGroupNonUniformBitwiseOr:
1812 case SPIRV::OpGroupNonUniformBitwiseXor:
1813 case SPIRV::OpGroupNonUniformLogicalAnd:
1814 case SPIRV::OpGroupNonUniformLogicalOr:
1815 case SPIRV::OpGroupNonUniformLogicalXor: {
1817 int64_t GroupOp =
MI.getOperand(3).getImm();
1819 case SPIRV::GroupOperation::Reduce:
1820 case SPIRV::GroupOperation::InclusiveScan:
1821 case SPIRV::GroupOperation::ExclusiveScan:
1822 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1824 case SPIRV::GroupOperation::ClusteredReduce:
1825 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1827 case SPIRV::GroupOperation::PartitionedReduceNV:
1828 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1829 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1830 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1835 case SPIRV::OpGroupNonUniformQuadSwap:
1838 case SPIRV::OpImageQueryLod:
1841 case SPIRV::OpImageQuerySize:
1842 case SPIRV::OpImageQuerySizeLod:
1843 case SPIRV::OpImageQueryLevels:
1844 case SPIRV::OpImageQuerySamples:
1848 case SPIRV::OpImageQueryFormat: {
1849 Register ResultReg =
MI.getOperand(0).getReg();
1851 static const unsigned CompareOps[] = {
1852 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1853 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1854 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1855 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1856 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1858 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1859 if (ImmVal == 4323 || ImmVal == 4324) {
1860 if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1861 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1864 "SPV_EXT_image_raw10_raw12 extension");
1869 unsigned Opc = UseInst.getOpcode();
1871 if (
Opc == SPIRV::OpSwitch) {
1874 CheckAndAddExtension(
Op.getImm());
1876 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1879 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1882 CheckAndAddExtension(ImmVal);
1890 case SPIRV::OpGroupNonUniformShuffle:
1891 case SPIRV::OpGroupNonUniformShuffleXor:
1892 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1894 case SPIRV::OpGroupNonUniformShuffleUp:
1895 case SPIRV::OpGroupNonUniformShuffleDown:
1896 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1898 case SPIRV::OpGroupAll:
1899 case SPIRV::OpGroupAny:
1900 case SPIRV::OpGroupBroadcast:
1901 case SPIRV::OpGroupIAdd:
1902 case SPIRV::OpGroupFAdd:
1903 case SPIRV::OpGroupFMin:
1904 case SPIRV::OpGroupUMin:
1905 case SPIRV::OpGroupSMin:
1906 case SPIRV::OpGroupFMax:
1907 case SPIRV::OpGroupUMax:
1908 case SPIRV::OpGroupSMax:
1911 case SPIRV::OpGroupNonUniformElect:
1914 case SPIRV::OpGroupNonUniformAll:
1915 case SPIRV::OpGroupNonUniformAny:
1916 case SPIRV::OpGroupNonUniformAllEqual:
1919 case SPIRV::OpGroupNonUniformBroadcast:
1920 case SPIRV::OpGroupNonUniformBroadcastFirst:
1921 case SPIRV::OpGroupNonUniformBallot:
1922 case SPIRV::OpGroupNonUniformInverseBallot:
1923 case SPIRV::OpGroupNonUniformBallotBitExtract:
1924 case SPIRV::OpGroupNonUniformBallotBitCount:
1925 case SPIRV::OpGroupNonUniformBallotFindLSB:
1926 case SPIRV::OpGroupNonUniformBallotFindMSB:
1927 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1929 case SPIRV::OpSubgroupShuffleINTEL:
1930 case SPIRV::OpSubgroupShuffleDownINTEL:
1931 case SPIRV::OpSubgroupShuffleUpINTEL:
1932 case SPIRV::OpSubgroupShuffleXorINTEL:
1933 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1934 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1935 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1938 case SPIRV::OpSubgroupBlockReadINTEL:
1939 case SPIRV::OpSubgroupBlockWriteINTEL:
1940 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1941 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1942 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1945 case SPIRV::OpSubgroupImageBlockReadINTEL:
1946 case SPIRV::OpSubgroupImageBlockWriteINTEL:
1947 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1948 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1949 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
1952 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
1953 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
1954 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
1955 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
1956 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
1959 case SPIRV::OpAssumeTrueKHR:
1960 case SPIRV::OpExpectKHR:
1961 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
1962 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
1966 case SPIRV::OpFmaKHR:
1967 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
1972 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
1973 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
1974 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
1975 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
1976 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
1979 case SPIRV::OpConstantFunctionPointerINTEL:
1980 case SPIRV::OpFunctionPointerCallINTEL:
1981 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1982 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1983 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1986 case SPIRV::OpGroupNonUniformRotateKHR:
1987 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
1989 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
1991 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
1992 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
1995 case SPIRV::OpFixedCosALTERA:
1996 case SPIRV::OpFixedSinALTERA:
1997 case SPIRV::OpFixedCosPiALTERA:
1998 case SPIRV::OpFixedSinPiALTERA:
1999 case SPIRV::OpFixedExpALTERA:
2000 case SPIRV::OpFixedLogALTERA:
2001 case SPIRV::OpFixedRecipALTERA:
2002 case SPIRV::OpFixedSqrtALTERA:
2003 case SPIRV::OpFixedSinCosALTERA:
2004 case SPIRV::OpFixedSinCosPiALTERA:
2005 case SPIRV::OpFixedRsqrtALTERA:
2006 if (!
ST.canUseExtension(
2007 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
2009 "following SPIR-V extension: "
2010 "SPV_ALTERA_arbitrary_precision_fixed_point",
2013 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
2014 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
2016 case SPIRV::OpGroupIMulKHR:
2017 case SPIRV::OpGroupFMulKHR:
2018 case SPIRV::OpGroupBitwiseAndKHR:
2019 case SPIRV::OpGroupBitwiseOrKHR:
2020 case SPIRV::OpGroupBitwiseXorKHR:
2021 case SPIRV::OpGroupLogicalAndKHR:
2022 case SPIRV::OpGroupLogicalOrKHR:
2023 case SPIRV::OpGroupLogicalXorKHR:
2024 if (
ST.canUseExtension(
2025 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
2026 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
2027 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
2030 case SPIRV::OpReadClockKHR:
2031 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
2033 "following SPIR-V extension: SPV_KHR_shader_clock",
2035 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
2038 case SPIRV::OpAbortKHR:
2039 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_abort))
2041 "following SPIR-V extension: SPV_KHR_abort",
2046 case SPIRV::OpPoisonKHR:
2047 case SPIRV::OpFreezeKHR:
2048 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_poison_freeze))
2050 "following SPIR-V extension: SPV_KHR_poison_freeze",
2052 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_poison_freeze);
2055 case SPIRV::OpAtomicFAddEXT:
2056 case SPIRV::OpAtomicFMinEXT:
2057 case SPIRV::OpAtomicFMaxEXT:
2058 AddAtomicFloatRequirements(
MI, Reqs, ST);
2060 case SPIRV::OpConvertBF16ToFINTEL:
2061 case SPIRV::OpConvertFToBF16INTEL:
2062 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
2063 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
2064 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
2067 case SPIRV::OpRoundFToTF32INTEL:
2068 if (
ST.canUseExtension(
2069 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
2070 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
2071 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
2074 case SPIRV::OpVariableLengthArrayINTEL:
2075 case SPIRV::OpSaveMemoryINTEL:
2076 case SPIRV::OpRestoreMemoryINTEL:
2077 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
2078 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
2079 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
2082 case SPIRV::OpAsmTargetINTEL:
2083 case SPIRV::OpAsmINTEL:
2084 case SPIRV::OpAsmCallINTEL:
2085 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
2086 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
2090 case SPIRV::OpTypeCooperativeMatrixKHR: {
2091 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2093 "OpTypeCooperativeMatrixKHR type requires the "
2094 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
2096 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2097 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2100 if (isBFloat16Type(TypeDef))
2101 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
2104 case SPIRV::OpArithmeticFenceEXT:
2105 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
2107 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
2109 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
2112 case SPIRV::OpControlBarrierArriveINTEL:
2113 case SPIRV::OpControlBarrierWaitINTEL:
2114 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
2115 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
2119 case SPIRV::OpCooperativeMatrixMulAddKHR: {
2120 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2122 "following SPIR-V extension: "
2123 "SPV_KHR_cooperative_matrix",
2125 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2126 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2127 constexpr unsigned MulAddMaxSize = 6;
2128 if (
MI.getNumOperands() != MulAddMaxSize)
2130 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
2132 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
2133 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2135 "require the following SPIR-V extension: "
2136 "SPV_INTEL_joint_matrix",
2138 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2140 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
2143 MatrixAAndBBFloat16ComponentsINTEL ||
2145 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
2147 MatrixResultBFloat16ComponentsINTEL) {
2148 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2150 "require the following SPIR-V extension: "
2151 "SPV_INTEL_joint_matrix",
2153 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2155 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
2159 case SPIRV::OpCooperativeMatrixLoadKHR:
2160 case SPIRV::OpCooperativeMatrixStoreKHR:
2161 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2162 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2163 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
2164 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2166 "following SPIR-V extension: "
2167 "SPV_KHR_cooperative_matrix",
2169 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2170 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2176 case SPIRV::OpCooperativeMatrixLoadKHR:
2179 case SPIRV::OpCooperativeMatrixStoreKHR:
2182 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2185 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2186 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2192 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
2195 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
2198 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
2199 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2201 "extension: SPV_INTEL_joint_matrix",
2203 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2204 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2209 if (
Op == SPIRV::OpCooperativeMatrixLoadKHR ||
2210 Op == SPIRV::OpCooperativeMatrixStoreKHR)
2213 std::string InstName;
2215 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2216 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2218 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2219 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2221 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2222 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2226 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2227 const std::string ErrorMsg =
2228 InstName +
" instruction requires the "
2229 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2232 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2233 if (
Op == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2234 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2238 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2241 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2242 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2244 "instructions require the following SPIR-V extension: "
2245 "SPV_INTEL_joint_matrix",
2247 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2249 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2251 case SPIRV::OpReadPipeBlockingALTERA:
2252 case SPIRV::OpWritePipeBlockingALTERA:
2253 if (
ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2254 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2258 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2259 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2261 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2263 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2265 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2267 case SPIRV::OpConvertHandleToImageINTEL:
2268 case SPIRV::OpConvertHandleToSamplerINTEL:
2269 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2270 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2272 "instructions require the following SPIR-V extension: "
2273 "SPV_INTEL_bindless_images",
2276 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2278 if (
Op == SPIRV::OpConvertHandleToImageINTEL &&
2279 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2281 "OpConvertHandleToImageINTEL",
2283 }
else if (
Op == SPIRV::OpConvertHandleToSamplerINTEL &&
2284 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2286 "OpConvertHandleToSamplerINTEL",
2288 }
else if (
Op == SPIRV::OpConvertHandleToSampledImageINTEL &&
2289 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2291 "OpConvertHandleToSampledImageINTEL",
2296 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2297 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2299 "Parameter value must be a 32-bit scalar in case of "
2300 "Physical32 addressing model or a 64-bit scalar in case of "
2301 "Physical64 addressing model",
2304 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2308 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2309 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2310 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2311 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2312 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2313 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2315 "Prefetch/Store]INTEL instructions require the "
2316 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2318 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2319 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2321 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2322 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2325 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2326 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2331 case SPIRV::OpKill: {
2334 case SPIRV::OpDemoteToHelperInvocation:
2335 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2337 if (
ST.canUseExtension(
2338 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2341 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2346 case SPIRV::OpSUDot:
2347 case SPIRV::OpSDotAccSat:
2348 case SPIRV::OpUDotAccSat:
2349 case SPIRV::OpSUDotAccSat:
2350 AddDotProductRequirements(
MI, Reqs, ST);
2352 case SPIRV::OpImageSampleImplicitLod:
2353 case SPIRV::OpImageFetch:
2355 addImageOperandReqs(
MI, Reqs, ST, 4);
2357 case SPIRV::OpImageSampleExplicitLod:
2358 addImageOperandReqs(
MI, Reqs, ST, 4);
2360 case SPIRV::OpImageSampleDrefImplicitLod:
2361 case SPIRV::OpImageSampleDrefExplicitLod:
2362 case SPIRV::OpImageDrefGather:
2363 case SPIRV::OpImageGather:
2365 addImageOperandReqs(
MI, Reqs, ST, 5);
2367 case SPIRV::OpImageRead: {
2368 Register ImageReg =
MI.getOperand(2).getReg();
2377 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2378 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2381 case SPIRV::OpImageWrite: {
2382 Register ImageReg =
MI.getOperand(0).getReg();
2391 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2392 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2395 case SPIRV::OpTypeStructContinuedINTEL:
2396 case SPIRV::OpConstantCompositeContinuedINTEL:
2397 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2398 case SPIRV::OpCompositeConstructContinuedINTEL: {
2399 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2401 "Continued instructions require the "
2402 "following SPIR-V extension: SPV_INTEL_long_composites",
2404 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2408 case SPIRV::OpArbitraryFloatEQALTERA:
2409 case SPIRV::OpArbitraryFloatGEALTERA:
2410 case SPIRV::OpArbitraryFloatGTALTERA:
2411 case SPIRV::OpArbitraryFloatLEALTERA:
2412 case SPIRV::OpArbitraryFloatLTALTERA:
2413 case SPIRV::OpArbitraryFloatCbrtALTERA:
2414 case SPIRV::OpArbitraryFloatCosALTERA:
2415 case SPIRV::OpArbitraryFloatCosPiALTERA:
2416 case SPIRV::OpArbitraryFloatExp10ALTERA:
2417 case SPIRV::OpArbitraryFloatExp2ALTERA:
2418 case SPIRV::OpArbitraryFloatExpALTERA:
2419 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2420 case SPIRV::OpArbitraryFloatHypotALTERA:
2421 case SPIRV::OpArbitraryFloatLog10ALTERA:
2422 case SPIRV::OpArbitraryFloatLog1pALTERA:
2423 case SPIRV::OpArbitraryFloatLog2ALTERA:
2424 case SPIRV::OpArbitraryFloatLogALTERA:
2425 case SPIRV::OpArbitraryFloatRecipALTERA:
2426 case SPIRV::OpArbitraryFloatSinCosALTERA:
2427 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2428 case SPIRV::OpArbitraryFloatSinALTERA:
2429 case SPIRV::OpArbitraryFloatSinPiALTERA:
2430 case SPIRV::OpArbitraryFloatSqrtALTERA:
2431 case SPIRV::OpArbitraryFloatACosALTERA:
2432 case SPIRV::OpArbitraryFloatACosPiALTERA:
2433 case SPIRV::OpArbitraryFloatAddALTERA:
2434 case SPIRV::OpArbitraryFloatASinALTERA:
2435 case SPIRV::OpArbitraryFloatASinPiALTERA:
2436 case SPIRV::OpArbitraryFloatATan2ALTERA:
2437 case SPIRV::OpArbitraryFloatATanALTERA:
2438 case SPIRV::OpArbitraryFloatATanPiALTERA:
2439 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2440 case SPIRV::OpArbitraryFloatCastALTERA:
2441 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2442 case SPIRV::OpArbitraryFloatDivALTERA:
2443 case SPIRV::OpArbitraryFloatMulALTERA:
2444 case SPIRV::OpArbitraryFloatPowALTERA:
2445 case SPIRV::OpArbitraryFloatPowNALTERA:
2446 case SPIRV::OpArbitraryFloatPowRALTERA:
2447 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2448 case SPIRV::OpArbitraryFloatSubALTERA: {
2449 if (!
ST.canUseExtension(
2450 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2452 "Floating point instructions can't be translated correctly without "
2453 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2456 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2458 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2461 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2462 if (!
ST.canUseExtension(
2463 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2465 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2467 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2470 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2472 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2475 case SPIRV::OpBitwiseFunctionINTEL: {
2476 if (!
ST.canUseExtension(
2477 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2479 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2480 "extension: SPV_INTEL_ternary_bitwise_function",
2482 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2483 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2486 case SPIRV::OpCopyMemorySized: {
2491 case SPIRV::OpPredicatedLoadINTEL:
2492 case SPIRV::OpPredicatedStoreINTEL: {
2493 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2495 "OpPredicated[Load/Store]INTEL instructions require "
2496 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2498 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2502 case SPIRV::OpFAddS:
2503 case SPIRV::OpFSubS:
2504 case SPIRV::OpFMulS:
2505 case SPIRV::OpFDivS:
2506 case SPIRV::OpFRemS:
2508 case SPIRV::OpFNegate:
2509 case SPIRV::OpFAddV:
2510 case SPIRV::OpFSubV:
2511 case SPIRV::OpFMulV:
2512 case SPIRV::OpFDivV:
2513 case SPIRV::OpFRemV:
2514 case SPIRV::OpFNegateV: {
2517 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2519 if (isBFloat16Type(TypeDef)) {
2520 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2522 "Arithmetic instructions with bfloat16 arguments require the "
2523 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2525 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2526 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2530 case SPIRV::OpOrdered:
2531 case SPIRV::OpUnordered:
2532 case SPIRV::OpFOrdEqual:
2533 case SPIRV::OpFOrdNotEqual:
2534 case SPIRV::OpFOrdLessThan:
2535 case SPIRV::OpFOrdLessThanEqual:
2536 case SPIRV::OpFOrdGreaterThan:
2537 case SPIRV::OpFOrdGreaterThanEqual:
2538 case SPIRV::OpFUnordEqual:
2539 case SPIRV::OpFUnordNotEqual:
2540 case SPIRV::OpFUnordLessThan:
2541 case SPIRV::OpFUnordLessThanEqual:
2542 case SPIRV::OpFUnordGreaterThan:
2543 case SPIRV::OpFUnordGreaterThanEqual: {
2547 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2549 if (isBFloat16Type(TypeDef)) {
2550 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2552 "Relational instructions with bfloat16 arguments require the "
2553 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2555 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2556 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2560 case SPIRV::OpDPdxCoarse:
2561 case SPIRV::OpDPdyCoarse:
2562 case SPIRV::OpDPdxFine:
2563 case SPIRV::OpDPdyFine: {
2567 case SPIRV::OpLoopControlINTEL: {
2568 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2569 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2581 SPIRV::Capability::Shader);
2593 addInstrRequirements(
MI, MAI, ST);
2596 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2598 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2599 RequireKHRFloatControls2 =
false,
2601 bool HasIntelFloatControls2 =
2602 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2603 bool HasKHRFloatControls2 =
2604 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2605 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2611 auto EM =
Const->getZExtValue();
2615 case SPIRV::ExecutionMode::DenormPreserve:
2616 case SPIRV::ExecutionMode::DenormFlushToZero:
2617 case SPIRV::ExecutionMode::RoundingModeRTE:
2618 case SPIRV::ExecutionMode::RoundingModeRTZ:
2619 RequireFloatControls = VerLower14;
2621 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2623 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2624 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2625 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2626 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2627 if (HasIntelFloatControls2) {
2628 RequireIntelFloatControls2 =
true;
2630 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2633 case SPIRV::ExecutionMode::FPFastMathDefault: {
2634 if (HasKHRFloatControls2) {
2635 RequireKHRFloatControls2 =
true;
2637 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2641 case SPIRV::ExecutionMode::ContractionOff:
2642 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2643 if (HasKHRFloatControls2) {
2644 RequireKHRFloatControls2 =
true;
2646 SPIRV::OperandCategory::ExecutionModeOperand,
2647 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2650 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2655 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2660 if (RequireFloatControls &&
2661 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2663 if (RequireIntelFloatControls2)
2665 if (RequireKHRFloatControls2)
2669 if (
F.isDeclaration())
2671 if (
F.getMetadata(
"reqd_work_group_size"))
2673 SPIRV::OperandCategory::ExecutionModeOperand,
2674 SPIRV::ExecutionMode::LocalSize, ST);
2675 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2677 SPIRV::OperandCategory::ExecutionModeOperand,
2678 SPIRV::ExecutionMode::LocalSize, ST);
2680 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2683 if (
F.getMetadata(
"work_group_size_hint"))
2685 SPIRV::OperandCategory::ExecutionModeOperand,
2686 SPIRV::ExecutionMode::LocalSizeHint, ST);
2687 if (
F.getMetadata(
"intel_reqd_sub_group_size") ||
2688 F.getMetadata(
"reqd_sub_group_size"))
2690 SPIRV::OperandCategory::ExecutionModeOperand,
2691 SPIRV::ExecutionMode::SubgroupSize, ST);
2692 if (
F.getMetadata(
"max_work_group_size"))
2694 SPIRV::OperandCategory::ExecutionModeOperand,
2695 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2696 if (
F.getMetadata(
"vec_type_hint"))
2698 SPIRV::OperandCategory::ExecutionModeOperand,
2699 SPIRV::ExecutionMode::VecTypeHint, ST);
2701 if (
F.hasOptNone()) {
2702 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2705 }
else if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2715 unsigned Flags = SPIRV::FPFastMathMode::None;
2716 bool CanUseKHRFloatControls2 =
2717 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2719 Flags |= SPIRV::FPFastMathMode::NotNaN;
2721 Flags |= SPIRV::FPFastMathMode::NotInf;
2723 Flags |= SPIRV::FPFastMathMode::NSZ;
2725 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2727 Flags |= SPIRV::FPFastMathMode::AllowContract;
2729 if (CanUseKHRFloatControls2)
2737 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2738 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2739 SPIRV::FPFastMathMode::AllowTransform |
2740 SPIRV::FPFastMathMode::AllowReassoc |
2741 SPIRV::FPFastMathMode::AllowContract;
2743 Flags |= SPIRV::FPFastMathMode::Fast;
2746 if (CanUseKHRFloatControls2) {
2748 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2749 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2754 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2755 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2756 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2757 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2758 "AllowContract flags to be enabled as well.");
2769 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2772static void handleMIFlagDecoration(
2777 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2778 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2781 SPIRV::Decoration::NoSignedWrap, {});
2784 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2785 SPIRV::Decoration::NoUnsignedWrap, ST,
2789 SPIRV::Decoration::NoUnsignedWrap, {});
2794 TII.canUseFastMathFlags(
2795 I,
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) ||
2796 (
ST.isKernel() &&
I.getOpcode() == SPIRV::OpExtInst);
2800 unsigned FMFlags = getFastMathFlags(
I, ST);
2801 if (FMFlags == SPIRV::FPFastMathMode::None) {
2804 if (FPFastMathDefaultInfoVec.
empty())
2820 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2821 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2822 ?
I.getOperand(1).getReg()
2823 :
I.getOperand(2).getReg();
2831 if (Ty == Elem.Ty) {
2832 FMFlags = Elem.FastMathFlags;
2833 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2834 Elem.FPFastMathDefault;
2839 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2842 if (isFastMathModeAvailable(ST)) {
2843 Register DstReg =
I.getOperand(0).getReg();
2859 for (
auto &
MBB : *MF)
2860 for (
auto &
MI :
MBB)
2861 handleMIFlagDecoration(
MI, ST,
TII, MAI.
Reqs, GR,
2878 for (
auto &
MBB : *MF) {
2879 if (!
MBB.hasName() ||
MBB.empty())
2898 for (
auto &
MBB : *MF) {
2900 MI.setDesc(
TII.get(SPIRV::OpPhi));
2903 MI.insert(
MI.operands_begin() + 1,
2904 {MachineOperand::CreateReg(ResTypeReg, false)});
2923 SPIRV::FPFastMathMode::None);
2925 SPIRV::FPFastMathMode::None);
2927 SPIRV::FPFastMathMode::None);
2934 size_t BitWidth = Ty->getScalarSizeInBits();
2938 assert(Index >= 0 && Index < 3 &&
2939 "Expected FPFastMathDefaultInfo for half, float, or double");
2940 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2941 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2942 return FPFastMathDefaultInfoVec[Index];
2945static void collectFPFastMathDefaults(
const Module &M,
2948 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
2957 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2961 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2970 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
2972 "Expected 4 operands for FPFastMathDefault");
2983 Info.FastMathFlags = Flags;
2984 Info.FPFastMathDefault =
true;
2985 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
2987 "Expected no operands for ContractionOff");
2994 Info.ContractionOff =
true;
2996 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
2998 "Expected 1 operand for SignedZeroInfNanPreserve");
2999 unsigned TargetWidth =
3008 assert(Index >= 0 && Index < 3 &&
3009 "Expected FPFastMathDefaultInfo for half, float, or double");
3010 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
3011 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
3012 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
3023 SPIRVTargetMachine &TM =
3027 TII = ST->getInstrInfo();
3033 patchPhis(M, GR, *TII, MMI);
3035 addMBBNames(M, *TII, MMI, *ST,
MAI);
3036 collectFPFastMathDefaults(M,
MAI, *ST);
3037 addDecorations(M, *TII, MMI, *ST,
MAI, GR);
3039 collectReqs(M,
MAI, MMI, *ST);
3043 collectDeclarations(M);
3046 numberRegistersGlobally(M);
3049 processOtherInstrs(M);
3053 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
3056 GR->setBound(
MAI.MaxID);
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet & ToRemove
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
Promote Memory to Register
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static SPIRV::FPFastMathDefaultInfoVector & getOrCreateFPFastMathDefaultInfoVec(const Module &M, DenseMap< Function *, SPIRV::FPFastMathDefaultInfoVector > &FPFastMathDefaultInfoMap, Function *F)
static SPIRV::FPFastMathDefaultInfo & getFPFastMathDefaultInfo(SPIRV::FPFastMathDefaultInfoVector &FPFastMathDefaultInfoVec, const Type *Ty)
#define ATOM_FLT_REQ_EXT_MSG(ExtName)
static cl::opt< bool > SPVDumpDeps("spv-dump-deps", cl::desc("Dump MIR with SPIR-V dependencies info"), cl::Optional, cl::init(false))
static cl::list< SPIRV::Capability::Capability > AvoidCapabilities("avoid-spirv-capabilities", cl::desc("SPIR-V capabilities to avoid if there are " "other options enabling a feature"), cl::Hidden, cl::values(clEnumValN(SPIRV::Capability::Shader, "Shader", "SPIR-V Shader capability")))
#define SPIRV_BACKEND_SERVICE_FUN_NAME
Target-Independent Code Generator Pass Configuration Options pass.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
bool isValid() const
Return true if the attribute is any kind of attribute.
This is the shared class of boolean and integer constants.
This is an important base class in LLVM.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
Tracking metadata reference owned by Metadata.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
Register getReg(unsigned Idx) const
Get the register for the operand index.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
This class contains meta information specific to a module.
LLVM_ABI MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
LLVM_ABI void print(raw_ostream &os, const TargetRegisterInfo *TRI=nullptr) const
Print the MachineOperand to os.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
iterator_range< reg_instr_iterator > reg_instructions(Register Reg) const
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
A Module instance is used to store all the information related to an LLVM module.
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
unsigned getScalarOrVectorBitWidth(SPIRVTypeInst Type) const
const Type * getTypeForSPIRVType(SPIRVTypeInst Ty) const
Register getSPIRVTypeID(SPIRVTypeInst SpirvType) const
SPIRVTypeInst getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
bool isConstantInstr(const MachineInstr &MI) const
const SPIRVInstrInfo * getInstrInfo() const override
SPIRVGlobalRegistry * getSPIRVGlobalRegistry() const
const SPIRVSubtarget * getSubtargetImpl() const
bool isTypeIntN(unsigned N=0) const
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
Represents a version number in the form major[.minor[.subminor[.build]]].
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
SmallVector< const MachineInstr * > InstrList
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
FunctionAddr VTableAddr Value
void stable_sort(R &&Range)
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
hash_code hash_value(const FixedPointSemantics &Val)
ExtensionList getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
CapabilityList getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
SmallVector< SPIRV::Extension::Extension, 8 > ExtensionList
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
SmallVector< size_t > InstrSignature
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
VersionTuple getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
CapabilityList getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
std::string getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, int32_t Value)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
VersionTuple getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
SmallVector< SPIRV::Capability::Capability, 8 > CapabilityList
std::set< InstrSignature > InstrTraces
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
std::map< SmallVector< size_t >, unsigned > InstrGRegsMap
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
SmallSet< SPIRV::Capability::Capability, 4 > S
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
SPIRV::ModuleAnalysisInfo MAI
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
static size_t computeFPFastMathDefaultInfoVecIndex(size_t BitWidth)
void setSkipEmission(const MachineInstr *MI)
MCRegister getRegisterAlias(const MachineFunction *MF, Register Reg)
MCRegister getOrCreateMBBRegister(const MachineBasicBlock &MBB)
InstrList MS[NUM_MODULE_SECTIONS]
AddressingModel::AddressingModel Addr
void setRegisterAlias(const MachineFunction *MF, Register Reg, MCRegister AliasReg)
DenseMap< const Function *, SPIRV::FPFastMathDefaultInfoVector > FPFastMathDefaultInfoMap
void addCapabilities(const CapabilityList &ToAdd)
bool isCapabilityAvailable(Capability::Capability Cap) const
void checkSatisfiable(const SPIRVSubtarget &ST) const
void getAndAddRequirements(SPIRV::OperandCategory::OperandCategory Category, uint32_t i, const SPIRVSubtarget &ST)
void addExtension(Extension::Extension ToAdd)
void initAvailableCapabilities(const SPIRVSubtarget &ST)
void removeCapabilityIf(const Capability::Capability ToRemove, const Capability::Capability IfPresent)
void addCapability(Capability::Capability ToAdd)
void addAvailableCaps(const CapabilityList &ToAdd)
void addRequirements(const Requirements &Req)
const std::optional< Capability::Capability > Cap
const VersionTuple MinVer
const VersionTuple MaxVer