34#define DEBUG_TYPE "spirv-module-analysis"
38 cl::desc(
"Dump MIR with SPIR-V dependencies info"),
43 cl::desc(
"SPIR-V capabilities to avoid if there are "
44 "other options enabling a feature"),
47 "SPIR-V Shader capability")));
61 unsigned DefaultVal = 0) {
63 const auto &
Op = MdNode->getOperand(
OpIndex);
70getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category,
76 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
78 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
83 bool MinVerOK = SPIRVVersion.
empty() || SPIRVVersion >= ReqMinVer;
85 ReqMaxVer.
empty() || SPIRVVersion.
empty() || SPIRVVersion <= ReqMaxVer;
88 if (ReqCaps.
empty()) {
89 if (ReqExts.
empty()) {
90 if (MinVerOK && MaxVerOK)
91 return {
true, {}, {}, ReqMinVer, ReqMaxVer};
94 }
else if (MinVerOK && MaxVerOK) {
95 if (ReqCaps.
size() == 1) {
96 auto Cap = ReqCaps[0];
99 SPIRV::OperandCategory::CapabilityOperand, Cap));
100 return {
true, {Cap}, std::move(ReqExts), ReqMinVer, ReqMaxVer};
110 for (
auto Cap : ReqCaps)
113 for (
size_t i = 0, Sz = UseCaps.
size(); i < Sz; ++i) {
114 auto Cap = UseCaps[i];
115 if (i == Sz - 1 || !AvoidCaps.
S.
contains(Cap)) {
117 SPIRV::OperandCategory::CapabilityOperand, Cap));
118 return {
true, {Cap}, std::move(ReqExts), ReqMinVer, ReqMaxVer};
126 if (
llvm::all_of(ReqExts, [&ST](
const SPIRV::Extension::Extension &Ext) {
127 return ST.canUseExtension(Ext);
138void SPIRVModuleAnalysis::setBaseInfo(
const Module &M) {
142 MAI.RegisterAliasTable.clear();
143 MAI.InstrsToDelete.clear();
144 MAI.GlobalObjMap.clear();
145 MAI.GlobalVarList.clear();
146 MAI.ExtInstSetMap.clear();
148 MAI.Reqs.initAvailableCapabilities(*ST);
151 if (
auto MemModel =
M.getNamedMetadata(
"spirv.MemoryModel")) {
152 auto MemMD = MemModel->getOperand(0);
153 MAI.Addr =
static_cast<SPIRV::AddressingModel::AddressingModel
>(
154 getMetadataUInt(MemMD, 0));
156 static_cast<SPIRV::MemoryModel::MemoryModel
>(getMetadataUInt(MemMD, 1));
159 MAI.Mem = ST->isShader() ? SPIRV::MemoryModel::GLSL450
160 : SPIRV::MemoryModel::OpenCL;
161 if (
MAI.Mem == SPIRV::MemoryModel::OpenCL) {
162 unsigned PtrSize = ST->getPointerSize();
163 MAI.Addr = PtrSize == 32 ? SPIRV::AddressingModel::Physical32
164 : PtrSize == 64 ? SPIRV::AddressingModel::Physical64
165 : SPIRV::AddressingModel::Logical;
168 MAI.Addr = SPIRV::AddressingModel::Logical;
173 if (
auto VerNode =
M.getNamedMetadata(
"opencl.ocl.version")) {
174 MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_C;
177 assert(VerNode->getNumOperands() > 0 &&
"Invalid SPIR");
178 auto VersionMD = VerNode->getOperand(0);
179 unsigned MajorNum = getMetadataUInt(VersionMD, 0, 2);
180 unsigned MinorNum = getMetadataUInt(VersionMD, 1);
181 unsigned RevNum = getMetadataUInt(VersionMD, 2);
184 (std::max(1U, MajorNum) * 100 + MinorNum) * 1000 + RevNum;
187 if (
auto *CxxVerNode =
M.getNamedMetadata(
"opencl.cxx.version")) {
188 assert(CxxVerNode->getNumOperands() > 0 &&
"Invalid SPIR");
189 auto *CxxMD = CxxVerNode->getOperand(0);
191 (getMetadataUInt(CxxMD, 0) * 100 + getMetadataUInt(CxxMD, 1)) * 1000 +
192 getMetadataUInt(CxxMD, 2);
193 if ((
MAI.SrcLangVersion == 200000 && CxxVer == 100000) ||
194 (
MAI.SrcLangVersion == 300000 && CxxVer == 202100000)) {
195 MAI.SrcLang = SPIRV::SourceLanguage::CPP_for_OpenCL;
196 MAI.SrcLangVersion = CxxVer;
199 "opencl cxx version is not compatible with opencl c version!");
207 if (!ST->isShader()) {
208 MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_CPP;
209 MAI.SrcLangVersion = 100000;
211 MAI.SrcLang = SPIRV::SourceLanguage::Unknown;
212 MAI.SrcLangVersion = 0;
216 if (
auto ExtNode =
M.getNamedMetadata(
"opencl.used.extensions")) {
217 for (
unsigned I = 0,
E = ExtNode->getNumOperands();
I !=
E; ++
I) {
218 MDNode *MD = ExtNode->getOperand(
I);
228 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::MemoryModelOperand,
230 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::SourceLanguageOperand,
232 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::AddressingModelOperand,
235 if (
MAI.Mem == SPIRV::MemoryModel::VulkanKHR)
236 MAI.Reqs.addExtension(SPIRV::Extension::SPV_KHR_vulkan_memory_model);
238 if (!ST->isShader()) {
240 MAI.ExtInstSetMap[
static_cast<unsigned>(
241 SPIRV::InstructionSet::OpenCL_std)] =
MAI.getNextIDRegister();
252 if (
UseMI.getOpcode() != SPIRV::OpDecorate &&
253 UseMI.getOpcode() != SPIRV::OpMemberDecorate)
256 for (
unsigned I = 0;
I <
UseMI.getNumOperands(); ++
I) {
274 for (
unsigned i = 0; i <
MI.getNumOperands(); ++i) {
283 unsigned Opcode =
MI.getOpcode();
284 if ((Opcode == SPIRV::OpDecorate) && i >= 2) {
285 unsigned DecorationID =
MI.getOperand(1).getImm();
286 if (DecorationID != SPIRV::Decoration::FuncParamAttr &&
287 DecorationID != SPIRV::Decoration::UserSemantic &&
288 DecorationID != SPIRV::Decoration::CacheControlLoadINTEL &&
289 DecorationID != SPIRV::Decoration::CacheControlStoreINTEL)
295 if (!UseDefReg && MO.
isDef()) {
303 dbgs() <<
"Unexpectedly, no global id found for the operand ";
305 dbgs() <<
"\nInstruction: ";
324 appendDecorationsForReg(
MI.getMF()->getRegInfo(), DefReg, Signature);
331 unsigned Opcode =
MI.getOpcode();
333 case SPIRV::OpTypeForwardPointer:
336 case SPIRV::OpVariable:
337 return static_cast<SPIRV::StorageClass::StorageClass
>(
338 MI.getOperand(2).
getImm()) != SPIRV::StorageClass::Function;
339 case SPIRV::OpFunction:
340 case SPIRV::OpFunctionParameter:
343 if (GR->hasConstFunPtr() && Opcode == SPIRV::OpUndef) {
346 if (
UseMI.getOpcode() != SPIRV::OpConstantFunctionPointerINTEL)
352 MAI.setSkipEmission(&
MI);
356 return TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
357 TII->isInlineAsmDefInstr(
MI);
363void SPIRVModuleAnalysis::visitFunPtrUse(
365 std::map<const Value *, unsigned> &GlobalToGReg,
const MachineFunction *MF,
367 const MachineOperand *OpFunDef =
368 GR->getFunctionDefinitionByUse(&
MI.getOperand(2));
371 const MachineInstr *OpDefMI = OpFunDef->
getParent();
374 const MachineRegisterInfo &FunDefMRI = FunDefMF->
getRegInfo();
376 visitDecl(FunDefMRI, SignatureToGReg, GlobalToGReg, FunDefMF, *OpDefMI);
378 }
while (OpDefMI && (OpDefMI->
getOpcode() == SPIRV::OpFunction ||
379 OpDefMI->
getOpcode() == SPIRV::OpFunctionParameter));
381 MCRegister GlobalFunDefReg =
382 MAI.getRegisterAlias(FunDefMF, OpFunDef->
getReg());
384 "Function definition must refer to a global register");
385 MAI.setRegisterAlias(MF, OpReg, GlobalFunDefReg);
390void SPIRVModuleAnalysis::visitDecl(
392 std::map<const Value *, unsigned> &GlobalToGReg,
const MachineFunction *MF,
394 unsigned Opcode =
MI.getOpcode();
397 for (
const MachineOperand &MO :
MI.operands()) {
402 if (Opcode == SPIRV::OpConstantFunctionPointerINTEL &&
404 visitFunPtrUse(OpReg, SignatureToGReg, GlobalToGReg, MF,
MI);
408 if (
MAI.hasRegisterAlias(MF, MO.
getReg()))
412 if (isDeclSection(MRI, *OpDefMI))
413 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF, *OpDefMI);
419 dbgs() <<
"Unexpectedly, no unique definition for the operand ";
421 dbgs() <<
"\nInstruction: ";
426 "No unique definition is found for the virtual register");
430 bool IsFunDef =
false;
431 if (TII->isSpecConstantInstr(
MI)) {
432 GReg =
MAI.getNextIDRegister();
434 }
else if (Opcode == SPIRV::OpFunction ||
435 Opcode == SPIRV::OpFunctionParameter) {
436 GReg = handleFunctionOrParameter(MF,
MI, GlobalToGReg, IsFunDef);
437 }
else if (Opcode == SPIRV::OpTypeStruct ||
438 Opcode == SPIRV::OpConstantComposite) {
439 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
440 const MachineInstr *NextInstr =
MI.getNextNode();
442 ((Opcode == SPIRV::OpTypeStruct &&
443 NextInstr->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL) ||
444 (Opcode == SPIRV::OpConstantComposite &&
446 SPIRV::OpConstantCompositeContinuedINTEL))) {
447 MCRegister Tmp = handleTypeDeclOrConstant(*NextInstr, SignatureToGReg);
449 MAI.setSkipEmission(NextInstr);
452 }
else if (TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
453 TII->isInlineAsmDefInstr(
MI)) {
454 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
455 }
else if (Opcode == SPIRV::OpVariable) {
456 GReg = handleVariable(MF,
MI, GlobalToGReg);
459 dbgs() <<
"\nInstruction: ";
465 MAI.setRegisterAlias(MF,
MI.getOperand(0).getReg(), GReg);
467 MAI.setSkipEmission(&
MI);
470MCRegister SPIRVModuleAnalysis::handleFunctionOrParameter(
472 std::map<const Value *, unsigned> &GlobalToGReg,
bool &IsFunDef) {
473 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
474 assert(GObj &&
"Unregistered global definition");
478 assert(
F &&
"Expected a reference to a function or an argument");
479 IsFunDef = !
F->isDeclaration();
480 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
483 MCRegister GReg =
MAI.getNextIDRegister();
491SPIRVModuleAnalysis::handleTypeDeclOrConstant(
const MachineInstr &
MI,
494 auto [It,
Inserted] = SignatureToGReg.try_emplace(MISign);
497 MCRegister GReg =
MAI.getNextIDRegister();
503MCRegister SPIRVModuleAnalysis::handleVariable(
505 std::map<const Value *, unsigned> &GlobalToGReg) {
506 MAI.GlobalVarList.push_back(&
MI);
507 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
508 assert(GObj &&
"Unregistered global definition");
509 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
512 MCRegister GReg =
MAI.getNextIDRegister();
516 MAI.GlobalObjMap[GV] = GReg;
520void SPIRVModuleAnalysis::collectDeclarations(
const Module &M) {
522 std::map<const Value *, unsigned> GlobalToGReg;
523 for (
const Function &
F : M) {
524 MachineFunction *MF = MMI->getMachineFunction(
F);
527 const MachineRegisterInfo &MRI = MF->
getRegInfo();
528 unsigned PastHeader = 0;
529 for (MachineBasicBlock &
MBB : *MF) {
530 for (MachineInstr &
MI :
MBB) {
531 if (
MI.getNumOperands() == 0)
533 unsigned Opcode =
MI.getOpcode();
534 if (Opcode == SPIRV::OpFunction) {
535 if (PastHeader == 0) {
539 }
else if (Opcode == SPIRV::OpFunctionParameter) {
542 }
else if (PastHeader > 0) {
546 const MachineOperand &DefMO =
MI.getOperand(0);
548 case SPIRV::OpExtension:
549 MAI.Reqs.addExtension(SPIRV::Extension::Extension(DefMO.
getImm()));
550 MAI.setSkipEmission(&
MI);
552 case SPIRV::OpCapability:
553 MAI.Reqs.addCapability(SPIRV::Capability::Capability(DefMO.
getImm()));
554 MAI.setSkipEmission(&
MI);
559 if (DefMO.
isReg() && isDeclSection(MRI,
MI) &&
560 !
MAI.hasRegisterAlias(MF, DefMO.
getReg()))
561 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF,
MI);
574 if (
MI.getOpcode() == SPIRV::OpDecorate) {
576 auto Dec =
MI.getOperand(1).getImm();
577 if (Dec == SPIRV::Decoration::LinkageAttributes) {
578 auto Lnk =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
579 if (Lnk == SPIRV::LinkageType::Import) {
584 MAI.GlobalObjMap[ImportedFunc] =
585 MAI.getRegisterAlias(
MI.getMF(), Target);
588 }
else if (
MI.getOpcode() == SPIRV::OpFunction) {
591 MCRegister GlobalReg =
MAI.getRegisterAlias(
MI.getMF(),
Reg);
593 MAI.GlobalObjMap[
F] = GlobalReg;
605 auto FoundMI = IS.insert(std::move(MISign));
606 if (!FoundMI.second) {
607 if (
MI.getOpcode() == SPIRV::OpDecorate) {
609 "Decoration instructions must have at least 2 operands");
611 "Only OpDecorate instructions can be duplicates");
616 if (
MI.getOperand(1).getImm() != SPIRV::Decoration::FPFastMathMode)
621 if (instrToSignature(*OrigMI, MAI,
true) == MISign) {
622 assert(OrigMI->getNumOperands() ==
MI.getNumOperands() &&
623 "Original instruction must have the same number of operands");
625 OrigMI->getNumOperands() == 3 &&
626 "FPFastMathMode decoration must have 3 operands for OpDecorate");
627 unsigned OrigFlags = OrigMI->getOperand(2).getImm();
628 unsigned NewFlags =
MI.getOperand(2).getImm();
629 if (OrigFlags == NewFlags)
633 unsigned FinalFlags = OrigFlags | NewFlags;
635 <<
"Warning: Conflicting FPFastMathMode decoration flags "
637 << *OrigMI <<
"Original flags: " << OrigFlags
638 <<
", new flags: " << NewFlags
639 <<
". They will be merged on a best effort basis, but not "
640 "validated. Final flags: "
641 << FinalFlags <<
"\n";
648 assert(
false &&
"No original instruction found for the duplicate "
649 "OpDecorate, but we found one in IS.");
662void SPIRVModuleAnalysis::processOtherInstrs(
const Module &M) {
664 for (
const Function &
F : M) {
665 if (
F.isDeclaration())
667 MachineFunction *MF = MMI->getMachineFunction(
F);
670 for (MachineBasicBlock &
MBB : *MF)
671 for (MachineInstr &
MI :
MBB) {
672 if (
MAI.getSkipEmission(&
MI))
674 const unsigned OpCode =
MI.getOpcode();
675 if (OpCode == SPIRV::OpString) {
677 }
else if (OpCode == SPIRV::OpExtInst &&
MI.getOperand(2).isImm() &&
678 MI.getOperand(2).getImm() ==
679 SPIRV::InstructionSet::
680 NonSemantic_Shader_DebugInfo_100) {
687 MachineOperand Ins =
MI.getOperand(3);
688 namespace NS = SPIRV::NonSemanticExtInst;
689 static constexpr int64_t GlobalNonSemanticDITy[] = {
690 NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
691 NS::DebugTypeBasic, NS::DebugTypePointer};
692 bool IsGlobalDI =
false;
693 for (
unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
694 IsGlobalDI |= Ins.
getImm() == GlobalNonSemanticDITy[Idx];
697 }
else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
699 }
else if (OpCode == SPIRV::OpEntryPoint) {
701 }
else if (TII->isAliasingInstr(
MI)) {
703 }
else if (TII->isDecorationInstr(
MI)) {
705 collectFuncNames(
MI, &
F);
706 }
else if (TII->isConstantInstr(
MI)) {
710 }
else if (OpCode == SPIRV::OpFunction) {
711 collectFuncNames(
MI, &
F);
712 }
else if (OpCode == SPIRV::OpTypeForwardPointer) {
722void SPIRVModuleAnalysis::numberRegistersGlobally(
const Module &M) {
723 for (
const Function &
F : M) {
724 if (
F.isDeclaration())
726 MachineFunction *MF = MMI->getMachineFunction(
F);
728 for (MachineBasicBlock &
MBB : *MF) {
729 for (MachineInstr &
MI :
MBB) {
730 for (MachineOperand &
Op :
MI.operands()) {
734 if (
MAI.hasRegisterAlias(MF,
Reg))
736 MCRegister NewReg =
MAI.getNextIDRegister();
737 MAI.setRegisterAlias(MF,
Reg, NewReg);
739 if (
MI.getOpcode() != SPIRV::OpExtInst)
741 auto Set =
MI.getOperand(2).getImm();
742 auto [It,
Inserted] =
MAI.ExtInstSetMap.try_emplace(Set);
744 It->second =
MAI.getNextIDRegister();
752 SPIRV::OperandCategory::OperandCategory Category, uint32_t i,
754 addRequirements(getSymbolicOperandRequirements(Category, i, ST, *
this));
757void SPIRV::RequirementHandler::recursiveAddCapabilities(
759 for (
const auto &Cap : ToPrune) {
763 recursiveAddCapabilities(ImplicitDecls);
768 for (
const auto &Cap : ToAdd) {
769 bool IsNewlyInserted = AllCaps.insert(Cap).second;
770 if (!IsNewlyInserted)
774 recursiveAddCapabilities(ImplicitDecls);
775 MinimalCaps.push_back(Cap);
780 const SPIRV::Requirements &Req) {
784 if (Req.
Cap.has_value())
785 addCapabilities({Req.
Cap.value()});
787 addExtensions(Req.
Exts);
790 if (!MaxVersion.empty() && Req.
MinVer > MaxVersion) {
792 <<
" and <= " << MaxVersion <<
"\n");
796 if (MinVersion.empty() || Req.
MinVer > MinVersion)
801 if (!MinVersion.empty() && Req.
MaxVer < MinVersion) {
803 <<
" and >= " << MinVersion <<
"\n");
807 if (MaxVersion.empty() || Req.
MaxVer < MaxVersion)
813 const SPIRVSubtarget &ST)
const {
815 bool IsSatisfiable =
true;
816 auto TargetVer =
ST.getSPIRVVersion();
818 if (!MaxVersion.empty() && !TargetVer.empty() && MaxVersion < TargetVer) {
820 dbgs() <<
"Target SPIR-V version too high for required features\n"
821 <<
"Required max version: " << MaxVersion <<
" target version "
822 << TargetVer <<
"\n");
823 IsSatisfiable =
false;
826 if (!MinVersion.empty() && !TargetVer.empty() && MinVersion > TargetVer) {
827 LLVM_DEBUG(
dbgs() <<
"Target SPIR-V version too low for required features\n"
828 <<
"Required min version: " << MinVersion
829 <<
" target version " << TargetVer <<
"\n");
830 IsSatisfiable =
false;
833 if (!MinVersion.empty() && !MaxVersion.empty() && MinVersion > MaxVersion) {
836 <<
"Version is too low for some features and too high for others.\n"
837 <<
"Required SPIR-V min version: " << MinVersion
838 <<
" required SPIR-V max version " << MaxVersion <<
"\n");
839 IsSatisfiable =
false;
842 AvoidCapabilitiesSet AvoidCaps;
844 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
846 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
848 for (
auto Cap : MinimalCaps) {
849 if (AvailableCaps.contains(Cap) && !AvoidCaps.
S.
contains(Cap))
853 OperandCategory::CapabilityOperand, Cap)
855 IsSatisfiable =
false;
858 for (
auto Ext : AllExtensions) {
859 if (
ST.canUseExtension(Ext))
863 OperandCategory::ExtensionOperand, Ext)
865 IsSatisfiable =
false;
874 for (
const auto Cap : ToAdd)
875 if (AvailableCaps.insert(Cap).second)
877 SPIRV::OperandCategory::CapabilityOperand, Cap));
881 const Capability::Capability
ToRemove,
882 const Capability::Capability IfPresent) {
883 if (AllCaps.contains(IfPresent))
891 addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8,
894 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
896 Capability::GroupNonUniformVote,
897 Capability::GroupNonUniformArithmetic,
898 Capability::GroupNonUniformBallot,
899 Capability::GroupNonUniformClustered,
900 Capability::GroupNonUniformShuffle,
901 Capability::GroupNonUniformShuffleRelative,
902 Capability::GroupNonUniformQuad});
904 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
906 Capability::DotProductInput4x8Bit,
907 Capability::DotProductInput4x8BitPacked,
908 Capability::DemoteToHelperInvocation});
911 for (
auto Extension :
ST.getAllAvailableExtensions()) {
917 if (!
ST.isShader()) {
918 initAvailableCapabilitiesForOpenCL(ST);
923 initAvailableCapabilitiesForVulkan(ST);
930void RequirementHandler::initAvailableCapabilitiesForOpenCL(
931 const SPIRVSubtarget &ST) {
934 Capability::Kernel, Capability::Vector16,
935 Capability::Groups, Capability::GenericPointer,
936 Capability::StorageImageWriteWithoutFormat,
937 Capability::StorageImageReadWithoutFormat});
938 if (
ST.hasOpenCLFullProfile())
940 if (
ST.hasOpenCLImageSupport()) {
942 Capability::Image1D, Capability::SampledBuffer,
943 Capability::ImageBuffer});
944 if (
ST.isAtLeastOpenCLVer(VersionTuple(2, 0)))
947 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) &&
948 ST.isAtLeastOpenCLVer(VersionTuple(2, 2)))
950 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 4)))
951 addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
952 Capability::SignedZeroInfNanPreserve,
953 Capability::RoundingModeRTE,
954 Capability::RoundingModeRTZ});
961void RequirementHandler::initAvailableCapabilitiesForVulkan(
962 const SPIRVSubtarget &ST) {
965 addAvailableCaps({Capability::Int64, Capability::Float16, Capability::Float64,
966 Capability::GroupNonUniform, Capability::Image1D,
967 Capability::SampledBuffer, Capability::ImageBuffer,
968 Capability::UniformBufferArrayDynamicIndexing,
969 Capability::SampledImageArrayDynamicIndexing,
970 Capability::StorageBufferArrayDynamicIndexing,
971 Capability::StorageImageArrayDynamicIndexing,
972 Capability::DerivativeControl, Capability::MinLod,
973 Capability::ImageQuery, Capability::ImageGatherExtended,
974 Capability::Addresses, Capability::VulkanMemoryModelKHR,
975 Capability::StorageImageExtendedFormats});
978 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
980 {Capability::ShaderNonUniformEXT, Capability::RuntimeDescriptorArrayEXT,
981 Capability::InputAttachmentArrayDynamicIndexingEXT,
982 Capability::UniformTexelBufferArrayDynamicIndexingEXT,
983 Capability::StorageTexelBufferArrayDynamicIndexingEXT,
984 Capability::UniformBufferArrayNonUniformIndexingEXT,
985 Capability::SampledImageArrayNonUniformIndexingEXT,
986 Capability::StorageBufferArrayNonUniformIndexingEXT,
987 Capability::StorageImageArrayNonUniformIndexingEXT,
988 Capability::InputAttachmentArrayNonUniformIndexingEXT,
989 Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
990 Capability::StorageTexelBufferArrayNonUniformIndexingEXT});
994 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
996 Capability::StorageImageReadWithoutFormat});
1004static void addOpDecorateReqs(
const MachineInstr &
MI,
unsigned DecIndex,
1007 int64_t DecOp =
MI.getOperand(DecIndex).getImm();
1008 auto Dec =
static_cast<SPIRV::Decoration::Decoration
>(DecOp);
1010 SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
1012 if (Dec == SPIRV::Decoration::BuiltIn) {
1013 int64_t BuiltInOp =
MI.getOperand(DecIndex + 1).getImm();
1014 auto BuiltIn =
static_cast<SPIRV::BuiltIn::BuiltIn
>(BuiltInOp);
1016 SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
1017 }
else if (Dec == SPIRV::Decoration::LinkageAttributes) {
1018 int64_t LinkageOp =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
1019 SPIRV::LinkageType::LinkageType LnkType =
1020 static_cast<SPIRV::LinkageType::LinkageType
>(LinkageOp);
1021 if (LnkType == SPIRV::LinkageType::LinkOnceODR)
1022 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_linkonce_odr);
1023 }
else if (Dec == SPIRV::Decoration::CacheControlLoadINTEL ||
1024 Dec == SPIRV::Decoration::CacheControlStoreINTEL) {
1025 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_cache_controls);
1026 }
else if (Dec == SPIRV::Decoration::HostAccessINTEL) {
1027 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_global_variable_host_access);
1028 }
else if (Dec == SPIRV::Decoration::InitModeINTEL ||
1029 Dec == SPIRV::Decoration::ImplementInRegisterMapINTEL) {
1031 SPIRV::Extension::SPV_INTEL_global_variable_fpga_decorations);
1032 }
else if (Dec == SPIRV::Decoration::NonUniformEXT) {
1034 }
else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
1036 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_fp_max_error);
1037 }
else if (Dec == SPIRV::Decoration::FPFastMathMode) {
1038 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
1040 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_float_controls2);
1049 assert(
MI.getNumOperands() >= 8 &&
"Insufficient operands for OpTypeImage");
1052 int64_t ImgFormatOp =
MI.getOperand(7).getImm();
1053 auto ImgFormat =
static_cast<SPIRV::ImageFormat::ImageFormat
>(ImgFormatOp);
1057 bool IsArrayed =
MI.getOperand(4).getImm() == 1;
1058 bool IsMultisampled =
MI.getOperand(5).getImm() == 1;
1059 bool NoSampler =
MI.getOperand(6).getImm() == 2;
1062 switch (
MI.getOperand(2).getImm()) {
1063 case SPIRV::Dim::DIM_1D:
1065 : SPIRV::Capability::Sampled1D);
1067 case SPIRV::Dim::DIM_2D:
1068 if (IsMultisampled && NoSampler)
1071 case SPIRV::Dim::DIM_Cube:
1075 : SPIRV::Capability::SampledCubeArray);
1077 case SPIRV::Dim::DIM_Rect:
1079 : SPIRV::Capability::SampledRect);
1081 case SPIRV::Dim::DIM_Buffer:
1083 : SPIRV::Capability::SampledBuffer);
1085 case SPIRV::Dim::DIM_SubpassData:
1097 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_image_int64);
1101 if (!
ST.isShader()) {
1102 if (
MI.getNumOperands() > 8 &&
1103 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
1112 TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
1118#define ATOM_FLT_REQ_EXT_MSG(ExtName) \
1119 "The atomic float instruction requires the following SPIR-V " \
1120 "extension: SPV_EXT_shader_atomic_float" ExtName
1121static void AddAtomicVectorFloatRequirements(
const MachineInstr &
MI,
1125 MI.getMF()->getRegInfo().getVRegDef(
MI.getOperand(1).getReg());
1128 if (Rank != 2 && Rank != 4)
1130 "must be a 2-component or 4 component vector");
1135 if (EltTypeDef->
getOpcode() != SPIRV::OpTypeFloat ||
1138 "The element type for the result type of an atomic vector float "
1139 "instruction must be a 16-bit floating-point scalar");
1141 if (isBFloat16Type(EltTypeDef))
1143 "The element type for the result type of an atomic vector float "
1144 "instruction cannot be a bfloat16 scalar");
1145 if (!
ST.canUseExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector))
1147 "The atomic float16 vector instruction requires the following SPIR-V "
1148 "extension: SPV_NV_shader_atomic_fp16_vector");
1150 Reqs.
addExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector);
1151 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16VectorNV);
1158 "Expect register operand in atomic float instruction");
1159 Register TypeReg =
MI.getOperand(1).getReg();
1162 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
1163 return AddAtomicVectorFloatRequirements(
MI, Reqs, ST);
1165 if (TypeDef->
getOpcode() != SPIRV::OpTypeFloat)
1167 "floating-point type scalar");
1170 unsigned Op =
MI.getOpcode();
1171 if (
Op == SPIRV::OpAtomicFAddEXT) {
1172 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add))
1174 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
1177 if (isBFloat16Type(TypeDef)) {
1178 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1180 "The atomic bfloat16 instruction requires the following SPIR-V "
1181 "extension: SPV_INTEL_16bit_atomics",
1183 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1184 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16AddINTEL);
1186 if (!
ST.canUseExtension(
1187 SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
1189 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
1201 "Unexpected floating-point type width in atomic float instruction");
1204 if (!
ST.canUseExtension(
1205 SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max))
1207 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
1210 if (isBFloat16Type(TypeDef)) {
1211 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1213 "The atomic bfloat16 instruction requires the following SPIR-V "
1214 "extension: SPV_INTEL_16bit_atomics",
1216 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1217 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16MinMaxINTEL);
1219 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
1223 Reqs.
addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
1226 Reqs.
addCapability(SPIRV::Capability::AtomicFloat64MinMaxEXT);
1230 "Unexpected floating-point type width in atomic float instruction");
1236 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1240 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
1244 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1248 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
1252 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1256 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
1260 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1264 return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
1268 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1272 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
1275bool isCombinedImageSampler(
MachineInstr *SampledImageInst) {
1276 if (SampledImageInst->
getOpcode() != SPIRV::OpTypeSampledImage)
1282 return isSampledImage(ImageInst);
1287 if (
MI.getOpcode() != SPIRV::OpDecorate)
1291 if (Dec == SPIRV::Decoration::NonUniformEXT)
1309 if (
StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
1310 StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
1311 StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
1316 hasNonUniformDecoration(
Instr.getOperand(0).getReg(), MRI);
1318 auto FirstIndexReg =
Instr.getOperand(3).getReg();
1319 bool FirstIndexIsConstant =
1322 if (
StorageClass == SPIRV::StorageClass::StorageClass::StorageBuffer) {
1325 SPIRV::Capability::StorageBufferArrayNonUniformIndexingEXT);
1326 else if (!FirstIndexIsConstant)
1328 SPIRV::Capability::StorageBufferArrayDynamicIndexing);
1334 if (PointeeType->
getOpcode() != SPIRV::OpTypeImage &&
1335 PointeeType->
getOpcode() != SPIRV::OpTypeSampledImage &&
1336 PointeeType->
getOpcode() != SPIRV::OpTypeSampler) {
1340 if (isUniformTexelBuffer(PointeeType)) {
1343 SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1344 else if (!FirstIndexIsConstant)
1346 SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
1347 }
else if (isInputAttachment(PointeeType)) {
1350 SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1351 else if (!FirstIndexIsConstant)
1353 SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
1354 }
else if (isStorageTexelBuffer(PointeeType)) {
1357 SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1358 else if (!FirstIndexIsConstant)
1360 SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
1361 }
else if (isSampledImage(PointeeType) ||
1362 isCombinedImageSampler(PointeeType) ||
1363 PointeeType->
getOpcode() == SPIRV::OpTypeSampler) {
1366 SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1367 else if (!FirstIndexIsConstant)
1369 SPIRV::Capability::SampledImageArrayDynamicIndexing);
1370 }
else if (isStorageImage(PointeeType)) {
1373 SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1374 else if (!FirstIndexIsConstant)
1376 SPIRV::Capability::StorageImageArrayDynamicIndexing);
1380static bool isImageTypeWithUnknownFormat(
SPIRVTypeInst TypeInst) {
1381 if (TypeInst->
getOpcode() != SPIRV::OpTypeImage)
1390 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product))
1391 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_integer_dot_product);
1395 assert(
MI.getOperand(2).isReg() &&
"Unexpected operand in dot");
1399 assert(
Input->getOperand(1).isReg() &&
"Unexpected operand in dot input");
1403 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1405 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8BitPacked);
1406 }
else if (TypeDef->
getOpcode() == SPIRV::OpTypeVector) {
1412 "Dot operand of 8-bit integer type requires 4 components");
1413 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8Bit);
1428 unsigned AddrSpace = ASOp.
getImm();
1429 if (AddrSpace != SPIRV::StorageClass::UniformConstant) {
1430 if (!
ST.canUseExtension(
1432 SPV_EXT_relaxed_printf_string_address_space)) {
1434 "required because printf uses a format string not "
1435 "in constant address space.",
1439 SPIRV::Extension::SPV_EXT_relaxed_printf_string_address_space);
1448 if (
MI.getNumOperands() <=
OpIdx)
1452 if (Mask & (1U <<
I))
1461 unsigned Op =
MI.getOpcode();
1463 case SPIRV::OpMemoryModel: {
1464 int64_t Addr =
MI.getOperand(0).getImm();
1467 int64_t Mem =
MI.getOperand(1).getImm();
1472 case SPIRV::OpEntryPoint: {
1473 int64_t
Exe =
MI.getOperand(0).getImm();
1478 case SPIRV::OpExecutionMode:
1479 case SPIRV::OpExecutionModeId: {
1480 int64_t
Exe =
MI.getOperand(1).getImm();
1485 case SPIRV::OpTypeMatrix:
1488 case SPIRV::OpTypeInt: {
1489 unsigned BitWidth =
MI.getOperand(1).getImm();
1497 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1501 if (!
ST.canUseExtension(
1502 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers))
1504 "OpTypeInt type with a width other than 8, 16, 32 or 64 bits "
1505 "requires the following SPIR-V extension: "
1506 "SPV_ALTERA_arbitrary_precision_integers");
1508 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
1509 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
1513 case SPIRV::OpDot: {
1516 if (isBFloat16Type(TypeDef))
1517 Reqs.
addCapability(SPIRV::Capability::BFloat16DotProductKHR);
1520 case SPIRV::OpTypeFloat: {
1521 unsigned BitWidth =
MI.getOperand(1).getImm();
1525 if (isBFloat16Type(&
MI)) {
1526 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bfloat16))
1528 "following SPIR-V extension: SPV_KHR_bfloat16",
1538 case SPIRV::OpTypeVector: {
1539 unsigned NumComponents =
MI.getOperand(2).getImm();
1540 if (NumComponents == 8 || NumComponents == 16)
1546 if (ElemTypeDef->
getOpcode() == SPIRV::OpTypePointer &&
1547 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
1548 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter);
1549 Reqs.
addCapability(SPIRV::Capability::MaskedGatherScatterINTEL);
1553 case SPIRV::OpTypePointer: {
1554 auto SC =
MI.getOperand(1).getImm();
1565 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1570 case SPIRV::OpExtInst: {
1571 if (
MI.getOperand(2).getImm() ==
1572 static_cast<int64_t
>(
1573 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1574 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1577 if (
MI.getOperand(3).getImm() ==
1578 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1579 addPrintfRequirements(
MI, Reqs, ST);
1586 case SPIRV::OpAliasDomainDeclINTEL:
1587 case SPIRV::OpAliasScopeDeclINTEL:
1588 case SPIRV::OpAliasScopeListDeclINTEL: {
1589 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1590 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1593 case SPIRV::OpBitReverse:
1594 case SPIRV::OpBitFieldInsert:
1595 case SPIRV::OpBitFieldSExtract:
1596 case SPIRV::OpBitFieldUExtract:
1597 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1601 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1604 case SPIRV::OpTypeRuntimeArray:
1607 case SPIRV::OpTypeOpaque:
1608 case SPIRV::OpTypeEvent:
1611 case SPIRV::OpTypePipe:
1612 case SPIRV::OpTypeReserveId:
1615 case SPIRV::OpTypeDeviceEvent:
1616 case SPIRV::OpTypeQueue:
1617 case SPIRV::OpBuildNDRange:
1620 case SPIRV::OpDecorate:
1621 case SPIRV::OpDecorateId:
1622 case SPIRV::OpDecorateString:
1623 addOpDecorateReqs(
MI, 1, Reqs, ST);
1625 case SPIRV::OpMemberDecorate:
1626 case SPIRV::OpMemberDecorateString:
1627 addOpDecorateReqs(
MI, 2, Reqs, ST);
1629 case SPIRV::OpInBoundsPtrAccessChain:
1632 case SPIRV::OpConstantSampler:
1635 case SPIRV::OpInBoundsAccessChain:
1636 case SPIRV::OpAccessChain:
1637 addOpAccessChainReqs(
MI, Reqs, ST);
1639 case SPIRV::OpTypeImage:
1640 addOpTypeImageReqs(
MI, Reqs, ST);
1642 case SPIRV::OpTypeSampler:
1643 if (!
ST.isShader()) {
1647 case SPIRV::OpTypeForwardPointer:
1651 case SPIRV::OpAtomicFlagTestAndSet:
1652 case SPIRV::OpAtomicLoad:
1653 case SPIRV::OpAtomicStore:
1654 case SPIRV::OpAtomicExchange:
1655 case SPIRV::OpAtomicCompareExchange:
1656 case SPIRV::OpAtomicIIncrement:
1657 case SPIRV::OpAtomicIDecrement:
1658 case SPIRV::OpAtomicIAdd:
1659 case SPIRV::OpAtomicISub:
1660 case SPIRV::OpAtomicUMin:
1661 case SPIRV::OpAtomicUMax:
1662 case SPIRV::OpAtomicSMin:
1663 case SPIRV::OpAtomicSMax:
1664 case SPIRV::OpAtomicAnd:
1665 case SPIRV::OpAtomicOr:
1666 case SPIRV::OpAtomicXor: {
1669 if (
Op == SPIRV::OpAtomicStore) {
1672 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1678 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1683 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1685 "16-bit integer atomic operations require the following SPIR-V "
1686 "extension: SPV_INTEL_16bit_atomics",
1688 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1690 case SPIRV::OpAtomicLoad:
1691 case SPIRV::OpAtomicStore:
1692 case SPIRV::OpAtomicExchange:
1693 case SPIRV::OpAtomicCompareExchange:
1694 case SPIRV::OpAtomicCompareExchangeWeak:
1696 SPIRV::Capability::AtomicInt16CompareExchangeINTEL);
1703 }
else if (isBFloat16Type(TypeDef)) {
1704 if (
is_contained({SPIRV::OpAtomicLoad, SPIRV::OpAtomicStore,
1705 SPIRV::OpAtomicExchange},
1707 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1709 "The atomic bfloat16 instruction requires the following SPIR-V "
1710 "extension: SPV_INTEL_16bit_atomics",
1712 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1713 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16LoadStoreINTEL);
1718 case SPIRV::OpGroupNonUniformIAdd:
1719 case SPIRV::OpGroupNonUniformFAdd:
1720 case SPIRV::OpGroupNonUniformIMul:
1721 case SPIRV::OpGroupNonUniformFMul:
1722 case SPIRV::OpGroupNonUniformSMin:
1723 case SPIRV::OpGroupNonUniformUMin:
1724 case SPIRV::OpGroupNonUniformFMin:
1725 case SPIRV::OpGroupNonUniformSMax:
1726 case SPIRV::OpGroupNonUniformUMax:
1727 case SPIRV::OpGroupNonUniformFMax:
1728 case SPIRV::OpGroupNonUniformBitwiseAnd:
1729 case SPIRV::OpGroupNonUniformBitwiseOr:
1730 case SPIRV::OpGroupNonUniformBitwiseXor:
1731 case SPIRV::OpGroupNonUniformLogicalAnd:
1732 case SPIRV::OpGroupNonUniformLogicalOr:
1733 case SPIRV::OpGroupNonUniformLogicalXor: {
1735 int64_t GroupOp =
MI.getOperand(3).getImm();
1737 case SPIRV::GroupOperation::Reduce:
1738 case SPIRV::GroupOperation::InclusiveScan:
1739 case SPIRV::GroupOperation::ExclusiveScan:
1740 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1742 case SPIRV::GroupOperation::ClusteredReduce:
1743 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1745 case SPIRV::GroupOperation::PartitionedReduceNV:
1746 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1747 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1748 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1753 case SPIRV::OpGroupNonUniformQuadSwap:
1756 case SPIRV::OpImageQueryLod:
1759 case SPIRV::OpImageQuerySize:
1760 case SPIRV::OpImageQuerySizeLod:
1761 case SPIRV::OpImageQueryLevels:
1762 case SPIRV::OpImageQuerySamples:
1766 case SPIRV::OpImageQueryFormat: {
1767 Register ResultReg =
MI.getOperand(0).getReg();
1769 static const unsigned CompareOps[] = {
1770 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1771 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1772 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1773 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1774 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1776 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1777 if (ImmVal == 4323 || ImmVal == 4324) {
1778 if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1779 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1782 "SPV_EXT_image_raw10_raw12 extension");
1787 unsigned Opc = UseInst.getOpcode();
1789 if (
Opc == SPIRV::OpSwitch) {
1792 CheckAndAddExtension(
Op.getImm());
1794 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1797 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1800 CheckAndAddExtension(ImmVal);
1808 case SPIRV::OpGroupNonUniformShuffle:
1809 case SPIRV::OpGroupNonUniformShuffleXor:
1810 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1812 case SPIRV::OpGroupNonUniformShuffleUp:
1813 case SPIRV::OpGroupNonUniformShuffleDown:
1814 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1816 case SPIRV::OpGroupAll:
1817 case SPIRV::OpGroupAny:
1818 case SPIRV::OpGroupBroadcast:
1819 case SPIRV::OpGroupIAdd:
1820 case SPIRV::OpGroupFAdd:
1821 case SPIRV::OpGroupFMin:
1822 case SPIRV::OpGroupUMin:
1823 case SPIRV::OpGroupSMin:
1824 case SPIRV::OpGroupFMax:
1825 case SPIRV::OpGroupUMax:
1826 case SPIRV::OpGroupSMax:
1829 case SPIRV::OpGroupNonUniformElect:
1832 case SPIRV::OpGroupNonUniformAll:
1833 case SPIRV::OpGroupNonUniformAny:
1834 case SPIRV::OpGroupNonUniformAllEqual:
1837 case SPIRV::OpGroupNonUniformBroadcast:
1838 case SPIRV::OpGroupNonUniformBroadcastFirst:
1839 case SPIRV::OpGroupNonUniformBallot:
1840 case SPIRV::OpGroupNonUniformInverseBallot:
1841 case SPIRV::OpGroupNonUniformBallotBitExtract:
1842 case SPIRV::OpGroupNonUniformBallotBitCount:
1843 case SPIRV::OpGroupNonUniformBallotFindLSB:
1844 case SPIRV::OpGroupNonUniformBallotFindMSB:
1845 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1847 case SPIRV::OpSubgroupShuffleINTEL:
1848 case SPIRV::OpSubgroupShuffleDownINTEL:
1849 case SPIRV::OpSubgroupShuffleUpINTEL:
1850 case SPIRV::OpSubgroupShuffleXorINTEL:
1851 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1852 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1853 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1856 case SPIRV::OpSubgroupBlockReadINTEL:
1857 case SPIRV::OpSubgroupBlockWriteINTEL:
1858 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1859 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1860 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1863 case SPIRV::OpSubgroupImageBlockReadINTEL:
1864 case SPIRV::OpSubgroupImageBlockWriteINTEL:
1865 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1866 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1867 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
1870 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
1871 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
1872 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
1873 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
1874 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
1877 case SPIRV::OpAssumeTrueKHR:
1878 case SPIRV::OpExpectKHR:
1879 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
1880 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
1884 case SPIRV::OpFmaKHR:
1885 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
1890 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
1891 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
1892 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
1893 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
1894 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
1897 case SPIRV::OpConstantFunctionPointerINTEL:
1898 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1899 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1900 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1903 case SPIRV::OpGroupNonUniformRotateKHR:
1904 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
1906 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
1908 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
1909 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
1912 case SPIRV::OpFixedCosALTERA:
1913 case SPIRV::OpFixedSinALTERA:
1914 case SPIRV::OpFixedCosPiALTERA:
1915 case SPIRV::OpFixedSinPiALTERA:
1916 case SPIRV::OpFixedExpALTERA:
1917 case SPIRV::OpFixedLogALTERA:
1918 case SPIRV::OpFixedRecipALTERA:
1919 case SPIRV::OpFixedSqrtALTERA:
1920 case SPIRV::OpFixedSinCosALTERA:
1921 case SPIRV::OpFixedSinCosPiALTERA:
1922 case SPIRV::OpFixedRsqrtALTERA:
1923 if (!
ST.canUseExtension(
1924 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
1926 "following SPIR-V extension: "
1927 "SPV_ALTERA_arbitrary_precision_fixed_point",
1930 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
1931 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
1933 case SPIRV::OpGroupIMulKHR:
1934 case SPIRV::OpGroupFMulKHR:
1935 case SPIRV::OpGroupBitwiseAndKHR:
1936 case SPIRV::OpGroupBitwiseOrKHR:
1937 case SPIRV::OpGroupBitwiseXorKHR:
1938 case SPIRV::OpGroupLogicalAndKHR:
1939 case SPIRV::OpGroupLogicalOrKHR:
1940 case SPIRV::OpGroupLogicalXorKHR:
1941 if (
ST.canUseExtension(
1942 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
1943 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
1944 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
1947 case SPIRV::OpReadClockKHR:
1948 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
1950 "following SPIR-V extension: SPV_KHR_shader_clock",
1952 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
1955 case SPIRV::OpFunctionPointerCallINTEL:
1956 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1957 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1958 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1961 case SPIRV::OpAtomicFAddEXT:
1962 case SPIRV::OpAtomicFMinEXT:
1963 case SPIRV::OpAtomicFMaxEXT:
1964 AddAtomicFloatRequirements(
MI, Reqs, ST);
1966 case SPIRV::OpConvertBF16ToFINTEL:
1967 case SPIRV::OpConvertFToBF16INTEL:
1968 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
1969 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
1970 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
1973 case SPIRV::OpRoundFToTF32INTEL:
1974 if (
ST.canUseExtension(
1975 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
1976 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
1977 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
1980 case SPIRV::OpVariableLengthArrayINTEL:
1981 case SPIRV::OpSaveMemoryINTEL:
1982 case SPIRV::OpRestoreMemoryINTEL:
1983 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
1984 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
1985 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
1988 case SPIRV::OpAsmTargetINTEL:
1989 case SPIRV::OpAsmINTEL:
1990 case SPIRV::OpAsmCallINTEL:
1991 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
1992 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
1996 case SPIRV::OpTypeCooperativeMatrixKHR: {
1997 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1999 "OpTypeCooperativeMatrixKHR type requires the "
2000 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
2002 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2003 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2006 if (isBFloat16Type(TypeDef))
2007 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
2010 case SPIRV::OpArithmeticFenceEXT:
2011 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
2013 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
2015 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
2018 case SPIRV::OpControlBarrierArriveINTEL:
2019 case SPIRV::OpControlBarrierWaitINTEL:
2020 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
2021 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
2025 case SPIRV::OpCooperativeMatrixMulAddKHR: {
2026 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2028 "following SPIR-V extension: "
2029 "SPV_KHR_cooperative_matrix",
2031 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2032 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2033 constexpr unsigned MulAddMaxSize = 6;
2034 if (
MI.getNumOperands() != MulAddMaxSize)
2036 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
2038 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
2039 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2041 "require the following SPIR-V extension: "
2042 "SPV_INTEL_joint_matrix",
2044 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2046 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
2049 MatrixAAndBBFloat16ComponentsINTEL ||
2051 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
2053 MatrixResultBFloat16ComponentsINTEL) {
2054 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2056 "require the following SPIR-V extension: "
2057 "SPV_INTEL_joint_matrix",
2059 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2061 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
2065 case SPIRV::OpCooperativeMatrixLoadKHR:
2066 case SPIRV::OpCooperativeMatrixStoreKHR:
2067 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2068 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2069 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
2070 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2072 "following SPIR-V extension: "
2073 "SPV_KHR_cooperative_matrix",
2075 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2076 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2080 std::unordered_map<unsigned, unsigned> LayoutToInstMap = {
2081 {SPIRV::OpCooperativeMatrixLoadKHR, 3},
2082 {SPIRV::OpCooperativeMatrixStoreKHR, 2},
2083 {SPIRV::OpCooperativeMatrixLoadCheckedINTEL, 5},
2084 {SPIRV::OpCooperativeMatrixStoreCheckedINTEL, 4},
2085 {SPIRV::OpCooperativeMatrixPrefetchINTEL, 4}};
2087 const unsigned LayoutNum = LayoutToInstMap[
Op];
2088 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
2091 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
2094 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
2095 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2097 "extension: SPV_INTEL_joint_matrix",
2099 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2100 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2105 if (
Op == SPIRV::OpCooperativeMatrixLoadKHR ||
2106 Op == SPIRV::OpCooperativeMatrixStoreKHR)
2109 std::string InstName;
2111 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2112 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2114 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2115 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2117 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2118 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2122 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2123 const std::string ErrorMsg =
2124 InstName +
" instruction requires the "
2125 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2128 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2129 if (
Op == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2130 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2134 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2137 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2138 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2140 "instructions require the following SPIR-V extension: "
2141 "SPV_INTEL_joint_matrix",
2143 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2145 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2147 case SPIRV::OpReadPipeBlockingALTERA:
2148 case SPIRV::OpWritePipeBlockingALTERA:
2149 if (
ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2150 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2154 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2155 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2157 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2159 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2161 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2163 case SPIRV::OpConvertHandleToImageINTEL:
2164 case SPIRV::OpConvertHandleToSamplerINTEL:
2165 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2166 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2168 "instructions require the following SPIR-V extension: "
2169 "SPV_INTEL_bindless_images",
2172 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2174 if (
Op == SPIRV::OpConvertHandleToImageINTEL &&
2175 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2177 "OpConvertHandleToImageINTEL",
2179 }
else if (
Op == SPIRV::OpConvertHandleToSamplerINTEL &&
2180 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2182 "OpConvertHandleToSamplerINTEL",
2184 }
else if (
Op == SPIRV::OpConvertHandleToSampledImageINTEL &&
2185 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2187 "OpConvertHandleToSampledImageINTEL",
2192 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2193 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2195 "Parameter value must be a 32-bit scalar in case of "
2196 "Physical32 addressing model or a 64-bit scalar in case of "
2197 "Physical64 addressing model",
2200 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2204 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2205 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2206 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2207 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2208 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2209 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2211 "Prefetch/Store]INTEL instructions require the "
2212 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2214 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2215 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2217 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2218 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2221 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2222 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2227 case SPIRV::OpKill: {
2230 case SPIRV::OpDemoteToHelperInvocation:
2231 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2233 if (
ST.canUseExtension(
2234 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2237 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2242 case SPIRV::OpSUDot:
2243 case SPIRV::OpSDotAccSat:
2244 case SPIRV::OpUDotAccSat:
2245 case SPIRV::OpSUDotAccSat:
2246 AddDotProductRequirements(
MI, Reqs, ST);
2248 case SPIRV::OpImageSampleImplicitLod:
2250 addImageOperandReqs(
MI, Reqs, ST, 4);
2252 case SPIRV::OpImageSampleExplicitLod:
2253 addImageOperandReqs(
MI, Reqs, ST, 4);
2255 case SPIRV::OpImageSampleDrefImplicitLod:
2257 addImageOperandReqs(
MI, Reqs, ST, 5);
2259 case SPIRV::OpImageSampleDrefExplicitLod:
2261 addImageOperandReqs(
MI, Reqs, ST, 5);
2263 case SPIRV::OpImageFetch:
2265 addImageOperandReqs(
MI, Reqs, ST, 4);
2267 case SPIRV::OpImageDrefGather:
2268 case SPIRV::OpImageGather:
2270 addImageOperandReqs(
MI, Reqs, ST, 5);
2272 case SPIRV::OpImageRead: {
2273 Register ImageReg =
MI.getOperand(2).getReg();
2282 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2283 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2286 case SPIRV::OpImageWrite: {
2287 Register ImageReg =
MI.getOperand(0).getReg();
2296 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2297 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2300 case SPIRV::OpTypeStructContinuedINTEL:
2301 case SPIRV::OpConstantCompositeContinuedINTEL:
2302 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2303 case SPIRV::OpCompositeConstructContinuedINTEL: {
2304 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2306 "Continued instructions require the "
2307 "following SPIR-V extension: SPV_INTEL_long_composites",
2309 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2313 case SPIRV::OpArbitraryFloatEQALTERA:
2314 case SPIRV::OpArbitraryFloatGEALTERA:
2315 case SPIRV::OpArbitraryFloatGTALTERA:
2316 case SPIRV::OpArbitraryFloatLEALTERA:
2317 case SPIRV::OpArbitraryFloatLTALTERA:
2318 case SPIRV::OpArbitraryFloatCbrtALTERA:
2319 case SPIRV::OpArbitraryFloatCosALTERA:
2320 case SPIRV::OpArbitraryFloatCosPiALTERA:
2321 case SPIRV::OpArbitraryFloatExp10ALTERA:
2322 case SPIRV::OpArbitraryFloatExp2ALTERA:
2323 case SPIRV::OpArbitraryFloatExpALTERA:
2324 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2325 case SPIRV::OpArbitraryFloatHypotALTERA:
2326 case SPIRV::OpArbitraryFloatLog10ALTERA:
2327 case SPIRV::OpArbitraryFloatLog1pALTERA:
2328 case SPIRV::OpArbitraryFloatLog2ALTERA:
2329 case SPIRV::OpArbitraryFloatLogALTERA:
2330 case SPIRV::OpArbitraryFloatRecipALTERA:
2331 case SPIRV::OpArbitraryFloatSinCosALTERA:
2332 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2333 case SPIRV::OpArbitraryFloatSinALTERA:
2334 case SPIRV::OpArbitraryFloatSinPiALTERA:
2335 case SPIRV::OpArbitraryFloatSqrtALTERA:
2336 case SPIRV::OpArbitraryFloatACosALTERA:
2337 case SPIRV::OpArbitraryFloatACosPiALTERA:
2338 case SPIRV::OpArbitraryFloatAddALTERA:
2339 case SPIRV::OpArbitraryFloatASinALTERA:
2340 case SPIRV::OpArbitraryFloatASinPiALTERA:
2341 case SPIRV::OpArbitraryFloatATan2ALTERA:
2342 case SPIRV::OpArbitraryFloatATanALTERA:
2343 case SPIRV::OpArbitraryFloatATanPiALTERA:
2344 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2345 case SPIRV::OpArbitraryFloatCastALTERA:
2346 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2347 case SPIRV::OpArbitraryFloatDivALTERA:
2348 case SPIRV::OpArbitraryFloatMulALTERA:
2349 case SPIRV::OpArbitraryFloatPowALTERA:
2350 case SPIRV::OpArbitraryFloatPowNALTERA:
2351 case SPIRV::OpArbitraryFloatPowRALTERA:
2352 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2353 case SPIRV::OpArbitraryFloatSubALTERA: {
2354 if (!
ST.canUseExtension(
2355 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2357 "Floating point instructions can't be translated correctly without "
2358 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2361 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2363 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2366 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2367 if (!
ST.canUseExtension(
2368 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2370 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2372 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2375 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2377 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2380 case SPIRV::OpBitwiseFunctionINTEL: {
2381 if (!
ST.canUseExtension(
2382 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2384 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2385 "extension: SPV_INTEL_ternary_bitwise_function",
2387 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2388 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2391 case SPIRV::OpCopyMemorySized: {
2396 case SPIRV::OpPredicatedLoadINTEL:
2397 case SPIRV::OpPredicatedStoreINTEL: {
2398 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2400 "OpPredicated[Load/Store]INTEL instructions require "
2401 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2403 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2407 case SPIRV::OpFAddS:
2408 case SPIRV::OpFSubS:
2409 case SPIRV::OpFMulS:
2410 case SPIRV::OpFDivS:
2411 case SPIRV::OpFRemS:
2413 case SPIRV::OpFNegate:
2414 case SPIRV::OpFAddV:
2415 case SPIRV::OpFSubV:
2416 case SPIRV::OpFMulV:
2417 case SPIRV::OpFDivV:
2418 case SPIRV::OpFRemV:
2419 case SPIRV::OpFNegateV: {
2422 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2424 if (isBFloat16Type(TypeDef)) {
2425 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2427 "Arithmetic instructions with bfloat16 arguments require the "
2428 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2430 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2431 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2435 case SPIRV::OpOrdered:
2436 case SPIRV::OpUnordered:
2437 case SPIRV::OpFOrdEqual:
2438 case SPIRV::OpFOrdNotEqual:
2439 case SPIRV::OpFOrdLessThan:
2440 case SPIRV::OpFOrdLessThanEqual:
2441 case SPIRV::OpFOrdGreaterThan:
2442 case SPIRV::OpFOrdGreaterThanEqual:
2443 case SPIRV::OpFUnordEqual:
2444 case SPIRV::OpFUnordNotEqual:
2445 case SPIRV::OpFUnordLessThan:
2446 case SPIRV::OpFUnordLessThanEqual:
2447 case SPIRV::OpFUnordGreaterThan:
2448 case SPIRV::OpFUnordGreaterThanEqual: {
2452 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2454 if (isBFloat16Type(TypeDef)) {
2455 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2457 "Relational instructions with bfloat16 arguments require the "
2458 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2460 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2461 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2465 case SPIRV::OpDPdxCoarse:
2466 case SPIRV::OpDPdyCoarse:
2467 case SPIRV::OpDPdxFine:
2468 case SPIRV::OpDPdyFine: {
2472 case SPIRV::OpLoopControlINTEL: {
2473 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2474 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2486 SPIRV::Capability::Shader);
2498 addInstrRequirements(
MI, MAI, ST);
2501 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2503 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2504 RequireKHRFloatControls2 =
false,
2506 bool HasIntelFloatControls2 =
2507 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2508 bool HasKHRFloatControls2 =
2509 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2510 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2516 auto EM =
Const->getZExtValue();
2520 case SPIRV::ExecutionMode::DenormPreserve:
2521 case SPIRV::ExecutionMode::DenormFlushToZero:
2522 case SPIRV::ExecutionMode::RoundingModeRTE:
2523 case SPIRV::ExecutionMode::RoundingModeRTZ:
2524 RequireFloatControls = VerLower14;
2526 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2528 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2529 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2530 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2531 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2532 if (HasIntelFloatControls2) {
2533 RequireIntelFloatControls2 =
true;
2535 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2538 case SPIRV::ExecutionMode::FPFastMathDefault: {
2539 if (HasKHRFloatControls2) {
2540 RequireKHRFloatControls2 =
true;
2542 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2546 case SPIRV::ExecutionMode::ContractionOff:
2547 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2548 if (HasKHRFloatControls2) {
2549 RequireKHRFloatControls2 =
true;
2551 SPIRV::OperandCategory::ExecutionModeOperand,
2552 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2555 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2560 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2565 if (RequireFloatControls &&
2566 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2568 if (RequireIntelFloatControls2)
2570 if (RequireKHRFloatControls2)
2574 if (
F.isDeclaration())
2576 if (
F.getMetadata(
"reqd_work_group_size"))
2578 SPIRV::OperandCategory::ExecutionModeOperand,
2579 SPIRV::ExecutionMode::LocalSize, ST);
2580 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2582 SPIRV::OperandCategory::ExecutionModeOperand,
2583 SPIRV::ExecutionMode::LocalSize, ST);
2585 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2588 if (
F.getMetadata(
"work_group_size_hint"))
2590 SPIRV::OperandCategory::ExecutionModeOperand,
2591 SPIRV::ExecutionMode::LocalSizeHint, ST);
2592 if (
F.getMetadata(
"intel_reqd_sub_group_size"))
2594 SPIRV::OperandCategory::ExecutionModeOperand,
2595 SPIRV::ExecutionMode::SubgroupSize, ST);
2596 if (
F.getMetadata(
"max_work_group_size"))
2598 SPIRV::OperandCategory::ExecutionModeOperand,
2599 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2600 if (
F.getMetadata(
"vec_type_hint"))
2602 SPIRV::OperandCategory::ExecutionModeOperand,
2603 SPIRV::ExecutionMode::VecTypeHint, ST);
2605 if (
F.hasOptNone()) {
2606 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2609 }
else if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2619 unsigned Flags = SPIRV::FPFastMathMode::None;
2620 bool CanUseKHRFloatControls2 =
2621 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2623 Flags |= SPIRV::FPFastMathMode::NotNaN;
2625 Flags |= SPIRV::FPFastMathMode::NotInf;
2627 Flags |= SPIRV::FPFastMathMode::NSZ;
2629 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2631 Flags |= SPIRV::FPFastMathMode::AllowContract;
2633 if (CanUseKHRFloatControls2)
2641 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2642 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2643 SPIRV::FPFastMathMode::AllowTransform |
2644 SPIRV::FPFastMathMode::AllowReassoc |
2645 SPIRV::FPFastMathMode::AllowContract;
2647 Flags |= SPIRV::FPFastMathMode::Fast;
2650 if (CanUseKHRFloatControls2) {
2652 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2653 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2658 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2659 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2660 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2661 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2662 "AllowContract flags to be enabled as well.");
2673 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2676static void handleMIFlagDecoration(
2681 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2682 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2685 SPIRV::Decoration::NoSignedWrap, {});
2688 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2689 SPIRV::Decoration::NoUnsignedWrap, ST,
2693 SPIRV::Decoration::NoUnsignedWrap, {});
2698 TII.canUseFastMathFlags(
2699 I,
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) ||
2700 (
ST.isKernel() &&
I.getOpcode() == SPIRV::OpExtInst);
2704 unsigned FMFlags = getFastMathFlags(
I, ST);
2705 if (FMFlags == SPIRV::FPFastMathMode::None) {
2708 if (FPFastMathDefaultInfoVec.
empty())
2724 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2725 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2726 ?
I.getOperand(1).getReg()
2727 :
I.getOperand(2).getReg();
2735 if (Ty == Elem.Ty) {
2736 FMFlags = Elem.FastMathFlags;
2737 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2738 Elem.FPFastMathDefault;
2743 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2746 if (isFastMathModeAvailable(ST)) {
2747 Register DstReg =
I.getOperand(0).getReg();
2763 for (
auto &
MBB : *MF)
2764 for (
auto &
MI :
MBB)
2765 handleMIFlagDecoration(
MI, ST,
TII, MAI.
Reqs, GR,
2782 for (
auto &
MBB : *MF) {
2783 if (!
MBB.hasName() ||
MBB.empty())
2802 for (
auto &
MBB : *MF) {
2804 MI.setDesc(
TII.get(SPIRV::OpPhi));
2807 MI.insert(
MI.operands_begin() + 1,
2808 {MachineOperand::CreateReg(ResTypeReg, false)});
2827 SPIRV::FPFastMathMode::None);
2829 SPIRV::FPFastMathMode::None);
2831 SPIRV::FPFastMathMode::None);
2838 size_t BitWidth = Ty->getScalarSizeInBits();
2842 assert(Index >= 0 && Index < 3 &&
2843 "Expected FPFastMathDefaultInfo for half, float, or double");
2844 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2845 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2846 return FPFastMathDefaultInfoVec[Index];
2849static void collectFPFastMathDefaults(
const Module &M,
2852 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
2861 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2865 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2874 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
2876 "Expected 4 operands for FPFastMathDefault");
2887 Info.FastMathFlags = Flags;
2888 Info.FPFastMathDefault =
true;
2889 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
2891 "Expected no operands for ContractionOff");
2898 Info.ContractionOff =
true;
2900 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
2902 "Expected 1 operand for SignedZeroInfNanPreserve");
2903 unsigned TargetWidth =
2912 assert(Index >= 0 && Index < 3 &&
2913 "Expected FPFastMathDefaultInfo for half, float, or double");
2914 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2915 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2916 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
2927 SPIRVTargetMachine &TM =
2931 TII = ST->getInstrInfo();
2937 patchPhis(M, GR, *TII, MMI);
2939 addMBBNames(M, *TII, MMI, *ST,
MAI);
2940 collectFPFastMathDefaults(M,
MAI, *ST);
2941 addDecorations(M, *TII, MMI, *ST,
MAI, GR);
2943 collectReqs(M,
MAI, MMI, *ST);
2947 collectReqs(M,
MAI, MMI, *ST);
2948 collectDeclarations(M);
2951 numberRegistersGlobally(M);
2954 processOtherInstrs(M);
2958 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
2961 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