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)
1640 case SPIRV::OpTypeVectorIdEXT: {
1641 if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_long_vector))
1643 "extension: SPV_EXT_long_vector extension");
1644 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_long_vector);
1649 case SPIRV::OpTypePointer: {
1650 auto SC =
MI.getOperand(1).getImm();
1661 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1666 case SPIRV::OpExtInst: {
1667 if (
MI.getOperand(2).getImm() ==
1668 static_cast<int64_t
>(
1669 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1670 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1673 if (
MI.getOperand(3).getImm() ==
1674 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1678 if (
MI.getOperand(2).getImm() ==
1679 static_cast<int64_t
>(SPIRV::InstructionSet::OpenCL_std)) {
1685 if (TypeDef && TypeDef->getOpcode() == SPIRV::OpTypeVector)
1686 TypeDef = MRI.
getVRegDef(TypeDef->getOperand(1).getReg());
1691 bool UsesBFloat16 = IsBFloat16(MRI.
getVRegDef(
MI.getOperand(1).getReg()));
1692 for (
unsigned I = 4,
E =
MI.getNumOperands();
I <
E && !UsesBFloat16;
1701 if (!ST.canUseExtension(
1702 SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic)) {
1704 MI,
"OpenCL Extended instructions with bfloat16 require the "
1705 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic");
1708 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
1709 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
1714 case SPIRV::OpAliasDomainDeclINTEL:
1715 case SPIRV::OpAliasScopeDeclINTEL:
1716 case SPIRV::OpAliasScopeListDeclINTEL: {
1717 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1718 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1721 case SPIRV::OpBitReverse:
1722 case SPIRV::OpBitFieldInsert:
1723 case SPIRV::OpBitFieldSExtract:
1724 case SPIRV::OpBitFieldUExtract:
1725 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1729 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1732 case SPIRV::OpTypeRuntimeArray:
1735 case SPIRV::OpTypeOpaque:
1736 case SPIRV::OpTypeEvent:
1739 case SPIRV::OpTypePipe:
1740 case SPIRV::OpTypeReserveId:
1743 case SPIRV::OpTypeDeviceEvent:
1744 case SPIRV::OpTypeQueue:
1745 case SPIRV::OpBuildNDRange:
1746 case SPIRV::OpEnqueueKernel:
1749 case SPIRV::OpDecorate:
1750 case SPIRV::OpDecorateId:
1751 case SPIRV::OpDecorateString:
1754 case SPIRV::OpMemberDecorate:
1755 case SPIRV::OpMemberDecorateString:
1758 case SPIRV::OpInBoundsPtrAccessChain:
1761 case SPIRV::OpConstantSampler:
1764 case SPIRV::OpInBoundsAccessChain:
1765 case SPIRV::OpAccessChain:
1768 case SPIRV::OpTypeImage:
1771 case SPIRV::OpTypeSampler:
1772 if (!ST.isShader()) {
1776 case SPIRV::OpTypeForwardPointer:
1780 case SPIRV::OpAtomicFlagTestAndSet:
1781 case SPIRV::OpAtomicLoad:
1782 case SPIRV::OpAtomicStore:
1783 case SPIRV::OpAtomicExchange:
1784 case SPIRV::OpAtomicCompareExchange:
1785 case SPIRV::OpAtomicCompareExchangeWeak:
1786 case SPIRV::OpAtomicIIncrement:
1787 case SPIRV::OpAtomicIDecrement:
1788 case SPIRV::OpAtomicIAdd:
1789 case SPIRV::OpAtomicISub:
1790 case SPIRV::OpAtomicUMin:
1791 case SPIRV::OpAtomicUMax:
1792 case SPIRV::OpAtomicSMin:
1793 case SPIRV::OpAtomicSMax:
1794 case SPIRV::OpAtomicAnd:
1795 case SPIRV::OpAtomicOr:
1796 case SPIRV::OpAtomicXor: {
1799 if (
Op == SPIRV::OpAtomicStore) {
1802 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1808 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1813 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1815 "16-bit integer atomic operations require the following SPIR-V "
1816 "extension: SPV_INTEL_16bit_atomics",
1818 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1820 case SPIRV::OpAtomicLoad:
1821 case SPIRV::OpAtomicStore:
1822 case SPIRV::OpAtomicExchange:
1823 case SPIRV::OpAtomicCompareExchange:
1824 case SPIRV::OpAtomicCompareExchangeWeak:
1826 SPIRV::Capability::AtomicInt16CompareExchangeINTEL);
1834 if (
is_contained({SPIRV::OpAtomicLoad, SPIRV::OpAtomicStore,
1835 SPIRV::OpAtomicExchange},
1837 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1839 "The atomic bfloat16 instruction requires the following SPIR-V "
1840 "extension: SPV_INTEL_16bit_atomics",
1842 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1843 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16LoadStoreINTEL);
1848 case SPIRV::OpGroupNonUniformIAdd:
1849 case SPIRV::OpGroupNonUniformFAdd:
1850 case SPIRV::OpGroupNonUniformIMul:
1851 case SPIRV::OpGroupNonUniformFMul:
1852 case SPIRV::OpGroupNonUniformSMin:
1853 case SPIRV::OpGroupNonUniformUMin:
1854 case SPIRV::OpGroupNonUniformFMin:
1855 case SPIRV::OpGroupNonUniformSMax:
1856 case SPIRV::OpGroupNonUniformUMax:
1857 case SPIRV::OpGroupNonUniformFMax:
1858 case SPIRV::OpGroupNonUniformBitwiseAnd:
1859 case SPIRV::OpGroupNonUniformBitwiseOr:
1860 case SPIRV::OpGroupNonUniformBitwiseXor:
1861 case SPIRV::OpGroupNonUniformLogicalAnd:
1862 case SPIRV::OpGroupNonUniformLogicalOr:
1863 case SPIRV::OpGroupNonUniformLogicalXor: {
1865 int64_t GroupOp =
MI.getOperand(3).getImm();
1867 case SPIRV::GroupOperation::Reduce:
1868 case SPIRV::GroupOperation::InclusiveScan:
1869 case SPIRV::GroupOperation::ExclusiveScan:
1870 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1872 case SPIRV::GroupOperation::ClusteredReduce:
1873 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1875 case SPIRV::GroupOperation::PartitionedReduceNV:
1876 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1877 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1878 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1883 case SPIRV::OpGroupNonUniformQuadSwap:
1886 case SPIRV::OpImageQueryLod:
1889 case SPIRV::OpImageQuerySize:
1890 case SPIRV::OpImageQuerySizeLod:
1891 case SPIRV::OpImageQueryLevels:
1892 case SPIRV::OpImageQuerySamples:
1896 case SPIRV::OpImageQueryFormat: {
1897 Register ResultReg =
MI.getOperand(0).getReg();
1899 static const unsigned CompareOps[] = {
1900 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1901 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1902 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1903 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1904 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1906 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1907 if (ImmVal == 4323 || ImmVal == 4324) {
1908 if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1909 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1912 "SPV_EXT_image_raw10_raw12 extension");
1917 unsigned Opc = UseInst.getOpcode();
1919 if (
Opc == SPIRV::OpSwitch) {
1922 CheckAndAddExtension(
Op.getImm());
1924 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1927 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1930 CheckAndAddExtension(ImmVal);
1938 case SPIRV::OpGroupNonUniformShuffle:
1939 case SPIRV::OpGroupNonUniformShuffleXor:
1940 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1942 case SPIRV::OpGroupNonUniformShuffleUp:
1943 case SPIRV::OpGroupNonUniformShuffleDown:
1944 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1946 case SPIRV::OpGroupAll:
1947 case SPIRV::OpGroupAny:
1948 case SPIRV::OpGroupBroadcast:
1949 case SPIRV::OpGroupIAdd:
1950 case SPIRV::OpGroupFAdd:
1951 case SPIRV::OpGroupFMin:
1952 case SPIRV::OpGroupUMin:
1953 case SPIRV::OpGroupSMin:
1954 case SPIRV::OpGroupFMax:
1955 case SPIRV::OpGroupUMax:
1956 case SPIRV::OpGroupSMax:
1959 case SPIRV::OpGroupNonUniformElect:
1962 case SPIRV::OpGroupNonUniformAll:
1963 case SPIRV::OpGroupNonUniformAny:
1964 case SPIRV::OpGroupNonUniformAllEqual:
1967 case SPIRV::OpGroupNonUniformBroadcast:
1968 case SPIRV::OpGroupNonUniformBroadcastFirst:
1969 case SPIRV::OpGroupNonUniformBallot:
1970 case SPIRV::OpGroupNonUniformInverseBallot:
1971 case SPIRV::OpGroupNonUniformBallotBitExtract:
1972 case SPIRV::OpGroupNonUniformBallotBitCount:
1973 case SPIRV::OpGroupNonUniformBallotFindLSB:
1974 case SPIRV::OpGroupNonUniformBallotFindMSB:
1975 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1977 case SPIRV::OpSubgroupShuffleINTEL:
1978 case SPIRV::OpSubgroupShuffleDownINTEL:
1979 case SPIRV::OpSubgroupShuffleUpINTEL:
1980 case SPIRV::OpSubgroupShuffleXorINTEL:
1981 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1982 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1983 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1986 case SPIRV::OpSubgroupBlockReadINTEL:
1987 case SPIRV::OpSubgroupBlockWriteINTEL:
1988 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1989 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1990 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1993 case SPIRV::OpSubgroupImageBlockReadINTEL:
1994 case SPIRV::OpSubgroupImageBlockWriteINTEL:
1995 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1996 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1997 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
2000 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
2001 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
2002 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
2003 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
2004 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
2007 case SPIRV::OpAssumeTrueKHR:
2008 case SPIRV::OpExpectKHR:
2009 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
2010 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
2014 case SPIRV::OpFmaKHR:
2015 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
2020 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
2021 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
2022 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
2023 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
2024 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
2027 case SPIRV::OpConstantFunctionPointerINTEL:
2028 case SPIRV::OpFunctionPointerCallINTEL:
2029 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
2030 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
2031 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
2034 case SPIRV::OpGroupNonUniformRotateKHR:
2035 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
2037 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
2039 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
2040 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
2043 case SPIRV::OpFixedCosALTERA:
2044 case SPIRV::OpFixedSinALTERA:
2045 case SPIRV::OpFixedCosPiALTERA:
2046 case SPIRV::OpFixedSinPiALTERA:
2047 case SPIRV::OpFixedExpALTERA:
2048 case SPIRV::OpFixedLogALTERA:
2049 case SPIRV::OpFixedRecipALTERA:
2050 case SPIRV::OpFixedSqrtALTERA:
2051 case SPIRV::OpFixedSinCosALTERA:
2052 case SPIRV::OpFixedSinCosPiALTERA:
2053 case SPIRV::OpFixedRsqrtALTERA:
2054 if (!ST.canUseExtension(
2055 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
2057 "following SPIR-V extension: "
2058 "SPV_ALTERA_arbitrary_precision_fixed_point",
2061 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
2062 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
2064 case SPIRV::OpGroupIMulKHR:
2065 case SPIRV::OpGroupFMulKHR:
2066 case SPIRV::OpGroupBitwiseAndKHR:
2067 case SPIRV::OpGroupBitwiseOrKHR:
2068 case SPIRV::OpGroupBitwiseXorKHR:
2069 case SPIRV::OpGroupLogicalAndKHR:
2070 case SPIRV::OpGroupLogicalOrKHR:
2071 case SPIRV::OpGroupLogicalXorKHR:
2072 if (ST.canUseExtension(
2073 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
2074 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
2075 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
2078 case SPIRV::OpReadClockKHR:
2079 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
2081 "following SPIR-V extension: SPV_KHR_shader_clock",
2083 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
2086 case SPIRV::OpAbortKHR:
2087 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_abort))
2089 "following SPIR-V extension: SPV_KHR_abort",
2094 case SPIRV::OpPoisonKHR:
2095 case SPIRV::OpFreezeKHR:
2096 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_poison_freeze))
2098 "following SPIR-V extension: SPV_KHR_poison_freeze",
2100 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_poison_freeze);
2103 case SPIRV::OpAtomicFAddEXT:
2104 case SPIRV::OpAtomicFMinEXT:
2105 case SPIRV::OpAtomicFMaxEXT:
2108 case SPIRV::OpConvertBF16ToFINTEL:
2109 case SPIRV::OpConvertFToBF16INTEL:
2110 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
2111 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
2112 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
2115 case SPIRV::OpRoundFToTF32INTEL:
2116 if (ST.canUseExtension(
2117 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
2118 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
2119 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
2122 case SPIRV::OpVariableLengthArrayINTEL:
2123 case SPIRV::OpSaveMemoryINTEL:
2124 case SPIRV::OpRestoreMemoryINTEL:
2125 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
2126 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
2127 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
2130 case SPIRV::OpAsmTargetINTEL:
2131 case SPIRV::OpAsmINTEL:
2132 case SPIRV::OpAsmCallINTEL:
2133 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
2134 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
2138 case SPIRV::OpTypeCooperativeMatrixKHR: {
2139 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2141 "OpTypeCooperativeMatrixKHR type requires the "
2142 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
2144 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2145 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2149 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
2152 case SPIRV::OpArithmeticFenceEXT:
2153 if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
2155 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
2157 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
2160 case SPIRV::OpControlBarrierArriveINTEL:
2161 case SPIRV::OpControlBarrierWaitINTEL:
2162 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
2163 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
2167 case SPIRV::OpCooperativeMatrixMulAddKHR: {
2168 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2170 "following SPIR-V extension: "
2171 "SPV_KHR_cooperative_matrix",
2173 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2174 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2175 constexpr unsigned MulAddMaxSize = 6;
2176 if (
MI.getNumOperands() != MulAddMaxSize)
2178 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
2180 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
2181 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2183 "require the following SPIR-V extension: "
2184 "SPV_INTEL_joint_matrix",
2186 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2188 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
2191 MatrixAAndBBFloat16ComponentsINTEL ||
2193 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
2195 MatrixResultBFloat16ComponentsINTEL) {
2196 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2198 "require the following SPIR-V extension: "
2199 "SPV_INTEL_joint_matrix",
2201 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2203 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
2207 case SPIRV::OpCooperativeMatrixLoadKHR:
2208 case SPIRV::OpCooperativeMatrixStoreKHR:
2209 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2210 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2211 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
2212 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2214 "following SPIR-V extension: "
2215 "SPV_KHR_cooperative_matrix",
2217 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2218 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2224 case SPIRV::OpCooperativeMatrixLoadKHR:
2227 case SPIRV::OpCooperativeMatrixStoreKHR:
2230 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2233 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2234 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2240 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
2243 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
2246 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
2247 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2249 "extension: SPV_INTEL_joint_matrix",
2251 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2252 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2257 if (
Op == SPIRV::OpCooperativeMatrixLoadKHR ||
2258 Op == SPIRV::OpCooperativeMatrixStoreKHR)
2261 std::string InstName;
2263 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2264 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2266 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2267 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2269 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2270 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2274 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2275 const std::string ErrorMsg =
2276 InstName +
" instruction requires the "
2277 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2280 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2281 if (
Op == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2282 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2286 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2289 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2290 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2292 "instructions require the following SPIR-V extension: "
2293 "SPV_INTEL_joint_matrix",
2295 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2297 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2299 case SPIRV::OpReadPipeBlockingALTERA:
2300 case SPIRV::OpWritePipeBlockingALTERA:
2301 if (ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2302 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2306 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2307 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2309 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2311 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2313 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2315 case SPIRV::OpConvertHandleToImageINTEL:
2316 case SPIRV::OpConvertHandleToSamplerINTEL:
2317 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2318 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2320 "instructions require the following SPIR-V extension: "
2321 "SPV_INTEL_bindless_images",
2324 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2326 if (
Op == SPIRV::OpConvertHandleToImageINTEL &&
2327 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2329 "OpConvertHandleToImageINTEL",
2331 }
else if (
Op == SPIRV::OpConvertHandleToSamplerINTEL &&
2332 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2334 "OpConvertHandleToSamplerINTEL",
2336 }
else if (
Op == SPIRV::OpConvertHandleToSampledImageINTEL &&
2337 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2339 "OpConvertHandleToSampledImageINTEL",
2344 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2345 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2347 "Parameter value must be a 32-bit scalar in case of "
2348 "Physical32 addressing model or a 64-bit scalar in case of "
2349 "Physical64 addressing model",
2352 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2356 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2357 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2358 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2359 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2360 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2361 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2363 "Prefetch/Store]INTEL instructions require the "
2364 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2366 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2367 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2369 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2370 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2373 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2374 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2379 case SPIRV::OpKill: {
2382 case SPIRV::OpDemoteToHelperInvocation:
2383 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2385 if (ST.canUseExtension(
2386 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2389 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2394 case SPIRV::OpSUDot:
2395 case SPIRV::OpSDotAccSat:
2396 case SPIRV::OpUDotAccSat:
2397 case SPIRV::OpSUDotAccSat:
2400 case SPIRV::OpImageSampleImplicitLod:
2401 case SPIRV::OpImageFetch:
2405 case SPIRV::OpImageSampleExplicitLod:
2408 case SPIRV::OpImageSampleDrefImplicitLod:
2409 case SPIRV::OpImageSampleDrefExplicitLod:
2410 case SPIRV::OpImageDrefGather:
2411 case SPIRV::OpImageGather:
2415 case SPIRV::OpImageRead: {
2416 Register ImageReg =
MI.getOperand(2).getReg();
2417 SPIRVTypeInst TypeDef = ST.getSPIRVGlobalRegistry()->getResultType(
2426 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2429 case SPIRV::OpImageWrite: {
2430 Register ImageReg =
MI.getOperand(0).getReg();
2431 SPIRVTypeInst TypeDef = ST.getSPIRVGlobalRegistry()->getResultType(
2440 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2443 case SPIRV::OpTypeStructContinuedINTEL:
2444 case SPIRV::OpConstantCompositeContinuedINTEL:
2445 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2446 case SPIRV::OpCompositeConstructContinuedINTEL: {
2447 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2449 "Continued instructions require the "
2450 "following SPIR-V extension: SPV_INTEL_long_composites",
2452 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2456 case SPIRV::OpArbitraryFloatEQALTERA:
2457 case SPIRV::OpArbitraryFloatGEALTERA:
2458 case SPIRV::OpArbitraryFloatGTALTERA:
2459 case SPIRV::OpArbitraryFloatLEALTERA:
2460 case SPIRV::OpArbitraryFloatLTALTERA:
2461 case SPIRV::OpArbitraryFloatCbrtALTERA:
2462 case SPIRV::OpArbitraryFloatCosALTERA:
2463 case SPIRV::OpArbitraryFloatCosPiALTERA:
2464 case SPIRV::OpArbitraryFloatExp10ALTERA:
2465 case SPIRV::OpArbitraryFloatExp2ALTERA:
2466 case SPIRV::OpArbitraryFloatExpALTERA:
2467 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2468 case SPIRV::OpArbitraryFloatHypotALTERA:
2469 case SPIRV::OpArbitraryFloatLog10ALTERA:
2470 case SPIRV::OpArbitraryFloatLog1pALTERA:
2471 case SPIRV::OpArbitraryFloatLog2ALTERA:
2472 case SPIRV::OpArbitraryFloatLogALTERA:
2473 case SPIRV::OpArbitraryFloatRecipALTERA:
2474 case SPIRV::OpArbitraryFloatSinCosALTERA:
2475 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2476 case SPIRV::OpArbitraryFloatSinALTERA:
2477 case SPIRV::OpArbitraryFloatSinPiALTERA:
2478 case SPIRV::OpArbitraryFloatSqrtALTERA:
2479 case SPIRV::OpArbitraryFloatACosALTERA:
2480 case SPIRV::OpArbitraryFloatACosPiALTERA:
2481 case SPIRV::OpArbitraryFloatAddALTERA:
2482 case SPIRV::OpArbitraryFloatASinALTERA:
2483 case SPIRV::OpArbitraryFloatASinPiALTERA:
2484 case SPIRV::OpArbitraryFloatATan2ALTERA:
2485 case SPIRV::OpArbitraryFloatATanALTERA:
2486 case SPIRV::OpArbitraryFloatATanPiALTERA:
2487 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2488 case SPIRV::OpArbitraryFloatCastALTERA:
2489 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2490 case SPIRV::OpArbitraryFloatDivALTERA:
2491 case SPIRV::OpArbitraryFloatMulALTERA:
2492 case SPIRV::OpArbitraryFloatPowALTERA:
2493 case SPIRV::OpArbitraryFloatPowNALTERA:
2494 case SPIRV::OpArbitraryFloatPowRALTERA:
2495 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2496 case SPIRV::OpArbitraryFloatSubALTERA: {
2497 if (!ST.canUseExtension(
2498 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2500 "Floating point instructions can't be translated correctly without "
2501 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2504 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2506 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2509 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2510 if (!ST.canUseExtension(
2511 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2513 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2515 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2518 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2520 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2523 case SPIRV::OpBitwiseFunctionINTEL: {
2524 if (!ST.canUseExtension(
2525 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2527 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2528 "extension: SPV_INTEL_ternary_bitwise_function",
2530 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2531 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2534 case SPIRV::OpCopyMemorySized: {
2539 case SPIRV::OpTypeUntypedPointerKHR:
2541 MI.getOperand(1).getImm(), ST);
2543 case SPIRV::OpUntypedVariableKHR:
2544 case SPIRV::OpUntypedAccessChainKHR:
2545 case SPIRV::OpUntypedInBoundsAccessChainKHR:
2546 case SPIRV::OpUntypedPtrAccessChainKHR:
2547 case SPIRV::OpUntypedInBoundsPtrAccessChainKHR:
2548 case SPIRV::OpUntypedPrefetchKHR:
2549 case SPIRV::OpUntypedGroupAsyncCopyKHR: {
2550 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_untyped_pointers))
2552 "SPIR-V extension: SPV_KHR_untyped_pointers",
2554 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_untyped_pointers);
2558 case SPIRV::OpPredicatedLoadINTEL:
2559 case SPIRV::OpPredicatedStoreINTEL: {
2560 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2562 "OpPredicated[Load/Store]INTEL instructions require "
2563 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2565 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2569 case SPIRV::OpFAddS:
2570 case SPIRV::OpFSubS:
2571 case SPIRV::OpFMulS:
2572 case SPIRV::OpFDivS:
2573 case SPIRV::OpFRemS:
2575 case SPIRV::OpFNegate:
2576 case SPIRV::OpFAddV:
2577 case SPIRV::OpFSubV:
2578 case SPIRV::OpFMulV:
2579 case SPIRV::OpFDivV:
2580 case SPIRV::OpFRemV:
2581 case SPIRV::OpFNegateV: {
2587 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2589 "Arithmetic instructions with bfloat16 arguments require the "
2590 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2592 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2593 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2597 case SPIRV::OpOrdered:
2598 case SPIRV::OpUnordered:
2599 case SPIRV::OpFOrdEqual:
2600 case SPIRV::OpFOrdNotEqual:
2601 case SPIRV::OpFOrdLessThan:
2602 case SPIRV::OpFOrdLessThanEqual:
2603 case SPIRV::OpFOrdGreaterThan:
2604 case SPIRV::OpFOrdGreaterThanEqual:
2605 case SPIRV::OpFUnordEqual:
2606 case SPIRV::OpFUnordNotEqual:
2607 case SPIRV::OpFUnordLessThan:
2608 case SPIRV::OpFUnordLessThanEqual:
2609 case SPIRV::OpFUnordGreaterThan:
2610 case SPIRV::OpFUnordGreaterThanEqual: {
2617 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2619 "Relational instructions with bfloat16 arguments require the "
2620 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2622 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2623 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2627 case SPIRV::OpDPdxCoarse:
2628 case SPIRV::OpDPdyCoarse:
2629 case SPIRV::OpDPdxFine:
2630 case SPIRV::OpDPdyFine: {
2634 case SPIRV::OpLoopControlINTEL: {
2635 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2636 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2648 SPIRV::Capability::Shader);
2663 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2665 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2666 RequireKHRFloatControls2 =
false,
2667 VerLower14 = !ST.isAtLeastSPIRVVer(
VersionTuple(1, 4));
2668 bool HasIntelFloatControls2 =
2669 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2670 bool HasKHRFloatControls2 =
2671 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2672 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2678 auto EM = Const->getZExtValue();
2682 case SPIRV::ExecutionMode::DenormPreserve:
2683 case SPIRV::ExecutionMode::DenormFlushToZero:
2684 case SPIRV::ExecutionMode::RoundingModeRTE:
2685 case SPIRV::ExecutionMode::RoundingModeRTZ:
2686 RequireFloatControls = VerLower14;
2688 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2690 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2691 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2692 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2693 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2694 if (HasIntelFloatControls2) {
2695 RequireIntelFloatControls2 =
true;
2697 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2700 case SPIRV::ExecutionMode::FPFastMathDefault: {
2701 if (HasKHRFloatControls2) {
2702 RequireKHRFloatControls2 =
true;
2704 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2708 case SPIRV::ExecutionMode::ContractionOff:
2709 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2710 if (HasKHRFloatControls2) {
2711 RequireKHRFloatControls2 =
true;
2713 SPIRV::OperandCategory::ExecutionModeOperand,
2714 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2717 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2722 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2727 if (RequireFloatControls &&
2728 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2730 if (RequireIntelFloatControls2)
2732 if (RequireKHRFloatControls2)
2736 if (
F.isDeclaration())
2738 if (
F.getMetadata(
"reqd_work_group_size"))
2740 SPIRV::OperandCategory::ExecutionModeOperand,
2741 SPIRV::ExecutionMode::LocalSize, ST);
2742 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2744 SPIRV::OperandCategory::ExecutionModeOperand,
2745 SPIRV::ExecutionMode::LocalSize, ST);
2747 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2750 if (
F.getMetadata(
"work_group_size_hint"))
2752 SPIRV::OperandCategory::ExecutionModeOperand,
2753 SPIRV::ExecutionMode::LocalSizeHint, ST);
2754 if (
F.getMetadata(
"intel_reqd_sub_group_size") ||
2755 F.getMetadata(
"reqd_sub_group_size"))
2757 SPIRV::OperandCategory::ExecutionModeOperand,
2758 SPIRV::ExecutionMode::SubgroupSize, ST);
2759 if (
F.getMetadata(
"max_work_group_size"))
2761 SPIRV::OperandCategory::ExecutionModeOperand,
2762 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2763 if (
F.getMetadata(
"vec_type_hint"))
2765 SPIRV::OperandCategory::ExecutionModeOperand,
2766 SPIRV::ExecutionMode::VecTypeHint, ST);
2768 if (
F.hasOptNone()) {
2769 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2772 }
else if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2782 unsigned Flags = SPIRV::FPFastMathMode::None;
2783 bool CanUseKHRFloatControls2 =
2784 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2786 Flags |= SPIRV::FPFastMathMode::NotNaN;
2788 Flags |= SPIRV::FPFastMathMode::NotInf;
2790 Flags |= SPIRV::FPFastMathMode::NSZ;
2792 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2794 Flags |= SPIRV::FPFastMathMode::AllowContract;
2796 if (CanUseKHRFloatControls2)
2804 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2805 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2806 SPIRV::FPFastMathMode::AllowTransform |
2807 SPIRV::FPFastMathMode::AllowReassoc |
2808 SPIRV::FPFastMathMode::AllowContract;
2810 Flags |= SPIRV::FPFastMathMode::Fast;
2813 if (CanUseKHRFloatControls2) {
2815 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2816 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2821 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2822 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2823 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2824 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2825 "AllowContract flags to be enabled as well.");
2836 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2843 if (
TII.canUseIntegerWrapDecoration(
I)) {
2846 SPIRV::OperandCategory::DecorationOperand,
2847 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2850 SPIRV::Decoration::NoSignedWrap, {});
2853 SPIRV::OperandCategory::DecorationOperand,
2854 SPIRV::Decoration::NoUnsignedWrap, ST, Reqs)
2857 SPIRV::Decoration::NoUnsignedWrap, {});
2862 TII.canUseFastMathFlags(
2863 I, ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) ||
2864 (ST.isKernel() &&
I.getOpcode() == SPIRV::OpExtInst);
2869 if (FMFlags == SPIRV::FPFastMathMode::None) {
2872 if (FPFastMathDefaultInfoVec.
empty())
2888 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2889 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2890 ?
I.getOperand(1).getReg()
2891 :
I.getOperand(2).getReg();
2899 if (Ty == Elem.Ty) {
2900 FMFlags = Elem.FastMathFlags;
2901 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2902 Elem.FPFastMathDefault;
2907 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2911 Register DstReg =
I.getOperand(0).getReg();
2927 for (
auto &
MBB : *MF)
2928 for (
auto &
MI :
MBB)
2946 for (
auto &
MBB : *MF) {
2947 if (!
MBB.hasName() ||
MBB.empty())
2966 for (
auto &
MBB : *MF) {
2968 MI.setDesc(
TII.get(SPIRV::OpPhi));
2971 MI.insert(
MI.operands_begin() + 1,
2972 {MachineOperand::CreateReg(ResTypeReg, false)});
2991 SPIRV::FPFastMathMode::None);
2993 SPIRV::FPFastMathMode::None);
2995 SPIRV::FPFastMathMode::None);
3002 size_t BitWidth = Ty->getScalarSizeInBits();
3006 assert(Index >= 0 && Index < 3 &&
3007 "Expected FPFastMathDefaultInfo for half, float, or double");
3008 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
3009 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
3010 return FPFastMathDefaultInfoVec[Index];
3016 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
3025 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
3029 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
3038 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
3040 "Expected 4 operands for FPFastMathDefault");
3051 Info.FastMathFlags = Flags;
3052 Info.FPFastMathDefault =
true;
3053 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
3055 "Expected no operands for ContractionOff");
3062 Info.ContractionOff =
true;
3064 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
3066 "Expected 1 operand for SignedZeroInfNanPreserve");
3067 unsigned TargetWidth =
3076 assert(Index >= 0 && Index < 3 &&
3077 "Expected FPFastMathDefaultInfo for half, float, or double");
3078 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
3079 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
3080 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
3095 TII = ST->getInstrInfo();
3111 collectDeclarations(M);
3114 numberRegistersGlobally(M);
3117 processOtherInstrs(M);
3121 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
3124 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.
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
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