18#include "llvm/IR/IntrinsicsAArch64.h"
19#include "llvm/IR/IntrinsicsAMDGPU.h"
20#include "llvm/IR/IntrinsicsARM.h"
21#include "llvm/IR/IntrinsicsBPF.h"
22#include "llvm/IR/IntrinsicsHexagon.h"
23#include "llvm/IR/IntrinsicsLoongArch.h"
24#include "llvm/IR/IntrinsicsMips.h"
25#include "llvm/IR/IntrinsicsPowerPC.h"
26#include "llvm/IR/IntrinsicsR600.h"
27#include "llvm/IR/IntrinsicsRISCV.h"
28#include "llvm/IR/IntrinsicsS390.h"
29#include "llvm/IR/IntrinsicsSPIRV.h"
30#include "llvm/IR/IntrinsicsVE.h"
31#include "llvm/IR/IntrinsicsX86.h"
32#include "llvm/IR/IntrinsicsXCore.h"
44 unsigned NumArgs,
bool IsVarArg,
49#define GET_INTRINSIC_NAME_TABLE
50#include "llvm/IR/IntrinsicImpl.inc"
53#define GET_INTRINSIC_TARGET_FEATURES_TABLE
54#include "llvm/IR/IntrinsicImpl.inc"
57 assert(
id < num_intrinsics &&
"Invalid intrinsic ID!");
58 return IntrinsicNameTable[IntrinsicNameOffsetTable[id]];
62 assert(
id < num_intrinsics &&
"invalid intrinsic ID!");
63 return IntrinsicTargetFeaturesTable[IntrinsicTargetFeaturesOffsetTable[id]];
67 assert(
id < num_intrinsics &&
"Invalid intrinsic ID!");
69 "This version of getName does not support overloading");
88 Result +=
"p" +
utostr(PTyp->getAddressSpace());
90 Result +=
"a" +
utostr(ATyp->getNumElements()) +
93 if (!STyp->isLiteral()) {
96 Result += STyp->getName();
98 HasUnnamedType =
true;
101 for (
auto *Elem : STyp->elements())
108 for (
size_t i = 0; i < FT->getNumParams(); i++)
118 Result +=
"v" +
utostr(EC.getKnownMinValue()) +
122 Result += TETy->getName();
123 for (
Type *ParamTy : TETy->type_params())
125 for (
unsigned IntParam : TETy->int_params())
126 Result +=
"_" +
utostr(IntParam);
130 switch (Ty->getTypeID()) {
137 Result +=
"Metadata";
177 bool EarlyModuleCheck) {
179 assert(Id < Intrinsic::num_intrinsics &&
"Invalid intrinsic ID!");
181 "This version of getName is for overloaded intrinsics only");
182 (void)EarlyModuleCheck;
183 assert((!EarlyModuleCheck || M ||
185 "Intrinsic overloading on pointer types need to provide a Module");
186 bool HasUnnamedType =
false;
188 for (
Type *Ty : OverloadTys)
190 if (HasUnnamedType) {
191 assert(M &&
"unnamed types need a module");
196 "Provided FunctionType must match arguments");
197 return M->getUniqueIntrinsicName(Result, Id, FT);
204 assert(M &&
"We need to have a Module");
218#define GET_INTRINSIC_IITINFO
219#include "llvm/IR/IntrinsicImpl.inc"
222static_assert(IIT_Done == 0,
"IIT_Done expected to be 0");
229 auto IsScalableVector = [&]() {
231 if (NextInfo != IIT_SCALABLE_VEC)
242 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Void, 0));
245 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::VarArg, 0));
248 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::MMX, 0));
251 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::AMX, 0));
254 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Token, 0));
257 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Metadata, 0));
260 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Half, 0));
263 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::BFloat, 0));
266 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Float, 0));
269 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Double, 0));
272 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Quad, 0));
275 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::PPCQuad, 0));
278 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 1));
281 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 2));
284 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 4));
286 case IIT_AARCH64_SVCOUNT:
287 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::AArch64Svcount, 0));
290 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 8));
293 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 16));
296 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 32));
299 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 64));
302 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Integer, 128));
305 OutputTable.
push_back(IITDescriptor::getVector(1, IsScalableVector()));
309 OutputTable.
push_back(IITDescriptor::getVector(2, IsScalableVector()));
313 OutputTable.
push_back(IITDescriptor::getVector(3, IsScalableVector()));
317 OutputTable.
push_back(IITDescriptor::getVector(4, IsScalableVector()));
321 OutputTable.
push_back(IITDescriptor::getVector(6, IsScalableVector()));
325 OutputTable.
push_back(IITDescriptor::getVector(8, IsScalableVector()));
329 OutputTable.
push_back(IITDescriptor::getVector(10, IsScalableVector()));
333 OutputTable.
push_back(IITDescriptor::getVector(16, IsScalableVector()));
337 OutputTable.
push_back(IITDescriptor::getVector(32, IsScalableVector()));
341 OutputTable.
push_back(IITDescriptor::getVector(64, IsScalableVector()));
345 OutputTable.
push_back(IITDescriptor::getVector(128, IsScalableVector()));
349 OutputTable.
push_back(IITDescriptor::getVector(256, IsScalableVector()));
353 OutputTable.
push_back(IITDescriptor::getVector(512, IsScalableVector()));
357 OutputTable.
push_back(IITDescriptor::getVector(1024, IsScalableVector()));
361 OutputTable.
push_back(IITDescriptor::getVector(2048, IsScalableVector()));
365 OutputTable.
push_back(IITDescriptor::getVector(4096, IsScalableVector()));
369 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::WasmExternref, 0));
372 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::WasmFuncref, 0));
375 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
379 IITDescriptor::get(IITDescriptor::Pointer, Infos[NextElt++]));
382 unsigned OverloadIndex = Infos[NextElt++];
383 unsigned ArgKindEnums = Infos[NextElt++];
384 unsigned Packed = (ArgKindEnums << 8) | OverloadIndex;
386 IITDescriptor::get(IITDescriptor::Overloaded, Packed));
390 unsigned OverloadIndex = Infos[NextElt++];
392 IITDescriptor::get(IITDescriptor::Match, OverloadIndex));
395 case IIT_EXTEND_ARG: {
396 unsigned OverloadIndex = Infos[NextElt++];
398 IITDescriptor::get(IITDescriptor::Extend, OverloadIndex));
401 case IIT_TRUNC_ARG: {
402 unsigned OverloadIndex = Infos[NextElt++];
404 IITDescriptor::get(IITDescriptor::Trunc, OverloadIndex));
407 case IIT_ONE_NTH_ELTS_VEC_ARG: {
408 unsigned short OverloadIndex = Infos[NextElt++];
409 unsigned short N = Infos[NextElt++];
410 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::OneNthEltsVec,
414 case IIT_SAME_VEC_WIDTH_ARG: {
415 unsigned OverloadIndex = Infos[NextElt++];
417 IITDescriptor::get(IITDescriptor::SameVecWidth, OverloadIndex));
422 case IIT_VEC_OF_ANYPTRS_TO_ELT: {
423 unsigned short OverloadIndex = Infos[NextElt++];
424 unsigned short RefOverloadIndex = Infos[NextElt++];
425 OutputTable.
push_back(IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt,
431 unsigned StructElts = Infos[NextElt++] + 2;
434 IITDescriptor::get(IITDescriptor::Struct, StructElts));
436 for (
unsigned i = 0; i != StructElts; ++i)
440 case IIT_SUBDIVIDE2_ARG: {
441 unsigned OverloadIndex = Infos[NextElt++];
443 IITDescriptor::get(IITDescriptor::Subdivide2, OverloadIndex));
446 case IIT_SUBDIVIDE4_ARG: {
447 unsigned OverloadIndex = Infos[NextElt++];
449 IITDescriptor::get(IITDescriptor::Subdivide4, OverloadIndex));
452 case IIT_VEC_ELEMENT: {
453 unsigned OverloadIndex = Infos[NextElt++];
455 IITDescriptor::get(IITDescriptor::VecElement, OverloadIndex));
458 case IIT_VEC_OF_BITCASTS_TO_INT: {
459 unsigned OverloadIndex = Infos[NextElt++];
461 IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt, OverloadIndex));
464 case IIT_SCALABLE_VEC:
470#define GET_INTRINSIC_GENERATOR_GLOBAL
471#include "llvm/IR/IntrinsicImpl.inc"
473std::tuple<ArrayRef<Intrinsic::IITDescriptor>,
unsigned,
bool>
479 constexpr unsigned FixedEncodingBits =
sizeof(FixedEncodingTy) * CHAR_BIT;
480 constexpr unsigned MSBPosition = FixedEncodingBits - 1;
482 constexpr unsigned Mask = (1U << MSBPosition) - 1;
484 FixedEncodingTy TableVal = IIT_Table[
id - 1];
494 unsigned char IITValues[FixedEncodingBits / 4 + 1] = {0};
497 unsigned NextElt = 0;
500 if (TableVal >> MSBPosition) {
502 IITEntries = IIT_LongEncodingTable;
505 NextElt = TableVal & Mask;
510 IITValues[NextElt++] = TableVal & 0xF;
514 IITEntries = IITValues;
520 unsigned NumArgs = 0;
521 while (IITEntries[NextElt] != IIT_Done) {
528 bool IsVarArg =
false;
534 return {
TableRef, NumArgs, IsVarArg};
545 case IITDescriptor::Void:
547 case IITDescriptor::MMX:
549 case IITDescriptor::AMX:
551 case IITDescriptor::Token:
553 case IITDescriptor::Metadata:
555 case IITDescriptor::Half:
557 case IITDescriptor::BFloat:
559 case IITDescriptor::Float:
561 case IITDescriptor::Double:
563 case IITDescriptor::Quad:
565 case IITDescriptor::PPCQuad:
567 case IITDescriptor::AArch64Svcount:
569 case IITDescriptor::WasmExternref:
571 case IITDescriptor::WasmFuncref:
573 case IITDescriptor::Integer:
575 case IITDescriptor::Vector:
578 case IITDescriptor::Pointer:
580 case IITDescriptor::Struct: {
582 for (
unsigned i = 0, e =
D.StructNumElements; i != e; ++i)
589 case IITDescriptor::Overloaded:
590 case IITDescriptor::VecOfAnyPtrsToElt:
591 case IITDescriptor::Match:
592 return OverloadTys[
D.getOverloadIndex()];
593 case IITDescriptor::Extend:
594 return OverloadTys[
D.getOverloadIndex()]->getExtendedType();
595 case IITDescriptor::Trunc:
596 return OverloadTys[
D.getOverloadIndex()]->getTruncatedType();
597 case IITDescriptor::Subdivide2:
598 case IITDescriptor::Subdivide4: {
599 Type *Ty = OverloadTys[
D.getOverloadIndex()];
601 assert(VTy &&
"Expected overload type to be a Vector Type");
602 int SubDivs =
D.Kind == IITDescriptor::Subdivide2 ? 1 : 2;
605 case IITDescriptor::OneNthEltsVec:
608 D.getVectorDivisor());
609 case IITDescriptor::SameVecWidth: {
611 Type *Ty = OverloadTys[
D.getOverloadIndex()];
616 case IITDescriptor::VecElement: {
617 Type *Ty = OverloadTys[
D.getOverloadIndex()];
619 return VTy->getElementType();
622 case IITDescriptor::VecOfBitcastsToInt: {
623 Type *Ty = OverloadTys[
D.getOverloadIndex()];
625 assert(VTy &&
"Expected overload type to be a Vector Type");
628 case IITDescriptor::VarArg:
650#define GET_INTRINSIC_OVERLOAD_TABLE
651#include "llvm/IR/IntrinsicImpl.inc"
655#define GET_INTRINSIC_SCALARIZABLE_TABLE
656#include "llvm/IR/IntrinsicImpl.inc"
660#define GET_INTRINSIC_PRETTY_PRINT_TABLE
661#include "llvm/IR/IntrinsicImpl.inc"
665#define GET_INTRINSIC_TARGET_DATA
666#include "llvm/IR/IntrinsicImpl.inc"
669 return IID > TargetInfos[0].Count;
678 assert(Name.starts_with(
"llvm.") &&
"Unexpected intrinsic prefix");
679 assert(Name.drop_front(5).starts_with(
Target) &&
"Unexpected target");
690 CmpEnd += 1 +
Target.size();
692 const unsigned *
Low = NameOffsetTable.
begin();
693 const unsigned *
High = NameOffsetTable.
end();
694 const unsigned *LastLow =
Low;
695 while (CmpEnd < Name.size() &&
High -
Low > 0) {
696 size_t CmpStart = CmpEnd;
697 CmpEnd = Name.find(
'.', CmpStart + 1);
699 auto Cmp = [CmpStart, CmpEnd](
auto LHS,
auto RHS) {
704 if constexpr (std::is_integral_v<
decltype(
LHS)>)
705 LHSStr = IntrinsicNameTable.getCString(
LHS);
710 if constexpr (std::is_integral_v<
decltype(
RHS)>)
711 RHSStr = IntrinsicNameTable.getCString(
RHS);
715 return strncmp(LHSStr + CmpStart, RHSStr + CmpStart, CmpEnd - CmpStart) <
719 std::tie(
Low,
High) = std::equal_range(
Low,
High, Name.data(), Cmp);
724 if (LastLow == NameOffsetTable.
end())
726 StringRef NameFound = IntrinsicNameTable[*LastLow];
727 if (Name == NameFound ||
728 (Name.starts_with(NameFound) && Name[NameFound.
size()] ==
'.'))
729 return LastLow - NameOffsetTable.
begin();
738static std::pair<ArrayRef<unsigned>,
StringRef>
740 assert(Name.starts_with(
"llvm."));
747 Targets, [=](
const IntrinsicTargetInfo &TI) {
return TI.Name <
Target; });
750 const auto &TI = It != Targets.
end() && It->Name ==
Target ? *It : Targets[0];
751 return {
ArrayRef(&IntrinsicNameOffsetTable[1] + TI.Offset, TI.Count),
765 int Adjust = NameOffsetTable.data() - IntrinsicNameOffsetTable;
770 const auto MatchSize = IntrinsicNameTable[NameOffsetTable[Idx]].size();
771 assert(Name.size() >= MatchSize &&
"Expected either exact or prefix match");
772 bool IsExactMatch = Name.size() == MatchSize;
778#define GET_INTRINSIC_ATTRIBUTES
779#include "llvm/IR/IntrinsicImpl.inc"
785 std::string Name = OverloadTys.
empty()
789 if (
F->getFunctionType() == FT)
797 F->setName(
F->getName() +
".invalid");
798 return cast<Function>(M->getOrInsertFunction(Name, FT).getCallee());
824 assert(IsValid &&
"intrinsic signature mismatch");
839#define GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN
840#include "llvm/IR/IntrinsicImpl.inc"
843#define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
844#include "llvm/IR/IntrinsicImpl.inc"
848#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
849 case Intrinsic::INTRINSIC:
850#include "llvm/IR/ConstrainedOps.def"
860#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
861 case Intrinsic::INTRINSIC: \
862 return ROUND_MODE == 1;
863#include "llvm/IR/ConstrainedOps.def"
887struct MatchPosition {
891 uint16_t IsStruct : 1;
897 static constexpr unsigned INDEX_TABLE_SIZE = 2;
898 Index Indices[INDEX_TABLE_SIZE];
902 assert(NumIndices > 0 &&
"cannot pop from empty indices");
906 void push_struct_element(
unsigned ElementNum) {
907 assert(NumIndices < INDEX_TABLE_SIZE &&
"index table overflow");
909 Indices[NumIndices].IsStruct =
true;
910 Indices[NumIndices++].Num = ElementNum;
913 void push_vector_element() {
914 assert(NumIndices < INDEX_TABLE_SIZE &&
"index table overflow");
915 Indices[NumIndices].IsStruct =
false;
916 Indices[NumIndices++].Num = 0;
927 OS <<
"argument " << Pos.Num;
929 for (
const MatchPosition::Index &Idx :
930 ArrayRef(Pos.Indices).take_front(Pos.NumIndices)) {
932 OS <<
" struct element " << Idx.Num;
934 OS <<
" vector element";
940 std::tuple<Type *, ArrayRef<Intrinsic::IITDescriptor>, MatchPosition>;
951 OS << Position <<
" too many "
952 << (Position.IsRet ?
"returns" :
"arguments");
957 auto InfosRef = Infos;
958 auto DeferCheck = [&DeferredChecks, &InfosRef, &Position](
Type *
T) {
967 auto PrintMsg = [&OS, &Position,
969 std::optional<unsigned> OIdx = std::nullopt) ->
bool {
972 OS << Position <<
" type";
974 OS <<
" (overload type " << *OIdx <<
")";
975 OS <<
" expected " <<
Expected <<
", but got " << *Ty;
982 auto PrintMsgInvalidOverloadTy =
983 [&OS, &Position, &OverloadTys](
const Twine &DependentQualifier,
985 unsigned OIdx) ->
bool {
986 OS << Position <<
" is " << DependentQualifier <<
" overload type " << OIdx
987 <<
", so overload type " << OIdx <<
" expected " <<
Expected
988 <<
", but got " << *OverloadTys[OIdx];
993 auto PrintMsgInvalidDepType =
994 [&OS, &Position, &OverloadTys,
996 unsigned OIdx) ->
bool {
999 bool IsMatching = DependentQualifier.isSingleStringRef() &&
1000 DependentQualifier.getSingleStringRef() ==
"matching";
1001 OS << Position <<
" type (" << DependentQualifier <<
" overload type "
1002 << OIdx <<
") expected " <<
Expected;
1004 OS <<
" (overload type " << OIdx <<
" is " << *OverloadTys[OIdx] <<
")";
1005 OS <<
", but got " << *Ty;
1010 case IITDescriptor::Void:
1011 assert(Position.IsRet && Position.NumIndices == 0 &&
1012 "void descriptor expected only for return type");
1013 return PrintMsg(Ty->isVoidTy(),
"void");
1014 case IITDescriptor::MMX: {
1018 "x86_mmx (<1 x i64>)");
1020 case IITDescriptor::AMX:
1021 return PrintMsg(Ty->isX86_AMXTy(),
"x86_amx");
1022 case IITDescriptor::Token:
1023 return PrintMsg(Ty->isTokenTy(),
"token");
1024 case IITDescriptor::Metadata:
1025 return PrintMsg(Ty->isMetadataTy(),
"metadata");
1026 case IITDescriptor::Half:
1027 return PrintMsg(Ty->isHalfTy(),
"half");
1028 case IITDescriptor::BFloat:
1029 return PrintMsg(Ty->isBFloatTy(),
"bfloat");
1030 case IITDescriptor::Float:
1031 return PrintMsg(Ty->isFloatTy(),
"float");
1032 case IITDescriptor::Double:
1033 return PrintMsg(Ty->isDoubleTy(),
"double");
1034 case IITDescriptor::Quad:
1035 return PrintMsg(Ty->isFP128Ty(),
"fp128");
1036 case IITDescriptor::PPCQuad:
1037 return PrintMsg(Ty->isPPC_FP128Ty(),
"ppc_fp128");
1038 case IITDescriptor::Integer:
1039 return PrintMsg(Ty->isIntegerTy(
D.IntegerWidth),
1040 "i" +
Twine(
D.IntegerWidth));
1041 case IITDescriptor::AArch64Svcount:
1045 case IITDescriptor::WasmExternref:
1049 case IITDescriptor::WasmFuncref:
1053 case IITDescriptor::Vector: {
1055 StringRef Scalable =
D.VectorWidth.isScalable() ?
"vscale " :
"";
1057 PrintMsg(VT && VT->getElementCount() ==
D.VectorWidth,
1058 Twine(Scalable) +
"vector with " +
1059 Twine(
D.VectorWidth.getKnownMinValue()) +
" elements");
1062 Position.push_vector_element();
1064 OverloadTys, DeferredChecks, IsDeferredCheck, OS);
1066 case IITDescriptor::Pointer: {
1068 unsigned AS =
D.PointerAddressSpace;
1069 bool IsValid = PT && PT->getAddressSpace() == AS;
1071 return PrintMsg(IsValid,
"ptr");
1072 return PrintMsg(IsValid,
"ptr addrspace(" +
Twine(AS) +
")");
1075 case IITDescriptor::Struct: {
1077 unsigned EC =
D.StructNumElements;
1078 bool HasError = PrintMsg(
1079 ST && ST->isLiteral() && !ST->isPacked() && ST->getNumElements() == EC,
1080 "literal non-packed struct with " +
Twine(EC) +
" elements");
1085 Position.push_struct_element(Idx);
1087 IsDeferredCheck, OS))
1089 Position.pop_index();
1094 case IITDescriptor::Overloaded: {
1095 unsigned OIdx =
D.getOverloadIndex();
1096 assert(OIdx == OverloadTys.
size() && !IsDeferredCheck &&
1097 "Table consistency error");
1103 if (Ty->isTokenTy())
1104 return PrintMsg(
false,
"any manglable type", OIdx);
1106 IITDescriptor::AnyKindVectorConstraint VC;
1107 IITDescriptor::AnyKindElementConstraint EC;
1108 std::tie(VC, EC) =
D.getOverloadConstraints();
1110 bool IsValid = [&]() {
1112 case IITDescriptor::VC_None:
1114 case IITDescriptor::VC_Vector:
1116 case IITDescriptor::VC_Scalar:
1125 case IITDescriptor::EC_None:
1127 case IITDescriptor::EC_Integer:
1129 case IITDescriptor::EC_Float:
1131 case IITDescriptor::EC_Pointer:
1152 if (EC == IITDescriptor::EC_None) {
1156 return PrintMsg(
false,
formatv(
"any {} type", VK), OIdx);
1161 case IITDescriptor::VC_None:
1163 return PrintMsg(
false,
formatv(
"any {0} or {0} vector", EK), OIdx);
1164 case IITDescriptor::VC_Vector:
1165 return PrintMsg(
false,
formatv(
"any {} vector", EK), OIdx);
1166 case IITDescriptor::VC_Scalar:
1167 return PrintMsg(
false,
formatv(
"any {} type", EK), OIdx);
1172 case IITDescriptor::Match: {
1173 unsigned OIdx =
D.getOverloadIndex();
1174 if (OIdx >= OverloadTys.
size())
1175 return IsDeferredCheck || DeferCheck(Ty);
1176 return PrintMsgInvalidDepType(Ty == OverloadTys[OIdx],
"matching",
1177 formatv(
"{}", *OverloadTys[OIdx]), OIdx);
1180 case IITDescriptor::Extend:
1181 case IITDescriptor::Trunc: {
1182 unsigned OIdx =
D.getOverloadIndex();
1184 if (OIdx >= OverloadTys.
size())
1185 return IsDeferredCheck || DeferCheck(Ty);
1187 Type *OTy = OverloadTys[OIdx];
1188 bool IsExtend =
D.Kind == IITDescriptor::Extend;
1189 StringRef Qualifier = IsExtend ?
"extended" :
"truncated";
1191 return PrintMsgInvalidOverloadTy(Qualifier,
"int or vector of int", OIdx);
1194 return PrintMsgInvalidDepType(Ty == NewTy, Qualifier,
formatv(
"{}", *NewTy),
1197 case IITDescriptor::OneNthEltsVec: {
1198 unsigned OIdx =
D.getOverloadIndex();
1199 unsigned Divisor =
D.getVectorDivisor();
1201 if (OIdx >= OverloadTys.
size())
1202 return IsDeferredCheck || DeferCheck(Ty);
1203 Type *OTy = OverloadTys[OIdx];
1205 auto Qualifier =
formatv(
"1/nth (n={}) elements vector of", Divisor);
1207 return PrintMsgInvalidOverloadTy(Qualifier,
"vector", OIdx);
1208 if (!OVecTy->getElementCount().isKnownMultipleOf(Divisor))
1209 return PrintMsgInvalidOverloadTy(
1210 Qualifier,
formatv(
"vector with multiple of {} elements", Divisor),
1213 return PrintMsgInvalidDepType(
Expected == Ty, Qualifier,
1216 case IITDescriptor::SameVecWidth: {
1217 unsigned OIdx =
D.getOverloadIndex();
1218 if (OIdx >= OverloadTys.
size()) {
1221 return IsDeferredCheck || DeferCheck(Ty);
1226 StringRef Qualifier =
"same vector width of";
1227 if (OVecTy && !ThisArgVecType)
1228 return PrintMsgInvalidDepType(
false, Qualifier,
"vector", OIdx);
1229 if (!OVecTy && ThisArgVecType)
1230 return PrintMsgInvalidDepType(
false, Qualifier,
"scalar", OIdx);
1232 if (ThisArgVecType) {
1234 if (
Expected != ThisArgVecType->getElementCount())
1235 return PrintMsgInvalidDepType(
1238 EltTy = ThisArgVecType->getElementType();
1239 Position.push_vector_element();
1242 DeferredChecks, IsDeferredCheck, OS);
1244 case IITDescriptor::VecOfAnyPtrsToElt: {
1245 unsigned RefOverloadIndex =
D.getRefOverloadIndex();
1246 if (RefOverloadIndex >= OverloadTys.
size()) {
1247 if (IsDeferredCheck)
1251 assert(
D.getOverloadIndex() == OverloadTys.
size() &&
1252 "Table consistency error");
1254 return DeferCheck(Ty);
1257 if (!IsDeferredCheck) {
1258 assert(
D.getOverloadIndex() == OverloadTys.
size() &&
1259 "Table consistency error");
1266 StringRef Qualifier =
"vector of pointers to elements of";
1269 return PrintMsgInvalidOverloadTy(Qualifier,
"vector", RefOverloadIndex);
1273 return PrintMsgInvalidDepType(
false, Qualifier,
"vector",
1278 formatv(
"vector of pointers with {} elements", ExpectedCount);
1279 bool IsValid = ThisArgVecTy->getElementCount() == ExpectedCount &&
1280 ThisArgVecTy->getElementType()->isPointerTy();
1281 return PrintMsgInvalidDepType(IsValid, Qualifier,
Expected,
1284 case IITDescriptor::VecElement: {
1285 unsigned OIdx =
D.getOverloadIndex();
1286 if (OIdx >= OverloadTys.
size())
1287 return IsDeferredCheck || DeferCheck(Ty);
1288 StringRef Qualifier =
"vector element of";
1291 return PrintMsgInvalidOverloadTy(Qualifier,
"vector", OIdx);
1293 return PrintMsgInvalidDepType(
Expected == Ty, Qualifier,
1296 case IITDescriptor::Subdivide2:
1297 case IITDescriptor::Subdivide4: {
1298 unsigned OIdx =
D.getOverloadIndex();
1300 if (OIdx >= OverloadTys.
size())
1301 return IsDeferredCheck || DeferCheck(Ty);
1303 int SubDivs =
D.Kind == IITDescriptor::Subdivide2 ? 1 : 2;
1306 formatv(
"subdivided by {} vector of", SubDivs == 1 ? 2 : 4);
1308 return PrintMsgInvalidOverloadTy(Qualifier,
"vector", OIdx);
1313 return PrintMsgInvalidDepType(
Expected == Ty, Qualifier,
1316 case IITDescriptor::VecOfBitcastsToInt: {
1317 unsigned OIdx =
D.getOverloadIndex();
1318 if (OIdx >= OverloadTys.
size())
1319 return IsDeferredCheck || DeferCheck(Ty);
1321 StringRef Qualifier =
"vector of bitcasts to int of";
1323 return PrintMsgInvalidOverloadTy(Qualifier,
"vector", OIdx);
1325 return PrintMsgInvalidDepType(
Expected == Ty, Qualifier,
1328 case IITDescriptor::VarArg:
1345 unsigned NumArgs,
bool IsVarArg,
1350 assert(!Infos.
empty() &&
"Table consistency error");
1357 DeferredChecks,
false, OS))
1360 if (FTy->getNumParams() != NumArgs) {
1361 OS <<
"intrinsic has incorrect number of args. Expected " << NumArgs
1362 <<
", but got " << FTy->getNumParams();
1374 for (
unsigned I = 0,
E = DeferredChecks.
size();
I !=
E; ++
I) {
1375 auto &[DefTy, DefInfos, DefPosition] = DeferredChecks[
I];
1377 DeferredChecks,
true, OS))
1381 if (!Infos.
empty()) {
1382 OS <<
"intrinsic has too few arguments!";
1386 if (FTy->isVarArg() != IsVarArg) {
1388 OS <<
"intrinsic was not defined with variable arguments!";
1390 OS <<
"intrinsic was defined with variable arguments!";
1413 return ::isSignatureValid(FT,
TableRef, NumArgs, IsVarArg, OverloadTys, OS);
1426 return std::nullopt;
1430 std::string WantedName =
1432 if (Name == WantedName)
1433 return std::nullopt;
1436 if (
auto *ExistingGV =
F->getParent()->getNamedValue(WantedName)) {
1438 if (ExistingF->getFunctionType() ==
F->getFunctionType())
1445 ExistingGV->setName(WantedName +
".renamed");
1452 "Shouldn't change the signature");
1461 {Intrinsic::vector_interleave2, Intrinsic::vector_deinterleave2},
1462 {Intrinsic::vector_interleave3, Intrinsic::vector_deinterleave3},
1463 {Intrinsic::vector_interleave4, Intrinsic::vector_deinterleave4},
1464 {Intrinsic::vector_interleave5, Intrinsic::vector_deinterleave5},
1465 {Intrinsic::vector_interleave6, Intrinsic::vector_deinterleave6},
1466 {Intrinsic::vector_interleave7, Intrinsic::vector_deinterleave7},
1467 {Intrinsic::vector_interleave8, Intrinsic::vector_deinterleave8},
1471 assert(Factor >= 2 && Factor <= 8 &&
"Unexpected factor");
1476 assert(Factor >= 2 && Factor <= 8 &&
"Unexpected factor");
1483 OS << static_cast<FPClassTest>(Val);
1486#define GET_INTRINSIC_IMMARG_RANGE_SET_CHECKS
1487#include "llvm/IR/IntrinsicImpl.inc"
1489#define GET_INTRINSIC_PRETTY_PRINT_ARGUMENTS
1490#include "llvm/IR/IntrinsicImpl.inc"
1494#define GET_INTRINSIC_DEFAULT_ARG_VALUES
1495#include "llvm/IR/IntrinsicImpl.inc"
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ArrayRef< TableEntry > TableRef
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Module.h This file contains the declarations for the Module class.
static bool matchIntrinsicType(Type *Ty, ArrayRef< Intrinsic::IITDescriptor > &Infos, MatchPosition Position, SmallVectorImpl< Type * > &OverloadTys, SmallVectorImpl< DeferredIntrinsicMatchInfo > &DeferredChecks, bool IsDeferredCheck, raw_ostream &OS)
static bool isSignatureValid(FunctionType *FTy, ArrayRef< Intrinsic::IITDescriptor > &Infos, unsigned NumArgs, bool IsVarArg, SmallVectorImpl< Type * > &OverloadTys, raw_ostream &OS)
Return true if the function type FTy is a valid type signature for the type constraints specified in ...
static InterleaveIntrinsic InterleaveIntrinsics[]
std::tuple< Type *, ArrayRef< Intrinsic::IITDescriptor >, MatchPosition > DeferredIntrinsicMatchInfo
static std::pair< ArrayRef< unsigned >, StringRef > findTargetSubtable(StringRef Name)
Find the segment of IntrinsicNameOffsetTable for intrinsics with the same target as Name,...
static Function * getOrInsertIntrinsicDeclarationImpl(Module *M, Intrinsic::ID id, ArrayRef< Type * > OverloadTys, FunctionType *FT)
static void DecodeIITType(unsigned &NextElt, ArrayRef< unsigned char > Infos, SmallVectorImpl< Intrinsic::IITDescriptor > &OutputTable)
static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef< Type * > OverloadTys, Module *M, FunctionType *FT, bool EarlyModuleCheck)
IIT_Info
IIT_Info - These are enumerators that describe the entries returned by the getIntrinsicInfoTableEntri...
static Type * DecodeFixedType(ArrayRef< Intrinsic::IITDescriptor > &Infos, ArrayRef< Type * > OverloadTys, LLVMContext &Context)
static int lookupLLVMIntrinsicByName(ArrayRef< unsigned > NameOffsetTable, StringRef Name, StringRef Target="")
Looks up Name in NameTable via binary search.
static std::string getMangledTypeStr(Type *Ty, bool &HasUnnamedType)
Returns a stable mangling for the type specified for use in the name mangling scheme used by 'any' ty...
This file contains the definitions of the enumerations and flags associated with NVVM Intrinsics,...
static StringRef getName(Value *V)
static SymbolRef::Type getType(const Symbol *Sym)
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
Check if the array is empty.
const T & consume_front()
consume_front() - Returns the first element and drops it from ArrayRef.
This is an important base class in LLVM.
Tagged union holding either a T or a Error.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Class to represent function types.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
const Function & getFunction() const
void setCallingConv(CallingConv::ID CC)
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
This is an important class for using LLVM in a threaded context.
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Represent a constant reference to a string, i.e.
static constexpr size_t npos
std::string str() const
Get the contents as an std::string.
constexpr size_t size() const
Get the string size.
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Class to represent target extensions types, which are generally unintrospectable from target-independ...
static LLVM_ABI TargetExtType * get(LLVMContext &Context, StringRef Name, ArrayRef< Type * > Types={}, ArrayRef< unsigned > Ints={})
Return a target extension type having the specified name and optional type and integer parameters.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI Type * getX86_AMXTy(LLVMContext &C)
LLVM_ABI Type * getTruncatedType() const
Given scalar/vector integer type, returns a type with elements half as wide as in the original type.
static LLVM_ABI Type * getMetadataTy(LLVMContext &C)
static LLVM_ABI Type * getTokenTy(LLVMContext &C)
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isPointerTy() const
True if this is an instance of PointerType.
static LLVM_ABI Type * getPPC_FP128Ty(LLVMContext &C)
static LLVM_ABI Type * getFP128Ty(LLVMContext &C)
@ X86_AMXTyID
AMX vectors (8192 bits, X86 specific)
@ HalfTyID
16-bit floating point type
@ VoidTyID
type with no size
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ BFloatTyID
16-bit floating point type (7-bit significand)
@ DoubleTyID
64-bit floating point type
@ X86_FP80TyID
80-bit floating point type (X87)
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
@ ByteTyID
Arbitrary bit width bytes.
@ FP128TyID
128-bit floating point type (112-bit significand)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
LLVM_ABI Type * getExtendedType() const
Given scalar/vector integer type, returns a type with elements twice as wide as in the original type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
static LLVM_ABI Type * getBFloatTy(LLVMContext &C)
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
static VectorType * getOneNthElementsVectorType(VectorType *VTy, unsigned Denominator)
static VectorType * getSubdividedVectorType(VectorType *VTy, int NumSubdivs)
static VectorType * getInteger(VectorType *VTy)
This static method gets a VectorType with the same number of elements as the input type,...
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Type * getElementType() const
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Intrinsic::ID getDeinterleaveIntrinsicID(unsigned Factor)
Returns the corresponding llvm.vector.deinterleaveN intrinsic for factor N.
LLVM_ABI void printFPClassMask(raw_ostream &OS, const Constant *ImmArgVal)
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
LLVM_ABI std::optional< Function * > remangleIntrinsicFunction(Function *F)
LLVM_ABI bool hasConstrainedFPRoundingModeOperand(ID QID)
Returns true if the intrinsic ID is for one of the "ConstrainedFloating-Point Intrinsics" that take r...
LLVM_ABI StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
LLVM_ABI bool isConstrainedFPIntrinsic(ID QID)
Returns true if the intrinsic ID is for one of the "ConstrainedFloating-Point Intrinsics".
LLVM_ABI ID lookupIntrinsicID(StringRef Name)
This does the actual lookup of an intrinsic ID which matches the given function name.
LLVM_ABI bool hasPrettyPrintedArgs(ID id)
Returns true if the intrinsic has pretty printed immediate arguments.
LLVM_ABI std::tuple< ArrayRef< IITDescriptor >, unsigned, bool > getIntrinsicInfoTableEntries(ID id, SmallVectorImpl< IITDescriptor > &T)
Fill the IIT table descriptor for the intrinsic id into an array of IITDescriptors.
LLVM_ABI StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
LLVM_ABI Intrinsic::ID getInterleaveIntrinsicID(unsigned Factor)
Returns the corresponding llvm.vector.interleaveN intrinsic for factor N.
LLVM_ABI bool isOverloaded(ID id)
Returns true if the intrinsic can be overloaded.
LLVM_ABI FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > OverloadTys={})
Return the function type for an intrinsic.
LLVM_ABI bool isSignatureValid(Intrinsic::ID ID, FunctionType *FT, SmallVectorImpl< Type * > &OverloadTys, raw_ostream &OS=nulls())
Returns true if FT is a valid function type for intrinsic ID.
LLVM_ABI bool hasStructReturnType(ID id)
Returns true if id has a struct return type.
LLVM_ABI bool isTriviallyScalarizable(ID id)
Returns true if the intrinsic is trivially scalarizable.
LLVM_ABI bool isTargetIntrinsic(ID IID)
isTargetIntrinsic - Returns true if IID is an intrinsic specific to a certain target.
LLVM_ABI StringRef getRequiredTargetFeatures(ID id)
LLVM_ABI std::string getNameNoUnnamedTypes(ID Id, ArrayRef< Type * > OverloadTys)
Return the LLVM name for an intrinsic.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
std::string utostr(uint64_t X, bool isNeg=false)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Intrinsic::ID Deinterleave