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) {
681 MachineOperand Ins =
MI.getOperand(3);
682 namespace NS = SPIRV::NonSemanticExtInst;
683 static constexpr int64_t GlobalNonSemanticDITy[] = {
684 NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
685 NS::DebugTypeBasic, NS::DebugTypePointer};
686 bool IsGlobalDI =
false;
687 for (
unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
688 IsGlobalDI |= Ins.
getImm() == GlobalNonSemanticDITy[Idx];
691 }
else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
693 }
else if (OpCode == SPIRV::OpEntryPoint) {
695 }
else if (TII->isAliasingInstr(
MI)) {
697 }
else if (TII->isDecorationInstr(
MI)) {
699 collectFuncNames(
MI, &
F);
700 }
else if (TII->isConstantInstr(
MI)) {
704 }
else if (OpCode == SPIRV::OpFunction) {
705 collectFuncNames(
MI, &
F);
706 }
else if (OpCode == SPIRV::OpTypeForwardPointer) {
716void SPIRVModuleAnalysis::numberRegistersGlobally(
const Module &M) {
717 for (
const Function &
F : M) {
718 if (
F.isDeclaration())
720 MachineFunction *MF = MMI->getMachineFunction(
F);
722 for (MachineBasicBlock &
MBB : *MF) {
723 for (MachineInstr &
MI :
MBB) {
724 for (MachineOperand &
Op :
MI.operands()) {
728 if (
MAI.hasRegisterAlias(MF,
Reg))
730 MCRegister NewReg =
MAI.getNextIDRegister();
731 MAI.setRegisterAlias(MF,
Reg, NewReg);
733 if (
MI.getOpcode() != SPIRV::OpExtInst)
735 auto Set =
MI.getOperand(2).getImm();
736 auto [It,
Inserted] =
MAI.ExtInstSetMap.try_emplace(Set);
738 It->second =
MAI.getNextIDRegister();
746 SPIRV::OperandCategory::OperandCategory Category, uint32_t i,
748 addRequirements(getSymbolicOperandRequirements(Category, i, ST, *
this));
751void SPIRV::RequirementHandler::recursiveAddCapabilities(
753 for (
const auto &Cap : ToPrune) {
757 recursiveAddCapabilities(ImplicitDecls);
762 for (
const auto &Cap : ToAdd) {
763 bool IsNewlyInserted = AllCaps.insert(Cap).second;
764 if (!IsNewlyInserted)
768 recursiveAddCapabilities(ImplicitDecls);
769 MinimalCaps.push_back(Cap);
774 const SPIRV::Requirements &Req) {
778 if (Req.
Cap.has_value())
779 addCapabilities({Req.
Cap.value()});
781 addExtensions(Req.
Exts);
784 if (!MaxVersion.empty() && Req.
MinVer > MaxVersion) {
786 <<
" and <= " << MaxVersion <<
"\n");
790 if (MinVersion.empty() || Req.
MinVer > MinVersion)
795 if (!MinVersion.empty() && Req.
MaxVer < MinVersion) {
797 <<
" and >= " << MinVersion <<
"\n");
801 if (MaxVersion.empty() || Req.
MaxVer < MaxVersion)
807 const SPIRVSubtarget &ST)
const {
809 bool IsSatisfiable =
true;
810 auto TargetVer =
ST.getSPIRVVersion();
812 if (!MaxVersion.empty() && !TargetVer.empty() && MaxVersion < TargetVer) {
814 dbgs() <<
"Target SPIR-V version too high for required features\n"
815 <<
"Required max version: " << MaxVersion <<
" target version "
816 << TargetVer <<
"\n");
817 IsSatisfiable =
false;
820 if (!MinVersion.empty() && !TargetVer.empty() && MinVersion > TargetVer) {
821 LLVM_DEBUG(
dbgs() <<
"Target SPIR-V version too low for required features\n"
822 <<
"Required min version: " << MinVersion
823 <<
" target version " << TargetVer <<
"\n");
824 IsSatisfiable =
false;
827 if (!MinVersion.empty() && !MaxVersion.empty() && MinVersion > MaxVersion) {
830 <<
"Version is too low for some features and too high for others.\n"
831 <<
"Required SPIR-V min version: " << MinVersion
832 <<
" required SPIR-V max version " << MaxVersion <<
"\n");
833 IsSatisfiable =
false;
836 AvoidCapabilitiesSet AvoidCaps;
838 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
840 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
842 for (
auto Cap : MinimalCaps) {
843 if (AvailableCaps.contains(Cap) && !AvoidCaps.
S.
contains(Cap))
847 OperandCategory::CapabilityOperand, Cap)
849 IsSatisfiable =
false;
852 for (
auto Ext : AllExtensions) {
853 if (
ST.canUseExtension(Ext))
857 OperandCategory::ExtensionOperand, Ext)
859 IsSatisfiable =
false;
868 for (
const auto Cap : ToAdd)
869 if (AvailableCaps.insert(Cap).second)
871 SPIRV::OperandCategory::CapabilityOperand, Cap));
875 const Capability::Capability
ToRemove,
876 const Capability::Capability IfPresent) {
877 if (AllCaps.contains(IfPresent))
885 addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8,
888 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
890 Capability::GroupNonUniformVote,
891 Capability::GroupNonUniformArithmetic,
892 Capability::GroupNonUniformBallot,
893 Capability::GroupNonUniformClustered,
894 Capability::GroupNonUniformShuffle,
895 Capability::GroupNonUniformShuffleRelative,
896 Capability::GroupNonUniformQuad});
898 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
900 Capability::DotProductInput4x8Bit,
901 Capability::DotProductInput4x8BitPacked,
902 Capability::DemoteToHelperInvocation});
905 for (
auto Extension :
ST.getAllAvailableExtensions()) {
911 if (!
ST.isShader()) {
912 initAvailableCapabilitiesForOpenCL(ST);
917 initAvailableCapabilitiesForVulkan(ST);
924void RequirementHandler::initAvailableCapabilitiesForOpenCL(
925 const SPIRVSubtarget &ST) {
928 Capability::Kernel, Capability::Vector16,
929 Capability::Groups, Capability::GenericPointer,
930 Capability::StorageImageWriteWithoutFormat,
931 Capability::StorageImageReadWithoutFormat});
932 if (
ST.hasOpenCLFullProfile())
934 if (
ST.hasOpenCLImageSupport()) {
936 Capability::Image1D, Capability::SampledBuffer,
937 Capability::ImageBuffer});
938 if (
ST.isAtLeastOpenCLVer(VersionTuple(2, 0)))
941 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) &&
942 ST.isAtLeastOpenCLVer(VersionTuple(2, 2)))
944 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 4)))
945 addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
946 Capability::SignedZeroInfNanPreserve,
947 Capability::RoundingModeRTE,
948 Capability::RoundingModeRTZ});
955void RequirementHandler::initAvailableCapabilitiesForVulkan(
956 const SPIRVSubtarget &ST) {
959 addAvailableCaps({Capability::Int64, Capability::Float16, Capability::Float64,
960 Capability::GroupNonUniform, Capability::Image1D,
961 Capability::SampledBuffer, Capability::ImageBuffer,
962 Capability::UniformBufferArrayDynamicIndexing,
963 Capability::SampledImageArrayDynamicIndexing,
964 Capability::StorageBufferArrayDynamicIndexing,
965 Capability::StorageImageArrayDynamicIndexing,
966 Capability::DerivativeControl, Capability::MinLod,
967 Capability::ImageGatherExtended, Capability::Addresses,
968 Capability::VulkanMemoryModelKHR});
971 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
973 {Capability::ShaderNonUniformEXT, Capability::RuntimeDescriptorArrayEXT,
974 Capability::InputAttachmentArrayDynamicIndexingEXT,
975 Capability::UniformTexelBufferArrayDynamicIndexingEXT,
976 Capability::StorageTexelBufferArrayDynamicIndexingEXT,
977 Capability::UniformBufferArrayNonUniformIndexingEXT,
978 Capability::SampledImageArrayNonUniformIndexingEXT,
979 Capability::StorageBufferArrayNonUniformIndexingEXT,
980 Capability::StorageImageArrayNonUniformIndexingEXT,
981 Capability::InputAttachmentArrayNonUniformIndexingEXT,
982 Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
983 Capability::StorageTexelBufferArrayNonUniformIndexingEXT});
987 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
989 Capability::StorageImageReadWithoutFormat});
997static void addOpDecorateReqs(
const MachineInstr &
MI,
unsigned DecIndex,
1000 int64_t DecOp =
MI.getOperand(DecIndex).getImm();
1001 auto Dec =
static_cast<SPIRV::Decoration::Decoration
>(DecOp);
1003 SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
1005 if (Dec == SPIRV::Decoration::BuiltIn) {
1006 int64_t BuiltInOp =
MI.getOperand(DecIndex + 1).getImm();
1007 auto BuiltIn =
static_cast<SPIRV::BuiltIn::BuiltIn
>(BuiltInOp);
1009 SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
1010 }
else if (Dec == SPIRV::Decoration::LinkageAttributes) {
1011 int64_t LinkageOp =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
1012 SPIRV::LinkageType::LinkageType LnkType =
1013 static_cast<SPIRV::LinkageType::LinkageType
>(LinkageOp);
1014 if (LnkType == SPIRV::LinkageType::LinkOnceODR)
1015 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_linkonce_odr);
1016 }
else if (Dec == SPIRV::Decoration::CacheControlLoadINTEL ||
1017 Dec == SPIRV::Decoration::CacheControlStoreINTEL) {
1018 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_cache_controls);
1019 }
else if (Dec == SPIRV::Decoration::HostAccessINTEL) {
1020 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_global_variable_host_access);
1021 }
else if (Dec == SPIRV::Decoration::InitModeINTEL ||
1022 Dec == SPIRV::Decoration::ImplementInRegisterMapINTEL) {
1024 SPIRV::Extension::SPV_INTEL_global_variable_fpga_decorations);
1025 }
else if (Dec == SPIRV::Decoration::NonUniformEXT) {
1027 }
else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
1029 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_fp_max_error);
1030 }
else if (Dec == SPIRV::Decoration::FPFastMathMode) {
1031 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
1033 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_float_controls2);
1042 assert(
MI.getNumOperands() >= 8 &&
"Insufficient operands for OpTypeImage");
1045 int64_t ImgFormatOp =
MI.getOperand(7).getImm();
1046 auto ImgFormat =
static_cast<SPIRV::ImageFormat::ImageFormat
>(ImgFormatOp);
1050 bool IsArrayed =
MI.getOperand(4).getImm() == 1;
1051 bool IsMultisampled =
MI.getOperand(5).getImm() == 1;
1052 bool NoSampler =
MI.getOperand(6).getImm() == 2;
1055 switch (
MI.getOperand(2).getImm()) {
1056 case SPIRV::Dim::DIM_1D:
1058 : SPIRV::Capability::Sampled1D);
1060 case SPIRV::Dim::DIM_2D:
1061 if (IsMultisampled && NoSampler)
1064 case SPIRV::Dim::DIM_Cube:
1068 : SPIRV::Capability::SampledCubeArray);
1070 case SPIRV::Dim::DIM_Rect:
1072 : SPIRV::Capability::SampledRect);
1074 case SPIRV::Dim::DIM_Buffer:
1076 : SPIRV::Capability::SampledBuffer);
1078 case SPIRV::Dim::DIM_SubpassData:
1084 if (!
ST.isShader()) {
1085 if (
MI.getNumOperands() > 8 &&
1086 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
1095 TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
1101#define ATOM_FLT_REQ_EXT_MSG(ExtName) \
1102 "The atomic float instruction requires the following SPIR-V " \
1103 "extension: SPV_EXT_shader_atomic_float" ExtName
1104static void AddAtomicVectorFloatRequirements(
const MachineInstr &
MI,
1108 MI.getMF()->getRegInfo().getVRegDef(
MI.getOperand(1).getReg());
1111 if (Rank != 2 && Rank != 4)
1113 "must be a 2-component or 4 component vector");
1118 if (EltTypeDef->
getOpcode() != SPIRV::OpTypeFloat ||
1121 "The element type for the result type of an atomic vector float "
1122 "instruction must be a 16-bit floating-point scalar");
1124 if (isBFloat16Type(EltTypeDef))
1126 "The element type for the result type of an atomic vector float "
1127 "instruction cannot be a bfloat16 scalar");
1128 if (!
ST.canUseExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector))
1130 "The atomic float16 vector instruction requires the following SPIR-V "
1131 "extension: SPV_NV_shader_atomic_fp16_vector");
1133 Reqs.
addExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector);
1134 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16VectorNV);
1141 "Expect register operand in atomic float instruction");
1142 Register TypeReg =
MI.getOperand(1).getReg();
1145 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
1146 return AddAtomicVectorFloatRequirements(
MI, Reqs, ST);
1148 if (TypeDef->
getOpcode() != SPIRV::OpTypeFloat)
1150 "floating-point type scalar");
1153 unsigned Op =
MI.getOpcode();
1154 if (
Op == SPIRV::OpAtomicFAddEXT) {
1155 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add))
1157 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
1160 if (isBFloat16Type(TypeDef)) {
1161 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1163 "The atomic bfloat16 instruction requires the following SPIR-V "
1164 "extension: SPV_INTEL_16bit_atomics",
1166 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1167 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16AddINTEL);
1169 if (!
ST.canUseExtension(
1170 SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
1172 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
1184 "Unexpected floating-point type width in atomic float instruction");
1187 if (!
ST.canUseExtension(
1188 SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max))
1190 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
1193 if (isBFloat16Type(TypeDef)) {
1194 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1196 "The atomic bfloat16 instruction requires the following SPIR-V "
1197 "extension: SPV_INTEL_16bit_atomics",
1199 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1200 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16MinMaxINTEL);
1202 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
1206 Reqs.
addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
1209 Reqs.
addCapability(SPIRV::Capability::AtomicFloat64MinMaxEXT);
1213 "Unexpected floating-point type width in atomic float instruction");
1219 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1223 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
1227 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1231 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
1235 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1239 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
1243 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1247 return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
1251 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1255 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
1258bool isCombinedImageSampler(
MachineInstr *SampledImageInst) {
1259 if (SampledImageInst->
getOpcode() != SPIRV::OpTypeSampledImage)
1265 return isSampledImage(ImageInst);
1270 if (
MI.getOpcode() != SPIRV::OpDecorate)
1274 if (Dec == SPIRV::Decoration::NonUniformEXT)
1292 if (
StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
1293 StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
1294 StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
1299 hasNonUniformDecoration(
Instr.getOperand(0).getReg(), MRI);
1301 auto FirstIndexReg =
Instr.getOperand(3).getReg();
1302 bool FirstIndexIsConstant =
1305 if (
StorageClass == SPIRV::StorageClass::StorageClass::StorageBuffer) {
1308 SPIRV::Capability::StorageBufferArrayNonUniformIndexingEXT);
1309 else if (!FirstIndexIsConstant)
1311 SPIRV::Capability::StorageBufferArrayDynamicIndexing);
1317 if (PointeeType->
getOpcode() != SPIRV::OpTypeImage &&
1318 PointeeType->
getOpcode() != SPIRV::OpTypeSampledImage &&
1319 PointeeType->
getOpcode() != SPIRV::OpTypeSampler) {
1323 if (isUniformTexelBuffer(PointeeType)) {
1326 SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1327 else if (!FirstIndexIsConstant)
1329 SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
1330 }
else if (isInputAttachment(PointeeType)) {
1333 SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1334 else if (!FirstIndexIsConstant)
1336 SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
1337 }
else if (isStorageTexelBuffer(PointeeType)) {
1340 SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1341 else if (!FirstIndexIsConstant)
1343 SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
1344 }
else if (isSampledImage(PointeeType) ||
1345 isCombinedImageSampler(PointeeType) ||
1346 PointeeType->
getOpcode() == SPIRV::OpTypeSampler) {
1349 SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1350 else if (!FirstIndexIsConstant)
1352 SPIRV::Capability::SampledImageArrayDynamicIndexing);
1353 }
else if (isStorageImage(PointeeType)) {
1356 SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1357 else if (!FirstIndexIsConstant)
1359 SPIRV::Capability::StorageImageArrayDynamicIndexing);
1363static bool isImageTypeWithUnknownFormat(
SPIRVTypeInst TypeInst) {
1364 if (TypeInst->
getOpcode() != SPIRV::OpTypeImage)
1373 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product))
1374 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_integer_dot_product);
1378 assert(
MI.getOperand(2).isReg() &&
"Unexpected operand in dot");
1382 assert(
Input->getOperand(1).isReg() &&
"Unexpected operand in dot input");
1386 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1388 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8BitPacked);
1389 }
else if (TypeDef->
getOpcode() == SPIRV::OpTypeVector) {
1395 "Dot operand of 8-bit integer type requires 4 components");
1396 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8Bit);
1411 unsigned AddrSpace = ASOp.
getImm();
1412 if (AddrSpace != SPIRV::StorageClass::UniformConstant) {
1413 if (!
ST.canUseExtension(
1415 SPV_EXT_relaxed_printf_string_address_space)) {
1417 "required because printf uses a format string not "
1418 "in constant address space.",
1422 SPIRV::Extension::SPV_EXT_relaxed_printf_string_address_space);
1431 if (
MI.getNumOperands() <=
OpIdx)
1435 if (Mask & (1U <<
I))
1444 unsigned Op =
MI.getOpcode();
1446 case SPIRV::OpMemoryModel: {
1447 int64_t Addr =
MI.getOperand(0).getImm();
1450 int64_t Mem =
MI.getOperand(1).getImm();
1455 case SPIRV::OpEntryPoint: {
1456 int64_t
Exe =
MI.getOperand(0).getImm();
1461 case SPIRV::OpExecutionMode:
1462 case SPIRV::OpExecutionModeId: {
1463 int64_t
Exe =
MI.getOperand(1).getImm();
1468 case SPIRV::OpTypeMatrix:
1471 case SPIRV::OpTypeInt: {
1472 unsigned BitWidth =
MI.getOperand(1).getImm();
1480 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1484 if (!
ST.canUseExtension(
1485 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers))
1487 "OpTypeInt type with a width other than 8, 16, 32 or 64 bits "
1488 "requires the following SPIR-V extension: "
1489 "SPV_ALTERA_arbitrary_precision_integers");
1491 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
1492 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
1496 case SPIRV::OpDot: {
1499 if (isBFloat16Type(TypeDef))
1500 Reqs.
addCapability(SPIRV::Capability::BFloat16DotProductKHR);
1503 case SPIRV::OpTypeFloat: {
1504 unsigned BitWidth =
MI.getOperand(1).getImm();
1508 if (isBFloat16Type(&
MI)) {
1509 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bfloat16))
1511 "following SPIR-V extension: SPV_KHR_bfloat16",
1521 case SPIRV::OpTypeVector: {
1522 unsigned NumComponents =
MI.getOperand(2).getImm();
1523 if (NumComponents == 8 || NumComponents == 16)
1529 if (ElemTypeDef->
getOpcode() == SPIRV::OpTypePointer &&
1530 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
1531 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter);
1532 Reqs.
addCapability(SPIRV::Capability::MaskedGatherScatterINTEL);
1536 case SPIRV::OpTypePointer: {
1537 auto SC =
MI.getOperand(1).getImm();
1548 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1553 case SPIRV::OpExtInst: {
1554 if (
MI.getOperand(2).getImm() ==
1555 static_cast<int64_t
>(
1556 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1557 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1560 if (
MI.getOperand(3).getImm() ==
1561 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1562 addPrintfRequirements(
MI, Reqs, ST);
1569 case SPIRV::OpAliasDomainDeclINTEL:
1570 case SPIRV::OpAliasScopeDeclINTEL:
1571 case SPIRV::OpAliasScopeListDeclINTEL: {
1572 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1573 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1576 case SPIRV::OpBitReverse:
1577 case SPIRV::OpBitFieldInsert:
1578 case SPIRV::OpBitFieldSExtract:
1579 case SPIRV::OpBitFieldUExtract:
1580 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1584 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1587 case SPIRV::OpTypeRuntimeArray:
1590 case SPIRV::OpTypeOpaque:
1591 case SPIRV::OpTypeEvent:
1594 case SPIRV::OpTypePipe:
1595 case SPIRV::OpTypeReserveId:
1598 case SPIRV::OpTypeDeviceEvent:
1599 case SPIRV::OpTypeQueue:
1600 case SPIRV::OpBuildNDRange:
1603 case SPIRV::OpDecorate:
1604 case SPIRV::OpDecorateId:
1605 case SPIRV::OpDecorateString:
1606 addOpDecorateReqs(
MI, 1, Reqs, ST);
1608 case SPIRV::OpMemberDecorate:
1609 case SPIRV::OpMemberDecorateString:
1610 addOpDecorateReqs(
MI, 2, Reqs, ST);
1612 case SPIRV::OpInBoundsPtrAccessChain:
1615 case SPIRV::OpConstantSampler:
1618 case SPIRV::OpInBoundsAccessChain:
1619 case SPIRV::OpAccessChain:
1620 addOpAccessChainReqs(
MI, Reqs, ST);
1622 case SPIRV::OpTypeImage:
1623 addOpTypeImageReqs(
MI, Reqs, ST);
1625 case SPIRV::OpTypeSampler:
1626 if (!
ST.isShader()) {
1630 case SPIRV::OpTypeForwardPointer:
1634 case SPIRV::OpAtomicFlagTestAndSet:
1635 case SPIRV::OpAtomicLoad:
1636 case SPIRV::OpAtomicStore:
1637 case SPIRV::OpAtomicExchange:
1638 case SPIRV::OpAtomicCompareExchange:
1639 case SPIRV::OpAtomicIIncrement:
1640 case SPIRV::OpAtomicIDecrement:
1641 case SPIRV::OpAtomicIAdd:
1642 case SPIRV::OpAtomicISub:
1643 case SPIRV::OpAtomicUMin:
1644 case SPIRV::OpAtomicUMax:
1645 case SPIRV::OpAtomicSMin:
1646 case SPIRV::OpAtomicSMax:
1647 case SPIRV::OpAtomicAnd:
1648 case SPIRV::OpAtomicOr:
1649 case SPIRV::OpAtomicXor: {
1652 if (
Op == SPIRV::OpAtomicStore) {
1655 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1661 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1666 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1668 "16-bit integer atomic operations require the following SPIR-V "
1669 "extension: SPV_INTEL_16bit_atomics",
1671 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1673 case SPIRV::OpAtomicLoad:
1674 case SPIRV::OpAtomicStore:
1675 case SPIRV::OpAtomicExchange:
1676 case SPIRV::OpAtomicCompareExchange:
1677 case SPIRV::OpAtomicCompareExchangeWeak:
1679 SPIRV::Capability::AtomicInt16CompareExchangeINTEL);
1686 }
else if (isBFloat16Type(TypeDef)) {
1687 if (
is_contained({SPIRV::OpAtomicLoad, SPIRV::OpAtomicStore,
1688 SPIRV::OpAtomicExchange},
1690 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1692 "The atomic bfloat16 instruction requires the following SPIR-V "
1693 "extension: SPV_INTEL_16bit_atomics",
1695 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1696 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16LoadStoreINTEL);
1701 case SPIRV::OpGroupNonUniformIAdd:
1702 case SPIRV::OpGroupNonUniformFAdd:
1703 case SPIRV::OpGroupNonUniformIMul:
1704 case SPIRV::OpGroupNonUniformFMul:
1705 case SPIRV::OpGroupNonUniformSMin:
1706 case SPIRV::OpGroupNonUniformUMin:
1707 case SPIRV::OpGroupNonUniformFMin:
1708 case SPIRV::OpGroupNonUniformSMax:
1709 case SPIRV::OpGroupNonUniformUMax:
1710 case SPIRV::OpGroupNonUniformFMax:
1711 case SPIRV::OpGroupNonUniformBitwiseAnd:
1712 case SPIRV::OpGroupNonUniformBitwiseOr:
1713 case SPIRV::OpGroupNonUniformBitwiseXor:
1714 case SPIRV::OpGroupNonUniformLogicalAnd:
1715 case SPIRV::OpGroupNonUniformLogicalOr:
1716 case SPIRV::OpGroupNonUniformLogicalXor: {
1718 int64_t GroupOp =
MI.getOperand(3).getImm();
1720 case SPIRV::GroupOperation::Reduce:
1721 case SPIRV::GroupOperation::InclusiveScan:
1722 case SPIRV::GroupOperation::ExclusiveScan:
1723 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1725 case SPIRV::GroupOperation::ClusteredReduce:
1726 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1728 case SPIRV::GroupOperation::PartitionedReduceNV:
1729 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1730 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1731 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1736 case SPIRV::OpGroupNonUniformQuadSwap:
1739 case SPIRV::OpImageQueryFormat: {
1740 Register ResultReg =
MI.getOperand(0).getReg();
1742 static const unsigned CompareOps[] = {
1743 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1744 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1745 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1746 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1747 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1749 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1750 if (ImmVal == 4323 || ImmVal == 4324) {
1751 if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1752 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1755 "SPV_EXT_image_raw10_raw12 extension");
1760 unsigned Opc = UseInst.getOpcode();
1762 if (
Opc == SPIRV::OpSwitch) {
1765 CheckAndAddExtension(
Op.getImm());
1767 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1770 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1773 CheckAndAddExtension(ImmVal);
1781 case SPIRV::OpGroupNonUniformShuffle:
1782 case SPIRV::OpGroupNonUniformShuffleXor:
1783 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1785 case SPIRV::OpGroupNonUniformShuffleUp:
1786 case SPIRV::OpGroupNonUniformShuffleDown:
1787 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1789 case SPIRV::OpGroupAll:
1790 case SPIRV::OpGroupAny:
1791 case SPIRV::OpGroupBroadcast:
1792 case SPIRV::OpGroupIAdd:
1793 case SPIRV::OpGroupFAdd:
1794 case SPIRV::OpGroupFMin:
1795 case SPIRV::OpGroupUMin:
1796 case SPIRV::OpGroupSMin:
1797 case SPIRV::OpGroupFMax:
1798 case SPIRV::OpGroupUMax:
1799 case SPIRV::OpGroupSMax:
1802 case SPIRV::OpGroupNonUniformElect:
1805 case SPIRV::OpGroupNonUniformAll:
1806 case SPIRV::OpGroupNonUniformAny:
1807 case SPIRV::OpGroupNonUniformAllEqual:
1810 case SPIRV::OpGroupNonUniformBroadcast:
1811 case SPIRV::OpGroupNonUniformBroadcastFirst:
1812 case SPIRV::OpGroupNonUniformBallot:
1813 case SPIRV::OpGroupNonUniformInverseBallot:
1814 case SPIRV::OpGroupNonUniformBallotBitExtract:
1815 case SPIRV::OpGroupNonUniformBallotBitCount:
1816 case SPIRV::OpGroupNonUniformBallotFindLSB:
1817 case SPIRV::OpGroupNonUniformBallotFindMSB:
1818 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1820 case SPIRV::OpSubgroupShuffleINTEL:
1821 case SPIRV::OpSubgroupShuffleDownINTEL:
1822 case SPIRV::OpSubgroupShuffleUpINTEL:
1823 case SPIRV::OpSubgroupShuffleXorINTEL:
1824 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1825 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1826 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1829 case SPIRV::OpSubgroupBlockReadINTEL:
1830 case SPIRV::OpSubgroupBlockWriteINTEL:
1831 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1832 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1833 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1836 case SPIRV::OpSubgroupImageBlockReadINTEL:
1837 case SPIRV::OpSubgroupImageBlockWriteINTEL:
1838 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1839 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1840 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
1843 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
1844 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
1845 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
1846 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
1847 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
1850 case SPIRV::OpAssumeTrueKHR:
1851 case SPIRV::OpExpectKHR:
1852 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
1853 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
1857 case SPIRV::OpFmaKHR:
1858 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
1863 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
1864 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
1865 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
1866 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
1867 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
1870 case SPIRV::OpConstantFunctionPointerINTEL:
1871 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1872 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1873 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1876 case SPIRV::OpGroupNonUniformRotateKHR:
1877 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
1879 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
1881 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
1882 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
1885 case SPIRV::OpFixedCosALTERA:
1886 case SPIRV::OpFixedSinALTERA:
1887 case SPIRV::OpFixedCosPiALTERA:
1888 case SPIRV::OpFixedSinPiALTERA:
1889 case SPIRV::OpFixedExpALTERA:
1890 case SPIRV::OpFixedLogALTERA:
1891 case SPIRV::OpFixedRecipALTERA:
1892 case SPIRV::OpFixedSqrtALTERA:
1893 case SPIRV::OpFixedSinCosALTERA:
1894 case SPIRV::OpFixedSinCosPiALTERA:
1895 case SPIRV::OpFixedRsqrtALTERA:
1896 if (!
ST.canUseExtension(
1897 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
1899 "following SPIR-V extension: "
1900 "SPV_ALTERA_arbitrary_precision_fixed_point",
1903 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
1904 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
1906 case SPIRV::OpGroupIMulKHR:
1907 case SPIRV::OpGroupFMulKHR:
1908 case SPIRV::OpGroupBitwiseAndKHR:
1909 case SPIRV::OpGroupBitwiseOrKHR:
1910 case SPIRV::OpGroupBitwiseXorKHR:
1911 case SPIRV::OpGroupLogicalAndKHR:
1912 case SPIRV::OpGroupLogicalOrKHR:
1913 case SPIRV::OpGroupLogicalXorKHR:
1914 if (
ST.canUseExtension(
1915 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
1916 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
1917 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
1920 case SPIRV::OpReadClockKHR:
1921 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
1923 "following SPIR-V extension: SPV_KHR_shader_clock",
1925 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
1928 case SPIRV::OpFunctionPointerCallINTEL:
1929 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1930 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1931 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1934 case SPIRV::OpAtomicFAddEXT:
1935 case SPIRV::OpAtomicFMinEXT:
1936 case SPIRV::OpAtomicFMaxEXT:
1937 AddAtomicFloatRequirements(
MI, Reqs, ST);
1939 case SPIRV::OpConvertBF16ToFINTEL:
1940 case SPIRV::OpConvertFToBF16INTEL:
1941 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
1942 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
1943 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
1946 case SPIRV::OpRoundFToTF32INTEL:
1947 if (
ST.canUseExtension(
1948 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
1949 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
1950 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
1953 case SPIRV::OpVariableLengthArrayINTEL:
1954 case SPIRV::OpSaveMemoryINTEL:
1955 case SPIRV::OpRestoreMemoryINTEL:
1956 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
1957 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
1958 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
1961 case SPIRV::OpAsmTargetINTEL:
1962 case SPIRV::OpAsmINTEL:
1963 case SPIRV::OpAsmCallINTEL:
1964 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
1965 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
1969 case SPIRV::OpTypeCooperativeMatrixKHR: {
1970 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1972 "OpTypeCooperativeMatrixKHR type requires the "
1973 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
1975 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1976 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1979 if (isBFloat16Type(TypeDef))
1980 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
1983 case SPIRV::OpArithmeticFenceEXT:
1984 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
1986 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
1988 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
1991 case SPIRV::OpControlBarrierArriveINTEL:
1992 case SPIRV::OpControlBarrierWaitINTEL:
1993 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
1994 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
1998 case SPIRV::OpCooperativeMatrixMulAddKHR: {
1999 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2001 "following SPIR-V extension: "
2002 "SPV_KHR_cooperative_matrix",
2004 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2005 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2006 constexpr unsigned MulAddMaxSize = 6;
2007 if (
MI.getNumOperands() != MulAddMaxSize)
2009 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
2011 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
2012 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2014 "require the following SPIR-V extension: "
2015 "SPV_INTEL_joint_matrix",
2017 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2019 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
2022 MatrixAAndBBFloat16ComponentsINTEL ||
2024 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
2026 MatrixResultBFloat16ComponentsINTEL) {
2027 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2029 "require the following SPIR-V extension: "
2030 "SPV_INTEL_joint_matrix",
2032 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2034 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
2038 case SPIRV::OpCooperativeMatrixLoadKHR:
2039 case SPIRV::OpCooperativeMatrixStoreKHR:
2040 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2041 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2042 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
2043 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2045 "following SPIR-V extension: "
2046 "SPV_KHR_cooperative_matrix",
2048 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2049 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2053 std::unordered_map<unsigned, unsigned> LayoutToInstMap = {
2054 {SPIRV::OpCooperativeMatrixLoadKHR, 3},
2055 {SPIRV::OpCooperativeMatrixStoreKHR, 2},
2056 {SPIRV::OpCooperativeMatrixLoadCheckedINTEL, 5},
2057 {SPIRV::OpCooperativeMatrixStoreCheckedINTEL, 4},
2058 {SPIRV::OpCooperativeMatrixPrefetchINTEL, 4}};
2060 const unsigned LayoutNum = LayoutToInstMap[
Op];
2061 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
2064 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
2067 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
2068 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2070 "extension: SPV_INTEL_joint_matrix",
2072 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2073 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2078 if (
Op == SPIRV::OpCooperativeMatrixLoadKHR ||
2079 Op == SPIRV::OpCooperativeMatrixStoreKHR)
2082 std::string InstName;
2084 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2085 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2087 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2088 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2090 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2091 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2095 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2096 const std::string ErrorMsg =
2097 InstName +
" instruction requires the "
2098 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2101 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2102 if (
Op == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2103 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2107 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2110 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2111 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2113 "instructions require the following SPIR-V extension: "
2114 "SPV_INTEL_joint_matrix",
2116 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2118 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2120 case SPIRV::OpReadPipeBlockingALTERA:
2121 case SPIRV::OpWritePipeBlockingALTERA:
2122 if (
ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2123 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2127 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2128 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2130 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2132 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2134 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2136 case SPIRV::OpConvertHandleToImageINTEL:
2137 case SPIRV::OpConvertHandleToSamplerINTEL:
2138 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2139 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2141 "instructions require the following SPIR-V extension: "
2142 "SPV_INTEL_bindless_images",
2145 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2147 if (
Op == SPIRV::OpConvertHandleToImageINTEL &&
2148 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2150 "OpConvertHandleToImageINTEL",
2152 }
else if (
Op == SPIRV::OpConvertHandleToSamplerINTEL &&
2153 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2155 "OpConvertHandleToSamplerINTEL",
2157 }
else if (
Op == SPIRV::OpConvertHandleToSampledImageINTEL &&
2158 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2160 "OpConvertHandleToSampledImageINTEL",
2165 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2166 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2168 "Parameter value must be a 32-bit scalar in case of "
2169 "Physical32 addressing model or a 64-bit scalar in case of "
2170 "Physical64 addressing model",
2173 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2177 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2178 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2179 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2180 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2181 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2182 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2184 "Prefetch/Store]INTEL instructions require the "
2185 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2187 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2188 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2190 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2191 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2194 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2195 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2200 case SPIRV::OpKill: {
2203 case SPIRV::OpDemoteToHelperInvocation:
2204 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2206 if (
ST.canUseExtension(
2207 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2210 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2215 case SPIRV::OpSUDot:
2216 case SPIRV::OpSDotAccSat:
2217 case SPIRV::OpUDotAccSat:
2218 case SPIRV::OpSUDotAccSat:
2219 AddDotProductRequirements(
MI, Reqs, ST);
2221 case SPIRV::OpImageSampleImplicitLod:
2223 addImageOperandReqs(
MI, Reqs, ST, 4);
2225 case SPIRV::OpImageSampleExplicitLod:
2226 addImageOperandReqs(
MI, Reqs, ST, 4);
2228 case SPIRV::OpImageSampleDrefImplicitLod:
2230 addImageOperandReqs(
MI, Reqs, ST, 5);
2232 case SPIRV::OpImageSampleDrefExplicitLod:
2234 addImageOperandReqs(
MI, Reqs, ST, 5);
2236 case SPIRV::OpImageFetch:
2238 addImageOperandReqs(
MI, Reqs, ST, 4);
2240 case SPIRV::OpImageDrefGather:
2241 case SPIRV::OpImageGather:
2243 addImageOperandReqs(
MI, Reqs, ST, 5);
2245 case SPIRV::OpImageRead: {
2246 Register ImageReg =
MI.getOperand(2).getReg();
2255 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2256 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2259 case SPIRV::OpImageWrite: {
2260 Register ImageReg =
MI.getOperand(0).getReg();
2269 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2270 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2273 case SPIRV::OpTypeStructContinuedINTEL:
2274 case SPIRV::OpConstantCompositeContinuedINTEL:
2275 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2276 case SPIRV::OpCompositeConstructContinuedINTEL: {
2277 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2279 "Continued instructions require the "
2280 "following SPIR-V extension: SPV_INTEL_long_composites",
2282 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2286 case SPIRV::OpArbitraryFloatEQALTERA:
2287 case SPIRV::OpArbitraryFloatGEALTERA:
2288 case SPIRV::OpArbitraryFloatGTALTERA:
2289 case SPIRV::OpArbitraryFloatLEALTERA:
2290 case SPIRV::OpArbitraryFloatLTALTERA:
2291 case SPIRV::OpArbitraryFloatCbrtALTERA:
2292 case SPIRV::OpArbitraryFloatCosALTERA:
2293 case SPIRV::OpArbitraryFloatCosPiALTERA:
2294 case SPIRV::OpArbitraryFloatExp10ALTERA:
2295 case SPIRV::OpArbitraryFloatExp2ALTERA:
2296 case SPIRV::OpArbitraryFloatExpALTERA:
2297 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2298 case SPIRV::OpArbitraryFloatHypotALTERA:
2299 case SPIRV::OpArbitraryFloatLog10ALTERA:
2300 case SPIRV::OpArbitraryFloatLog1pALTERA:
2301 case SPIRV::OpArbitraryFloatLog2ALTERA:
2302 case SPIRV::OpArbitraryFloatLogALTERA:
2303 case SPIRV::OpArbitraryFloatRecipALTERA:
2304 case SPIRV::OpArbitraryFloatSinCosALTERA:
2305 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2306 case SPIRV::OpArbitraryFloatSinALTERA:
2307 case SPIRV::OpArbitraryFloatSinPiALTERA:
2308 case SPIRV::OpArbitraryFloatSqrtALTERA:
2309 case SPIRV::OpArbitraryFloatACosALTERA:
2310 case SPIRV::OpArbitraryFloatACosPiALTERA:
2311 case SPIRV::OpArbitraryFloatAddALTERA:
2312 case SPIRV::OpArbitraryFloatASinALTERA:
2313 case SPIRV::OpArbitraryFloatASinPiALTERA:
2314 case SPIRV::OpArbitraryFloatATan2ALTERA:
2315 case SPIRV::OpArbitraryFloatATanALTERA:
2316 case SPIRV::OpArbitraryFloatATanPiALTERA:
2317 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2318 case SPIRV::OpArbitraryFloatCastALTERA:
2319 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2320 case SPIRV::OpArbitraryFloatDivALTERA:
2321 case SPIRV::OpArbitraryFloatMulALTERA:
2322 case SPIRV::OpArbitraryFloatPowALTERA:
2323 case SPIRV::OpArbitraryFloatPowNALTERA:
2324 case SPIRV::OpArbitraryFloatPowRALTERA:
2325 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2326 case SPIRV::OpArbitraryFloatSubALTERA: {
2327 if (!
ST.canUseExtension(
2328 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2330 "Floating point instructions can't be translated correctly without "
2331 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2334 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2336 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2339 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2340 if (!
ST.canUseExtension(
2341 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2343 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2345 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2348 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2350 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2353 case SPIRV::OpBitwiseFunctionINTEL: {
2354 if (!
ST.canUseExtension(
2355 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2357 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2358 "extension: SPV_INTEL_ternary_bitwise_function",
2360 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2361 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2364 case SPIRV::OpCopyMemorySized: {
2369 case SPIRV::OpPredicatedLoadINTEL:
2370 case SPIRV::OpPredicatedStoreINTEL: {
2371 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2373 "OpPredicated[Load/Store]INTEL instructions require "
2374 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2376 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2380 case SPIRV::OpFAddS:
2381 case SPIRV::OpFSubS:
2382 case SPIRV::OpFMulS:
2383 case SPIRV::OpFDivS:
2384 case SPIRV::OpFRemS:
2386 case SPIRV::OpFNegate:
2387 case SPIRV::OpFAddV:
2388 case SPIRV::OpFSubV:
2389 case SPIRV::OpFMulV:
2390 case SPIRV::OpFDivV:
2391 case SPIRV::OpFRemV:
2392 case SPIRV::OpFNegateV: {
2395 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2397 if (isBFloat16Type(TypeDef)) {
2398 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2400 "Arithmetic instructions with bfloat16 arguments require the "
2401 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2403 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2404 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2408 case SPIRV::OpOrdered:
2409 case SPIRV::OpUnordered:
2410 case SPIRV::OpFOrdEqual:
2411 case SPIRV::OpFOrdNotEqual:
2412 case SPIRV::OpFOrdLessThan:
2413 case SPIRV::OpFOrdLessThanEqual:
2414 case SPIRV::OpFOrdGreaterThan:
2415 case SPIRV::OpFOrdGreaterThanEqual:
2416 case SPIRV::OpFUnordEqual:
2417 case SPIRV::OpFUnordNotEqual:
2418 case SPIRV::OpFUnordLessThan:
2419 case SPIRV::OpFUnordLessThanEqual:
2420 case SPIRV::OpFUnordGreaterThan:
2421 case SPIRV::OpFUnordGreaterThanEqual: {
2425 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2427 if (isBFloat16Type(TypeDef)) {
2428 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2430 "Relational instructions with bfloat16 arguments require the "
2431 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2433 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2434 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2438 case SPIRV::OpDPdxCoarse:
2439 case SPIRV::OpDPdyCoarse:
2440 case SPIRV::OpDPdxFine:
2441 case SPIRV::OpDPdyFine: {
2445 case SPIRV::OpLoopControlINTEL: {
2446 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2447 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2459 SPIRV::Capability::Shader);
2471 addInstrRequirements(
MI, MAI, ST);
2474 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2476 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2477 RequireKHRFloatControls2 =
false,
2479 bool HasIntelFloatControls2 =
2480 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2481 bool HasKHRFloatControls2 =
2482 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2483 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2489 auto EM =
Const->getZExtValue();
2493 case SPIRV::ExecutionMode::DenormPreserve:
2494 case SPIRV::ExecutionMode::DenormFlushToZero:
2495 case SPIRV::ExecutionMode::RoundingModeRTE:
2496 case SPIRV::ExecutionMode::RoundingModeRTZ:
2497 RequireFloatControls = VerLower14;
2499 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2501 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2502 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2503 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2504 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2505 if (HasIntelFloatControls2) {
2506 RequireIntelFloatControls2 =
true;
2508 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2511 case SPIRV::ExecutionMode::FPFastMathDefault: {
2512 if (HasKHRFloatControls2) {
2513 RequireKHRFloatControls2 =
true;
2515 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2519 case SPIRV::ExecutionMode::ContractionOff:
2520 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2521 if (HasKHRFloatControls2) {
2522 RequireKHRFloatControls2 =
true;
2524 SPIRV::OperandCategory::ExecutionModeOperand,
2525 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2528 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2533 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2538 if (RequireFloatControls &&
2539 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2541 if (RequireIntelFloatControls2)
2543 if (RequireKHRFloatControls2)
2547 if (
F.isDeclaration())
2549 if (
F.getMetadata(
"reqd_work_group_size"))
2551 SPIRV::OperandCategory::ExecutionModeOperand,
2552 SPIRV::ExecutionMode::LocalSize, ST);
2553 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2555 SPIRV::OperandCategory::ExecutionModeOperand,
2556 SPIRV::ExecutionMode::LocalSize, ST);
2558 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2561 if (
F.getMetadata(
"work_group_size_hint"))
2563 SPIRV::OperandCategory::ExecutionModeOperand,
2564 SPIRV::ExecutionMode::LocalSizeHint, ST);
2565 if (
F.getMetadata(
"intel_reqd_sub_group_size"))
2567 SPIRV::OperandCategory::ExecutionModeOperand,
2568 SPIRV::ExecutionMode::SubgroupSize, ST);
2569 if (
F.getMetadata(
"max_work_group_size"))
2571 SPIRV::OperandCategory::ExecutionModeOperand,
2572 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2573 if (
F.getMetadata(
"vec_type_hint"))
2575 SPIRV::OperandCategory::ExecutionModeOperand,
2576 SPIRV::ExecutionMode::VecTypeHint, ST);
2578 if (
F.hasOptNone()) {
2579 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2582 }
else if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2592 unsigned Flags = SPIRV::FPFastMathMode::None;
2593 bool CanUseKHRFloatControls2 =
2594 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2596 Flags |= SPIRV::FPFastMathMode::NotNaN;
2598 Flags |= SPIRV::FPFastMathMode::NotInf;
2600 Flags |= SPIRV::FPFastMathMode::NSZ;
2602 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2604 Flags |= SPIRV::FPFastMathMode::AllowContract;
2606 if (CanUseKHRFloatControls2)
2614 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2615 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2616 SPIRV::FPFastMathMode::AllowTransform |
2617 SPIRV::FPFastMathMode::AllowReassoc |
2618 SPIRV::FPFastMathMode::AllowContract;
2620 Flags |= SPIRV::FPFastMathMode::Fast;
2623 if (CanUseKHRFloatControls2) {
2625 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2626 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2631 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2632 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2633 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2634 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2635 "AllowContract flags to be enabled as well.");
2646 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2649static void handleMIFlagDecoration(
2654 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2655 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2658 SPIRV::Decoration::NoSignedWrap, {});
2661 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2662 SPIRV::Decoration::NoUnsignedWrap, ST,
2666 SPIRV::Decoration::NoUnsignedWrap, {});
2671 TII.canUseFastMathFlags(
2672 I,
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) ||
2673 (
ST.isKernel() &&
I.getOpcode() == SPIRV::OpExtInst);
2677 unsigned FMFlags = getFastMathFlags(
I, ST);
2678 if (FMFlags == SPIRV::FPFastMathMode::None) {
2681 if (FPFastMathDefaultInfoVec.
empty())
2697 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2698 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2699 ?
I.getOperand(1).getReg()
2700 :
I.getOperand(2).getReg();
2708 if (Ty == Elem.Ty) {
2709 FMFlags = Elem.FastMathFlags;
2710 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2711 Elem.FPFastMathDefault;
2716 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2719 if (isFastMathModeAvailable(ST)) {
2720 Register DstReg =
I.getOperand(0).getReg();
2736 for (
auto &
MBB : *MF)
2737 for (
auto &
MI :
MBB)
2738 handleMIFlagDecoration(
MI, ST,
TII, MAI.
Reqs, GR,
2755 for (
auto &
MBB : *MF) {
2756 if (!
MBB.hasName() ||
MBB.empty())
2775 for (
auto &
MBB : *MF) {
2777 MI.setDesc(
TII.get(SPIRV::OpPhi));
2780 MI.insert(
MI.operands_begin() + 1,
2781 {MachineOperand::CreateReg(ResTypeReg, false)});
2800 SPIRV::FPFastMathMode::None);
2802 SPIRV::FPFastMathMode::None);
2804 SPIRV::FPFastMathMode::None);
2811 size_t BitWidth = Ty->getScalarSizeInBits();
2815 assert(Index >= 0 && Index < 3 &&
2816 "Expected FPFastMathDefaultInfo for half, float, or double");
2817 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2818 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2819 return FPFastMathDefaultInfoVec[Index];
2822static void collectFPFastMathDefaults(
const Module &M,
2825 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
2834 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2838 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2847 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
2849 "Expected 4 operands for FPFastMathDefault");
2860 Info.FastMathFlags = Flags;
2861 Info.FPFastMathDefault =
true;
2862 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
2864 "Expected no operands for ContractionOff");
2871 Info.ContractionOff =
true;
2873 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
2875 "Expected 1 operand for SignedZeroInfNanPreserve");
2876 unsigned TargetWidth =
2885 assert(Index >= 0 && Index < 3 &&
2886 "Expected FPFastMathDefaultInfo for half, float, or double");
2887 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2888 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2889 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
2900 SPIRVTargetMachine &TM =
2904 TII = ST->getInstrInfo();
2910 patchPhis(M, GR, *TII, MMI);
2912 addMBBNames(M, *TII, MMI, *ST,
MAI);
2913 collectFPFastMathDefaults(M,
MAI, *ST);
2914 addDecorations(M, *TII, MMI, *ST,
MAI, GR);
2916 collectReqs(M,
MAI, MMI, *ST);
2920 collectReqs(M,
MAI, MMI, *ST);
2921 collectDeclarations(M);
2924 numberRegistersGlobally(M);
2927 processOtherInstrs(M);
2931 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
2934 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
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