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 Func.getContext().diagnose(
67 unsigned DefaultVal = 0) {
68 if (MdNode && OpIndex < MdNode->getNumOperands()) {
82 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
84 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
89 bool MinVerOK = SPIRVVersion.
empty() || SPIRVVersion >= ReqMinVer;
91 ReqMaxVer.
empty() || SPIRVVersion.
empty() || SPIRVVersion <= ReqMaxVer;
94 if (ReqCaps.
empty()) {
95 if (ReqExts.
empty()) {
96 if (MinVerOK && MaxVerOK)
97 return {
true, {}, {}, ReqMinVer, ReqMaxVer};
100 }
else if (MinVerOK && MaxVerOK) {
101 if (ReqCaps.
size() == 1) {
102 auto Cap = ReqCaps[0];
105 SPIRV::OperandCategory::CapabilityOperand, Cap));
106 return {
true, {Cap}, std::move(ReqExts), ReqMinVer, ReqMaxVer};
116 for (
auto Cap : ReqCaps)
119 for (
size_t i = 0, Sz = UseCaps.
size(); i < Sz; ++i) {
120 auto Cap = UseCaps[i];
121 if (i == Sz - 1 || !AvoidCaps.
S.
contains(Cap)) {
123 SPIRV::OperandCategory::CapabilityOperand, Cap));
124 return {
true, {Cap}, std::move(ReqExts), ReqMinVer, ReqMaxVer};
132 if (
llvm::all_of(ReqExts, [&ST](
const SPIRV::Extension::Extension &Ext) {
133 return ST.canUseExtension(Ext);
144void SPIRVModuleAnalysis::setBaseInfo(
const Module &M) {
148 MAI.RegisterAliasTable.clear();
149 MAI.InstrsToDelete.clear();
150 MAI.GlobalObjMap.clear();
151 MAI.GlobalVarList.clear();
152 MAI.ExtInstSetMap.clear();
154 MAI.Reqs.initAvailableCapabilities(*ST);
157 if (
auto MemModel =
M.getNamedMetadata(
"spirv.MemoryModel")) {
158 auto MemMD = MemModel->getOperand(0);
159 MAI.Addr =
static_cast<SPIRV::AddressingModel::AddressingModel
>(
162 static_cast<SPIRV::MemoryModel::MemoryModel
>(
getMetadataUInt(MemMD, 1));
165 MAI.Mem = ST->isShader() ? SPIRV::MemoryModel::GLSL450
166 : SPIRV::MemoryModel::OpenCL;
167 if (
MAI.Mem == SPIRV::MemoryModel::OpenCL) {
168 unsigned PtrSize = ST->getPointerSize();
169 MAI.Addr = PtrSize == 32 ? SPIRV::AddressingModel::Physical32
170 : PtrSize == 64 ? SPIRV::AddressingModel::Physical64
171 : SPIRV::AddressingModel::Logical;
174 MAI.Addr = SPIRV::AddressingModel::Logical;
179 if (
auto VerNode =
M.getNamedMetadata(
"opencl.ocl.version")) {
180 MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_C;
183 assert(VerNode->getNumOperands() > 0 &&
"Invalid SPIR");
184 auto VersionMD = VerNode->getOperand(0);
190 (std::max(1U, MajorNum) * 100 + MinorNum) * 1000 + RevNum;
193 if (
auto *CxxVerNode =
M.getNamedMetadata(
"opencl.cxx.version")) {
194 assert(CxxVerNode->getNumOperands() > 0 &&
"Invalid SPIR");
195 auto *CxxMD = CxxVerNode->getOperand(0);
199 if ((
MAI.SrcLangVersion == 200000 && CxxVer == 100000) ||
200 (
MAI.SrcLangVersion == 300000 && CxxVer == 202100000)) {
201 MAI.SrcLang = SPIRV::SourceLanguage::CPP_for_OpenCL;
202 MAI.SrcLangVersion = CxxVer;
205 "opencl cxx version is not compatible with opencl c version!");
213 if (!ST->isShader()) {
214 MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_CPP;
215 MAI.SrcLangVersion = 100000;
217 MAI.SrcLang = SPIRV::SourceLanguage::Unknown;
218 MAI.SrcLangVersion = 0;
222 if (
auto ExtNode =
M.getNamedMetadata(
"opencl.used.extensions")) {
223 for (
unsigned I = 0,
E = ExtNode->getNumOperands();
I !=
E; ++
I) {
224 MDNode *MD = ExtNode->getOperand(
I);
234 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::MemoryModelOperand,
236 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::SourceLanguageOperand,
238 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::AddressingModelOperand,
241 if (
MAI.Mem == SPIRV::MemoryModel::VulkanKHR)
242 MAI.Reqs.addExtension(SPIRV::Extension::SPV_KHR_vulkan_memory_model);
244 if (!ST->isShader()) {
246 MAI.ExtInstSetMap[
static_cast<unsigned>(
247 SPIRV::InstructionSet::OpenCL_std)] =
MAI.getNextIDRegister();
258 if (
UseMI.getOpcode() != SPIRV::OpDecorate &&
259 UseMI.getOpcode() != SPIRV::OpMemberDecorate)
262 for (
unsigned I = 0;
I <
UseMI.getNumOperands(); ++
I) {
280 for (
unsigned i = 0; i <
MI.getNumOperands(); ++i) {
289 unsigned Opcode =
MI.getOpcode();
290 if ((Opcode == SPIRV::OpDecorate) && i >= 2) {
291 unsigned DecorationID =
MI.getOperand(1).getImm();
292 if (DecorationID != SPIRV::Decoration::FuncParamAttr &&
293 DecorationID != SPIRV::Decoration::UserSemantic &&
294 DecorationID != SPIRV::Decoration::CacheControlLoadINTEL &&
295 DecorationID != SPIRV::Decoration::CacheControlStoreINTEL)
301 if (!UseDefReg && MO.
isDef()) {
309 dbgs() <<
"Unexpectedly, no global id found for the operand ";
311 dbgs() <<
"\nInstruction: ";
337 unsigned Opcode =
MI.getOpcode();
339 case SPIRV::OpTypeForwardPointer:
342 case SPIRV::OpVariable:
343 return static_cast<SPIRV::StorageClass::StorageClass
>(
344 MI.getOperand(2).
getImm()) != SPIRV::StorageClass::Function;
345 case SPIRV::OpFunction:
346 case SPIRV::OpFunctionParameter:
349 if (GR->hasConstFunPtr() && Opcode == SPIRV::OpUndef) {
357 if (GR->getFunctionDefinitionByUse(&
MI.getOperand(0))) {
359 unsigned UseOp =
UseMI.getOpcode();
360 if (UseOp == SPIRV::OpConstantFunctionPointerINTEL ||
361 UseOp == SPIRV::OpEnqueueKernel) {
362 MAI.setSkipEmission(&
MI);
368 if (
UseMI.getOpcode() != SPIRV::OpConstantFunctionPointerINTEL)
374 MAI.setSkipEmission(&
MI);
378 return TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
379 TII->isInlineAsmDefInstr(
MI);
388void SPIRVModuleAnalysis::visitFunPtrUse(
391 std::map<const Value *, unsigned> &GlobalToGReg,
393 const MachineOperand *OpFunDef = GR->getFunctionDefinitionByUse(FunPtrOp);
396 const MachineInstr *OpDefMI = OpFunDef->
getParent();
399 const MachineRegisterInfo &FunDefMRI = FunDefMF->
getRegInfo();
401 visitDecl(FunDefMRI, SignatureToGReg, GlobalToGReg, FunDefMF, *OpDefMI);
403 }
while (OpDefMI && (OpDefMI->
getOpcode() == SPIRV::OpFunction ||
404 OpDefMI->
getOpcode() == SPIRV::OpFunctionParameter));
406 MCRegister GlobalFunDefReg =
407 MAI.getRegisterAlias(FunDefMF, OpFunDef->
getReg());
409 "Function definition must refer to a global register");
410 MAI.setRegisterAlias(MF, OpReg, GlobalFunDefReg);
415void SPIRVModuleAnalysis::visitDecl(
417 std::map<const Value *, unsigned> &GlobalToGReg,
const MachineFunction *MF,
419 unsigned Opcode =
MI.getOpcode();
422 for (
const MachineOperand &MO :
MI.operands()) {
423 if (!MO.isReg() || MO.isDef())
427 if (Opcode == SPIRV::OpConstantFunctionPointerINTEL &&
429 visitFunPtrUse(OpReg, &
MI.getOperand(2), SignatureToGReg, GlobalToGReg,
434 if (
MAI.hasRegisterAlias(MF, MO.getReg()))
438 if (isDeclSection(MRI, *OpDefMI))
439 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF, *OpDefMI);
445 dbgs() <<
"Unexpectedly, no unique definition for the operand ";
447 dbgs() <<
"\nInstruction: ";
452 "No unique definition is found for the virtual register");
456 bool IsFunDef =
false;
457 if (TII->isSpecConstantInstr(
MI)) {
458 GReg =
MAI.getNextIDRegister();
460 }
else if (Opcode == SPIRV::OpFunction ||
461 Opcode == SPIRV::OpFunctionParameter) {
462 GReg = handleFunctionOrParameter(MF,
MI, GlobalToGReg, IsFunDef);
463 }
else if (Opcode == SPIRV::OpTypeStruct ||
464 Opcode == SPIRV::OpConstantComposite) {
465 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
466 const MachineInstr *NextInstr =
MI.getNextNode();
468 ((Opcode == SPIRV::OpTypeStruct &&
469 NextInstr->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL) ||
470 (Opcode == SPIRV::OpConstantComposite &&
472 SPIRV::OpConstantCompositeContinuedINTEL))) {
473 MCRegister Tmp = handleTypeDeclOrConstant(*NextInstr, SignatureToGReg);
475 MAI.setSkipEmission(NextInstr);
478 }
else if (TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
479 TII->isInlineAsmDefInstr(
MI)) {
480 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
481 }
else if (Opcode == SPIRV::OpVariable) {
482 GReg = handleVariable(MF,
MI, GlobalToGReg);
485 dbgs() <<
"\nInstruction: ";
491 MAI.setRegisterAlias(MF,
MI.getOperand(0).getReg(), GReg);
493 MAI.setSkipEmission(&
MI);
496MCRegister SPIRVModuleAnalysis::handleFunctionOrParameter(
498 std::map<const Value *, unsigned> &GlobalToGReg,
bool &IsFunDef) {
499 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
500 assert(GObj &&
"Unregistered global definition");
504 assert(
F &&
"Expected a reference to a function or an argument");
505 IsFunDef = !
F->isDeclaration();
506 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
509 MCRegister GReg =
MAI.getNextIDRegister();
517SPIRVModuleAnalysis::handleTypeDeclOrConstant(
const MachineInstr &
MI,
520 auto [It,
Inserted] = SignatureToGReg.try_emplace(MISign);
523 MCRegister GReg =
MAI.getNextIDRegister();
529MCRegister SPIRVModuleAnalysis::handleVariable(
531 std::map<const Value *, unsigned> &GlobalToGReg) {
532 MAI.GlobalVarList.push_back(&
MI);
533 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
534 assert(GObj &&
"Unregistered global definition");
535 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
538 MCRegister GReg =
MAI.getNextIDRegister();
542 MAI.GlobalObjMap[GV] = GReg;
546void SPIRVModuleAnalysis::collectDeclarations(
const Module &M) {
548 std::map<const Value *, unsigned> GlobalToGReg;
549 for (
const Function &
F : M) {
550 MachineFunction *MF = MMI->getMachineFunction(
F);
553 const MachineRegisterInfo &MRI = MF->
getRegInfo();
554 unsigned PastHeader = 0;
555 for (MachineBasicBlock &
MBB : *MF) {
556 for (MachineInstr &
MI :
MBB) {
557 if (
MI.getNumOperands() == 0)
559 unsigned Opcode =
MI.getOpcode();
560 if (Opcode == SPIRV::OpFunction) {
561 if (PastHeader == 0) {
565 }
else if (Opcode == SPIRV::OpFunctionParameter) {
568 }
else if (PastHeader > 0) {
572 const MachineOperand &DefMO =
MI.getOperand(0);
574 case SPIRV::OpExtension:
575 MAI.Reqs.addExtension(SPIRV::Extension::Extension(DefMO.
getImm()));
576 MAI.setSkipEmission(&
MI);
578 case SPIRV::OpCapability:
579 MAI.Reqs.addCapability(SPIRV::Capability::Capability(DefMO.
getImm()));
580 MAI.setSkipEmission(&
MI);
585 if (DefMO.
isReg() && isDeclSection(MRI,
MI) &&
586 !
MAI.hasRegisterAlias(MF, DefMO.
getReg()))
587 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF,
MI);
591 if (Opcode == SPIRV::OpEnqueueKernel &&
MI.getNumOperands() > 8) {
592 const MachineOperand &InvokeMO =
MI.getOperand(8);
593 if (InvokeMO.
isReg()) {
595 if (!
MAI.hasRegisterAlias(MF, InvokeReg)) {
596 if (
const MachineInstr *
DefMI =
600 if (GR->getFunctionDefinitionByUse(FunPtrOp))
601 visitFunPtrUse(InvokeReg, FunPtrOp, SignatureToGReg,
620 if (
MI.getOpcode() == SPIRV::OpDecorate) {
622 auto Dec =
MI.getOperand(1).getImm();
623 if (Dec == SPIRV::Decoration::LinkageAttributes) {
624 auto Lnk =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
625 if (Lnk == SPIRV::LinkageType::Import) {
630 MAI.GlobalObjMap[ImportedFunc] =
631 MAI.getRegisterAlias(
MI.getMF(), Target);
634 }
else if (
MI.getOpcode() == SPIRV::OpFunction) {
637 MCRegister GlobalReg =
MAI.getRegisterAlias(
MI.getMF(),
Reg);
639 MAI.GlobalObjMap[
F] = GlobalReg;
651 auto FoundMI = IS.insert(std::move(MISign));
652 if (!FoundMI.second) {
653 if (
MI.getOpcode() == SPIRV::OpDecorate) {
655 "Decoration instructions must have at least 2 operands");
657 "Only OpDecorate instructions can be duplicates");
662 if (
MI.getOperand(1).getImm() != SPIRV::Decoration::FPFastMathMode)
668 assert(OrigMI->getNumOperands() ==
MI.getNumOperands() &&
669 "Original instruction must have the same number of operands");
671 OrigMI->getNumOperands() == 3 &&
672 "FPFastMathMode decoration must have 3 operands for OpDecorate");
673 unsigned OrigFlags = OrigMI->getOperand(2).getImm();
674 unsigned NewFlags =
MI.getOperand(2).getImm();
675 if (OrigFlags == NewFlags)
679 unsigned FinalFlags = OrigFlags | NewFlags;
681 <<
"Warning: Conflicting FPFastMathMode decoration flags "
683 << *OrigMI <<
"Original flags: " << OrigFlags
684 <<
", new flags: " << NewFlags
685 <<
". They will be merged on a best effort basis, but not "
686 "validated. Final flags: "
687 << FinalFlags <<
"\n";
694 assert(
false &&
"No original instruction found for the duplicate "
695 "OpDecorate, but we found one in IS.");
708void SPIRVModuleAnalysis::processOtherInstrs(
const Module &M) {
710 for (
const Function &
F : M) {
711 if (
F.isDeclaration())
713 MachineFunction *MF = MMI->getMachineFunction(
F);
716 for (MachineBasicBlock &
MBB : *MF)
717 for (MachineInstr &
MI :
MBB) {
718 if (
MAI.getSkipEmission(&
MI))
720 const unsigned OpCode =
MI.getOpcode();
721 if (OpCode == SPIRV::OpString) {
723 }
else if (OpCode == SPIRV::OpExtInst &&
MI.getOperand(2).isImm() &&
724 MI.getOperand(2).getImm() ==
725 SPIRV::InstructionSet::
726 NonSemantic_Shader_DebugInfo_100) {
733 MachineOperand Ins =
MI.getOperand(3);
734 namespace NS = SPIRV::NonSemanticExtInst;
735 static constexpr int64_t GlobalNonSemanticDITy[] = {
736 NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
737 NS::DebugTypeBasic, NS::DebugTypePointer};
738 bool IsGlobalDI =
false;
739 for (
unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
740 IsGlobalDI |= Ins.
getImm() == GlobalNonSemanticDITy[Idx];
743 }
else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
745 }
else if (OpCode == SPIRV::OpEntryPoint) {
747 }
else if (TII->isAliasingInstr(
MI)) {
749 }
else if (TII->isDecorationInstr(
MI)) {
751 collectFuncNames(
MI, &
F);
752 }
else if (TII->isConstantInstr(
MI)) {
756 }
else if (OpCode == SPIRV::OpFunction) {
757 collectFuncNames(
MI, &
F);
758 }
else if (OpCode == SPIRV::OpTypeForwardPointer) {
766 auto AliasingTier = [](
const MachineInstr *
MI) {
767 switch (
MI->getOpcode()) {
768 case SPIRV::OpAliasDomainDeclINTEL:
770 case SPIRV::OpAliasScopeDeclINTEL:
772 case SPIRV::OpAliasScopeListDeclINTEL:
779 [&](
const MachineInstr *
LHS,
const MachineInstr *
RHS) {
780 return AliasingTier(LHS) < AliasingTier(RHS);
787void SPIRVModuleAnalysis::numberRegistersGlobally(
const Module &M) {
788 for (
const Function &
F : M) {
789 if (
F.isDeclaration())
791 MachineFunction *MF = MMI->getMachineFunction(
F);
793 for (MachineBasicBlock &
MBB : *MF) {
794 for (MachineInstr &
MI :
MBB) {
795 for (MachineOperand &
Op :
MI.operands()) {
799 if (
MAI.hasRegisterAlias(MF,
Reg))
801 MCRegister NewReg =
MAI.getNextIDRegister();
802 MAI.setRegisterAlias(MF,
Reg, NewReg);
804 if (
MI.getOpcode() != SPIRV::OpExtInst)
806 auto Set =
MI.getOperand(2).getImm();
807 auto [It,
Inserted] =
MAI.ExtInstSetMap.try_emplace(Set);
809 It->second =
MAI.getNextIDRegister();
817 SPIRV::OperandCategory::OperandCategory Category,
uint32_t i,
822void SPIRV::RequirementHandler::recursiveAddCapabilities(
824 for (
const auto &Cap : ToPrune) {
828 recursiveAddCapabilities(ImplicitDecls);
833 for (
const auto &Cap : ToAdd) {
834 bool IsNewlyInserted = AllCaps.insert(Cap).second;
835 if (!IsNewlyInserted)
839 recursiveAddCapabilities(ImplicitDecls);
840 MinimalCaps.push_back(Cap);
849 if (Req.
Cap.has_value())
855 if (!MaxVersion.empty() && Req.
MinVer > MaxVersion) {
857 <<
" and <= " << MaxVersion <<
"\n");
861 if (MinVersion.empty() || Req.
MinVer > MinVersion)
866 if (!MinVersion.empty() && Req.
MaxVer < MinVersion) {
868 <<
" and >= " << MinVersion <<
"\n");
872 if (MaxVersion.empty() || Req.
MaxVer < MaxVersion)
880 bool IsSatisfiable =
true;
881 auto TargetVer = ST.getSPIRVVersion();
883 if (!MaxVersion.empty() && !TargetVer.empty() && MaxVersion < TargetVer) {
885 dbgs() <<
"Target SPIR-V version too high for required features\n"
886 <<
"Required max version: " << MaxVersion <<
" target version "
887 << TargetVer <<
"\n");
888 IsSatisfiable =
false;
891 if (!MinVersion.empty() && !TargetVer.empty() && MinVersion > TargetVer) {
892 LLVM_DEBUG(
dbgs() <<
"Target SPIR-V version too low for required features\n"
893 <<
"Required min version: " << MinVersion
894 <<
" target version " << TargetVer <<
"\n");
895 IsSatisfiable =
false;
898 if (!MinVersion.empty() && !MaxVersion.empty() && MinVersion > MaxVersion) {
901 <<
"Version is too low for some features and too high for others.\n"
902 <<
"Required SPIR-V min version: " << MinVersion
903 <<
" required SPIR-V max version " << MaxVersion <<
"\n");
904 IsSatisfiable =
false;
909 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
911 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
913 for (
auto Cap : MinimalCaps) {
914 if (AvailableCaps.contains(Cap) && !AvoidCaps.
S.
contains(Cap))
918 OperandCategory::CapabilityOperand, Cap)
920 IsSatisfiable =
false;
923 for (
auto Ext : AllExtensions) {
924 if (ST.canUseExtension(Ext))
928 OperandCategory::ExtensionOperand, Ext)
930 IsSatisfiable =
false;
939 for (
const auto Cap : ToAdd)
940 if (AvailableCaps.insert(Cap).second)
942 SPIRV::OperandCategory::CapabilityOperand, Cap));
946 const Capability::Capability
ToRemove,
947 const Capability::Capability IfPresent) {
948 if (AllCaps.contains(IfPresent)) {
958 addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8,
963 Capability::GroupNonUniformVote,
964 Capability::GroupNonUniformArithmetic,
965 Capability::GroupNonUniformBallot,
966 Capability::GroupNonUniformClustered,
967 Capability::GroupNonUniformShuffle,
968 Capability::GroupNonUniformShuffleRelative,
969 Capability::GroupNonUniformQuad});
973 Capability::DotProductInput4x8Bit,
974 Capability::DotProductInput4x8BitPacked,
975 Capability::DemoteToHelperInvocation});
978 for (
auto Extension : ST.getAllAvailableExtensions()) {
984 if (!ST.isShader()) {
985 initAvailableCapabilitiesForOpenCL(ST);
990 initAvailableCapabilitiesForVulkan(ST);
997void RequirementHandler::initAvailableCapabilitiesForOpenCL(
1001 Capability::Kernel, Capability::Vector16,
1002 Capability::Groups, Capability::GenericPointer,
1003 Capability::StorageImageWriteWithoutFormat,
1004 Capability::StorageImageReadWithoutFormat});
1005 if (ST.hasOpenCLFullProfile())
1007 if (ST.hasOpenCLImageSupport()) {
1009 Capability::Image1D, Capability::SampledBuffer,
1010 Capability::ImageBuffer});
1011 if (
ST.isAtLeastOpenCLVer(VersionTuple(2, 0)))
1014 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) &&
1015 ST.isAtLeastOpenCLVer(VersionTuple(2, 2)))
1017 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 4)))
1018 addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
1019 Capability::SignedZeroInfNanPreserve,
1020 Capability::RoundingModeRTE,
1021 Capability::RoundingModeRTZ});
1028void RequirementHandler::initAvailableCapabilitiesForVulkan(
1029 const SPIRVSubtarget &ST) {
1033 Capability::Float16,
1034 Capability::Float64,
1035 Capability::GroupNonUniform,
1036 Capability::Image1D,
1037 Capability::SampledBuffer,
1038 Capability::ImageBuffer,
1039 Capability::UniformBufferArrayDynamicIndexing,
1040 Capability::SampledImageArrayDynamicIndexing,
1041 Capability::StorageBufferArrayDynamicIndexing,
1042 Capability::StorageImageArrayDynamicIndexing,
1043 Capability::DerivativeControl,
1045 Capability::ImageQuery,
1046 Capability::ImageGatherExtended,
1047 Capability::Addresses,
1048 Capability::VulkanMemoryModelKHR,
1049 Capability::StorageImageExtendedFormats,
1050 Capability::StorageImageMultisample,
1051 Capability::ImageMSArray});
1054 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
1056 {Capability::Int64Atomics, Capability::ShaderNonUniformEXT,
1057 Capability::RuntimeDescriptorArrayEXT,
1058 Capability::InputAttachmentArrayDynamicIndexingEXT,
1059 Capability::UniformTexelBufferArrayDynamicIndexingEXT,
1060 Capability::StorageTexelBufferArrayDynamicIndexingEXT,
1061 Capability::UniformBufferArrayNonUniformIndexingEXT,
1062 Capability::SampledImageArrayNonUniformIndexingEXT,
1063 Capability::StorageBufferArrayNonUniformIndexingEXT,
1064 Capability::StorageImageArrayNonUniformIndexingEXT,
1065 Capability::InputAttachmentArrayNonUniformIndexingEXT,
1066 Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
1067 Capability::StorageTexelBufferArrayNonUniformIndexingEXT});
1071 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
1073 Capability::StorageImageReadWithoutFormat});
1084 int64_t DecOp =
MI.getOperand(DecIndex).getImm();
1085 auto Dec =
static_cast<SPIRV::Decoration::Decoration
>(DecOp);
1087 SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
1089 if (Dec == SPIRV::Decoration::BuiltIn) {
1090 int64_t BuiltInOp =
MI.getOperand(DecIndex + 1).getImm();
1091 auto BuiltIn =
static_cast<SPIRV::BuiltIn::BuiltIn
>(BuiltInOp);
1093 SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
1094 }
else if (Dec == SPIRV::Decoration::LinkageAttributes) {
1095 int64_t LinkageOp =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
1096 SPIRV::LinkageType::LinkageType LnkType =
1097 static_cast<SPIRV::LinkageType::LinkageType
>(LinkageOp);
1098 if (LnkType == SPIRV::LinkageType::LinkOnceODR)
1099 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_linkonce_odr);
1100 else if (LnkType == SPIRV::LinkageType::WeakAMD) {
1101 Reqs.
addExtension(SPIRV::Extension::SPV_AMD_weak_linkage);
1104 }
else if (Dec == SPIRV::Decoration::CacheControlLoadINTEL ||
1105 Dec == SPIRV::Decoration::CacheControlStoreINTEL) {
1106 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_cache_controls);
1107 }
else if (Dec == SPIRV::Decoration::HostAccessINTEL) {
1108 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_global_variable_host_access);
1109 }
else if (Dec == SPIRV::Decoration::InitModeINTEL ||
1110 Dec == SPIRV::Decoration::ImplementInRegisterMapINTEL) {
1112 SPIRV::Extension::SPV_INTEL_global_variable_fpga_decorations);
1113 }
else if (Dec == SPIRV::Decoration::NonUniformEXT) {
1115 }
else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
1117 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_fp_max_error);
1118 }
else if (Dec == SPIRV::Decoration::FPFastMathMode) {
1119 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
1121 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_float_controls2);
1130 assert(
MI.getNumOperands() >= 8 &&
"Insufficient operands for OpTypeImage");
1133 int64_t ImgFormatOp =
MI.getOperand(7).getImm();
1134 auto ImgFormat =
static_cast<SPIRV::ImageFormat::ImageFormat
>(ImgFormatOp);
1138 bool IsArrayed =
MI.getOperand(4).getImm() == 1;
1139 bool IsMultisampled =
MI.getOperand(5).getImm() == 1;
1140 bool NoSampler =
MI.getOperand(6).getImm() == 2;
1143 switch (
MI.getOperand(2).getImm()) {
1144 case SPIRV::Dim::DIM_1D:
1146 : SPIRV::Capability::Sampled1D);
1148 case SPIRV::Dim::DIM_2D:
1149 if (IsMultisampled && NoSampler)
1151 if (IsMultisampled && IsArrayed)
1154 case SPIRV::Dim::DIM_3D:
1156 case SPIRV::Dim::DIM_Cube:
1160 : SPIRV::Capability::SampledCubeArray);
1162 case SPIRV::Dim::DIM_Rect:
1164 : SPIRV::Capability::SampledRect);
1166 case SPIRV::Dim::DIM_Buffer:
1168 : SPIRV::Capability::SampledBuffer);
1170 case SPIRV::Dim::DIM_SubpassData:
1176 if (!ST.isShader()) {
1177 if (
MI.getNumOperands() > 8 &&
1178 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
1187 TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
1193#define ATOM_FLT_REQ_EXT_MSG(ExtName) \
1194 "The atomic float instruction requires the following SPIR-V " \
1195 "extension: SPV_EXT_shader_atomic_float" ExtName
1200 MI.getMF()->getRegInfo().getVRegDef(
MI.getOperand(1).getReg());
1203 if (Rank != 2 && Rank != 4)
1205 "must be a 2-component or 4 component vector");
1210 if (EltTypeDef->
getOpcode() != SPIRV::OpTypeFloat ||
1213 "The element type for the result type of an atomic vector float "
1214 "instruction must be a 16-bit floating-point scalar");
1221 "The element type for the result type of an atomic vector float "
1222 "instruction cannot be a bfloat16 scalar");
1223 if (!ST.canUseExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector))
1225 "The atomic float16 vector instruction requires the following SPIR-V "
1226 "extension: SPV_NV_shader_atomic_fp16_vector");
1228 Reqs.
addExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector);
1229 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16VectorNV);
1236 "Expect register operand in atomic float instruction");
1237 Register TypeReg =
MI.getOperand(1).getReg();
1240 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
1243 if (TypeDef->
getOpcode() != SPIRV::OpTypeFloat)
1245 "floating-point type scalar");
1248 unsigned Op =
MI.getOpcode();
1249 if (
Op == SPIRV::OpAtomicFAddEXT) {
1250 if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add))
1252 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
1256 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1258 "The atomic bfloat16 instruction requires the following SPIR-V "
1259 "extension: SPV_INTEL_16bit_atomics",
1261 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1262 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16AddINTEL);
1264 if (!ST.canUseExtension(
1265 SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
1267 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
1279 "Unexpected floating-point type width in atomic float instruction");
1282 if (!ST.canUseExtension(
1283 SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max))
1285 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
1289 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1291 "The atomic bfloat16 instruction requires the following SPIR-V "
1292 "extension: SPV_INTEL_16bit_atomics",
1294 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1295 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16MinMaxINTEL);
1297 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
1301 Reqs.
addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
1304 Reqs.
addCapability(SPIRV::Capability::AtomicFloat64MinMaxEXT);
1308 "Unexpected floating-point type width in atomic float instruction");
1314 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1318 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
1322 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1326 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
1330 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1334 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
1338 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1342 return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
1346 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1350 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
1354 if (SampledImageInst->
getOpcode() != SPIRV::OpTypeSampledImage)
1365 if (
MI.getOpcode() != SPIRV::OpDecorate)
1369 if (Dec == SPIRV::Decoration::NonUniformEXT)
1382 Register ResTypeReg = Instr.getOperand(1).getReg();
1387 if (
StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
1388 StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
1389 StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
1396 auto FirstIndexReg = Instr.getOperand(3).getReg();
1397 bool FirstIndexIsConstant =
1400 if (
StorageClass == SPIRV::StorageClass::StorageClass::StorageBuffer) {
1403 SPIRV::Capability::StorageBufferArrayNonUniformIndexingEXT);
1404 else if (!FirstIndexIsConstant)
1406 SPIRV::Capability::StorageBufferArrayDynamicIndexing);
1412 if (PointeeType->
getOpcode() != SPIRV::OpTypeImage &&
1413 PointeeType->
getOpcode() != SPIRV::OpTypeSampledImage &&
1414 PointeeType->
getOpcode() != SPIRV::OpTypeSampler) {
1421 SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1422 else if (!FirstIndexIsConstant)
1424 SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
1428 SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1429 else if (!FirstIndexIsConstant)
1431 SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
1435 SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1436 else if (!FirstIndexIsConstant)
1438 SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
1441 PointeeType->
getOpcode() == SPIRV::OpTypeSampler) {
1444 SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1445 else if (!FirstIndexIsConstant)
1447 SPIRV::Capability::SampledImageArrayDynamicIndexing);
1451 SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1452 else if (!FirstIndexIsConstant)
1454 SPIRV::Capability::StorageImageArrayDynamicIndexing);
1459 if (TypeInst->
getOpcode() != SPIRV::OpTypeImage)
1468 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product))
1469 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_integer_dot_product);
1473 assert(
MI.getOperand(2).isReg() &&
"Unexpected operand in dot");
1477 assert(
Input->getOperand(1).isReg() &&
"Unexpected operand in dot input");
1481 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1483 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8BitPacked);
1484 }
else if (TypeDef->
getOpcode() == SPIRV::OpTypeVector) {
1490 "Dot operand of 8-bit integer type requires 4 components");
1491 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8Bit);
1507 unsigned AddrSpace = ASOp.
getImm();
1508 if (AddrSpace != SPIRV::StorageClass::UniformConstant) {
1509 if (!ST.canUseExtension(
1511 SPV_EXT_relaxed_printf_string_address_space)) {
1513 "required because printf uses a format string not "
1514 "in constant address space.",
1518 SPIRV::Extension::SPV_EXT_relaxed_printf_string_address_space);
1527 if (
MI.getNumOperands() <=
OpIdx)
1531 if (Mask & (1U <<
I))
1540 unsigned Op =
MI.getOpcode();
1542 case SPIRV::OpMemoryModel: {
1543 int64_t Addr =
MI.getOperand(0).getImm();
1546 int64_t Mem =
MI.getOperand(1).getImm();
1551 case SPIRV::OpEntryPoint: {
1552 int64_t Exe =
MI.getOperand(0).getImm();
1557 case SPIRV::OpExecutionMode:
1558 case SPIRV::OpExecutionModeId: {
1559 int64_t Exe =
MI.getOperand(1).getImm();
1564 case SPIRV::OpTypeMatrix:
1567 case SPIRV::OpTypeInt: {
1568 unsigned BitWidth =
MI.getOperand(1).getImm();
1576 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1580 if (!ST.canUseExtension(
1581 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers))
1583 "OpTypeInt type with a width other than 8, 16, 32 or 64 bits "
1584 "requires the following SPIR-V extension: "
1585 "SPV_ALTERA_arbitrary_precision_integers");
1587 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
1588 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
1592 case SPIRV::OpDot: {
1596 Reqs.
addCapability(SPIRV::Capability::BFloat16DotProductKHR);
1599 case SPIRV::OpTypeFloat: {
1600 unsigned BitWidth =
MI.getOperand(1).getImm();
1605 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_bfloat16))
1607 "following SPIR-V extension: SPV_KHR_bfloat16",
1617 case SPIRV::OpTypeVector: {
1618 unsigned NumComponents =
MI.getOperand(2).getImm();
1619 if (NumComponents == 8 || NumComponents == 16)
1625 if (ElemTypeDef->
getOpcode() == SPIRV::OpTypePointer &&
1626 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
1627 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter);
1628 Reqs.
addCapability(SPIRV::Capability::MaskedGatherScatterINTEL);
1632 case SPIRV::OpTypePointer: {
1633 auto SC =
MI.getOperand(1).getImm();
1644 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1649 case SPIRV::OpExtInst: {
1650 if (
MI.getOperand(2).getImm() ==
1651 static_cast<int64_t
>(
1652 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1653 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1656 if (
MI.getOperand(3).getImm() ==
1657 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1661 if (
MI.getOperand(2).getImm() ==
1662 static_cast<int64_t
>(SPIRV::InstructionSet::OpenCL_std)) {
1668 if (TypeDef && TypeDef->getOpcode() == SPIRV::OpTypeVector)
1669 TypeDef = MRI.
getVRegDef(TypeDef->getOperand(1).getReg());
1674 bool UsesBFloat16 = IsBFloat16(MRI.
getVRegDef(
MI.getOperand(1).getReg()));
1675 for (
unsigned I = 4,
E =
MI.getNumOperands();
I <
E && !UsesBFloat16;
1684 if (!ST.canUseExtension(
1685 SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic)) {
1687 MI,
"OpenCL Extended instructions with bfloat16 require the "
1688 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic");
1691 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
1692 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
1697 case SPIRV::OpAliasDomainDeclINTEL:
1698 case SPIRV::OpAliasScopeDeclINTEL:
1699 case SPIRV::OpAliasScopeListDeclINTEL: {
1700 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1701 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1704 case SPIRV::OpBitReverse:
1705 case SPIRV::OpBitFieldInsert:
1706 case SPIRV::OpBitFieldSExtract:
1707 case SPIRV::OpBitFieldUExtract:
1708 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1712 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1715 case SPIRV::OpTypeRuntimeArray:
1718 case SPIRV::OpTypeOpaque:
1719 case SPIRV::OpTypeEvent:
1722 case SPIRV::OpTypePipe:
1723 case SPIRV::OpTypeReserveId:
1726 case SPIRV::OpTypeDeviceEvent:
1727 case SPIRV::OpTypeQueue:
1728 case SPIRV::OpBuildNDRange:
1729 case SPIRV::OpEnqueueKernel:
1732 case SPIRV::OpDecorate:
1733 case SPIRV::OpDecorateId:
1734 case SPIRV::OpDecorateString:
1737 case SPIRV::OpMemberDecorate:
1738 case SPIRV::OpMemberDecorateString:
1741 case SPIRV::OpInBoundsPtrAccessChain:
1744 case SPIRV::OpConstantSampler:
1747 case SPIRV::OpInBoundsAccessChain:
1748 case SPIRV::OpAccessChain:
1751 case SPIRV::OpTypeImage:
1754 case SPIRV::OpTypeSampler:
1755 if (!ST.isShader()) {
1759 case SPIRV::OpTypeForwardPointer:
1763 case SPIRV::OpAtomicFlagTestAndSet:
1764 case SPIRV::OpAtomicLoad:
1765 case SPIRV::OpAtomicStore:
1766 case SPIRV::OpAtomicExchange:
1767 case SPIRV::OpAtomicCompareExchange:
1768 case SPIRV::OpAtomicCompareExchangeWeak:
1769 case SPIRV::OpAtomicIIncrement:
1770 case SPIRV::OpAtomicIDecrement:
1771 case SPIRV::OpAtomicIAdd:
1772 case SPIRV::OpAtomicISub:
1773 case SPIRV::OpAtomicUMin:
1774 case SPIRV::OpAtomicUMax:
1775 case SPIRV::OpAtomicSMin:
1776 case SPIRV::OpAtomicSMax:
1777 case SPIRV::OpAtomicAnd:
1778 case SPIRV::OpAtomicOr:
1779 case SPIRV::OpAtomicXor: {
1782 if (
Op == SPIRV::OpAtomicStore) {
1785 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1791 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1796 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1798 "16-bit integer atomic operations require the following SPIR-V "
1799 "extension: SPV_INTEL_16bit_atomics",
1801 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1803 case SPIRV::OpAtomicLoad:
1804 case SPIRV::OpAtomicStore:
1805 case SPIRV::OpAtomicExchange:
1806 case SPIRV::OpAtomicCompareExchange:
1807 case SPIRV::OpAtomicCompareExchangeWeak:
1809 SPIRV::Capability::AtomicInt16CompareExchangeINTEL);
1817 if (
is_contained({SPIRV::OpAtomicLoad, SPIRV::OpAtomicStore,
1818 SPIRV::OpAtomicExchange},
1820 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1822 "The atomic bfloat16 instruction requires the following SPIR-V "
1823 "extension: SPV_INTEL_16bit_atomics",
1825 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1826 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16LoadStoreINTEL);
1831 case SPIRV::OpGroupNonUniformIAdd:
1832 case SPIRV::OpGroupNonUniformFAdd:
1833 case SPIRV::OpGroupNonUniformIMul:
1834 case SPIRV::OpGroupNonUniformFMul:
1835 case SPIRV::OpGroupNonUniformSMin:
1836 case SPIRV::OpGroupNonUniformUMin:
1837 case SPIRV::OpGroupNonUniformFMin:
1838 case SPIRV::OpGroupNonUniformSMax:
1839 case SPIRV::OpGroupNonUniformUMax:
1840 case SPIRV::OpGroupNonUniformFMax:
1841 case SPIRV::OpGroupNonUniformBitwiseAnd:
1842 case SPIRV::OpGroupNonUniformBitwiseOr:
1843 case SPIRV::OpGroupNonUniformBitwiseXor:
1844 case SPIRV::OpGroupNonUniformLogicalAnd:
1845 case SPIRV::OpGroupNonUniformLogicalOr:
1846 case SPIRV::OpGroupNonUniformLogicalXor: {
1848 int64_t GroupOp =
MI.getOperand(3).getImm();
1850 case SPIRV::GroupOperation::Reduce:
1851 case SPIRV::GroupOperation::InclusiveScan:
1852 case SPIRV::GroupOperation::ExclusiveScan:
1853 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1855 case SPIRV::GroupOperation::ClusteredReduce:
1856 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1858 case SPIRV::GroupOperation::PartitionedReduceNV:
1859 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1860 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1861 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1866 case SPIRV::OpGroupNonUniformQuadSwap:
1869 case SPIRV::OpImageQueryLod:
1872 case SPIRV::OpImageQuerySize:
1873 case SPIRV::OpImageQuerySizeLod:
1874 case SPIRV::OpImageQueryLevels:
1875 case SPIRV::OpImageQuerySamples:
1879 case SPIRV::OpImageQueryFormat: {
1880 Register ResultReg =
MI.getOperand(0).getReg();
1882 static const unsigned CompareOps[] = {
1883 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1884 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1885 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1886 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1887 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1889 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1890 if (ImmVal == 4323 || ImmVal == 4324) {
1891 if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1892 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1895 "SPV_EXT_image_raw10_raw12 extension");
1900 unsigned Opc = UseInst.getOpcode();
1902 if (
Opc == SPIRV::OpSwitch) {
1905 CheckAndAddExtension(
Op.getImm());
1907 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1910 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1913 CheckAndAddExtension(ImmVal);
1921 case SPIRV::OpGroupNonUniformShuffle:
1922 case SPIRV::OpGroupNonUniformShuffleXor:
1923 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1925 case SPIRV::OpGroupNonUniformShuffleUp:
1926 case SPIRV::OpGroupNonUniformShuffleDown:
1927 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1929 case SPIRV::OpGroupAll:
1930 case SPIRV::OpGroupAny:
1931 case SPIRV::OpGroupBroadcast:
1932 case SPIRV::OpGroupIAdd:
1933 case SPIRV::OpGroupFAdd:
1934 case SPIRV::OpGroupFMin:
1935 case SPIRV::OpGroupUMin:
1936 case SPIRV::OpGroupSMin:
1937 case SPIRV::OpGroupFMax:
1938 case SPIRV::OpGroupUMax:
1939 case SPIRV::OpGroupSMax:
1942 case SPIRV::OpGroupNonUniformElect:
1945 case SPIRV::OpGroupNonUniformAll:
1946 case SPIRV::OpGroupNonUniformAny:
1947 case SPIRV::OpGroupNonUniformAllEqual:
1950 case SPIRV::OpGroupNonUniformBroadcast:
1951 case SPIRV::OpGroupNonUniformBroadcastFirst:
1952 case SPIRV::OpGroupNonUniformBallot:
1953 case SPIRV::OpGroupNonUniformInverseBallot:
1954 case SPIRV::OpGroupNonUniformBallotBitExtract:
1955 case SPIRV::OpGroupNonUniformBallotBitCount:
1956 case SPIRV::OpGroupNonUniformBallotFindLSB:
1957 case SPIRV::OpGroupNonUniformBallotFindMSB:
1958 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1960 case SPIRV::OpSubgroupShuffleINTEL:
1961 case SPIRV::OpSubgroupShuffleDownINTEL:
1962 case SPIRV::OpSubgroupShuffleUpINTEL:
1963 case SPIRV::OpSubgroupShuffleXorINTEL:
1964 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1965 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1966 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1969 case SPIRV::OpSubgroupBlockReadINTEL:
1970 case SPIRV::OpSubgroupBlockWriteINTEL:
1971 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1972 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1973 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1976 case SPIRV::OpSubgroupImageBlockReadINTEL:
1977 case SPIRV::OpSubgroupImageBlockWriteINTEL:
1978 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1979 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1980 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
1983 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
1984 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
1985 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
1986 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
1987 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
1990 case SPIRV::OpAssumeTrueKHR:
1991 case SPIRV::OpExpectKHR:
1992 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
1993 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
1997 case SPIRV::OpFmaKHR:
1998 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
2003 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
2004 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
2005 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
2006 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
2007 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
2010 case SPIRV::OpConstantFunctionPointerINTEL:
2011 case SPIRV::OpFunctionPointerCallINTEL:
2012 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
2013 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
2014 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
2017 case SPIRV::OpGroupNonUniformRotateKHR:
2018 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
2020 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
2022 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
2023 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
2026 case SPIRV::OpFixedCosALTERA:
2027 case SPIRV::OpFixedSinALTERA:
2028 case SPIRV::OpFixedCosPiALTERA:
2029 case SPIRV::OpFixedSinPiALTERA:
2030 case SPIRV::OpFixedExpALTERA:
2031 case SPIRV::OpFixedLogALTERA:
2032 case SPIRV::OpFixedRecipALTERA:
2033 case SPIRV::OpFixedSqrtALTERA:
2034 case SPIRV::OpFixedSinCosALTERA:
2035 case SPIRV::OpFixedSinCosPiALTERA:
2036 case SPIRV::OpFixedRsqrtALTERA:
2037 if (!ST.canUseExtension(
2038 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
2040 "following SPIR-V extension: "
2041 "SPV_ALTERA_arbitrary_precision_fixed_point",
2044 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
2045 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
2047 case SPIRV::OpGroupIMulKHR:
2048 case SPIRV::OpGroupFMulKHR:
2049 case SPIRV::OpGroupBitwiseAndKHR:
2050 case SPIRV::OpGroupBitwiseOrKHR:
2051 case SPIRV::OpGroupBitwiseXorKHR:
2052 case SPIRV::OpGroupLogicalAndKHR:
2053 case SPIRV::OpGroupLogicalOrKHR:
2054 case SPIRV::OpGroupLogicalXorKHR:
2055 if (ST.canUseExtension(
2056 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
2057 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
2058 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
2061 case SPIRV::OpReadClockKHR:
2062 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
2064 "following SPIR-V extension: SPV_KHR_shader_clock",
2066 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
2069 case SPIRV::OpAbortKHR:
2070 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_abort))
2072 "following SPIR-V extension: SPV_KHR_abort",
2077 case SPIRV::OpPoisonKHR:
2078 case SPIRV::OpFreezeKHR:
2079 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_poison_freeze))
2081 "following SPIR-V extension: SPV_KHR_poison_freeze",
2083 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_poison_freeze);
2086 case SPIRV::OpAtomicFAddEXT:
2087 case SPIRV::OpAtomicFMinEXT:
2088 case SPIRV::OpAtomicFMaxEXT:
2091 case SPIRV::OpConvertBF16ToFINTEL:
2092 case SPIRV::OpConvertFToBF16INTEL:
2093 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
2094 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
2095 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
2098 case SPIRV::OpRoundFToTF32INTEL:
2099 if (ST.canUseExtension(
2100 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
2101 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
2102 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
2105 case SPIRV::OpVariableLengthArrayINTEL:
2106 case SPIRV::OpSaveMemoryINTEL:
2107 case SPIRV::OpRestoreMemoryINTEL:
2108 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
2109 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
2110 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
2113 case SPIRV::OpAsmTargetINTEL:
2114 case SPIRV::OpAsmINTEL:
2115 case SPIRV::OpAsmCallINTEL:
2116 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
2117 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
2121 case SPIRV::OpTypeCooperativeMatrixKHR: {
2122 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2124 "OpTypeCooperativeMatrixKHR type requires the "
2125 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
2127 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2128 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2132 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
2135 case SPIRV::OpArithmeticFenceEXT:
2136 if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
2138 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
2140 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
2143 case SPIRV::OpControlBarrierArriveINTEL:
2144 case SPIRV::OpControlBarrierWaitINTEL:
2145 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
2146 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
2150 case SPIRV::OpCooperativeMatrixMulAddKHR: {
2151 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2153 "following SPIR-V extension: "
2154 "SPV_KHR_cooperative_matrix",
2156 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2157 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2158 constexpr unsigned MulAddMaxSize = 6;
2159 if (
MI.getNumOperands() != MulAddMaxSize)
2161 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
2163 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
2164 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2166 "require the following SPIR-V extension: "
2167 "SPV_INTEL_joint_matrix",
2169 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2171 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
2174 MatrixAAndBBFloat16ComponentsINTEL ||
2176 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
2178 MatrixResultBFloat16ComponentsINTEL) {
2179 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2181 "require the following SPIR-V extension: "
2182 "SPV_INTEL_joint_matrix",
2184 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2186 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
2190 case SPIRV::OpCooperativeMatrixLoadKHR:
2191 case SPIRV::OpCooperativeMatrixStoreKHR:
2192 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2193 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2194 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
2195 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2197 "following SPIR-V extension: "
2198 "SPV_KHR_cooperative_matrix",
2200 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2201 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2207 case SPIRV::OpCooperativeMatrixLoadKHR:
2210 case SPIRV::OpCooperativeMatrixStoreKHR:
2213 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2216 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2217 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2223 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
2226 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
2229 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
2230 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2232 "extension: SPV_INTEL_joint_matrix",
2234 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2235 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2240 if (
Op == SPIRV::OpCooperativeMatrixLoadKHR ||
2241 Op == SPIRV::OpCooperativeMatrixStoreKHR)
2244 std::string InstName;
2246 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2247 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2249 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2250 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2252 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2253 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2257 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2258 const std::string ErrorMsg =
2259 InstName +
" instruction requires the "
2260 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2263 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2264 if (
Op == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2265 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2269 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2272 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2273 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2275 "instructions require the following SPIR-V extension: "
2276 "SPV_INTEL_joint_matrix",
2278 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2280 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2282 case SPIRV::OpReadPipeBlockingALTERA:
2283 case SPIRV::OpWritePipeBlockingALTERA:
2284 if (ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2285 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2289 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2290 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2292 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2294 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2296 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2298 case SPIRV::OpConvertHandleToImageINTEL:
2299 case SPIRV::OpConvertHandleToSamplerINTEL:
2300 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2301 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2303 "instructions require the following SPIR-V extension: "
2304 "SPV_INTEL_bindless_images",
2307 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2309 if (
Op == SPIRV::OpConvertHandleToImageINTEL &&
2310 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2312 "OpConvertHandleToImageINTEL",
2314 }
else if (
Op == SPIRV::OpConvertHandleToSamplerINTEL &&
2315 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2317 "OpConvertHandleToSamplerINTEL",
2319 }
else if (
Op == SPIRV::OpConvertHandleToSampledImageINTEL &&
2320 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2322 "OpConvertHandleToSampledImageINTEL",
2327 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2328 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2330 "Parameter value must be a 32-bit scalar in case of "
2331 "Physical32 addressing model or a 64-bit scalar in case of "
2332 "Physical64 addressing model",
2335 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2339 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2340 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2341 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2342 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2343 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2344 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2346 "Prefetch/Store]INTEL instructions require the "
2347 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2349 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2350 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2352 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2353 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2356 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2357 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2362 case SPIRV::OpKill: {
2365 case SPIRV::OpDemoteToHelperInvocation:
2366 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2368 if (ST.canUseExtension(
2369 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2372 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2377 case SPIRV::OpSUDot:
2378 case SPIRV::OpSDotAccSat:
2379 case SPIRV::OpUDotAccSat:
2380 case SPIRV::OpSUDotAccSat:
2383 case SPIRV::OpImageSampleImplicitLod:
2384 case SPIRV::OpImageFetch:
2388 case SPIRV::OpImageSampleExplicitLod:
2391 case SPIRV::OpImageSampleDrefImplicitLod:
2392 case SPIRV::OpImageSampleDrefExplicitLod:
2393 case SPIRV::OpImageDrefGather:
2394 case SPIRV::OpImageGather:
2398 case SPIRV::OpImageRead: {
2399 Register ImageReg =
MI.getOperand(2).getReg();
2400 SPIRVTypeInst TypeDef = ST.getSPIRVGlobalRegistry()->getResultType(
2409 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2412 case SPIRV::OpImageWrite: {
2413 Register ImageReg =
MI.getOperand(0).getReg();
2414 SPIRVTypeInst TypeDef = ST.getSPIRVGlobalRegistry()->getResultType(
2423 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2426 case SPIRV::OpTypeStructContinuedINTEL:
2427 case SPIRV::OpConstantCompositeContinuedINTEL:
2428 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2429 case SPIRV::OpCompositeConstructContinuedINTEL: {
2430 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2432 "Continued instructions require the "
2433 "following SPIR-V extension: SPV_INTEL_long_composites",
2435 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2439 case SPIRV::OpArbitraryFloatEQALTERA:
2440 case SPIRV::OpArbitraryFloatGEALTERA:
2441 case SPIRV::OpArbitraryFloatGTALTERA:
2442 case SPIRV::OpArbitraryFloatLEALTERA:
2443 case SPIRV::OpArbitraryFloatLTALTERA:
2444 case SPIRV::OpArbitraryFloatCbrtALTERA:
2445 case SPIRV::OpArbitraryFloatCosALTERA:
2446 case SPIRV::OpArbitraryFloatCosPiALTERA:
2447 case SPIRV::OpArbitraryFloatExp10ALTERA:
2448 case SPIRV::OpArbitraryFloatExp2ALTERA:
2449 case SPIRV::OpArbitraryFloatExpALTERA:
2450 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2451 case SPIRV::OpArbitraryFloatHypotALTERA:
2452 case SPIRV::OpArbitraryFloatLog10ALTERA:
2453 case SPIRV::OpArbitraryFloatLog1pALTERA:
2454 case SPIRV::OpArbitraryFloatLog2ALTERA:
2455 case SPIRV::OpArbitraryFloatLogALTERA:
2456 case SPIRV::OpArbitraryFloatRecipALTERA:
2457 case SPIRV::OpArbitraryFloatSinCosALTERA:
2458 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2459 case SPIRV::OpArbitraryFloatSinALTERA:
2460 case SPIRV::OpArbitraryFloatSinPiALTERA:
2461 case SPIRV::OpArbitraryFloatSqrtALTERA:
2462 case SPIRV::OpArbitraryFloatACosALTERA:
2463 case SPIRV::OpArbitraryFloatACosPiALTERA:
2464 case SPIRV::OpArbitraryFloatAddALTERA:
2465 case SPIRV::OpArbitraryFloatASinALTERA:
2466 case SPIRV::OpArbitraryFloatASinPiALTERA:
2467 case SPIRV::OpArbitraryFloatATan2ALTERA:
2468 case SPIRV::OpArbitraryFloatATanALTERA:
2469 case SPIRV::OpArbitraryFloatATanPiALTERA:
2470 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2471 case SPIRV::OpArbitraryFloatCastALTERA:
2472 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2473 case SPIRV::OpArbitraryFloatDivALTERA:
2474 case SPIRV::OpArbitraryFloatMulALTERA:
2475 case SPIRV::OpArbitraryFloatPowALTERA:
2476 case SPIRV::OpArbitraryFloatPowNALTERA:
2477 case SPIRV::OpArbitraryFloatPowRALTERA:
2478 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2479 case SPIRV::OpArbitraryFloatSubALTERA: {
2480 if (!ST.canUseExtension(
2481 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2483 "Floating point instructions can't be translated correctly without "
2484 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2487 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2489 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2492 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2493 if (!ST.canUseExtension(
2494 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2496 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2498 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2501 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2503 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2506 case SPIRV::OpBitwiseFunctionINTEL: {
2507 if (!ST.canUseExtension(
2508 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2510 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2511 "extension: SPV_INTEL_ternary_bitwise_function",
2513 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2514 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2517 case SPIRV::OpCopyMemorySized: {
2522 case SPIRV::OpPredicatedLoadINTEL:
2523 case SPIRV::OpPredicatedStoreINTEL: {
2524 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2526 "OpPredicated[Load/Store]INTEL instructions require "
2527 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2529 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2533 case SPIRV::OpFAddS:
2534 case SPIRV::OpFSubS:
2535 case SPIRV::OpFMulS:
2536 case SPIRV::OpFDivS:
2537 case SPIRV::OpFRemS:
2539 case SPIRV::OpFNegate:
2540 case SPIRV::OpFAddV:
2541 case SPIRV::OpFSubV:
2542 case SPIRV::OpFMulV:
2543 case SPIRV::OpFDivV:
2544 case SPIRV::OpFRemV:
2545 case SPIRV::OpFNegateV: {
2548 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2551 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2553 "Arithmetic instructions with bfloat16 arguments require the "
2554 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2556 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2557 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2561 case SPIRV::OpOrdered:
2562 case SPIRV::OpUnordered:
2563 case SPIRV::OpFOrdEqual:
2564 case SPIRV::OpFOrdNotEqual:
2565 case SPIRV::OpFOrdLessThan:
2566 case SPIRV::OpFOrdLessThanEqual:
2567 case SPIRV::OpFOrdGreaterThan:
2568 case SPIRV::OpFOrdGreaterThanEqual:
2569 case SPIRV::OpFUnordEqual:
2570 case SPIRV::OpFUnordNotEqual:
2571 case SPIRV::OpFUnordLessThan:
2572 case SPIRV::OpFUnordLessThanEqual:
2573 case SPIRV::OpFUnordGreaterThan:
2574 case SPIRV::OpFUnordGreaterThanEqual: {
2578 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2581 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2583 "Relational instructions with bfloat16 arguments require the "
2584 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2586 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2587 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2591 case SPIRV::OpDPdxCoarse:
2592 case SPIRV::OpDPdyCoarse:
2593 case SPIRV::OpDPdxFine:
2594 case SPIRV::OpDPdyFine: {
2598 case SPIRV::OpLoopControlINTEL: {
2599 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2600 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2612 SPIRV::Capability::Shader);
2627 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2629 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2630 RequireKHRFloatControls2 =
false,
2631 VerLower14 = !ST.isAtLeastSPIRVVer(
VersionTuple(1, 4));
2632 bool HasIntelFloatControls2 =
2633 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2634 bool HasKHRFloatControls2 =
2635 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2636 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2642 auto EM = Const->getZExtValue();
2646 case SPIRV::ExecutionMode::DenormPreserve:
2647 case SPIRV::ExecutionMode::DenormFlushToZero:
2648 case SPIRV::ExecutionMode::RoundingModeRTE:
2649 case SPIRV::ExecutionMode::RoundingModeRTZ:
2650 RequireFloatControls = VerLower14;
2652 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2654 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2655 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2656 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2657 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2658 if (HasIntelFloatControls2) {
2659 RequireIntelFloatControls2 =
true;
2661 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2664 case SPIRV::ExecutionMode::FPFastMathDefault: {
2665 if (HasKHRFloatControls2) {
2666 RequireKHRFloatControls2 =
true;
2668 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2672 case SPIRV::ExecutionMode::ContractionOff:
2673 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2674 if (HasKHRFloatControls2) {
2675 RequireKHRFloatControls2 =
true;
2677 SPIRV::OperandCategory::ExecutionModeOperand,
2678 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2681 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2686 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2691 if (RequireFloatControls &&
2692 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2694 if (RequireIntelFloatControls2)
2696 if (RequireKHRFloatControls2)
2700 if (
F.isDeclaration())
2702 if (
F.getMetadata(
"reqd_work_group_size"))
2704 SPIRV::OperandCategory::ExecutionModeOperand,
2705 SPIRV::ExecutionMode::LocalSize, ST);
2706 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2708 SPIRV::OperandCategory::ExecutionModeOperand,
2709 SPIRV::ExecutionMode::LocalSize, ST);
2711 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2714 if (
F.getMetadata(
"work_group_size_hint"))
2716 SPIRV::OperandCategory::ExecutionModeOperand,
2717 SPIRV::ExecutionMode::LocalSizeHint, ST);
2718 if (
F.getMetadata(
"intel_reqd_sub_group_size") ||
2719 F.getMetadata(
"reqd_sub_group_size"))
2721 SPIRV::OperandCategory::ExecutionModeOperand,
2722 SPIRV::ExecutionMode::SubgroupSize, ST);
2723 if (
F.getMetadata(
"max_work_group_size"))
2725 SPIRV::OperandCategory::ExecutionModeOperand,
2726 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2727 if (
F.getMetadata(
"vec_type_hint"))
2729 SPIRV::OperandCategory::ExecutionModeOperand,
2730 SPIRV::ExecutionMode::VecTypeHint, ST);
2732 if (
F.hasOptNone()) {
2733 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2736 }
else if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2746 unsigned Flags = SPIRV::FPFastMathMode::None;
2747 bool CanUseKHRFloatControls2 =
2748 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2750 Flags |= SPIRV::FPFastMathMode::NotNaN;
2752 Flags |= SPIRV::FPFastMathMode::NotInf;
2754 Flags |= SPIRV::FPFastMathMode::NSZ;
2756 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2758 Flags |= SPIRV::FPFastMathMode::AllowContract;
2760 if (CanUseKHRFloatControls2)
2768 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2769 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2770 SPIRV::FPFastMathMode::AllowTransform |
2771 SPIRV::FPFastMathMode::AllowReassoc |
2772 SPIRV::FPFastMathMode::AllowContract;
2774 Flags |= SPIRV::FPFastMathMode::Fast;
2777 if (CanUseKHRFloatControls2) {
2779 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2780 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2785 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2786 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2787 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2788 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2789 "AllowContract flags to be enabled as well.");
2800 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2807 if (
TII.canUseIntegerWrapDecoration(
I)) {
2810 SPIRV::OperandCategory::DecorationOperand,
2811 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2814 SPIRV::Decoration::NoSignedWrap, {});
2817 SPIRV::OperandCategory::DecorationOperand,
2818 SPIRV::Decoration::NoUnsignedWrap, ST, Reqs)
2821 SPIRV::Decoration::NoUnsignedWrap, {});
2826 TII.canUseFastMathFlags(
2827 I, ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) ||
2828 (ST.isKernel() &&
I.getOpcode() == SPIRV::OpExtInst);
2833 if (FMFlags == SPIRV::FPFastMathMode::None) {
2836 if (FPFastMathDefaultInfoVec.
empty())
2852 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2853 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2854 ?
I.getOperand(1).getReg()
2855 :
I.getOperand(2).getReg();
2863 if (Ty == Elem.Ty) {
2864 FMFlags = Elem.FastMathFlags;
2865 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2866 Elem.FPFastMathDefault;
2871 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2875 Register DstReg =
I.getOperand(0).getReg();
2891 for (
auto &
MBB : *MF)
2892 for (
auto &
MI :
MBB)
2910 for (
auto &
MBB : *MF) {
2911 if (!
MBB.hasName() ||
MBB.empty())
2930 for (
auto &
MBB : *MF) {
2932 MI.setDesc(
TII.get(SPIRV::OpPhi));
2935 MI.insert(
MI.operands_begin() + 1,
2936 {MachineOperand::CreateReg(ResTypeReg, false)});
2955 SPIRV::FPFastMathMode::None);
2957 SPIRV::FPFastMathMode::None);
2959 SPIRV::FPFastMathMode::None);
2966 size_t BitWidth = Ty->getScalarSizeInBits();
2970 assert(Index >= 0 && Index < 3 &&
2971 "Expected FPFastMathDefaultInfo for half, float, or double");
2972 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2973 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2974 return FPFastMathDefaultInfoVec[Index];
2980 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
2989 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2993 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
3002 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
3004 "Expected 4 operands for FPFastMathDefault");
3015 Info.FastMathFlags = Flags;
3016 Info.FPFastMathDefault =
true;
3017 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
3019 "Expected no operands for ContractionOff");
3026 Info.ContractionOff =
true;
3028 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
3030 "Expected 1 operand for SignedZeroInfNanPreserve");
3031 unsigned TargetWidth =
3040 assert(Index >= 0 && Index < 3 &&
3041 "Expected FPFastMathDefaultInfo for half, float, or double");
3042 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
3043 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
3044 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
3059 TII = ST->getInstrInfo();
3075 collectDeclarations(M);
3078 numberRegistersGlobally(M);
3081 processOtherInstrs(M);
3085 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
3088 GR->setBound(
MAI.MaxID);
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet & ToRemove
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
Promote Memory to Register
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
#define ATOM_FLT_REQ_EXT_MSG(ExtName)
static bool isFastMathModeAvailable(const SPIRVSubtarget &ST)
static void addDecorations(const Module &M, const SPIRVInstrInfo &TII, MachineModuleInfo *MMI, const SPIRVSubtarget &ST, SPIRV::ModuleAnalysisInfo &MAI, const SPIRVGlobalRegistry *GR)
static void addImageOperandReqs(const MachineInstr &MI, SPIRV::RequirementHandler &Reqs, const SPIRVSubtarget &ST, unsigned OpIdx)
bool isStorageImage(MachineInstr *ImageInst)
bool isInputAttachment(MachineInstr *ImageInst)
static cl::opt< bool > SPVDumpDeps("spv-dump-deps", cl::desc("Dump MIR with SPIR-V dependencies info"), cl::Optional, cl::init(false))
static bool isBFloat16Type(SPIRVTypeInst TypeDef)
bool isSampledImage(MachineInstr *ImageInst)
static void patchPhis(const Module &M, SPIRVGlobalRegistry *GR, const SPIRVInstrInfo &TII, MachineModuleInfo *MMI)
static void handleMIFlagDecoration(MachineInstr &I, const SPIRVSubtarget &ST, const SPIRVInstrInfo &TII, SPIRV::RequirementHandler &Reqs, const SPIRVGlobalRegistry *GR, SPIRV::FPFastMathDefaultInfoVector &FPFastMathDefaultInfoVec)
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")))
static SPIRV::FPFastMathDefaultInfo & getFPFastMathDefaultInfo(SPIRV::FPFastMathDefaultInfoVector &FPFastMathDefaultInfoVec, const Type *Ty)
static void collectOtherInstr(MachineInstr &MI, SPIRV::ModuleAnalysisInfo &MAI, SPIRV::ModuleSectionType MSType, InstrTraces &IS, bool Append=true)
void addPrintfRequirements(const MachineInstr &MI, SPIRV::RequirementHandler &Reqs, const SPIRVSubtarget &ST)
static void addOpTypeImageReqs(const MachineInstr &MI, SPIRV::RequirementHandler &Reqs, const SPIRVSubtarget &ST)
static bool isImageTypeWithUnknownFormat(SPIRVTypeInst TypeInst)
bool isUniformTexelBuffer(MachineInstr *ImageInst)
bool isStorageTexelBuffer(MachineInstr *ImageInst)
static void AddAtomicFloatRequirements(const MachineInstr &MI, SPIRV::RequirementHandler &Reqs, const SPIRVSubtarget &ST)
bool isCombinedImageSampler(MachineInstr *SampledImageInst)
bool hasNonUniformDecoration(Register Reg, const MachineRegisterInfo &MRI)
void addInstrRequirements(const MachineInstr &MI, SPIRV::ModuleAnalysisInfo &MAI, const SPIRVSubtarget &ST)
static void addOpDecorateReqs(const MachineInstr &MI, unsigned DecIndex, SPIRV::RequirementHandler &Reqs, const SPIRVSubtarget &ST)
static InstrSignature instrToSignature(const MachineInstr &MI, SPIRV::ModuleAnalysisInfo &MAI, bool UseDefReg)
static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI, MachineModuleInfo *MMI, const SPIRVSubtarget &ST)
static void AddDotProductRequirements(const MachineInstr &MI, SPIRV::RequirementHandler &Reqs, const SPIRVSubtarget &ST)
static void collectFPFastMathDefaults(const Module &M, SPIRV::ModuleAnalysisInfo &MAI, const SPIRVSubtarget &ST)
static SPIRV::Requirements getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category, unsigned i, const SPIRVSubtarget &ST, SPIRV::RequirementHandler &Reqs)
static unsigned getMetadataUInt(MDNode *MdNode, unsigned OpIndex, unsigned DefaultVal=0)
void addOpAccessChainReqs(const MachineInstr &Instr, SPIRV::RequirementHandler &Handler, const SPIRVSubtarget &Subtarget)
static void addMBBNames(const Module &M, const SPIRVInstrInfo &TII, MachineModuleInfo *MMI, const SPIRVSubtarget &ST, SPIRV::ModuleAnalysisInfo &MAI)
static void appendDecorationsForReg(const MachineRegisterInfo &MRI, Register R, InstrSignature &Signature)
static SPIRV::FPFastMathDefaultInfoVector & getOrCreateFPFastMathDefaultInfoVec(const Module &M, SPIRV::ModuleAnalysisInfo &MAI, const Function *F)
static void AddAtomicVectorFloatRequirements(const MachineInstr &MI, SPIRV::RequirementHandler &Reqs, const SPIRVSubtarget &ST)
static unsigned getFastMathFlags(const MachineInstr &I, const SPIRVSubtarget &ST)
#define SPIRV_BACKEND_SERVICE_FUN_NAME
Target-Independent Code Generator Pass Configuration Options pass.
static Function * getFunction(FunctionType *Ty, const Twine &Name, Module *M)
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.
Diagnostic information for unsupported feature in backend.
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
SPIRVTypeInst getResultType(Register VReg, MachineFunction *MF=nullptr)
const Type * getTypeForSPIRVType(SPIRVTypeInst Ty) const
Register getSPIRVTypeID(SPIRVTypeInst SpirvType) const
SPIRVTypeInst getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
bool isConstantInstr(const MachineInstr &MI) const
const SPIRVInstrInfo * getInstrInfo() const override
SPIRVGlobalRegistry * getSPIRVGlobalRegistry() const
const SPIRVSubtarget * getSubtargetImpl() const
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
Target-Independent Code Generator Pass Configuration Options.
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.
@ 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.
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
hash_code hash_value(const FixedPointSemantics &Val)
ExtensionList getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
CapabilityList getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
SmallVector< SPIRV::Extension::Extension, 8 > ExtensionList
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
SmallVector< size_t > InstrSignature
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
VersionTuple getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
void buildOpName(Register Target, StringRef Name, MachineIRBuilder &MIRBuilder)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
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
SPIRV::ModuleAnalysisInfo MAI
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
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 checkSatisfiable(const SPIRVSubtarget &ST) const
void getAndAddRequirements(SPIRV::OperandCategory::OperandCategory Category, uint32_t i, const SPIRVSubtarget &ST)
void addRequirements(const Requirements &Req)
bool isCapabilityAvailable(Capability::Capability Cap) const
void removeCapabilityIf(const Capability::Capability ToRemove, const Capability::Capability IfPresent)
void addExtensions(const ExtensionList &ToAdd)
void addAvailableCaps(const CapabilityList &ToAdd)
void addExtension(Extension::Extension ToAdd)
void initAvailableCapabilities(const SPIRVSubtarget &ST)
void addCapability(Capability::Capability ToAdd)
void addCapabilities(const CapabilityList &ToAdd)
const std::optional< Capability::Capability > Cap
const VersionTuple MinVer
const VersionTuple MaxVer