LLVM: lib/IR/Intrinsics.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
16#include "llvm/IR/IntrinsicsAArch64.h"
17#include "llvm/IR/IntrinsicsAMDGPU.h"
18#include "llvm/IR/IntrinsicsARM.h"
19#include "llvm/IR/IntrinsicsBPF.h"
20#include "llvm/IR/IntrinsicsHexagon.h"
21#include "llvm/IR/IntrinsicsLoongArch.h"
22#include "llvm/IR/IntrinsicsMips.h"
23#include "llvm/IR/IntrinsicsNVPTX.h"
24#include "llvm/IR/IntrinsicsPowerPC.h"
25#include "llvm/IR/IntrinsicsR600.h"
26#include "llvm/IR/IntrinsicsRISCV.h"
27#include "llvm/IR/IntrinsicsS390.h"
28#include "llvm/IR/IntrinsicsVE.h"
29#include "llvm/IR/IntrinsicsX86.h"
30#include "llvm/IR/IntrinsicsXCore.h"
33
34using namespace llvm;
35
36
37#define GET_INTRINSIC_NAME_TABLE
38#include "llvm/IR/IntrinsicImpl.inc"
39#undef GET_INTRINSIC_NAME_TABLE
40
42 assert(id < num_intrinsics && "Invalid intrinsic ID!");
43 return IntrinsicNameTable + IntrinsicNameOffsetTable[id];
44}
45
47 assert(id < num_intrinsics && "Invalid intrinsic ID!");
49 "This version of getName does not support overloading");
51}
52
53
54
55
56
57
58
59
60
61
62
63
64
66 std::string Result;
67 if (PointerType *PTyp = dyn_cast(Ty)) {
68 Result += "p" + utostr(PTyp->getAddressSpace());
69 } else if (ArrayType *ATyp = dyn_cast(Ty)) {
70 Result += "a" + utostr(ATyp->getNumElements()) +
72 } else if (StructType *STyp = dyn_cast(Ty)) {
73 if (!STyp->isLiteral()) {
74 Result += "s_";
75 if (STyp->hasName())
76 Result += STyp->getName();
77 else
78 HasUnnamedType = true;
79 } else {
80 Result += "sl_";
81 for (auto *Elem : STyp->elements())
83 }
84
85 Result += "s";
86 } else if (FunctionType *FT = dyn_cast(Ty)) {
87 Result += "f_" + getMangledTypeStr(FT->getReturnType(), HasUnnamedType);
88 for (size_t i = 0; i < FT->getNumParams(); i++)
90 if (FT->isVarArg())
91 Result += "vararg";
92
93 Result += "f";
94 } else if (VectorType *VTy = dyn_cast(Ty)) {
96 if (EC.isScalable())
97 Result += "nx";
98 Result += "v" + utostr(EC.getKnownMinValue()) +
100 } else if (TargetExtType *TETy = dyn_cast(Ty)) {
101 Result += "t";
102 Result += TETy->getName();
103 for (Type *ParamTy : TETy->type_params())
105 for (unsigned IntParam : TETy->int_params())
106 Result += "_" + utostr(IntParam);
107
108 Result += "t";
109 } else if (Ty) {
111 default:
114 Result += "isVoid";
115 break;
117 Result += "Metadata";
118 break;
120 Result += "f16";
121 break;
123 Result += "bf16";
124 break;
126 Result += "f32";
127 break;
129 Result += "f64";
130 break;
132 Result += "f80";
133 break;
135 Result += "f128";
136 break;
138 Result += "ppcf128";
139 break;
141 Result += "x86amx";
142 break;
144 Result += "i" + utostr(cast(Ty)->getBitWidth());
145 break;
146 }
147 }
148 return Result;
149}
150
153 bool EarlyModuleCheck) {
154
155 assert(Id < Intrinsic::num_intrinsics && "Invalid intrinsic ID!");
157 "This version of getName is for overloaded intrinsics only");
158 (void)EarlyModuleCheck;
159 assert((!EarlyModuleCheck || M ||
160 (Tys, [](Type *T) { return isa(T); })) &&
161 "Intrinsic overloading on pointer types need to provide a Module");
162 bool HasUnnamedType = false;
164 for (Type *Ty : Tys)
166 if (HasUnnamedType) {
167 assert(M && "unnamed types need a module");
168 if (!FT)
170 else
172 "Provided FunctionType must match arguments");
173 return M->getUniqueIntrinsicName(Result, Id, FT);
174 }
175 return Result;
176}
177
180 assert(M && "We need to have a Module");
182}
183
186}
187
188
189
190
191
193#define GET_INTRINSIC_IITINFO
194#include "llvm/IR/IntrinsicImpl.inc"
195#undef GET_INTRINSIC_IITINFO
196};
197
198static void
202 using namespace Intrinsic;
203
204 bool IsScalableVector = (LastInfo == IIT_SCALABLE_VEC);
205
207 unsigned StructElts = 2;
208
209 switch (Info) {
210 case IIT_Done:
211 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Void, 0));
212 return;
213 case IIT_VARARG:
214 OutputTable.push_back(IITDescriptor::get(IITDescriptor::VarArg, 0));
215 return;
216 case IIT_MMX:
217 OutputTable.push_back(IITDescriptor::get(IITDescriptor::MMX, 0));
218 return;
219 case IIT_AMX:
220 OutputTable.push_back(IITDescriptor::get(IITDescriptor::AMX, 0));
221 return;
222 case IIT_TOKEN:
223 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Token, 0));
224 return;
225 case IIT_METADATA:
226 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Metadata, 0));
227 return;
228 case IIT_F16:
229 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Half, 0));
230 return;
231 case IIT_BF16:
232 OutputTable.push_back(IITDescriptor::get(IITDescriptor::BFloat, 0));
233 return;
234 case IIT_F32:
235 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Float, 0));
236 return;
237 case IIT_F64:
238 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Double, 0));
239 return;
240 case IIT_F128:
241 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Quad, 0));
242 return;
243 case IIT_PPCF128:
244 OutputTable.push_back(IITDescriptor::get(IITDescriptor::PPCQuad, 0));
245 return;
246 case IIT_I1:
247 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 1));
248 return;
249 case IIT_I2:
250 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 2));
251 return;
252 case IIT_I4:
253 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 4));
254 return;
255 case IIT_AARCH64_SVCOUNT:
256 OutputTable.push_back(IITDescriptor::get(IITDescriptor::AArch64Svcount, 0));
257 return;
258 case IIT_I8:
259 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 8));
260 return;
261 case IIT_I16:
262 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 16));
263 return;
264 case IIT_I32:
265 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 32));
266 return;
267 case IIT_I64:
268 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 64));
269 return;
270 case IIT_I128:
271 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 128));
272 return;
273 case IIT_V1:
274 OutputTable.push_back(IITDescriptor::getVector(1, IsScalableVector));
276 return;
277 case IIT_V2:
278 OutputTable.push_back(IITDescriptor::getVector(2, IsScalableVector));
280 return;
281 case IIT_V3:
282 OutputTable.push_back(IITDescriptor::getVector(3, IsScalableVector));
284 return;
285 case IIT_V4:
286 OutputTable.push_back(IITDescriptor::getVector(4, IsScalableVector));
288 return;
289 case IIT_V6:
290 OutputTable.push_back(IITDescriptor::getVector(6, IsScalableVector));
292 return;
293 case IIT_V8:
294 OutputTable.push_back(IITDescriptor::getVector(8, IsScalableVector));
296 return;
297 case IIT_V10:
298 OutputTable.push_back(IITDescriptor::getVector(10, IsScalableVector));
300 return;
301 case IIT_V16:
302 OutputTable.push_back(IITDescriptor::getVector(16, IsScalableVector));
304 return;
305 case IIT_V32:
306 OutputTable.push_back(IITDescriptor::getVector(32, IsScalableVector));
308 return;
309 case IIT_V64:
310 OutputTable.push_back(IITDescriptor::getVector(64, IsScalableVector));
312 return;
313 case IIT_V128:
314 OutputTable.push_back(IITDescriptor::getVector(128, IsScalableVector));
316 return;
317 case IIT_V256:
318 OutputTable.push_back(IITDescriptor::getVector(256, IsScalableVector));
320 return;
321 case IIT_V512:
322 OutputTable.push_back(IITDescriptor::getVector(512, IsScalableVector));
324 return;
325 case IIT_V1024:
326 OutputTable.push_back(IITDescriptor::getVector(1024, IsScalableVector));
328 return;
329 case IIT_EXTERNREF:
330 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 10));
331 return;
332 case IIT_FUNCREF:
333 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 20));
334 return;
335 case IIT_PTR:
336 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Pointer, 0));
337 return;
338 case IIT_ANYPTR:
340 IITDescriptor::get(IITDescriptor::Pointer, Infos[NextElt++]));
341 return;
342 case IIT_ARG: {
343 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
344 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Argument, ArgInfo));
345 return;
346 }
347 case IIT_EXTEND_ARG: {
348 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
350 IITDescriptor::get(IITDescriptor::ExtendArgument, ArgInfo));
351 return;
352 }
353 case IIT_TRUNC_ARG: {
354 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
356 IITDescriptor::get(IITDescriptor::TruncArgument, ArgInfo));
357 return;
358 }
359 case IIT_HALF_VEC_ARG: {
360 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
362 IITDescriptor::get(IITDescriptor::HalfVecArgument, ArgInfo));
363 return;
364 }
365 case IIT_SAME_VEC_WIDTH_ARG: {
366 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
368 IITDescriptor::get(IITDescriptor::SameVecWidthArgument, ArgInfo));
369 return;
370 }
371 case IIT_VEC_OF_ANYPTRS_TO_ELT: {
372 unsigned short ArgNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
373 unsigned short RefNo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
375 IITDescriptor::get(IITDescriptor::VecOfAnyPtrsToElt, ArgNo, RefNo));
376 return;
377 }
378 case IIT_EMPTYSTRUCT:
379 OutputTable.push_back(IITDescriptor::get(IITDescriptor::Struct, 0));
380 return;
381 case IIT_STRUCT9:
382 ++StructElts;
383 [[fallthrough]];
384 case IIT_STRUCT8:
385 ++StructElts;
386 [[fallthrough]];
387 case IIT_STRUCT7:
388 ++StructElts;
389 [[fallthrough]];
390 case IIT_STRUCT6:
391 ++StructElts;
392 [[fallthrough]];
393 case IIT_STRUCT5:
394 ++StructElts;
395 [[fallthrough]];
396 case IIT_STRUCT4:
397 ++StructElts;
398 [[fallthrough]];
399 case IIT_STRUCT3:
400 ++StructElts;
401 [[fallthrough]];
402 case IIT_STRUCT2: {
404 IITDescriptor::get(IITDescriptor::Struct, StructElts));
405
406 for (unsigned i = 0; i != StructElts; ++i)
408 return;
409 }
410 case IIT_SUBDIVIDE2_ARG: {
411 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
413 IITDescriptor::get(IITDescriptor::Subdivide2Argument, ArgInfo));
414 return;
415 }
416 case IIT_SUBDIVIDE4_ARG: {
417 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
419 IITDescriptor::get(IITDescriptor::Subdivide4Argument, ArgInfo));
420 return;
421 }
422 case IIT_VEC_ELEMENT: {
423 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
425 IITDescriptor::get(IITDescriptor::VecElementArgument, ArgInfo));
426 return;
427 }
428 case IIT_SCALABLE_VEC: {
430 return;
431 }
432 case IIT_VEC_OF_BITCASTS_TO_INT: {
433 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
435 IITDescriptor::get(IITDescriptor::VecOfBitcastsToInt, ArgInfo));
436 return;
437 }
438 }
440}
441
442#define GET_INTRINSIC_GENERATOR_GLOBAL
443#include "llvm/IR/IntrinsicImpl.inc"
444#undef GET_INTRINSIC_GENERATOR_GLOBAL
445
448 static_assert(sizeof(IIT_Table[0]) == 2,
449 "Expect 16-bit entries in IIT_Table");
450
451 uint16_t TableVal = IIT_Table[id - 1];
452
453
456 unsigned NextElt = 0;
457 if (TableVal >> 15) {
458
459 IITEntries = IIT_LongEncodingTable;
460
461
462 NextElt = TableVal & 0x7fff;
463 } else {
464
465
466 do {
467 IITValues.push_back(TableVal & 0xF);
468 TableVal >>= 4;
469 } while (TableVal);
470
471 IITEntries = IITValues;
472 NextElt = 0;
473 }
474
475
477 while (NextElt != IITEntries.size() && IITEntries[NextElt] != 0)
479}
480
483 using namespace Intrinsic;
484
485 IITDescriptor D = Infos.front();
486 Infos = Infos.slice(1);
487
488 switch (D.Kind) {
489 case IITDescriptor::Void:
491 case IITDescriptor::VarArg:
493 case IITDescriptor::MMX:
495 case IITDescriptor::AMX:
497 case IITDescriptor::Token:
499 case IITDescriptor::Metadata:
501 case IITDescriptor::Half:
503 case IITDescriptor::BFloat:
505 case IITDescriptor::Float:
507 case IITDescriptor::Double:
509 case IITDescriptor::Quad:
511 case IITDescriptor::PPCQuad:
513 case IITDescriptor::AArch64Svcount:
515
516 case IITDescriptor::Integer:
518 case IITDescriptor::Vector:
519 return VectorType::get(DecodeFixedType(Infos, Tys, Context),
520 D.Vector_Width);
521 case IITDescriptor::Pointer:
522 return PointerType::get(Context, D.Pointer_AddressSpace);
523 case IITDescriptor::Struct: {
525 for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
528 }
529 case IITDescriptor::Argument:
530 return Tys[D.getArgumentNumber()];
531 case IITDescriptor::ExtendArgument: {
532 Type *Ty = Tys[D.getArgumentNumber()];
533 if (VectorType *VTy = dyn_cast(Ty))
534 return VectorType::getExtendedElementVectorType(VTy);
535
537 }
538 case IITDescriptor::TruncArgument: {
539 Type *Ty = Tys[D.getArgumentNumber()];
540 if (VectorType *VTy = dyn_cast(Ty))
541 return VectorType::getTruncatedElementVectorType(VTy);
542
543 IntegerType *ITy = cast(Ty);
546 }
547 case IITDescriptor::Subdivide2Argument:
548 case IITDescriptor::Subdivide4Argument: {
549 Type *Ty = Tys[D.getArgumentNumber()];
550 VectorType *VTy = dyn_cast(Ty);
551 assert(VTy && "Expected an argument of Vector Type");
552 int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
553 return VectorType::getSubdividedVectorType(VTy, SubDivs);
554 }
555 case IITDescriptor::HalfVecArgument:
556 return VectorType::getHalfElementsVectorType(
557 cast(Tys[D.getArgumentNumber()]));
558 case IITDescriptor::SameVecWidthArgument: {
560 Type *Ty = Tys[D.getArgumentNumber()];
561 if (auto *VTy = dyn_cast(Ty))
562 return VectorType::get(EltTy, VTy->getElementCount());
563 return EltTy;
564 }
565 case IITDescriptor::VecElementArgument: {
566 Type *Ty = Tys[D.getArgumentNumber()];
567 if (VectorType *VTy = dyn_cast(Ty))
568 return VTy->getElementType();
570 }
571 case IITDescriptor::VecOfBitcastsToInt: {
572 Type *Ty = Tys[D.getArgumentNumber()];
573 VectorType *VTy = dyn_cast(Ty);
574 assert(VTy && "Expected an argument of Vector Type");
575 return VectorType::getInteger(VTy);
576 }
577 case IITDescriptor::VecOfAnyPtrsToElt:
578
579 return Tys[D.getOverloadArgNumber()];
580 }
582}
583
588
591
595
596
597
598
599 if (!ArgTys.empty() && ArgTys.back()->isVoidTy()) {
601 return FunctionType::get(ResultTy, ArgTys, true);
602 }
603 return FunctionType::get(ResultTy, ArgTys, false);
604}
605
607#define GET_INTRINSIC_OVERLOAD_TABLE
608#include "llvm/IR/IntrinsicImpl.inc"
609#undef GET_INTRINSIC_OVERLOAD_TABLE
610}
611
612
613#define GET_INTRINSIC_TARGET_DATA
614#include "llvm/IR/IntrinsicImpl.inc"
615#undef GET_INTRINSIC_TARGET_DATA
616
618 return IID > TargetInfos[0].Count;
619}
620
621
622
623
624
627 assert(Name.starts_with("llvm.") && "Unexpected intrinsic prefix");
628 assert(Name.drop_front(5).starts_with(Target) && "Unexpected target");
629
630
631
632
633
634
635
636
637 size_t CmpEnd = 4;
639 CmpEnd += 1 + Target.size();
640
641 const unsigned *Low = NameOffsetTable.begin();
642 const unsigned *High = NameOffsetTable.end();
643 const unsigned *LastLow = Low;
644 while (CmpEnd < Name.size() && High - Low > 0) {
645 size_t CmpStart = CmpEnd;
646 CmpEnd = Name.find('.', CmpStart + 1);
648 auto Cmp = [CmpStart, CmpEnd](auto LHS, auto RHS) {
649
650
651
652 const char *LHSStr;
653 if constexpr (std::is_integral_v<decltype(LHS)>) {
654 LHSStr = &IntrinsicNameTable[LHS];
655 } else {
656 LHSStr = LHS;
657 }
658 const char *RHSStr;
659 if constexpr (std::is_integral_v<decltype(RHS)>) {
660 RHSStr = &IntrinsicNameTable[RHS];
661 } else {
662 RHSStr = RHS;
663 }
664 return strncmp(LHSStr + CmpStart, RHSStr + CmpStart, CmpEnd - CmpStart) <
665 0;
666 };
667 LastLow = Low;
669 }
671 LastLow = Low;
672
673 if (LastLow == NameOffsetTable.end())
674 return -1;
675 StringRef NameFound = &IntrinsicNameTable[*LastLow];
676 if (Name == NameFound ||
677 (Name.starts_with(NameFound) && Name[NameFound.size()] == '.'))
678 return LastLow - NameOffsetTable.begin();
679 return -1;
680}
681
682
683
684
685
686
687static std::pair<ArrayRef, StringRef>
690
692
693
696 Targets, [=](const IntrinsicTargetInfo &TI) { return TI.Name < Target; });
697
698
699 const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0];
700 return {ArrayRef(&IntrinsicNameOffsetTable[1] + TI.Offset, TI.Count),
701 TI.Name};
702}
703
704
705
709 if (Idx == -1)
711
712
713
714 int Adjust = NameOffsetTable.data() - IntrinsicNameOffsetTable;
716
717
718
719 const auto MatchSize = strlen(&IntrinsicNameTable[NameOffsetTable[Idx]]);
720 assert(Name.size() >= MatchSize && "Expected either exact or prefix match");
721 bool IsExactMatch = Name.size() == MatchSize;
724}
725
726
727#define GET_INTRINSIC_ATTRIBUTES
728#include "llvm/IR/IntrinsicImpl.inc"
729#undef GET_INTRINSIC_ATTRIBUTES
730
733
734
735 auto *FT = getType(M->getContext(), id, Tys);
736 return cast(
737 M->getOrInsertFunction(
739 .getCallee());
740}
741
743 return M->getFunction(getName(id));
744}
745
749 return M->getFunction(getName(id, Tys, M, FT));
750}
751
752
753#define GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN
754#include "llvm/IR/IntrinsicImpl.inc"
755#undef GET_LLVM_INTRINSIC_FOR_CLANG_BUILTIN
756
757
758#define GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
759#include "llvm/IR/IntrinsicImpl.inc"
760#undef GET_LLVM_INTRINSIC_FOR_MS_BUILTIN
761
763 switch (QID) {
764#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
765 case Intrinsic::INTRINSIC:
766#include "llvm/IR/ConstrainedOps.def"
767#undef INSTRUCTION
768 return true;
769 default:
770 return false;
771 }
772}
773
775 switch (QID) {
776#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
777 case Intrinsic::INTRINSIC: \
778 return ROUND_MODE == 1;
779#include "llvm/IR/ConstrainedOps.def"
780#undef INSTRUCTION
781 default:
782 return false;
783 }
784}
785
787 std::pair<Type *, ArrayRefIntrinsic::IITDescriptor>;
788
789static bool
793 bool IsDeferredCheck) {
794 using namespace Intrinsic;
795
796
797 if (Infos.empty())
798 return true;
799
800
801 auto InfosRef = Infos;
802 auto DeferCheck = [&DeferredChecks, &InfosRef](Type *T) {
804 return false;
805 };
806
807 IITDescriptor D = Infos.front();
808 Infos = Infos.slice(1);
809
810 switch (D.Kind) {
811 case IITDescriptor::Void:
813 case IITDescriptor::VarArg:
814 return true;
815 case IITDescriptor::MMX: {
819 }
820 case IITDescriptor::AMX:
822 case IITDescriptor::Token:
824 case IITDescriptor::Metadata:
826 case IITDescriptor::Half:
828 case IITDescriptor::BFloat:
830 case IITDescriptor::Float:
832 case IITDescriptor::Double:
834 case IITDescriptor::Quad:
836 case IITDescriptor::PPCQuad:
838 case IITDescriptor::Integer:
840 case IITDescriptor::AArch64Svcount:
841 return !isa(Ty) ||
842 cast(Ty)->getName() != "aarch64.svcount";
843 case IITDescriptor::Vector: {
844 VectorType *VT = dyn_cast(Ty);
845 return !VT || VT->getElementCount() != D.Vector_Width ||
847 DeferredChecks, IsDeferredCheck);
848 }
849 case IITDescriptor::Pointer: {
850 PointerType *PT = dyn_cast(Ty);
851 return !PT || PT->getAddressSpace() != D.Pointer_AddressSpace;
852 }
853
854 case IITDescriptor::Struct: {
855 StructType *ST = dyn_cast(Ty);
856 if (!ST || !ST->isLiteral() || ST->isPacked() ||
857 ST->getNumElements() != D.Struct_NumElements)
858 return true;
859
860 for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)
862 DeferredChecks, IsDeferredCheck))
863 return true;
864 return false;
865 }
866
867 case IITDescriptor::Argument:
868
869
870 if (D.getArgumentNumber() < ArgTys.size())
871 return Ty != ArgTys[D.getArgumentNumber()];
872
873 if (D.getArgumentNumber() > ArgTys.size() ||
874 D.getArgumentKind() == IITDescriptor::AK_MatchType)
875 return IsDeferredCheck || DeferCheck(Ty);
876
877 assert(D.getArgumentNumber() == ArgTys.size() && !IsDeferredCheck &&
878 "Table consistency error");
880
881 switch (D.getArgumentKind()) {
882 case IITDescriptor::AK_Any:
883 return false;
884 case IITDescriptor::AK_AnyInteger:
886 case IITDescriptor::AK_AnyFloat:
888 case IITDescriptor::AK_AnyVector:
889 return !isa(Ty);
890 case IITDescriptor::AK_AnyPointer:
891 return !isa(Ty);
892 default:
893 break;
894 }
896
897 case IITDescriptor::ExtendArgument: {
898
899 if (D.getArgumentNumber() >= ArgTys.size())
900 return IsDeferredCheck || DeferCheck(Ty);
901
902 Type *NewTy = ArgTys[D.getArgumentNumber()];
903 if (VectorType *VTy = dyn_cast(NewTy))
904 NewTy = VectorType::getExtendedElementVectorType(VTy);
905 else if (IntegerType *ITy = dyn_cast(NewTy))
906 NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth());
907 else
908 return true;
909
910 return Ty != NewTy;
911 }
912 case IITDescriptor::TruncArgument: {
913
914 if (D.getArgumentNumber() >= ArgTys.size())
915 return IsDeferredCheck || DeferCheck(Ty);
916
917 Type *NewTy = ArgTys[D.getArgumentNumber()];
918 if (VectorType *VTy = dyn_cast(NewTy))
919 NewTy = VectorType::getTruncatedElementVectorType(VTy);
920 else if (IntegerType *ITy = dyn_cast(NewTy))
921 NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2);
922 else
923 return true;
924
925 return Ty != NewTy;
926 }
927 case IITDescriptor::HalfVecArgument:
928
929 if (D.getArgumentNumber() >= ArgTys.size())
930 return IsDeferredCheck || DeferCheck(Ty);
931 return !isa(ArgTys[D.getArgumentNumber()]) ||
932 VectorType::getHalfElementsVectorType(
933 cast(ArgTys[D.getArgumentNumber()])) != Ty;
934 case IITDescriptor::SameVecWidthArgument: {
935 if (D.getArgumentNumber() >= ArgTys.size()) {
936
937 Infos = Infos.slice(1);
938 return IsDeferredCheck || DeferCheck(Ty);
939 }
940 auto *ReferenceType = dyn_cast(ArgTys[D.getArgumentNumber()]);
941 auto *ThisArgType = dyn_cast(Ty);
942
943 if ((ReferenceType != nullptr) != (ThisArgType != nullptr))
944 return true;
945 Type *EltTy = Ty;
946 if (ThisArgType) {
947 if (ReferenceType->getElementCount() != ThisArgType->getElementCount())
948 return true;
949 EltTy = ThisArgType->getElementType();
950 }
952 IsDeferredCheck);
953 }
954 case IITDescriptor::VecOfAnyPtrsToElt: {
955 unsigned RefArgNumber = D.getRefArgNumber();
956 if (RefArgNumber >= ArgTys.size()) {
957 if (IsDeferredCheck)
958 return true;
959
960
962 return DeferCheck(Ty);
963 }
964
965 if (!IsDeferredCheck) {
966 assert(D.getOverloadArgNumber() == ArgTys.size() &&
967 "Table consistency error");
969 }
970
971
972
973
974 auto *ReferenceType = dyn_cast(ArgTys[RefArgNumber]);
975 auto *ThisArgVecTy = dyn_cast(Ty);
977 (ReferenceType->getElementCount() != ThisArgVecTy->getElementCount()))
978 return true;
979 return !ThisArgVecTy->getElementType()->isPointerTy();
980 }
981 case IITDescriptor::VecElementArgument: {
982 if (D.getArgumentNumber() >= ArgTys.size())
983 return IsDeferredCheck ? true : DeferCheck(Ty);
984 auto *ReferenceType = dyn_cast(ArgTys[D.getArgumentNumber()]);
986 }
987 case IITDescriptor::Subdivide2Argument:
988 case IITDescriptor::Subdivide4Argument: {
989
990 if (D.getArgumentNumber() >= ArgTys.size())
991 return IsDeferredCheck || DeferCheck(Ty);
992
993 Type *NewTy = ArgTys[D.getArgumentNumber()];
994 if (auto *VTy = dyn_cast(NewTy)) {
995 int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
996 NewTy = VectorType::getSubdividedVectorType(VTy, SubDivs);
997 return Ty != NewTy;
998 }
999 return true;
1000 }
1001 case IITDescriptor::VecOfBitcastsToInt: {
1002 if (D.getArgumentNumber() >= ArgTys.size())
1003 return IsDeferredCheck || DeferCheck(Ty);
1004 auto *ReferenceType = dyn_cast(ArgTys[D.getArgumentNumber()]);
1005 auto *ThisArgVecTy = dyn_cast(Ty);
1007 return true;
1008 return ThisArgVecTy != VectorType::getInteger(ReferenceType);
1009 }
1010 }
1012}
1013
1020 false))
1022
1023 unsigned NumDeferredReturnChecks = DeferredChecks.size();
1024
1025 for (auto *Ty : FTy->params())
1028
1029 for (unsigned I = 0, E = DeferredChecks.size(); I != E; ++I) {
1032 true))
1035 }
1036
1038}
1039
1042
1043 if (Infos.empty())
1044 return isVarArg;
1045
1046
1047 if (Infos.size() != 1)
1048 return true;
1049
1050
1052 Infos = Infos.slice(1);
1053 if (D.Kind == IITDescriptor::VarArg)
1054 return !isVarArg;
1055
1056 return true;
1057}
1058
1061 if ()
1062 return false;
1063
1067
1069 Intrinsic::MatchIntrinsicTypesResult::MatchIntrinsicTypes_Match) {
1070 return false;
1071 }
1073 return false;
1074 return true;
1075}
1076
1080 ArgTys);
1081}
1082
1086 return std::nullopt;
1087
1090 std::string WantedName =
1092 if (Name == WantedName)
1093 return std::nullopt;
1094
1096 if (auto *ExistingGV = F->getParent()->getNamedValue(WantedName)) {
1097 if (auto *ExistingF = dyn_cast(ExistingGV))
1098 if (ExistingF->getFunctionType() == F->getFunctionType())
1099 return ExistingF;
1100
1101
1102
1103
1104
1105 ExistingGV->setName(WantedName + ".renamed");
1106 }
1108 }();
1109
1112 "Shouldn't change the signature");
1113 return NewDecl;
1114}
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Module.h This file contains the declarations for the Module class.
static bool matchIntrinsicType(Type *Ty, ArrayRef< Intrinsic::IITDescriptor > &Infos, SmallVectorImpl< Type * > &ArgTys, SmallVectorImpl< DeferredIntrinsicMatchPair > &DeferredChecks, bool IsDeferredCheck)
static std::string getIntrinsicNameImpl(Intrinsic::ID Id, ArrayRef< Type * > Tys, Module *M, FunctionType *FT, bool EarlyModuleCheck)
std::pair< Type *, ArrayRef< Intrinsic::IITDescriptor > > DeferredIntrinsicMatchPair
static std::pair< ArrayRef< unsigned >, StringRef > findTargetSubtable(StringRef Name)
Find the segment of IntrinsicNameOffsetTable for intrinsics with the same target as Name,...
static void DecodeIITType(unsigned &NextElt, ArrayRef< unsigned char > Infos, IIT_Info LastInfo, SmallVectorImpl< Intrinsic::IITDescriptor > &OutputTable)
IIT_Info
IIT_Info - These are enumerators that describe the entries returned by the getIntrinsicInfoTableEntri...
static Type * DecodeFixedType(ArrayRef< Intrinsic::IITDescriptor > &Infos, ArrayRef< Type * > Tys, 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...
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Class to represent function types.
ArrayRef< Type * > params() const
Type * getReturnType() const
FunctionType * getFunctionType() const
Returns the FunctionType for me.
void setCallingConv(CallingConv::ID CC)
Class to represent integer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
unsigned getBitWidth() const
Get the number of bits in this 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.
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.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
static constexpr size_t npos
Class to represent struct types.
static 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 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.
The instances of the Type class are immutable: once they are created, they are never changed.
static Type * getHalfTy(LLVMContext &C)
static Type * getDoubleTy(LLVMContext &C)
static Type * getBFloatTy(LLVMContext &C)
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
static Type * getX86_AMXTy(LLVMContext &C)
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
static Type * getMetadataTy(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)
@ FP128TyID
128-bit floating point type (112-bit significand)
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
bool isFP128Ty() const
Return true if this is 'fp128'.
static Type * getVoidTy(LLVMContext &C)
static Type * getFP128Ty(LLVMContext &C)
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
static Type * getTokenTy(LLVMContext &C)
bool isX86_AMXTy() const
Return true if this is X86 AMX.
static Type * getFloatTy(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
bool isTokenTy() const
Return true if this is 'token'.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
static Type * getPPC_FP128Ty(LLVMContext &C)
bool isVoidTy() const
Return true if this is 'void'.
bool isMetadataTy() const
Return true if this is 'metadata'.
void setName(const Twine &Name)
Change the name of the value.
Type * getElementType() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
ID ArrayRef< Type * > Tys
Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
MatchIntrinsicTypesResult matchIntrinsicSignature(FunctionType *FTy, ArrayRef< IITDescriptor > &Infos, SmallVectorImpl< Type * > &ArgTys)
Match the specified function type with the type constraints specified by the .td file.
void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl< IITDescriptor > &T)
Return the IIT table descriptor for the specified intrinsic into an array of IITDescriptors.
MatchIntrinsicTypesResult
@ MatchIntrinsicTypes_Match
@ MatchIntrinsicTypes_NoMatchRet
@ MatchIntrinsicTypes_NoMatchArg
std::string getNameNoUnnamedTypes(ID Id, ArrayRef< Type * > Tys)
Return the LLVM name for an intrinsic.
std::optional< Function * > remangleIntrinsicFunction(Function *F)
bool hasConstrainedFPRoundingModeOperand(ID QID)
Returns true if the intrinsic ID is for one of the "Constrained Floating-Point Intrinsics" that take ...
StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
bool isConstrainedFPIntrinsic(ID QID)
Returns true if the intrinsic ID is for one of the "Constrained Floating-Point Intrinsics".
ID lookupIntrinsicID(StringRef Name)
This does the actual lookup of an intrinsic ID which matches the given function name.
Function * getDeclarationIfExists(Module *M, ID id, ArrayRef< Type * > Tys, FunctionType *FT=nullptr)
This version supports overloaded intrinsics.
StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
bool isOverloaded(ID id)
Returns true if the intrinsic can be overloaded.
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys={})
Return the function type for an intrinsic.
bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, SmallVectorImpl< Type * > &ArgTys)
Gets the type arguments of an intrinsic call by matching type contraints specified by the ....
bool isTargetIntrinsic(ID IID)
isTargetIntrinsic - Returns true if IID is an intrinsic specific to a certain target.
bool matchIntrinsicVarArg(bool isVarArg, ArrayRef< IITDescriptor > &Infos)
Verify if the intrinsic has variable arguments.
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.
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is 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.
Helper struct shared between Function Specialization and SCCP Solver.
This is a type descriptor which explains the type requirements of an intrinsic.