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::ImageQuery, Capability::ImageGatherExtended,
968 Capability::Addresses, 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:
1090 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_image_int64);
1094 if (!
ST.isShader()) {
1095 if (
MI.getNumOperands() > 8 &&
1096 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
1105 TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
1111#define ATOM_FLT_REQ_EXT_MSG(ExtName) \
1112 "The atomic float instruction requires the following SPIR-V " \
1113 "extension: SPV_EXT_shader_atomic_float" ExtName
1114static void AddAtomicVectorFloatRequirements(
const MachineInstr &
MI,
1118 MI.getMF()->getRegInfo().getVRegDef(
MI.getOperand(1).getReg());
1121 if (Rank != 2 && Rank != 4)
1123 "must be a 2-component or 4 component vector");
1128 if (EltTypeDef->
getOpcode() != SPIRV::OpTypeFloat ||
1131 "The element type for the result type of an atomic vector float "
1132 "instruction must be a 16-bit floating-point scalar");
1134 if (isBFloat16Type(EltTypeDef))
1136 "The element type for the result type of an atomic vector float "
1137 "instruction cannot be a bfloat16 scalar");
1138 if (!
ST.canUseExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector))
1140 "The atomic float16 vector instruction requires the following SPIR-V "
1141 "extension: SPV_NV_shader_atomic_fp16_vector");
1143 Reqs.
addExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector);
1144 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16VectorNV);
1151 "Expect register operand in atomic float instruction");
1152 Register TypeReg =
MI.getOperand(1).getReg();
1155 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
1156 return AddAtomicVectorFloatRequirements(
MI, Reqs, ST);
1158 if (TypeDef->
getOpcode() != SPIRV::OpTypeFloat)
1160 "floating-point type scalar");
1163 unsigned Op =
MI.getOpcode();
1164 if (
Op == SPIRV::OpAtomicFAddEXT) {
1165 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add))
1167 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
1170 if (isBFloat16Type(TypeDef)) {
1171 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1173 "The atomic bfloat16 instruction requires the following SPIR-V "
1174 "extension: SPV_INTEL_16bit_atomics",
1176 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1177 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16AddINTEL);
1179 if (!
ST.canUseExtension(
1180 SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
1182 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
1194 "Unexpected floating-point type width in atomic float instruction");
1197 if (!
ST.canUseExtension(
1198 SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max))
1200 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
1203 if (isBFloat16Type(TypeDef)) {
1204 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1206 "The atomic bfloat16 instruction requires the following SPIR-V "
1207 "extension: SPV_INTEL_16bit_atomics",
1209 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1210 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16MinMaxINTEL);
1212 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
1216 Reqs.
addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
1219 Reqs.
addCapability(SPIRV::Capability::AtomicFloat64MinMaxEXT);
1223 "Unexpected floating-point type width in atomic float instruction");
1229 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1233 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
1237 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1241 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
1245 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1249 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
1253 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1257 return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
1261 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1265 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
1268bool isCombinedImageSampler(
MachineInstr *SampledImageInst) {
1269 if (SampledImageInst->
getOpcode() != SPIRV::OpTypeSampledImage)
1275 return isSampledImage(ImageInst);
1280 if (
MI.getOpcode() != SPIRV::OpDecorate)
1284 if (Dec == SPIRV::Decoration::NonUniformEXT)
1302 if (
StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
1303 StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
1304 StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
1309 hasNonUniformDecoration(
Instr.getOperand(0).getReg(), MRI);
1311 auto FirstIndexReg =
Instr.getOperand(3).getReg();
1312 bool FirstIndexIsConstant =
1315 if (
StorageClass == SPIRV::StorageClass::StorageClass::StorageBuffer) {
1318 SPIRV::Capability::StorageBufferArrayNonUniformIndexingEXT);
1319 else if (!FirstIndexIsConstant)
1321 SPIRV::Capability::StorageBufferArrayDynamicIndexing);
1327 if (PointeeType->
getOpcode() != SPIRV::OpTypeImage &&
1328 PointeeType->
getOpcode() != SPIRV::OpTypeSampledImage &&
1329 PointeeType->
getOpcode() != SPIRV::OpTypeSampler) {
1333 if (isUniformTexelBuffer(PointeeType)) {
1336 SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1337 else if (!FirstIndexIsConstant)
1339 SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
1340 }
else if (isInputAttachment(PointeeType)) {
1343 SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1344 else if (!FirstIndexIsConstant)
1346 SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
1347 }
else if (isStorageTexelBuffer(PointeeType)) {
1350 SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1351 else if (!FirstIndexIsConstant)
1353 SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
1354 }
else if (isSampledImage(PointeeType) ||
1355 isCombinedImageSampler(PointeeType) ||
1356 PointeeType->
getOpcode() == SPIRV::OpTypeSampler) {
1359 SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1360 else if (!FirstIndexIsConstant)
1362 SPIRV::Capability::SampledImageArrayDynamicIndexing);
1363 }
else if (isStorageImage(PointeeType)) {
1366 SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1367 else if (!FirstIndexIsConstant)
1369 SPIRV::Capability::StorageImageArrayDynamicIndexing);
1373static bool isImageTypeWithUnknownFormat(
SPIRVTypeInst TypeInst) {
1374 if (TypeInst->
getOpcode() != SPIRV::OpTypeImage)
1383 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product))
1384 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_integer_dot_product);
1388 assert(
MI.getOperand(2).isReg() &&
"Unexpected operand in dot");
1392 assert(
Input->getOperand(1).isReg() &&
"Unexpected operand in dot input");
1396 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1398 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8BitPacked);
1399 }
else if (TypeDef->
getOpcode() == SPIRV::OpTypeVector) {
1405 "Dot operand of 8-bit integer type requires 4 components");
1406 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8Bit);
1421 unsigned AddrSpace = ASOp.
getImm();
1422 if (AddrSpace != SPIRV::StorageClass::UniformConstant) {
1423 if (!
ST.canUseExtension(
1425 SPV_EXT_relaxed_printf_string_address_space)) {
1427 "required because printf uses a format string not "
1428 "in constant address space.",
1432 SPIRV::Extension::SPV_EXT_relaxed_printf_string_address_space);
1441 if (
MI.getNumOperands() <=
OpIdx)
1445 if (Mask & (1U <<
I))
1454 unsigned Op =
MI.getOpcode();
1456 case SPIRV::OpMemoryModel: {
1457 int64_t Addr =
MI.getOperand(0).getImm();
1460 int64_t Mem =
MI.getOperand(1).getImm();
1465 case SPIRV::OpEntryPoint: {
1466 int64_t
Exe =
MI.getOperand(0).getImm();
1471 case SPIRV::OpExecutionMode:
1472 case SPIRV::OpExecutionModeId: {
1473 int64_t
Exe =
MI.getOperand(1).getImm();
1478 case SPIRV::OpTypeMatrix:
1481 case SPIRV::OpTypeInt: {
1482 unsigned BitWidth =
MI.getOperand(1).getImm();
1490 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1494 if (!
ST.canUseExtension(
1495 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers))
1497 "OpTypeInt type with a width other than 8, 16, 32 or 64 bits "
1498 "requires the following SPIR-V extension: "
1499 "SPV_ALTERA_arbitrary_precision_integers");
1501 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
1502 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
1506 case SPIRV::OpDot: {
1509 if (isBFloat16Type(TypeDef))
1510 Reqs.
addCapability(SPIRV::Capability::BFloat16DotProductKHR);
1513 case SPIRV::OpTypeFloat: {
1514 unsigned BitWidth =
MI.getOperand(1).getImm();
1518 if (isBFloat16Type(&
MI)) {
1519 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bfloat16))
1521 "following SPIR-V extension: SPV_KHR_bfloat16",
1531 case SPIRV::OpTypeVector: {
1532 unsigned NumComponents =
MI.getOperand(2).getImm();
1533 if (NumComponents == 8 || NumComponents == 16)
1539 if (ElemTypeDef->
getOpcode() == SPIRV::OpTypePointer &&
1540 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
1541 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter);
1542 Reqs.
addCapability(SPIRV::Capability::MaskedGatherScatterINTEL);
1546 case SPIRV::OpTypePointer: {
1547 auto SC =
MI.getOperand(1).getImm();
1558 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1563 case SPIRV::OpExtInst: {
1564 if (
MI.getOperand(2).getImm() ==
1565 static_cast<int64_t
>(
1566 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1567 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1570 if (
MI.getOperand(3).getImm() ==
1571 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1572 addPrintfRequirements(
MI, Reqs, ST);
1579 case SPIRV::OpAliasDomainDeclINTEL:
1580 case SPIRV::OpAliasScopeDeclINTEL:
1581 case SPIRV::OpAliasScopeListDeclINTEL: {
1582 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1583 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1586 case SPIRV::OpBitReverse:
1587 case SPIRV::OpBitFieldInsert:
1588 case SPIRV::OpBitFieldSExtract:
1589 case SPIRV::OpBitFieldUExtract:
1590 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1594 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1597 case SPIRV::OpTypeRuntimeArray:
1600 case SPIRV::OpTypeOpaque:
1601 case SPIRV::OpTypeEvent:
1604 case SPIRV::OpTypePipe:
1605 case SPIRV::OpTypeReserveId:
1608 case SPIRV::OpTypeDeviceEvent:
1609 case SPIRV::OpTypeQueue:
1610 case SPIRV::OpBuildNDRange:
1613 case SPIRV::OpDecorate:
1614 case SPIRV::OpDecorateId:
1615 case SPIRV::OpDecorateString:
1616 addOpDecorateReqs(
MI, 1, Reqs, ST);
1618 case SPIRV::OpMemberDecorate:
1619 case SPIRV::OpMemberDecorateString:
1620 addOpDecorateReqs(
MI, 2, Reqs, ST);
1622 case SPIRV::OpInBoundsPtrAccessChain:
1625 case SPIRV::OpConstantSampler:
1628 case SPIRV::OpInBoundsAccessChain:
1629 case SPIRV::OpAccessChain:
1630 addOpAccessChainReqs(
MI, Reqs, ST);
1632 case SPIRV::OpTypeImage:
1633 addOpTypeImageReqs(
MI, Reqs, ST);
1635 case SPIRV::OpTypeSampler:
1636 if (!
ST.isShader()) {
1640 case SPIRV::OpTypeForwardPointer:
1644 case SPIRV::OpAtomicFlagTestAndSet:
1645 case SPIRV::OpAtomicLoad:
1646 case SPIRV::OpAtomicStore:
1647 case SPIRV::OpAtomicExchange:
1648 case SPIRV::OpAtomicCompareExchange:
1649 case SPIRV::OpAtomicIIncrement:
1650 case SPIRV::OpAtomicIDecrement:
1651 case SPIRV::OpAtomicIAdd:
1652 case SPIRV::OpAtomicISub:
1653 case SPIRV::OpAtomicUMin:
1654 case SPIRV::OpAtomicUMax:
1655 case SPIRV::OpAtomicSMin:
1656 case SPIRV::OpAtomicSMax:
1657 case SPIRV::OpAtomicAnd:
1658 case SPIRV::OpAtomicOr:
1659 case SPIRV::OpAtomicXor: {
1662 if (
Op == SPIRV::OpAtomicStore) {
1665 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1671 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1676 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1678 "16-bit integer atomic operations require the following SPIR-V "
1679 "extension: SPV_INTEL_16bit_atomics",
1681 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1683 case SPIRV::OpAtomicLoad:
1684 case SPIRV::OpAtomicStore:
1685 case SPIRV::OpAtomicExchange:
1686 case SPIRV::OpAtomicCompareExchange:
1687 case SPIRV::OpAtomicCompareExchangeWeak:
1689 SPIRV::Capability::AtomicInt16CompareExchangeINTEL);
1696 }
else if (isBFloat16Type(TypeDef)) {
1697 if (
is_contained({SPIRV::OpAtomicLoad, SPIRV::OpAtomicStore,
1698 SPIRV::OpAtomicExchange},
1700 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1702 "The atomic bfloat16 instruction requires the following SPIR-V "
1703 "extension: SPV_INTEL_16bit_atomics",
1705 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1706 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16LoadStoreINTEL);
1711 case SPIRV::OpGroupNonUniformIAdd:
1712 case SPIRV::OpGroupNonUniformFAdd:
1713 case SPIRV::OpGroupNonUniformIMul:
1714 case SPIRV::OpGroupNonUniformFMul:
1715 case SPIRV::OpGroupNonUniformSMin:
1716 case SPIRV::OpGroupNonUniformUMin:
1717 case SPIRV::OpGroupNonUniformFMin:
1718 case SPIRV::OpGroupNonUniformSMax:
1719 case SPIRV::OpGroupNonUniformUMax:
1720 case SPIRV::OpGroupNonUniformFMax:
1721 case SPIRV::OpGroupNonUniformBitwiseAnd:
1722 case SPIRV::OpGroupNonUniformBitwiseOr:
1723 case SPIRV::OpGroupNonUniformBitwiseXor:
1724 case SPIRV::OpGroupNonUniformLogicalAnd:
1725 case SPIRV::OpGroupNonUniformLogicalOr:
1726 case SPIRV::OpGroupNonUniformLogicalXor: {
1728 int64_t GroupOp =
MI.getOperand(3).getImm();
1730 case SPIRV::GroupOperation::Reduce:
1731 case SPIRV::GroupOperation::InclusiveScan:
1732 case SPIRV::GroupOperation::ExclusiveScan:
1733 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1735 case SPIRV::GroupOperation::ClusteredReduce:
1736 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1738 case SPIRV::GroupOperation::PartitionedReduceNV:
1739 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1740 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1741 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1746 case SPIRV::OpGroupNonUniformQuadSwap:
1749 case SPIRV::OpImageQueryLod:
1752 case SPIRV::OpImageQuerySize:
1753 case SPIRV::OpImageQuerySizeLod:
1754 case SPIRV::OpImageQueryLevels:
1755 case SPIRV::OpImageQuerySamples:
1759 case SPIRV::OpImageQueryFormat: {
1760 Register ResultReg =
MI.getOperand(0).getReg();
1762 static const unsigned CompareOps[] = {
1763 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1764 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1765 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1766 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1767 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1769 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1770 if (ImmVal == 4323 || ImmVal == 4324) {
1771 if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1772 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1775 "SPV_EXT_image_raw10_raw12 extension");
1780 unsigned Opc = UseInst.getOpcode();
1782 if (
Opc == SPIRV::OpSwitch) {
1785 CheckAndAddExtension(
Op.getImm());
1787 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1790 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1793 CheckAndAddExtension(ImmVal);
1801 case SPIRV::OpGroupNonUniformShuffle:
1802 case SPIRV::OpGroupNonUniformShuffleXor:
1803 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1805 case SPIRV::OpGroupNonUniformShuffleUp:
1806 case SPIRV::OpGroupNonUniformShuffleDown:
1807 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1809 case SPIRV::OpGroupAll:
1810 case SPIRV::OpGroupAny:
1811 case SPIRV::OpGroupBroadcast:
1812 case SPIRV::OpGroupIAdd:
1813 case SPIRV::OpGroupFAdd:
1814 case SPIRV::OpGroupFMin:
1815 case SPIRV::OpGroupUMin:
1816 case SPIRV::OpGroupSMin:
1817 case SPIRV::OpGroupFMax:
1818 case SPIRV::OpGroupUMax:
1819 case SPIRV::OpGroupSMax:
1822 case SPIRV::OpGroupNonUniformElect:
1825 case SPIRV::OpGroupNonUniformAll:
1826 case SPIRV::OpGroupNonUniformAny:
1827 case SPIRV::OpGroupNonUniformAllEqual:
1830 case SPIRV::OpGroupNonUniformBroadcast:
1831 case SPIRV::OpGroupNonUniformBroadcastFirst:
1832 case SPIRV::OpGroupNonUniformBallot:
1833 case SPIRV::OpGroupNonUniformInverseBallot:
1834 case SPIRV::OpGroupNonUniformBallotBitExtract:
1835 case SPIRV::OpGroupNonUniformBallotBitCount:
1836 case SPIRV::OpGroupNonUniformBallotFindLSB:
1837 case SPIRV::OpGroupNonUniformBallotFindMSB:
1838 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1840 case SPIRV::OpSubgroupShuffleINTEL:
1841 case SPIRV::OpSubgroupShuffleDownINTEL:
1842 case SPIRV::OpSubgroupShuffleUpINTEL:
1843 case SPIRV::OpSubgroupShuffleXorINTEL:
1844 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1845 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1846 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1849 case SPIRV::OpSubgroupBlockReadINTEL:
1850 case SPIRV::OpSubgroupBlockWriteINTEL:
1851 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1852 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1853 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1856 case SPIRV::OpSubgroupImageBlockReadINTEL:
1857 case SPIRV::OpSubgroupImageBlockWriteINTEL:
1858 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1859 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1860 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
1863 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
1864 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
1865 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
1866 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
1867 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
1870 case SPIRV::OpAssumeTrueKHR:
1871 case SPIRV::OpExpectKHR:
1872 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
1873 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
1877 case SPIRV::OpFmaKHR:
1878 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
1883 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
1884 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
1885 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
1886 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
1887 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
1890 case SPIRV::OpConstantFunctionPointerINTEL:
1891 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1892 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1893 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1896 case SPIRV::OpGroupNonUniformRotateKHR:
1897 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
1899 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
1901 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
1902 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
1905 case SPIRV::OpFixedCosALTERA:
1906 case SPIRV::OpFixedSinALTERA:
1907 case SPIRV::OpFixedCosPiALTERA:
1908 case SPIRV::OpFixedSinPiALTERA:
1909 case SPIRV::OpFixedExpALTERA:
1910 case SPIRV::OpFixedLogALTERA:
1911 case SPIRV::OpFixedRecipALTERA:
1912 case SPIRV::OpFixedSqrtALTERA:
1913 case SPIRV::OpFixedSinCosALTERA:
1914 case SPIRV::OpFixedSinCosPiALTERA:
1915 case SPIRV::OpFixedRsqrtALTERA:
1916 if (!
ST.canUseExtension(
1917 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
1919 "following SPIR-V extension: "
1920 "SPV_ALTERA_arbitrary_precision_fixed_point",
1923 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
1924 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
1926 case SPIRV::OpGroupIMulKHR:
1927 case SPIRV::OpGroupFMulKHR:
1928 case SPIRV::OpGroupBitwiseAndKHR:
1929 case SPIRV::OpGroupBitwiseOrKHR:
1930 case SPIRV::OpGroupBitwiseXorKHR:
1931 case SPIRV::OpGroupLogicalAndKHR:
1932 case SPIRV::OpGroupLogicalOrKHR:
1933 case SPIRV::OpGroupLogicalXorKHR:
1934 if (
ST.canUseExtension(
1935 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
1936 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
1937 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
1940 case SPIRV::OpReadClockKHR:
1941 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
1943 "following SPIR-V extension: SPV_KHR_shader_clock",
1945 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
1948 case SPIRV::OpFunctionPointerCallINTEL:
1949 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1950 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1951 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1954 case SPIRV::OpAtomicFAddEXT:
1955 case SPIRV::OpAtomicFMinEXT:
1956 case SPIRV::OpAtomicFMaxEXT:
1957 AddAtomicFloatRequirements(
MI, Reqs, ST);
1959 case SPIRV::OpConvertBF16ToFINTEL:
1960 case SPIRV::OpConvertFToBF16INTEL:
1961 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
1962 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
1963 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
1966 case SPIRV::OpRoundFToTF32INTEL:
1967 if (
ST.canUseExtension(
1968 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
1969 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
1970 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
1973 case SPIRV::OpVariableLengthArrayINTEL:
1974 case SPIRV::OpSaveMemoryINTEL:
1975 case SPIRV::OpRestoreMemoryINTEL:
1976 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
1977 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
1978 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
1981 case SPIRV::OpAsmTargetINTEL:
1982 case SPIRV::OpAsmINTEL:
1983 case SPIRV::OpAsmCallINTEL:
1984 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
1985 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
1989 case SPIRV::OpTypeCooperativeMatrixKHR: {
1990 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1992 "OpTypeCooperativeMatrixKHR type requires the "
1993 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
1995 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1996 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1999 if (isBFloat16Type(TypeDef))
2000 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
2003 case SPIRV::OpArithmeticFenceEXT:
2004 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
2006 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
2008 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
2011 case SPIRV::OpControlBarrierArriveINTEL:
2012 case SPIRV::OpControlBarrierWaitINTEL:
2013 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
2014 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
2018 case SPIRV::OpCooperativeMatrixMulAddKHR: {
2019 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2021 "following SPIR-V extension: "
2022 "SPV_KHR_cooperative_matrix",
2024 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2025 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2026 constexpr unsigned MulAddMaxSize = 6;
2027 if (
MI.getNumOperands() != MulAddMaxSize)
2029 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
2031 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
2032 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2034 "require the following SPIR-V extension: "
2035 "SPV_INTEL_joint_matrix",
2037 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2039 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
2042 MatrixAAndBBFloat16ComponentsINTEL ||
2044 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
2046 MatrixResultBFloat16ComponentsINTEL) {
2047 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2049 "require the following SPIR-V extension: "
2050 "SPV_INTEL_joint_matrix",
2052 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2054 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
2058 case SPIRV::OpCooperativeMatrixLoadKHR:
2059 case SPIRV::OpCooperativeMatrixStoreKHR:
2060 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2061 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2062 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
2063 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2065 "following SPIR-V extension: "
2066 "SPV_KHR_cooperative_matrix",
2068 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2069 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2073 std::unordered_map<unsigned, unsigned> LayoutToInstMap = {
2074 {SPIRV::OpCooperativeMatrixLoadKHR, 3},
2075 {SPIRV::OpCooperativeMatrixStoreKHR, 2},
2076 {SPIRV::OpCooperativeMatrixLoadCheckedINTEL, 5},
2077 {SPIRV::OpCooperativeMatrixStoreCheckedINTEL, 4},
2078 {SPIRV::OpCooperativeMatrixPrefetchINTEL, 4}};
2080 const unsigned LayoutNum = LayoutToInstMap[
Op];
2081 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
2084 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
2087 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
2088 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2090 "extension: SPV_INTEL_joint_matrix",
2092 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2093 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2098 if (
Op == SPIRV::OpCooperativeMatrixLoadKHR ||
2099 Op == SPIRV::OpCooperativeMatrixStoreKHR)
2102 std::string InstName;
2104 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2105 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2107 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2108 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2110 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2111 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2115 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2116 const std::string ErrorMsg =
2117 InstName +
" instruction requires the "
2118 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2121 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2122 if (
Op == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2123 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2127 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2130 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2131 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2133 "instructions require the following SPIR-V extension: "
2134 "SPV_INTEL_joint_matrix",
2136 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2138 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2140 case SPIRV::OpReadPipeBlockingALTERA:
2141 case SPIRV::OpWritePipeBlockingALTERA:
2142 if (
ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2143 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2147 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2148 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2150 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2152 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2154 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2156 case SPIRV::OpConvertHandleToImageINTEL:
2157 case SPIRV::OpConvertHandleToSamplerINTEL:
2158 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2159 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2161 "instructions require the following SPIR-V extension: "
2162 "SPV_INTEL_bindless_images",
2165 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2167 if (
Op == SPIRV::OpConvertHandleToImageINTEL &&
2168 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2170 "OpConvertHandleToImageINTEL",
2172 }
else if (
Op == SPIRV::OpConvertHandleToSamplerINTEL &&
2173 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2175 "OpConvertHandleToSamplerINTEL",
2177 }
else if (
Op == SPIRV::OpConvertHandleToSampledImageINTEL &&
2178 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2180 "OpConvertHandleToSampledImageINTEL",
2185 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2186 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2188 "Parameter value must be a 32-bit scalar in case of "
2189 "Physical32 addressing model or a 64-bit scalar in case of "
2190 "Physical64 addressing model",
2193 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2197 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2198 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2199 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2200 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2201 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2202 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2204 "Prefetch/Store]INTEL instructions require the "
2205 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2207 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2208 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2210 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2211 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2214 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2215 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2220 case SPIRV::OpKill: {
2223 case SPIRV::OpDemoteToHelperInvocation:
2224 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2226 if (
ST.canUseExtension(
2227 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2230 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2235 case SPIRV::OpSUDot:
2236 case SPIRV::OpSDotAccSat:
2237 case SPIRV::OpUDotAccSat:
2238 case SPIRV::OpSUDotAccSat:
2239 AddDotProductRequirements(
MI, Reqs, ST);
2241 case SPIRV::OpImageSampleImplicitLod:
2243 addImageOperandReqs(
MI, Reqs, ST, 4);
2245 case SPIRV::OpImageSampleExplicitLod:
2246 addImageOperandReqs(
MI, Reqs, ST, 4);
2248 case SPIRV::OpImageSampleDrefImplicitLod:
2250 addImageOperandReqs(
MI, Reqs, ST, 5);
2252 case SPIRV::OpImageSampleDrefExplicitLod:
2254 addImageOperandReqs(
MI, Reqs, ST, 5);
2256 case SPIRV::OpImageFetch:
2258 addImageOperandReqs(
MI, Reqs, ST, 4);
2260 case SPIRV::OpImageDrefGather:
2261 case SPIRV::OpImageGather:
2263 addImageOperandReqs(
MI, Reqs, ST, 5);
2265 case SPIRV::OpImageRead: {
2266 Register ImageReg =
MI.getOperand(2).getReg();
2275 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2276 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2279 case SPIRV::OpImageWrite: {
2280 Register ImageReg =
MI.getOperand(0).getReg();
2289 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2290 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2293 case SPIRV::OpTypeStructContinuedINTEL:
2294 case SPIRV::OpConstantCompositeContinuedINTEL:
2295 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2296 case SPIRV::OpCompositeConstructContinuedINTEL: {
2297 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2299 "Continued instructions require the "
2300 "following SPIR-V extension: SPV_INTEL_long_composites",
2302 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2306 case SPIRV::OpArbitraryFloatEQALTERA:
2307 case SPIRV::OpArbitraryFloatGEALTERA:
2308 case SPIRV::OpArbitraryFloatGTALTERA:
2309 case SPIRV::OpArbitraryFloatLEALTERA:
2310 case SPIRV::OpArbitraryFloatLTALTERA:
2311 case SPIRV::OpArbitraryFloatCbrtALTERA:
2312 case SPIRV::OpArbitraryFloatCosALTERA:
2313 case SPIRV::OpArbitraryFloatCosPiALTERA:
2314 case SPIRV::OpArbitraryFloatExp10ALTERA:
2315 case SPIRV::OpArbitraryFloatExp2ALTERA:
2316 case SPIRV::OpArbitraryFloatExpALTERA:
2317 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2318 case SPIRV::OpArbitraryFloatHypotALTERA:
2319 case SPIRV::OpArbitraryFloatLog10ALTERA:
2320 case SPIRV::OpArbitraryFloatLog1pALTERA:
2321 case SPIRV::OpArbitraryFloatLog2ALTERA:
2322 case SPIRV::OpArbitraryFloatLogALTERA:
2323 case SPIRV::OpArbitraryFloatRecipALTERA:
2324 case SPIRV::OpArbitraryFloatSinCosALTERA:
2325 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2326 case SPIRV::OpArbitraryFloatSinALTERA:
2327 case SPIRV::OpArbitraryFloatSinPiALTERA:
2328 case SPIRV::OpArbitraryFloatSqrtALTERA:
2329 case SPIRV::OpArbitraryFloatACosALTERA:
2330 case SPIRV::OpArbitraryFloatACosPiALTERA:
2331 case SPIRV::OpArbitraryFloatAddALTERA:
2332 case SPIRV::OpArbitraryFloatASinALTERA:
2333 case SPIRV::OpArbitraryFloatASinPiALTERA:
2334 case SPIRV::OpArbitraryFloatATan2ALTERA:
2335 case SPIRV::OpArbitraryFloatATanALTERA:
2336 case SPIRV::OpArbitraryFloatATanPiALTERA:
2337 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2338 case SPIRV::OpArbitraryFloatCastALTERA:
2339 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2340 case SPIRV::OpArbitraryFloatDivALTERA:
2341 case SPIRV::OpArbitraryFloatMulALTERA:
2342 case SPIRV::OpArbitraryFloatPowALTERA:
2343 case SPIRV::OpArbitraryFloatPowNALTERA:
2344 case SPIRV::OpArbitraryFloatPowRALTERA:
2345 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2346 case SPIRV::OpArbitraryFloatSubALTERA: {
2347 if (!
ST.canUseExtension(
2348 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2350 "Floating point instructions can't be translated correctly without "
2351 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2354 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2356 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2359 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2360 if (!
ST.canUseExtension(
2361 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2363 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2365 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2368 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2370 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2373 case SPIRV::OpBitwiseFunctionINTEL: {
2374 if (!
ST.canUseExtension(
2375 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2377 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2378 "extension: SPV_INTEL_ternary_bitwise_function",
2380 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2381 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2384 case SPIRV::OpCopyMemorySized: {
2389 case SPIRV::OpPredicatedLoadINTEL:
2390 case SPIRV::OpPredicatedStoreINTEL: {
2391 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2393 "OpPredicated[Load/Store]INTEL instructions require "
2394 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2396 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2400 case SPIRV::OpFAddS:
2401 case SPIRV::OpFSubS:
2402 case SPIRV::OpFMulS:
2403 case SPIRV::OpFDivS:
2404 case SPIRV::OpFRemS:
2406 case SPIRV::OpFNegate:
2407 case SPIRV::OpFAddV:
2408 case SPIRV::OpFSubV:
2409 case SPIRV::OpFMulV:
2410 case SPIRV::OpFDivV:
2411 case SPIRV::OpFRemV:
2412 case SPIRV::OpFNegateV: {
2415 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2417 if (isBFloat16Type(TypeDef)) {
2418 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2420 "Arithmetic instructions with bfloat16 arguments require the "
2421 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2423 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2424 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2428 case SPIRV::OpOrdered:
2429 case SPIRV::OpUnordered:
2430 case SPIRV::OpFOrdEqual:
2431 case SPIRV::OpFOrdNotEqual:
2432 case SPIRV::OpFOrdLessThan:
2433 case SPIRV::OpFOrdLessThanEqual:
2434 case SPIRV::OpFOrdGreaterThan:
2435 case SPIRV::OpFOrdGreaterThanEqual:
2436 case SPIRV::OpFUnordEqual:
2437 case SPIRV::OpFUnordNotEqual:
2438 case SPIRV::OpFUnordLessThan:
2439 case SPIRV::OpFUnordLessThanEqual:
2440 case SPIRV::OpFUnordGreaterThan:
2441 case SPIRV::OpFUnordGreaterThanEqual: {
2445 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2447 if (isBFloat16Type(TypeDef)) {
2448 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2450 "Relational instructions with bfloat16 arguments require the "
2451 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2453 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2454 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2458 case SPIRV::OpDPdxCoarse:
2459 case SPIRV::OpDPdyCoarse:
2460 case SPIRV::OpDPdxFine:
2461 case SPIRV::OpDPdyFine: {
2465 case SPIRV::OpLoopControlINTEL: {
2466 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2467 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2479 SPIRV::Capability::Shader);
2491 addInstrRequirements(
MI, MAI, ST);
2494 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2496 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2497 RequireKHRFloatControls2 =
false,
2499 bool HasIntelFloatControls2 =
2500 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2501 bool HasKHRFloatControls2 =
2502 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2503 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2509 auto EM =
Const->getZExtValue();
2513 case SPIRV::ExecutionMode::DenormPreserve:
2514 case SPIRV::ExecutionMode::DenormFlushToZero:
2515 case SPIRV::ExecutionMode::RoundingModeRTE:
2516 case SPIRV::ExecutionMode::RoundingModeRTZ:
2517 RequireFloatControls = VerLower14;
2519 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2521 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2522 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2523 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2524 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2525 if (HasIntelFloatControls2) {
2526 RequireIntelFloatControls2 =
true;
2528 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2531 case SPIRV::ExecutionMode::FPFastMathDefault: {
2532 if (HasKHRFloatControls2) {
2533 RequireKHRFloatControls2 =
true;
2535 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2539 case SPIRV::ExecutionMode::ContractionOff:
2540 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2541 if (HasKHRFloatControls2) {
2542 RequireKHRFloatControls2 =
true;
2544 SPIRV::OperandCategory::ExecutionModeOperand,
2545 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2548 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2553 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2558 if (RequireFloatControls &&
2559 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2561 if (RequireIntelFloatControls2)
2563 if (RequireKHRFloatControls2)
2567 if (
F.isDeclaration())
2569 if (
F.getMetadata(
"reqd_work_group_size"))
2571 SPIRV::OperandCategory::ExecutionModeOperand,
2572 SPIRV::ExecutionMode::LocalSize, ST);
2573 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2575 SPIRV::OperandCategory::ExecutionModeOperand,
2576 SPIRV::ExecutionMode::LocalSize, ST);
2578 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2581 if (
F.getMetadata(
"work_group_size_hint"))
2583 SPIRV::OperandCategory::ExecutionModeOperand,
2584 SPIRV::ExecutionMode::LocalSizeHint, ST);
2585 if (
F.getMetadata(
"intel_reqd_sub_group_size"))
2587 SPIRV::OperandCategory::ExecutionModeOperand,
2588 SPIRV::ExecutionMode::SubgroupSize, ST);
2589 if (
F.getMetadata(
"max_work_group_size"))
2591 SPIRV::OperandCategory::ExecutionModeOperand,
2592 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2593 if (
F.getMetadata(
"vec_type_hint"))
2595 SPIRV::OperandCategory::ExecutionModeOperand,
2596 SPIRV::ExecutionMode::VecTypeHint, ST);
2598 if (
F.hasOptNone()) {
2599 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2602 }
else if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2612 unsigned Flags = SPIRV::FPFastMathMode::None;
2613 bool CanUseKHRFloatControls2 =
2614 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2616 Flags |= SPIRV::FPFastMathMode::NotNaN;
2618 Flags |= SPIRV::FPFastMathMode::NotInf;
2620 Flags |= SPIRV::FPFastMathMode::NSZ;
2622 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2624 Flags |= SPIRV::FPFastMathMode::AllowContract;
2626 if (CanUseKHRFloatControls2)
2634 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2635 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2636 SPIRV::FPFastMathMode::AllowTransform |
2637 SPIRV::FPFastMathMode::AllowReassoc |
2638 SPIRV::FPFastMathMode::AllowContract;
2640 Flags |= SPIRV::FPFastMathMode::Fast;
2643 if (CanUseKHRFloatControls2) {
2645 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2646 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2651 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2652 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2653 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2654 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2655 "AllowContract flags to be enabled as well.");
2666 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2669static void handleMIFlagDecoration(
2674 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2675 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2678 SPIRV::Decoration::NoSignedWrap, {});
2681 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2682 SPIRV::Decoration::NoUnsignedWrap, ST,
2686 SPIRV::Decoration::NoUnsignedWrap, {});
2691 TII.canUseFastMathFlags(
2692 I,
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) ||
2693 (
ST.isKernel() &&
I.getOpcode() == SPIRV::OpExtInst);
2697 unsigned FMFlags = getFastMathFlags(
I, ST);
2698 if (FMFlags == SPIRV::FPFastMathMode::None) {
2701 if (FPFastMathDefaultInfoVec.
empty())
2717 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2718 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2719 ?
I.getOperand(1).getReg()
2720 :
I.getOperand(2).getReg();
2728 if (Ty == Elem.Ty) {
2729 FMFlags = Elem.FastMathFlags;
2730 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2731 Elem.FPFastMathDefault;
2736 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2739 if (isFastMathModeAvailable(ST)) {
2740 Register DstReg =
I.getOperand(0).getReg();
2756 for (
auto &
MBB : *MF)
2757 for (
auto &
MI :
MBB)
2758 handleMIFlagDecoration(
MI, ST,
TII, MAI.
Reqs, GR,
2775 for (
auto &
MBB : *MF) {
2776 if (!
MBB.hasName() ||
MBB.empty())
2795 for (
auto &
MBB : *MF) {
2797 MI.setDesc(
TII.get(SPIRV::OpPhi));
2800 MI.insert(
MI.operands_begin() + 1,
2801 {MachineOperand::CreateReg(ResTypeReg, false)});
2820 SPIRV::FPFastMathMode::None);
2822 SPIRV::FPFastMathMode::None);
2824 SPIRV::FPFastMathMode::None);
2831 size_t BitWidth = Ty->getScalarSizeInBits();
2835 assert(Index >= 0 && Index < 3 &&
2836 "Expected FPFastMathDefaultInfo for half, float, or double");
2837 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2838 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2839 return FPFastMathDefaultInfoVec[Index];
2842static void collectFPFastMathDefaults(
const Module &M,
2845 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
2854 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2858 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2867 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
2869 "Expected 4 operands for FPFastMathDefault");
2880 Info.FastMathFlags = Flags;
2881 Info.FPFastMathDefault =
true;
2882 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
2884 "Expected no operands for ContractionOff");
2891 Info.ContractionOff =
true;
2893 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
2895 "Expected 1 operand for SignedZeroInfNanPreserve");
2896 unsigned TargetWidth =
2905 assert(Index >= 0 && Index < 3 &&
2906 "Expected FPFastMathDefaultInfo for half, float, or double");
2907 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2908 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2909 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
2920 SPIRVTargetMachine &TM =
2924 TII = ST->getInstrInfo();
2930 patchPhis(M, GR, *TII, MMI);
2932 addMBBNames(M, *TII, MMI, *ST,
MAI);
2933 collectFPFastMathDefaults(M,
MAI, *ST);
2934 addDecorations(M, *TII, MMI, *ST,
MAI, GR);
2936 collectReqs(M,
MAI, MMI, *ST);
2940 collectReqs(M,
MAI, MMI, *ST);
2941 collectDeclarations(M);
2944 numberRegistersGlobally(M);
2947 processOtherInstrs(M);
2951 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
2954 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