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_MASKED_VECTOR_LIBCALL_MAPPING
26#define GET_SET_TARGET_RUNTIME_LIBCALL_SETS
27#define DEFINE_GET_LOOKUP_LIBCALL_IMPL_NAME
28#define GET_RUNTIME_LIBCALL_INTRINSIC_TO_LIBCALL
29#include "llvm/IR/RuntimeLibcalls.inc"
30
31static RuntimeLibrary getVectorRuntimeLibrary(VectorLibrary VecLib) {
32 switch (VecLib) {
34 break;
36 return RuntimeLibrary::accelerate;
38 return RuntimeLibrary::darwin_libsystem_m;
40 return RuntimeLibrary::libmvec;
42 return RuntimeLibrary::massv;
44 return RuntimeLibrary::svml;
46 return RuntimeLibrary::sleefgnuabi;
48 return RuntimeLibrary::armpl;
50 return RuntimeLibrary::amdlibm;
51 }
52
53 llvm_unreachable("no RuntimeLibrary for VectorLibrary");
54}
55
57 const Triple &TT, ExceptionHandling ExceptionModel,
58 FloatABI::ABIType FloatABI, std::optional<LongDoubleFormat> LDblFormat,
59 StringRef ABIName, VectorLibrary VecLib)
60 : LongDoubleFmt(LDblFormat.value_or(TT.getDefaultLongDoubleFormat())) {
61 // Only an unspecified model resolves to the triple default; None is left as
62 // an explicit disable.
63 if (ExceptionModel == ExceptionHandling::Default)
64 ExceptionModel = TT.getDefaultExceptionHandling();
65
66 initLibcalls(TT, ExceptionModel, FloatABI, ABIName, LongDoubleFmt);
67
68 if (VecLib != VectorLibrary::NoLibrary) {
69 setAvailableLibraryLibcalls(getVectorRuntimeLibrary(VecLib), TT,
70 ExceptionModel, FloatABI, ABIName,
71 LongDoubleFmt);
72 }
73}
74
75// TODO: Consider the remaining module flags.
77 VectorLibrary VecLib)
78 : RuntimeLibcallsInfo(M.getTargetTriple(), M.getExceptionModel(),
79 M.getFloatABI(), M.getLongDoubleFormat(), ABIName,
80 VecLib) {}
81
82RTLIB::Libcall RuntimeLibcallsInfo::selectLongDoubleLibcall(
83 RTLIB::Libcall F80, RTLIB::Libcall F128, RTLIB::Libcall PPCF128) const {
84 switch (LongDoubleFmt) {
86 return F80;
88 return F128;
90 return PPCF128;
93 // These long double formats aren't properly handled, but we also don't emit
94 // calls for them. TODO: We could fix the avr_sin/avr_cos hack if we handled
95 // the float case.
96 return RTLIB::UNKNOWN_LIBCALL;
97 }
98
99 llvm_unreachable("unhandled long double format");
100}
101
102bool RuntimeLibcallsInfo::isLibraryAvailable(RuntimeLibrary Library) const {
103 // TODO: Drive this from module-level state (e.g. the linked runtime). For now
104 // every named library is reported as available.
105 return true;
106}
107
108void RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(
109 const Triple &TT, ExceptionHandling ExceptionModel,
110 FloatABI::ABIType FloatABI, StringRef ABIName,
112 CallingConv::ID DefaultCC = getDefaultLibcallCallingConv(
113 TT, ExceptionModel, FloatABI, ABIName, LongDoubleFormat);
114 if (DefaultCC != CallingConv::C)
115 llvm::fill(LibcallImplCallingConvs, DefaultCC);
116
117 for (RTLIB::RuntimeLibrary Library : getDefaultRuntimeLibraries(TT)) {
118 if (isLibraryAvailable(Library))
119 setAvailableLibraryLibcalls(Library, TT, ExceptionModel, FloatABI,
120 ABIName, LongDoubleFormat);
121 }
122}
123
124/// Set default libcall names. If a target wants to opt-out of a libcall it
125/// should be placed here.
126void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
127 ExceptionHandling ExceptionModel,
128 FloatABI::ABIType FloatABI,
129 StringRef ABIName,
131 setTargetRuntimeLibcallSets(TT, ExceptionModel, FloatABI, ABIName,
133}
134
136iota_range<RTLIB::LibcallImpl>
137RuntimeLibcallsInfo::libcallImplNameHit(uint16_t NameOffsetEntry,
138 uint16_t StrOffset) {
139 int NumAliases = 1;
140 for (uint16_t Entry : ArrayRef(RuntimeLibcallNameOffsetTable)
141 .drop_front(NameOffsetEntry + 1)) {
142 if (Entry != StrOffset)
143 break;
144 ++NumAliases;
145 }
146
147 RTLIB::LibcallImpl ImplStart = static_cast<RTLIB::LibcallImpl>(
148 &RuntimeLibcallNameOffsetTable[NameOffsetEntry] -
149 &RuntimeLibcallNameOffsetTable[0]);
150 return enum_seq(ImplStart,
151 static_cast<RTLIB::LibcallImpl>(ImplStart + NumAliases));
152}
153
154bool RuntimeLibcallsInfo::isAAPCS_ABI(const Triple &TT, StringRef ABIName) {
155 const ARM::ARMABI TargetABI = ARM::computeTargetABI(TT, ABIName);
156 return TargetABI == ARM::ARM_ABI_AAPCS || TargetABI == ARM::ARM_ABI_AAPCS16;
157}
158
159// PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and
160// returns corresponding to C-level ints and unsigned ints.
161static bool shouldExtI32(const Triple &T) {
162 return T.isPPC64() || T.getArch() == Triple::sparcv9 ||
163 T.getArch() == Triple::systemz;
164}
165
166// LoongArch, Mips, and riscv64, on the other hand, need signext on i32
167// parameters corresponding to both signed and unsigned ints.
168static bool shouldSignExtI32Param(const Triple &T) {
169 return T.isLoongArch() || T.isMIPS() || T.isRISCV64();
170}
171
172// LoongArch and riscv64 need signext on i32 returns corresponding to both
173// signed and unsigned ints.
174static bool shouldSignExtI32Return(const Triple &T) {
175 return T.isLoongArch() || T.isRISCV64();
176}
177
179 bool &ShouldExtI32Return,
180 bool &ShouldSignExtI32Param,
181 bool &ShouldSignExtI32Return,
182 const Triple &T) {
183 ShouldExtI32Param = ShouldExtI32Return = shouldExtI32(T);
184 ShouldSignExtI32Param = shouldSignExtI32Param(T);
185 ShouldSignExtI32Return = shouldSignExtI32Return(T);
186}
187
188static bool shouldZExtBool(const Triple &T) {
189 return !T.isAArch64() && !T.isOSDarwin();
190}
191
193 bool &ShouldZExtBoolParam, bool &ShouldZExtBoolReturn, const Triple &T) {
194 ShouldZExtBoolParam = ShouldZExtBoolReturn = shouldZExtBool(T);
195}
196
197/// TODO: There is really no guarantee that sizeof(size_t) is equal to the index
198/// size of the default address space. This matches TargetLibraryInfo and should
199/// be kept in sync.
201 return DL.getIndexType(Ctx, /*AddressSpace=*/0);
202}
203
204static unsigned getLongSize(const Triple &TT, const DataLayout &DL) {
205 if (TT.isOSWindowsOrUEFI() && !TT.isWindowsCygwinEnvironment())
206 return 32;
207 return std::max(32u, DL.getPointerSizeInBits(/*AS=*/0));
208}
209
210// TODO: NoCallback probably unsafe in general
211static constexpr Attribute::AttrKind CommonFnAttrs[] = {
212 Attribute::NoCallback, Attribute::NoFree, Attribute::NoSync,
213 Attribute::NoUnwind, Attribute::WillReturn};
214
216 switch (Format) {
218 return Type::getFloatTy(Ctx);
220 return Type::getDoubleTy(Ctx);
222 return Type::getX86_FP80Ty(Ctx);
224 return Type::getFP128Ty(Ctx);
226 return Type::getPPC_FP128Ty(Ctx);
227 }
228
229 llvm_unreachable("unhandled long double format");
230}
231
232static Type *convertToIRType(FuncArgTypeID ID, LLVMContext &Ctx,
233 const Triple &TT, const DataLayout &DL,
234 unsigned IntBits, LongDoubleFormat LdblFormat) {
235 // FIXME: Use the llvm/ABI library to get accurate IR types and attributes.
236 switch (ID) {
237 case Void:
238 return Type::getVoidTy(Ctx);
239 case Bool:
240 return IntegerType::get(Ctx, 1);
241 case Int8:
242 case UInt8:
243 return IntegerType::get(Ctx, 8);
244 case Int16:
245 case UInt16:
246 return IntegerType::get(Ctx, 16);
247 case Int32:
248 case UInt32:
249 return IntegerType::get(Ctx, 32);
250 case Int:
251 case UInt:
252 case IntPlus:
253 case UIntPlus:
254 case IntX:
255 case UIntX:
256 return IntegerType::get(Ctx, IntBits);
257 case Long:
258 case ULong:
259 return IntegerType::get(Ctx, getLongSize(TT, DL));
260 case Int64:
261 case UInt64:
262 case LLong:
263 case ULLong:
264 return IntegerType::get(Ctx, 64);
265 case Int128:
266 case UInt128:
267 return IntegerType::get(Ctx, 128);
268 case SizeT:
269 case SSizeT:
270 return getSizeTType(Ctx, DL);
271 case Flt:
272 case Floating:
273 return Type::getFloatTy(Ctx);
274 case Dbl:
275 return Type::getDoubleTy(Ctx);
276 case LDbl:
277 return getLongDoubleType(Ctx, LdblFormat);
278 case X86FP80:
279 return Type::getX86_FP80Ty(Ctx);
280 case FP128:
281 return Type::getFP128Ty(Ctx);
282 case PPCFP128:
283 return Type::getPPC_FP128Ty(Ctx);
284 case Ptr:
285 return PointerType::get(Ctx, 0);
286 case V2F32:
288 case V4F32:
290 case V8F32:
292 case V16F32:
293 return FixedVectorType::get(Type::getFloatTy(Ctx), 16);
294 case NXV4F32:
296 case V2F64:
298 case V4F64:
300 case V8F64:
302 case NXV2F64:
304 case NXV2I1:
306 case NXV4I1:
308 case V2I32:
310 case V4I32:
312 case V8I32:
314 case V16I32:
315 return FixedVectorType::get(Type::getInt32Ty(Ctx), 16);
316 case NXV2I32:
318 case NXV4I32:
320 default:
321 return nullptr;
322 }
323}
324
325static std::optional<bool> isSignedIntArgType(FuncArgTypeID ID) {
326 switch (ID) {
327 case Int8:
328 case Int16:
329 case Int32:
330 case Int:
331 case IntPlus:
332 case Long:
333 case Int64:
334 case LLong:
335 case Int128:
336 case SSizeT:
337 return true;
338 case UInt8:
339 case UInt16:
340 case UInt32:
341 case UInt:
342 case UIntPlus:
343 case ULong:
344 case UIntX:
345 case UInt64:
346 case ULLong:
347 case UInt128:
348 case SizeT:
349 return false;
350 default:
351 return std::nullopt;
352 }
353}
354
355static Attribute::AttrKind getIntExtAttr(FuncArgTypeID ID, Type *Ty,
356 const Triple &TT, unsigned IntBits,
357 bool IsReturn) {
358 if (ID == Bool)
359 return shouldZExtBool(TT) ? Attribute::ZExt : Attribute::None;
360
361 std::optional<bool> Signed = isSignedIntArgType(ID);
362 if (!Signed)
363 return Attribute::None;
364
365 // All targets currently extend types narrower than int according to their
366 // signedness, but this could become target dependent if a target needs it.
367 unsigned Bits = Ty->getIntegerBitWidth();
368 if (Bits < IntBits)
369 return *Signed ? Attribute::SExt : Attribute::ZExt;
370 if (Bits != 32 || IntBits != 32)
371 return Attribute::None;
372 if (shouldExtI32(TT))
373 return *Signed ? Attribute::SExt : Attribute::ZExt;
374 if (IsReturn ? shouldSignExtI32Return(TT) : shouldSignExtI32Param(TT))
375 return Attribute::SExt;
376 return Attribute::None;
377}
378
379std::pair<FunctionType *, AttributeList>
381 LLVMContext &Ctx, const Triple &TT, const DataLayout &DL,
382 RTLIB::LibcallImpl LibcallImpl) const {
383 const FuncArgTypeID *ProtoTypes =
384 &SignatureTable[SignatureOffset[LibcallImpl]];
385
386 if (ProtoTypes[0] == NoFuncArgType)
387 return {};
388
389 unsigned IntBits = getIntSize(TT);
390 AttributeList Attrs;
391
392 FuncArgTypeID LastID = ProtoTypes[0];
393 Type *RetTy = convertToIRType(LastID, Ctx, TT, DL, IntBits, LongDoubleFmt);
394 if (Attribute::AttrKind AK =
395 getIntExtAttr(LastID, RetTy, TT, IntBits, /*IsReturn=*/true))
396 Attrs = Attrs.addRetAttribute(Ctx, AK);
397
399 bool IsVarArg = false;
400 unsigned Idx = 1;
401 for (FuncArgTypeID TyID = ProtoTypes[Idx]; TyID != NoFuncArgType;
402 TyID = ProtoTypes[++Idx]) {
403 if (TyID == Ellip) {
404 // The ellipsis ends the protoype list so it must be followed by
405 // NoFuncArgType.
406 assert(ProtoTypes[Idx + 1] == NoFuncArgType);
407 IsVarArg = true;
408 break;
409 }
410
411 if (TyID == Same)
412 TyID = LastID;
413 else
414 LastID = TyID;
415
416 Type *ArgTy = convertToIRType(TyID, Ctx, TT, DL, IntBits, LongDoubleFmt);
417 ArgTys.push_back(ArgTy);
418 if (Attribute::AttrKind AK =
419 getIntExtAttr(TyID, ArgTy, TT, IntBits, /*IsReturn=*/false))
420 Attrs = Attrs.addParamAttribute(Ctx, Idx - 1, AK);
421 }
422
423 if (RetTy->isVectorTy()) {
424 AttrBuilder FuncAttrBuilder(Ctx);
426 FuncAttrBuilder.addAttribute(Attr);
427 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
428 }
429
430 return {FunctionType::get(RetTy, ArgTys, IsVarArg), Attrs};
431}
432
433std::pair<FunctionType *, AttributeList>
435 const DataLayout &DL,
436 RTLIB::LibcallImpl LibcallImpl) const {
437 static constexpr Attribute::AttrKind MemoryFnAttrs[] = {
438 Attribute::NoUnwind, Attribute::WillReturn};
439 static constexpr Attribute::AttrKind CommonPtrArgAttrs[] = {
440 Attribute::NoAlias, Attribute::WriteOnly, Attribute::NonNull};
441
442 switch (LibcallImpl) {
443 // FIXME: Should also include __sincospi[f]_stret
444 case RTLIB::impl___sincos_stret:
445 case RTLIB::impl___sincosf_stret: {
446 if (!darwinHasSinCosStret(TT)) // Non-darwin currently unexpected
447 return {};
448
449 Type *ScalarTy = LibcallImpl == RTLIB::impl___sincosf_stret
450 ? Type::getFloatTy(Ctx)
451 : Type::getDoubleTy(Ctx);
452
453 AttrBuilder FuncAttrBuilder(Ctx);
455 FuncAttrBuilder.addAttribute(Attr);
456
457 const bool UseSret =
458 TT.isX86_32() || ((TT.isARM() || TT.isThumb()) &&
460
461 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argMemOnly(
463
464 AttributeList Attrs;
465 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
466
467 if (UseSret) {
468 AttrBuilder AttrBuilder(Ctx);
469 StructType *StructTy = StructType::get(ScalarTy, ScalarTy);
470 AttrBuilder.addStructRetAttr(StructTy);
471 AttrBuilder.addAlignmentAttr(DL.getABITypeAlign(StructTy));
473 Type::getVoidTy(Ctx), {DL.getAllocaPtrType(Ctx), ScalarTy}, false);
474
475 return {FuncTy, Attrs.addParamAttributes(Ctx, 0, AttrBuilder)};
476 }
477
478 Type *RetTy =
479 LibcallImpl == RTLIB::impl___sincosf_stret && TT.isX86_64()
480 ? static_cast<Type *>(FixedVectorType::get(ScalarTy, 2))
481 : static_cast<Type *>(StructType::get(ScalarTy, ScalarTy));
482
483 return {FunctionType::get(RetTy, {ScalarTy}, false), Attrs};
484 }
485 case RTLIB::impl_malloc:
486 case RTLIB::impl_calloc: {
487 AttrBuilder FuncAttrBuilder(Ctx);
488 for (Attribute::AttrKind Attr : MemoryFnAttrs)
489 FuncAttrBuilder.addAttribute(Attr);
490 FuncAttrBuilder.addAttribute(Attribute::NoFree);
491
493 if (LibcallImpl == RTLIB::impl_malloc)
494 AllocKind |= AllocFnKind::Uninitialized;
495
496 // TODO: Set memory attribute
497 FuncAttrBuilder.addAllocKindAttr(AllocKind);
498 FuncAttrBuilder.addAttribute("alloc-family", "malloc");
499 FuncAttrBuilder.addAllocSizeAttr(0, LibcallImpl == RTLIB::impl_malloc
500 ? std::nullopt
501 : std::make_optional(1));
502
503 AttributeList Attrs;
504 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
505
506 {
507 AttrBuilder ArgAttrBuilder(Ctx);
508 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
509 ArgAttrBuilder.addAttribute(AK);
510
511 Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoUndef);
512 Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoAlias);
513 Attrs = Attrs.addParamAttribute(Ctx, 0, Attribute::NoUndef);
514 if (LibcallImpl == RTLIB::impl_calloc)
515 Attrs = Attrs.addParamAttribute(Ctx, 1, Attribute::NoUndef);
516 }
517
518 IntegerType *SizeT = getSizeTType(Ctx, DL);
519 PointerType *PtrTy = PointerType::get(Ctx, 0);
520 SmallVector<Type *, 2> ArgTys = {SizeT};
521 if (LibcallImpl == RTLIB::impl_calloc)
522 ArgTys.push_back(SizeT);
523
524 return {FunctionType::get(PtrTy, ArgTys, false), Attrs};
525 }
526 case RTLIB::impl_free: {
527 // TODO: Set memory attribute
528 AttrBuilder FuncAttrBuilder(Ctx);
529 for (Attribute::AttrKind Attr : MemoryFnAttrs)
530 FuncAttrBuilder.addAttribute(Attr);
531
532 FuncAttrBuilder.addAllocKindAttr(AllocFnKind::Free);
533 FuncAttrBuilder.addAttribute("alloc-family", "malloc");
534
535 AttributeList Attrs;
536 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
537
538 {
539 AttrBuilder ArgAttrBuilder(Ctx);
540 ArgAttrBuilder.addAttribute(Attribute::NoUndef);
541 ArgAttrBuilder.addAttribute(Attribute::AllocatedPointer);
542 ArgAttrBuilder.addCapturesAttr(CaptureInfo::none());
543 Attrs = Attrs.addParamAttributes(Ctx, 0, ArgAttrBuilder);
544 }
545
546 return {FunctionType::get(Type::getVoidTy(Ctx), {PointerType::get(Ctx, 0)},
547 false),
548 Attrs};
549 }
550 case RTLIB::impl___aeabi_idivmod:
551 case RTLIB::impl___aeabi_uidivmod:
552 case RTLIB::impl___aeabi_ldivmod:
553 case RTLIB::impl___aeabi_uldivmod:
554 case RTLIB::impl___rt_sdiv:
555 case RTLIB::impl___rt_udiv:
556 case RTLIB::impl___rt_sdiv64:
557 case RTLIB::impl___rt_udiv64: {
558 // The ARM AEABI (__aeabi_*divmod) and Windows (__rt_*div*) divmod functions
559 // return both values modeled as an inreg { iN, iN } struct (quotient,
560 // remainder). The __rt_*div* cases pass the arguments in opposite order,
561 // though this doesn't affect the declaration.
562 bool IsSigned;
563 unsigned Bits;
564 switch (LibcallImpl) {
565 case RTLIB::impl___aeabi_idivmod:
566 case RTLIB::impl___rt_sdiv:
567 IsSigned = true;
568 Bits = 32;
569 break;
570 case RTLIB::impl___aeabi_uidivmod:
571 case RTLIB::impl___rt_udiv:
572 IsSigned = false;
573 Bits = 32;
574 break;
575 case RTLIB::impl___aeabi_ldivmod:
576 case RTLIB::impl___rt_sdiv64:
577 IsSigned = true;
578 Bits = 64;
579 break;
580 case RTLIB::impl___aeabi_uldivmod:
581 case RTLIB::impl___rt_udiv64:
582 IsSigned = false;
583 Bits = 64;
584 break;
585 default:
586 llvm_unreachable("unexpected divmod libcall");
587 }
588
589 Type *IntTy = IntegerType::get(Ctx, Bits);
590 StructType *RetTy = StructType::get(IntTy, IntTy);
591 FunctionType *FuncTy = FunctionType::get(RetTy, {IntTy, IntTy}, false);
592
593 AttrBuilder FuncAttrBuilder(Ctx);
595 FuncAttrBuilder.addAttribute(Attr);
596 FuncAttrBuilder.addMemoryAttr(MemoryEffects::none());
597
598 AttributeList Attrs;
599 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
600
601 Attribute::AttrKind ExtKind = IsSigned ? Attribute::SExt : Attribute::ZExt;
602 Attrs = Attrs.addRetAttribute(Ctx, Attribute::InReg);
603 Attrs = Attrs.addParamAttribute(Ctx, 0, ExtKind);
604 Attrs = Attrs.addParamAttribute(Ctx, 1, ExtKind);
605
606 return {FuncTy, Attrs};
607 }
608 case RTLIB::impl_sqrtf:
609 case RTLIB::impl_sqrt: {
610 AttrBuilder FuncAttrBuilder(Ctx);
611
613 FuncAttrBuilder.addAttribute(Attr);
614 FuncAttrBuilder.addMemoryAttr(MemoryEffects::errnoMemOnly(ModRefInfo::Mod));
615
616 AttributeList Attrs;
617 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
618
619 Type *ScalarTy = LibcallImpl == RTLIB::impl_sqrtf ? Type::getFloatTy(Ctx)
620 : Type::getDoubleTy(Ctx);
621 FunctionType *FuncTy = FunctionType::get(ScalarTy, {ScalarTy}, false);
622
623 Attrs = Attrs.addRetAttribute(
625 fcNegNormal));
626 return {FuncTy, Attrs};
627 }
628 default:
629 break;
630 }
631
632 auto [FuncTy, Attrs] = getDefaultFunctionTy(Ctx, TT, DL, LibcallImpl);
633 if (!FuncTy || FuncTy->getNumParams() == 0 ||
634 !FuncTy->getParamType(0)->isVectorTy())
635 return {FuncTy, Attrs};
636
637 Type *VecTy = FuncTy->getParamType(0);
638 Align PtrAlign = DL.getABITypeAlign(VecTy->getScalarType());
639 switch (LibcallImpl) {
640 case RTLIB::impl_amd_vrd2_sincos:
641 case RTLIB::impl_amd_vrd4_sincos:
642 case RTLIB::impl_amd_vrd8_sincos:
643 case RTLIB::impl_amd_vrs4_sincosf:
644 case RTLIB::impl_amd_vrs8_sincosf:
645 case RTLIB::impl_amd_vrs16_sincosf:
646 PtrAlign = DL.getABITypeAlign(VecTy);
647 break;
648 default:
649 break;
650 }
651
652 AttrBuilder ArgAttrBuilder(Ctx);
653 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
654 ArgAttrBuilder.addAttribute(AK);
655 ArgAttrBuilder.addAlignmentAttr(PtrAlign);
656
657 bool HasPtrArg = false;
658 for (auto [Idx, ParamTy] : enumerate(FuncTy->params())) {
659 if (ParamTy->isPointerTy()) {
660 Attrs = Attrs.addParamAttributes(Ctx, Idx, ArgAttrBuilder);
661 HasPtrArg = true;
662 }
663 }
664
665 if (HasPtrArg) {
666 AttrBuilder FuncAttrBuilder(Ctx);
668 FuncAttrBuilder.addAttribute(Attr);
669 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Mod));
670 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
671 }
672
673 return {FuncTy, Attrs};
674}
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 * 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 constexpr Attribute::AttrKind CommonFnAttrs[]
static bool shouldSignExtI32Param(const Triple &T)
static bool shouldSignExtI32Return(const Triple &T)
static std::optional< bool > isSignedIntArgType(FuncArgTypeID ID)
static Type * convertToIRType(FuncArgTypeID ID, LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, unsigned IntBits, LongDoubleFormat LdblFormat)
static unsigned getLongSize(const Triple &TT, const DataLayout &DL)
static Attribute::AttrKind getIntExtAttr(FuncArgTypeID ID, Type *Ty, const Triple &TT, unsigned IntBits, bool IsReturn)
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 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
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
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
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
#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
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
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.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static LLVM_ABI ArrayRef< RTLIB::RuntimeLibrary > getDefaultRuntimeLibraries(const Triple &TT)
Return the runtime libraries enabled by default for TT.
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.
unsigned getIntSize(const Triple &TT) const
Get size of a C-level int or unsigned int, in bits.
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...