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) {
346 if (
UseMI.getOpcode() != SPIRV::OpConstantFunctionPointerINTEL)
352 MAI.setSkipEmission(&
MI);
356 return TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
357 TII->isInlineAsmDefInstr(
MI);
363void SPIRVModuleAnalysis::visitFunPtrUse(
365 std::map<const Value *, unsigned> &GlobalToGReg,
const MachineFunction *MF,
367 const MachineOperand *OpFunDef =
368 GR->getFunctionDefinitionByUse(&
MI.getOperand(2));
371 const MachineInstr *OpDefMI = OpFunDef->
getParent();
374 const MachineRegisterInfo &FunDefMRI = FunDefMF->
getRegInfo();
376 visitDecl(FunDefMRI, SignatureToGReg, GlobalToGReg, FunDefMF, *OpDefMI);
378 }
while (OpDefMI && (OpDefMI->
getOpcode() == SPIRV::OpFunction ||
379 OpDefMI->
getOpcode() == SPIRV::OpFunctionParameter));
381 MCRegister GlobalFunDefReg =
382 MAI.getRegisterAlias(FunDefMF, OpFunDef->
getReg());
384 "Function definition must refer to a global register");
385 MAI.setRegisterAlias(MF, OpReg, GlobalFunDefReg);
390void SPIRVModuleAnalysis::visitDecl(
392 std::map<const Value *, unsigned> &GlobalToGReg,
const MachineFunction *MF,
394 unsigned Opcode =
MI.getOpcode();
397 for (
const MachineOperand &MO :
MI.operands()) {
402 if (Opcode == SPIRV::OpConstantFunctionPointerINTEL &&
404 visitFunPtrUse(OpReg, SignatureToGReg, GlobalToGReg, MF,
MI);
408 if (
MAI.hasRegisterAlias(MF, MO.
getReg()))
412 if (isDeclSection(MRI, *OpDefMI))
413 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF, *OpDefMI);
419 dbgs() <<
"Unexpectedly, no unique definition for the operand ";
421 dbgs() <<
"\nInstruction: ";
426 "No unique definition is found for the virtual register");
430 bool IsFunDef =
false;
431 if (TII->isSpecConstantInstr(
MI)) {
432 GReg =
MAI.getNextIDRegister();
434 }
else if (Opcode == SPIRV::OpFunction ||
435 Opcode == SPIRV::OpFunctionParameter) {
436 GReg = handleFunctionOrParameter(MF,
MI, GlobalToGReg, IsFunDef);
437 }
else if (Opcode == SPIRV::OpTypeStruct ||
438 Opcode == SPIRV::OpConstantComposite) {
439 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
440 const MachineInstr *NextInstr =
MI.getNextNode();
442 ((Opcode == SPIRV::OpTypeStruct &&
443 NextInstr->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL) ||
444 (Opcode == SPIRV::OpConstantComposite &&
446 SPIRV::OpConstantCompositeContinuedINTEL))) {
447 MCRegister Tmp = handleTypeDeclOrConstant(*NextInstr, SignatureToGReg);
449 MAI.setSkipEmission(NextInstr);
452 }
else if (TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
453 TII->isInlineAsmDefInstr(
MI)) {
454 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
455 }
else if (Opcode == SPIRV::OpVariable) {
456 GReg = handleVariable(MF,
MI, GlobalToGReg);
459 dbgs() <<
"\nInstruction: ";
465 MAI.setRegisterAlias(MF,
MI.getOperand(0).getReg(), GReg);
467 MAI.setSkipEmission(&
MI);
470MCRegister SPIRVModuleAnalysis::handleFunctionOrParameter(
472 std::map<const Value *, unsigned> &GlobalToGReg,
bool &IsFunDef) {
473 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
474 assert(GObj &&
"Unregistered global definition");
478 assert(
F &&
"Expected a reference to a function or an argument");
479 IsFunDef = !
F->isDeclaration();
480 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
483 MCRegister GReg =
MAI.getNextIDRegister();
491SPIRVModuleAnalysis::handleTypeDeclOrConstant(
const MachineInstr &
MI,
494 auto [It,
Inserted] = SignatureToGReg.try_emplace(MISign);
497 MCRegister GReg =
MAI.getNextIDRegister();
503MCRegister SPIRVModuleAnalysis::handleVariable(
505 std::map<const Value *, unsigned> &GlobalToGReg) {
506 MAI.GlobalVarList.push_back(&
MI);
507 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
508 assert(GObj &&
"Unregistered global definition");
509 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
512 MCRegister GReg =
MAI.getNextIDRegister();
516 MAI.GlobalObjMap[GV] = GReg;
520void SPIRVModuleAnalysis::collectDeclarations(
const Module &M) {
522 std::map<const Value *, unsigned> GlobalToGReg;
523 for (
const Function &
F : M) {
524 MachineFunction *MF = MMI->getMachineFunction(
F);
527 const MachineRegisterInfo &MRI = MF->
getRegInfo();
528 unsigned PastHeader = 0;
529 for (MachineBasicBlock &
MBB : *MF) {
530 for (MachineInstr &
MI :
MBB) {
531 if (
MI.getNumOperands() == 0)
533 unsigned Opcode =
MI.getOpcode();
534 if (Opcode == SPIRV::OpFunction) {
535 if (PastHeader == 0) {
539 }
else if (Opcode == SPIRV::OpFunctionParameter) {
542 }
else if (PastHeader > 0) {
546 const MachineOperand &DefMO =
MI.getOperand(0);
548 case SPIRV::OpExtension:
549 MAI.Reqs.addExtension(SPIRV::Extension::Extension(DefMO.
getImm()));
550 MAI.setSkipEmission(&
MI);
552 case SPIRV::OpCapability:
553 MAI.Reqs.addCapability(SPIRV::Capability::Capability(DefMO.
getImm()));
554 MAI.setSkipEmission(&
MI);
559 if (DefMO.
isReg() && isDeclSection(MRI,
MI) &&
560 !
MAI.hasRegisterAlias(MF, DefMO.
getReg()))
561 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF,
MI);
574 if (
MI.getOpcode() == SPIRV::OpDecorate) {
576 auto Dec =
MI.getOperand(1).getImm();
577 if (Dec == SPIRV::Decoration::LinkageAttributes) {
578 auto Lnk =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
579 if (Lnk == SPIRV::LinkageType::Import) {
584 MAI.GlobalObjMap[ImportedFunc] =
585 MAI.getRegisterAlias(
MI.getMF(), Target);
588 }
else if (
MI.getOpcode() == SPIRV::OpFunction) {
591 MCRegister GlobalReg =
MAI.getRegisterAlias(
MI.getMF(),
Reg);
593 MAI.GlobalObjMap[
F] = GlobalReg;
605 auto FoundMI = IS.insert(std::move(MISign));
606 if (!FoundMI.second) {
607 if (
MI.getOpcode() == SPIRV::OpDecorate) {
609 "Decoration instructions must have at least 2 operands");
611 "Only OpDecorate instructions can be duplicates");
616 if (
MI.getOperand(1).getImm() != SPIRV::Decoration::FPFastMathMode)
621 if (instrToSignature(*OrigMI, MAI,
true) == MISign) {
622 assert(OrigMI->getNumOperands() ==
MI.getNumOperands() &&
623 "Original instruction must have the same number of operands");
625 OrigMI->getNumOperands() == 3 &&
626 "FPFastMathMode decoration must have 3 operands for OpDecorate");
627 unsigned OrigFlags = OrigMI->getOperand(2).getImm();
628 unsigned NewFlags =
MI.getOperand(2).getImm();
629 if (OrigFlags == NewFlags)
633 unsigned FinalFlags = OrigFlags | NewFlags;
635 <<
"Warning: Conflicting FPFastMathMode decoration flags "
637 << *OrigMI <<
"Original flags: " << OrigFlags
638 <<
", new flags: " << NewFlags
639 <<
". They will be merged on a best effort basis, but not "
640 "validated. Final flags: "
641 << FinalFlags <<
"\n";
648 assert(
false &&
"No original instruction found for the duplicate "
649 "OpDecorate, but we found one in IS.");
662void SPIRVModuleAnalysis::processOtherInstrs(
const Module &M) {
664 for (
const Function &
F : M) {
665 if (
F.isDeclaration())
667 MachineFunction *MF = MMI->getMachineFunction(
F);
670 for (MachineBasicBlock &
MBB : *MF)
671 for (MachineInstr &
MI :
MBB) {
672 if (
MAI.getSkipEmission(&
MI))
674 const unsigned OpCode =
MI.getOpcode();
675 if (OpCode == SPIRV::OpString) {
677 }
else if (OpCode == SPIRV::OpExtInst &&
MI.getOperand(2).isImm() &&
678 MI.getOperand(2).getImm() ==
679 SPIRV::InstructionSet::
680 NonSemantic_Shader_DebugInfo_100) {
687 MachineOperand Ins =
MI.getOperand(3);
688 namespace NS = SPIRV::NonSemanticExtInst;
689 static constexpr int64_t GlobalNonSemanticDITy[] = {
690 NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
691 NS::DebugTypeBasic, NS::DebugTypePointer};
692 bool IsGlobalDI =
false;
693 for (
unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
694 IsGlobalDI |= Ins.
getImm() == GlobalNonSemanticDITy[Idx];
697 }
else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
699 }
else if (OpCode == SPIRV::OpEntryPoint) {
701 }
else if (TII->isAliasingInstr(
MI)) {
703 }
else if (TII->isDecorationInstr(
MI)) {
705 collectFuncNames(
MI, &
F);
706 }
else if (TII->isConstantInstr(
MI)) {
710 }
else if (OpCode == SPIRV::OpFunction) {
711 collectFuncNames(
MI, &
F);
712 }
else if (OpCode == SPIRV::OpTypeForwardPointer) {
722void SPIRVModuleAnalysis::numberRegistersGlobally(
const Module &M) {
723 for (
const Function &
F : M) {
724 if (
F.isDeclaration())
726 MachineFunction *MF = MMI->getMachineFunction(
F);
728 for (MachineBasicBlock &
MBB : *MF) {
729 for (MachineInstr &
MI :
MBB) {
730 for (MachineOperand &
Op :
MI.operands()) {
734 if (
MAI.hasRegisterAlias(MF,
Reg))
736 MCRegister NewReg =
MAI.getNextIDRegister();
737 MAI.setRegisterAlias(MF,
Reg, NewReg);
739 if (
MI.getOpcode() != SPIRV::OpExtInst)
741 auto Set =
MI.getOperand(2).getImm();
742 auto [It,
Inserted] =
MAI.ExtInstSetMap.try_emplace(Set);
744 It->second =
MAI.getNextIDRegister();
752 SPIRV::OperandCategory::OperandCategory Category, uint32_t i,
754 addRequirements(getSymbolicOperandRequirements(Category, i, ST, *
this));
757void SPIRV::RequirementHandler::recursiveAddCapabilities(
759 for (
const auto &Cap : ToPrune) {
763 recursiveAddCapabilities(ImplicitDecls);
768 for (
const auto &Cap : ToAdd) {
769 bool IsNewlyInserted = AllCaps.insert(Cap).second;
770 if (!IsNewlyInserted)
774 recursiveAddCapabilities(ImplicitDecls);
775 MinimalCaps.push_back(Cap);
780 const SPIRV::Requirements &Req) {
784 if (Req.
Cap.has_value())
785 addCapabilities({Req.
Cap.value()});
787 addExtensions(Req.
Exts);
790 if (!MaxVersion.empty() && Req.
MinVer > MaxVersion) {
792 <<
" and <= " << MaxVersion <<
"\n");
796 if (MinVersion.empty() || Req.
MinVer > MinVersion)
801 if (!MinVersion.empty() && Req.
MaxVer < MinVersion) {
803 <<
" and >= " << MinVersion <<
"\n");
807 if (MaxVersion.empty() || Req.
MaxVer < MaxVersion)
813 const SPIRVSubtarget &ST)
const {
815 bool IsSatisfiable =
true;
816 auto TargetVer =
ST.getSPIRVVersion();
818 if (!MaxVersion.empty() && !TargetVer.empty() && MaxVersion < TargetVer) {
820 dbgs() <<
"Target SPIR-V version too high for required features\n"
821 <<
"Required max version: " << MaxVersion <<
" target version "
822 << TargetVer <<
"\n");
823 IsSatisfiable =
false;
826 if (!MinVersion.empty() && !TargetVer.empty() && MinVersion > TargetVer) {
827 LLVM_DEBUG(
dbgs() <<
"Target SPIR-V version too low for required features\n"
828 <<
"Required min version: " << MinVersion
829 <<
" target version " << TargetVer <<
"\n");
830 IsSatisfiable =
false;
833 if (!MinVersion.empty() && !MaxVersion.empty() && MinVersion > MaxVersion) {
836 <<
"Version is too low for some features and too high for others.\n"
837 <<
"Required SPIR-V min version: " << MinVersion
838 <<
" required SPIR-V max version " << MaxVersion <<
"\n");
839 IsSatisfiable =
false;
842 AvoidCapabilitiesSet AvoidCaps;
844 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
846 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
848 for (
auto Cap : MinimalCaps) {
849 if (AvailableCaps.contains(Cap) && !AvoidCaps.
S.
contains(Cap))
853 OperandCategory::CapabilityOperand, Cap)
855 IsSatisfiable =
false;
858 for (
auto Ext : AllExtensions) {
859 if (
ST.canUseExtension(Ext))
863 OperandCategory::ExtensionOperand, Ext)
865 IsSatisfiable =
false;
874 for (
const auto Cap : ToAdd)
875 if (AvailableCaps.insert(Cap).second)
877 SPIRV::OperandCategory::CapabilityOperand, Cap));
881 const Capability::Capability
ToRemove,
882 const Capability::Capability IfPresent) {
883 if (AllCaps.contains(IfPresent))
891 addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8,
894 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
896 Capability::GroupNonUniformVote,
897 Capability::GroupNonUniformArithmetic,
898 Capability::GroupNonUniformBallot,
899 Capability::GroupNonUniformClustered,
900 Capability::GroupNonUniformShuffle,
901 Capability::GroupNonUniformShuffleRelative,
902 Capability::GroupNonUniformQuad});
904 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
906 Capability::DotProductInput4x8Bit,
907 Capability::DotProductInput4x8BitPacked,
908 Capability::DemoteToHelperInvocation});
911 for (
auto Extension :
ST.getAllAvailableExtensions()) {
917 if (!
ST.isShader()) {
918 initAvailableCapabilitiesForOpenCL(ST);
923 initAvailableCapabilitiesForVulkan(ST);
930void RequirementHandler::initAvailableCapabilitiesForOpenCL(
931 const SPIRVSubtarget &ST) {
934 Capability::Kernel, Capability::Vector16,
935 Capability::Groups, Capability::GenericPointer,
936 Capability::StorageImageWriteWithoutFormat,
937 Capability::StorageImageReadWithoutFormat});
938 if (
ST.hasOpenCLFullProfile())
940 if (
ST.hasOpenCLImageSupport()) {
942 Capability::Image1D, Capability::SampledBuffer,
943 Capability::ImageBuffer});
944 if (
ST.isAtLeastOpenCLVer(VersionTuple(2, 0)))
947 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) &&
948 ST.isAtLeastOpenCLVer(VersionTuple(2, 2)))
950 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 4)))
951 addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
952 Capability::SignedZeroInfNanPreserve,
953 Capability::RoundingModeRTE,
954 Capability::RoundingModeRTZ});
961void RequirementHandler::initAvailableCapabilitiesForVulkan(
962 const SPIRVSubtarget &ST) {
968 Capability::GroupNonUniform,
970 Capability::SampledBuffer,
971 Capability::ImageBuffer,
972 Capability::UniformBufferArrayDynamicIndexing,
973 Capability::SampledImageArrayDynamicIndexing,
974 Capability::StorageBufferArrayDynamicIndexing,
975 Capability::StorageImageArrayDynamicIndexing,
976 Capability::DerivativeControl,
978 Capability::ImageQuery,
979 Capability::ImageGatherExtended,
980 Capability::Addresses,
981 Capability::VulkanMemoryModelKHR,
982 Capability::StorageImageExtendedFormats,
983 Capability::StorageImageMultisample,
984 Capability::ImageMSArray});
987 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
989 {Capability::ShaderNonUniformEXT, Capability::RuntimeDescriptorArrayEXT,
990 Capability::InputAttachmentArrayDynamicIndexingEXT,
991 Capability::UniformTexelBufferArrayDynamicIndexingEXT,
992 Capability::StorageTexelBufferArrayDynamicIndexingEXT,
993 Capability::UniformBufferArrayNonUniformIndexingEXT,
994 Capability::SampledImageArrayNonUniformIndexingEXT,
995 Capability::StorageBufferArrayNonUniformIndexingEXT,
996 Capability::StorageImageArrayNonUniformIndexingEXT,
997 Capability::InputAttachmentArrayNonUniformIndexingEXT,
998 Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
999 Capability::StorageTexelBufferArrayNonUniformIndexingEXT});
1003 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
1005 Capability::StorageImageReadWithoutFormat});
1013static void addOpDecorateReqs(
const MachineInstr &
MI,
unsigned DecIndex,
1016 int64_t DecOp =
MI.getOperand(DecIndex).getImm();
1017 auto Dec =
static_cast<SPIRV::Decoration::Decoration
>(DecOp);
1019 SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
1021 if (Dec == SPIRV::Decoration::BuiltIn) {
1022 int64_t BuiltInOp =
MI.getOperand(DecIndex + 1).getImm();
1023 auto BuiltIn =
static_cast<SPIRV::BuiltIn::BuiltIn
>(BuiltInOp);
1025 SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
1026 }
else if (Dec == SPIRV::Decoration::LinkageAttributes) {
1027 int64_t LinkageOp =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
1028 SPIRV::LinkageType::LinkageType LnkType =
1029 static_cast<SPIRV::LinkageType::LinkageType
>(LinkageOp);
1030 if (LnkType == SPIRV::LinkageType::LinkOnceODR)
1031 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_linkonce_odr);
1032 else if (LnkType == SPIRV::LinkageType::WeakAMD) {
1033 Reqs.
addExtension(SPIRV::Extension::SPV_AMD_weak_linkage);
1036 }
else if (Dec == SPIRV::Decoration::CacheControlLoadINTEL ||
1037 Dec == SPIRV::Decoration::CacheControlStoreINTEL) {
1038 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_cache_controls);
1039 }
else if (Dec == SPIRV::Decoration::HostAccessINTEL) {
1040 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_global_variable_host_access);
1041 }
else if (Dec == SPIRV::Decoration::InitModeINTEL ||
1042 Dec == SPIRV::Decoration::ImplementInRegisterMapINTEL) {
1044 SPIRV::Extension::SPV_INTEL_global_variable_fpga_decorations);
1045 }
else if (Dec == SPIRV::Decoration::NonUniformEXT) {
1047 }
else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
1049 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_fp_max_error);
1050 }
else if (Dec == SPIRV::Decoration::FPFastMathMode) {
1051 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
1053 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_float_controls2);
1062 assert(
MI.getNumOperands() >= 8 &&
"Insufficient operands for OpTypeImage");
1065 int64_t ImgFormatOp =
MI.getOperand(7).getImm();
1066 auto ImgFormat =
static_cast<SPIRV::ImageFormat::ImageFormat
>(ImgFormatOp);
1070 bool IsArrayed =
MI.getOperand(4).getImm() == 1;
1071 bool IsMultisampled =
MI.getOperand(5).getImm() == 1;
1072 bool NoSampler =
MI.getOperand(6).getImm() == 2;
1075 switch (
MI.getOperand(2).getImm()) {
1076 case SPIRV::Dim::DIM_1D:
1078 : SPIRV::Capability::Sampled1D);
1080 case SPIRV::Dim::DIM_2D:
1081 if (IsMultisampled && NoSampler)
1083 if (IsMultisampled && IsArrayed)
1086 case SPIRV::Dim::DIM_3D:
1088 case SPIRV::Dim::DIM_Cube:
1092 : SPIRV::Capability::SampledCubeArray);
1094 case SPIRV::Dim::DIM_Rect:
1096 : SPIRV::Capability::SampledRect);
1098 case SPIRV::Dim::DIM_Buffer:
1100 : SPIRV::Capability::SampledBuffer);
1102 case SPIRV::Dim::DIM_SubpassData:
1114 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_image_int64);
1118 if (!
ST.isShader()) {
1119 if (
MI.getNumOperands() > 8 &&
1120 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
1129 TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
1135#define ATOM_FLT_REQ_EXT_MSG(ExtName) \
1136 "The atomic float instruction requires the following SPIR-V " \
1137 "extension: SPV_EXT_shader_atomic_float" ExtName
1138static void AddAtomicVectorFloatRequirements(
const MachineInstr &
MI,
1142 MI.getMF()->getRegInfo().getVRegDef(
MI.getOperand(1).getReg());
1145 if (Rank != 2 && Rank != 4)
1147 "must be a 2-component or 4 component vector");
1152 if (EltTypeDef->
getOpcode() != SPIRV::OpTypeFloat ||
1155 "The element type for the result type of an atomic vector float "
1156 "instruction must be a 16-bit floating-point scalar");
1158 if (isBFloat16Type(EltTypeDef))
1160 "The element type for the result type of an atomic vector float "
1161 "instruction cannot be a bfloat16 scalar");
1162 if (!
ST.canUseExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector))
1164 "The atomic float16 vector instruction requires the following SPIR-V "
1165 "extension: SPV_NV_shader_atomic_fp16_vector");
1167 Reqs.
addExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector);
1168 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16VectorNV);
1175 "Expect register operand in atomic float instruction");
1176 Register TypeReg =
MI.getOperand(1).getReg();
1179 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
1180 return AddAtomicVectorFloatRequirements(
MI, Reqs, ST);
1182 if (TypeDef->
getOpcode() != SPIRV::OpTypeFloat)
1184 "floating-point type scalar");
1187 unsigned Op =
MI.getOpcode();
1188 if (
Op == SPIRV::OpAtomicFAddEXT) {
1189 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add))
1191 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
1194 if (isBFloat16Type(TypeDef)) {
1195 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1197 "The atomic bfloat16 instruction requires the following SPIR-V "
1198 "extension: SPV_INTEL_16bit_atomics",
1200 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1201 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16AddINTEL);
1203 if (!
ST.canUseExtension(
1204 SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
1206 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
1218 "Unexpected floating-point type width in atomic float instruction");
1221 if (!
ST.canUseExtension(
1222 SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max))
1224 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
1227 if (isBFloat16Type(TypeDef)) {
1228 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1230 "The atomic bfloat16 instruction requires the following SPIR-V "
1231 "extension: SPV_INTEL_16bit_atomics",
1233 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1234 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16MinMaxINTEL);
1236 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
1240 Reqs.
addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
1243 Reqs.
addCapability(SPIRV::Capability::AtomicFloat64MinMaxEXT);
1247 "Unexpected floating-point type width in atomic float instruction");
1253 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1257 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
1261 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1265 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
1269 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1273 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
1277 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1281 return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
1285 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1289 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
1292bool isCombinedImageSampler(
MachineInstr *SampledImageInst) {
1293 if (SampledImageInst->
getOpcode() != SPIRV::OpTypeSampledImage)
1299 return isSampledImage(ImageInst);
1304 if (
MI.getOpcode() != SPIRV::OpDecorate)
1308 if (Dec == SPIRV::Decoration::NonUniformEXT)
1326 if (
StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
1327 StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
1328 StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
1333 hasNonUniformDecoration(
Instr.getOperand(0).getReg(), MRI);
1335 auto FirstIndexReg =
Instr.getOperand(3).getReg();
1336 bool FirstIndexIsConstant =
1339 if (
StorageClass == SPIRV::StorageClass::StorageClass::StorageBuffer) {
1342 SPIRV::Capability::StorageBufferArrayNonUniformIndexingEXT);
1343 else if (!FirstIndexIsConstant)
1345 SPIRV::Capability::StorageBufferArrayDynamicIndexing);
1351 if (PointeeType->
getOpcode() != SPIRV::OpTypeImage &&
1352 PointeeType->
getOpcode() != SPIRV::OpTypeSampledImage &&
1353 PointeeType->
getOpcode() != SPIRV::OpTypeSampler) {
1357 if (isUniformTexelBuffer(PointeeType)) {
1360 SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1361 else if (!FirstIndexIsConstant)
1363 SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
1364 }
else if (isInputAttachment(PointeeType)) {
1367 SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1368 else if (!FirstIndexIsConstant)
1370 SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
1371 }
else if (isStorageTexelBuffer(PointeeType)) {
1374 SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1375 else if (!FirstIndexIsConstant)
1377 SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
1378 }
else if (isSampledImage(PointeeType) ||
1379 isCombinedImageSampler(PointeeType) ||
1380 PointeeType->
getOpcode() == SPIRV::OpTypeSampler) {
1383 SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1384 else if (!FirstIndexIsConstant)
1386 SPIRV::Capability::SampledImageArrayDynamicIndexing);
1387 }
else if (isStorageImage(PointeeType)) {
1390 SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1391 else if (!FirstIndexIsConstant)
1393 SPIRV::Capability::StorageImageArrayDynamicIndexing);
1397static bool isImageTypeWithUnknownFormat(
SPIRVTypeInst TypeInst) {
1398 if (TypeInst->
getOpcode() != SPIRV::OpTypeImage)
1407 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product))
1408 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_integer_dot_product);
1412 assert(
MI.getOperand(2).isReg() &&
"Unexpected operand in dot");
1416 assert(
Input->getOperand(1).isReg() &&
"Unexpected operand in dot input");
1420 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1422 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8BitPacked);
1423 }
else if (TypeDef->
getOpcode() == SPIRV::OpTypeVector) {
1429 "Dot operand of 8-bit integer type requires 4 components");
1430 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8Bit);
1445 unsigned AddrSpace = ASOp.
getImm();
1446 if (AddrSpace != SPIRV::StorageClass::UniformConstant) {
1447 if (!
ST.canUseExtension(
1449 SPV_EXT_relaxed_printf_string_address_space)) {
1451 "required because printf uses a format string not "
1452 "in constant address space.",
1456 SPIRV::Extension::SPV_EXT_relaxed_printf_string_address_space);
1465 if (
MI.getNumOperands() <=
OpIdx)
1469 if (Mask & (1U <<
I))
1478 unsigned Op =
MI.getOpcode();
1480 case SPIRV::OpMemoryModel: {
1481 int64_t Addr =
MI.getOperand(0).getImm();
1484 int64_t Mem =
MI.getOperand(1).getImm();
1489 case SPIRV::OpEntryPoint: {
1490 int64_t
Exe =
MI.getOperand(0).getImm();
1495 case SPIRV::OpExecutionMode:
1496 case SPIRV::OpExecutionModeId: {
1497 int64_t
Exe =
MI.getOperand(1).getImm();
1502 case SPIRV::OpTypeMatrix:
1505 case SPIRV::OpTypeInt: {
1506 unsigned BitWidth =
MI.getOperand(1).getImm();
1514 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1518 if (!
ST.canUseExtension(
1519 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers))
1521 "OpTypeInt type with a width other than 8, 16, 32 or 64 bits "
1522 "requires the following SPIR-V extension: "
1523 "SPV_ALTERA_arbitrary_precision_integers");
1525 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
1526 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
1530 case SPIRV::OpDot: {
1533 if (isBFloat16Type(TypeDef))
1534 Reqs.
addCapability(SPIRV::Capability::BFloat16DotProductKHR);
1537 case SPIRV::OpTypeFloat: {
1538 unsigned BitWidth =
MI.getOperand(1).getImm();
1542 if (isBFloat16Type(&
MI)) {
1543 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bfloat16))
1545 "following SPIR-V extension: SPV_KHR_bfloat16",
1555 case SPIRV::OpTypeVector: {
1556 unsigned NumComponents =
MI.getOperand(2).getImm();
1557 if (NumComponents == 8 || NumComponents == 16)
1563 if (ElemTypeDef->
getOpcode() == SPIRV::OpTypePointer &&
1564 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
1565 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter);
1566 Reqs.
addCapability(SPIRV::Capability::MaskedGatherScatterINTEL);
1570 case SPIRV::OpTypePointer: {
1571 auto SC =
MI.getOperand(1).getImm();
1582 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1587 case SPIRV::OpExtInst: {
1588 if (
MI.getOperand(2).getImm() ==
1589 static_cast<int64_t
>(
1590 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1591 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1594 if (
MI.getOperand(3).getImm() ==
1595 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1596 addPrintfRequirements(
MI, Reqs, ST);
1603 case SPIRV::OpAliasDomainDeclINTEL:
1604 case SPIRV::OpAliasScopeDeclINTEL:
1605 case SPIRV::OpAliasScopeListDeclINTEL: {
1606 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1607 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1610 case SPIRV::OpBitReverse:
1611 case SPIRV::OpBitFieldInsert:
1612 case SPIRV::OpBitFieldSExtract:
1613 case SPIRV::OpBitFieldUExtract:
1614 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1618 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1621 case SPIRV::OpTypeRuntimeArray:
1624 case SPIRV::OpTypeOpaque:
1625 case SPIRV::OpTypeEvent:
1628 case SPIRV::OpTypePipe:
1629 case SPIRV::OpTypeReserveId:
1632 case SPIRV::OpTypeDeviceEvent:
1633 case SPIRV::OpTypeQueue:
1634 case SPIRV::OpBuildNDRange:
1637 case SPIRV::OpDecorate:
1638 case SPIRV::OpDecorateId:
1639 case SPIRV::OpDecorateString:
1640 addOpDecorateReqs(
MI, 1, Reqs, ST);
1642 case SPIRV::OpMemberDecorate:
1643 case SPIRV::OpMemberDecorateString:
1644 addOpDecorateReqs(
MI, 2, Reqs, ST);
1646 case SPIRV::OpInBoundsPtrAccessChain:
1649 case SPIRV::OpConstantSampler:
1652 case SPIRV::OpInBoundsAccessChain:
1653 case SPIRV::OpAccessChain:
1654 addOpAccessChainReqs(
MI, Reqs, ST);
1656 case SPIRV::OpTypeImage:
1657 addOpTypeImageReqs(
MI, Reqs, ST);
1659 case SPIRV::OpTypeSampler:
1660 if (!
ST.isShader()) {
1664 case SPIRV::OpTypeForwardPointer:
1668 case SPIRV::OpAtomicFlagTestAndSet:
1669 case SPIRV::OpAtomicLoad:
1670 case SPIRV::OpAtomicStore:
1671 case SPIRV::OpAtomicExchange:
1672 case SPIRV::OpAtomicCompareExchange:
1673 case SPIRV::OpAtomicIIncrement:
1674 case SPIRV::OpAtomicIDecrement:
1675 case SPIRV::OpAtomicIAdd:
1676 case SPIRV::OpAtomicISub:
1677 case SPIRV::OpAtomicUMin:
1678 case SPIRV::OpAtomicUMax:
1679 case SPIRV::OpAtomicSMin:
1680 case SPIRV::OpAtomicSMax:
1681 case SPIRV::OpAtomicAnd:
1682 case SPIRV::OpAtomicOr:
1683 case SPIRV::OpAtomicXor: {
1686 if (
Op == SPIRV::OpAtomicStore) {
1689 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1695 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1700 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1702 "16-bit integer atomic operations require the following SPIR-V "
1703 "extension: SPV_INTEL_16bit_atomics",
1705 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1707 case SPIRV::OpAtomicLoad:
1708 case SPIRV::OpAtomicStore:
1709 case SPIRV::OpAtomicExchange:
1710 case SPIRV::OpAtomicCompareExchange:
1711 case SPIRV::OpAtomicCompareExchangeWeak:
1713 SPIRV::Capability::AtomicInt16CompareExchangeINTEL);
1720 }
else if (isBFloat16Type(TypeDef)) {
1721 if (
is_contained({SPIRV::OpAtomicLoad, SPIRV::OpAtomicStore,
1722 SPIRV::OpAtomicExchange},
1724 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1726 "The atomic bfloat16 instruction requires the following SPIR-V "
1727 "extension: SPV_INTEL_16bit_atomics",
1729 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1730 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16LoadStoreINTEL);
1735 case SPIRV::OpGroupNonUniformIAdd:
1736 case SPIRV::OpGroupNonUniformFAdd:
1737 case SPIRV::OpGroupNonUniformIMul:
1738 case SPIRV::OpGroupNonUniformFMul:
1739 case SPIRV::OpGroupNonUniformSMin:
1740 case SPIRV::OpGroupNonUniformUMin:
1741 case SPIRV::OpGroupNonUniformFMin:
1742 case SPIRV::OpGroupNonUniformSMax:
1743 case SPIRV::OpGroupNonUniformUMax:
1744 case SPIRV::OpGroupNonUniformFMax:
1745 case SPIRV::OpGroupNonUniformBitwiseAnd:
1746 case SPIRV::OpGroupNonUniformBitwiseOr:
1747 case SPIRV::OpGroupNonUniformBitwiseXor:
1748 case SPIRV::OpGroupNonUniformLogicalAnd:
1749 case SPIRV::OpGroupNonUniformLogicalOr:
1750 case SPIRV::OpGroupNonUniformLogicalXor: {
1752 int64_t GroupOp =
MI.getOperand(3).getImm();
1754 case SPIRV::GroupOperation::Reduce:
1755 case SPIRV::GroupOperation::InclusiveScan:
1756 case SPIRV::GroupOperation::ExclusiveScan:
1757 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1759 case SPIRV::GroupOperation::ClusteredReduce:
1760 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1762 case SPIRV::GroupOperation::PartitionedReduceNV:
1763 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1764 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1765 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1770 case SPIRV::OpGroupNonUniformQuadSwap:
1773 case SPIRV::OpImageQueryLod:
1776 case SPIRV::OpImageQuerySize:
1777 case SPIRV::OpImageQuerySizeLod:
1778 case SPIRV::OpImageQueryLevels:
1779 case SPIRV::OpImageQuerySamples:
1783 case SPIRV::OpImageQueryFormat: {
1784 Register ResultReg =
MI.getOperand(0).getReg();
1786 static const unsigned CompareOps[] = {
1787 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1788 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1789 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1790 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1791 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1793 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1794 if (ImmVal == 4323 || ImmVal == 4324) {
1795 if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1796 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1799 "SPV_EXT_image_raw10_raw12 extension");
1804 unsigned Opc = UseInst.getOpcode();
1806 if (
Opc == SPIRV::OpSwitch) {
1809 CheckAndAddExtension(
Op.getImm());
1811 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1814 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1817 CheckAndAddExtension(ImmVal);
1825 case SPIRV::OpGroupNonUniformShuffle:
1826 case SPIRV::OpGroupNonUniformShuffleXor:
1827 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1829 case SPIRV::OpGroupNonUniformShuffleUp:
1830 case SPIRV::OpGroupNonUniformShuffleDown:
1831 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1833 case SPIRV::OpGroupAll:
1834 case SPIRV::OpGroupAny:
1835 case SPIRV::OpGroupBroadcast:
1836 case SPIRV::OpGroupIAdd:
1837 case SPIRV::OpGroupFAdd:
1838 case SPIRV::OpGroupFMin:
1839 case SPIRV::OpGroupUMin:
1840 case SPIRV::OpGroupSMin:
1841 case SPIRV::OpGroupFMax:
1842 case SPIRV::OpGroupUMax:
1843 case SPIRV::OpGroupSMax:
1846 case SPIRV::OpGroupNonUniformElect:
1849 case SPIRV::OpGroupNonUniformAll:
1850 case SPIRV::OpGroupNonUniformAny:
1851 case SPIRV::OpGroupNonUniformAllEqual:
1854 case SPIRV::OpGroupNonUniformBroadcast:
1855 case SPIRV::OpGroupNonUniformBroadcastFirst:
1856 case SPIRV::OpGroupNonUniformBallot:
1857 case SPIRV::OpGroupNonUniformInverseBallot:
1858 case SPIRV::OpGroupNonUniformBallotBitExtract:
1859 case SPIRV::OpGroupNonUniformBallotBitCount:
1860 case SPIRV::OpGroupNonUniformBallotFindLSB:
1861 case SPIRV::OpGroupNonUniformBallotFindMSB:
1862 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1864 case SPIRV::OpSubgroupShuffleINTEL:
1865 case SPIRV::OpSubgroupShuffleDownINTEL:
1866 case SPIRV::OpSubgroupShuffleUpINTEL:
1867 case SPIRV::OpSubgroupShuffleXorINTEL:
1868 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1869 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1870 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1873 case SPIRV::OpSubgroupBlockReadINTEL:
1874 case SPIRV::OpSubgroupBlockWriteINTEL:
1875 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1876 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1877 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1880 case SPIRV::OpSubgroupImageBlockReadINTEL:
1881 case SPIRV::OpSubgroupImageBlockWriteINTEL:
1882 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1883 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1884 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
1887 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
1888 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
1889 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
1890 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
1891 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
1894 case SPIRV::OpAssumeTrueKHR:
1895 case SPIRV::OpExpectKHR:
1896 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
1897 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
1901 case SPIRV::OpFmaKHR:
1902 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
1907 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
1908 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
1909 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
1910 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
1911 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
1914 case SPIRV::OpConstantFunctionPointerINTEL:
1915 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1916 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1917 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1920 case SPIRV::OpGroupNonUniformRotateKHR:
1921 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
1923 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
1925 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
1926 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
1929 case SPIRV::OpFixedCosALTERA:
1930 case SPIRV::OpFixedSinALTERA:
1931 case SPIRV::OpFixedCosPiALTERA:
1932 case SPIRV::OpFixedSinPiALTERA:
1933 case SPIRV::OpFixedExpALTERA:
1934 case SPIRV::OpFixedLogALTERA:
1935 case SPIRV::OpFixedRecipALTERA:
1936 case SPIRV::OpFixedSqrtALTERA:
1937 case SPIRV::OpFixedSinCosALTERA:
1938 case SPIRV::OpFixedSinCosPiALTERA:
1939 case SPIRV::OpFixedRsqrtALTERA:
1940 if (!
ST.canUseExtension(
1941 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
1943 "following SPIR-V extension: "
1944 "SPV_ALTERA_arbitrary_precision_fixed_point",
1947 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
1948 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
1950 case SPIRV::OpGroupIMulKHR:
1951 case SPIRV::OpGroupFMulKHR:
1952 case SPIRV::OpGroupBitwiseAndKHR:
1953 case SPIRV::OpGroupBitwiseOrKHR:
1954 case SPIRV::OpGroupBitwiseXorKHR:
1955 case SPIRV::OpGroupLogicalAndKHR:
1956 case SPIRV::OpGroupLogicalOrKHR:
1957 case SPIRV::OpGroupLogicalXorKHR:
1958 if (
ST.canUseExtension(
1959 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
1960 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
1961 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
1964 case SPIRV::OpReadClockKHR:
1965 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
1967 "following SPIR-V extension: SPV_KHR_shader_clock",
1969 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
1972 case SPIRV::OpAbortKHR:
1973 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_abort))
1975 "following SPIR-V extension: SPV_KHR_abort",
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::OpAtomicFAddEXT:
1987 case SPIRV::OpAtomicFMinEXT:
1988 case SPIRV::OpAtomicFMaxEXT:
1989 AddAtomicFloatRequirements(
MI, Reqs, ST);
1991 case SPIRV::OpConvertBF16ToFINTEL:
1992 case SPIRV::OpConvertFToBF16INTEL:
1993 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
1994 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
1995 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
1998 case SPIRV::OpRoundFToTF32INTEL:
1999 if (
ST.canUseExtension(
2000 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
2001 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
2002 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
2005 case SPIRV::OpVariableLengthArrayINTEL:
2006 case SPIRV::OpSaveMemoryINTEL:
2007 case SPIRV::OpRestoreMemoryINTEL:
2008 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
2009 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
2010 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
2013 case SPIRV::OpAsmTargetINTEL:
2014 case SPIRV::OpAsmINTEL:
2015 case SPIRV::OpAsmCallINTEL:
2016 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
2017 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
2021 case SPIRV::OpTypeCooperativeMatrixKHR: {
2022 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2024 "OpTypeCooperativeMatrixKHR type requires the "
2025 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
2027 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2028 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2031 if (isBFloat16Type(TypeDef))
2032 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
2035 case SPIRV::OpArithmeticFenceEXT:
2036 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
2038 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
2040 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
2043 case SPIRV::OpControlBarrierArriveINTEL:
2044 case SPIRV::OpControlBarrierWaitINTEL:
2045 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
2046 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
2050 case SPIRV::OpCooperativeMatrixMulAddKHR: {
2051 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2053 "following SPIR-V extension: "
2054 "SPV_KHR_cooperative_matrix",
2056 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2057 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2058 constexpr unsigned MulAddMaxSize = 6;
2059 if (
MI.getNumOperands() != MulAddMaxSize)
2061 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
2063 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
2064 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2066 "require the following SPIR-V extension: "
2067 "SPV_INTEL_joint_matrix",
2069 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2071 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
2074 MatrixAAndBBFloat16ComponentsINTEL ||
2076 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
2078 MatrixResultBFloat16ComponentsINTEL) {
2079 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2081 "require the following SPIR-V extension: "
2082 "SPV_INTEL_joint_matrix",
2084 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2086 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
2090 case SPIRV::OpCooperativeMatrixLoadKHR:
2091 case SPIRV::OpCooperativeMatrixStoreKHR:
2092 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2093 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2094 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
2095 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2097 "following SPIR-V extension: "
2098 "SPV_KHR_cooperative_matrix",
2100 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2101 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2105 std::unordered_map<unsigned, unsigned> LayoutToInstMap = {
2106 {SPIRV::OpCooperativeMatrixLoadKHR, 3},
2107 {SPIRV::OpCooperativeMatrixStoreKHR, 2},
2108 {SPIRV::OpCooperativeMatrixLoadCheckedINTEL, 5},
2109 {SPIRV::OpCooperativeMatrixStoreCheckedINTEL, 4},
2110 {SPIRV::OpCooperativeMatrixPrefetchINTEL, 4}};
2112 const unsigned LayoutNum = LayoutToInstMap[
Op];
2113 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
2116 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
2119 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
2120 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2122 "extension: SPV_INTEL_joint_matrix",
2124 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2125 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2130 if (
Op == SPIRV::OpCooperativeMatrixLoadKHR ||
2131 Op == SPIRV::OpCooperativeMatrixStoreKHR)
2134 std::string InstName;
2136 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2137 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2139 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2140 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2142 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2143 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2147 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2148 const std::string ErrorMsg =
2149 InstName +
" instruction requires the "
2150 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2153 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2154 if (
Op == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2155 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2159 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2162 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2163 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2165 "instructions require the following SPIR-V extension: "
2166 "SPV_INTEL_joint_matrix",
2168 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2170 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2172 case SPIRV::OpReadPipeBlockingALTERA:
2173 case SPIRV::OpWritePipeBlockingALTERA:
2174 if (
ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2175 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2179 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2180 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2182 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2184 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2186 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2188 case SPIRV::OpConvertHandleToImageINTEL:
2189 case SPIRV::OpConvertHandleToSamplerINTEL:
2190 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2191 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2193 "instructions require the following SPIR-V extension: "
2194 "SPV_INTEL_bindless_images",
2197 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2199 if (
Op == SPIRV::OpConvertHandleToImageINTEL &&
2200 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2202 "OpConvertHandleToImageINTEL",
2204 }
else if (
Op == SPIRV::OpConvertHandleToSamplerINTEL &&
2205 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2207 "OpConvertHandleToSamplerINTEL",
2209 }
else if (
Op == SPIRV::OpConvertHandleToSampledImageINTEL &&
2210 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2212 "OpConvertHandleToSampledImageINTEL",
2217 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2218 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2220 "Parameter value must be a 32-bit scalar in case of "
2221 "Physical32 addressing model or a 64-bit scalar in case of "
2222 "Physical64 addressing model",
2225 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2229 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2230 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2231 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2232 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2233 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2234 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2236 "Prefetch/Store]INTEL instructions require the "
2237 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2239 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2240 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2242 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2243 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2246 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2247 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2252 case SPIRV::OpKill: {
2255 case SPIRV::OpDemoteToHelperInvocation:
2256 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2258 if (
ST.canUseExtension(
2259 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2262 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2267 case SPIRV::OpSUDot:
2268 case SPIRV::OpSDotAccSat:
2269 case SPIRV::OpUDotAccSat:
2270 case SPIRV::OpSUDotAccSat:
2271 AddDotProductRequirements(
MI, Reqs, ST);
2273 case SPIRV::OpImageSampleImplicitLod:
2275 addImageOperandReqs(
MI, Reqs, ST, 4);
2277 case SPIRV::OpImageSampleExplicitLod:
2278 addImageOperandReqs(
MI, Reqs, ST, 4);
2280 case SPIRV::OpImageSampleDrefImplicitLod:
2282 addImageOperandReqs(
MI, Reqs, ST, 5);
2284 case SPIRV::OpImageSampleDrefExplicitLod:
2286 addImageOperandReqs(
MI, Reqs, ST, 5);
2288 case SPIRV::OpImageFetch:
2290 addImageOperandReqs(
MI, Reqs, ST, 4);
2292 case SPIRV::OpImageDrefGather:
2293 case SPIRV::OpImageGather:
2295 addImageOperandReqs(
MI, Reqs, ST, 5);
2297 case SPIRV::OpImageRead: {
2298 Register ImageReg =
MI.getOperand(2).getReg();
2307 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2308 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2311 case SPIRV::OpImageWrite: {
2312 Register ImageReg =
MI.getOperand(0).getReg();
2321 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2322 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2325 case SPIRV::OpTypeStructContinuedINTEL:
2326 case SPIRV::OpConstantCompositeContinuedINTEL:
2327 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2328 case SPIRV::OpCompositeConstructContinuedINTEL: {
2329 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2331 "Continued instructions require the "
2332 "following SPIR-V extension: SPV_INTEL_long_composites",
2334 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2338 case SPIRV::OpArbitraryFloatEQALTERA:
2339 case SPIRV::OpArbitraryFloatGEALTERA:
2340 case SPIRV::OpArbitraryFloatGTALTERA:
2341 case SPIRV::OpArbitraryFloatLEALTERA:
2342 case SPIRV::OpArbitraryFloatLTALTERA:
2343 case SPIRV::OpArbitraryFloatCbrtALTERA:
2344 case SPIRV::OpArbitraryFloatCosALTERA:
2345 case SPIRV::OpArbitraryFloatCosPiALTERA:
2346 case SPIRV::OpArbitraryFloatExp10ALTERA:
2347 case SPIRV::OpArbitraryFloatExp2ALTERA:
2348 case SPIRV::OpArbitraryFloatExpALTERA:
2349 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2350 case SPIRV::OpArbitraryFloatHypotALTERA:
2351 case SPIRV::OpArbitraryFloatLog10ALTERA:
2352 case SPIRV::OpArbitraryFloatLog1pALTERA:
2353 case SPIRV::OpArbitraryFloatLog2ALTERA:
2354 case SPIRV::OpArbitraryFloatLogALTERA:
2355 case SPIRV::OpArbitraryFloatRecipALTERA:
2356 case SPIRV::OpArbitraryFloatSinCosALTERA:
2357 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2358 case SPIRV::OpArbitraryFloatSinALTERA:
2359 case SPIRV::OpArbitraryFloatSinPiALTERA:
2360 case SPIRV::OpArbitraryFloatSqrtALTERA:
2361 case SPIRV::OpArbitraryFloatACosALTERA:
2362 case SPIRV::OpArbitraryFloatACosPiALTERA:
2363 case SPIRV::OpArbitraryFloatAddALTERA:
2364 case SPIRV::OpArbitraryFloatASinALTERA:
2365 case SPIRV::OpArbitraryFloatASinPiALTERA:
2366 case SPIRV::OpArbitraryFloatATan2ALTERA:
2367 case SPIRV::OpArbitraryFloatATanALTERA:
2368 case SPIRV::OpArbitraryFloatATanPiALTERA:
2369 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2370 case SPIRV::OpArbitraryFloatCastALTERA:
2371 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2372 case SPIRV::OpArbitraryFloatDivALTERA:
2373 case SPIRV::OpArbitraryFloatMulALTERA:
2374 case SPIRV::OpArbitraryFloatPowALTERA:
2375 case SPIRV::OpArbitraryFloatPowNALTERA:
2376 case SPIRV::OpArbitraryFloatPowRALTERA:
2377 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2378 case SPIRV::OpArbitraryFloatSubALTERA: {
2379 if (!
ST.canUseExtension(
2380 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2382 "Floating point instructions can't be translated correctly without "
2383 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2386 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2388 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2391 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2392 if (!
ST.canUseExtension(
2393 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2395 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2397 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2400 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2402 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2405 case SPIRV::OpBitwiseFunctionINTEL: {
2406 if (!
ST.canUseExtension(
2407 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2409 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2410 "extension: SPV_INTEL_ternary_bitwise_function",
2412 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2413 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2416 case SPIRV::OpCopyMemorySized: {
2421 case SPIRV::OpPredicatedLoadINTEL:
2422 case SPIRV::OpPredicatedStoreINTEL: {
2423 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2425 "OpPredicated[Load/Store]INTEL instructions require "
2426 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2428 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2432 case SPIRV::OpFAddS:
2433 case SPIRV::OpFSubS:
2434 case SPIRV::OpFMulS:
2435 case SPIRV::OpFDivS:
2436 case SPIRV::OpFRemS:
2438 case SPIRV::OpFNegate:
2439 case SPIRV::OpFAddV:
2440 case SPIRV::OpFSubV:
2441 case SPIRV::OpFMulV:
2442 case SPIRV::OpFDivV:
2443 case SPIRV::OpFRemV:
2444 case SPIRV::OpFNegateV: {
2447 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2449 if (isBFloat16Type(TypeDef)) {
2450 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2452 "Arithmetic instructions with bfloat16 arguments require the "
2453 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2455 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2456 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2460 case SPIRV::OpOrdered:
2461 case SPIRV::OpUnordered:
2462 case SPIRV::OpFOrdEqual:
2463 case SPIRV::OpFOrdNotEqual:
2464 case SPIRV::OpFOrdLessThan:
2465 case SPIRV::OpFOrdLessThanEqual:
2466 case SPIRV::OpFOrdGreaterThan:
2467 case SPIRV::OpFOrdGreaterThanEqual:
2468 case SPIRV::OpFUnordEqual:
2469 case SPIRV::OpFUnordNotEqual:
2470 case SPIRV::OpFUnordLessThan:
2471 case SPIRV::OpFUnordLessThanEqual:
2472 case SPIRV::OpFUnordGreaterThan:
2473 case SPIRV::OpFUnordGreaterThanEqual: {
2477 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2479 if (isBFloat16Type(TypeDef)) {
2480 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2482 "Relational instructions with bfloat16 arguments require the "
2483 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2485 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2486 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2490 case SPIRV::OpDPdxCoarse:
2491 case SPIRV::OpDPdyCoarse:
2492 case SPIRV::OpDPdxFine:
2493 case SPIRV::OpDPdyFine: {
2497 case SPIRV::OpLoopControlINTEL: {
2498 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2499 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2511 SPIRV::Capability::Shader);
2523 addInstrRequirements(
MI, MAI, ST);
2526 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2528 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2529 RequireKHRFloatControls2 =
false,
2531 bool HasIntelFloatControls2 =
2532 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2533 bool HasKHRFloatControls2 =
2534 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2535 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2541 auto EM =
Const->getZExtValue();
2545 case SPIRV::ExecutionMode::DenormPreserve:
2546 case SPIRV::ExecutionMode::DenormFlushToZero:
2547 case SPIRV::ExecutionMode::RoundingModeRTE:
2548 case SPIRV::ExecutionMode::RoundingModeRTZ:
2549 RequireFloatControls = VerLower14;
2551 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2553 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2554 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2555 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2556 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2557 if (HasIntelFloatControls2) {
2558 RequireIntelFloatControls2 =
true;
2560 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2563 case SPIRV::ExecutionMode::FPFastMathDefault: {
2564 if (HasKHRFloatControls2) {
2565 RequireKHRFloatControls2 =
true;
2567 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2571 case SPIRV::ExecutionMode::ContractionOff:
2572 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2573 if (HasKHRFloatControls2) {
2574 RequireKHRFloatControls2 =
true;
2576 SPIRV::OperandCategory::ExecutionModeOperand,
2577 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2580 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2585 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2590 if (RequireFloatControls &&
2591 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2593 if (RequireIntelFloatControls2)
2595 if (RequireKHRFloatControls2)
2599 if (
F.isDeclaration())
2601 if (
F.getMetadata(
"reqd_work_group_size"))
2603 SPIRV::OperandCategory::ExecutionModeOperand,
2604 SPIRV::ExecutionMode::LocalSize, ST);
2605 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2607 SPIRV::OperandCategory::ExecutionModeOperand,
2608 SPIRV::ExecutionMode::LocalSize, ST);
2610 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2613 if (
F.getMetadata(
"work_group_size_hint"))
2615 SPIRV::OperandCategory::ExecutionModeOperand,
2616 SPIRV::ExecutionMode::LocalSizeHint, ST);
2617 if (
F.getMetadata(
"intel_reqd_sub_group_size"))
2619 SPIRV::OperandCategory::ExecutionModeOperand,
2620 SPIRV::ExecutionMode::SubgroupSize, ST);
2621 if (
F.getMetadata(
"max_work_group_size"))
2623 SPIRV::OperandCategory::ExecutionModeOperand,
2624 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2625 if (
F.getMetadata(
"vec_type_hint"))
2627 SPIRV::OperandCategory::ExecutionModeOperand,
2628 SPIRV::ExecutionMode::VecTypeHint, ST);
2630 if (
F.hasOptNone()) {
2631 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2634 }
else if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2644 unsigned Flags = SPIRV::FPFastMathMode::None;
2645 bool CanUseKHRFloatControls2 =
2646 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2648 Flags |= SPIRV::FPFastMathMode::NotNaN;
2650 Flags |= SPIRV::FPFastMathMode::NotInf;
2652 Flags |= SPIRV::FPFastMathMode::NSZ;
2654 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2656 Flags |= SPIRV::FPFastMathMode::AllowContract;
2658 if (CanUseKHRFloatControls2)
2666 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2667 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2668 SPIRV::FPFastMathMode::AllowTransform |
2669 SPIRV::FPFastMathMode::AllowReassoc |
2670 SPIRV::FPFastMathMode::AllowContract;
2672 Flags |= SPIRV::FPFastMathMode::Fast;
2675 if (CanUseKHRFloatControls2) {
2677 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2678 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2683 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2684 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2685 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2686 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2687 "AllowContract flags to be enabled as well.");
2698 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2701static void handleMIFlagDecoration(
2706 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2707 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2710 SPIRV::Decoration::NoSignedWrap, {});
2713 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2714 SPIRV::Decoration::NoUnsignedWrap, ST,
2718 SPIRV::Decoration::NoUnsignedWrap, {});
2723 TII.canUseFastMathFlags(
2724 I,
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) ||
2725 (
ST.isKernel() &&
I.getOpcode() == SPIRV::OpExtInst);
2729 unsigned FMFlags = getFastMathFlags(
I, ST);
2730 if (FMFlags == SPIRV::FPFastMathMode::None) {
2733 if (FPFastMathDefaultInfoVec.
empty())
2749 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2750 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2751 ?
I.getOperand(1).getReg()
2752 :
I.getOperand(2).getReg();
2760 if (Ty == Elem.Ty) {
2761 FMFlags = Elem.FastMathFlags;
2762 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2763 Elem.FPFastMathDefault;
2768 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2771 if (isFastMathModeAvailable(ST)) {
2772 Register DstReg =
I.getOperand(0).getReg();
2788 for (
auto &
MBB : *MF)
2789 for (
auto &
MI :
MBB)
2790 handleMIFlagDecoration(
MI, ST,
TII, MAI.
Reqs, GR,
2807 for (
auto &
MBB : *MF) {
2808 if (!
MBB.hasName() ||
MBB.empty())
2827 for (
auto &
MBB : *MF) {
2829 MI.setDesc(
TII.get(SPIRV::OpPhi));
2832 MI.insert(
MI.operands_begin() + 1,
2833 {MachineOperand::CreateReg(ResTypeReg, false)});
2852 SPIRV::FPFastMathMode::None);
2854 SPIRV::FPFastMathMode::None);
2856 SPIRV::FPFastMathMode::None);
2863 size_t BitWidth = Ty->getScalarSizeInBits();
2867 assert(Index >= 0 && Index < 3 &&
2868 "Expected FPFastMathDefaultInfo for half, float, or double");
2869 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2870 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2871 return FPFastMathDefaultInfoVec[Index];
2874static void collectFPFastMathDefaults(
const Module &M,
2877 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
2886 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2890 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2899 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
2901 "Expected 4 operands for FPFastMathDefault");
2912 Info.FastMathFlags = Flags;
2913 Info.FPFastMathDefault =
true;
2914 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
2916 "Expected no operands for ContractionOff");
2923 Info.ContractionOff =
true;
2925 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
2927 "Expected 1 operand for SignedZeroInfNanPreserve");
2928 unsigned TargetWidth =
2937 assert(Index >= 0 && Index < 3 &&
2938 "Expected FPFastMathDefaultInfo for half, float, or double");
2939 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2940 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2941 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
2952 SPIRVTargetMachine &TM =
2956 TII = ST->getInstrInfo();
2962 patchPhis(M, GR, *TII, MMI);
2964 addMBBNames(M, *TII, MMI, *ST,
MAI);
2965 collectFPFastMathDefaults(M,
MAI, *ST);
2966 addDecorations(M, *TII, MMI, *ST,
MAI, GR);
2968 collectReqs(M,
MAI, MMI, *ST);
2972 collectReqs(M,
MAI, MMI, *ST);
2973 collectDeclarations(M);
2976 numberRegistersGlobally(M);
2979 processOtherInstrs(M);
2983 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
2986 GR->setBound(
MAI.MaxID);
MachineInstrBuilder & UseMI
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
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
VersionTuple getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
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