34#define DEBUG_TYPE "spirv-module-analysis"
38 cl::desc(
"Dump MIR with SPIR-V dependencies info"),
43 cl::desc(
"SPIR-V capabilities to avoid if there are "
44 "other options enabling a feature"),
47 "SPIR-V Shader capability")));
61 unsigned DefaultVal = 0) {
63 const auto &
Op = MdNode->getOperand(
OpIndex);
70getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category,
76 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
78 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
83 bool MinVerOK = SPIRVVersion.
empty() || SPIRVVersion >= ReqMinVer;
85 ReqMaxVer.
empty() || SPIRVVersion.
empty() || SPIRVVersion <= ReqMaxVer;
88 if (ReqCaps.
empty()) {
89 if (ReqExts.
empty()) {
90 if (MinVerOK && MaxVerOK)
91 return {
true, {}, {}, ReqMinVer, ReqMaxVer};
94 }
else if (MinVerOK && MaxVerOK) {
95 if (ReqCaps.
size() == 1) {
96 auto Cap = ReqCaps[0];
99 SPIRV::OperandCategory::CapabilityOperand, Cap));
100 return {
true, {Cap}, std::move(ReqExts), ReqMinVer, ReqMaxVer};
110 for (
auto Cap : ReqCaps)
113 for (
size_t i = 0, Sz = UseCaps.
size(); i < Sz; ++i) {
114 auto Cap = UseCaps[i];
115 if (i == Sz - 1 || !AvoidCaps.
S.
contains(Cap)) {
117 SPIRV::OperandCategory::CapabilityOperand, Cap));
118 return {
true, {Cap}, std::move(ReqExts), ReqMinVer, ReqMaxVer};
126 if (
llvm::all_of(ReqExts, [&ST](
const SPIRV::Extension::Extension &Ext) {
127 return ST.canUseExtension(Ext);
138void SPIRVModuleAnalysis::setBaseInfo(
const Module &M) {
142 MAI.RegisterAliasTable.clear();
143 MAI.InstrsToDelete.clear();
145 MAI.GlobalVarList.clear();
146 MAI.ExtInstSetMap.clear();
148 MAI.Reqs.initAvailableCapabilities(*ST);
151 if (
auto MemModel =
M.getNamedMetadata(
"spirv.MemoryModel")) {
152 auto MemMD = MemModel->getOperand(0);
153 MAI.Addr =
static_cast<SPIRV::AddressingModel::AddressingModel
>(
154 getMetadataUInt(MemMD, 0));
156 static_cast<SPIRV::MemoryModel::MemoryModel
>(getMetadataUInt(MemMD, 1));
159 MAI.Mem = ST->isShader() ? SPIRV::MemoryModel::GLSL450
160 : SPIRV::MemoryModel::OpenCL;
161 if (
MAI.Mem == SPIRV::MemoryModel::OpenCL) {
162 unsigned PtrSize = ST->getPointerSize();
163 MAI.Addr = PtrSize == 32 ? SPIRV::AddressingModel::Physical32
164 : PtrSize == 64 ? SPIRV::AddressingModel::Physical64
165 : SPIRV::AddressingModel::Logical;
168 MAI.Addr = SPIRV::AddressingModel::Logical;
173 if (
auto VerNode =
M.getNamedMetadata(
"opencl.ocl.version")) {
174 MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_C;
177 assert(VerNode->getNumOperands() > 0 &&
"Invalid SPIR");
178 auto VersionMD = VerNode->getOperand(0);
179 unsigned MajorNum = getMetadataUInt(VersionMD, 0, 2);
180 unsigned MinorNum = getMetadataUInt(VersionMD, 1);
181 unsigned RevNum = getMetadataUInt(VersionMD, 2);
184 (std::max(1U, MajorNum) * 100 + MinorNum) * 1000 + RevNum;
190 if (!ST->isShader()) {
191 MAI.SrcLang = SPIRV::SourceLanguage::OpenCL_CPP;
192 MAI.SrcLangVersion = 100000;
194 MAI.SrcLang = SPIRV::SourceLanguage::Unknown;
195 MAI.SrcLangVersion = 0;
199 if (
auto ExtNode =
M.getNamedMetadata(
"opencl.used.extensions")) {
200 for (
unsigned I = 0,
E = ExtNode->getNumOperands();
I !=
E; ++
I) {
201 MDNode *MD = ExtNode->getOperand(
I);
211 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::MemoryModelOperand,
213 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::SourceLanguageOperand,
215 MAI.Reqs.getAndAddRequirements(SPIRV::OperandCategory::AddressingModelOperand,
218 if (!ST->isShader()) {
220 MAI.ExtInstSetMap[
static_cast<unsigned>(
221 SPIRV::InstructionSet::OpenCL_std)] =
MAI.getNextIDRegister();
232 if (
UseMI.getOpcode() != SPIRV::OpDecorate &&
233 UseMI.getOpcode() != SPIRV::OpMemberDecorate)
236 for (
unsigned I = 0;
I <
UseMI.getNumOperands(); ++
I) {
254 for (
unsigned i = 0; i <
MI.getNumOperands(); ++i) {
263 unsigned Opcode =
MI.getOpcode();
264 if ((Opcode == SPIRV::OpDecorate) && i >= 2) {
265 unsigned DecorationID =
MI.getOperand(1).getImm();
266 if (DecorationID != SPIRV::Decoration::FuncParamAttr &&
267 DecorationID != SPIRV::Decoration::UserSemantic &&
268 DecorationID != SPIRV::Decoration::CacheControlLoadINTEL &&
269 DecorationID != SPIRV::Decoration::CacheControlStoreINTEL)
275 if (!UseDefReg && MO.
isDef()) {
283 dbgs() <<
"Unexpectedly, no global id found for the operand ";
285 dbgs() <<
"\nInstruction: ";
304 appendDecorationsForReg(
MI.getMF()->getRegInfo(), DefReg, Signature);
311 unsigned Opcode =
MI.getOpcode();
313 case SPIRV::OpTypeForwardPointer:
316 case SPIRV::OpVariable:
317 return static_cast<SPIRV::StorageClass::StorageClass
>(
318 MI.getOperand(2).
getImm()) != SPIRV::StorageClass::Function;
319 case SPIRV::OpFunction:
320 case SPIRV::OpFunctionParameter:
323 if (GR->hasConstFunPtr() && Opcode == SPIRV::OpUndef) {
326 if (
UseMI.getOpcode() != SPIRV::OpConstantFunctionPointerINTEL)
332 MAI.setSkipEmission(&
MI);
336 return TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
337 TII->isInlineAsmDefInstr(
MI);
343void SPIRVModuleAnalysis::visitFunPtrUse(
345 std::map<const Value *, unsigned> &GlobalToGReg,
const MachineFunction *MF,
347 const MachineOperand *OpFunDef =
348 GR->getFunctionDefinitionByUse(&
MI.getOperand(2));
351 const MachineInstr *OpDefMI = OpFunDef->
getParent();
354 const MachineRegisterInfo &FunDefMRI = FunDefMF->
getRegInfo();
356 visitDecl(FunDefMRI, SignatureToGReg, GlobalToGReg, FunDefMF, *OpDefMI);
358 }
while (OpDefMI && (OpDefMI->
getOpcode() == SPIRV::OpFunction ||
359 OpDefMI->
getOpcode() == SPIRV::OpFunctionParameter));
361 MCRegister GlobalFunDefReg =
362 MAI.getRegisterAlias(FunDefMF, OpFunDef->
getReg());
364 "Function definition must refer to a global register");
365 MAI.setRegisterAlias(MF, OpReg, GlobalFunDefReg);
370void SPIRVModuleAnalysis::visitDecl(
372 std::map<const Value *, unsigned> &GlobalToGReg,
const MachineFunction *MF,
374 unsigned Opcode =
MI.getOpcode();
377 for (
const MachineOperand &MO :
MI.operands()) {
382 if (Opcode == SPIRV::OpConstantFunctionPointerINTEL &&
384 visitFunPtrUse(OpReg, SignatureToGReg, GlobalToGReg, MF,
MI);
388 if (
MAI.hasRegisterAlias(MF, MO.
getReg()))
392 if (isDeclSection(MRI, *OpDefMI))
393 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF, *OpDefMI);
399 dbgs() <<
"Unexpectedly, no unique definition for the operand ";
401 dbgs() <<
"\nInstruction: ";
406 "No unique definition is found for the virtual register");
410 bool IsFunDef =
false;
411 if (TII->isSpecConstantInstr(
MI)) {
412 GReg =
MAI.getNextIDRegister();
414 }
else if (Opcode == SPIRV::OpFunction ||
415 Opcode == SPIRV::OpFunctionParameter) {
416 GReg = handleFunctionOrParameter(MF,
MI, GlobalToGReg, IsFunDef);
417 }
else if (Opcode == SPIRV::OpTypeStruct ||
418 Opcode == SPIRV::OpConstantComposite) {
419 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
420 const MachineInstr *NextInstr =
MI.getNextNode();
422 ((Opcode == SPIRV::OpTypeStruct &&
423 NextInstr->
getOpcode() == SPIRV::OpTypeStructContinuedINTEL) ||
424 (Opcode == SPIRV::OpConstantComposite &&
426 SPIRV::OpConstantCompositeContinuedINTEL))) {
427 MCRegister Tmp = handleTypeDeclOrConstant(*NextInstr, SignatureToGReg);
429 MAI.setSkipEmission(NextInstr);
432 }
else if (TII->isTypeDeclInstr(
MI) || TII->isConstantInstr(
MI) ||
433 TII->isInlineAsmDefInstr(
MI)) {
434 GReg = handleTypeDeclOrConstant(
MI, SignatureToGReg);
435 }
else if (Opcode == SPIRV::OpVariable) {
436 GReg = handleVariable(MF,
MI, GlobalToGReg);
439 dbgs() <<
"\nInstruction: ";
445 MAI.setRegisterAlias(MF,
MI.getOperand(0).getReg(), GReg);
447 MAI.setSkipEmission(&
MI);
450MCRegister SPIRVModuleAnalysis::handleFunctionOrParameter(
452 std::map<const Value *, unsigned> &GlobalToGReg,
bool &IsFunDef) {
453 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
454 assert(GObj &&
"Unregistered global definition");
458 assert(
F &&
"Expected a reference to a function or an argument");
459 IsFunDef = !
F->isDeclaration();
460 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
463 MCRegister GReg =
MAI.getNextIDRegister();
471SPIRVModuleAnalysis::handleTypeDeclOrConstant(
const MachineInstr &
MI,
474 auto [It,
Inserted] = SignatureToGReg.try_emplace(MISign);
477 MCRegister GReg =
MAI.getNextIDRegister();
483MCRegister SPIRVModuleAnalysis::handleVariable(
485 std::map<const Value *, unsigned> &GlobalToGReg) {
486 MAI.GlobalVarList.push_back(&
MI);
487 const Value *GObj = GR->getGlobalObject(MF,
MI.getOperand(0).getReg());
488 assert(GObj &&
"Unregistered global definition");
489 auto [It,
Inserted] = GlobalToGReg.try_emplace(GObj);
492 MCRegister GReg =
MAI.getNextIDRegister();
498void SPIRVModuleAnalysis::collectDeclarations(
const Module &M) {
500 std::map<const Value *, unsigned> GlobalToGReg;
501 for (
const Function &
F : M) {
502 MachineFunction *MF = MMI->getMachineFunction(
F);
505 const MachineRegisterInfo &MRI = MF->
getRegInfo();
506 unsigned PastHeader = 0;
507 for (MachineBasicBlock &
MBB : *MF) {
508 for (MachineInstr &
MI :
MBB) {
509 if (
MI.getNumOperands() == 0)
511 unsigned Opcode =
MI.getOpcode();
512 if (Opcode == SPIRV::OpFunction) {
513 if (PastHeader == 0) {
517 }
else if (Opcode == SPIRV::OpFunctionParameter) {
520 }
else if (PastHeader > 0) {
524 const MachineOperand &DefMO =
MI.getOperand(0);
526 case SPIRV::OpExtension:
527 MAI.Reqs.addExtension(SPIRV::Extension::Extension(DefMO.
getImm()));
528 MAI.setSkipEmission(&
MI);
530 case SPIRV::OpCapability:
531 MAI.Reqs.addCapability(SPIRV::Capability::Capability(DefMO.
getImm()));
532 MAI.setSkipEmission(&
MI);
537 if (DefMO.
isReg() && isDeclSection(MRI,
MI) &&
538 !
MAI.hasRegisterAlias(MF, DefMO.
getReg()))
539 visitDecl(MRI, SignatureToGReg, GlobalToGReg, MF,
MI);
552 if (
MI.getOpcode() == SPIRV::OpDecorate) {
554 auto Dec =
MI.getOperand(1).getImm();
555 if (Dec == SPIRV::Decoration::LinkageAttributes) {
556 auto Lnk =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
557 if (Lnk == SPIRV::LinkageType::Import) {
562 MAI.FuncMap[ImportedFunc] =
MAI.getRegisterAlias(
MI.getMF(), Target);
565 }
else if (
MI.getOpcode() == SPIRV::OpFunction) {
568 MCRegister GlobalReg =
MAI.getRegisterAlias(
MI.getMF(),
Reg);
570 MAI.FuncMap[
F] = GlobalReg;
582 auto FoundMI = IS.insert(std::move(MISign));
583 if (!FoundMI.second) {
584 if (
MI.getOpcode() == SPIRV::OpDecorate) {
586 "Decoration instructions must have at least 2 operands");
588 "Only OpDecorate instructions can be duplicates");
593 if (
MI.getOperand(1).getImm() != SPIRV::Decoration::FPFastMathMode)
598 if (instrToSignature(*OrigMI, MAI,
true) == MISign) {
599 assert(OrigMI->getNumOperands() ==
MI.getNumOperands() &&
600 "Original instruction must have the same number of operands");
602 OrigMI->getNumOperands() == 3 &&
603 "FPFastMathMode decoration must have 3 operands for OpDecorate");
604 unsigned OrigFlags = OrigMI->getOperand(2).getImm();
605 unsigned NewFlags =
MI.getOperand(2).getImm();
606 if (OrigFlags == NewFlags)
610 unsigned FinalFlags = OrigFlags | NewFlags;
612 <<
"Warning: Conflicting FPFastMathMode decoration flags "
614 << *OrigMI <<
"Original flags: " << OrigFlags
615 <<
", new flags: " << NewFlags
616 <<
". They will be merged on a best effort basis, but not "
617 "validated. Final flags: "
618 << FinalFlags <<
"\n";
625 assert(
false &&
"No original instruction found for the duplicate "
626 "OpDecorate, but we found one in IS.");
639void SPIRVModuleAnalysis::processOtherInstrs(
const Module &M) {
641 for (
const Function &
F : M) {
642 if (
F.isDeclaration())
644 MachineFunction *MF = MMI->getMachineFunction(
F);
647 for (MachineBasicBlock &
MBB : *MF)
648 for (MachineInstr &
MI :
MBB) {
649 if (
MAI.getSkipEmission(&
MI))
651 const unsigned OpCode =
MI.getOpcode();
652 if (OpCode == SPIRV::OpString) {
654 }
else if (OpCode == SPIRV::OpExtInst &&
MI.getOperand(2).isImm() &&
655 MI.getOperand(2).getImm() ==
656 SPIRV::InstructionSet::
657 NonSemantic_Shader_DebugInfo_100) {
658 MachineOperand Ins =
MI.getOperand(3);
659 namespace NS = SPIRV::NonSemanticExtInst;
660 static constexpr int64_t GlobalNonSemanticDITy[] = {
661 NS::DebugSource, NS::DebugCompilationUnit, NS::DebugInfoNone,
662 NS::DebugTypeBasic, NS::DebugTypePointer};
663 bool IsGlobalDI =
false;
664 for (
unsigned Idx = 0; Idx < std::size(GlobalNonSemanticDITy); ++Idx)
665 IsGlobalDI |= Ins.
getImm() == GlobalNonSemanticDITy[Idx];
668 }
else if (OpCode == SPIRV::OpName || OpCode == SPIRV::OpMemberName) {
670 }
else if (OpCode == SPIRV::OpEntryPoint) {
672 }
else if (TII->isAliasingInstr(
MI)) {
674 }
else if (TII->isDecorationInstr(
MI)) {
676 collectFuncNames(
MI, &
F);
677 }
else if (TII->isConstantInstr(
MI)) {
681 }
else if (OpCode == SPIRV::OpFunction) {
682 collectFuncNames(
MI, &
F);
683 }
else if (OpCode == SPIRV::OpTypeForwardPointer) {
693void SPIRVModuleAnalysis::numberRegistersGlobally(
const Module &M) {
694 for (
const Function &
F : M) {
695 if (
F.isDeclaration())
697 MachineFunction *MF = MMI->getMachineFunction(
F);
699 for (MachineBasicBlock &
MBB : *MF) {
700 for (MachineInstr &
MI :
MBB) {
701 for (MachineOperand &
Op :
MI.operands()) {
705 if (
MAI.hasRegisterAlias(MF,
Reg))
707 MCRegister NewReg =
MAI.getNextIDRegister();
708 MAI.setRegisterAlias(MF,
Reg, NewReg);
710 if (
MI.getOpcode() != SPIRV::OpExtInst)
712 auto Set =
MI.getOperand(2).getImm();
713 auto [It,
Inserted] =
MAI.ExtInstSetMap.try_emplace(Set);
715 It->second =
MAI.getNextIDRegister();
723 SPIRV::OperandCategory::OperandCategory Category, uint32_t i,
725 addRequirements(getSymbolicOperandRequirements(Category, i, ST, *
this));
728void SPIRV::RequirementHandler::recursiveAddCapabilities(
730 for (
const auto &Cap : ToPrune) {
734 recursiveAddCapabilities(ImplicitDecls);
739 for (
const auto &Cap : ToAdd) {
740 bool IsNewlyInserted = AllCaps.insert(Cap).second;
741 if (!IsNewlyInserted)
745 recursiveAddCapabilities(ImplicitDecls);
746 MinimalCaps.push_back(Cap);
751 const SPIRV::Requirements &Req) {
755 if (Req.
Cap.has_value())
756 addCapabilities({Req.
Cap.value()});
758 addExtensions(Req.
Exts);
761 if (!MaxVersion.empty() && Req.
MinVer > MaxVersion) {
763 <<
" and <= " << MaxVersion <<
"\n");
767 if (MinVersion.empty() || Req.
MinVer > MinVersion)
772 if (!MinVersion.empty() && Req.
MaxVer < MinVersion) {
774 <<
" and >= " << MinVersion <<
"\n");
778 if (MaxVersion.empty() || Req.
MaxVer < MaxVersion)
784 const SPIRVSubtarget &ST)
const {
786 bool IsSatisfiable =
true;
787 auto TargetVer =
ST.getSPIRVVersion();
789 if (!MaxVersion.empty() && !TargetVer.empty() && MaxVersion < TargetVer) {
791 dbgs() <<
"Target SPIR-V version too high for required features\n"
792 <<
"Required max version: " << MaxVersion <<
" target version "
793 << TargetVer <<
"\n");
794 IsSatisfiable =
false;
797 if (!MinVersion.empty() && !TargetVer.empty() && MinVersion > TargetVer) {
798 LLVM_DEBUG(
dbgs() <<
"Target SPIR-V version too low for required features\n"
799 <<
"Required min version: " << MinVersion
800 <<
" target version " << TargetVer <<
"\n");
801 IsSatisfiable =
false;
804 if (!MinVersion.empty() && !MaxVersion.empty() && MinVersion > MaxVersion) {
807 <<
"Version is too low for some features and too high for others.\n"
808 <<
"Required SPIR-V min version: " << MinVersion
809 <<
" required SPIR-V max version " << MaxVersion <<
"\n");
810 IsSatisfiable =
false;
813 AvoidCapabilitiesSet AvoidCaps;
815 AvoidCaps.
S.
insert(SPIRV::Capability::Shader);
817 AvoidCaps.
S.
insert(SPIRV::Capability::Kernel);
819 for (
auto Cap : MinimalCaps) {
820 if (AvailableCaps.contains(Cap) && !AvoidCaps.
S.
contains(Cap))
824 OperandCategory::CapabilityOperand, Cap)
826 IsSatisfiable =
false;
829 for (
auto Ext : AllExtensions) {
830 if (
ST.canUseExtension(Ext))
834 OperandCategory::ExtensionOperand, Ext)
836 IsSatisfiable =
false;
845 for (
const auto Cap : ToAdd)
846 if (AvailableCaps.insert(Cap).second)
848 SPIRV::OperandCategory::CapabilityOperand, Cap));
852 const Capability::Capability
ToRemove,
853 const Capability::Capability IfPresent) {
854 if (AllCaps.contains(IfPresent))
862 addAvailableCaps({Capability::Shader, Capability::Linkage, Capability::Int8,
865 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 3)))
867 Capability::GroupNonUniformVote,
868 Capability::GroupNonUniformArithmetic,
869 Capability::GroupNonUniformBallot,
870 Capability::GroupNonUniformClustered,
871 Capability::GroupNonUniformShuffle,
872 Capability::GroupNonUniformShuffleRelative});
874 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
876 Capability::DotProductInput4x8Bit,
877 Capability::DotProductInput4x8BitPacked,
878 Capability::DemoteToHelperInvocation});
881 for (
auto Extension :
ST.getAllAvailableExtensions()) {
887 if (!
ST.isShader()) {
888 initAvailableCapabilitiesForOpenCL(ST);
893 initAvailableCapabilitiesForVulkan(ST);
900void RequirementHandler::initAvailableCapabilitiesForOpenCL(
901 const SPIRVSubtarget &ST) {
904 Capability::Kernel, Capability::Vector16,
905 Capability::Groups, Capability::GenericPointer,
906 Capability::StorageImageWriteWithoutFormat,
907 Capability::StorageImageReadWithoutFormat});
908 if (
ST.hasOpenCLFullProfile())
910 if (
ST.hasOpenCLImageSupport()) {
912 Capability::Image1D, Capability::SampledBuffer,
913 Capability::ImageBuffer});
914 if (
ST.isAtLeastOpenCLVer(VersionTuple(2, 0)))
917 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 1)) &&
918 ST.isAtLeastOpenCLVer(VersionTuple(2, 2)))
920 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 4)))
921 addAvailableCaps({Capability::DenormPreserve, Capability::DenormFlushToZero,
922 Capability::SignedZeroInfNanPreserve,
923 Capability::RoundingModeRTE,
924 Capability::RoundingModeRTZ});
931void RequirementHandler::initAvailableCapabilitiesForVulkan(
932 const SPIRVSubtarget &ST) {
935 addAvailableCaps({Capability::Int64, Capability::Float16, Capability::Float64,
936 Capability::GroupNonUniform, Capability::Image1D,
937 Capability::SampledBuffer, Capability::ImageBuffer,
938 Capability::UniformBufferArrayDynamicIndexing,
939 Capability::SampledImageArrayDynamicIndexing,
940 Capability::StorageBufferArrayDynamicIndexing,
941 Capability::StorageImageArrayDynamicIndexing,
942 Capability::DerivativeControl, Capability::MinLod,
943 Capability::ImageGatherExtended});
946 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 5))) {
948 {Capability::ShaderNonUniformEXT, Capability::RuntimeDescriptorArrayEXT,
949 Capability::InputAttachmentArrayDynamicIndexingEXT,
950 Capability::UniformTexelBufferArrayDynamicIndexingEXT,
951 Capability::StorageTexelBufferArrayDynamicIndexingEXT,
952 Capability::UniformBufferArrayNonUniformIndexingEXT,
953 Capability::SampledImageArrayNonUniformIndexingEXT,
954 Capability::StorageBufferArrayNonUniformIndexingEXT,
955 Capability::StorageImageArrayNonUniformIndexingEXT,
956 Capability::InputAttachmentArrayNonUniformIndexingEXT,
957 Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
958 Capability::StorageTexelBufferArrayNonUniformIndexingEXT});
962 if (
ST.isAtLeastSPIRVVer(VersionTuple(1, 6)))
964 Capability::StorageImageReadWithoutFormat});
972static void addOpDecorateReqs(
const MachineInstr &
MI,
unsigned DecIndex,
975 int64_t DecOp =
MI.getOperand(DecIndex).getImm();
976 auto Dec =
static_cast<SPIRV::Decoration::Decoration
>(DecOp);
978 SPIRV::OperandCategory::DecorationOperand, Dec, ST, Reqs));
980 if (Dec == SPIRV::Decoration::BuiltIn) {
981 int64_t BuiltInOp =
MI.getOperand(DecIndex + 1).getImm();
982 auto BuiltIn =
static_cast<SPIRV::BuiltIn::BuiltIn
>(BuiltInOp);
984 SPIRV::OperandCategory::BuiltInOperand, BuiltIn, ST, Reqs));
985 }
else if (Dec == SPIRV::Decoration::LinkageAttributes) {
986 int64_t LinkageOp =
MI.getOperand(
MI.getNumOperands() - 1).getImm();
987 SPIRV::LinkageType::LinkageType LnkType =
988 static_cast<SPIRV::LinkageType::LinkageType
>(LinkageOp);
989 if (LnkType == SPIRV::LinkageType::LinkOnceODR)
990 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_linkonce_odr);
991 }
else if (Dec == SPIRV::Decoration::CacheControlLoadINTEL ||
992 Dec == SPIRV::Decoration::CacheControlStoreINTEL) {
993 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_cache_controls);
994 }
else if (Dec == SPIRV::Decoration::HostAccessINTEL) {
995 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_global_variable_host_access);
996 }
else if (Dec == SPIRV::Decoration::InitModeINTEL ||
997 Dec == SPIRV::Decoration::ImplementInRegisterMapINTEL) {
999 SPIRV::Extension::SPV_INTEL_global_variable_fpga_decorations);
1000 }
else if (Dec == SPIRV::Decoration::NonUniformEXT) {
1002 }
else if (Dec == SPIRV::Decoration::FPMaxErrorDecorationINTEL) {
1004 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_fp_max_error);
1005 }
else if (Dec == SPIRV::Decoration::FPFastMathMode) {
1006 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)) {
1008 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_float_controls2);
1017 assert(
MI.getNumOperands() >= 8 &&
"Insufficient operands for OpTypeImage");
1020 int64_t ImgFormatOp =
MI.getOperand(7).getImm();
1021 auto ImgFormat =
static_cast<SPIRV::ImageFormat::ImageFormat
>(ImgFormatOp);
1025 bool IsArrayed =
MI.getOperand(4).getImm() == 1;
1026 bool IsMultisampled =
MI.getOperand(5).getImm() == 1;
1027 bool NoSampler =
MI.getOperand(6).getImm() == 2;
1030 switch (
MI.getOperand(2).getImm()) {
1031 case SPIRV::Dim::DIM_1D:
1033 : SPIRV::Capability::Sampled1D);
1035 case SPIRV::Dim::DIM_2D:
1036 if (IsMultisampled && NoSampler)
1039 case SPIRV::Dim::DIM_Cube:
1043 : SPIRV::Capability::SampledCubeArray);
1045 case SPIRV::Dim::DIM_Rect:
1047 : SPIRV::Capability::SampledRect);
1049 case SPIRV::Dim::DIM_Buffer:
1051 : SPIRV::Capability::SampledBuffer);
1053 case SPIRV::Dim::DIM_SubpassData:
1059 if (!
ST.isShader()) {
1060 if (
MI.getNumOperands() > 8 &&
1061 MI.getOperand(8).getImm() == SPIRV::AccessQualifier::ReadWrite)
1070 TypeDef->
getOpcode() == SPIRV::OpTypeFloat &&
1076#define ATOM_FLT_REQ_EXT_MSG(ExtName) \
1077 "The atomic float instruction requires the following SPIR-V " \
1078 "extension: SPV_EXT_shader_atomic_float" ExtName
1079static void AddAtomicVectorFloatRequirements(
const MachineInstr &
MI,
1083 MI.getMF()->getRegInfo().getVRegDef(
MI.getOperand(1).getReg());
1086 if (Rank != 2 && Rank != 4)
1088 "must be a 2-component or 4 component vector");
1093 if (EltTypeDef->
getOpcode() != SPIRV::OpTypeFloat ||
1096 "The element type for the result type of an atomic vector float "
1097 "instruction must be a 16-bit floating-point scalar");
1099 if (isBFloat16Type(EltTypeDef))
1101 "The element type for the result type of an atomic vector float "
1102 "instruction cannot be a bfloat16 scalar");
1103 if (!
ST.canUseExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector))
1105 "The atomic float16 vector instruction requires the following SPIR-V "
1106 "extension: SPV_NV_shader_atomic_fp16_vector");
1108 Reqs.
addExtension(SPIRV::Extension::SPV_NV_shader_atomic_fp16_vector);
1109 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16VectorNV);
1116 "Expect register operand in atomic float instruction");
1117 Register TypeReg =
MI.getOperand(1).getReg();
1120 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
1121 return AddAtomicVectorFloatRequirements(
MI, Reqs, ST);
1123 if (TypeDef->
getOpcode() != SPIRV::OpTypeFloat)
1125 "floating-point type scalar");
1128 unsigned Op =
MI.getOpcode();
1129 if (
Op == SPIRV::OpAtomicFAddEXT) {
1130 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add))
1132 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_add);
1135 if (isBFloat16Type(TypeDef)) {
1136 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1138 "The atomic bfloat16 instruction requires the following SPIR-V "
1139 "extension: SPV_INTEL_16bit_atomics",
1141 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1142 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16AddINTEL);
1144 if (!
ST.canUseExtension(
1145 SPIRV::Extension::SPV_EXT_shader_atomic_float16_add))
1147 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float16_add);
1159 "Unexpected floating-point type width in atomic float instruction");
1162 if (!
ST.canUseExtension(
1163 SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max))
1165 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_shader_atomic_float_min_max);
1168 if (isBFloat16Type(TypeDef)) {
1169 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics))
1171 "The atomic bfloat16 instruction requires the following SPIR-V "
1172 "extension: SPV_INTEL_16bit_atomics",
1174 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_16bit_atomics);
1175 Reqs.
addCapability(SPIRV::Capability::AtomicBFloat16MinMaxINTEL);
1177 Reqs.
addCapability(SPIRV::Capability::AtomicFloat16MinMaxEXT);
1181 Reqs.
addCapability(SPIRV::Capability::AtomicFloat32MinMaxEXT);
1184 Reqs.
addCapability(SPIRV::Capability::AtomicFloat64MinMaxEXT);
1188 "Unexpected floating-point type width in atomic float instruction");
1194 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1198 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 1;
1202 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1206 return Dim == SPIRV::Dim::DIM_Buffer && Sampled == 2;
1210 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1214 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 1;
1218 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1222 return Dim == SPIRV::Dim::DIM_SubpassData && Sampled == 2;
1226 if (ImageInst->
getOpcode() != SPIRV::OpTypeImage)
1230 return Dim != SPIRV::Dim::DIM_Buffer && Sampled == 2;
1233bool isCombinedImageSampler(
MachineInstr *SampledImageInst) {
1234 if (SampledImageInst->
getOpcode() != SPIRV::OpTypeSampledImage)
1240 return isSampledImage(ImageInst);
1245 if (
MI.getOpcode() != SPIRV::OpDecorate)
1249 if (Dec == SPIRV::Decoration::NonUniformEXT)
1267 if (
StorageClass != SPIRV::StorageClass::StorageClass::UniformConstant &&
1268 StorageClass != SPIRV::StorageClass::StorageClass::Uniform &&
1269 StorageClass != SPIRV::StorageClass::StorageClass::StorageBuffer) {
1274 hasNonUniformDecoration(
Instr.getOperand(0).getReg(), MRI);
1276 auto FirstIndexReg =
Instr.getOperand(3).getReg();
1277 bool FirstIndexIsConstant =
1280 if (
StorageClass == SPIRV::StorageClass::StorageClass::StorageBuffer) {
1283 SPIRV::Capability::StorageBufferArrayNonUniformIndexingEXT);
1284 else if (!FirstIndexIsConstant)
1286 SPIRV::Capability::StorageBufferArrayDynamicIndexing);
1292 if (PointeeType->
getOpcode() != SPIRV::OpTypeImage &&
1293 PointeeType->
getOpcode() != SPIRV::OpTypeSampledImage &&
1294 PointeeType->
getOpcode() != SPIRV::OpTypeSampler) {
1298 if (isUniformTexelBuffer(PointeeType)) {
1301 SPIRV::Capability::UniformTexelBufferArrayNonUniformIndexingEXT);
1302 else if (!FirstIndexIsConstant)
1304 SPIRV::Capability::UniformTexelBufferArrayDynamicIndexingEXT);
1305 }
else if (isInputAttachment(PointeeType)) {
1308 SPIRV::Capability::InputAttachmentArrayNonUniformIndexingEXT);
1309 else if (!FirstIndexIsConstant)
1311 SPIRV::Capability::InputAttachmentArrayDynamicIndexingEXT);
1312 }
else if (isStorageTexelBuffer(PointeeType)) {
1315 SPIRV::Capability::StorageTexelBufferArrayNonUniformIndexingEXT);
1316 else if (!FirstIndexIsConstant)
1318 SPIRV::Capability::StorageTexelBufferArrayDynamicIndexingEXT);
1319 }
else if (isSampledImage(PointeeType) ||
1320 isCombinedImageSampler(PointeeType) ||
1321 PointeeType->
getOpcode() == SPIRV::OpTypeSampler) {
1324 SPIRV::Capability::SampledImageArrayNonUniformIndexingEXT);
1325 else if (!FirstIndexIsConstant)
1327 SPIRV::Capability::SampledImageArrayDynamicIndexing);
1328 }
else if (isStorageImage(PointeeType)) {
1331 SPIRV::Capability::StorageImageArrayNonUniformIndexingEXT);
1332 else if (!FirstIndexIsConstant)
1334 SPIRV::Capability::StorageImageArrayDynamicIndexing);
1338static bool isImageTypeWithUnknownFormat(
SPIRVTypeInst TypeInst) {
1339 if (TypeInst->
getOpcode() != SPIRV::OpTypeImage)
1348 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_integer_dot_product))
1349 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_integer_dot_product);
1353 assert(
MI.getOperand(2).isReg() &&
"Unexpected operand in dot");
1357 assert(
Input->getOperand(1).isReg() &&
"Unexpected operand in dot input");
1361 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1363 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8BitPacked);
1364 }
else if (TypeDef->
getOpcode() == SPIRV::OpTypeVector) {
1370 "Dot operand of 8-bit integer type requires 4 components");
1371 Reqs.
addCapability(SPIRV::Capability::DotProductInput4x8Bit);
1386 unsigned AddrSpace = ASOp.
getImm();
1387 if (AddrSpace != SPIRV::StorageClass::UniformConstant) {
1388 if (!
ST.canUseExtension(
1390 SPV_EXT_relaxed_printf_string_address_space)) {
1392 "required because printf uses a format string not "
1393 "in constant address space.",
1397 SPIRV::Extension::SPV_EXT_relaxed_printf_string_address_space);
1406 if (
MI.getNumOperands() <=
OpIdx)
1410 if (Mask & (1U <<
I))
1419 switch (
MI.getOpcode()) {
1420 case SPIRV::OpMemoryModel: {
1421 int64_t Addr =
MI.getOperand(0).getImm();
1424 int64_t Mem =
MI.getOperand(1).getImm();
1429 case SPIRV::OpEntryPoint: {
1430 int64_t
Exe =
MI.getOperand(0).getImm();
1435 case SPIRV::OpExecutionMode:
1436 case SPIRV::OpExecutionModeId: {
1437 int64_t
Exe =
MI.getOperand(1).getImm();
1442 case SPIRV::OpTypeMatrix:
1445 case SPIRV::OpTypeInt: {
1446 unsigned BitWidth =
MI.getOperand(1).getImm();
1454 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_int4)) {
1458 if (!
ST.canUseExtension(
1459 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers))
1461 "OpTypeInt type with a width other than 8, 16, 32 or 64 bits "
1462 "requires the following SPIR-V extension: "
1463 "SPV_ALTERA_arbitrary_precision_integers");
1465 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_integers);
1466 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionIntegersALTERA);
1470 case SPIRV::OpDot: {
1473 if (isBFloat16Type(TypeDef))
1474 Reqs.
addCapability(SPIRV::Capability::BFloat16DotProductKHR);
1477 case SPIRV::OpTypeFloat: {
1478 unsigned BitWidth =
MI.getOperand(1).getImm();
1482 if (isBFloat16Type(&
MI)) {
1483 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bfloat16))
1485 "following SPIR-V extension: SPV_KHR_bfloat16",
1495 case SPIRV::OpTypeVector: {
1496 unsigned NumComponents =
MI.getOperand(2).getImm();
1497 if (NumComponents == 8 || NumComponents == 16)
1503 if (ElemTypeDef->
getOpcode() == SPIRV::OpTypePointer &&
1504 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter)) {
1505 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_masked_gather_scatter);
1506 Reqs.
addCapability(SPIRV::Capability::MaskedGatherScatterINTEL);
1510 case SPIRV::OpTypePointer: {
1511 auto SC =
MI.getOperand(1).getImm();
1522 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1527 case SPIRV::OpExtInst: {
1528 if (
MI.getOperand(2).getImm() ==
1529 static_cast<int64_t
>(
1530 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1531 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1534 if (
MI.getOperand(3).getImm() ==
1535 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1536 addPrintfRequirements(
MI, Reqs, ST);
1543 case SPIRV::OpAliasDomainDeclINTEL:
1544 case SPIRV::OpAliasScopeDeclINTEL:
1545 case SPIRV::OpAliasScopeListDeclINTEL: {
1546 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1547 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1550 case SPIRV::OpBitReverse:
1551 case SPIRV::OpBitFieldInsert:
1552 case SPIRV::OpBitFieldSExtract:
1553 case SPIRV::OpBitFieldUExtract:
1554 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1558 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1561 case SPIRV::OpTypeRuntimeArray:
1564 case SPIRV::OpTypeOpaque:
1565 case SPIRV::OpTypeEvent:
1568 case SPIRV::OpTypePipe:
1569 case SPIRV::OpTypeReserveId:
1572 case SPIRV::OpTypeDeviceEvent:
1573 case SPIRV::OpTypeQueue:
1574 case SPIRV::OpBuildNDRange:
1577 case SPIRV::OpDecorate:
1578 case SPIRV::OpDecorateId:
1579 case SPIRV::OpDecorateString:
1580 addOpDecorateReqs(
MI, 1, Reqs, ST);
1582 case SPIRV::OpMemberDecorate:
1583 case SPIRV::OpMemberDecorateString:
1584 addOpDecorateReqs(
MI, 2, Reqs, ST);
1586 case SPIRV::OpInBoundsPtrAccessChain:
1589 case SPIRV::OpConstantSampler:
1592 case SPIRV::OpInBoundsAccessChain:
1593 case SPIRV::OpAccessChain:
1594 addOpAccessChainReqs(
MI, Reqs, ST);
1596 case SPIRV::OpTypeImage:
1597 addOpTypeImageReqs(
MI, Reqs, ST);
1599 case SPIRV::OpTypeSampler:
1600 if (!
ST.isShader()) {
1604 case SPIRV::OpTypeForwardPointer:
1608 case SPIRV::OpAtomicFlagTestAndSet:
1609 case SPIRV::OpAtomicLoad:
1610 case SPIRV::OpAtomicStore:
1611 case SPIRV::OpAtomicExchange:
1612 case SPIRV::OpAtomicCompareExchange:
1613 case SPIRV::OpAtomicIIncrement:
1614 case SPIRV::OpAtomicIDecrement:
1615 case SPIRV::OpAtomicIAdd:
1616 case SPIRV::OpAtomicISub:
1617 case SPIRV::OpAtomicUMin:
1618 case SPIRV::OpAtomicUMax:
1619 case SPIRV::OpAtomicSMin:
1620 case SPIRV::OpAtomicSMax:
1621 case SPIRV::OpAtomicAnd:
1622 case SPIRV::OpAtomicOr:
1623 case SPIRV::OpAtomicXor: {
1626 if (
MI.getOpcode() == SPIRV::OpAtomicStore) {
1629 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1634 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1641 case SPIRV::OpGroupNonUniformIAdd:
1642 case SPIRV::OpGroupNonUniformFAdd:
1643 case SPIRV::OpGroupNonUniformIMul:
1644 case SPIRV::OpGroupNonUniformFMul:
1645 case SPIRV::OpGroupNonUniformSMin:
1646 case SPIRV::OpGroupNonUniformUMin:
1647 case SPIRV::OpGroupNonUniformFMin:
1648 case SPIRV::OpGroupNonUniformSMax:
1649 case SPIRV::OpGroupNonUniformUMax:
1650 case SPIRV::OpGroupNonUniformFMax:
1651 case SPIRV::OpGroupNonUniformBitwiseAnd:
1652 case SPIRV::OpGroupNonUniformBitwiseOr:
1653 case SPIRV::OpGroupNonUniformBitwiseXor:
1654 case SPIRV::OpGroupNonUniformLogicalAnd:
1655 case SPIRV::OpGroupNonUniformLogicalOr:
1656 case SPIRV::OpGroupNonUniformLogicalXor: {
1658 int64_t GroupOp =
MI.getOperand(3).getImm();
1660 case SPIRV::GroupOperation::Reduce:
1661 case SPIRV::GroupOperation::InclusiveScan:
1662 case SPIRV::GroupOperation::ExclusiveScan:
1663 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1665 case SPIRV::GroupOperation::ClusteredReduce:
1666 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1668 case SPIRV::GroupOperation::PartitionedReduceNV:
1669 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1670 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1671 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1676 case SPIRV::OpImageQueryFormat: {
1677 Register ResultReg =
MI.getOperand(0).getReg();
1679 static const unsigned CompareOps[] = {
1680 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1681 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1682 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1683 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1684 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1686 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1687 if (ImmVal == 4323 || ImmVal == 4324) {
1688 if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1689 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1692 "SPV_EXT_image_raw10_raw12 extension");
1697 unsigned Opc = UseInst.getOpcode();
1699 if (
Opc == SPIRV::OpSwitch) {
1702 CheckAndAddExtension(
Op.getImm());
1704 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1707 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1710 CheckAndAddExtension(ImmVal);
1718 case SPIRV::OpGroupNonUniformShuffle:
1719 case SPIRV::OpGroupNonUniformShuffleXor:
1720 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1722 case SPIRV::OpGroupNonUniformShuffleUp:
1723 case SPIRV::OpGroupNonUniformShuffleDown:
1724 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1726 case SPIRV::OpGroupAll:
1727 case SPIRV::OpGroupAny:
1728 case SPIRV::OpGroupBroadcast:
1729 case SPIRV::OpGroupIAdd:
1730 case SPIRV::OpGroupFAdd:
1731 case SPIRV::OpGroupFMin:
1732 case SPIRV::OpGroupUMin:
1733 case SPIRV::OpGroupSMin:
1734 case SPIRV::OpGroupFMax:
1735 case SPIRV::OpGroupUMax:
1736 case SPIRV::OpGroupSMax:
1739 case SPIRV::OpGroupNonUniformElect:
1742 case SPIRV::OpGroupNonUniformAll:
1743 case SPIRV::OpGroupNonUniformAny:
1744 case SPIRV::OpGroupNonUniformAllEqual:
1747 case SPIRV::OpGroupNonUniformBroadcast:
1748 case SPIRV::OpGroupNonUniformBroadcastFirst:
1749 case SPIRV::OpGroupNonUniformBallot:
1750 case SPIRV::OpGroupNonUniformInverseBallot:
1751 case SPIRV::OpGroupNonUniformBallotBitExtract:
1752 case SPIRV::OpGroupNonUniformBallotBitCount:
1753 case SPIRV::OpGroupNonUniformBallotFindLSB:
1754 case SPIRV::OpGroupNonUniformBallotFindMSB:
1755 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1757 case SPIRV::OpSubgroupShuffleINTEL:
1758 case SPIRV::OpSubgroupShuffleDownINTEL:
1759 case SPIRV::OpSubgroupShuffleUpINTEL:
1760 case SPIRV::OpSubgroupShuffleXorINTEL:
1761 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1762 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1763 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1766 case SPIRV::OpSubgroupBlockReadINTEL:
1767 case SPIRV::OpSubgroupBlockWriteINTEL:
1768 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1769 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1770 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1773 case SPIRV::OpSubgroupImageBlockReadINTEL:
1774 case SPIRV::OpSubgroupImageBlockWriteINTEL:
1775 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1776 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1777 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
1780 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
1781 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
1782 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
1783 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
1784 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
1787 case SPIRV::OpAssumeTrueKHR:
1788 case SPIRV::OpExpectKHR:
1789 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
1790 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
1794 case SPIRV::OpFmaKHR:
1795 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
1800 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
1801 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
1802 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
1803 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
1804 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
1807 case SPIRV::OpConstantFunctionPointerINTEL:
1808 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1809 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1810 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1813 case SPIRV::OpGroupNonUniformRotateKHR:
1814 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
1816 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
1818 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
1819 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
1822 case SPIRV::OpFixedCosALTERA:
1823 case SPIRV::OpFixedSinALTERA:
1824 case SPIRV::OpFixedCosPiALTERA:
1825 case SPIRV::OpFixedSinPiALTERA:
1826 case SPIRV::OpFixedExpALTERA:
1827 case SPIRV::OpFixedLogALTERA:
1828 case SPIRV::OpFixedRecipALTERA:
1829 case SPIRV::OpFixedSqrtALTERA:
1830 case SPIRV::OpFixedSinCosALTERA:
1831 case SPIRV::OpFixedSinCosPiALTERA:
1832 case SPIRV::OpFixedRsqrtALTERA:
1833 if (!
ST.canUseExtension(
1834 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
1836 "following SPIR-V extension: "
1837 "SPV_ALTERA_arbitrary_precision_fixed_point",
1840 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
1841 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
1843 case SPIRV::OpGroupIMulKHR:
1844 case SPIRV::OpGroupFMulKHR:
1845 case SPIRV::OpGroupBitwiseAndKHR:
1846 case SPIRV::OpGroupBitwiseOrKHR:
1847 case SPIRV::OpGroupBitwiseXorKHR:
1848 case SPIRV::OpGroupLogicalAndKHR:
1849 case SPIRV::OpGroupLogicalOrKHR:
1850 case SPIRV::OpGroupLogicalXorKHR:
1851 if (
ST.canUseExtension(
1852 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
1853 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
1854 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
1857 case SPIRV::OpReadClockKHR:
1858 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
1860 "following SPIR-V extension: SPV_KHR_shader_clock",
1862 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
1865 case SPIRV::OpFunctionPointerCallINTEL:
1866 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1867 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1868 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1871 case SPIRV::OpAtomicFAddEXT:
1872 case SPIRV::OpAtomicFMinEXT:
1873 case SPIRV::OpAtomicFMaxEXT:
1874 AddAtomicFloatRequirements(
MI, Reqs, ST);
1876 case SPIRV::OpConvertBF16ToFINTEL:
1877 case SPIRV::OpConvertFToBF16INTEL:
1878 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
1879 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
1880 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
1883 case SPIRV::OpRoundFToTF32INTEL:
1884 if (
ST.canUseExtension(
1885 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
1886 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
1887 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
1890 case SPIRV::OpVariableLengthArrayINTEL:
1891 case SPIRV::OpSaveMemoryINTEL:
1892 case SPIRV::OpRestoreMemoryINTEL:
1893 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
1894 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
1895 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
1898 case SPIRV::OpAsmTargetINTEL:
1899 case SPIRV::OpAsmINTEL:
1900 case SPIRV::OpAsmCallINTEL:
1901 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
1902 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
1906 case SPIRV::OpTypeCooperativeMatrixKHR: {
1907 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1909 "OpTypeCooperativeMatrixKHR type requires the "
1910 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
1912 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1913 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1916 if (isBFloat16Type(TypeDef))
1917 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
1920 case SPIRV::OpArithmeticFenceEXT:
1921 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
1923 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
1925 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
1928 case SPIRV::OpControlBarrierArriveINTEL:
1929 case SPIRV::OpControlBarrierWaitINTEL:
1930 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
1931 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
1935 case SPIRV::OpCooperativeMatrixMulAddKHR: {
1936 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1938 "following SPIR-V extension: "
1939 "SPV_KHR_cooperative_matrix",
1941 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1942 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1943 constexpr unsigned MulAddMaxSize = 6;
1944 if (
MI.getNumOperands() != MulAddMaxSize)
1946 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
1948 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
1949 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
1951 "require the following SPIR-V extension: "
1952 "SPV_INTEL_joint_matrix",
1954 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
1956 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
1959 MatrixAAndBBFloat16ComponentsINTEL ||
1961 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
1963 MatrixResultBFloat16ComponentsINTEL) {
1964 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
1966 "require the following SPIR-V extension: "
1967 "SPV_INTEL_joint_matrix",
1969 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
1971 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
1975 case SPIRV::OpCooperativeMatrixLoadKHR:
1976 case SPIRV::OpCooperativeMatrixStoreKHR:
1977 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
1978 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
1979 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
1980 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1982 "following SPIR-V extension: "
1983 "SPV_KHR_cooperative_matrix",
1985 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1986 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1990 std::unordered_map<unsigned, unsigned> LayoutToInstMap = {
1991 {SPIRV::OpCooperativeMatrixLoadKHR, 3},
1992 {SPIRV::OpCooperativeMatrixStoreKHR, 2},
1993 {SPIRV::OpCooperativeMatrixLoadCheckedINTEL, 5},
1994 {SPIRV::OpCooperativeMatrixStoreCheckedINTEL, 4},
1995 {SPIRV::OpCooperativeMatrixPrefetchINTEL, 4}};
1997 const auto OpCode =
MI.getOpcode();
1998 const unsigned LayoutNum = LayoutToInstMap[OpCode];
1999 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
2002 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
2005 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
2006 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2008 "extension: SPV_INTEL_joint_matrix",
2010 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2011 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2016 if (OpCode == SPIRV::OpCooperativeMatrixLoadKHR ||
2017 OpCode == SPIRV::OpCooperativeMatrixStoreKHR)
2020 std::string InstName;
2022 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2023 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2025 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2026 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2028 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2029 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2033 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2034 const std::string ErrorMsg =
2035 InstName +
" instruction requires the "
2036 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2039 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2040 if (OpCode == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2041 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2045 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2048 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2049 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2051 "instructions require the following SPIR-V extension: "
2052 "SPV_INTEL_joint_matrix",
2054 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2056 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2058 case SPIRV::OpReadPipeBlockingALTERA:
2059 case SPIRV::OpWritePipeBlockingALTERA:
2060 if (
ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2061 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2065 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2066 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2068 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2070 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2072 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2074 case SPIRV::OpConvertHandleToImageINTEL:
2075 case SPIRV::OpConvertHandleToSamplerINTEL:
2076 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2077 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2079 "instructions require the following SPIR-V extension: "
2080 "SPV_INTEL_bindless_images",
2083 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2085 if (
MI.getOpcode() == SPIRV::OpConvertHandleToImageINTEL &&
2086 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2088 "OpConvertHandleToImageINTEL",
2090 }
else if (
MI.getOpcode() == SPIRV::OpConvertHandleToSamplerINTEL &&
2091 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2093 "OpConvertHandleToSamplerINTEL",
2095 }
else if (
MI.getOpcode() == SPIRV::OpConvertHandleToSampledImageINTEL &&
2096 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2098 "OpConvertHandleToSampledImageINTEL",
2103 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2104 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2106 "Parameter value must be a 32-bit scalar in case of "
2107 "Physical32 addressing model or a 64-bit scalar in case of "
2108 "Physical64 addressing model",
2111 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2115 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2116 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2117 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2118 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2119 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2120 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2122 "Prefetch/Store]INTEL instructions require the "
2123 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2125 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2126 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2128 const auto OpCode =
MI.getOpcode();
2129 if (OpCode == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2130 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2133 if (OpCode == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2134 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2139 case SPIRV::OpKill: {
2142 case SPIRV::OpDemoteToHelperInvocation:
2143 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2145 if (
ST.canUseExtension(
2146 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2149 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2154 case SPIRV::OpSUDot:
2155 case SPIRV::OpSDotAccSat:
2156 case SPIRV::OpUDotAccSat:
2157 case SPIRV::OpSUDotAccSat:
2158 AddDotProductRequirements(
MI, Reqs, ST);
2160 case SPIRV::OpImageSampleImplicitLod:
2162 addImageOperandReqs(
MI, Reqs, ST, 4);
2164 case SPIRV::OpImageSampleExplicitLod:
2165 addImageOperandReqs(
MI, Reqs, ST, 4);
2167 case SPIRV::OpImageSampleDrefImplicitLod:
2169 addImageOperandReqs(
MI, Reqs, ST, 5);
2171 case SPIRV::OpImageSampleDrefExplicitLod:
2173 addImageOperandReqs(
MI, Reqs, ST, 5);
2175 case SPIRV::OpImageFetch:
2177 addImageOperandReqs(
MI, Reqs, ST, 4);
2179 case SPIRV::OpImageDrefGather:
2180 case SPIRV::OpImageGather:
2182 addImageOperandReqs(
MI, Reqs, ST, 5);
2184 case SPIRV::OpImageRead: {
2185 Register ImageReg =
MI.getOperand(2).getReg();
2194 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2195 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2198 case SPIRV::OpImageWrite: {
2199 Register ImageReg =
MI.getOperand(0).getReg();
2208 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2209 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2212 case SPIRV::OpTypeStructContinuedINTEL:
2213 case SPIRV::OpConstantCompositeContinuedINTEL:
2214 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2215 case SPIRV::OpCompositeConstructContinuedINTEL: {
2216 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2218 "Continued instructions require the "
2219 "following SPIR-V extension: SPV_INTEL_long_composites",
2221 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2225 case SPIRV::OpArbitraryFloatEQALTERA:
2226 case SPIRV::OpArbitraryFloatGEALTERA:
2227 case SPIRV::OpArbitraryFloatGTALTERA:
2228 case SPIRV::OpArbitraryFloatLEALTERA:
2229 case SPIRV::OpArbitraryFloatLTALTERA:
2230 case SPIRV::OpArbitraryFloatCbrtALTERA:
2231 case SPIRV::OpArbitraryFloatCosALTERA:
2232 case SPIRV::OpArbitraryFloatCosPiALTERA:
2233 case SPIRV::OpArbitraryFloatExp10ALTERA:
2234 case SPIRV::OpArbitraryFloatExp2ALTERA:
2235 case SPIRV::OpArbitraryFloatExpALTERA:
2236 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2237 case SPIRV::OpArbitraryFloatHypotALTERA:
2238 case SPIRV::OpArbitraryFloatLog10ALTERA:
2239 case SPIRV::OpArbitraryFloatLog1pALTERA:
2240 case SPIRV::OpArbitraryFloatLog2ALTERA:
2241 case SPIRV::OpArbitraryFloatLogALTERA:
2242 case SPIRV::OpArbitraryFloatRecipALTERA:
2243 case SPIRV::OpArbitraryFloatSinCosALTERA:
2244 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2245 case SPIRV::OpArbitraryFloatSinALTERA:
2246 case SPIRV::OpArbitraryFloatSinPiALTERA:
2247 case SPIRV::OpArbitraryFloatSqrtALTERA:
2248 case SPIRV::OpArbitraryFloatACosALTERA:
2249 case SPIRV::OpArbitraryFloatACosPiALTERA:
2250 case SPIRV::OpArbitraryFloatAddALTERA:
2251 case SPIRV::OpArbitraryFloatASinALTERA:
2252 case SPIRV::OpArbitraryFloatASinPiALTERA:
2253 case SPIRV::OpArbitraryFloatATan2ALTERA:
2254 case SPIRV::OpArbitraryFloatATanALTERA:
2255 case SPIRV::OpArbitraryFloatATanPiALTERA:
2256 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2257 case SPIRV::OpArbitraryFloatCastALTERA:
2258 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2259 case SPIRV::OpArbitraryFloatDivALTERA:
2260 case SPIRV::OpArbitraryFloatMulALTERA:
2261 case SPIRV::OpArbitraryFloatPowALTERA:
2262 case SPIRV::OpArbitraryFloatPowNALTERA:
2263 case SPIRV::OpArbitraryFloatPowRALTERA:
2264 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2265 case SPIRV::OpArbitraryFloatSubALTERA: {
2266 if (!
ST.canUseExtension(
2267 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2269 "Floating point instructions can't be translated correctly without "
2270 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2273 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2275 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2278 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2279 if (!
ST.canUseExtension(
2280 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2282 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2284 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2287 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2289 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2292 case SPIRV::OpBitwiseFunctionINTEL: {
2293 if (!
ST.canUseExtension(
2294 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2296 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2297 "extension: SPV_INTEL_ternary_bitwise_function",
2299 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2300 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2303 case SPIRV::OpCopyMemorySized: {
2308 case SPIRV::OpPredicatedLoadINTEL:
2309 case SPIRV::OpPredicatedStoreINTEL: {
2310 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2312 "OpPredicated[Load/Store]INTEL instructions require "
2313 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2315 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2319 case SPIRV::OpFAddS:
2320 case SPIRV::OpFSubS:
2321 case SPIRV::OpFMulS:
2322 case SPIRV::OpFDivS:
2323 case SPIRV::OpFRemS:
2325 case SPIRV::OpFNegate:
2326 case SPIRV::OpFAddV:
2327 case SPIRV::OpFSubV:
2328 case SPIRV::OpFMulV:
2329 case SPIRV::OpFDivV:
2330 case SPIRV::OpFRemV:
2331 case SPIRV::OpFNegateV: {
2334 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2336 if (isBFloat16Type(TypeDef)) {
2337 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2339 "Arithmetic instructions with bfloat16 arguments require the "
2340 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2342 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2343 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2347 case SPIRV::OpOrdered:
2348 case SPIRV::OpUnordered:
2349 case SPIRV::OpFOrdEqual:
2350 case SPIRV::OpFOrdNotEqual:
2351 case SPIRV::OpFOrdLessThan:
2352 case SPIRV::OpFOrdLessThanEqual:
2353 case SPIRV::OpFOrdGreaterThan:
2354 case SPIRV::OpFOrdGreaterThanEqual:
2355 case SPIRV::OpFUnordEqual:
2356 case SPIRV::OpFUnordNotEqual:
2357 case SPIRV::OpFUnordLessThan:
2358 case SPIRV::OpFUnordLessThanEqual:
2359 case SPIRV::OpFUnordGreaterThan:
2360 case SPIRV::OpFUnordGreaterThanEqual: {
2364 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2366 if (isBFloat16Type(TypeDef)) {
2367 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2369 "Relational instructions with bfloat16 arguments require the "
2370 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2372 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2373 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2377 case SPIRV::OpDPdxCoarse:
2378 case SPIRV::OpDPdyCoarse:
2379 case SPIRV::OpDPdxFine:
2380 case SPIRV::OpDPdyFine: {
2384 case SPIRV::OpLoopControlINTEL: {
2385 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2386 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2398 SPIRV::Capability::Shader);
2410 addInstrRequirements(
MI, MAI, ST);
2413 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2415 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2416 RequireKHRFloatControls2 =
false,
2418 bool HasIntelFloatControls2 =
2419 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2420 bool HasKHRFloatControls2 =
2421 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2422 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2428 auto EM =
Const->getZExtValue();
2432 case SPIRV::ExecutionMode::DenormPreserve:
2433 case SPIRV::ExecutionMode::DenormFlushToZero:
2434 case SPIRV::ExecutionMode::RoundingModeRTE:
2435 case SPIRV::ExecutionMode::RoundingModeRTZ:
2436 RequireFloatControls = VerLower14;
2438 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2440 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2441 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2442 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2443 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2444 if (HasIntelFloatControls2) {
2445 RequireIntelFloatControls2 =
true;
2447 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2450 case SPIRV::ExecutionMode::FPFastMathDefault: {
2451 if (HasKHRFloatControls2) {
2452 RequireKHRFloatControls2 =
true;
2454 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2458 case SPIRV::ExecutionMode::ContractionOff:
2459 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2460 if (HasKHRFloatControls2) {
2461 RequireKHRFloatControls2 =
true;
2463 SPIRV::OperandCategory::ExecutionModeOperand,
2464 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2467 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2472 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2477 if (RequireFloatControls &&
2478 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2480 if (RequireIntelFloatControls2)
2482 if (RequireKHRFloatControls2)
2486 if (
F.isDeclaration())
2488 if (
F.getMetadata(
"reqd_work_group_size"))
2490 SPIRV::OperandCategory::ExecutionModeOperand,
2491 SPIRV::ExecutionMode::LocalSize, ST);
2492 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2494 SPIRV::OperandCategory::ExecutionModeOperand,
2495 SPIRV::ExecutionMode::LocalSize, ST);
2497 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2500 if (
F.getMetadata(
"work_group_size_hint"))
2502 SPIRV::OperandCategory::ExecutionModeOperand,
2503 SPIRV::ExecutionMode::LocalSizeHint, ST);
2504 if (
F.getMetadata(
"intel_reqd_sub_group_size"))
2506 SPIRV::OperandCategory::ExecutionModeOperand,
2507 SPIRV::ExecutionMode::SubgroupSize, ST);
2508 if (
F.getMetadata(
"max_work_group_size"))
2510 SPIRV::OperandCategory::ExecutionModeOperand,
2511 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2512 if (
F.getMetadata(
"vec_type_hint"))
2514 SPIRV::OperandCategory::ExecutionModeOperand,
2515 SPIRV::ExecutionMode::VecTypeHint, ST);
2517 if (
F.hasOptNone()) {
2518 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2521 }
else if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2531 unsigned Flags = SPIRV::FPFastMathMode::None;
2532 bool CanUseKHRFloatControls2 =
2533 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2535 Flags |= SPIRV::FPFastMathMode::NotNaN;
2537 Flags |= SPIRV::FPFastMathMode::NotInf;
2539 Flags |= SPIRV::FPFastMathMode::NSZ;
2541 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2543 Flags |= SPIRV::FPFastMathMode::AllowContract;
2545 if (CanUseKHRFloatControls2)
2553 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2554 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2555 SPIRV::FPFastMathMode::AllowTransform |
2556 SPIRV::FPFastMathMode::AllowReassoc |
2557 SPIRV::FPFastMathMode::AllowContract;
2559 Flags |= SPIRV::FPFastMathMode::Fast;
2562 if (CanUseKHRFloatControls2) {
2564 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2565 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2570 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2571 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2572 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2573 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2574 "AllowContract flags to be enabled as well.");
2585 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2588static void handleMIFlagDecoration(
2593 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2594 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2597 SPIRV::Decoration::NoSignedWrap, {});
2600 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2601 SPIRV::Decoration::NoUnsignedWrap, ST,
2605 SPIRV::Decoration::NoUnsignedWrap, {});
2607 if (!
TII.canUseFastMathFlags(
2608 I,
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)))
2611 unsigned FMFlags = getFastMathFlags(
I, ST);
2612 if (FMFlags == SPIRV::FPFastMathMode::None) {
2615 if (FPFastMathDefaultInfoVec.
empty())
2631 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2632 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2633 ?
I.getOperand(1).getReg()
2634 :
I.getOperand(2).getReg();
2642 if (Ty == Elem.Ty) {
2643 FMFlags = Elem.FastMathFlags;
2644 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2645 Elem.FPFastMathDefault;
2650 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2653 if (isFastMathModeAvailable(ST)) {
2654 Register DstReg =
I.getOperand(0).getReg();
2670 for (
auto &
MBB : *MF)
2671 for (
auto &
MI :
MBB)
2672 handleMIFlagDecoration(
MI, ST,
TII, MAI.
Reqs, GR,
2689 for (
auto &
MBB : *MF) {
2690 if (!
MBB.hasName() ||
MBB.empty())
2709 for (
auto &
MBB : *MF) {
2711 MI.setDesc(
TII.get(SPIRV::OpPhi));
2714 MI.insert(
MI.operands_begin() + 1,
2715 {MachineOperand::CreateReg(ResTypeReg, false)});
2734 SPIRV::FPFastMathMode::None);
2736 SPIRV::FPFastMathMode::None);
2738 SPIRV::FPFastMathMode::None);
2745 size_t BitWidth = Ty->getScalarSizeInBits();
2749 assert(Index >= 0 && Index < 3 &&
2750 "Expected FPFastMathDefaultInfo for half, float, or double");
2751 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2752 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2753 return FPFastMathDefaultInfoVec[Index];
2756static void collectFPFastMathDefaults(
const Module &M,
2759 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
2768 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2772 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2781 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
2783 "Expected 4 operands for FPFastMathDefault");
2794 Info.FastMathFlags = Flags;
2795 Info.FPFastMathDefault =
true;
2796 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
2798 "Expected no operands for ContractionOff");
2805 Info.ContractionOff =
true;
2807 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
2809 "Expected 1 operand for SignedZeroInfNanPreserve");
2810 unsigned TargetWidth =
2819 assert(Index >= 0 && Index < 3 &&
2820 "Expected FPFastMathDefaultInfo for half, float, or double");
2821 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2822 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2823 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
2834 SPIRVTargetMachine &TM =
2838 TII = ST->getInstrInfo();
2844 patchPhis(M, GR, *TII, MMI);
2846 addMBBNames(M, *TII, MMI, *ST,
MAI);
2847 collectFPFastMathDefaults(M,
MAI, *ST);
2848 addDecorations(M, *TII, MMI, *ST,
MAI, GR);
2850 collectReqs(M,
MAI, MMI, *ST);
2854 collectReqs(M,
MAI, MMI, *ST);
2855 collectDeclarations(M);
2858 numberRegistersGlobally(M);
2861 processOtherInstrs(M);
2865 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
2868 GR->setBound(
MAI.MaxID);
MachineInstrBuilder & UseMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet & ToRemove
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
Promote Memory to Register
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static SPIRV::FPFastMathDefaultInfoVector & getOrCreateFPFastMathDefaultInfoVec(const Module &M, DenseMap< Function *, SPIRV::FPFastMathDefaultInfoVector > &FPFastMathDefaultInfoMap, Function *F)
static SPIRV::FPFastMathDefaultInfo & getFPFastMathDefaultInfo(SPIRV::FPFastMathDefaultInfoVector &FPFastMathDefaultInfoVec, const Type *Ty)
#define ATOM_FLT_REQ_EXT_MSG(ExtName)
static cl::opt< bool > SPVDumpDeps("spv-dump-deps", cl::desc("Dump MIR with SPIR-V dependencies info"), cl::Optional, cl::init(false))
static cl::list< SPIRV::Capability::Capability > AvoidCapabilities("avoid-spirv-capabilities", cl::desc("SPIR-V capabilities to avoid if there are " "other options enabling a feature"), cl::Hidden, cl::values(clEnumValN(SPIRV::Capability::Shader, "Shader", "SPIR-V Shader capability")))
#define SPIRV_BACKEND_SERVICE_FUN_NAME
Target-Independent Code Generator Pass Configuration Options pass.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
bool isValid() const
Return true if the attribute is any kind of attribute.
This is the shared class of boolean and integer constants.
This is an important base class in LLVM.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
Tracking metadata reference owned by Metadata.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
Register getReg(unsigned Idx) const
Get the register for the operand index.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
This class contains meta information specific to a module.
LLVM_ABI MachineFunction * getMachineFunction(const Function &F) const
Returns the MachineFunction associated to IR function F if there is one, otherwise nullptr.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
LLVM_ABI void print(raw_ostream &os, const TargetRegisterInfo *TRI=nullptr) const
Print the MachineOperand to os.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
iterator_range< reg_instr_iterator > reg_instructions(Register Reg) const
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
A Module instance is used to store all the information related to an LLVM module.
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
unsigned getScalarOrVectorBitWidth(SPIRVTypeInst Type) const
const Type * getTypeForSPIRVType(SPIRVTypeInst Ty) const
Register getSPIRVTypeID(SPIRVTypeInst SpirvType) const
SPIRVTypeInst getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
bool isConstantInstr(const MachineInstr &MI) const
const SPIRVInstrInfo * getInstrInfo() const override
SPIRVGlobalRegistry * getSPIRVGlobalRegistry() const
const SPIRVSubtarget * getSubtargetImpl() const
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
Represents a version number in the form major[.minor[.subminor[.build]]].
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
SmallVector< const MachineInstr * > InstrList
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
FunctionAddr VTableAddr Value
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
hash_code hash_value(const FixedPointSemantics &Val)
ExtensionList getSymbolicOperandExtensions(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
CapabilityList getSymbolicOperandCapabilities(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
SmallVector< SPIRV::Extension::Extension, 8 > ExtensionList
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
SmallVector< size_t > InstrSignature
VersionTuple getSymbolicOperandMaxVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
CapabilityList getCapabilitiesEnabledByExtension(SPIRV::Extension::Extension Extension)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
std::string getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, int32_t Value)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
VersionTuple getSymbolicOperandMinVersion(SPIRV::OperandCategory::OperandCategory Category, uint32_t Value)
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
SmallVector< SPIRV::Capability::Capability, 8 > CapabilityList
std::set< InstrSignature > InstrTraces
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
std::map< SmallVector< size_t >, unsigned > InstrGRegsMap
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
SmallSet< SPIRV::Capability::Capability, 4 > S
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
SPIRV::ModuleAnalysisInfo MAI
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
static size_t computeFPFastMathDefaultInfoVecIndex(size_t BitWidth)
void setSkipEmission(const MachineInstr *MI)
MCRegister getRegisterAlias(const MachineFunction *MF, Register Reg)
MCRegister getOrCreateMBBRegister(const MachineBasicBlock &MBB)
InstrList MS[NUM_MODULE_SECTIONS]
AddressingModel::AddressingModel Addr
void setRegisterAlias(const MachineFunction *MF, Register Reg, MCRegister AliasReg)
DenseMap< const Function *, SPIRV::FPFastMathDefaultInfoVector > FPFastMathDefaultInfoMap
void addCapabilities(const CapabilityList &ToAdd)
bool isCapabilityAvailable(Capability::Capability Cap) const
void checkSatisfiable(const SPIRVSubtarget &ST) const
void getAndAddRequirements(SPIRV::OperandCategory::OperandCategory Category, uint32_t i, const SPIRVSubtarget &ST)
void addExtension(Extension::Extension ToAdd)
void initAvailableCapabilities(const SPIRVSubtarget &ST)
void removeCapabilityIf(const Capability::Capability ToRemove, const Capability::Capability IfPresent)
void addCapability(Capability::Capability ToAdd)
void addAvailableCaps(const CapabilityList &ToAdd)
void addRequirements(const Requirements &Req)
const std::optional< Capability::Capability > Cap
const VersionTuple MinVer
const VersionTuple MaxVer