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)
1501 case SPIRV::OpTypePointer: {
1502 auto SC =
MI.getOperand(1).getImm();
1513 (TypeDef->
getOpcode() == SPIRV::OpTypeFloat) &&
1518 case SPIRV::OpExtInst: {
1519 if (
MI.getOperand(2).getImm() ==
1520 static_cast<int64_t
>(
1521 SPIRV::InstructionSet::NonSemantic_Shader_DebugInfo_100)) {
1522 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_non_semantic_info);
1525 if (
MI.getOperand(3).getImm() ==
1526 static_cast<int64_t
>(SPIRV::OpenCLExtInst::printf)) {
1527 addPrintfRequirements(
MI, Reqs, ST);
1534 case SPIRV::OpAliasDomainDeclINTEL:
1535 case SPIRV::OpAliasScopeDeclINTEL:
1536 case SPIRV::OpAliasScopeListDeclINTEL: {
1537 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_memory_access_aliasing);
1538 Reqs.
addCapability(SPIRV::Capability::MemoryAccessAliasingINTEL);
1541 case SPIRV::OpBitReverse:
1542 case SPIRV::OpBitFieldInsert:
1543 case SPIRV::OpBitFieldSExtract:
1544 case SPIRV::OpBitFieldUExtract:
1545 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_bit_instructions)) {
1549 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_bit_instructions);
1552 case SPIRV::OpTypeRuntimeArray:
1555 case SPIRV::OpTypeOpaque:
1556 case SPIRV::OpTypeEvent:
1559 case SPIRV::OpTypePipe:
1560 case SPIRV::OpTypeReserveId:
1563 case SPIRV::OpTypeDeviceEvent:
1564 case SPIRV::OpTypeQueue:
1565 case SPIRV::OpBuildNDRange:
1568 case SPIRV::OpDecorate:
1569 case SPIRV::OpDecorateId:
1570 case SPIRV::OpDecorateString:
1571 addOpDecorateReqs(
MI, 1, Reqs, ST);
1573 case SPIRV::OpMemberDecorate:
1574 case SPIRV::OpMemberDecorateString:
1575 addOpDecorateReqs(
MI, 2, Reqs, ST);
1577 case SPIRV::OpInBoundsPtrAccessChain:
1580 case SPIRV::OpConstantSampler:
1583 case SPIRV::OpInBoundsAccessChain:
1584 case SPIRV::OpAccessChain:
1585 addOpAccessChainReqs(
MI, Reqs, ST);
1587 case SPIRV::OpTypeImage:
1588 addOpTypeImageReqs(
MI, Reqs, ST);
1590 case SPIRV::OpTypeSampler:
1591 if (!
ST.isShader()) {
1595 case SPIRV::OpTypeForwardPointer:
1599 case SPIRV::OpAtomicFlagTestAndSet:
1600 case SPIRV::OpAtomicLoad:
1601 case SPIRV::OpAtomicStore:
1602 case SPIRV::OpAtomicExchange:
1603 case SPIRV::OpAtomicCompareExchange:
1604 case SPIRV::OpAtomicIIncrement:
1605 case SPIRV::OpAtomicIDecrement:
1606 case SPIRV::OpAtomicIAdd:
1607 case SPIRV::OpAtomicISub:
1608 case SPIRV::OpAtomicUMin:
1609 case SPIRV::OpAtomicUMax:
1610 case SPIRV::OpAtomicSMin:
1611 case SPIRV::OpAtomicSMax:
1612 case SPIRV::OpAtomicAnd:
1613 case SPIRV::OpAtomicOr:
1614 case SPIRV::OpAtomicXor: {
1617 if (
MI.getOpcode() == SPIRV::OpAtomicStore) {
1620 assert(InstrPtr &&
"Unexpected type instruction for OpAtomicStore");
1625 if (TypeDef->
getOpcode() == SPIRV::OpTypeInt) {
1632 case SPIRV::OpGroupNonUniformIAdd:
1633 case SPIRV::OpGroupNonUniformFAdd:
1634 case SPIRV::OpGroupNonUniformIMul:
1635 case SPIRV::OpGroupNonUniformFMul:
1636 case SPIRV::OpGroupNonUniformSMin:
1637 case SPIRV::OpGroupNonUniformUMin:
1638 case SPIRV::OpGroupNonUniformFMin:
1639 case SPIRV::OpGroupNonUniformSMax:
1640 case SPIRV::OpGroupNonUniformUMax:
1641 case SPIRV::OpGroupNonUniformFMax:
1642 case SPIRV::OpGroupNonUniformBitwiseAnd:
1643 case SPIRV::OpGroupNonUniformBitwiseOr:
1644 case SPIRV::OpGroupNonUniformBitwiseXor:
1645 case SPIRV::OpGroupNonUniformLogicalAnd:
1646 case SPIRV::OpGroupNonUniformLogicalOr:
1647 case SPIRV::OpGroupNonUniformLogicalXor: {
1649 int64_t GroupOp =
MI.getOperand(3).getImm();
1651 case SPIRV::GroupOperation::Reduce:
1652 case SPIRV::GroupOperation::InclusiveScan:
1653 case SPIRV::GroupOperation::ExclusiveScan:
1654 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformArithmetic);
1656 case SPIRV::GroupOperation::ClusteredReduce:
1657 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformClustered);
1659 case SPIRV::GroupOperation::PartitionedReduceNV:
1660 case SPIRV::GroupOperation::PartitionedInclusiveScanNV:
1661 case SPIRV::GroupOperation::PartitionedExclusiveScanNV:
1662 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformPartitionedNV);
1667 case SPIRV::OpImageQueryFormat: {
1668 Register ResultReg =
MI.getOperand(0).getReg();
1670 static const unsigned CompareOps[] = {
1671 SPIRV::OpIEqual, SPIRV::OpINotEqual,
1672 SPIRV::OpUGreaterThan, SPIRV::OpUGreaterThanEqual,
1673 SPIRV::OpULessThan, SPIRV::OpULessThanEqual,
1674 SPIRV::OpSGreaterThan, SPIRV::OpSGreaterThanEqual,
1675 SPIRV::OpSLessThan, SPIRV::OpSLessThanEqual};
1677 auto CheckAndAddExtension = [&](int64_t ImmVal) {
1678 if (ImmVal == 4323 || ImmVal == 4324) {
1679 if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12))
1680 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_image_raw10_raw12);
1683 "SPV_EXT_image_raw10_raw12 extension");
1688 unsigned Opc = UseInst.getOpcode();
1690 if (
Opc == SPIRV::OpSwitch) {
1693 CheckAndAddExtension(
Op.getImm());
1695 for (
unsigned i = 1; i < UseInst.getNumOperands(); ++i) {
1698 if (ConstInst && ConstInst->
getOpcode() == SPIRV::OpConstantI) {
1701 CheckAndAddExtension(ImmVal);
1709 case SPIRV::OpGroupNonUniformShuffle:
1710 case SPIRV::OpGroupNonUniformShuffleXor:
1711 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffle);
1713 case SPIRV::OpGroupNonUniformShuffleUp:
1714 case SPIRV::OpGroupNonUniformShuffleDown:
1715 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformShuffleRelative);
1717 case SPIRV::OpGroupAll:
1718 case SPIRV::OpGroupAny:
1719 case SPIRV::OpGroupBroadcast:
1720 case SPIRV::OpGroupIAdd:
1721 case SPIRV::OpGroupFAdd:
1722 case SPIRV::OpGroupFMin:
1723 case SPIRV::OpGroupUMin:
1724 case SPIRV::OpGroupSMin:
1725 case SPIRV::OpGroupFMax:
1726 case SPIRV::OpGroupUMax:
1727 case SPIRV::OpGroupSMax:
1730 case SPIRV::OpGroupNonUniformElect:
1733 case SPIRV::OpGroupNonUniformAll:
1734 case SPIRV::OpGroupNonUniformAny:
1735 case SPIRV::OpGroupNonUniformAllEqual:
1738 case SPIRV::OpGroupNonUniformBroadcast:
1739 case SPIRV::OpGroupNonUniformBroadcastFirst:
1740 case SPIRV::OpGroupNonUniformBallot:
1741 case SPIRV::OpGroupNonUniformInverseBallot:
1742 case SPIRV::OpGroupNonUniformBallotBitExtract:
1743 case SPIRV::OpGroupNonUniformBallotBitCount:
1744 case SPIRV::OpGroupNonUniformBallotFindLSB:
1745 case SPIRV::OpGroupNonUniformBallotFindMSB:
1746 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformBallot);
1748 case SPIRV::OpSubgroupShuffleINTEL:
1749 case SPIRV::OpSubgroupShuffleDownINTEL:
1750 case SPIRV::OpSubgroupShuffleUpINTEL:
1751 case SPIRV::OpSubgroupShuffleXorINTEL:
1752 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1753 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1754 Reqs.
addCapability(SPIRV::Capability::SubgroupShuffleINTEL);
1757 case SPIRV::OpSubgroupBlockReadINTEL:
1758 case SPIRV::OpSubgroupBlockWriteINTEL:
1759 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1760 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1761 Reqs.
addCapability(SPIRV::Capability::SubgroupBufferBlockIOINTEL);
1764 case SPIRV::OpSubgroupImageBlockReadINTEL:
1765 case SPIRV::OpSubgroupImageBlockWriteINTEL:
1766 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_subgroups)) {
1767 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_subgroups);
1768 Reqs.
addCapability(SPIRV::Capability::SubgroupImageBlockIOINTEL);
1771 case SPIRV::OpSubgroupImageMediaBlockReadINTEL:
1772 case SPIRV::OpSubgroupImageMediaBlockWriteINTEL:
1773 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_media_block_io)) {
1774 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_media_block_io);
1775 Reqs.
addCapability(SPIRV::Capability::SubgroupImageMediaBlockIOINTEL);
1778 case SPIRV::OpAssumeTrueKHR:
1779 case SPIRV::OpExpectKHR:
1780 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume)) {
1781 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_expect_assume);
1785 case SPIRV::OpFmaKHR:
1786 if (
ST.canUseExtension(SPIRV::Extension::SPV_KHR_fma)) {
1791 case SPIRV::OpPtrCastToCrossWorkgroupINTEL:
1792 case SPIRV::OpCrossWorkgroupCastToPtrINTEL:
1793 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)) {
1794 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes);
1795 Reqs.
addCapability(SPIRV::Capability::USMStorageClassesINTEL);
1798 case SPIRV::OpConstantFunctionPointerINTEL:
1799 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1800 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1801 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1804 case SPIRV::OpGroupNonUniformRotateKHR:
1805 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate))
1807 "following SPIR-V extension: SPV_KHR_subgroup_rotate",
1809 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_subgroup_rotate);
1810 Reqs.
addCapability(SPIRV::Capability::GroupNonUniformRotateKHR);
1813 case SPIRV::OpFixedCosALTERA:
1814 case SPIRV::OpFixedSinALTERA:
1815 case SPIRV::OpFixedCosPiALTERA:
1816 case SPIRV::OpFixedSinPiALTERA:
1817 case SPIRV::OpFixedExpALTERA:
1818 case SPIRV::OpFixedLogALTERA:
1819 case SPIRV::OpFixedRecipALTERA:
1820 case SPIRV::OpFixedSqrtALTERA:
1821 case SPIRV::OpFixedSinCosALTERA:
1822 case SPIRV::OpFixedSinCosPiALTERA:
1823 case SPIRV::OpFixedRsqrtALTERA:
1824 if (!
ST.canUseExtension(
1825 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point))
1827 "following SPIR-V extension: "
1828 "SPV_ALTERA_arbitrary_precision_fixed_point",
1831 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_fixed_point);
1832 Reqs.
addCapability(SPIRV::Capability::ArbitraryPrecisionFixedPointALTERA);
1834 case SPIRV::OpGroupIMulKHR:
1835 case SPIRV::OpGroupFMulKHR:
1836 case SPIRV::OpGroupBitwiseAndKHR:
1837 case SPIRV::OpGroupBitwiseOrKHR:
1838 case SPIRV::OpGroupBitwiseXorKHR:
1839 case SPIRV::OpGroupLogicalAndKHR:
1840 case SPIRV::OpGroupLogicalOrKHR:
1841 case SPIRV::OpGroupLogicalXorKHR:
1842 if (
ST.canUseExtension(
1843 SPIRV::Extension::SPV_KHR_uniform_group_instructions)) {
1844 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_uniform_group_instructions);
1845 Reqs.
addCapability(SPIRV::Capability::GroupUniformArithmeticKHR);
1848 case SPIRV::OpReadClockKHR:
1849 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_shader_clock))
1851 "following SPIR-V extension: SPV_KHR_shader_clock",
1853 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_shader_clock);
1856 case SPIRV::OpFunctionPointerCallINTEL:
1857 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)) {
1858 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_function_pointers);
1859 Reqs.
addCapability(SPIRV::Capability::FunctionPointersINTEL);
1862 case SPIRV::OpAtomicFAddEXT:
1863 case SPIRV::OpAtomicFMinEXT:
1864 case SPIRV::OpAtomicFMaxEXT:
1865 AddAtomicFloatRequirements(
MI, Reqs, ST);
1867 case SPIRV::OpConvertBF16ToFINTEL:
1868 case SPIRV::OpConvertFToBF16INTEL:
1869 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion)) {
1870 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_conversion);
1871 Reqs.
addCapability(SPIRV::Capability::BFloat16ConversionINTEL);
1874 case SPIRV::OpRoundFToTF32INTEL:
1875 if (
ST.canUseExtension(
1876 SPIRV::Extension::SPV_INTEL_tensor_float32_conversion)) {
1877 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_tensor_float32_conversion);
1878 Reqs.
addCapability(SPIRV::Capability::TensorFloat32RoundingINTEL);
1881 case SPIRV::OpVariableLengthArrayINTEL:
1882 case SPIRV::OpSaveMemoryINTEL:
1883 case SPIRV::OpRestoreMemoryINTEL:
1884 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_variable_length_array)) {
1885 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_variable_length_array);
1886 Reqs.
addCapability(SPIRV::Capability::VariableLengthArrayINTEL);
1889 case SPIRV::OpAsmTargetINTEL:
1890 case SPIRV::OpAsmINTEL:
1891 case SPIRV::OpAsmCallINTEL:
1892 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_inline_assembly)) {
1893 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_inline_assembly);
1897 case SPIRV::OpTypeCooperativeMatrixKHR: {
1898 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1900 "OpTypeCooperativeMatrixKHR type requires the "
1901 "following SPIR-V extension: SPV_KHR_cooperative_matrix",
1903 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1904 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1907 if (isBFloat16Type(TypeDef))
1908 Reqs.
addCapability(SPIRV::Capability::BFloat16CooperativeMatrixKHR);
1911 case SPIRV::OpArithmeticFenceEXT:
1912 if (!
ST.canUseExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence))
1914 "following SPIR-V extension: SPV_EXT_arithmetic_fence",
1916 Reqs.
addExtension(SPIRV::Extension::SPV_EXT_arithmetic_fence);
1919 case SPIRV::OpControlBarrierArriveINTEL:
1920 case SPIRV::OpControlBarrierWaitINTEL:
1921 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_split_barrier)) {
1922 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_split_barrier);
1926 case SPIRV::OpCooperativeMatrixMulAddKHR: {
1927 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1929 "following SPIR-V extension: "
1930 "SPV_KHR_cooperative_matrix",
1932 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1933 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1934 constexpr unsigned MulAddMaxSize = 6;
1935 if (
MI.getNumOperands() != MulAddMaxSize)
1937 const int64_t CoopOperands =
MI.getOperand(MulAddMaxSize - 1).getImm();
1939 SPIRV::CooperativeMatrixOperands::MatrixAAndBTF32ComponentsINTEL) {
1940 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
1942 "require the following SPIR-V extension: "
1943 "SPV_INTEL_joint_matrix",
1945 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
1947 SPIRV::Capability::CooperativeMatrixTF32ComponentTypeINTEL);
1950 MatrixAAndBBFloat16ComponentsINTEL ||
1952 SPIRV::CooperativeMatrixOperands::MatrixCBFloat16ComponentsINTEL ||
1954 MatrixResultBFloat16ComponentsINTEL) {
1955 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
1957 "require the following SPIR-V extension: "
1958 "SPV_INTEL_joint_matrix",
1960 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
1962 SPIRV::Capability::CooperativeMatrixBFloat16ComponentTypeINTEL);
1966 case SPIRV::OpCooperativeMatrixLoadKHR:
1967 case SPIRV::OpCooperativeMatrixStoreKHR:
1968 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
1969 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
1970 case SPIRV::OpCooperativeMatrixPrefetchINTEL: {
1971 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix))
1973 "following SPIR-V extension: "
1974 "SPV_KHR_cooperative_matrix",
1976 Reqs.
addExtension(SPIRV::Extension::SPV_KHR_cooperative_matrix);
1977 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixKHR);
1981 std::unordered_map<unsigned, unsigned> LayoutToInstMap = {
1982 {SPIRV::OpCooperativeMatrixLoadKHR, 3},
1983 {SPIRV::OpCooperativeMatrixStoreKHR, 2},
1984 {SPIRV::OpCooperativeMatrixLoadCheckedINTEL, 5},
1985 {SPIRV::OpCooperativeMatrixStoreCheckedINTEL, 4},
1986 {SPIRV::OpCooperativeMatrixPrefetchINTEL, 4}};
1988 const auto OpCode =
MI.getOpcode();
1989 const unsigned LayoutNum = LayoutToInstMap[OpCode];
1990 Register RegLayout =
MI.getOperand(LayoutNum).getReg();
1993 if (MILayout->
getOpcode() == SPIRV::OpConstantI) {
1996 static_cast<unsigned>(SPIRV::CooperativeMatrixLayout::PackedINTEL)) {
1997 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
1999 "extension: SPV_INTEL_joint_matrix",
2001 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2002 Reqs.
addCapability(SPIRV::Capability::PackedCooperativeMatrixINTEL);
2007 if (OpCode == SPIRV::OpCooperativeMatrixLoadKHR ||
2008 OpCode == SPIRV::OpCooperativeMatrixStoreKHR)
2011 std::string InstName;
2013 case SPIRV::OpCooperativeMatrixPrefetchINTEL:
2014 InstName =
"OpCooperativeMatrixPrefetchINTEL";
2016 case SPIRV::OpCooperativeMatrixLoadCheckedINTEL:
2017 InstName =
"OpCooperativeMatrixLoadCheckedINTEL";
2019 case SPIRV::OpCooperativeMatrixStoreCheckedINTEL:
2020 InstName =
"OpCooperativeMatrixStoreCheckedINTEL";
2024 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix)) {
2025 const std::string ErrorMsg =
2026 InstName +
" instruction requires the "
2027 "following SPIR-V extension: SPV_INTEL_joint_matrix";
2030 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2031 if (OpCode == SPIRV::OpCooperativeMatrixPrefetchINTEL) {
2032 Reqs.
addCapability(SPIRV::Capability::CooperativeMatrixPrefetchINTEL);
2036 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2039 case SPIRV::OpCooperativeMatrixConstructCheckedINTEL:
2040 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2042 "instructions require the following SPIR-V extension: "
2043 "SPV_INTEL_joint_matrix",
2045 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2047 SPIRV::Capability::CooperativeMatrixCheckedInstructionsINTEL);
2049 case SPIRV::OpReadPipeBlockingALTERA:
2050 case SPIRV::OpWritePipeBlockingALTERA:
2051 if (
ST.canUseExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes)) {
2052 Reqs.
addExtension(SPIRV::Extension::SPV_ALTERA_blocking_pipes);
2056 case SPIRV::OpCooperativeMatrixGetElementCoordINTEL:
2057 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_joint_matrix))
2059 "following SPIR-V extension: SPV_INTEL_joint_matrix",
2061 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_joint_matrix);
2063 SPIRV::Capability::CooperativeMatrixInvocationInstructionsINTEL);
2065 case SPIRV::OpConvertHandleToImageINTEL:
2066 case SPIRV::OpConvertHandleToSamplerINTEL:
2067 case SPIRV::OpConvertHandleToSampledImageINTEL: {
2068 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bindless_images))
2070 "instructions require the following SPIR-V extension: "
2071 "SPV_INTEL_bindless_images",
2074 SPIRV::AddressingModel::AddressingModel AddrModel = MAI.
Addr;
2076 if (
MI.getOpcode() == SPIRV::OpConvertHandleToImageINTEL &&
2077 TyDef->
getOpcode() != SPIRV::OpTypeImage) {
2079 "OpConvertHandleToImageINTEL",
2081 }
else if (
MI.getOpcode() == SPIRV::OpConvertHandleToSamplerINTEL &&
2082 TyDef->
getOpcode() != SPIRV::OpTypeSampler) {
2084 "OpConvertHandleToSamplerINTEL",
2086 }
else if (
MI.getOpcode() == SPIRV::OpConvertHandleToSampledImageINTEL &&
2087 TyDef->
getOpcode() != SPIRV::OpTypeSampledImage) {
2089 "OpConvertHandleToSampledImageINTEL",
2094 if (!(Bitwidth == 32 && AddrModel == SPIRV::AddressingModel::Physical32) &&
2095 !(Bitwidth == 64 && AddrModel == SPIRV::AddressingModel::Physical64)) {
2097 "Parameter value must be a 32-bit scalar in case of "
2098 "Physical32 addressing model or a 64-bit scalar in case of "
2099 "Physical64 addressing model",
2102 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bindless_images);
2106 case SPIRV::OpSubgroup2DBlockLoadINTEL:
2107 case SPIRV::OpSubgroup2DBlockLoadTransposeINTEL:
2108 case SPIRV::OpSubgroup2DBlockLoadTransformINTEL:
2109 case SPIRV::OpSubgroup2DBlockPrefetchINTEL:
2110 case SPIRV::OpSubgroup2DBlockStoreINTEL: {
2111 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_2d_block_io))
2113 "Prefetch/Store]INTEL instructions require the "
2114 "following SPIR-V extension: SPV_INTEL_2d_block_io",
2116 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_2d_block_io);
2117 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockIOINTEL);
2119 const auto OpCode =
MI.getOpcode();
2120 if (OpCode == SPIRV::OpSubgroup2DBlockLoadTransposeINTEL) {
2121 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransposeINTEL);
2124 if (OpCode == SPIRV::OpSubgroup2DBlockLoadTransformINTEL) {
2125 Reqs.
addCapability(SPIRV::Capability::Subgroup2DBlockTransformINTEL);
2130 case SPIRV::OpKill: {
2133 case SPIRV::OpDemoteToHelperInvocation:
2134 Reqs.
addCapability(SPIRV::Capability::DemoteToHelperInvocation);
2136 if (
ST.canUseExtension(
2137 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation)) {
2140 SPIRV::Extension::SPV_EXT_demote_to_helper_invocation);
2145 case SPIRV::OpSUDot:
2146 case SPIRV::OpSDotAccSat:
2147 case SPIRV::OpUDotAccSat:
2148 case SPIRV::OpSUDotAccSat:
2149 AddDotProductRequirements(
MI, Reqs, ST);
2151 case SPIRV::OpImageSampleImplicitLod:
2153 addImageOperandReqs(
MI, Reqs, ST, 4);
2155 case SPIRV::OpImageSampleExplicitLod:
2156 addImageOperandReqs(
MI, Reqs, ST, 4);
2158 case SPIRV::OpImageSampleDrefImplicitLod:
2160 addImageOperandReqs(
MI, Reqs, ST, 5);
2162 case SPIRV::OpImageSampleDrefExplicitLod:
2164 addImageOperandReqs(
MI, Reqs, ST, 5);
2166 case SPIRV::OpImageDrefGather:
2167 case SPIRV::OpImageGather:
2169 addImageOperandReqs(
MI, Reqs, ST, 5);
2171 case SPIRV::OpImageRead: {
2172 Register ImageReg =
MI.getOperand(2).getReg();
2181 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2182 Reqs.
addCapability(SPIRV::Capability::StorageImageReadWithoutFormat);
2185 case SPIRV::OpImageWrite: {
2186 Register ImageReg =
MI.getOperand(0).getReg();
2195 if (isImageTypeWithUnknownFormat(TypeDef) &&
ST.isShader())
2196 Reqs.
addCapability(SPIRV::Capability::StorageImageWriteWithoutFormat);
2199 case SPIRV::OpTypeStructContinuedINTEL:
2200 case SPIRV::OpConstantCompositeContinuedINTEL:
2201 case SPIRV::OpSpecConstantCompositeContinuedINTEL:
2202 case SPIRV::OpCompositeConstructContinuedINTEL: {
2203 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_long_composites))
2205 "Continued instructions require the "
2206 "following SPIR-V extension: SPV_INTEL_long_composites",
2208 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_long_composites);
2212 case SPIRV::OpArbitraryFloatEQALTERA:
2213 case SPIRV::OpArbitraryFloatGEALTERA:
2214 case SPIRV::OpArbitraryFloatGTALTERA:
2215 case SPIRV::OpArbitraryFloatLEALTERA:
2216 case SPIRV::OpArbitraryFloatLTALTERA:
2217 case SPIRV::OpArbitraryFloatCbrtALTERA:
2218 case SPIRV::OpArbitraryFloatCosALTERA:
2219 case SPIRV::OpArbitraryFloatCosPiALTERA:
2220 case SPIRV::OpArbitraryFloatExp10ALTERA:
2221 case SPIRV::OpArbitraryFloatExp2ALTERA:
2222 case SPIRV::OpArbitraryFloatExpALTERA:
2223 case SPIRV::OpArbitraryFloatExpm1ALTERA:
2224 case SPIRV::OpArbitraryFloatHypotALTERA:
2225 case SPIRV::OpArbitraryFloatLog10ALTERA:
2226 case SPIRV::OpArbitraryFloatLog1pALTERA:
2227 case SPIRV::OpArbitraryFloatLog2ALTERA:
2228 case SPIRV::OpArbitraryFloatLogALTERA:
2229 case SPIRV::OpArbitraryFloatRecipALTERA:
2230 case SPIRV::OpArbitraryFloatSinCosALTERA:
2231 case SPIRV::OpArbitraryFloatSinCosPiALTERA:
2232 case SPIRV::OpArbitraryFloatSinALTERA:
2233 case SPIRV::OpArbitraryFloatSinPiALTERA:
2234 case SPIRV::OpArbitraryFloatSqrtALTERA:
2235 case SPIRV::OpArbitraryFloatACosALTERA:
2236 case SPIRV::OpArbitraryFloatACosPiALTERA:
2237 case SPIRV::OpArbitraryFloatAddALTERA:
2238 case SPIRV::OpArbitraryFloatASinALTERA:
2239 case SPIRV::OpArbitraryFloatASinPiALTERA:
2240 case SPIRV::OpArbitraryFloatATan2ALTERA:
2241 case SPIRV::OpArbitraryFloatATanALTERA:
2242 case SPIRV::OpArbitraryFloatATanPiALTERA:
2243 case SPIRV::OpArbitraryFloatCastFromIntALTERA:
2244 case SPIRV::OpArbitraryFloatCastALTERA:
2245 case SPIRV::OpArbitraryFloatCastToIntALTERA:
2246 case SPIRV::OpArbitraryFloatDivALTERA:
2247 case SPIRV::OpArbitraryFloatMulALTERA:
2248 case SPIRV::OpArbitraryFloatPowALTERA:
2249 case SPIRV::OpArbitraryFloatPowNALTERA:
2250 case SPIRV::OpArbitraryFloatPowRALTERA:
2251 case SPIRV::OpArbitraryFloatRSqrtALTERA:
2252 case SPIRV::OpArbitraryFloatSubALTERA: {
2253 if (!
ST.canUseExtension(
2254 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point))
2256 "Floating point instructions can't be translated correctly without "
2257 "enabled SPV_ALTERA_arbitrary_precision_floating_point extension!",
2260 SPIRV::Extension::SPV_ALTERA_arbitrary_precision_floating_point);
2262 SPIRV::Capability::ArbitraryPrecisionFloatingPointALTERA);
2265 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
2266 if (!
ST.canUseExtension(
2267 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate))
2269 "OpSubgroupMatrixMultiplyAccumulateINTEL instruction requires the "
2271 "extension: SPV_INTEL_subgroup_matrix_multiply_accumulate",
2274 SPIRV::Extension::SPV_INTEL_subgroup_matrix_multiply_accumulate);
2276 SPIRV::Capability::SubgroupMatrixMultiplyAccumulateINTEL);
2279 case SPIRV::OpBitwiseFunctionINTEL: {
2280 if (!
ST.canUseExtension(
2281 SPIRV::Extension::SPV_INTEL_ternary_bitwise_function))
2283 "OpBitwiseFunctionINTEL instruction requires the following SPIR-V "
2284 "extension: SPV_INTEL_ternary_bitwise_function",
2286 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_ternary_bitwise_function);
2287 Reqs.
addCapability(SPIRV::Capability::TernaryBitwiseFunctionINTEL);
2290 case SPIRV::OpCopyMemorySized: {
2295 case SPIRV::OpPredicatedLoadINTEL:
2296 case SPIRV::OpPredicatedStoreINTEL: {
2297 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_predicated_io))
2299 "OpPredicated[Load/Store]INTEL instructions require "
2300 "the following SPIR-V extension: SPV_INTEL_predicated_io",
2302 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_predicated_io);
2306 case SPIRV::OpFAddS:
2307 case SPIRV::OpFSubS:
2308 case SPIRV::OpFMulS:
2309 case SPIRV::OpFDivS:
2310 case SPIRV::OpFRemS:
2312 case SPIRV::OpFNegate:
2313 case SPIRV::OpFAddV:
2314 case SPIRV::OpFSubV:
2315 case SPIRV::OpFMulV:
2316 case SPIRV::OpFDivV:
2317 case SPIRV::OpFRemV:
2318 case SPIRV::OpFNegateV: {
2321 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2323 if (isBFloat16Type(TypeDef)) {
2324 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2326 "Arithmetic instructions with bfloat16 arguments require the "
2327 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2329 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2330 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2334 case SPIRV::OpOrdered:
2335 case SPIRV::OpUnordered:
2336 case SPIRV::OpFOrdEqual:
2337 case SPIRV::OpFOrdNotEqual:
2338 case SPIRV::OpFOrdLessThan:
2339 case SPIRV::OpFOrdLessThanEqual:
2340 case SPIRV::OpFOrdGreaterThan:
2341 case SPIRV::OpFOrdGreaterThanEqual:
2342 case SPIRV::OpFUnordEqual:
2343 case SPIRV::OpFUnordNotEqual:
2344 case SPIRV::OpFUnordLessThan:
2345 case SPIRV::OpFUnordLessThanEqual:
2346 case SPIRV::OpFUnordGreaterThan:
2347 case SPIRV::OpFUnordGreaterThanEqual: {
2351 if (TypeDef->
getOpcode() == SPIRV::OpTypeVector)
2353 if (isBFloat16Type(TypeDef)) {
2354 if (!
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic))
2356 "Relational instructions with bfloat16 arguments require the "
2357 "following SPIR-V extension: SPV_INTEL_bfloat16_arithmetic",
2359 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_bfloat16_arithmetic);
2360 Reqs.
addCapability(SPIRV::Capability::BFloat16ArithmeticINTEL);
2364 case SPIRV::OpDPdxCoarse:
2365 case SPIRV::OpDPdyCoarse:
2366 case SPIRV::OpDPdxFine:
2367 case SPIRV::OpDPdyFine: {
2371 case SPIRV::OpLoopControlINTEL: {
2372 Reqs.
addExtension(SPIRV::Extension::SPV_INTEL_unstructured_loop_controls);
2373 Reqs.
addCapability(SPIRV::Capability::UnstructuredLoopControlsINTEL);
2385 SPIRV::Capability::Shader);
2397 addInstrRequirements(
MI, MAI, ST);
2400 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2402 bool RequireFloatControls =
false, RequireIntelFloatControls2 =
false,
2403 RequireKHRFloatControls2 =
false,
2405 bool HasIntelFloatControls2 =
2406 ST.canUseExtension(SPIRV::Extension::SPV_INTEL_float_controls2);
2407 bool HasKHRFloatControls2 =
2408 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2409 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2415 auto EM =
Const->getZExtValue();
2419 case SPIRV::ExecutionMode::DenormPreserve:
2420 case SPIRV::ExecutionMode::DenormFlushToZero:
2421 case SPIRV::ExecutionMode::RoundingModeRTE:
2422 case SPIRV::ExecutionMode::RoundingModeRTZ:
2423 RequireFloatControls = VerLower14;
2425 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2427 case SPIRV::ExecutionMode::RoundingModeRTPINTEL:
2428 case SPIRV::ExecutionMode::RoundingModeRTNINTEL:
2429 case SPIRV::ExecutionMode::FloatingPointModeALTINTEL:
2430 case SPIRV::ExecutionMode::FloatingPointModeIEEEINTEL:
2431 if (HasIntelFloatControls2) {
2432 RequireIntelFloatControls2 =
true;
2434 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2437 case SPIRV::ExecutionMode::FPFastMathDefault: {
2438 if (HasKHRFloatControls2) {
2439 RequireKHRFloatControls2 =
true;
2441 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2445 case SPIRV::ExecutionMode::ContractionOff:
2446 case SPIRV::ExecutionMode::SignedZeroInfNanPreserve:
2447 if (HasKHRFloatControls2) {
2448 RequireKHRFloatControls2 =
true;
2450 SPIRV::OperandCategory::ExecutionModeOperand,
2451 SPIRV::ExecutionMode::FPFastMathDefault, ST);
2454 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2459 SPIRV::OperandCategory::ExecutionModeOperand, EM, ST);
2464 if (RequireFloatControls &&
2465 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls))
2467 if (RequireIntelFloatControls2)
2469 if (RequireKHRFloatControls2)
2473 if (
F.isDeclaration())
2475 if (
F.getMetadata(
"reqd_work_group_size"))
2477 SPIRV::OperandCategory::ExecutionModeOperand,
2478 SPIRV::ExecutionMode::LocalSize, ST);
2479 if (
F.getFnAttribute(
"hlsl.numthreads").isValid()) {
2481 SPIRV::OperandCategory::ExecutionModeOperand,
2482 SPIRV::ExecutionMode::LocalSize, ST);
2484 if (
F.getFnAttribute(
"enable-maximal-reconvergence").getValueAsBool()) {
2487 if (
F.getMetadata(
"work_group_size_hint"))
2489 SPIRV::OperandCategory::ExecutionModeOperand,
2490 SPIRV::ExecutionMode::LocalSizeHint, ST);
2491 if (
F.getMetadata(
"intel_reqd_sub_group_size"))
2493 SPIRV::OperandCategory::ExecutionModeOperand,
2494 SPIRV::ExecutionMode::SubgroupSize, ST);
2495 if (
F.getMetadata(
"max_work_group_size"))
2497 SPIRV::OperandCategory::ExecutionModeOperand,
2498 SPIRV::ExecutionMode::MaxWorkgroupSizeINTEL, ST);
2499 if (
F.getMetadata(
"vec_type_hint"))
2501 SPIRV::OperandCategory::ExecutionModeOperand,
2502 SPIRV::ExecutionMode::VecTypeHint, ST);
2504 if (
F.hasOptNone()) {
2505 if (
ST.canUseExtension(SPIRV::Extension::SPV_INTEL_optnone)) {
2508 }
else if (
ST.canUseExtension(SPIRV::Extension::SPV_EXT_optnone)) {
2518 unsigned Flags = SPIRV::FPFastMathMode::None;
2519 bool CanUseKHRFloatControls2 =
2520 ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2522 Flags |= SPIRV::FPFastMathMode::NotNaN;
2524 Flags |= SPIRV::FPFastMathMode::NotInf;
2526 Flags |= SPIRV::FPFastMathMode::NSZ;
2528 Flags |= SPIRV::FPFastMathMode::AllowRecip;
2530 Flags |= SPIRV::FPFastMathMode::AllowContract;
2532 if (CanUseKHRFloatControls2)
2540 Flags |= SPIRV::FPFastMathMode::NotNaN | SPIRV::FPFastMathMode::NotInf |
2541 SPIRV::FPFastMathMode::NSZ | SPIRV::FPFastMathMode::AllowRecip |
2542 SPIRV::FPFastMathMode::AllowTransform |
2543 SPIRV::FPFastMathMode::AllowReassoc |
2544 SPIRV::FPFastMathMode::AllowContract;
2546 Flags |= SPIRV::FPFastMathMode::Fast;
2549 if (CanUseKHRFloatControls2) {
2551 assert(!(Flags & SPIRV::FPFastMathMode::Fast) &&
2552 "SPIRV::FPFastMathMode::Fast is deprecated and should not be used "
2557 assert((!(Flags & SPIRV::FPFastMathMode::AllowTransform) ||
2558 ((Flags & SPIRV::FPFastMathMode::AllowReassoc &&
2559 Flags & SPIRV::FPFastMathMode::AllowContract))) &&
2560 "SPIRV::FPFastMathMode::AllowTransform requires AllowReassoc and "
2561 "AllowContract flags to be enabled as well.");
2572 return ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2);
2575static void handleMIFlagDecoration(
2580 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2581 SPIRV::Decoration::NoSignedWrap, ST, Reqs)
2584 SPIRV::Decoration::NoSignedWrap, {});
2587 getSymbolicOperandRequirements(SPIRV::OperandCategory::DecorationOperand,
2588 SPIRV::Decoration::NoUnsignedWrap, ST,
2592 SPIRV::Decoration::NoUnsignedWrap, {});
2594 if (!
TII.canUseFastMathFlags(
2595 I,
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2)))
2598 unsigned FMFlags = getFastMathFlags(
I, ST);
2599 if (FMFlags == SPIRV::FPFastMathMode::None) {
2602 if (FPFastMathDefaultInfoVec.
empty())
2618 assert(
I.getNumOperands() >= 3 &&
"Expected at least 3 operands");
2619 Register ResReg =
I.getOpcode() == SPIRV::OpExtInst
2620 ?
I.getOperand(1).getReg()
2621 :
I.getOperand(2).getReg();
2629 if (Ty == Elem.Ty) {
2630 FMFlags = Elem.FastMathFlags;
2631 Emit = Elem.ContractionOff || Elem.SignedZeroInfNanPreserve ||
2632 Elem.FPFastMathDefault;
2637 if (FMFlags == SPIRV::FPFastMathMode::None && !Emit)
2640 if (isFastMathModeAvailable(ST)) {
2641 Register DstReg =
I.getOperand(0).getReg();
2657 for (
auto &
MBB : *MF)
2658 for (
auto &
MI :
MBB)
2659 handleMIFlagDecoration(
MI, ST,
TII, MAI.
Reqs, GR,
2676 for (
auto &
MBB : *MF) {
2677 if (!
MBB.hasName() ||
MBB.empty())
2696 for (
auto &
MBB : *MF) {
2698 MI.setDesc(
TII.get(SPIRV::OpPhi));
2701 MI.insert(
MI.operands_begin() + 1,
2702 {MachineOperand::CreateReg(ResTypeReg, false)});
2721 SPIRV::FPFastMathMode::None);
2723 SPIRV::FPFastMathMode::None);
2725 SPIRV::FPFastMathMode::None);
2732 size_t BitWidth = Ty->getScalarSizeInBits();
2736 assert(Index >= 0 && Index < 3 &&
2737 "Expected FPFastMathDefaultInfo for half, float, or double");
2738 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2739 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2740 return FPFastMathDefaultInfoVec[Index];
2743static void collectFPFastMathDefaults(
const Module &M,
2746 if (!
ST.canUseExtension(SPIRV::Extension::SPV_KHR_float_controls2))
2755 auto Node = M.getNamedMetadata(
"spirv.ExecutionMode");
2759 for (
unsigned i = 0; i <
Node->getNumOperands(); i++) {
2768 if (EM == SPIRV::ExecutionMode::FPFastMathDefault) {
2770 "Expected 4 operands for FPFastMathDefault");
2781 Info.FastMathFlags = Flags;
2782 Info.FPFastMathDefault =
true;
2783 }
else if (EM == SPIRV::ExecutionMode::ContractionOff) {
2785 "Expected no operands for ContractionOff");
2792 Info.ContractionOff =
true;
2794 }
else if (EM == SPIRV::ExecutionMode::SignedZeroInfNanPreserve) {
2796 "Expected 1 operand for SignedZeroInfNanPreserve");
2797 unsigned TargetWidth =
2806 assert(Index >= 0 && Index < 3 &&
2807 "Expected FPFastMathDefaultInfo for half, float, or double");
2808 assert(FPFastMathDefaultInfoVec.
size() == 3 &&
2809 "Expected FPFastMathDefaultInfoVec to have exactly 3 elements");
2810 FPFastMathDefaultInfoVec[Index].SignedZeroInfNanPreserve =
true;
2821 SPIRVTargetMachine &TM =
2825 TII = ST->getInstrInfo();
2831 patchPhis(M, GR, *TII, MMI);
2833 addMBBNames(M, *TII, MMI, *ST,
MAI);
2834 collectFPFastMathDefaults(M,
MAI, *ST);
2835 addDecorations(M, *TII, MMI, *ST,
MAI, GR);
2837 collectReqs(M,
MAI, MMI, *ST);
2841 collectReqs(M,
MAI, MMI, *ST);
2842 collectDeclarations(M);
2845 numberRegistersGlobally(M);
2848 processOtherInstrs(M);
2852 MAI.Reqs.addCapability(SPIRV::Capability::Linkage);
2855 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::ZeroOrMore, 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