LLVM 24.0.0git
RuntimeLibcalls.cpp
Go to the documentation of this file.
1//===- RuntimeLibcalls.cpp - Interface for runtime libcalls -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/IR/Intrinsics.h"
12#include "llvm/IR/Module.h"
14#include "llvm/IR/Type.h"
16
17#define DEBUG_TYPE "runtime-libcalls-info"
18
19using namespace llvm;
20using namespace RTLIB;
21
22#define GET_RUNTIME_LIBCALLS_INFO
23#define GET_INIT_RUNTIME_LIBCALL_NAMES
24#define GET_INIT_RUNTIME_LIBCALL_SIGNATURES
25#define GET_RUNTIME_LIBCALL_ATTRIBUTES
26#define GET_RUNTIME_LIBCALL_MASKED_VECTOR_LIBCALL_MAPPING
27#define GET_SET_TARGET_RUNTIME_LIBCALL_SETS
28#define DEFINE_GET_LOOKUP_LIBCALL_IMPL_NAME
29#define GET_RUNTIME_LIBCALL_INTRINSIC_TO_LIBCALL
30#include "llvm/IR/RuntimeLibcalls.inc"
31
32static RuntimeLibrary getVectorRuntimeLibrary(VectorLibrary VecLib) {
33 switch (VecLib) {
35 break;
37 return RuntimeLibrary::accelerate;
39 return RuntimeLibrary::darwin_libsystem_m;
41 return RuntimeLibrary::libmvec;
43 return RuntimeLibrary::massv;
45 return RuntimeLibrary::svml;
47 return RuntimeLibrary::sleefgnuabi;
49 return RuntimeLibrary::armpl;
51 return RuntimeLibrary::amdlibm;
52 }
53
54 llvm_unreachable("no RuntimeLibrary for VectorLibrary");
55}
56
58 const Triple &TT, ExceptionHandling ExceptionModel,
59 FloatABI::ABIType FloatABI, std::optional<LongDoubleFormat> LDblFormat,
60 StringRef ABIName, VectorLibrary VecLib)
61 : LongDoubleFmt(LDblFormat.value_or(TT.getDefaultLongDoubleFormat())) {
62 // Only an unspecified model resolves to the triple default; None is left as
63 // an explicit disable.
64 if (ExceptionModel == ExceptionHandling::Default)
65 ExceptionModel = TT.getDefaultExceptionHandling();
66
67 initLibcalls(TT, ExceptionModel, FloatABI, ABIName, LongDoubleFmt);
68
69 if (VecLib != VectorLibrary::NoLibrary) {
70 setAvailableLibraryLibcalls(getVectorRuntimeLibrary(VecLib), TT,
71 ExceptionModel, FloatABI, ABIName,
72 LongDoubleFmt);
73 }
74}
75
76// TODO: Consider the remaining module flags.
78 VectorLibrary VecLib)
79 : RuntimeLibcallsInfo(M.getTargetTriple(), M.getExceptionModel(),
80 M.getFloatABI(), M.getLongDoubleFormat(), ABIName,
81 VecLib) {}
82
83RTLIB::Libcall RuntimeLibcallsInfo::selectLongDoubleLibcall(
84 RTLIB::Libcall F80, RTLIB::Libcall F128, RTLIB::Libcall PPCF128) const {
85 switch (LongDoubleFmt) {
87 return F80;
89 return F128;
91 return PPCF128;
94 // These long double formats aren't properly handled, but we also don't emit
95 // calls for them. TODO: We could fix the avr_sin/avr_cos hack if we handled
96 // the float case.
97 return RTLIB::UNKNOWN_LIBCALL;
98 }
99
100 llvm_unreachable("unhandled long double format");
101}
102
103bool RuntimeLibcallsInfo::isLibraryAvailable(RuntimeLibrary Library) const {
104 // TODO: Drive this from module-level state (e.g. the linked runtime). For now
105 // every named library is reported as available.
106 return true;
107}
108
109void RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(
110 const Triple &TT, ExceptionHandling ExceptionModel,
111 FloatABI::ABIType FloatABI, StringRef ABIName,
113 CallingConv::ID DefaultCC = getDefaultLibcallCallingConv(
114 TT, ExceptionModel, FloatABI, ABIName, LongDoubleFormat);
115 if (DefaultCC != CallingConv::C)
116 llvm::fill(LibcallImplCallingConvs, DefaultCC);
117
118 for (RTLIB::RuntimeLibrary Library : getDefaultRuntimeLibraries(TT)) {
119 if (isLibraryAvailable(Library))
120 setAvailableLibraryLibcalls(Library, TT, ExceptionModel, FloatABI,
121 ABIName, LongDoubleFormat);
122 }
123}
124
125/// Set default libcall names. If a target wants to opt-out of a libcall it
126/// should be placed here.
127void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
128 ExceptionHandling ExceptionModel,
129 FloatABI::ABIType FloatABI,
130 StringRef ABIName,
132 setTargetRuntimeLibcallSets(TT, ExceptionModel, FloatABI, ABIName,
134}
135
137iota_range<RTLIB::LibcallImpl>
138RuntimeLibcallsInfo::libcallImplNameHit(uint16_t NameOffsetEntry,
139 uint16_t StrOffset) {
140 int NumAliases = 1;
141 for (uint16_t Entry : ArrayRef(RuntimeLibcallNameOffsetTable)
142 .drop_front(NameOffsetEntry + 1)) {
143 if (Entry != StrOffset)
144 break;
145 ++NumAliases;
146 }
147
148 RTLIB::LibcallImpl ImplStart = static_cast<RTLIB::LibcallImpl>(
149 &RuntimeLibcallNameOffsetTable[NameOffsetEntry] -
150 &RuntimeLibcallNameOffsetTable[0]);
151 return enum_seq(ImplStart,
152 static_cast<RTLIB::LibcallImpl>(ImplStart + NumAliases));
153}
154
155bool RuntimeLibcallsInfo::isAAPCS_ABI(const Triple &TT, StringRef ABIName) {
156 const ARM::ARMABI TargetABI = ARM::computeTargetABI(TT, ABIName);
157 return TargetABI == ARM::ARM_ABI_AAPCS || TargetABI == ARM::ARM_ABI_AAPCS16;
158}
159
160// PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and
161// returns corresponding to C-level ints and unsigned ints.
162static bool shouldExtI32(const Triple &T) {
163 return T.isPPC64() || T.getArch() == Triple::sparcv9 ||
164 T.getArch() == Triple::systemz;
165}
166
167// LoongArch, Mips, and riscv64, on the other hand, need signext on i32
168// parameters corresponding to both signed and unsigned ints.
169static bool shouldSignExtI32Param(const Triple &T) {
170 return T.isLoongArch() || T.isMIPS() || T.isRISCV64();
171}
172
173// LoongArch and riscv64 need signext on i32 returns corresponding to both
174// signed and unsigned ints.
175static bool shouldSignExtI32Return(const Triple &T) {
176 return T.isLoongArch() || T.isRISCV64();
177}
178
180 bool &ShouldExtI32Return,
181 bool &ShouldSignExtI32Param,
182 bool &ShouldSignExtI32Return,
183 const Triple &T) {
184 ShouldExtI32Param = ShouldExtI32Return = shouldExtI32(T);
185 ShouldSignExtI32Param = shouldSignExtI32Param(T);
186 ShouldSignExtI32Return = shouldSignExtI32Return(T);
187}
188
189static bool shouldZExtBool(const Triple &T) {
190 return !T.isAArch64() && !T.isOSDarwin();
191}
192
194 bool &ShouldZExtBoolParam, bool &ShouldZExtBoolReturn, const Triple &T) {
195 ShouldZExtBoolParam = ShouldZExtBoolReturn = shouldZExtBool(T);
196}
197
198/// TODO: There is really no guarantee that sizeof(size_t) is equal to the index
199/// size of the default address space. This matches TargetLibraryInfo and should
200/// be kept in sync.
202 return DL.getIndexType(Ctx, /*AddressSpace=*/0);
203}
204
205static unsigned getIntSize(const Triple &TT) {
207}
208
209static unsigned getLongSize(const Triple &TT, const DataLayout &DL) {
210 if (TT.isOSWindowsOrUEFI() && !TT.isWindowsCygwinEnvironment())
211 return 32;
212 return std::max(32u, DL.getPointerSizeInBits(/*AS=*/0));
213}
214
215// TODO: NoCallback probably unsafe in general
216static constexpr Attribute::AttrKind CommonFnAttrs[] = {
217 Attribute::NoCallback, Attribute::NoFree, Attribute::NoSync,
218 Attribute::NoUnwind, Attribute::WillReturn};
219
221 switch (Format) {
223 return Type::getFloatTy(Ctx);
225 return Type::getDoubleTy(Ctx);
227 return Type::getX86_FP80Ty(Ctx);
229 return Type::getFP128Ty(Ctx);
231 return Type::getPPC_FP128Ty(Ctx);
232 }
233
234 llvm_unreachable("unhandled long double format");
235}
236
237static Type *getInt128Type(LLVMContext &Ctx, const Triple &TT) {
238 if (TT.isOSWindowsOrUEFI() && TT.isX86_64())
240 return Type::getInt128Ty(Ctx);
241}
242
243static Type *convertToIRType(FuncArgTypeID ID, LLVMContext &Ctx,
244 const Triple &TT, const DataLayout &DL,
245 LongDoubleFormat LdblFormat) {
246 // FIXME: Use the llvm/ABI library to get accurate IR types and attributes.
247 switch (ID) {
248 case Void:
249 return Type::getVoidTy(Ctx);
250 case Bool:
251 return IntegerType::get(Ctx, 1);
252 case Int8:
253 case UInt8:
254 return IntegerType::get(Ctx, 8);
255 case Int16:
256 case UInt16:
257 return IntegerType::get(Ctx, 16);
258 case Int32:
259 case UInt32:
260 return IntegerType::get(Ctx, 32);
261 case Int:
262 case UInt:
263 case IntPlus:
264 case UIntPlus:
265 case IntX:
266 case UIntX:
267 return IntegerType::get(Ctx, getIntSize(TT));
268 case Long:
269 case ULong:
270 return IntegerType::get(Ctx, getLongSize(TT, DL));
271 case Int64:
272 case UInt64:
273 case LLong:
274 case ULLong:
275 return IntegerType::get(Ctx, 64);
276 case Int128:
277 case UInt128:
278 return getInt128Type(Ctx, TT);
279 case SizeT:
280 case SSizeT:
281 return getSizeTType(Ctx, DL);
282 case CmpResult:
283 if (TT.isAArch64() || TT.isAMDGPU() || TT.isWasm())
284 return Type::getInt32Ty(Ctx);
285 if (TT.isAVR())
286 return Type::getInt8Ty(Ctx);
287 return IntegerType::get(Ctx, TT.getArchPointerBitWidth());
288 case Half:
289 return Type::getHalfTy(Ctx);
290 case BFloat:
291 return Type::getBFloatTy(Ctx);
292 case Flt:
293 case Floating:
294 return Type::getFloatTy(Ctx);
295 case Dbl:
296 return Type::getDoubleTy(Ctx);
297 case LDbl:
298 return getLongDoubleType(Ctx, LdblFormat);
299 case X86FP80:
300 return Type::getX86_FP80Ty(Ctx);
301 case FP128:
302 return Type::getFP128Ty(Ctx);
303 case PPCFP128:
304 return Type::getPPC_FP128Ty(Ctx);
305 case Ptr:
306 return PointerType::get(Ctx, 0);
307 case AllocaPtr:
308 return DL.getAllocaPtrType(Ctx);
309 case V2F32:
311 case V4F32:
313 case V8F32:
315 case V16F32:
316 return FixedVectorType::get(Type::getFloatTy(Ctx), 16);
317 case NXV4F32:
319 case V2F64:
321 case V4F64:
323 case V8F64:
325 case NXV2F64:
327 case NXV2I1:
329 case NXV4I1:
331 case V2I32:
333 case V4I32:
335 case V8I32:
337 case V16I32:
338 return FixedVectorType::get(Type::getInt32Ty(Ctx), 16);
339 case NXV2I32:
341 case NXV4I32:
343 default:
344 break;
345 }
346
347 ArrayRef<FuncArgTypeID> EltIDs = getStructElementTypes(ID);
348 if (EltIDs.empty())
349 return nullptr;
350
352 for (FuncArgTypeID EltID : EltIDs)
353 EltTys.push_back(convertToIRType(EltID, Ctx, TT, DL, LdblFormat));
354 return StructType::get(Ctx, EltTys);
355}
356
357static std::optional<bool> isSignedIntArgType(FuncArgTypeID ID) {
358 switch (ID) {
359 case Int8:
360 case Int16:
361 case Int32:
362 case Int:
363 case IntPlus:
364 case Long:
365 case Int64:
366 case LLong:
367 case Int128:
368 case SSizeT:
369 return true;
370 case UInt8:
371 case UInt16:
372 case UInt32:
373 case UInt:
374 case UIntPlus:
375 case ULong:
376 case UIntX:
377 case UInt64:
378 case ULLong:
379 case UInt128:
380 case SizeT:
381 return false;
382 default:
383 return std::nullopt;
384 }
385}
386
387static Attribute::AttrKind getIntExtAttr(FuncArgTypeID ID, Type *Ty,
388 const Triple &TT, bool IsReturn) {
389 if (ID == Bool)
390 return shouldZExtBool(TT) ? Attribute::ZExt : Attribute::None;
391
392 std::optional<bool> Signed = isSignedIntArgType(ID);
393 if (!Signed || !Ty->isIntegerTy())
394 return Attribute::None;
395
396 // All targets currently extend types narrower than int according to their
397 // signedness, but this could become target dependent if a target needs it.
398 unsigned Bits = Ty->getIntegerBitWidth();
399 unsigned IntBits = getIntSize(TT);
400
401 if (Bits < IntBits)
402 return *Signed ? Attribute::SExt : Attribute::ZExt;
403 if (Bits != 32 || IntBits != 32)
404 return Attribute::None;
405 if (shouldExtI32(TT))
406 return *Signed ? Attribute::SExt : Attribute::ZExt;
407 if (IsReturn ? shouldSignExtI32Return(TT) : shouldSignExtI32Param(TT))
408 return Attribute::SExt;
409 return Attribute::None;
410}
411
412std::pair<FunctionType *, AttributeList>
414 LLVMContext &Ctx, const Triple &TT, const DataLayout &DL,
415 RTLIB::LibcallImpl LibcallImpl) const {
416 const FuncArgTypeID *ProtoTypes =
417 &SignatureTable[SignatureOffset[LibcallImpl]];
418
419 if (ProtoTypes[0] == NoFuncArgType || ProtoTypes[0] == Variable ||
420 ProtoTypes[0] == ThreadLocalVariable)
421 return {};
422
423 FuncArgTypeID LastID = ProtoTypes[0];
424 Type *RetTy = convertToIRType(LastID, Ctx, TT, DL, LongDoubleFmt);
425 AttributeSet RetAttrs;
426 if (Attribute::AttrKind AK =
427 getIntExtAttr(LastID, RetTy, TT, /*IsReturn=*/true))
428 RetAttrs = AttributeSet::get(Ctx, Attribute::get(Ctx, AK));
429 if (isInRegStruct(LastID))
430 RetAttrs = RetAttrs.addAttribute(Ctx, Attribute::InReg);
431
434 bool IsVarArg = false;
435 unsigned Idx = 1;
436 for (FuncArgTypeID TyID = ProtoTypes[Idx]; TyID != NoFuncArgType;
437 TyID = ProtoTypes[++Idx]) {
438 if (TyID == Ellip) {
439 // The ellipsis ends the protoype list so it must be followed by
440 // NoFuncArgType.
441 assert(ProtoTypes[Idx + 1] == NoFuncArgType);
442 IsVarArg = true;
443 break;
444 }
445
446 if (TyID == Same)
447 TyID = LastID;
448 else
449 LastID = TyID;
450
451 Type *ArgTy = convertToIRType(TyID, Ctx, TT, DL, LongDoubleFmt);
452 ArgTys.push_back(ArgTy);
453
454 AttributeSet ArgAttrSet;
455 if (Attribute::AttrKind AK =
456 getIntExtAttr(TyID, ArgTy, TT, /*IsReturn=*/false))
457 ArgAttrSet = AttributeSet::get(Ctx, Attribute::get(Ctx, AK));
458 ArgAttrs.push_back(ArgAttrSet);
459 }
460
461 for (const LibcallArgAttrs &Static :
462 getLibcallImplArgAttributes(LibcallImpl)) {
463 assert(Static.ArgNo < ArgAttrs.size() &&
464 "attributes for nonexistent argument");
465 AttributeSet StaticAttrs = getLibcallArgAttributeSet(Ctx, Static.AttrSetID);
466 if (Static.PointeeType != NoFuncArgType) {
467 Type *PointeeTy =
468 convertToIRType(Static.PointeeType, Ctx, TT, DL, LongDoubleFmt);
469 Type *AlignTy =
470 Static.AlignToElement ? PointeeTy->getScalarType() : PointeeTy;
471 SmallVector<Attribute, 2> PointeeAttrs = {
472 Attribute::getWithAlignment(Ctx, DL.getABITypeAlign(AlignTy))};
473 TypeSize Size = DL.getTypeStoreSize(PointeeTy);
474 if (!Size.isScalable()) {
475 PointeeAttrs.push_back(
476 Attribute::getWithDereferenceableBytes(Ctx, Size.getFixedValue()));
477 }
478
479 StaticAttrs = StaticAttrs.addSortedAttributes(Ctx, PointeeAttrs);
480 }
481
482 AttributeSet &ArgAttrSet = ArgAttrs[Static.ArgNo];
483 ArgAttrSet = ArgAttrSet.addAttributes(Ctx, StaticAttrs);
484 }
485
486 return {FunctionType::get(RetTy, ArgTys, IsVarArg),
487 AttributeList::get(Ctx, getLibcallImplFnAttributes(Ctx, LibcallImpl),
488 RetAttrs, ArgAttrs)};
489}
490
491Type *
493 const DataLayout &DL,
494 RTLIB::LibcallImpl LibcallImpl) const {
495 const FuncArgTypeID *ProtoTypes =
496 &SignatureTable[SignatureOffset[LibcallImpl]];
497 if (ProtoTypes[0] != Variable && ProtoTypes[0] != ThreadLocalVariable)
498 return nullptr;
499 return convertToIRType(ProtoTypes[1], Ctx, TT, DL, LongDoubleFmt);
500}
501
502std::pair<FunctionType *, AttributeList>
504 const DataLayout &DL,
505 RTLIB::LibcallImpl LibcallImpl) const {
506 static constexpr Attribute::AttrKind MemoryFnAttrs[] = {
507 Attribute::NoUnwind, Attribute::WillReturn};
508 static constexpr Attribute::AttrKind CommonPtrArgAttrs[] = {
509 Attribute::NoAlias, Attribute::WriteOnly, Attribute::NonNull};
510
511 switch (LibcallImpl) {
512 // FIXME: Should also include __sincospi[f]_stret
513 case RTLIB::impl___sincos_stret:
514 case RTLIB::impl___sincosf_stret: {
515 if (!darwinHasSinCosStret(TT)) // Non-darwin currently unexpected
516 return {};
517
518 Type *ScalarTy = LibcallImpl == RTLIB::impl___sincosf_stret
519 ? Type::getFloatTy(Ctx)
520 : Type::getDoubleTy(Ctx);
521
522 AttrBuilder FuncAttrBuilder(Ctx);
524 FuncAttrBuilder.addAttribute(Attr);
525
526 const bool UseSret =
527 TT.isX86_32() || ((TT.isARM() || TT.isThumb()) &&
529
530 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argMemOnly(
532
533 AttributeList Attrs;
534 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
535
536 if (UseSret) {
537 AttrBuilder AttrBuilder(Ctx);
538 StructType *StructTy = StructType::get(ScalarTy, ScalarTy);
539 AttrBuilder.addStructRetAttr(StructTy);
540 AttrBuilder.addAlignmentAttr(DL.getABITypeAlign(StructTy));
542 Type::getVoidTy(Ctx), {DL.getAllocaPtrType(Ctx), ScalarTy}, false);
543
544 return {FuncTy, Attrs.addParamAttributes(Ctx, 0, AttrBuilder)};
545 }
546
547 Type *RetTy =
548 LibcallImpl == RTLIB::impl___sincosf_stret && TT.isX86_64()
549 ? static_cast<Type *>(FixedVectorType::get(ScalarTy, 2))
550 : static_cast<Type *>(StructType::get(ScalarTy, ScalarTy));
551
552 return {FunctionType::get(RetTy, {ScalarTy}, false), Attrs};
553 }
554 case RTLIB::impl_malloc:
555 case RTLIB::impl_calloc: {
556 AttrBuilder FuncAttrBuilder(Ctx);
557 for (Attribute::AttrKind Attr : MemoryFnAttrs)
558 FuncAttrBuilder.addAttribute(Attr);
559 FuncAttrBuilder.addAttribute(Attribute::NoFree);
560
562 if (LibcallImpl == RTLIB::impl_malloc)
563 AllocKind |= AllocFnKind::Uninitialized;
564
565 // TODO: Set memory attribute
566 FuncAttrBuilder.addAllocKindAttr(AllocKind);
567 FuncAttrBuilder.addAttribute("alloc-family", "malloc");
568 FuncAttrBuilder.addAllocSizeAttr(0, LibcallImpl == RTLIB::impl_malloc
569 ? std::nullopt
570 : std::make_optional(1));
571
572 AttributeList Attrs;
573 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
574
575 {
576 AttrBuilder ArgAttrBuilder(Ctx);
577 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
578 ArgAttrBuilder.addAttribute(AK);
579
580 Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoUndef);
581 Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoAlias);
582 Attrs = Attrs.addParamAttribute(Ctx, 0, Attribute::NoUndef);
583 if (LibcallImpl == RTLIB::impl_calloc)
584 Attrs = Attrs.addParamAttribute(Ctx, 1, Attribute::NoUndef);
585 }
586
587 IntegerType *SizeT = getSizeTType(Ctx, DL);
588 PointerType *PtrTy = PointerType::get(Ctx, 0);
589 SmallVector<Type *, 2> ArgTys = {SizeT};
590 if (LibcallImpl == RTLIB::impl_calloc)
591 ArgTys.push_back(SizeT);
592
593 return {FunctionType::get(PtrTy, ArgTys, false), Attrs};
594 }
595 case RTLIB::impl_free: {
596 // TODO: Set memory attribute
597 AttrBuilder FuncAttrBuilder(Ctx);
598 for (Attribute::AttrKind Attr : MemoryFnAttrs)
599 FuncAttrBuilder.addAttribute(Attr);
600
601 FuncAttrBuilder.addAllocKindAttr(AllocFnKind::Free);
602 FuncAttrBuilder.addAttribute("alloc-family", "malloc");
603
604 AttributeList Attrs;
605 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
606
607 {
608 AttrBuilder ArgAttrBuilder(Ctx);
609 ArgAttrBuilder.addAttribute(Attribute::NoUndef);
610 ArgAttrBuilder.addAttribute(Attribute::AllocatedPointer);
611 ArgAttrBuilder.addCapturesAttr(CaptureInfo::none());
612 Attrs = Attrs.addParamAttributes(Ctx, 0, ArgAttrBuilder);
613 }
614
615 return {FunctionType::get(Type::getVoidTy(Ctx), {PointerType::get(Ctx, 0)},
616 false),
617 Attrs};
618 }
619 case RTLIB::impl___aeabi_idivmod:
620 case RTLIB::impl___aeabi_uidivmod:
621 case RTLIB::impl___aeabi_ldivmod:
622 case RTLIB::impl___aeabi_uldivmod:
623 case RTLIB::impl___rt_sdiv:
624 case RTLIB::impl___rt_udiv:
625 case RTLIB::impl___rt_sdiv64:
626 case RTLIB::impl___rt_udiv64:
627 case RTLIB::impl___divmodqi4:
628 case RTLIB::impl___udivmodqi4:
629 case RTLIB::impl___divmodhi4:
630 case RTLIB::impl___udivmodhi4:
631 case RTLIB::impl_avr___divmodsi4:
632 case RTLIB::impl_avr___udivmodsi4: {
633 auto [FuncTy, Attrs] = getDefaultFunctionTy(Ctx, TT, DL, LibcallImpl);
634 AttrBuilder FuncAttrBuilder(Ctx);
636 FuncAttrBuilder.addAttribute(Attr);
637 FuncAttrBuilder.addMemoryAttr(MemoryEffects::none());
638 return {FuncTy, Attrs.addFnAttributes(Ctx, FuncAttrBuilder)};
639 }
640 case RTLIB::impl_sqrtf:
641 case RTLIB::impl_sqrt: {
642 AttrBuilder FuncAttrBuilder(Ctx);
643
645 FuncAttrBuilder.addAttribute(Attr);
646 FuncAttrBuilder.addMemoryAttr(MemoryEffects::errnoMemOnly(ModRefInfo::Mod));
647
648 AttributeList Attrs;
649 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
650
651 Type *ScalarTy = LibcallImpl == RTLIB::impl_sqrtf ? Type::getFloatTy(Ctx)
652 : Type::getDoubleTy(Ctx);
653 FunctionType *FuncTy = FunctionType::get(ScalarTy, {ScalarTy}, false);
654
655 Attrs = Attrs.addRetAttribute(
657 fcNegNormal));
658 return {FuncTy, Attrs};
659 }
660 default:
661 break;
662 }
663
664 return getDefaultFunctionTy(Ctx, TT, DL, LibcallImpl);
665}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
constexpr LLT V2F32
constexpr LLT V2F64
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do so, mark a method "always...
Definition Compiler.h:376
Utilities for dealing with flags related to floating point properties and mode controls.
Module.h This file contains the declarations for the Module class.
#define T
static Type * convertToIRType(FuncArgTypeID ID, LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, LongDoubleFormat LdblFormat)
static Type * getLongDoubleType(LLVMContext &Ctx, LongDoubleFormat Format)
static bool shouldZExtBool(const Triple &T)
static IntegerType * getSizeTType(LLVMContext &Ctx, const DataLayout &DL)
TODO: There is really no guarantee that sizeof(size_t) is equal to the index size of the default addr...
static bool shouldExtI32(const Triple &T)
static RuntimeLibrary getVectorRuntimeLibrary(VectorLibrary VecLib)
static Attribute::AttrKind getIntExtAttr(FuncArgTypeID ID, Type *Ty, const Triple &TT, bool IsReturn)
static Type * getInt128Type(LLVMContext &Ctx, const Triple &TT)
static constexpr Attribute::AttrKind CommonFnAttrs[]
static bool shouldSignExtI32Param(const Triple &T)
static unsigned getIntSize(const Triple &TT)
static bool shouldSignExtI32Return(const Triple &T)
static std::optional< bool > isSignedIntArgType(FuncArgTypeID ID)
static unsigned getLongSize(const Triple &TT, const DataLayout &DL)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
This class holds the attributes for a particular argument, parameter, function, or return value.
Definition Attributes.h:406
LLVM_ABI AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const
Add attributes to the attribute set.
LLVM_ABI AttributeSet addSortedAttributes(LLVMContext &C, ArrayRef< Attribute > Attrs) const
Add attributes to the attribute set, replacing attributes of the same kind.
static LLVM_ABI AttributeSet get(LLVMContext &C, const AttrBuilder &B)
LLVM_ABI AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add an argument attribute.
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
static LLVM_ABI Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
static LLVM_ABI Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:125
@ None
No attributes have been set.
Definition Attributes.h:127
static LLVM_ABI Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:427
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
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.
Class to represent integer types.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
static MemoryEffectsBase errnoMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:154
static MemoryEffectsBase none()
Definition ModRef.h:128
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Class to represent pointers.
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:887
static LLVM_ABI ScalableVectorType * get(Type *ElementType, unsigned MinNumElts)
Definition Type.cpp:865
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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.
Definition Type.cpp:467
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:300
static LLVM_ABI IntegerType * getInt128Ty(LLVMContext &C)
Definition Type.cpp:301
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
static LLVM_ABI Type * getPPC_FP128Ty(LLVMContext &C)
Definition Type.cpp:282
static LLVM_ABI Type * getFP128Ty(LLVMContext &C)
Definition Type.cpp:281
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:277
static LLVM_ABI Type * getX86_FP80Ty(LLVMContext &C)
Definition Type.cpp:280
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:276
static LLVM_ABI Type * getBFloatTy(LLVMContext &C)
Definition Type.cpp:275
static LLVM_ABI Type * getHalfTy(LLVMContext &C)
Definition Type.cpp:274
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI LLVM_READONLY ARMABI computeTargetABI(const Triple &TT, StringRef ABIName="")
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
void fill(R &&Range, T &&Value)
Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1775
AllocFnKind
Definition Attributes.h:54
LongDoubleFormat
The floating-point format used for the target's "long double" type.
Definition CodeGen.h:117
constexpr auto enum_seq(EnumT Begin, EnumT End)
Iterate over an enum type from Begin up to - but not including - End.
Definition Sequence.h:373
@ Mod
The access may modify the value stored in memory.
Definition ModRef.h:34
@ NoModRef
The access neither references nor modifies the value stored in memory.
Definition ModRef.h:30
ArrayRef(const T &OneElt) -> ArrayRef< T >
ExceptionHandling
Definition CodeGen.h:54
@ Default
Not specified; resolve to the target's default model.
Definition CodeGen.h:55
VectorLibrary
List of known vector-functions libraries.
static LLVM_ABI ArrayRef< RTLIB::RuntimeLibrary > getDefaultRuntimeLibraries(const Triple &TT)
Return the runtime libraries enabled by default for TT.
static unsigned getIntSize(const Triple &TT)
Get size of a C-level int or unsigned int, in bits.
LLVM_ABI Type * getVariableType(LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, RTLIB::LibcallImpl LibcallImpl) const
LLVM_ABI std::pair< FunctionType *, AttributeList > getFunctionTy(LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, RTLIB::LibcallImpl LibcallImpl) const
static LLVM_ABI void initExtensionsForTriple(bool &ShouldExtI32Param, bool &ShouldExtI32Return, bool &ShouldSignExtI32Param, bool &ShouldSignExtI32Return, const Triple &T)
Determine the extension attributes needed for i32 parameters and returns corresponding to C-level int...
static LLVM_ABI void initBoolExtensionsForTriple(bool &ShouldZExtBoolParam, bool &ShouldZExtBoolReturn, const Triple &T)
Determine whether bool parameters and returns need zeroext on T.
LLVM_ABI std::pair< FunctionType *, AttributeList > getDefaultFunctionTy(LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, RTLIB::LibcallImpl LibcallImpl) const
Get the C-type function signature of the Libcall if provided, and convert it to IR FunctionType and A...