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});
1055 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 3)) ||
1056 ST.canUseExtension(Extension::SPV_KHR_variable_pointers))
1058 Capability::VariablePointers});
1061 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
1063 {Capability::Int64Atomics, Capability::ShaderNonUniformEXT,
1064 Capability::RuntimeDescriptorArrayEXT,
1065 Capability::InputAttachmentArrayDynamicIndexingEXT,
1066 Capability::UniformTexelBufferArrayDynamicIndexingEXT,
1067 Capability::StorageTexelBufferArrayDynamicIndexingEXT,
1068 Capability::UniformBufferArrayNonUniformIndexingEXT,
1069 Capability::SampledImageArrayNonUniformIndexingEXT,
1070 Capability::StorageBufferArrayNonUniformIndexingEXT,
1071 Capability::StorageImageArrayNonUniformIndexingEXT,
1072 Capability::InputAttachmentArrayNonUniformIndexingEXT,
1073 Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
1074 Capability::StorageTexelBufferArrayNonUniformIndexingEXT});
1078 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
1080 Capability::StorageImageReadWithoutFormat});
1091 int64_t DecOp =
MI.getOperand(DecIndex).getImm();
1092 auto Dec =
static_cast<SPIRV::Decoration::Decoration
>(DecOp);
1094 SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
1096 if (Dec == SPIRV::Decoration::BuiltIn) {
1097 int64_t BuiltInOp =
MI.getOperand(DecIndex + 1).getImm();
1098 auto BuiltIn =
static_cast<SPIRV::BuiltIn::BuiltIn
>(BuiltInOp);
1100 SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
1101 }
else if (Dec == SPIRV::Decoration::LinkageAttributes) {
1102 int64_t LinkageOp =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
1103 SPIRV::LinkageType::LinkageType LnkType =
1104 static_cast<SPIRV::LinkageType::LinkageType
>(LinkageOp);
1105 if (LnkType == SPIRV::LinkageType::LinkOnceODR)
1106 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_linkonce_odr);
1107 else if (LnkType == SPIRV::LinkageType::WeakAMD) {
1108 Reqs.
addExtension(SPIRV::Extension::SPV_AMD_weak_linkage);
1111 }
else if (Dec == SPIRV::Decoration::CacheControlLoadINTEL ||
1112 Dec == SPIRV::Decoration::CacheControlStoreINTEL) {
1113 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_cache_controls);
1114 }
else if (Dec == SPIRV::Decoration::HostAccessINTEL) {
1115 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_global_variable_host_access);
1116 }
else if (Dec == SPIRV::Decoration::InitModeINTEL ||
1117 Dec == SPIRV::Decoration::ImplementInRegisterMapINTEL) {
1119 SPIRV::Extension::SPV_INTEL_global_variable_fpga_decorations);
1120 }
else if (Dec == SPIRV::Decoration::NonUniformEXT) {
1122 }
else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
1124 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_fp_max_error);
1125 }
else if (Dec == SPIRV::Decoration::FPFastMathMode) {
1126 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
1128 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_float_controls2);
1137 assert(
MI.getNumOperands() >= 8 &&
"Insufficient operands for OpTypeImage");
1140 int64_t ImgFormatOp =
MI.getOperand(7).getImm();
1141 auto ImgFormat =
static_cast<SPIRV::ImageFormat::ImageFormat
>(ImgFormatOp);
1145 bool IsArrayed =
MI.getOperand(4).getImm() == 1;
1146 bool IsMultisampled =
MI.getOperand(5).getImm() == 1;
1147 bool NoSampler =
MI.getOperand(6).getImm() == 2;
1150 switch (
MI.getOperand(2).getImm()) {
1151 case SPIRV::Dim::DIM_1D:
1153 : SPIRV::Capability::Sampled1D);
1155 case SPIRV::Dim::DIM_2D:
1156 if (IsMultisampled && NoSampler)
1158 if (IsMultisampled && IsArrayed)
1161 case SPIRV::Dim::DIM_3D:
1163 case SPIRV::Dim::DIM_Cube:
1167 : SPIRV::Capability::SampledCubeArray);
1169 case SPIRV::Dim::DIM_Rect:
1171 : SPIRV::Capability::SampledRect);
1173 case SPIRV::Dim::DIM_Buffer:
1175 : SPIRV::Capability::SampledBuffer);
1177 case SPIRV::Dim::DIM_SubpassData:
1183 if (!ST.isShader()) {
1184 if (
MI.getNumOperands() > 8 &&
1185 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
1194 TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
1200#define ATOM_FLT_REQ_EXT_MSG(ExtName) \
1201 "The atomic float instruction requires the following SPIR-V " \
1202 "extension: SPV_EXT_shader_atomic_float" ExtName
1207 MI.getMF()->getRegInfo().getVRegDef(
MI.getOperand(1).getReg());
1210 if (Rank != 2 && Rank != 4)
1212 "must be a 2-component or 4 component vector");
1217 if (EltTypeDef->
getOpcode() != SPIRV::OpTypeFloat ||
1220 "The element type for the result type of an atomic vector float "
1221 "instruction must be a 16-bit floating-point scalar");
1228 "The element type for the result type of an atomic vector float "
1229 "instruction cannot be a bfloat16 scalar");
1230 if (!ST.canUseExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector))
1232 "The atomic float16 vector instruction requires the following SPIR-V "
1233 "extension: SPV_NV_shader_atomic_fp16_vector");
1235 Reqs.
addExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector);
1236 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16VectorNV);
1243 "Expect register operand in atomic float instruction");
1244 Register TypeReg =
MI.getOperand(1).getReg();
1250 if (TypeDef->
getOpcode() != SPIRV::OpTypeFloat)
1252 "floating-point type scalar");
1255 unsigned Op =
MI.getOpcode();
1256 if (
Op == SPIRV::OpAtomicFAddEXT) {
1257 if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add))
1259 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
1263 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1265 "The atomic bfloat16 instruction requires the following SPIR-V "
1266 "extension: SPV_INTEL_16bit_atomics",
1268 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1269 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16AddINTEL);
1271 if (!ST.canUseExtension(
1272 SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
1274 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
1286 "Unexpected floating-point type width in atomic float instruction");
1289 if (!ST.canUseExtension(
1290 SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max))
1292 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
1296 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1298 "The atomic bfloat16 instruction requires the following SPIR-V "
1299 "extension: SPV_INTEL_16bit_atomics",
1301 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1302 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16MinMaxINTEL);
1304 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
1308 Reqs.
addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
1311 Reqs.
addCapability(SPIRV::Capability::AtomicFloat64MinMaxEXT);
1315 "Unexpected floating-point type width in atomic float instruction");
1321 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1325 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
1329 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1333 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
1337 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1341 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
1345 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1349 return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
1353 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1357 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
1361 if (SampledImageInst->
getOpcode() != SPIRV::OpTypeSampledImage)
1372 if (
MI.getOpcode() != SPIRV::OpDecorate)
1376 if (Dec == SPIRV::Decoration::NonUniformEXT)
1389 Register ResTypeReg = Instr.getOperand(1).getReg();
1394 if (
StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
1395 StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
1396 StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
1403 auto FirstIndexReg = Instr.getOperand(3).getReg();
1404 bool FirstIndexIsConstant =
1407 if (
StorageClass == SPIRV::StorageClass::StorageClass::StorageBuffer) {
1410 SPIRV::Capability::StorageBufferArrayNonUniformIndexingEXT);
1411 else if (!FirstIndexIsConstant)
1413 SPIRV::Capability::StorageBufferArrayDynamicIndexing);
1419 if (PointeeType->
getOpcode() != SPIRV::OpTypeImage &&
1420 PointeeType->
getOpcode() != SPIRV::OpTypeSampledImage &&
1421 PointeeType->
getOpcode() != SPIRV::OpTypeSampler) {
1428 SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1429 else if (!FirstIndexIsConstant)
1431 SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
1435 SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1436 else if (!FirstIndexIsConstant)
1438 SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
1442 SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1443 else if (!FirstIndexIsConstant)
1445 SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
1448 PointeeType->
getOpcode() == SPIRV::OpTypeSampler) {
1451 SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1452 else if (!FirstIndexIsConstant)
1454 SPIRV::Capability::SampledImageArrayDynamicIndexing);
1458 SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1459 else if (!FirstIndexIsConstant)
1461 SPIRV::Capability::StorageImageArrayDynamicIndexing);
1466 if (TypeInst->
getOpcode() != SPIRV::OpTypeImage)
1475 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product))
1476 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_integer_dot_product);
1480 assert(
MI.getOperand(2).isReg() &&
"Unexpected operand in dot");
1484 assert(
Input->getOperand(1).isReg() &&
"Unexpected operand in dot input");
1488 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1490 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8BitPacked);
1497 "Dot operand of 8-bit integer type requires 4 components");
1498 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8Bit);
1514 unsigned AddrSpace = ASOp.
getImm();
1515 if (AddrSpace != SPIRV::StorageClass::UniformConstant) {
1516 if (!ST.canUseExtension(
1518 SPV_EXT_relaxed_printf_string_address_space)) {
1520 "required because printf uses a format string not "
1521 "in constant address space.",
1525 SPIRV::Extension::SPV_EXT_relaxed_printf_string_address_space);
1534 if (
MI.getNumOperands() <= OpIdx)
1536 uint32_t Mask =
MI.getOperand(OpIdx).getImm();
1538 if (Mask & (1U <<
I))
1549 if (ElemTypeDef->
getOpcode() == SPIRV::OpTypePointer &&
1550 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
1551 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter);
1552 Reqs.
addCapability(SPIRV::Capability::MaskedGatherScatterINTEL);
1560 unsigned Op =
MI.getOpcode();
1562 case SPIRV::OpMemoryModel: {
1563 int64_t Addr =
MI.getOperand(0).getImm();
1566 int64_t Mem =
MI.getOperand(1).getImm();
1571 case SPIRV::OpEntryPoint: {
1572 int64_t Exe =
MI.getOperand(0).getImm();
1577 case SPIRV::OpExecutionMode:
1578 case SPIRV::OpExecutionModeId: {
1579 int64_t Exe =
MI.getOperand(1).getImm();
1584 case SPIRV::OpTypeMatrix:
1587 case SPIRV::OpTypeInt: {
1588 unsigned BitWidth =
MI.getOperand(1).getImm();
1596 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1600 if (!ST.canUseExtension(
1601 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers))
1603 "OpTypeInt type with a width other than 8, 16, 32 or 64 bits "
1604 "requires the following SPIR-V extension: "
1605 "SPV_ALTERA_arbitrary_precision_integers");
1607 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
1608 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
1612 case SPIRV::OpDot: {
1616 Reqs.
addCapability(SPIRV::Capability::BFloat16DotProductKHR);
1619 case SPIRV::OpTypeFloat: {
1620 unsigned BitWidth =
MI.getOperand(1).getImm();
1625 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_bfloat16))
1627 "following SPIR-V extension: SPV_KHR_bfloat16",
1637 case SPIRV::OpTypeVector: {
1638 unsigned NumComponents =
MI.getOperand(2).getImm();
1639 if (NumComponents == 8 || NumComponents == 16)
1644 "OpTypeVector with " +
Twine(NumComponents) +
1645 " components requires the following SPIR-V extension: "
1646 "SPV_EXT_long_vector");
1651 case SPIRV::OpTypeVectorIdEXT: {
1652 if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_long_vector))
1654 "extension: SPV_EXT_long_vector extension");
1655 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_long_vector);
1660 case SPIRV::OpTypePointer: {
1661 auto SC =
MI.getOperand(1).getImm();
1672 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1677 case SPIRV::OpExtInst: {
1678 if (
MI.getOperand(2).getImm() ==
1679 static_cast<int64_t
>(
1680 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1681 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1684 if (
MI.getOperand(3).getImm() ==
1685 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1689 if (
MI.getOperand(2).getImm() ==
1690 static_cast<int64_t
>(SPIRV::InstructionSet::OpenCL_std)) {
1696 if (TypeDef && TypeDef->getOpcode() == SPIRV::OpTypeVector)
1697 TypeDef = MRI.
getVRegDef(TypeDef->getOperand(1).getReg());
1702 bool UsesBFloat16 = IsBFloat16(MRI.
getVRegDef(
MI.getOperand(1).getReg()));
1703 for (
unsigned I = 4,
E =
MI.getNumOperands();
I <
E && !UsesBFloat16;
1712 if (!ST.canUseExtension(
1713 SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic)) {
1715 MI,
"OpenCL Extended instructions with bfloat16 require the "
1716 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic");
1719 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
1720 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
1725 case SPIRV::OpAliasDomainDeclINTEL:
1726 case SPIRV::OpAliasScopeDeclINTEL:
1727 case SPIRV::OpAliasScopeListDeclINTEL: {
1728 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1729 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1732 case SPIRV::OpBitReverse:
1733 case SPIRV::OpBitFieldInsert:
1734 case SPIRV::OpBitFieldSExtract:
1735 case SPIRV::OpBitFieldUExtract:
1736 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1740 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1743 case SPIRV::OpTypeRuntimeArray:
1746 case SPIRV::OpTypeOpaque:
1747 case SPIRV::OpTypeEvent:
1750 case SPIRV::OpTypePipe:
1751 case SPIRV::OpTypeReserveId:
1754 case SPIRV::OpTypeDeviceEvent:
1755 case SPIRV::OpTypeQueue:
1756 case SPIRV::OpBuildNDRange:
1757 case SPIRV::OpEnqueueKernel:
1760 case SPIRV::OpDecorate:
1761 case SPIRV::OpDecorateId:
1762 case SPIRV::OpDecorateString:
1765 case SPIRV::OpMemberDecorate:
1766 case SPIRV::OpMemberDecorateString:
1769 case SPIRV::OpInBoundsPtrAccessChain:
1772 case SPIRV::OpConstantSampler:
1775 case SPIRV::OpInBoundsAccessChain:
1776 case SPIRV::OpAccessChain:
1779 case SPIRV::OpTypeImage:
1782 case SPIRV::OpTypeSampler:
1783 if (!ST.isShader()) {
1787 case SPIRV::OpTypeForwardPointer:
1791 case SPIRV::OpAtomicFlagTestAndSet:
1792 case SPIRV::OpAtomicLoad:
1793 case SPIRV::OpAtomicStore:
1794 case SPIRV::OpAtomicExchange:
1795 case SPIRV::OpAtomicCompareExchange:
1796 case SPIRV::OpAtomicCompareExchangeWeak:
1797 case SPIRV::OpAtomicIIncrement:
1798 case SPIRV::OpAtomicIDecrement:
1799 case SPIRV::OpAtomicIAdd:
1800 case SPIRV::OpAtomicISub:
1801 case SPIRV::OpAtomicUMin:
1802 case SPIRV::OpAtomicUMax:
1803 case SPIRV::OpAtomicSMin:
1804 case SPIRV::OpAtomicSMax:
1805 case SPIRV::OpAtomicAnd:
1806 case SPIRV::OpAtomicOr:
1807 case SPIRV::OpAtomicXor: {
1810 if (
Op == SPIRV::OpAtomicStore) {
1813 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1819 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1824 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1826 "16-bit integer atomic operations require the following SPIR-V "
1827 "extension: SPV_INTEL_16bit_atomics",
1829 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1831 case SPIRV::OpAtomicLoad:
1832 case SPIRV::OpAtomicStore:
1833 case SPIRV::OpAtomicExchange:
1834 case SPIRV::OpAtomicCompareExchange:
1835 case SPIRV::OpAtomicCompareExchangeWeak:
1837 SPIRV::Capability::AtomicInt16CompareExchangeINTEL);
1845 if (
is_contained({SPIRV::OpAtomicLoad, SPIRV::OpAtomicStore,
1846 SPIRV::OpAtomicExchange},
1848 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1850 "The atomic bfloat16 instruction requires the following SPIR-V "
1851 "extension: SPV_INTEL_16bit_atomics",
1853 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1854 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16LoadStoreINTEL);
1859 case SPIRV::OpGroupNonUniformIAdd:
1860 case SPIRV::OpGroupNonUniformFAdd:
1861 case SPIRV::OpGroupNonUniformIMul:
1862 case SPIRV::OpGroupNonUniformFMul:
1863 case SPIRV::OpGroupNonUniformSMin:
1864 case SPIRV::OpGroupNonUniformUMin:
1865 case SPIRV::OpGroupNonUniformFMin:
1866 case SPIRV::OpGroupNonUniformSMax:
1867 case SPIRV::OpGroupNonUniformUMax:
1868 case SPIRV::OpGroupNonUniformFMax:
1869 case SPIRV::OpGroupNonUniformBitwiseAnd:
1870 case SPIRV::OpGroupNonUniformBitwiseOr:
1871 case SPIRV::OpGroupNonUniformBitwiseXor:
1872 case SPIRV::OpGroupNonUniformLogicalAnd:
1873 case SPIRV::OpGroupNonUniformLogicalOr:
1874 case SPIRV::OpGroupNonUniformLogicalXor: {
1876 int64_t GroupOp =
MI.getOperand(3).getImm();
1878 case SPIRV::GroupOperation::Reduce:
1879 case SPIRV::GroupOperation::InclusiveScan:
1880 case SPIRV::GroupOperation::ExclusiveScan:
1881 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1883 case SPIRV::GroupOperation::ClusteredReduce:
1884 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1886 case SPIRV::GroupOperation::PartitionedReduceNV:
1887 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1888 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1889 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1894 case SPIRV::OpGroupNonUniformQuadSwap:
1897 case SPIRV::OpImageQueryLod:
1900 case SPIRV::OpImageQuerySize:
1901 case SPIRV::OpImageQuerySizeLod:
1902 case SPIRV::OpImageQueryLevels:
1903 case SPIRV::OpImageQuerySamples:
1907 case SPIRV::OpImageQueryFormat: {
1908 Register ResultReg =
MI.getOperand(0).getReg();
1910 static const unsigned CompareOps[] = {
1911 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1912 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1913 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1914 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1915 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1917 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1918 if (ImmVal == 4323 || ImmVal == 4324) {
1919 if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1920 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1923 "SPV_EXT_image_raw10_raw12 extension");
1928 unsigned Opc = UseInst.getOpcode();
1930 if (
Opc == SPIRV::OpSwitch) {
1933 CheckAndAddExtension(
Op.getImm());
1935 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1938 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1941 CheckAndAddExtension(ImmVal);
1949 case SPIRV::OpGroupNonUniformShuffle:
1950 case SPIRV::OpGroupNonUniformShuffleXor:
1951 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1953 case SPIRV::OpGroupNonUniformShuffleUp:
1954 case SPIRV::OpGroupNonUniformShuffleDown:
1955 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1957 case SPIRV::OpGroupAll:
1958 case SPIRV::OpGroupAny:
1959 case SPIRV::OpGroupBroadcast:
1960 case SPIRV::OpGroupIAdd:
1961 case SPIRV::OpGroupFAdd:
1962 case SPIRV::OpGroupFMin:
1963 case SPIRV::OpGroupUMin:
1964 case SPIRV::OpGroupSMin:
1965 case SPIRV::OpGroupFMax:
1966 case SPIRV::OpGroupUMax:
1967 case SPIRV::OpGroupSMax:
1970 case SPIRV::OpGroupNonUniformElect:
1973 case SPIRV::OpGroupNonUniformAll:
1974 case SPIRV::OpGroupNonUniformAny:
1975 case SPIRV::OpGroupNonUniformAllEqual:
1978 case SPIRV::OpGroupNonUniformBroadcast:
1979 case SPIRV::OpGroupNonUniformBroadcastFirst:
1980 case SPIRV::OpGroupNonUniformBallot:
1981 case SPIRV::OpGroupNonUniformInverseBallot:
1982 case SPIRV::OpGroupNonUniformBallotBitExtract:
1983 case SPIRV::OpGroupNonUniformBallotBitCount:
1984 case SPIRV::OpGroupNonUniformBallotFindLSB:
1985 case SPIRV::OpGroupNonUniformBallotFindMSB:
1986 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1988 case SPIRV::OpSubgroupShuffleINTEL:
1989 case SPIRV::OpSubgroupShuffleDownINTEL:
1990 case SPIRV::OpSubgroupShuffleUpINTEL:
1991 case SPIRV::OpSubgroupShuffleXorINTEL:
1992 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1993 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1994 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1997 case SPIRV::OpSubgroupBlockReadINTEL:
1998 case SPIRV::OpSubgroupBlockWriteINTEL:
1999 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
2000 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
2001 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
2004 case SPIRV::OpSubgroupImageBlockReadINTEL:
2005 case SPIRV::OpSubgroupImageBlockWriteINTEL:
2006 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
2007 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
2008 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
2011 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
2012 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
2013 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
2014 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
2015 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
2018 case SPIRV::OpAssumeTrueKHR:
2019 case SPIRV::OpExpectKHR:
2020 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
2021 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
2025 case SPIRV::OpFmaKHR:
2026 if (ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
2031 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
2032 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
2033 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
2034 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
2035 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
2038 case SPIRV::OpConstantFunctionPointerINTEL:
2039 case SPIRV::OpFunctionPointerCallINTEL:
2040 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
2041 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
2042 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
2045 case SPIRV::OpGroupNonUniformRotateKHR:
2046 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
2048 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
2050 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
2051 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
2054 case SPIRV::OpFixedCosALTERA:
2055 case SPIRV::OpFixedSinALTERA:
2056 case SPIRV::OpFixedCosPiALTERA:
2057 case SPIRV::OpFixedSinPiALTERA:
2058 case SPIRV::OpFixedExpALTERA:
2059 case SPIRV::OpFixedLogALTERA:
2060 case SPIRV::OpFixedRecipALTERA:
2061 case SPIRV::OpFixedSqrtALTERA:
2062 case SPIRV::OpFixedSinCosALTERA:
2063 case SPIRV::OpFixedSinCosPiALTERA:
2064 case SPIRV::OpFixedRsqrtALTERA:
2065 if (!ST.canUseExtension(
2066 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
2068 "following SPIR-V extension: "
2069 "SPV_ALTERA_arbitrary_precision_fixed_point",
2072 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
2073 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
2075 case SPIRV::OpGroupIMulKHR:
2076 case SPIRV::OpGroupFMulKHR:
2077 case SPIRV::OpGroupBitwiseAndKHR:
2078 case SPIRV::OpGroupBitwiseOrKHR:
2079 case SPIRV::OpGroupBitwiseXorKHR:
2080 case SPIRV::OpGroupLogicalAndKHR:
2081 case SPIRV::OpGroupLogicalOrKHR:
2082 case SPIRV::OpGroupLogicalXorKHR:
2083 if (ST.canUseExtension(
2084 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
2085 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
2086 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
2089 case SPIRV::OpReadClockKHR:
2090 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
2092 "following SPIR-V extension: SPV_KHR_shader_clock",
2094 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
2097 case SPIRV::OpAbortKHR:
2098 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_abort))
2100 "following SPIR-V extension: SPV_KHR_abort",
2105 case SPIRV::OpPoisonKHR:
2106 case SPIRV::OpFreezeKHR:
2107 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_poison_freeze))
2109 "following SPIR-V extension: SPV_KHR_poison_freeze",
2111 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_poison_freeze);
2114 case SPIRV::OpAtomicFAddEXT:
2115 case SPIRV::OpAtomicFMinEXT:
2116 case SPIRV::OpAtomicFMaxEXT:
2119 case SPIRV::OpConvertBF16ToFINTEL:
2120 case SPIRV::OpConvertFToBF16INTEL:
2121 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
2122 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
2123 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
2126 case SPIRV::OpRoundFToTF32INTEL:
2127 if (ST.canUseExtension(
2128 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
2129 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
2130 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
2133 case SPIRV::OpVariableLengthArrayINTEL:
2134 case SPIRV::OpSaveMemoryINTEL:
2135 case SPIRV::OpRestoreMemoryINTEL:
2136 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
2137 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
2138 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
2141 case SPIRV::OpAsmTargetINTEL:
2142 case SPIRV::OpAsmINTEL:
2143 case SPIRV::OpAsmCallINTEL:
2144 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
2145 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
2149 case SPIRV::OpTypeCooperativeMatrixKHR: {
2150 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2152 "OpTypeCooperativeMatrixKHR type requires the "
2153 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
2155 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2156 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2160 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
2163 case SPIRV::OpArithmeticFenceEXT:
2164 if (!ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
2166 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
2168 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
2171 case SPIRV::OpControlBarrierArriveINTEL:
2172 case SPIRV::OpControlBarrierWaitINTEL:
2173 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
2174 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
2178 case SPIRV::OpCooperativeMatrixMulAddKHR: {
2179 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2181 "following SPIR-V extension: "
2182 "SPV_KHR_cooperative_matrix",
2184 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2185 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2186 constexpr unsigned MulAddMaxSize = 6;
2187 if (
MI.getNumOperands() != MulAddMaxSize)
2189 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
2191 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
2192 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2194 "require the following SPIR-V extension: "
2195 "SPV_INTEL_joint_matrix",
2197 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2199 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
2202 MatrixAAndBBFloat16ComponentsINTEL ||
2204 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
2206 MatrixResultBFloat16ComponentsINTEL) {
2207 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2209 "require the following SPIR-V extension: "
2210 "SPV_INTEL_joint_matrix",
2212 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2214 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
2218 case SPIRV::OpCooperativeMatrixLoadKHR:
2219 case SPIRV::OpCooperativeMatrixStoreKHR:
2220 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2221 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2222 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
2223 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
2225 "following SPIR-V extension: "
2226 "SPV_KHR_cooperative_matrix",
2228 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
2229 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
2235 case SPIRV::OpCooperativeMatrixLoadKHR:
2238 case SPIRV::OpCooperativeMatrixStoreKHR:
2241 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2244 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2245 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2251 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
2254 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
2257 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
2258 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2260 "extension: SPV_INTEL_joint_matrix",
2262 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2263 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2268 if (
Op == SPIRV::OpCooperativeMatrixLoadKHR ||
2269 Op == SPIRV::OpCooperativeMatrixStoreKHR)
2272 std::string InstName;
2274 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2275 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2277 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2278 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2280 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2281 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2285 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2286 const std::string ErrorMsg =
2287 InstName +
" instruction requires the "
2288 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2291 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2292 if (
Op == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2293 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2297 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2300 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2301 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2303 "instructions require the following SPIR-V extension: "
2304 "SPV_INTEL_joint_matrix",
2306 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2308 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2310 case SPIRV::OpReadPipeBlockingALTERA:
2311 case SPIRV::OpWritePipeBlockingALTERA:
2312 if (ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2313 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2317 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2318 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2320 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2322 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2324 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2326 case SPIRV::OpConvertHandleToImageINTEL:
2327 case SPIRV::OpConvertHandleToSamplerINTEL:
2328 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2329 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2331 "instructions require the following SPIR-V extension: "
2332 "SPV_INTEL_bindless_images",
2335 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2337 if (
Op == SPIRV::OpConvertHandleToImageINTEL &&
2338 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2340 "OpConvertHandleToImageINTEL",
2342 }
else if (
Op == SPIRV::OpConvertHandleToSamplerINTEL &&
2343 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2345 "OpConvertHandleToSamplerINTEL",
2347 }
else if (
Op == SPIRV::OpConvertHandleToSampledImageINTEL &&
2348 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2350 "OpConvertHandleToSampledImageINTEL",
2355 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2356 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2358 "Parameter value must be a 32-bit scalar in case of "
2359 "Physical32 addressing model or a 64-bit scalar in case of "
2360 "Physical64 addressing model",
2363 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2367 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2368 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2369 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2370 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2371 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2372 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2374 "Prefetch/Store]INTEL instructions require the "
2375 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2377 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2378 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2380 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2381 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2384 if (
Op == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2385 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2390 case SPIRV::OpKill: {
2393 case SPIRV::OpDemoteToHelperInvocation:
2394 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2396 if (ST.canUseExtension(
2397 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2400 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2405 case SPIRV::OpSUDot:
2406 case SPIRV::OpSDotAccSat:
2407 case SPIRV::OpUDotAccSat:
2408 case SPIRV::OpSUDotAccSat:
2411 case SPIRV::OpImageSampleImplicitLod:
2412 case SPIRV::OpImageFetch:
2416 case SPIRV::OpImageSampleExplicitLod:
2419 case SPIRV::OpImageSampleDrefImplicitLod:
2420 case SPIRV::OpImageSampleDrefExplicitLod:
2421 case SPIRV::OpImageDrefGather:
2422 case SPIRV::OpImageGather:
2426 case SPIRV::OpImageRead: {
2427 Register ImageReg =
MI.getOperand(2).getReg();
2428 SPIRVTypeInst TypeDef = ST.getSPIRVGlobalRegistry()->getResultType(
2437 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2440 case SPIRV::OpImageWrite: {
2441 Register ImageReg =
MI.getOperand(0).getReg();
2442 SPIRVTypeInst TypeDef = ST.getSPIRVGlobalRegistry()->getResultType(
2451 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2454 case SPIRV::OpTypeStructContinuedINTEL:
2455 case SPIRV::OpConstantCompositeContinuedINTEL:
2456 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2457 case SPIRV::OpCompositeConstructContinuedINTEL: {
2458 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2460 "Continued instructions require the "
2461 "following SPIR-V extension: SPV_INTEL_long_composites",
2463 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2467 case SPIRV::OpArbitraryFloatEQALTERA:
2468 case SPIRV::OpArbitraryFloatGEALTERA:
2469 case SPIRV::OpArbitraryFloatGTALTERA:
2470 case SPIRV::OpArbitraryFloatLEALTERA:
2471 case SPIRV::OpArbitraryFloatLTALTERA:
2472 case SPIRV::OpArbitraryFloatCbrtALTERA:
2473 case SPIRV::OpArbitraryFloatCosALTERA:
2474 case SPIRV::OpArbitraryFloatCosPiALTERA:
2475 case SPIRV::OpArbitraryFloatExp10ALTERA:
2476 case SPIRV::OpArbitraryFloatExp2ALTERA:
2477 case SPIRV::OpArbitraryFloatExpALTERA:
2478 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2479 case SPIRV::OpArbitraryFloatHypotALTERA:
2480 case SPIRV::OpArbitraryFloatLog10ALTERA:
2481 case SPIRV::OpArbitraryFloatLog1pALTERA:
2482 case SPIRV::OpArbitraryFloatLog2ALTERA:
2483 case SPIRV::OpArbitraryFloatLogALTERA:
2484 case SPIRV::OpArbitraryFloatRecipALTERA:
2485 case SPIRV::OpArbitraryFloatSinCosALTERA:
2486 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2487 case SPIRV::OpArbitraryFloatSinALTERA:
2488 case SPIRV::OpArbitraryFloatSinPiALTERA:
2489 case SPIRV::OpArbitraryFloatSqrtALTERA:
2490 case SPIRV::OpArbitraryFloatACosALTERA:
2491 case SPIRV::OpArbitraryFloatACosPiALTERA:
2492 case SPIRV::OpArbitraryFloatAddALTERA:
2493 case SPIRV::OpArbitraryFloatASinALTERA:
2494 case SPIRV::OpArbitraryFloatASinPiALTERA:
2495 case SPIRV::OpArbitraryFloatATan2ALTERA:
2496 case SPIRV::OpArbitraryFloatATanALTERA:
2497 case SPIRV::OpArbitraryFloatATanPiALTERA:
2498 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2499 case SPIRV::OpArbitraryFloatCastALTERA:
2500 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2501 case SPIRV::OpArbitraryFloatDivALTERA:
2502 case SPIRV::OpArbitraryFloatMulALTERA:
2503 case SPIRV::OpArbitraryFloatPowALTERA:
2504 case SPIRV::OpArbitraryFloatPowNALTERA:
2505 case SPIRV::OpArbitraryFloatPowRALTERA:
2506 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2507 case SPIRV::OpArbitraryFloatSubALTERA: {
2508 if (!ST.canUseExtension(
2509 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2511 "Floating point instructions can't be translated correctly without "
2512 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2515 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2517 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2520 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2521 if (!ST.canUseExtension(
2522 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2524 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2526 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2529 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2531 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2534 case SPIRV::OpBitwiseFunctionINTEL: {
2535 if (!ST.canUseExtension(
2536 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2538 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2539 "extension: SPV_INTEL_ternary_bitwise_function",
2541 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2542 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2545 case SPIRV::OpCopyMemorySized: {
2550 case SPIRV::OpTypeUntypedPointerKHR:
2552 MI.getOperand(1).getImm(), ST);
2554 case SPIRV::OpUntypedVariableKHR:
2555 case SPIRV::OpUntypedAccessChainKHR:
2556 case SPIRV::OpUntypedInBoundsAccessChainKHR:
2557 case SPIRV::OpUntypedPtrAccessChainKHR:
2558 case SPIRV::OpUntypedInBoundsPtrAccessChainKHR:
2559 case SPIRV::OpUntypedPrefetchKHR:
2560 case SPIRV::OpUntypedGroupAsyncCopyKHR: {
2561 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_untyped_pointers))
2563 "SPIR-V extension: SPV_KHR_untyped_pointers",
2565 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_untyped_pointers);
2569 case SPIRV::OpPredicatedLoadINTEL:
2570 case SPIRV::OpPredicatedStoreINTEL: {
2571 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2573 "OpPredicated[Load/Store]INTEL instructions require "
2574 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2576 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2580 case SPIRV::OpFAddS:
2581 case SPIRV::OpFSubS:
2582 case SPIRV::OpFMulS:
2583 case SPIRV::OpFDivS:
2584 case SPIRV::OpFRemS:
2586 case SPIRV::OpFNegate:
2587 case SPIRV::OpFAddV:
2588 case SPIRV::OpFSubV:
2589 case SPIRV::OpFMulV:
2590 case SPIRV::OpFDivV:
2591 case SPIRV::OpFRemV:
2592 case SPIRV::OpFNegateV: {
2598 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2600 "Arithmetic instructions with bfloat16 arguments require the "
2601 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2603 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2604 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2608 case SPIRV::OpOrdered:
2609 case SPIRV::OpUnordered:
2610 case SPIRV::OpFOrdEqual:
2611 case SPIRV::OpFOrdNotEqual:
2612 case SPIRV::OpFOrdLessThan:
2613 case SPIRV::OpFOrdLessThanEqual:
2614 case SPIRV::OpFOrdGreaterThan:
2615 case SPIRV::OpFOrdGreaterThanEqual:
2616 case SPIRV::OpFUnordEqual:
2617 case SPIRV::OpFUnordNotEqual:
2618 case SPIRV::OpFUnordLessThan:
2619 case SPIRV::OpFUnordLessThanEqual:
2620 case SPIRV::OpFUnordGreaterThan:
2621 case SPIRV::OpFUnordGreaterThanEqual: {
2628 if (!ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2630 "Relational instructions with bfloat16 arguments require the "
2631 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2633 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2634 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2638 case SPIRV::OpDPdxCoarse:
2639 case SPIRV::OpDPdyCoarse:
2640 case SPIRV::OpDPdxFine:
2641 case SPIRV::OpDPdyFine: {
2645 case SPIRV::OpLoopControlINTEL: {
2646 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2647 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2659 SPIRV::Capability::Shader);
2674 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2676 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2677 RequireKHRFloatControls2 =
false,
2678 VerLower14 = !ST.isAtLeastSPIRVVer(
VersionTuple(1, 4));
2679 bool HasIntelFloatControls2 =
2680 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2681 bool HasKHRFloatControls2 =
2682 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2683 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2689 auto EM = Const->getZExtValue();
2693 case SPIRV::ExecutionMode::DenormPreserve:
2694 case SPIRV::ExecutionMode::DenormFlushToZero:
2695 case SPIRV::ExecutionMode::RoundingModeRTE:
2696 case SPIRV::ExecutionMode::RoundingModeRTZ:
2697 RequireFloatControls = VerLower14;
2699 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2701 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2702 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2703 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2704 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2705 if (HasIntelFloatControls2) {
2706 RequireIntelFloatControls2 =
true;
2708 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2711 case SPIRV::ExecutionMode::FPFastMathDefault: {
2712 if (HasKHRFloatControls2) {
2713 RequireKHRFloatControls2 =
true;
2715 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2719 case SPIRV::ExecutionMode::ContractionOff:
2720 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2721 if (HasKHRFloatControls2) {
2722 RequireKHRFloatControls2 =
true;
2724 SPIRV::OperandCategory::ExecutionModeOperand,
2725 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2728 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2733 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2738 if (RequireFloatControls &&
2739 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2741 if (RequireIntelFloatControls2)
2743 if (RequireKHRFloatControls2)
2747 if (
F.isDeclaration())
2749 if (
F.getMetadata(
"reqd_work_group_size"))
2751 SPIRV::OperandCategory::ExecutionModeOperand,
2752 SPIRV::ExecutionMode::LocalSize, ST);
2753 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2755 SPIRV::OperandCategory::ExecutionModeOperand,
2756 SPIRV::ExecutionMode::LocalSize, ST);
2758 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2761 if (
F.getMetadata(
"work_group_size_hint"))
2763 SPIRV::OperandCategory::ExecutionModeOperand,
2764 SPIRV::ExecutionMode::LocalSizeHint, ST);
2765 if (
F.getMetadata(
"intel_reqd_sub_group_size") ||
2766 F.getMetadata(
"reqd_sub_group_size"))
2768 SPIRV::OperandCategory::ExecutionModeOperand,
2769 SPIRV::ExecutionMode::SubgroupSize, ST);
2770 if (
F.getMetadata(
"max_work_group_size"))
2772 SPIRV::OperandCategory::ExecutionModeOperand,
2773 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2774 if (
F.getMetadata(
"vec_type_hint"))
2776 SPIRV::OperandCategory::ExecutionModeOperand,
2777 SPIRV::ExecutionMode::VecTypeHint, ST);
2779 if (
F.hasOptNone()) {
2780 if (ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2783 }
else if (ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2793 unsigned Flags = SPIRV::FPFastMathMode::None;
2794 bool CanUseKHRFloatControls2 =
2795 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2797 Flags |= SPIRV::FPFastMathMode::NotNaN;
2799 Flags |= SPIRV::FPFastMathMode::NotInf;
2801 Flags |= SPIRV::FPFastMathMode::NSZ;
2803 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2805 Flags |= SPIRV::FPFastMathMode::AllowContract;
2807 if (CanUseKHRFloatControls2)
2815 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2816 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2817 SPIRV::FPFastMathMode::AllowTransform |
2818 SPIRV::FPFastMathMode::AllowReassoc |
2819 SPIRV::FPFastMathMode::AllowContract;
2821 Flags |= SPIRV::FPFastMathMode::Fast;
2824 if (CanUseKHRFloatControls2) {
2826 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2827 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2832 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2833 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2834 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2835 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2836 "AllowContract flags to be enabled as well.");
2847 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2854 if (
TII.canUseIntegerWrapDecoration(
I)) {
2857 SPIRV::OperandCategory::DecorationOperand,
2858 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2861 SPIRV::Decoration::NoSignedWrap, {});
2864 SPIRV::OperandCategory::DecorationOperand,
2865 SPIRV::Decoration::NoUnsignedWrap, ST, Reqs)
2868 SPIRV::Decoration::NoUnsignedWrap, {});
2873 TII.canUseFastMathFlags(
2874 I, ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) ||
2875 (ST.isKernel() &&
I.getOpcode() == SPIRV::OpExtInst);
2880 if (FMFlags == SPIRV::FPFastMathMode::None) {
2883 if (FPFastMathDefaultInfoVec.
empty())
2899 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2900 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2901 ?
I.getOperand(1).getReg()
2902 :
I.getOperand(2).getReg();
2910 if (Ty == Elem.Ty) {
2911 FMFlags = Elem.FastMathFlags;
2912 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2913 Elem.FPFastMathDefault;
2918 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2922 Register DstReg =
I.getOperand(0).getReg();
2938 for (
auto &
MBB : *MF)
2939 for (
auto &
MI :
MBB)
2957 for (
auto &
MBB : *MF) {
2958 if (!
MBB.hasName() ||
MBB.empty())
2977 for (
auto &
MBB : *MF) {
2979 MI.setDesc(
TII.get(SPIRV::OpPhi));
2982 MI.insert(
MI.operands_begin() + 1,
2983 {MachineOperand::CreateReg(ResTypeReg, false)});
3002 SPIRV::FPFastMathMode::None);
3004 SPIRV::FPFastMathMode::None);
3006 SPIRV::FPFastMathMode::None);
3013 size_t BitWidth = Ty->getScalarSizeInBits();
3017 assert(Index >= 0 && Index < 3 &&
3018 "Expected FPFastMathDefaultInfo for half, float, or double");
3019 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
3020 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
3021 return FPFastMathDefaultInfoVec[Index];
3027 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
3036 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
3040 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
3049 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
3051 "Expected 4 operands for FPFastMathDefault");
3062 Info.FastMathFlags = Flags;
3063 Info.FPFastMathDefault =
true;
3064 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
3066 "Expected no operands for ContractionOff");
3073 Info.ContractionOff =
true;
3075 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
3077 "Expected 1 operand for SignedZeroInfNanPreserve");
3078 unsigned TargetWidth =
3087 assert(Index >= 0 && Index < 3 &&
3088 "Expected FPFastMathDefaultInfo for half, float, or double");
3089 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
3090 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
3091 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
3106 TII = ST->getInstrInfo();
3122 collectDeclarations(M);
3125 numberRegistersGlobally(M);
3128 processOtherInstrs(M);
3132 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
3135 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 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 cl::opt< bool > SPVDumpDeps("spv-dump-deps", cl::desc("Dump MIR with SPIR-V dependencies info"), cl::init(false))
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