LLVM 22.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
12#include "llvm/IR/Module.h"
14#include "llvm/Support/Debug.h"
15#include "llvm/Support/xxhash.h"
17
18#define DEBUG_TYPE "runtime-libcalls-info"
19
20using namespace llvm;
21using namespace RTLIB;
22
23#define GET_RUNTIME_LIBCALLS_INFO
24#define GET_INIT_RUNTIME_LIBCALL_NAMES
25#define GET_SET_TARGET_RUNTIME_LIBCALL_SETS
26#define DEFINE_GET_LOOKUP_LIBCALL_IMPL_NAME
27#include "llvm/IR/RuntimeLibcalls.inc"
28
30 ExceptionHandling ExceptionModel,
32 EABI EABIVersion, StringRef ABIName,
33 VectorLibrary VecLib) {
34 // FIXME: The ExceptionModel parameter is to handle the field in
35 // TargetOptions. This interface fails to distinguish the forced disable
36 // case for targets which support exceptions by default. This should
37 // probably be a module flag and removed from TargetOptions.
38 if (ExceptionModel == ExceptionHandling::None)
39 ExceptionModel = TT.getDefaultExceptionHandling();
40
41 initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion, ABIName);
42
43 // TODO: Tablegen should generate these sets
44 switch (VecLib) {
46 for (RTLIB::LibcallImpl Impl :
47 {RTLIB::impl__ZGVnN2vl8_modf, RTLIB::impl__ZGVnN4vl4_modff,
48 RTLIB::impl__ZGVsNxvl8_modf, RTLIB::impl__ZGVsNxvl4_modff,
49 RTLIB::impl__ZGVnN2vl8l8_sincos, RTLIB::impl__ZGVnN4vl4l4_sincosf,
50 RTLIB::impl__ZGVsNxvl8l8_sincos, RTLIB::impl__ZGVsNxvl4l4_sincosf,
51 RTLIB::impl__ZGVnN4vl4l4_sincospif, RTLIB::impl__ZGVnN2vl8l8_sincospi,
52 RTLIB::impl__ZGVsNxvl4l4_sincospif,
53 RTLIB::impl__ZGVsNxvl8l8_sincospi})
54 setAvailable(Impl);
55 break;
57 for (RTLIB::LibcallImpl Impl :
58 {RTLIB::impl_armpl_vmodfq_f64, RTLIB::impl_armpl_vmodfq_f32,
59 RTLIB::impl_armpl_svmodf_f64_x, RTLIB::impl_armpl_svmodf_f32_x,
60 RTLIB::impl_armpl_vsincosq_f64, RTLIB::impl_armpl_vsincosq_f32,
61 RTLIB::impl_armpl_svsincos_f64_x, RTLIB::impl_armpl_svsincos_f32_x,
62 RTLIB::impl_armpl_vsincospiq_f32, RTLIB::impl_armpl_vsincospiq_f64,
63 RTLIB::impl_armpl_svsincospi_f32_x,
64 RTLIB::impl_armpl_svsincospi_f64_x})
65 setAvailable(Impl);
66
67 for (RTLIB::LibcallImpl Impl :
68 {RTLIB::impl_armpl_vsincosq_f64, RTLIB::impl_armpl_vsincosq_f32})
70
71 break;
72 default:
73 break;
74 }
75}
76
78 : RuntimeLibcallsInfo(M.getTargetTriple()) {
79 // TODO: Consider module flags
80}
81
82/// Set default libcall names. If a target wants to opt-out of a libcall it
83/// should be placed here.
84void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
85 ExceptionHandling ExceptionModel,
87 EABI EABIVersion, StringRef ABIName) {
88 setTargetRuntimeLibcallSets(TT, ExceptionModel, FloatABI, EABIVersion,
89 ABIName);
90}
91
94RuntimeLibcallsInfo::libcallImplNameHit(uint16_t NameOffsetEntry,
95 uint16_t StrOffset) {
96 int NumAliases = 1;
97 for (uint16_t Entry : ArrayRef(RuntimeLibcallNameOffsetTable)
98 .drop_front(NameOffsetEntry + 1)) {
99 if (Entry != StrOffset)
100 break;
101 ++NumAliases;
102 }
103
104 RTLIB::LibcallImpl ImplStart = static_cast<RTLIB::LibcallImpl>(
105 &RuntimeLibcallNameOffsetTable[NameOffsetEntry] -
106 &RuntimeLibcallNameOffsetTable[0]);
107 return enum_seq(ImplStart,
108 static_cast<RTLIB::LibcallImpl>(ImplStart + NumAliases));
109}
110
111bool RuntimeLibcallsInfo::isAAPCS_ABI(const Triple &TT, StringRef ABIName) {
112 const ARM::ARMABI TargetABI = ARM::computeTargetABI(TT, ABIName);
113 return TargetABI == ARM::ARM_ABI_AAPCS || TargetABI == ARM::ARM_ABI_AAPCS16;
114}
115
116bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) {
117 switch (TT.getOS()) {
118 case Triple::MacOSX:
119 return !TT.isMacOSXVersionLT(10, 9);
120 case Triple::IOS:
121 return !TT.isOSVersionLT(7, 0);
123 case Triple::TvOS:
124 case Triple::WatchOS:
125 case Triple::XROS:
126 case Triple::BridgeOS:
127 return true;
128 default:
129 return false;
130 }
131}
132
133/// TODO: There is really no guarantee that sizeof(size_t) is equal to the index
134/// size of the default address space. This matches TargetLibraryInfo and should
135/// be kept in sync.
137 return DL.getIndexType(Ctx, /*AddressSpace=*/0);
138}
139
140std::pair<FunctionType *, AttributeList>
142 const DataLayout &DL,
143 RTLIB::LibcallImpl LibcallImpl) const {
144 // TODO: NoCallback probably unsafe in general
145 static constexpr Attribute::AttrKind CommonFnAttrs[] = {
146 Attribute::MustProgress, Attribute::NoCallback, Attribute::NoFree,
147 Attribute::NoSync, Attribute::NoUnwind, Attribute::WillReturn};
148 static constexpr Attribute::AttrKind MemoryFnAttrs[] = {
149 Attribute::MustProgress, Attribute::NoUnwind, Attribute::WillReturn};
150 static constexpr Attribute::AttrKind CommonPtrArgAttrs[] = {
151 Attribute::NoAlias, Attribute::WriteOnly, Attribute::NonNull};
152
153 switch (LibcallImpl) {
154 case RTLIB::impl___sincos_stret:
155 case RTLIB::impl___sincosf_stret: {
156 if (!darwinHasSinCosStret(TT)) // Non-darwin currently unexpected
157 return {};
158
159 Type *ScalarTy = LibcallImpl == RTLIB::impl___sincosf_stret
160 ? Type::getFloatTy(Ctx)
161 : Type::getDoubleTy(Ctx);
162
163 AttrBuilder FuncAttrBuilder(Ctx);
164 for (Attribute::AttrKind Attr : CommonFnAttrs)
165 FuncAttrBuilder.addAttribute(Attr);
166
167 const bool UseSret =
168 TT.isX86_32() || ((TT.isARM() || TT.isThumb()) &&
170
171 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argumentOrErrnoMemOnly(
173
174 AttributeList Attrs;
175 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
176
177 if (UseSret) {
178 AttrBuilder AttrBuilder(Ctx);
179 StructType *StructTy = StructType::get(ScalarTy, ScalarTy);
180 AttrBuilder.addStructRetAttr(StructTy);
181 AttrBuilder.addAlignmentAttr(DL.getABITypeAlign(StructTy));
183 Type::getVoidTy(Ctx), {DL.getAllocaPtrType(Ctx), ScalarTy}, false);
184
185 return {FuncTy, Attrs.addParamAttributes(Ctx, 0, AttrBuilder)};
186 }
187
188 Type *RetTy =
189 LibcallImpl == RTLIB::impl___sincosf_stret && TT.isX86_64()
190 ? static_cast<Type *>(FixedVectorType::get(ScalarTy, 2))
191 : static_cast<Type *>(StructType::get(ScalarTy, ScalarTy));
192
193 return {FunctionType::get(RetTy, {ScalarTy}, false), Attrs};
194 }
195 case RTLIB::impl_malloc:
196 case RTLIB::impl_calloc: {
197 AttrBuilder FuncAttrBuilder(Ctx);
198 for (Attribute::AttrKind Attr : MemoryFnAttrs)
199 FuncAttrBuilder.addAttribute(Attr);
200 FuncAttrBuilder.addAttribute(Attribute::NoFree);
201
203 if (LibcallImpl == RTLIB::impl_malloc)
204 AllocKind |= AllocFnKind::Uninitialized;
205
206 // TODO: Set memory attribute
207 FuncAttrBuilder.addAllocKindAttr(AllocKind);
208 FuncAttrBuilder.addAttribute("alloc-family", "malloc");
209 FuncAttrBuilder.addAllocSizeAttr(0, LibcallImpl == RTLIB::impl_malloc
210 ? std::nullopt
211 : std::make_optional(1));
212
213 AttributeList Attrs;
214 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
215
216 {
217 AttrBuilder ArgAttrBuilder(Ctx);
218 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
219 ArgAttrBuilder.addAttribute(AK);
220
221 Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoUndef);
222 Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoAlias);
223 Attrs = Attrs.addParamAttribute(Ctx, 0, Attribute::NoUndef);
224 if (LibcallImpl == RTLIB::impl_calloc)
225 Attrs = Attrs.addParamAttribute(Ctx, 1, Attribute::NoUndef);
226 }
227
228 IntegerType *SizeT = getSizeTType(Ctx, DL);
229 PointerType *PtrTy = PointerType::get(Ctx, 0);
230 SmallVector<Type *, 2> ArgTys = {SizeT};
231 if (LibcallImpl == RTLIB::impl_calloc)
232 ArgTys.push_back(SizeT);
233
234 return {FunctionType::get(PtrTy, ArgTys, false), Attrs};
235 }
236 case RTLIB::impl_free: {
237 // TODO: Set memory attribute
238 AttrBuilder FuncAttrBuilder(Ctx);
239 for (Attribute::AttrKind Attr : MemoryFnAttrs)
240 FuncAttrBuilder.addAttribute(Attr);
241
242 FuncAttrBuilder.addAllocKindAttr(AllocFnKind::Free);
243 FuncAttrBuilder.addAttribute("alloc-family", "malloc");
244
245 AttributeList Attrs;
246 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
247
248 {
249 AttrBuilder ArgAttrBuilder(Ctx);
250 ArgAttrBuilder.addAttribute(Attribute::NoUndef);
251 ArgAttrBuilder.addAttribute(Attribute::AllocatedPointer);
252 ArgAttrBuilder.addCapturesAttr(CaptureInfo::none());
253 Attrs = Attrs.addParamAttributes(Ctx, 0, ArgAttrBuilder);
254 }
255
256 return {FunctionType::get(Type::getVoidTy(Ctx), {PointerType::get(Ctx, 0)},
257 false),
258 Attrs};
259 }
260 case RTLIB::impl_sqrtf:
261 case RTLIB::impl_sqrt: {
262 AttrBuilder FuncAttrBuilder(Ctx);
263
264 for (Attribute::AttrKind Attr : CommonFnAttrs)
265 FuncAttrBuilder.addAttribute(Attr);
266 FuncAttrBuilder.addMemoryAttr(MemoryEffects::errnoMemOnly(ModRefInfo::Mod));
267
268 AttributeList Attrs;
269 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
270
271 Type *ScalarTy = LibcallImpl == RTLIB::impl_sqrtf ? Type::getFloatTy(Ctx)
272 : Type::getDoubleTy(Ctx);
273 FunctionType *FuncTy = FunctionType::get(ScalarTy, {ScalarTy}, false);
274
275 Attrs = Attrs.addRetAttribute(
277 fcNegNormal));
278 return {FuncTy, Attrs};
279 }
280 case RTLIB::impl__ZGVnN2vl8_modf:
281 case RTLIB::impl__ZGVnN4vl4_modff:
282 case RTLIB::impl__ZGVsNxvl8_modf:
283 case RTLIB::impl__ZGVsNxvl4_modff:
284 case RTLIB::impl_armpl_vmodfq_f64:
285 case RTLIB::impl_armpl_vmodfq_f32:
286 case RTLIB::impl_armpl_svmodf_f64_x:
287 case RTLIB::impl_armpl_svmodf_f32_x: {
288 AttrBuilder FuncAttrBuilder(Ctx);
289
290 bool IsF32 = LibcallImpl == RTLIB::impl__ZGVnN4vl4_modff ||
291 LibcallImpl == RTLIB::impl__ZGVsNxvl4_modff ||
292 LibcallImpl == RTLIB::impl_armpl_vmodfq_f32 ||
293 LibcallImpl == RTLIB::impl_armpl_svmodf_f32_x;
294
295 bool IsScalable = LibcallImpl == RTLIB::impl__ZGVsNxvl8_modf ||
296 LibcallImpl == RTLIB::impl__ZGVsNxvl4_modff ||
297 LibcallImpl == RTLIB::impl_armpl_svmodf_f64_x ||
298 LibcallImpl == RTLIB::impl_armpl_svmodf_f32_x;
299
300 Type *ScalarTy = IsF32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
301 unsigned EC = IsF32 ? 4 : 2;
302 VectorType *VecTy = VectorType::get(ScalarTy, EC, IsScalable);
303
304 for (Attribute::AttrKind Attr : CommonFnAttrs)
305 FuncAttrBuilder.addAttribute(Attr);
306 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Mod));
307
308 AttributeList Attrs;
309 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
310
311 {
312 AttrBuilder ArgAttrBuilder(Ctx);
313 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
314 ArgAttrBuilder.addAttribute(AK);
315 ArgAttrBuilder.addAlignmentAttr(DL.getABITypeAlign(VecTy));
316 Attrs = Attrs.addParamAttributes(Ctx, 1, ArgAttrBuilder);
317 }
318
319 PointerType *PtrTy = PointerType::get(Ctx, 0);
320 SmallVector<Type *, 4> ArgTys = {VecTy, PtrTy};
321 if (hasVectorMaskArgument(LibcallImpl))
322 ArgTys.push_back(VectorType::get(Type::getInt1Ty(Ctx), EC, IsScalable));
323
324 return {FunctionType::get(VecTy, ArgTys, false), Attrs};
325 }
326 case RTLIB::impl__ZGVnN2vl8l8_sincos:
327 case RTLIB::impl__ZGVnN4vl4l4_sincosf:
328 case RTLIB::impl__ZGVsNxvl8l8_sincos:
329 case RTLIB::impl__ZGVsNxvl4l4_sincosf:
330 case RTLIB::impl_armpl_vsincosq_f64:
331 case RTLIB::impl_armpl_vsincosq_f32:
332 case RTLIB::impl_armpl_svsincos_f64_x:
333 case RTLIB::impl_armpl_svsincos_f32_x:
334 case RTLIB::impl__ZGVnN4vl4l4_sincospif:
335 case RTLIB::impl__ZGVnN2vl8l8_sincospi:
336 case RTLIB::impl__ZGVsNxvl4l4_sincospif:
337 case RTLIB::impl__ZGVsNxvl8l8_sincospi:
338 case RTLIB::impl_armpl_vsincospiq_f32:
339 case RTLIB::impl_armpl_vsincospiq_f64:
340 case RTLIB::impl_armpl_svsincospi_f32_x:
341 case RTLIB::impl_armpl_svsincospi_f64_x: {
342 AttrBuilder FuncAttrBuilder(Ctx);
343
344 bool IsF32 = LibcallImpl == RTLIB::impl__ZGVnN4vl4l4_sincospif ||
345 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincospif ||
346 LibcallImpl == RTLIB::impl_armpl_vsincospiq_f32 ||
347 LibcallImpl == RTLIB::impl_armpl_svsincospi_f32_x ||
348 LibcallImpl == RTLIB::impl__ZGVnN4vl4l4_sincosf ||
349 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincosf ||
350 LibcallImpl == RTLIB::impl_armpl_vsincosq_f32 ||
351 LibcallImpl == RTLIB::impl_armpl_svsincos_f32_x;
352
353 Type *ScalarTy = IsF32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
354 unsigned EC = IsF32 ? 4 : 2;
355
356 bool IsScalable = LibcallImpl == RTLIB::impl__ZGVsNxvl8l8_sincos ||
357 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincosf ||
358 LibcallImpl == RTLIB::impl_armpl_svsincos_f32_x ||
359 LibcallImpl == RTLIB::impl_armpl_svsincos_f64_x ||
360 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincospif ||
361 LibcallImpl == RTLIB::impl__ZGVsNxvl8l8_sincospi ||
362 LibcallImpl == RTLIB::impl_armpl_svsincospi_f32_x ||
363 LibcallImpl == RTLIB::impl_armpl_svsincospi_f64_x;
364 VectorType *VecTy = VectorType::get(ScalarTy, EC, IsScalable);
365
366 for (Attribute::AttrKind Attr : CommonFnAttrs)
367 FuncAttrBuilder.addAttribute(Attr);
368 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Mod));
369
370 AttributeList Attrs;
371 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
372
373 {
374 AttrBuilder ArgAttrBuilder(Ctx);
375 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
376 ArgAttrBuilder.addAttribute(AK);
377 ArgAttrBuilder.addAlignmentAttr(DL.getABITypeAlign(VecTy));
378 Attrs = Attrs.addParamAttributes(Ctx, 1, ArgAttrBuilder);
379 Attrs = Attrs.addParamAttributes(Ctx, 2, ArgAttrBuilder);
380 }
381
382 PointerType *PtrTy = PointerType::get(Ctx, 0);
383 SmallVector<Type *, 4> ArgTys = {VecTy, PtrTy, PtrTy};
384 if (hasVectorMaskArgument(LibcallImpl))
385 ArgTys.push_back(VectorType::get(Type::getInt1Ty(Ctx), EC, IsScalable));
386
387 return {FunctionType::get(Type::getVoidTy(Ctx), ArgTys, false), Attrs};
388 }
389 default:
390 return {};
391 }
392
393 return {};
394}
395
396bool RuntimeLibcallsInfo::hasVectorMaskArgument(RTLIB::LibcallImpl Impl) {
397 /// FIXME: This should be generated by tablegen and support the argument at an
398 /// arbitrary position
399 switch (Impl) {
400 case RTLIB::impl_armpl_svmodf_f64_x:
401 case RTLIB::impl_armpl_svmodf_f32_x:
402 case RTLIB::impl_armpl_svsincos_f32_x:
403 case RTLIB::impl_armpl_svsincos_f64_x:
404 case RTLIB::impl_armpl_svsincospi_f32_x:
405 case RTLIB::impl_armpl_svsincospi_f64_x:
406 return true;
407 default:
408 return false;
409 }
410}
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:356
Utilities for dealing with flags related to floating point properties and mode controls.
Module.h This file contains the declarations for the Module class.
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 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:88
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:372
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:802
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.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:140
static MemoryEffectsBase errnoMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:151
static MemoryEffectsBase argumentOrErrnoMemOnly(ModRefInfo ArgMR=ModRefInfo::ModRef, ModRefInfo ErrnoMR=ModRefInfo::ModRef)
Definition ModRef.h:172
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
Class to represent pointers.
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
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.
Definition StringRef.h:55
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:413
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:280
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:293
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:285
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:284
Base class of all SIMD vector types.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
LLVM_ABI LLVM_READONLY ARMABI computeTargetABI(const Triple &TT, StringRef ABIName="")
@ AArch64_VectorCall
Used between AArch64 Advanced SIMD functions.
This is an optimization pass for GlobalISel generic memory operations.
auto enum_seq(EnumT Begin, EnumT End)
Iterate over an enum type from Begin up to - but not including - End.
Definition Sequence.h:337
AllocFnKind
Definition Attributes.h:51
ExceptionHandling
Definition CodeGen.h:53
@ None
No exception support.
Definition CodeGen.h:54
@ 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 >
VectorLibrary
List of known vector-functions libraries.
EABI
Definition CodeGen.h:73
std::pair< FunctionType *, AttributeList > getFunctionTy(LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, RTLIB::LibcallImpl LibcallImpl) const
void setAvailable(RTLIB::LibcallImpl Impl)
static bool hasVectorMaskArgument(RTLIB::LibcallImpl Impl)
Returns true if the function has a vector mask argument, which is assumed to be the last argument.
void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC)
Set the CallingConv that should be used for the specified libcall implementation.