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 case SPIRV::OpUntypedVariableKHR:
344 return static_cast<SPIRV::StorageClass::StorageClass
>(
345 MI.getOperand(2).
getImm()) != SPIRV::StorageClass::Function;
346 case SPIRV::OpFunction:
347 case SPIRV::OpFunctionParameter:
350 if (GR->hasConstFunPtr() && Opcode == SPIRV::OpUndef) {
358 if (GR->getFunctionDefinitionByUse(&
MI.getOperand(0))) {
360 unsigned UseOp =
UseMI.getOpcode();
361 if (UseOp == SPIRV::OpConstantFunctionPointerINTEL ||
362 UseOp == SPIRV::OpEnqueueKernel) {
363 MAI.setSkipEmission(&
MI);
369 if (
UseMI.getOpcode() != SPIRV::OpConstantFunctionPointerINTEL)
375 MAI.setSkipEmission(&
MI);
379 return TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
380 TII->isInlineAsmDefInstr(
MI);
389void SPIRVModuleAnalysis::visitFunPtrUse(
392 std::map<const Value *, unsigned> &GlobalToGReg,
394 const MachineOperand *OpFunDef = GR->getFunctionDefinitionByUse(FunPtrOp);
397 const MachineInstr *OpDefMI = OpFunDef->
getParent();
400 const MachineRegisterInfo &FunDefMRI = FunDefMF->
getRegInfo();
402 visitDecl(FunDefMRI, SignatureToGReg, GlobalToGReg, FunDefMF, *OpDefMI);
404 }
while (OpDefMI && (OpDefMI->
getOpcode() == SPIRV::OpFunction ||
405 OpDefMI->
getOpcode() == SPIRV::OpFunctionParameter));
407 MCRegister GlobalFunDefReg =
408 MAI.getRegisterAlias(FunDefMF, OpFunDef->
getReg());
410 "Function definition must refer to a global register");
411 MAI.setRegisterAlias(MF, OpReg, GlobalFunDefReg);
416void SPIRVModuleAnalysis::visitDecl(
418 std::map<const Value *, unsigned> &GlobalToGReg,
const MachineFunction *MF,
420 unsigned Opcode =
MI.getOpcode();
423 for (
const MachineOperand &MO :
MI.operands()) {
424 if (!MO.isReg() || MO.isDef())
428 if (Opcode == SPIRV::OpConstantFunctionPointerINTEL &&
430 visitFunPtrUse(OpReg, &
MI.getOperand(2), SignatureToGReg, GlobalToGReg,
435 if (
MAI.hasRegisterAlias(MF, MO.getReg()))
439 if (isDeclSection(MRI, *OpDefMI))
440 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF, *OpDefMI);
446 dbgs() <<
"Unexpectedly, no unique definition for the operand ";
448 dbgs() <<
"\nInstruction: ";
453 "No unique definition is found for the virtual register");
457 bool IsFunDef =
false;
458 if (TII->isSpecConstantInstr(
MI)) {
459 GReg =
MAI.getNextIDRegister();
461 }
else if (Opcode == SPIRV::OpFunction ||
462 Opcode == SPIRV::OpFunctionParameter) {
463 GReg = handleFunctionOrParameter(MF,
MI, GlobalToGReg, IsFunDef);
464 }
else if (Opcode == SPIRV::OpTypeStruct ||
465 Opcode == SPIRV::OpConstantComposite) {
466 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
467 const MachineInstr *NextInstr =
MI.getNextNode();
469 ((Opcode == SPIRV::OpTypeStruct &&
470 NextInstr->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL) ||
471 (Opcode == SPIRV::OpConstantComposite &&
473 SPIRV::OpConstantCompositeContinuedINTEL))) {
474 MCRegister Tmp = handleTypeDeclOrConstant(*NextInstr, SignatureToGReg);
476 MAI.setSkipEmission(NextInstr);
479 }
else if (TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
480 TII->isInlineAsmDefInstr(
MI)) {
481 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
482 }
else if (Opcode == SPIRV::OpVariable ||
483 Opcode == SPIRV::OpUntypedVariableKHR) {
484 GReg = handleVariable(MF,
MI, GlobalToGReg);
487 dbgs() <<
"\nInstruction: ";
493 MAI.setRegisterAlias(MF,
MI.getOperand(0).getReg(), GReg);
495 MAI.setSkipEmission(&
MI);
498MCRegister SPIRVModuleAnalysis::handleFunctionOrParameter(
500 std::map<const Value *, unsigned> &GlobalToGReg,
bool &IsFunDef) {
501 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
502 assert(GObj &&
"Unregistered global definition");
506 assert(
F &&
"Expected a reference to a function or an argument");
507 IsFunDef = !
F->isDeclaration();
508 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
511 MCRegister GReg =
MAI.getNextIDRegister();
519SPIRVModuleAnalysis::handleTypeDeclOrConstant(
const MachineInstr &
MI,
522 auto [It,
Inserted] = SignatureToGReg.try_emplace(MISign);
525 MCRegister GReg =
MAI.getNextIDRegister();
531MCRegister SPIRVModuleAnalysis::handleVariable(
533 std::map<const Value *, unsigned> &GlobalToGReg) {
534 MAI.GlobalVarList.push_back(&
MI);
535 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
536 assert(GObj &&
"Unregistered global definition");
537 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
540 MCRegister GReg =
MAI.getNextIDRegister();
544 MAI.GlobalObjMap[GV] = GReg;
548void SPIRVModuleAnalysis::collectDeclarations(
const Module &M) {
550 std::map<const Value *, unsigned> GlobalToGReg;
555 const MachineRegisterInfo &MRI = MF->
getRegInfo();
556 unsigned PastHeader = 0;
557 for (MachineBasicBlock &
MBB : *MF) {
558 for (MachineInstr &
MI :
MBB) {
559 if (
MI.getNumOperands() == 0)
561 unsigned Opcode =
MI.getOpcode();
562 if (Opcode == SPIRV::OpFunction) {
563 if (PastHeader == 0) {
567 }
else if (Opcode == SPIRV::OpFunctionParameter) {
570 }
else if (PastHeader > 0) {
574 const MachineOperand &DefMO =
MI.getOperand(0);
576 case SPIRV::OpExtension:
577 MAI.Reqs.addExtension(SPIRV::Extension::Extension(DefMO.
getImm()));
578 MAI.setSkipEmission(&
MI);
580 case SPIRV::OpCapability:
581 MAI.Reqs.addCapability(SPIRV::Capability::Capability(DefMO.
getImm()));
582 MAI.setSkipEmission(&
MI);
587 if (DefMO.
isReg() && isDeclSection(MRI,
MI) &&
588 !
MAI.hasRegisterAlias(MF, DefMO.
getReg()))
589 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF,
MI);
593 if (Opcode == SPIRV::OpEnqueueKernel &&
MI.getNumOperands() > 8) {
594 const MachineOperand &InvokeMO =
MI.getOperand(8);
595 if (InvokeMO.
isReg()) {
597 if (!
MAI.hasRegisterAlias(MF, InvokeReg)) {
598 if (
const MachineInstr *
DefMI =
602 if (GR->getFunctionDefinitionByUse(FunPtrOp))
603 visitFunPtrUse(InvokeReg, FunPtrOp, SignatureToGReg,
622 if (
MI.getOpcode() == SPIRV::OpDecorate) {
624 auto Dec =
MI.getOperand(1).getImm();
625 if (Dec == SPIRV::Decoration::LinkageAttributes) {
626 auto Lnk =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
627 if (Lnk == SPIRV::LinkageType::Import) {
632 MAI.GlobalObjMap[ImportedFunc] =
633 MAI.getRegisterAlias(
MI.getMF(), Target);
636 }
else if (
MI.getOpcode() == SPIRV::OpFunction) {
639 MCRegister GlobalReg =
MAI.getRegisterAlias(
MI.getMF(),
Reg);
641 MAI.GlobalObjMap[
F] = GlobalReg;
653 auto FoundMI = IS.insert(std::move(MISign));
654 if (!FoundMI.second) {
655 if (
MI.getOpcode() == SPIRV::OpDecorate) {
657 "Decoration instructions must have at least 2 operands");
659 "Only OpDecorate instructions can be duplicates");
664 if (
MI.getOperand(1).getImm() != SPIRV::Decoration::FPFastMathMode)
670 assert(OrigMI->getNumOperands() ==
MI.getNumOperands() &&
671 "Original instruction must have the same number of operands");
673 OrigMI->getNumOperands() == 3 &&
674 "FPFastMathMode decoration must have 3 operands for OpDecorate");
675 unsigned OrigFlags = OrigMI->getOperand(2).getImm();
676 unsigned NewFlags =
MI.getOperand(2).getImm();
677 if (OrigFlags == NewFlags)
681 unsigned FinalFlags = OrigFlags | NewFlags;
683 <<
"Warning: Conflicting FPFastMathMode decoration flags "
685 << *OrigMI <<
"Original flags: " << OrigFlags
686 <<
", new flags: " << NewFlags
687 <<
". They will be merged on a best effort basis, but not "
688 "validated. Final flags: "
689 << FinalFlags <<
"\n";
696 assert(
false &&
"No original instruction found for the duplicate "
697 "OpDecorate, but we found one in IS.");
710void SPIRVModuleAnalysis::processOtherInstrs(
const Module &M) {
713 if (
F.isDeclaration())
718 for (MachineBasicBlock &
MBB : *MF)
719 for (MachineInstr &
MI :
MBB) {
720 if (
MAI.getSkipEmission(&
MI))
722 const unsigned OpCode =
MI.getOpcode();
723 if (OpCode == SPIRV::OpString) {
725 }
else if (OpCode == SPIRV::OpExtInst &&
MI.getOperand(2).isImm() &&
726 MI.getOperand(2).getImm() ==
727 SPIRV::InstructionSet::
728 NonSemantic_Shader_DebugInfo_100) {
735 MachineOperand Ins =
MI.getOperand(3);
736 namespace NS = SPIRV::NonSemanticExtInst;
737 static constexpr int64_t GlobalNonSemanticDITy[] = {
738 NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
739 NS::DebugTypeBasic, NS::DebugTypePointer};
740 bool IsGlobalDI =
false;
741 for (
unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
742 IsGlobalDI |= Ins.
getImm() == GlobalNonSemanticDITy[Idx];
745 }
else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
747 }
else if (OpCode == SPIRV::OpEntryPoint) {
749 }
else if (TII->isAliasingInstr(
MI)) {
751 }
else if (TII->isDecorationInstr(
MI)) {
753 collectFuncNames(
MI, &
F);
754 }
else if (TII->isConstantInstr(
MI)) {
758 }
else if (OpCode == SPIRV::OpFunction) {
759 collectFuncNames(
MI, &
F);
760 }
else if (OpCode == SPIRV::OpTypeForwardPointer) {
768 auto AliasingTier = [](
const MachineInstr *
MI) {
769 switch (
MI->getOpcode()) {
770 case SPIRV::OpAliasDomainDeclINTEL:
772 case SPIRV::OpAliasScopeDeclINTEL:
774 case SPIRV::OpAliasScopeListDeclINTEL:
781 [&](
const MachineInstr *
LHS,
const MachineInstr *
RHS) {
782 return AliasingTier(LHS) < AliasingTier(RHS);
789void SPIRVModuleAnalysis::numberRegistersGlobally(
const Module &M) {
791 if (
F.isDeclaration())
795 for (MachineBasicBlock &
MBB : *MF) {
796 for (MachineInstr &
MI :
MBB) {
797 for (MachineOperand &
Op :
MI.operands()) {
801 if (
MAI.hasRegisterAlias(MF,
Reg))
803 MCRegister NewReg =
MAI.getNextIDRegister();
804 MAI.setRegisterAlias(MF,
Reg, NewReg);
806 if (
MI.getOpcode() != SPIRV::OpExtInst)
808 auto Set =
MI.getOperand(2).getImm();
809 auto [It,
Inserted] =
MAI.ExtInstSetMap.try_emplace(Set);
811 It->second =
MAI.getNextIDRegister();
819 SPIRV::OperandCategory::OperandCategory Category,
uint32_t i,
824void SPIRV::RequirementHandler::recursiveAddCapabilities(
826 for (
const auto &Cap : ToPrune) {
830 recursiveAddCapabilities(ImplicitDecls);
835 for (
const auto &Cap : ToAdd) {
836 bool IsNewlyInserted = AllCaps.insert(Cap).second;
837 if (!IsNewlyInserted)
841 recursiveAddCapabilities(ImplicitDecls);
842 MinimalCaps.push_back(Cap);
851 if (Req.
Cap.has_value())
857 if (!MaxVersion.empty() && Req.
MinVer > MaxVersion) {
859 <<
" and <= " << MaxVersion <<
"\n");
863 if (MinVersion.empty() || Req.
MinVer > MinVersion)
868 if (!MinVersion.empty() && Req.
MaxVer < MinVersion) {
870 <<
" and >= " << MinVersion <<
"\n");
874 if (MaxVersion.empty() || Req.
MaxVer < MaxVersion)
882 bool IsSatisfiable =
true;
883 auto TargetVer = ST.getSPIRVVersion();
885 if (!MaxVersion.empty() && !TargetVer.empty() && MaxVersion < TargetVer) {
887 dbgs() <<
"Target SPIR-V version too high for required features\n"
888 <<
"Required max version: " << MaxVersion <<
" target version "
889 << TargetVer <<
"\n");
890 IsSatisfiable =
false;
893 if (!MinVersion.empty() && !TargetVer.empty() && MinVersion > TargetVer) {
894 LLVM_DEBUG(
dbgs() <<
"Target SPIR-V version too low for required features\n"
895 <<
"Required min version: " << MinVersion
896 <<
" target version " << TargetVer <<
"\n");
897 IsSatisfiable =
false;
900 if (!MinVersion.empty() && !MaxVersion.empty() && MinVersion > MaxVersion) {
903 <<
"Version is too low for some features and too high for others.\n"
904 <<
"Required SPIR-V min version: " << MinVersion
905 <<
" required SPIR-V max version " << MaxVersion <<
"\n");
906 IsSatisfiable =
false;
911 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
913 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
915 for (
auto Cap : MinimalCaps) {
916 if (AvailableCaps.contains(Cap) && !AvoidCaps.
S.
contains(Cap))
920 OperandCategory::CapabilityOperand, Cap)
922 IsSatisfiable =
false;
925 for (
auto Ext : AllExtensions) {
926 if (ST.canUseExtension(Ext))
930 OperandCategory::ExtensionOperand, Ext)
932 IsSatisfiable =
false;
941 for (
const auto Cap : ToAdd)
942 if (AvailableCaps.insert(Cap).second)
944 SPIRV::OperandCategory::CapabilityOperand, Cap));
948 const Capability::Capability
ToRemove,
949 const Capability::Capability IfPresent) {
950 if (AllCaps.contains(IfPresent)) {
960 addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8,
965 Capability::GroupNonUniformVote,
966 Capability::GroupNonUniformArithmetic,
967 Capability::GroupNonUniformBallot,
968 Capability::GroupNonUniformClustered,
969 Capability::GroupNonUniformShuffle,
970 Capability::GroupNonUniformShuffleRelative,
971 Capability::GroupNonUniformQuad});
975 Capability::DotProductInput4x8Bit,
976 Capability::DotProductInput4x8BitPacked,
977 Capability::DemoteToHelperInvocation});
980 for (
auto Extension : ST.getAllAvailableExtensions()) {
986 if (!ST.isShader()) {
987 initAvailableCapabilitiesForOpenCL(ST);
992 initAvailableCapabilitiesForVulkan(ST);
999void RequirementHandler::initAvailableCapabilitiesForOpenCL(
1003 Capability::Kernel, Capability::Vector16,
1004 Capability::Groups, Capability::GenericPointer,
1005 Capability::StorageImageWriteWithoutFormat,
1006 Capability::StorageImageReadWithoutFormat});
1007 if (ST.hasOpenCLFullProfile())
1009 if (ST.hasOpenCLImageSupport()) {
1011 Capability::Image1D, Capability::SampledBuffer,
1012 Capability::ImageBuffer});
1013 if (
ST.isAtLeastOpenCLVer(VersionTuple(2, 0)))
1016 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) &&
1017 ST.isAtLeastOpenCLVer(VersionTuple(2, 2)))
1019 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 4)))
1020 addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
1021 Capability::SignedZeroInfNanPreserve,
1022 Capability::RoundingModeRTE,
1023 Capability::RoundingModeRTZ});
1030void RequirementHandler::initAvailableCapabilitiesForVulkan(
1031 const SPIRVSubtarget &ST) {
1035 Capability::Float16,
1036 Capability::Float64,
1037 Capability::GroupNonUniform,
1038 Capability::Image1D,
1039 Capability::SampledBuffer,
1040 Capability::ImageBuffer,
1041 Capability::UniformBufferArrayDynamicIndexing,
1042 Capability::SampledImageArrayDynamicIndexing,
1043 Capability::StorageBufferArrayDynamicIndexing,
1044 Capability::StorageImageArrayDynamicIndexing,
1045 Capability::DerivativeControl,
1047 Capability::ImageQuery,
1048 Capability::ImageGatherExtended,
1049 Capability::Addresses,
1050 Capability::VulkanMemoryModelKHR,
1051 Capability::StorageImageExtendedFormats,
1052 Capability::StorageImageMultisample,
1053 Capability::ImageMSArray});
1056 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
1058 {Capability::Int64Atomics, Capability::ShaderNonUniformEXT,
1059 Capability::RuntimeDescriptorArrayEXT,
1060 Capability::InputAttachmentArrayDynamicIndexingEXT,
1061 Capability::UniformTexelBufferArrayDynamicIndexingEXT,
1062 Capability::StorageTexelBufferArrayDynamicIndexingEXT,
1063 Capability::UniformBufferArrayNonUniformIndexingEXT,
1064 Capability::SampledImageArrayNonUniformIndexingEXT,
1065 Capability::StorageBufferArrayNonUniformIndexingEXT,
1066 Capability::StorageImageArrayNonUniformIndexingEXT,
1067 Capability::InputAttachmentArrayNonUniformIndexingEXT,
1068 Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
1069 Capability::StorageTexelBufferArrayNonUniformIndexingEXT});
1073 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
1075 Capability::StorageImageReadWithoutFormat});
1086 int64_t DecOp =
MI.getOperand(DecIndex).getImm();
1087 auto Dec =
static_cast<SPIRV::Decoration::Decoration
>(DecOp);
1089 SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
1091 if (Dec == SPIRV::Decoration::BuiltIn) {
1092 int64_t BuiltInOp =
MI.getOperand(DecIndex + 1).getImm();
1093 auto BuiltIn =
static_cast<SPIRV::BuiltIn::BuiltIn
>(BuiltInOp);
1095 SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
1096 }
else if (Dec == SPIRV::Decoration::LinkageAttributes) {
1097 int64_t LinkageOp =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
1098 SPIRV::LinkageType::LinkageType LnkType =
1099 static_cast<SPIRV::LinkageType::LinkageType
>(LinkageOp);
1100 if (LnkType == SPIRV::LinkageType::LinkOnceODR)
1101 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_linkonce_odr);
1102 else if (LnkType == SPIRV::LinkageType::WeakAMD) {
1103 Reqs.
addExtension(SPIRV::Extension::SPV_AMD_weak_linkage);
1106 }
else if (Dec == SPIRV::Decoration::CacheControlLoadINTEL ||
1107 Dec == SPIRV::Decoration::CacheControlStoreINTEL) {
1108 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_cache_controls);
1109 }
else if (Dec == SPIRV::Decoration::HostAccessINTEL) {
1110 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_global_variable_host_access);
1111 }
else if (Dec == SPIRV::Decoration::InitModeINTEL ||
1112 Dec == SPIRV::Decoration::ImplementInRegisterMapINTEL) {
1114 SPIRV::Extension::SPV_INTEL_global_variable_fpga_decorations);
1115 }
else if (Dec == SPIRV::Decoration::NonUniformEXT) {
1117 }
else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
1119 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_fp_max_error);
1120 }
else if (Dec == SPIRV::Decoration::FPFastMathMode) {
1121 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
1123 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_float_controls2);
1132 assert(
MI.getNumOperands() >= 8 &&
"Insufficient operands for OpTypeImage");
1135 int64_t ImgFormatOp =
MI.getOperand(7).getImm();
1136 auto ImgFormat =
static_cast<SPIRV::ImageFormat::ImageFormat
>(ImgFormatOp);
1140 bool IsArrayed =
MI.getOperand(4).getImm() == 1;
1141 bool IsMultisampled =
MI.getOperand(5).getImm() == 1;
1142 bool NoSampler =
MI.getOperand(6).getImm() == 2;
1145 switch (
MI.getOperand(2).getImm()) {
1146 case SPIRV::Dim::DIM_1D:
1148 : SPIRV::Capability::Sampled1D);
1150 case SPIRV::Dim::DIM_2D:
1151 if (IsMultisampled && NoSampler)
1153 if (IsMultisampled && IsArrayed)
1156 case SPIRV::Dim::DIM_3D:
1158 case SPIRV::Dim::DIM_Cube:
1162 : SPIRV::Capability::SampledCubeArray);
1164 case SPIRV::Dim::DIM_Rect:
1166 : SPIRV::Capability::SampledRect);
1168 case SPIRV::Dim::DIM_Buffer:
1170 : SPIRV::Capability::SampledBuffer);
1172 case SPIRV::Dim::DIM_SubpassData:
1178 if (!ST.isShader()) {
1179 if (
MI.getNumOperands() > 8 &&
1180 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
1189 TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
1195#define ATOM_FLT_REQ_EXT_MSG(ExtName) \
1196 "The atomic float instruction requires the following SPIR-V " \
1197 "extension: SPV_EXT_shader_atomic_float" ExtName
1202 MI.getMF()->getRegInfo().getVRegDef(
MI.getOperand(1).getReg());
1205 if (Rank != 2 && Rank != 4)
1207 "must be a 2-component or 4 component vector");
1212 if (EltTypeDef->
getOpcode() != SPIRV::OpTypeFloat ||
1215 "The element type for the result type of an atomic vector float "
1216 "instruction must be a 16-bit floating-point scalar");
1223 "The element type for the result type of an atomic vector float "
1224 "instruction cannot be a bfloat16 scalar");
1225 if (!ST.canUseExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector))
1227 "The atomic float16 vector instruction requires the following SPIR-V "
1228 "extension: SPV_NV_shader_atomic_fp16_vector");
1230 Reqs.
addExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector);
1231 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16VectorNV);
1238 "Expect register operand in atomic float instruction");
1239 Register TypeReg =
MI.getOperand(1).getReg();
1245 if (TypeDef->
getOpcode() != SPIRV::OpTypeFloat)
1247 "floating-point type scalar");
1250 unsigned Op =
MI.getOpcode();
1251 if (
Op == SPIRV::OpAtomicFAddEXT) {
1252 if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add))
1254 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
1258 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1260 "The atomic bfloat16 instruction requires the following SPIR-V "
1261 "extension: SPV_INTEL_16bit_atomics",
1263 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1264 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16AddINTEL);
1266 if (!ST.canUseExtension(
1267 SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
1269 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
1281 "Unexpected floating-point type width in atomic float instruction");
1284 if (!ST.canUseExtension(
1285 SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max))
1287 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
1291 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1293 "The atomic bfloat16 instruction requires the following SPIR-V "
1294 "extension: SPV_INTEL_16bit_atomics",
1296 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1297 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16MinMaxINTEL);
1299 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
1303 Reqs.
addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
1306 Reqs.
addCapability(SPIRV::Capability::AtomicFloat64MinMaxEXT);
1310 "Unexpected floating-point type width in atomic float instruction");
1316 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1320 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
1324 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1328 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
1332 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1336 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
1340 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1344 return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
1348 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1352 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
1356 if (SampledImageInst->
getOpcode() != SPIRV::OpTypeSampledImage)
1367 if (
MI.getOpcode() != SPIRV::OpDecorate)
1371 if (Dec == SPIRV::Decoration::NonUniformEXT)
1384 Register ResTypeReg = Instr.getOperand(1).getReg();
1389 if (
StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
1390 StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
1391 StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
1398 auto FirstIndexReg = Instr.getOperand(3).getReg();
1399 bool FirstIndexIsConstant =
1402 if (
StorageClass == SPIRV::StorageClass::StorageClass::StorageBuffer) {
1405 SPIRV::Capability::StorageBufferArrayNonUniformIndexingEXT);
1406 else if (!FirstIndexIsConstant)
1408 SPIRV::Capability::StorageBufferArrayDynamicIndexing);
1414 if (PointeeType->
getOpcode() != SPIRV::OpTypeImage &&
1415 PointeeType->
getOpcode() != SPIRV::OpTypeSampledImage &&
1416 PointeeType->
getOpcode() != SPIRV::OpTypeSampler) {
1423 SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1424 else if (!FirstIndexIsConstant)
1426 SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
1430 SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1431 else if (!FirstIndexIsConstant)
1433 SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
1437 SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1438 else if (!FirstIndexIsConstant)
1440 SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
1443 PointeeType->
getOpcode() == SPIRV::OpTypeSampler) {
1446 SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1447 else if (!FirstIndexIsConstant)
1449 SPIRV::Capability::SampledImageArrayDynamicIndexing);
1453 SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1454 else if (!FirstIndexIsConstant)
1456 SPIRV::Capability::StorageImageArrayDynamicIndexing);
1461 if (TypeInst->
getOpcode() != SPIRV::OpTypeImage)
1470 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product))
1471 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_integer_dot_product);
1475 assert(
MI.getOperand(2).isReg() &&
"Unexpected operand in dot");
1479 assert(
Input->getOperand(1).isReg() &&
"Unexpected operand in dot input");
1483 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1485 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8BitPacked);
1492 "Dot operand of 8-bit integer type requires 4 components");
1493 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8Bit);
1509 unsigned AddrSpace = ASOp.
getImm();
1510 if (AddrSpace != SPIRV::StorageClass::UniformConstant) {
1511 if (!ST.canUseExtension(
1513 SPV_EXT_relaxed_printf_string_address_space)) {
1515 "required because printf uses a format string not "
1516 "in constant address space.",
1520 SPIRV::Extension::SPV_EXT_relaxed_printf_string_address_space);
1529 if (
MI.getNumOperands() <= OpIdx)
1531 uint32_t Mask =
MI.getOperand(OpIdx).getImm();
1533 if (Mask & (1U <<
I))
1544 if (ElemTypeDef->
getOpcode() == SPIRV::OpTypePointer &&
1545 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
1546 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter);
1547 Reqs.
addCapability(SPIRV::Capability::MaskedGatherScatterINTEL);
1555 unsigned Op =
MI.getOpcode();
1557 case SPIRV::OpMemoryModel: {
1558 int64_t Addr =
MI.getOperand(0).getImm();
1561 int64_t Mem =
MI.getOperand(1).getImm();
1566 case SPIRV::OpEntryPoint: {
1567 int64_t Exe =
MI.getOperand(0).getImm();
1572 case SPIRV::OpExecutionMode:
1573 case SPIRV::OpExecutionModeId: {
1574 int64_t Exe =
MI.getOperand(1).getImm();
1579 case SPIRV::OpTypeMatrix:
1582 case SPIRV::OpTypeInt: {
1583 unsigned BitWidth =
MI.getOperand(1).getImm();
1591 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1595 if (!ST.canUseExtension(
1596 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers))
1598 "OpTypeInt type with a width other than 8, 16, 32 or 64 bits "
1599 "requires the following SPIR-V extension: "
1600 "SPV_ALTERA_arbitrary_precision_integers");
1602 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
1603 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
1607 case SPIRV::OpDot: {
1611 Reqs.
addCapability(SPIRV::Capability::BFloat16DotProductKHR);
1614 case SPIRV::OpTypeFloat: {
1615 unsigned BitWidth =
MI.getOperand(1).getImm();
1620 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_bfloat16))
1622 "following SPIR-V extension: SPV_KHR_bfloat16",
1632 case SPIRV::OpTypeVector: {
1633 unsigned NumComponents =
MI.getOperand(2).getImm();
1634 if (NumComponents == 8 || NumComponents == 16)
1639 "OpTypeVector with " +
Twine(NumComponents) +
1640 " components requires the following SPIR-V extension: "
1641 "SPV_EXT_long_vector");
1646 case SPIRV::OpTypeVectorIdEXT: {
1647 if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_long_vector))
1649 "extension: SPV_EXT_long_vector extension");
1650 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_long_vector);
1655 case SPIRV::OpTypePointer: {
1656 auto SC =
MI.getOperand(1).getImm();
1667 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1672 case SPIRV::OpExtInst: {
1673 if (
MI.getOperand(2).getImm() ==
1674 static_cast<int64_t
>(
1675 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1676 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1679 if (
MI.getOperand(3).getImm() ==
1680 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1684 if (
MI.getOperand(2).getImm() ==
1685 static_cast<int64_t
>(SPIRV::InstructionSet::OpenCL_std)) {
1691 if (TypeDef && TypeDef->getOpcode() == SPIRV::OpTypeVector)
1692 TypeDef = MRI.
getVRegDef(TypeDef->getOperand(1).getReg());
1697 bool UsesBFloat16 = IsBFloat16(MRI.
getVRegDef(
MI.getOperand(1).getReg()));
1698 for (
unsigned I = 4,
E =
MI.getNumOperands();
I <
E && !UsesBFloat16;
1707 if (!ST.canUseExtension(
1708 SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic)) {
1710 MI,
"OpenCL Extended instructions with bfloat16 require the "
1711 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic");
1714 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
1715 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
1720 case SPIRV::OpAliasDomainDeclINTEL:
1721 case SPIRV::OpAliasScopeDeclINTEL:
1722 case SPIRV::OpAliasScopeListDeclINTEL: {
1723 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1724 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1727 case SPIRV::OpBitReverse:
1728 case SPIRV::OpBitFieldInsert:
1729 case SPIRV::OpBitFieldSExtract:
1730 case SPIRV::OpBitFieldUExtract:
1731 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1735 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1738 case SPIRV::OpTypeRuntimeArray:
1741 case SPIRV::OpTypeOpaque:
1742 case SPIRV::OpTypeEvent:
1745 case SPIRV::OpTypePipe:
1746 case SPIRV::OpTypeReserveId:
1749 case SPIRV::OpTypeDeviceEvent:
1750 case SPIRV::OpTypeQueue:
1751 case SPIRV::OpBuildNDRange:
1752 case SPIRV::OpEnqueueKernel:
1755 case SPIRV::OpDecorate:
1756 case SPIRV::OpDecorateId:
1757 case SPIRV::OpDecorateString:
1760 case SPIRV::OpMemberDecorate:
1761 case SPIRV::OpMemberDecorateString:
1764 case SPIRV::OpInBoundsPtrAccessChain:
1767 case SPIRV::OpConstantSampler:
1770 case SPIRV::OpInBoundsAccessChain:
1771 case SPIRV::OpAccessChain:
1774 case SPIRV::OpTypeImage:
1777 case SPIRV::OpTypeSampler:
1778 if (!ST.isShader()) {
1782 case SPIRV::OpTypeForwardPointer:
1786 case SPIRV::OpAtomicFlagTestAndSet:
1787 case SPIRV::OpAtomicLoad:
1788 case SPIRV::OpAtomicStore:
1789 case SPIRV::OpAtomicExchange:
1790 case SPIRV::OpAtomicCompareExchange:
1791 case SPIRV::OpAtomicCompareExchangeWeak:
1792 case SPIRV::OpAtomicIIncrement:
1793 case SPIRV::OpAtomicIDecrement:
1794 case SPIRV::OpAtomicIAdd:
1795 case SPIRV::OpAtomicISub:
1796 case SPIRV::OpAtomicUMin:
1797 case SPIRV::OpAtomicUMax:
1798 case SPIRV::OpAtomicSMin:
1799 case SPIRV::OpAtomicSMax:
1800 case SPIRV::OpAtomicAnd:
1801 case SPIRV::OpAtomicOr:
1802 case SPIRV::OpAtomicXor: {
1805 if (
Op == SPIRV::OpAtomicStore) {
1808 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1814 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1819 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1821 "16-bit integer atomic operations require the following SPIR-V "
1822 "extension: SPV_INTEL_16bit_atomics",
1824 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1826 case SPIRV::OpAtomicLoad:
1827 case SPIRV::OpAtomicStore:
1828 case SPIRV::OpAtomicExchange:
1829 case SPIRV::OpAtomicCompareExchange:
1830 case SPIRV::OpAtomicCompareExchangeWeak:
1832 SPIRV::Capability::AtomicInt16CompareExchangeINTEL);
1840 if (
is_contained({SPIRV::OpAtomicLoad, SPIRV::OpAtomicStore,
1841 SPIRV::OpAtomicExchange},
1843 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1845 "The atomic bfloat16 instruction requires the following SPIR-V "
1846 "extension: SPV_INTEL_16bit_atomics",
1848 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1849 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16LoadStoreINTEL);
1854 case SPIRV::OpGroupNonUniformIAdd:
1855 case SPIRV::OpGroupNonUniformFAdd:
1856 case SPIRV::OpGroupNonUniformIMul:
1857 case SPIRV::OpGroupNonUniformFMul:
1858 case SPIRV::OpGroupNonUniformSMin:
1859 case SPIRV::OpGroupNonUniformUMin:
1860 case SPIRV::OpGroupNonUniformFMin:
1861 case SPIRV::OpGroupNonUniformSMax:
1862 case SPIRV::OpGroupNonUniformUMax:
1863 case SPIRV::OpGroupNonUniformFMax:
1864 case SPIRV::OpGroupNonUniformBitwiseAnd:
1865 case SPIRV::OpGroupNonUniformBitwiseOr:
1866 case SPIRV::OpGroupNonUniformBitwiseXor:
1867 case SPIRV::OpGroupNonUniformLogicalAnd:
1868 case SPIRV::OpGroupNonUniformLogicalOr:
1869 case SPIRV::OpGroupNonUniformLogicalXor: {
1871 int64_t GroupOp =
MI.getOperand(3).getImm();
1873 case SPIRV::GroupOperation::Reduce:
1874 case SPIRV::GroupOperation::InclusiveScan:
1875 case SPIRV::GroupOperation::ExclusiveScan:
1876 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1878 case SPIRV::GroupOperation::ClusteredReduce:
1879 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1881 case SPIRV::GroupOperation::PartitionedReduceNV:
1882 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1883 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1884 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1889 case SPIRV::OpGroupNonUniformQuadSwap:
1892 case SPIRV::OpImageQueryLod:
1895 case SPIRV::OpImageQuerySize:
1896 case SPIRV::OpImageQuerySizeLod:
1897 case SPIRV::OpImageQueryLevels:
1898 case SPIRV::OpImageQuerySamples:
1902 case SPIRV::OpImageQueryFormat: {
1903 Register ResultReg =
MI.getOperand(0).getReg();
1905 static const unsigned CompareOps[] = {
1906 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1907 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1908 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1909 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1910 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1912 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1913 if (ImmVal == 4323 || ImmVal == 4324) {
1914 if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1915 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1918 "SPV_EXT_image_raw10_raw12 extension");
1923 unsigned Opc = UseInst.getOpcode();
1925 if (
Opc == SPIRV::OpSwitch) {
1928 CheckAndAddExtension(
Op.getImm());
1930 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1933 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1936 CheckAndAddExtension(ImmVal);
1944 case SPIRV::OpGroupNonUniformShuffle:
1945 case SPIRV::OpGroupNonUniformShuffleXor:
1946 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1948 case SPIRV::OpGroupNonUniformShuffleUp:
1949 case SPIRV::OpGroupNonUniformShuffleDown:
1950 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1952 case SPIRV::OpGroupAll:
1953 case SPIRV::OpGroupAny:
1954 case SPIRV::OpGroupBroadcast:
1955 case SPIRV::OpGroupIAdd:
1956 case SPIRV::OpGroupFAdd:
1957 case SPIRV::OpGroupFMin:
1958 case SPIRV::OpGroupUMin:
1959 case SPIRV::OpGroupSMin:
1960 case SPIRV::OpGroupFMax:
1961 case SPIRV::OpGroupUMax:
1962 case SPIRV::OpGroupSMax:
1965 case SPIRV::OpGroupNonUniformElect:
1968 case SPIRV::OpGroupNonUniformAll:
1969 case SPIRV::OpGroupNonUniformAny:
1970 case SPIRV::OpGroupNonUniformAllEqual:
1973 case SPIRV::OpGroupNonUniformBroadcast:
1974 case SPIRV::OpGroupNonUniformBroadcastFirst:
1975 case SPIRV::OpGroupNonUniformBallot:
1976 case SPIRV::OpGroupNonUniformInverseBallot:
1977 case SPIRV::OpGroupNonUniformBallotBitExtract:
1978 case SPIRV::OpGroupNonUniformBallotBitCount:
1979 case SPIRV::OpGroupNonUniformBallotFindLSB:
1980 case SPIRV::OpGroupNonUniformBallotFindMSB:
1981 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1983 case SPIRV::OpSubgroupShuffleINTEL:
1984 case SPIRV::OpSubgroupShuffleDownINTEL:
1985 case SPIRV::OpSubgroupShuffleUpINTEL:
1986 case SPIRV::OpSubgroupShuffleXorINTEL:
1987 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1988 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1989 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1992 case SPIRV::OpSubgroupBlockReadINTEL:
1993 case SPIRV::OpSubgroupBlockWriteINTEL:
1994 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1995 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1996 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1999 case SPIRV::OpSubgroupImageBlockReadINTEL:
2000 case SPIRV::OpSubgroupImageBlockWriteINTEL:
2001 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
2002 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
2003 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
2006 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
2007 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
2008 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
2009 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
2010 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
2013 case SPIRV::OpAssumeTrueKHR:
2014 case SPIRV::OpExpectKHR:
2015 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
2016 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
2020 case SPIRV::OpFmaKHR:
2021 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
2026 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
2027 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
2028 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
2029 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
2030 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
2033 case SPIRV::OpConstantFunctionPointerINTEL:
2034 case SPIRV::OpFunctionPointerCallINTEL:
2035 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
2036 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
2037 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
2040 case SPIRV::OpGroupNonUniformRotateKHR:
2041 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
2043 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
2045 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
2046 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
2049 case SPIRV::OpFixedCosALTERA:
2050 case SPIRV::OpFixedSinALTERA:
2051 case SPIRV::OpFixedCosPiALTERA:
2052 case SPIRV::OpFixedSinPiALTERA:
2053 case SPIRV::OpFixedExpALTERA:
2054 case SPIRV::OpFixedLogALTERA:
2055 case SPIRV::OpFixedRecipALTERA:
2056 case SPIRV::OpFixedSqrtALTERA:
2057 case SPIRV::OpFixedSinCosALTERA:
2058 case SPIRV::OpFixedSinCosPiALTERA:
2059 case SPIRV::OpFixedRsqrtALTERA:
2060 if (!ST.canUseExtension(
2061 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
2063 "following SPIR-V extension: "
2064 "SPV_ALTERA_arbitrary_precision_fixed_point",
2067 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
2068 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
2070 case SPIRV::OpGroupIMulKHR:
2071 case SPIRV::OpGroupFMulKHR:
2072 case SPIRV::OpGroupBitwiseAndKHR:
2073 case SPIRV::OpGroupBitwiseOrKHR:
2074 case SPIRV::OpGroupBitwiseXorKHR:
2075 case SPIRV::OpGroupLogicalAndKHR:
2076 case SPIRV::OpGroupLogicalOrKHR:
2077 case SPIRV::OpGroupLogicalXorKHR:
2078 if (ST.canUseExtension(
2079 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
2080 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
2081 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
2084 case SPIRV::OpReadClockKHR:
2085 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
2087 "following SPIR-V extension: SPV_KHR_shader_clock",
2089 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
2092 case SPIRV::OpAbortKHR:
2093 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_abort))
2095 "following SPIR-V extension: SPV_KHR_abort",
2100 case SPIRV::OpPoisonKHR:
2101 case SPIRV::OpFreezeKHR:
2102 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_poison_freeze))
2104 "following SPIR-V extension: SPV_KHR_poison_freeze",
2106 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_poison_freeze);
2109 case SPIRV::OpAtomicFAddEXT:
2110 case SPIRV::OpAtomicFMinEXT:
2111 case SPIRV::OpAtomicFMaxEXT:
2114 case SPIRV::OpConvertBF16ToFINTEL:
2115 case SPIRV::OpConvertFToBF16INTEL:
2116 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
2117 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
2118 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
2121 case SPIRV::OpRoundFToTF32INTEL:
2122 if (ST.canUseExtension(
2123 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
2124 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
2125 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
2128 case SPIRV::OpVariableLengthArrayINTEL:
2129 case SPIRV::OpSaveMemoryINTEL:
2130 case SPIRV::OpRestoreMemoryINTEL:
2131 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
2132 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
2133 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
2136 case SPIRV::OpAsmTargetINTEL:
2137 case SPIRV::OpAsmINTEL:
2138 case SPIRV::OpAsmCallINTEL:
2139 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
2140 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
2144 case SPIRV::OpTypeCooperativeMatrixKHR: {
2145 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2147 "OpTypeCooperativeMatrixKHR type requires the "
2148 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
2150 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2151 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2155 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
2158 case SPIRV::OpArithmeticFenceEXT:
2159 if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
2161 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
2163 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
2166 case SPIRV::OpControlBarrierArriveINTEL:
2167 case SPIRV::OpControlBarrierWaitINTEL:
2168 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
2169 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
2173 case SPIRV::OpCooperativeMatrixMulAddKHR: {
2174 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2176 "following SPIR-V extension: "
2177 "SPV_KHR_cooperative_matrix",
2179 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2180 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2181 constexpr unsigned MulAddMaxSize = 6;
2182 if (
MI.getNumOperands() != MulAddMaxSize)
2184 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
2186 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
2187 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2189 "require the following SPIR-V extension: "
2190 "SPV_INTEL_joint_matrix",
2192 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2194 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
2197 MatrixAAndBBFloat16ComponentsINTEL ||
2199 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
2201 MatrixResultBFloat16ComponentsINTEL) {
2202 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2204 "require the following SPIR-V extension: "
2205 "SPV_INTEL_joint_matrix",
2207 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2209 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
2213 case SPIRV::OpCooperativeMatrixLoadKHR:
2214 case SPIRV::OpCooperativeMatrixStoreKHR:
2215 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2216 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2217 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
2218 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2220 "following SPIR-V extension: "
2221 "SPV_KHR_cooperative_matrix",
2223 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2224 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2230 case SPIRV::OpCooperativeMatrixLoadKHR:
2233 case SPIRV::OpCooperativeMatrixStoreKHR:
2236 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2239 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2240 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2246 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
2249 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
2252 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
2253 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2255 "extension: SPV_INTEL_joint_matrix",
2257 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2258 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2263 if (
Op == SPIRV::OpCooperativeMatrixLoadKHR ||
2264 Op == SPIRV::OpCooperativeMatrixStoreKHR)
2267 std::string InstName;
2269 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2270 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2272 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2273 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2275 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2276 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2280 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2281 const std::string ErrorMsg =
2282 InstName +
" instruction requires the "
2283 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2286 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2287 if (
Op == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2288 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2292 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2295 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2296 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2298 "instructions require the following SPIR-V extension: "
2299 "SPV_INTEL_joint_matrix",
2301 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2303 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2305 case SPIRV::OpReadPipeBlockingALTERA:
2306 case SPIRV::OpWritePipeBlockingALTERA:
2307 if (ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2308 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2312 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2313 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2315 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2317 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2319 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2321 case SPIRV::OpConvertHandleToImageINTEL:
2322 case SPIRV::OpConvertHandleToSamplerINTEL:
2323 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2324 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2326 "instructions require the following SPIR-V extension: "
2327 "SPV_INTEL_bindless_images",
2330 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2332 if (
Op == SPIRV::OpConvertHandleToImageINTEL &&
2333 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2335 "OpConvertHandleToImageINTEL",
2337 }
else if (
Op == SPIRV::OpConvertHandleToSamplerINTEL &&
2338 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2340 "OpConvertHandleToSamplerINTEL",
2342 }
else if (
Op == SPIRV::OpConvertHandleToSampledImageINTEL &&
2343 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2345 "OpConvertHandleToSampledImageINTEL",
2350 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2351 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2353 "Parameter value must be a 32-bit scalar in case of "
2354 "Physical32 addressing model or a 64-bit scalar in case of "
2355 "Physical64 addressing model",
2358 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2362 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2363 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2364 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2365 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2366 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2367 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2369 "Prefetch/Store]INTEL instructions require the "
2370 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2372 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2373 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2375 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2376 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2379 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2380 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2385 case SPIRV::OpKill: {
2388 case SPIRV::OpDemoteToHelperInvocation:
2389 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2391 if (ST.canUseExtension(
2392 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2395 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2400 case SPIRV::OpSUDot:
2401 case SPIRV::OpSDotAccSat:
2402 case SPIRV::OpUDotAccSat:
2403 case SPIRV::OpSUDotAccSat:
2406 case SPIRV::OpImageSampleImplicitLod:
2407 case SPIRV::OpImageFetch:
2411 case SPIRV::OpImageSampleExplicitLod:
2414 case SPIRV::OpImageSampleDrefImplicitLod:
2415 case SPIRV::OpImageSampleDrefExplicitLod:
2416 case SPIRV::OpImageDrefGather:
2417 case SPIRV::OpImageGather:
2421 case SPIRV::OpImageRead: {
2422 Register ImageReg =
MI.getOperand(2).getReg();
2423 SPIRVTypeInst TypeDef = ST.getSPIRVGlobalRegistry()->getResultType(
2432 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2435 case SPIRV::OpImageWrite: {
2436 Register ImageReg =
MI.getOperand(0).getReg();
2437 SPIRVTypeInst TypeDef = ST.getSPIRVGlobalRegistry()->getResultType(
2446 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2449 case SPIRV::OpTypeStructContinuedINTEL:
2450 case SPIRV::OpConstantCompositeContinuedINTEL:
2451 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2452 case SPIRV::OpCompositeConstructContinuedINTEL: {
2453 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2455 "Continued instructions require the "
2456 "following SPIR-V extension: SPV_INTEL_long_composites",
2458 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2462 case SPIRV::OpArbitraryFloatEQALTERA:
2463 case SPIRV::OpArbitraryFloatGEALTERA:
2464 case SPIRV::OpArbitraryFloatGTALTERA:
2465 case SPIRV::OpArbitraryFloatLEALTERA:
2466 case SPIRV::OpArbitraryFloatLTALTERA:
2467 case SPIRV::OpArbitraryFloatCbrtALTERA:
2468 case SPIRV::OpArbitraryFloatCosALTERA:
2469 case SPIRV::OpArbitraryFloatCosPiALTERA:
2470 case SPIRV::OpArbitraryFloatExp10ALTERA:
2471 case SPIRV::OpArbitraryFloatExp2ALTERA:
2472 case SPIRV::OpArbitraryFloatExpALTERA:
2473 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2474 case SPIRV::OpArbitraryFloatHypotALTERA:
2475 case SPIRV::OpArbitraryFloatLog10ALTERA:
2476 case SPIRV::OpArbitraryFloatLog1pALTERA:
2477 case SPIRV::OpArbitraryFloatLog2ALTERA:
2478 case SPIRV::OpArbitraryFloatLogALTERA:
2479 case SPIRV::OpArbitraryFloatRecipALTERA:
2480 case SPIRV::OpArbitraryFloatSinCosALTERA:
2481 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2482 case SPIRV::OpArbitraryFloatSinALTERA:
2483 case SPIRV::OpArbitraryFloatSinPiALTERA:
2484 case SPIRV::OpArbitraryFloatSqrtALTERA:
2485 case SPIRV::OpArbitraryFloatACosALTERA:
2486 case SPIRV::OpArbitraryFloatACosPiALTERA:
2487 case SPIRV::OpArbitraryFloatAddALTERA:
2488 case SPIRV::OpArbitraryFloatASinALTERA:
2489 case SPIRV::OpArbitraryFloatASinPiALTERA:
2490 case SPIRV::OpArbitraryFloatATan2ALTERA:
2491 case SPIRV::OpArbitraryFloatATanALTERA:
2492 case SPIRV::OpArbitraryFloatATanPiALTERA:
2493 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2494 case SPIRV::OpArbitraryFloatCastALTERA:
2495 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2496 case SPIRV::OpArbitraryFloatDivALTERA:
2497 case SPIRV::OpArbitraryFloatMulALTERA:
2498 case SPIRV::OpArbitraryFloatPowALTERA:
2499 case SPIRV::OpArbitraryFloatPowNALTERA:
2500 case SPIRV::OpArbitraryFloatPowRALTERA:
2501 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2502 case SPIRV::OpArbitraryFloatSubALTERA: {
2503 if (!ST.canUseExtension(
2504 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2506 "Floating point instructions can't be translated correctly without "
2507 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2510 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2512 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2515 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2516 if (!ST.canUseExtension(
2517 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2519 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2521 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2524 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2526 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2529 case SPIRV::OpBitwiseFunctionINTEL: {
2530 if (!ST.canUseExtension(
2531 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2533 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2534 "extension: SPV_INTEL_ternary_bitwise_function",
2536 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2537 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2540 case SPIRV::OpCopyMemorySized: {
2545 case SPIRV::OpTypeUntypedPointerKHR:
2547 MI.getOperand(1).getImm(), ST);
2549 case SPIRV::OpUntypedVariableKHR:
2550 case SPIRV::OpUntypedAccessChainKHR:
2551 case SPIRV::OpUntypedInBoundsAccessChainKHR:
2552 case SPIRV::OpUntypedPtrAccessChainKHR:
2553 case SPIRV::OpUntypedInBoundsPtrAccessChainKHR:
2554 case SPIRV::OpUntypedPrefetchKHR:
2555 case SPIRV::OpUntypedGroupAsyncCopyKHR: {
2556 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_untyped_pointers))
2558 "SPIR-V extension: SPV_KHR_untyped_pointers",
2560 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_untyped_pointers);
2564 case SPIRV::OpPredicatedLoadINTEL:
2565 case SPIRV::OpPredicatedStoreINTEL: {
2566 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2568 "OpPredicated[Load/Store]INTEL instructions require "
2569 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2571 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2575 case SPIRV::OpFAddS:
2576 case SPIRV::OpFSubS:
2577 case SPIRV::OpFMulS:
2578 case SPIRV::OpFDivS:
2579 case SPIRV::OpFRemS:
2581 case SPIRV::OpFNegate:
2582 case SPIRV::OpFAddV:
2583 case SPIRV::OpFSubV:
2584 case SPIRV::OpFMulV:
2585 case SPIRV::OpFDivV:
2586 case SPIRV::OpFRemV:
2587 case SPIRV::OpFNegateV: {
2593 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2595 "Arithmetic instructions with bfloat16 arguments require the "
2596 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2598 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2599 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2603 case SPIRV::OpOrdered:
2604 case SPIRV::OpUnordered:
2605 case SPIRV::OpFOrdEqual:
2606 case SPIRV::OpFOrdNotEqual:
2607 case SPIRV::OpFOrdLessThan:
2608 case SPIRV::OpFOrdLessThanEqual:
2609 case SPIRV::OpFOrdGreaterThan:
2610 case SPIRV::OpFOrdGreaterThanEqual:
2611 case SPIRV::OpFUnordEqual:
2612 case SPIRV::OpFUnordNotEqual:
2613 case SPIRV::OpFUnordLessThan:
2614 case SPIRV::OpFUnordLessThanEqual:
2615 case SPIRV::OpFUnordGreaterThan:
2616 case SPIRV::OpFUnordGreaterThanEqual: {
2623 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2625 "Relational instructions with bfloat16 arguments require the "
2626 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2628 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2629 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2633 case SPIRV::OpDPdxCoarse:
2634 case SPIRV::OpDPdyCoarse:
2635 case SPIRV::OpDPdxFine:
2636 case SPIRV::OpDPdyFine: {
2640 case SPIRV::OpLoopControlINTEL: {
2641 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2642 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2654 SPIRV::Capability::Shader);
2669 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2671 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2672 RequireKHRFloatControls2 =
false,
2673 VerLower14 = !ST.isAtLeastSPIRVVer(
VersionTuple(1, 4));
2674 bool HasIntelFloatControls2 =
2675 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2676 bool HasKHRFloatControls2 =
2677 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2678 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2684 auto EM = Const->getZExtValue();
2688 case SPIRV::ExecutionMode::DenormPreserve:
2689 case SPIRV::ExecutionMode::DenormFlushToZero:
2690 case SPIRV::ExecutionMode::RoundingModeRTE:
2691 case SPIRV::ExecutionMode::RoundingModeRTZ:
2692 RequireFloatControls = VerLower14;
2694 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2696 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2697 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2698 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2699 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2700 if (HasIntelFloatControls2) {
2701 RequireIntelFloatControls2 =
true;
2703 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2706 case SPIRV::ExecutionMode::FPFastMathDefault: {
2707 if (HasKHRFloatControls2) {
2708 RequireKHRFloatControls2 =
true;
2710 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2714 case SPIRV::ExecutionMode::ContractionOff:
2715 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2716 if (HasKHRFloatControls2) {
2717 RequireKHRFloatControls2 =
true;
2719 SPIRV::OperandCategory::ExecutionModeOperand,
2720 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2723 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2728 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2733 if (RequireFloatControls &&
2734 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2736 if (RequireIntelFloatControls2)
2738 if (RequireKHRFloatControls2)
2742 if (
F.isDeclaration())
2744 if (
F.getMetadata(
"reqd_work_group_size"))
2746 SPIRV::OperandCategory::ExecutionModeOperand,
2747 SPIRV::ExecutionMode::LocalSize, ST);
2748 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2750 SPIRV::OperandCategory::ExecutionModeOperand,
2751 SPIRV::ExecutionMode::LocalSize, ST);
2753 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2756 if (
F.getMetadata(
"work_group_size_hint"))
2758 SPIRV::OperandCategory::ExecutionModeOperand,
2759 SPIRV::ExecutionMode::LocalSizeHint, ST);
2760 if (
F.getMetadata(
"intel_reqd_sub_group_size") ||
2761 F.getMetadata(
"reqd_sub_group_size"))
2763 SPIRV::OperandCategory::ExecutionModeOperand,
2764 SPIRV::ExecutionMode::SubgroupSize, ST);
2765 if (
F.getMetadata(
"max_work_group_size"))
2767 SPIRV::OperandCategory::ExecutionModeOperand,
2768 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2769 if (
F.getMetadata(
"vec_type_hint"))
2771 SPIRV::OperandCategory::ExecutionModeOperand,
2772 SPIRV::ExecutionMode::VecTypeHint, ST);
2774 if (
F.hasOptNone()) {
2775 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2778 }
else if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2788 unsigned Flags = SPIRV::FPFastMathMode::None;
2789 bool CanUseKHRFloatControls2 =
2790 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2792 Flags |= SPIRV::FPFastMathMode::NotNaN;
2794 Flags |= SPIRV::FPFastMathMode::NotInf;
2796 Flags |= SPIRV::FPFastMathMode::NSZ;
2798 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2800 Flags |= SPIRV::FPFastMathMode::AllowContract;
2802 if (CanUseKHRFloatControls2)
2810 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2811 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2812 SPIRV::FPFastMathMode::AllowTransform |
2813 SPIRV::FPFastMathMode::AllowReassoc |
2814 SPIRV::FPFastMathMode::AllowContract;
2816 Flags |= SPIRV::FPFastMathMode::Fast;
2819 if (CanUseKHRFloatControls2) {
2821 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2822 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2827 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2828 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2829 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2830 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2831 "AllowContract flags to be enabled as well.");
2842 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2849 if (
TII.canUseIntegerWrapDecoration(
I)) {
2852 SPIRV::OperandCategory::DecorationOperand,
2853 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2856 SPIRV::Decoration::NoSignedWrap, {});
2859 SPIRV::OperandCategory::DecorationOperand,
2860 SPIRV::Decoration::NoUnsignedWrap, ST, Reqs)
2863 SPIRV::Decoration::NoUnsignedWrap, {});
2868 TII.canUseFastMathFlags(
2869 I, ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) ||
2870 (ST.isKernel() &&
I.getOpcode() == SPIRV::OpExtInst);
2875 if (FMFlags == SPIRV::FPFastMathMode::None) {
2878 if (FPFastMathDefaultInfoVec.
empty())
2894 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2895 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2896 ?
I.getOperand(1).getReg()
2897 :
I.getOperand(2).getReg();
2905 if (Ty == Elem.Ty) {
2906 FMFlags = Elem.FastMathFlags;
2907 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2908 Elem.FPFastMathDefault;
2913 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2917 Register DstReg =
I.getOperand(0).getReg();
2933 for (
auto &
MBB : *MF)
2934 for (
auto &
MI :
MBB)
2952 for (
auto &
MBB : *MF) {
2953 if (!
MBB.hasName() ||
MBB.empty())
2972 for (
auto &
MBB : *MF) {
2974 MI.setDesc(
TII.get(SPIRV::OpPhi));
2977 MI.insert(
MI.operands_begin() + 1,
2978 {MachineOperand::CreateReg(ResTypeReg, false)});
2997 SPIRV::FPFastMathMode::None);
2999 SPIRV::FPFastMathMode::None);
3001 SPIRV::FPFastMathMode::None);
3008 size_t BitWidth = Ty->getScalarSizeInBits();
3012 assert(Index >= 0 && Index < 3 &&
3013 "Expected FPFastMathDefaultInfo for half, float, or double");
3014 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
3015 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
3016 return FPFastMathDefaultInfoVec[Index];
3022 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
3031 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
3035 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
3044 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
3046 "Expected 4 operands for FPFastMathDefault");
3057 Info.FastMathFlags = Flags;
3058 Info.FPFastMathDefault =
true;
3059 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
3061 "Expected no operands for ContractionOff");
3068 Info.ContractionOff =
true;
3070 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
3072 "Expected 1 operand for SignedZeroInfNanPreserve");
3073 unsigned TargetWidth =
3082 assert(Index >= 0 && Index < 3 &&
3083 "Expected FPFastMathDefaultInfo for half, float, or double");
3084 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
3085 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
3086 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
3101 TII = ST->getInstrInfo();
3117 collectDeclarations(M);
3120 numberRegistersGlobally(M);
3123 processOtherInstrs(M);
3127 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
3130 GR->setBound(
MAI.MaxID);
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet & ToRemove
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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
#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 maybeAddScatterGatherReq(const MachineInstr &MI, SPIRV::RequirementHandler &Reqs, const SPIRVSubtarget &ST)
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 LLVM_READONLY 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 LLVM_READONLY 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.
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.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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.
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
bool requiresLongVectorEXT(unsigned NumComponents)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, ArrayRef< uint32_t > DecArgs, StringRef StrImm)
bool isVectorType(SPIRVTypeInst SPVTy)
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