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
12#include "llvm/IR/Intrinsics.h"
13#include "llvm/IR/Module.h"
15#include "llvm/IR/Type.h"
16#include "llvm/Support/Debug.h"
17#include "llvm/Support/xxhash.h"
19
20#define DEBUG_TYPE "runtime-libcalls-info"
21
22using namespace llvm;
23using namespace RTLIB;
24
25#define GET_RUNTIME_LIBCALLS_INFO
26#define GET_INIT_RUNTIME_LIBCALL_NAMES
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
33 ExceptionHandling ExceptionModel,
35 EABI EABIVersion, StringRef ABIName,
36 VectorLibrary VecLib) {
37 // FIXME: The ExceptionModel parameter is to handle the field in
38 // TargetOptions. This interface fails to distinguish the forced disable
39 // case for targets which support exceptions by default. This should
40 // probably be a module flag and removed from TargetOptions.
41 if (ExceptionModel == ExceptionHandling::None)
42 ExceptionModel = TT.getDefaultExceptionHandling();
43
44 initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion, ABIName,
45 TT.getDefaultLongDoubleFormat());
46
47 // TODO: Tablegen should generate these sets
48 switch (VecLib) {
50 for (RTLIB::LibcallImpl Impl :
51 {RTLIB::impl__ZGVnN2vv_fmod, RTLIB::impl__ZGVnN4vv_fmodf,
52 RTLIB::impl__ZGVsMxvv_fmod, RTLIB::impl__ZGVsMxvv_fmodf,
53 RTLIB::impl__ZGVnN2vl8_modf, RTLIB::impl__ZGVnN4vl4_modff,
54 RTLIB::impl__ZGVsNxvl8_modf, RTLIB::impl__ZGVsNxvl4_modff,
55 RTLIB::impl__ZGVnN2vl8l8_sincos, RTLIB::impl__ZGVnN4vl4l4_sincosf,
56 RTLIB::impl__ZGVsNxvl8l8_sincos, RTLIB::impl__ZGVsNxvl4l4_sincosf,
57 RTLIB::impl__ZGVnN4vl4l4_sincospif, RTLIB::impl__ZGVnN2vl8l8_sincospi,
58 RTLIB::impl__ZGVsNxvl4l4_sincospif,
59 RTLIB::impl__ZGVsNxvl8l8_sincospi})
60 setAvailable(Impl);
61 break;
63 for (RTLIB::LibcallImpl Impl : {RTLIB::impl_armpl_svfmod_f32_x,
64 RTLIB::impl_armpl_svfmod_f64_x,
65 RTLIB::impl_armpl_vfmodq_f32,
66 RTLIB::impl_armpl_vfmodq_f64,
67 RTLIB::impl_armpl_vmodfq_f64,
68 RTLIB::impl_armpl_vmodfq_f32,
69 RTLIB::impl_armpl_svmodf_f64_x,
70 RTLIB::impl_armpl_svmodf_f32_x,
71 RTLIB::impl_armpl_vsincosq_f64,
72 RTLIB::impl_armpl_vsincosq_f32,
73 RTLIB::impl_armpl_svsincos_f64_x,
74 RTLIB::impl_armpl_svsincos_f32_x,
75 RTLIB::impl_armpl_vsincospiq_f32,
76 RTLIB::impl_armpl_vsincospiq_f64,
77 RTLIB::impl_armpl_svsincospi_f32_x,
78 RTLIB::impl_armpl_svsincospi_f64_x,
79 RTLIB::impl_armpl_svpow_f32_x,
80 RTLIB::impl_armpl_svpow_f64_x,
81 RTLIB::impl_armpl_vpowq_f32,
82 RTLIB::impl_armpl_vpowq_f64,
83 RTLIB::impl_armpl_svcbrt_f32_x,
84 RTLIB::impl_armpl_svcbrt_f64_x,
85 RTLIB::impl_armpl_vcbrtq_f32,
86 RTLIB::impl_armpl_vcbrtq_f64})
87 setAvailable(Impl);
88
89 for (RTLIB::LibcallImpl Impl :
90 {RTLIB::impl_armpl_vfmodq_f32, RTLIB::impl_armpl_vfmodq_f64,
91 RTLIB::impl_armpl_vsincosq_f64, RTLIB::impl_armpl_vsincosq_f32,
92 RTLIB::impl_armpl_vpowq_f32, RTLIB::impl_armpl_vpowq_f64,
93 RTLIB::impl_armpl_vcbrtq_f32, RTLIB::impl_armpl_vcbrtq_f64})
95 break;
97 for (RTLIB::LibcallImpl Impl :
98 {RTLIB::impl_amd_vrd2_sincos, RTLIB::impl_amd_vrd4_sincos,
99 RTLIB::impl_amd_vrd8_sincos, RTLIB::impl_amd_vrs4_sincosf,
100 RTLIB::impl_amd_vrs8_sincosf, RTLIB::impl_amd_vrs16_sincosf})
101 setAvailable(Impl);
102 break;
103 default:
104 break;
105 }
106}
107
108// TODO: Consider the remaining module flags.
110 ExceptionHandling ExceptionModel,
111 EABI EABIVersion, StringRef ABIName,
112 VectorLibrary VecLib)
113 : RuntimeLibcallsInfo(M.getTargetTriple(), ExceptionModel, M.getFloatABI(),
114 EABIVersion, ABIName, VecLib) {}
115
116/// Set default libcall names. If a target wants to opt-out of a libcall it
117/// should be placed here.
118void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
119 ExceptionHandling ExceptionModel,
121 EABI EABIVersion, StringRef ABIName,
123 setTargetRuntimeLibcallSets(TT, ExceptionModel, FloatABI, EABIVersion,
124 ABIName, LongDoubleFormat);
125}
126
129RuntimeLibcallsInfo::libcallImplNameHit(uint16_t NameOffsetEntry,
130 uint16_t StrOffset) {
131 int NumAliases = 1;
132 for (uint16_t Entry : ArrayRef(RuntimeLibcallNameOffsetTable)
133 .drop_front(NameOffsetEntry + 1)) {
134 if (Entry != StrOffset)
135 break;
136 ++NumAliases;
137 }
138
139 RTLIB::LibcallImpl ImplStart = static_cast<RTLIB::LibcallImpl>(
140 &RuntimeLibcallNameOffsetTable[NameOffsetEntry] -
141 &RuntimeLibcallNameOffsetTable[0]);
142 return enum_seq(ImplStart,
143 static_cast<RTLIB::LibcallImpl>(ImplStart + NumAliases));
144}
145
146bool RuntimeLibcallsInfo::isAAPCS_ABI(const Triple &TT, StringRef ABIName) {
147 const ARM::ARMABI TargetABI = ARM::computeTargetABI(TT, ABIName);
148 return TargetABI == ARM::ARM_ABI_AAPCS || TargetABI == ARM::ARM_ABI_AAPCS16;
149}
150
151/// TODO: There is really no guarantee that sizeof(size_t) is equal to the index
152/// size of the default address space. This matches TargetLibraryInfo and should
153/// be kept in sync.
155 return DL.getIndexType(Ctx, /*AddressSpace=*/0);
156}
157
158std::pair<FunctionType *, AttributeList>
160 const DataLayout &DL,
161 RTLIB::LibcallImpl LibcallImpl) const {
162 // TODO: NoCallback probably unsafe in general
163 static constexpr Attribute::AttrKind CommonFnAttrs[] = {
164 Attribute::NoCallback, Attribute::NoFree, Attribute::NoSync,
165 Attribute::NoUnwind, Attribute::WillReturn};
166 static constexpr Attribute::AttrKind MemoryFnAttrs[] = {
167 Attribute::NoUnwind, Attribute::WillReturn};
168 static constexpr Attribute::AttrKind CommonPtrArgAttrs[] = {
169 Attribute::NoAlias, Attribute::WriteOnly, Attribute::NonNull};
170
171 switch (LibcallImpl) {
172 case RTLIB::impl___sincos_stret:
173 case RTLIB::impl___sincosf_stret: {
174 if (!darwinHasSinCosStret(TT)) // Non-darwin currently unexpected
175 return {};
176
177 Type *ScalarTy = LibcallImpl == RTLIB::impl___sincosf_stret
178 ? Type::getFloatTy(Ctx)
179 : Type::getDoubleTy(Ctx);
180
181 AttrBuilder FuncAttrBuilder(Ctx);
182 for (Attribute::AttrKind Attr : CommonFnAttrs)
183 FuncAttrBuilder.addAttribute(Attr);
184
185 const bool UseSret =
186 TT.isX86_32() || ((TT.isARM() || TT.isThumb()) &&
188
189 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argumentOrErrnoMemOnly(
191
192 AttributeList Attrs;
193 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
194
195 if (UseSret) {
196 AttrBuilder AttrBuilder(Ctx);
197 StructType *StructTy = StructType::get(ScalarTy, ScalarTy);
198 AttrBuilder.addStructRetAttr(StructTy);
199 AttrBuilder.addAlignmentAttr(DL.getABITypeAlign(StructTy));
201 Type::getVoidTy(Ctx), {DL.getAllocaPtrType(Ctx), ScalarTy}, false);
202
203 return {FuncTy, Attrs.addParamAttributes(Ctx, 0, AttrBuilder)};
204 }
205
206 Type *RetTy =
207 LibcallImpl == RTLIB::impl___sincosf_stret && TT.isX86_64()
208 ? static_cast<Type *>(FixedVectorType::get(ScalarTy, 2))
209 : static_cast<Type *>(StructType::get(ScalarTy, ScalarTy));
210
211 return {FunctionType::get(RetTy, {ScalarTy}, false), Attrs};
212 }
213 case RTLIB::impl_malloc:
214 case RTLIB::impl_calloc: {
215 AttrBuilder FuncAttrBuilder(Ctx);
216 for (Attribute::AttrKind Attr : MemoryFnAttrs)
217 FuncAttrBuilder.addAttribute(Attr);
218 FuncAttrBuilder.addAttribute(Attribute::NoFree);
219
221 if (LibcallImpl == RTLIB::impl_malloc)
222 AllocKind |= AllocFnKind::Uninitialized;
223
224 // TODO: Set memory attribute
225 FuncAttrBuilder.addAllocKindAttr(AllocKind);
226 FuncAttrBuilder.addAttribute("alloc-family", "malloc");
227 FuncAttrBuilder.addAllocSizeAttr(0, LibcallImpl == RTLIB::impl_malloc
228 ? std::nullopt
229 : std::make_optional(1));
230
231 AttributeList Attrs;
232 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
233
234 {
235 AttrBuilder ArgAttrBuilder(Ctx);
236 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
237 ArgAttrBuilder.addAttribute(AK);
238
239 Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoUndef);
240 Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoAlias);
241 Attrs = Attrs.addParamAttribute(Ctx, 0, Attribute::NoUndef);
242 if (LibcallImpl == RTLIB::impl_calloc)
243 Attrs = Attrs.addParamAttribute(Ctx, 1, Attribute::NoUndef);
244 }
245
246 IntegerType *SizeT = getSizeTType(Ctx, DL);
247 PointerType *PtrTy = PointerType::get(Ctx, 0);
248 SmallVector<Type *, 2> ArgTys = {SizeT};
249 if (LibcallImpl == RTLIB::impl_calloc)
250 ArgTys.push_back(SizeT);
251
252 return {FunctionType::get(PtrTy, ArgTys, false), Attrs};
253 }
254 case RTLIB::impl_free: {
255 // TODO: Set memory attribute
256 AttrBuilder FuncAttrBuilder(Ctx);
257 for (Attribute::AttrKind Attr : MemoryFnAttrs)
258 FuncAttrBuilder.addAttribute(Attr);
259
260 FuncAttrBuilder.addAllocKindAttr(AllocFnKind::Free);
261 FuncAttrBuilder.addAttribute("alloc-family", "malloc");
262
263 AttributeList Attrs;
264 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
265
266 {
267 AttrBuilder ArgAttrBuilder(Ctx);
268 ArgAttrBuilder.addAttribute(Attribute::NoUndef);
269 ArgAttrBuilder.addAttribute(Attribute::AllocatedPointer);
270 ArgAttrBuilder.addCapturesAttr(CaptureInfo::none());
271 Attrs = Attrs.addParamAttributes(Ctx, 0, ArgAttrBuilder);
272 }
273
274 return {FunctionType::get(Type::getVoidTy(Ctx), {PointerType::get(Ctx, 0)},
275 false),
276 Attrs};
277 }
278 case RTLIB::impl_sqrtf:
279 case RTLIB::impl_sqrt: {
280 AttrBuilder FuncAttrBuilder(Ctx);
281
282 for (Attribute::AttrKind Attr : CommonFnAttrs)
283 FuncAttrBuilder.addAttribute(Attr);
284 FuncAttrBuilder.addMemoryAttr(MemoryEffects::errnoMemOnly(ModRefInfo::Mod));
285
286 AttributeList Attrs;
287 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
288
289 Type *ScalarTy = LibcallImpl == RTLIB::impl_sqrtf ? Type::getFloatTy(Ctx)
290 : Type::getDoubleTy(Ctx);
291 FunctionType *FuncTy = FunctionType::get(ScalarTy, {ScalarTy}, false);
292
293 Attrs = Attrs.addRetAttribute(
295 fcNegNormal));
296 return {FuncTy, Attrs};
297 }
298 case RTLIB::impl__ZGVnN2vv_fmod:
299 case RTLIB::impl__ZGVnN4vv_fmodf:
300 case RTLIB::impl__ZGVsMxvv_fmod:
301 case RTLIB::impl__ZGVsMxvv_fmodf:
302 case RTLIB::impl_armpl_vfmodq_f32:
303 case RTLIB::impl_armpl_vfmodq_f64:
304 case RTLIB::impl_armpl_svfmod_f32_x:
305 case RTLIB::impl_armpl_svfmod_f64_x:
306 case RTLIB::impl_armpl_vpowq_f32:
307 case RTLIB::impl_armpl_vpowq_f64:
308 case RTLIB::impl_armpl_svpow_f32_x:
309 case RTLIB::impl_armpl_svpow_f64_x:
310 case RTLIB::impl_armpl_vcbrtq_f32:
311 case RTLIB::impl_armpl_vcbrtq_f64:
312 case RTLIB::impl_armpl_svcbrt_f32_x:
313 case RTLIB::impl_armpl_svcbrt_f64_x: {
314 bool IsF32 = LibcallImpl == RTLIB::impl__ZGVnN4vv_fmodf ||
315 LibcallImpl == RTLIB::impl__ZGVsMxvv_fmodf ||
316 LibcallImpl == RTLIB::impl_armpl_svfmod_f32_x ||
317 LibcallImpl == RTLIB::impl_armpl_vfmodq_f32 ||
318 LibcallImpl == RTLIB::impl_armpl_vpowq_f32 ||
319 LibcallImpl == RTLIB::impl_armpl_svpow_f32_x ||
320 LibcallImpl == RTLIB::impl_armpl_vcbrtq_f32 ||
321 LibcallImpl == RTLIB::impl_armpl_svcbrt_f32_x;
322
323 bool IsScalable = LibcallImpl == RTLIB::impl__ZGVsMxvv_fmod ||
324 LibcallImpl == RTLIB::impl__ZGVsMxvv_fmodf ||
325 LibcallImpl == RTLIB::impl_armpl_svfmod_f32_x ||
326 LibcallImpl == RTLIB::impl_armpl_svfmod_f64_x ||
327 LibcallImpl == RTLIB::impl_armpl_svpow_f32_x ||
328 LibcallImpl == RTLIB::impl_armpl_svpow_f64_x ||
329 LibcallImpl == RTLIB::impl_armpl_svcbrt_f32_x ||
330 LibcallImpl == RTLIB::impl_armpl_svcbrt_f64_x;
331
332 bool HasOneArg = LibcallImpl == RTLIB::impl_armpl_vcbrtq_f32 ||
333 LibcallImpl == RTLIB::impl_armpl_vcbrtq_f64 ||
334 LibcallImpl == RTLIB::impl_armpl_svcbrt_f32_x ||
335 LibcallImpl == RTLIB::impl_armpl_svcbrt_f64_x;
336
337 AttrBuilder FuncAttrBuilder(Ctx);
338
339 for (Attribute::AttrKind Attr : CommonFnAttrs)
340 FuncAttrBuilder.addAttribute(Attr);
341
342 AttributeList Attrs;
343 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
344
345 Type *ScalarTy = IsF32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
346 unsigned EC = IsF32 ? 4 : 2;
347 VectorType *VecTy = VectorType::get(ScalarTy, EC, IsScalable);
348
349 SmallVector<Type *, 3> ArgTys(HasOneArg ? 1 : 2, VecTy);
350 if (hasVectorMaskArgument(LibcallImpl))
351 ArgTys.push_back(VectorType::get(Type::getInt1Ty(Ctx), EC, IsScalable));
352
353 FunctionType *FuncTy = FunctionType::get(VecTy, ArgTys, false);
354 return {FuncTy, Attrs};
355 }
356 case RTLIB::impl__ZGVnN2vl8_modf:
357 case RTLIB::impl__ZGVnN4vl4_modff:
358 case RTLIB::impl__ZGVsNxvl8_modf:
359 case RTLIB::impl__ZGVsNxvl4_modff:
360 case RTLIB::impl_armpl_vmodfq_f64:
361 case RTLIB::impl_armpl_vmodfq_f32:
362 case RTLIB::impl_armpl_svmodf_f64_x:
363 case RTLIB::impl_armpl_svmodf_f32_x: {
364 AttrBuilder FuncAttrBuilder(Ctx);
365
366 bool IsF32 = LibcallImpl == RTLIB::impl__ZGVnN4vl4_modff ||
367 LibcallImpl == RTLIB::impl__ZGVsNxvl4_modff ||
368 LibcallImpl == RTLIB::impl_armpl_vmodfq_f32 ||
369 LibcallImpl == RTLIB::impl_armpl_svmodf_f32_x;
370
371 bool IsScalable = LibcallImpl == RTLIB::impl__ZGVsNxvl8_modf ||
372 LibcallImpl == RTLIB::impl__ZGVsNxvl4_modff ||
373 LibcallImpl == RTLIB::impl_armpl_svmodf_f64_x ||
374 LibcallImpl == RTLIB::impl_armpl_svmodf_f32_x;
375
376 Type *ScalarTy = IsF32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
377 unsigned EC = IsF32 ? 4 : 2;
378 VectorType *VecTy = VectorType::get(ScalarTy, EC, IsScalable);
379
380 for (Attribute::AttrKind Attr : CommonFnAttrs)
381 FuncAttrBuilder.addAttribute(Attr);
382 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Mod));
383
384 AttributeList Attrs;
385 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
386
387 {
388 AttrBuilder ArgAttrBuilder(Ctx);
389 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
390 ArgAttrBuilder.addAttribute(AK);
391 ArgAttrBuilder.addAlignmentAttr(DL.getABITypeAlign(VecTy));
392 Attrs = Attrs.addParamAttributes(Ctx, 1, ArgAttrBuilder);
393 }
394
395 PointerType *PtrTy = PointerType::get(Ctx, 0);
396 SmallVector<Type *, 4> ArgTys = {VecTy, PtrTy};
397 if (hasVectorMaskArgument(LibcallImpl))
398 ArgTys.push_back(VectorType::get(Type::getInt1Ty(Ctx), EC, IsScalable));
399
400 return {FunctionType::get(VecTy, ArgTys, false), Attrs};
401 }
402 case RTLIB::impl__ZGVnN2vl8l8_sincos:
403 case RTLIB::impl__ZGVnN4vl4l4_sincosf:
404 case RTLIB::impl__ZGVsNxvl8l8_sincos:
405 case RTLIB::impl__ZGVsNxvl4l4_sincosf:
406 case RTLIB::impl_armpl_vsincosq_f64:
407 case RTLIB::impl_armpl_vsincosq_f32:
408 case RTLIB::impl_armpl_svsincos_f64_x:
409 case RTLIB::impl_armpl_svsincos_f32_x:
410 case RTLIB::impl__ZGVnN4vl4l4_sincospif:
411 case RTLIB::impl__ZGVnN2vl8l8_sincospi:
412 case RTLIB::impl__ZGVsNxvl4l4_sincospif:
413 case RTLIB::impl__ZGVsNxvl8l8_sincospi:
414 case RTLIB::impl_armpl_vsincospiq_f32:
415 case RTLIB::impl_armpl_vsincospiq_f64:
416 case RTLIB::impl_armpl_svsincospi_f32_x:
417 case RTLIB::impl_armpl_svsincospi_f64_x: {
418 AttrBuilder FuncAttrBuilder(Ctx);
419
420 bool IsF32 = LibcallImpl == RTLIB::impl__ZGVnN4vl4l4_sincospif ||
421 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincospif ||
422 LibcallImpl == RTLIB::impl_armpl_vsincospiq_f32 ||
423 LibcallImpl == RTLIB::impl_armpl_svsincospi_f32_x ||
424 LibcallImpl == RTLIB::impl__ZGVnN4vl4l4_sincosf ||
425 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincosf ||
426 LibcallImpl == RTLIB::impl_armpl_vsincosq_f32 ||
427 LibcallImpl == RTLIB::impl_armpl_svsincos_f32_x;
428
429 Type *ScalarTy = IsF32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
430 unsigned EC = IsF32 ? 4 : 2;
431
432 bool IsScalable = LibcallImpl == RTLIB::impl__ZGVsNxvl8l8_sincos ||
433 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincosf ||
434 LibcallImpl == RTLIB::impl_armpl_svsincos_f32_x ||
435 LibcallImpl == RTLIB::impl_armpl_svsincos_f64_x ||
436 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincospif ||
437 LibcallImpl == RTLIB::impl__ZGVsNxvl8l8_sincospi ||
438 LibcallImpl == RTLIB::impl_armpl_svsincospi_f32_x ||
439 LibcallImpl == RTLIB::impl_armpl_svsincospi_f64_x;
440 VectorType *VecTy = VectorType::get(ScalarTy, EC, IsScalable);
441
442 for (Attribute::AttrKind Attr : CommonFnAttrs)
443 FuncAttrBuilder.addAttribute(Attr);
444 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Mod));
445
446 AttributeList Attrs;
447 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
448
449 {
450 AttrBuilder ArgAttrBuilder(Ctx);
451 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
452 ArgAttrBuilder.addAttribute(AK);
453 ArgAttrBuilder.addAlignmentAttr(DL.getABITypeAlign(VecTy));
454 Attrs = Attrs.addParamAttributes(Ctx, 1, ArgAttrBuilder);
455 Attrs = Attrs.addParamAttributes(Ctx, 2, ArgAttrBuilder);
456 }
457
458 PointerType *PtrTy = PointerType::get(Ctx, 0);
459 SmallVector<Type *, 4> ArgTys = {VecTy, PtrTy, PtrTy};
460 if (hasVectorMaskArgument(LibcallImpl))
461 ArgTys.push_back(VectorType::get(Type::getInt1Ty(Ctx), EC, IsScalable));
462
463 return {FunctionType::get(Type::getVoidTy(Ctx), ArgTys, false), Attrs};
464 }
465 default:
466 return {};
467 }
468
469 return {};
470}
471
472bool RuntimeLibcallsInfo::hasVectorMaskArgument(RTLIB::LibcallImpl Impl) {
473 /// FIXME: This should be generated by tablegen and support the argument at an
474 /// arbitrary position
475 switch (Impl) {
476 case RTLIB::impl_armpl_svfmod_f32_x:
477 case RTLIB::impl_armpl_svfmod_f64_x:
478 case RTLIB::impl_armpl_svmodf_f64_x:
479 case RTLIB::impl_armpl_svmodf_f32_x:
480 case RTLIB::impl_armpl_svsincos_f32_x:
481 case RTLIB::impl_armpl_svsincos_f64_x:
482 case RTLIB::impl_armpl_svsincospi_f32_x:
483 case RTLIB::impl_armpl_svsincospi_f64_x:
484 case RTLIB::impl__ZGVsMxvv_fmod:
485 case RTLIB::impl__ZGVsMxvv_fmodf:
486 case RTLIB::impl_armpl_svpow_f32_x:
487 case RTLIB::impl_armpl_svpow_f64_x:
488 case RTLIB::impl_armpl_svcbrt_f32_x:
489 case RTLIB::impl_armpl_svcbrt_f64_x:
490 return true;
491 default:
492 return false;
493 }
494}
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:364
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:124
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:867
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:143
static MemoryEffectsBase errnoMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:154
static MemoryEffectsBase argumentOrErrnoMemOnly(ModRefInfo ArgMR=ModRefInfo::ModRef, ModRefInfo ErrnoMR=ModRefInfo::ModRef)
Definition ModRef.h:198
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(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Definition Type.cpp:911
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:477
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 Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:282
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:306
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:287
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:286
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.
AllocFnKind
Definition Attributes.h:53
LongDoubleFormat
The floating-point format used for the target's "long double" type.
Definition CodeGen.h:67
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
@ None
No exception support.
Definition CodeGen.h:55
VectorLibrary
List of known vector-functions libraries.
LLVM_ABI std::pair< FunctionType *, AttributeList > getFunctionTy(LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, RTLIB::LibcallImpl LibcallImpl) const
void setAvailable(RTLIB::LibcallImpl Impl)
static LLVM_ABI 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.