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_SET_TARGET_RUNTIME_LIBCALL_SETS
25#define DEFINE_GET_LOOKUP_LIBCALL_IMPL_NAME
26#define GET_RUNTIME_LIBCALL_INTRINSIC_TO_LIBCALL
27#include "llvm/IR/RuntimeLibcalls.inc"
28
30 ExceptionHandling ExceptionModel,
32 StringRef ABIName,
33 VectorLibrary VecLib) {
34 // Only an unspecified model resolves to the triple default; None is left as
35 // an explicit disable.
36 if (ExceptionModel == ExceptionHandling::Default)
37 ExceptionModel = TT.getDefaultExceptionHandling();
38
39 initLibcalls(TT, ExceptionModel, FloatABI, ABIName,
40 TT.getDefaultLongDoubleFormat());
41
42 // TODO: Tablegen should generate these sets
43 switch (VecLib) {
45 for (RTLIB::LibcallImpl Impl :
46 {RTLIB::impl__ZGVnN2vv_fmod, RTLIB::impl__ZGVnN4vv_fmodf,
47 RTLIB::impl__ZGVsMxvv_fmod, RTLIB::impl__ZGVsMxvv_fmodf,
48 RTLIB::impl__ZGVnN2vl8_modf, RTLIB::impl__ZGVnN4vl4_modff,
49 RTLIB::impl__ZGVsNxvl8_modf, RTLIB::impl__ZGVsNxvl4_modff,
50 RTLIB::impl__ZGVnN2vl8l8_sincos, RTLIB::impl__ZGVnN4vl4l4_sincosf,
51 RTLIB::impl__ZGVsNxvl8l8_sincos, RTLIB::impl__ZGVsNxvl4l4_sincosf,
52 RTLIB::impl__ZGVnN4vl4l4_sincospif, RTLIB::impl__ZGVnN2vl8l8_sincospi,
53 RTLIB::impl__ZGVsNxvl4l4_sincospif,
54 RTLIB::impl__ZGVsNxvl8l8_sincospi})
55 setAvailable(Impl);
56 break;
58 for (RTLIB::LibcallImpl Impl : {RTLIB::impl_armpl_svfmod_f32_x,
59 RTLIB::impl_armpl_svfmod_f64_x,
60 RTLIB::impl_armpl_vfmodq_f32,
61 RTLIB::impl_armpl_vfmodq_f64,
62 RTLIB::impl_armpl_vmodfq_f64,
63 RTLIB::impl_armpl_vmodfq_f32,
64 RTLIB::impl_armpl_svmodf_f64_x,
65 RTLIB::impl_armpl_svmodf_f32_x,
66 RTLIB::impl_armpl_vsincosq_f64,
67 RTLIB::impl_armpl_vsincosq_f32,
68 RTLIB::impl_armpl_svsincos_f64_x,
69 RTLIB::impl_armpl_svsincos_f32_x,
70 RTLIB::impl_armpl_vsincospiq_f32,
71 RTLIB::impl_armpl_vsincospiq_f64,
72 RTLIB::impl_armpl_svsincospi_f32_x,
73 RTLIB::impl_armpl_svsincospi_f64_x,
74 RTLIB::impl_armpl_svpow_f32_x,
75 RTLIB::impl_armpl_svpow_f64_x,
76 RTLIB::impl_armpl_vpowq_f32,
77 RTLIB::impl_armpl_vpowq_f64,
78 RTLIB::impl_armpl_svcbrt_f32_x,
79 RTLIB::impl_armpl_svcbrt_f64_x,
80 RTLIB::impl_armpl_vcbrtq_f32,
81 RTLIB::impl_armpl_vcbrtq_f64})
82 setAvailable(Impl);
83
84 for (RTLIB::LibcallImpl Impl :
85 {RTLIB::impl_armpl_vfmodq_f32, RTLIB::impl_armpl_vfmodq_f64,
86 RTLIB::impl_armpl_vsincosq_f64, RTLIB::impl_armpl_vsincosq_f32,
87 RTLIB::impl_armpl_vpowq_f32, RTLIB::impl_armpl_vpowq_f64,
88 RTLIB::impl_armpl_vcbrtq_f32, RTLIB::impl_armpl_vcbrtq_f64})
90 break;
92 for (RTLIB::LibcallImpl Impl :
93 {RTLIB::impl_amd_vrd2_sincos, RTLIB::impl_amd_vrd4_sincos,
94 RTLIB::impl_amd_vrd8_sincos, RTLIB::impl_amd_vrs4_sincosf,
95 RTLIB::impl_amd_vrs8_sincosf, RTLIB::impl_amd_vrs16_sincosf})
96 setAvailable(Impl);
97 break;
98 default:
99 break;
100 }
101}
102
103// TODO: Consider the remaining module flags.
105 VectorLibrary VecLib)
106 : RuntimeLibcallsInfo(M.getTargetTriple(), M.getExceptionModel(),
107 M.getFloatABI(), ABIName, VecLib) {}
108
109bool RuntimeLibcallsInfo::isLibraryAvailable(StringRef LibraryName) const {
110 // TODO: Drive this from module-level state (e.g. the linked runtime). For now
111 // every named library is reported as available.
112 return true;
113}
114
115/// Set default libcall names. If a target wants to opt-out of a libcall it
116/// should be placed here.
117void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
118 ExceptionHandling ExceptionModel,
120 StringRef ABIName,
122 setTargetRuntimeLibcallSets(TT, ExceptionModel, FloatABI, ABIName,
124}
125
128RuntimeLibcallsInfo::libcallImplNameHit(uint16_t NameOffsetEntry,
129 uint16_t StrOffset) {
130 int NumAliases = 1;
131 for (uint16_t Entry : ArrayRef(RuntimeLibcallNameOffsetTable)
132 .drop_front(NameOffsetEntry + 1)) {
133 if (Entry != StrOffset)
134 break;
135 ++NumAliases;
136 }
137
138 RTLIB::LibcallImpl ImplStart = static_cast<RTLIB::LibcallImpl>(
139 &RuntimeLibcallNameOffsetTable[NameOffsetEntry] -
140 &RuntimeLibcallNameOffsetTable[0]);
141 return enum_seq(ImplStart,
142 static_cast<RTLIB::LibcallImpl>(ImplStart + NumAliases));
143}
144
145bool RuntimeLibcallsInfo::isAAPCS_ABI(const Triple &TT, StringRef ABIName) {
146 const ARM::ARMABI TargetABI = ARM::computeTargetABI(TT, ABIName);
147 return TargetABI == ARM::ARM_ABI_AAPCS || TargetABI == ARM::ARM_ABI_AAPCS16;
148}
149
150/// TODO: There is really no guarantee that sizeof(size_t) is equal to the index
151/// size of the default address space. This matches TargetLibraryInfo and should
152/// be kept in sync.
154 return DL.getIndexType(Ctx, /*AddressSpace=*/0);
155}
156
157std::pair<FunctionType *, AttributeList>
159 const DataLayout &DL,
160 RTLIB::LibcallImpl LibcallImpl) const {
161 // TODO: NoCallback probably unsafe in general
162 static constexpr Attribute::AttrKind CommonFnAttrs[] = {
163 Attribute::NoCallback, Attribute::NoFree, Attribute::NoSync,
164 Attribute::NoUnwind, Attribute::WillReturn};
165 static constexpr Attribute::AttrKind MemoryFnAttrs[] = {
166 Attribute::NoUnwind, Attribute::WillReturn};
167 static constexpr Attribute::AttrKind CommonPtrArgAttrs[] = {
168 Attribute::NoAlias, Attribute::WriteOnly, Attribute::NonNull};
169
170 switch (LibcallImpl) {
171 case RTLIB::impl___sincos_stret:
172 case RTLIB::impl___sincosf_stret: {
173 if (!darwinHasSinCosStret(TT)) // Non-darwin currently unexpected
174 return {};
175
176 Type *ScalarTy = LibcallImpl == RTLIB::impl___sincosf_stret
177 ? Type::getFloatTy(Ctx)
178 : Type::getDoubleTy(Ctx);
179
180 AttrBuilder FuncAttrBuilder(Ctx);
181 for (Attribute::AttrKind Attr : CommonFnAttrs)
182 FuncAttrBuilder.addAttribute(Attr);
183
184 const bool UseSret =
185 TT.isX86_32() || ((TT.isARM() || TT.isThumb()) &&
187
188 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argumentOrErrnoMemOnly(
190
191 AttributeList Attrs;
192 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
193
194 if (UseSret) {
195 AttrBuilder AttrBuilder(Ctx);
196 StructType *StructTy = StructType::get(ScalarTy, ScalarTy);
197 AttrBuilder.addStructRetAttr(StructTy);
198 AttrBuilder.addAlignmentAttr(DL.getABITypeAlign(StructTy));
200 Type::getVoidTy(Ctx), {DL.getAllocaPtrType(Ctx), ScalarTy}, false);
201
202 return {FuncTy, Attrs.addParamAttributes(Ctx, 0, AttrBuilder)};
203 }
204
205 Type *RetTy =
206 LibcallImpl == RTLIB::impl___sincosf_stret && TT.isX86_64()
207 ? static_cast<Type *>(FixedVectorType::get(ScalarTy, 2))
208 : static_cast<Type *>(StructType::get(ScalarTy, ScalarTy));
209
210 return {FunctionType::get(RetTy, {ScalarTy}, false), Attrs};
211 }
212 case RTLIB::impl_malloc:
213 case RTLIB::impl_calloc: {
214 AttrBuilder FuncAttrBuilder(Ctx);
215 for (Attribute::AttrKind Attr : MemoryFnAttrs)
216 FuncAttrBuilder.addAttribute(Attr);
217 FuncAttrBuilder.addAttribute(Attribute::NoFree);
218
220 if (LibcallImpl == RTLIB::impl_malloc)
221 AllocKind |= AllocFnKind::Uninitialized;
222
223 // TODO: Set memory attribute
224 FuncAttrBuilder.addAllocKindAttr(AllocKind);
225 FuncAttrBuilder.addAttribute("alloc-family", "malloc");
226 FuncAttrBuilder.addAllocSizeAttr(0, LibcallImpl == RTLIB::impl_malloc
227 ? std::nullopt
228 : std::make_optional(1));
229
230 AttributeList Attrs;
231 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
232
233 {
234 AttrBuilder ArgAttrBuilder(Ctx);
235 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
236 ArgAttrBuilder.addAttribute(AK);
237
238 Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoUndef);
239 Attrs = Attrs.addRetAttribute(Ctx, Attribute::NoAlias);
240 Attrs = Attrs.addParamAttribute(Ctx, 0, Attribute::NoUndef);
241 if (LibcallImpl == RTLIB::impl_calloc)
242 Attrs = Attrs.addParamAttribute(Ctx, 1, Attribute::NoUndef);
243 }
244
245 IntegerType *SizeT = getSizeTType(Ctx, DL);
246 PointerType *PtrTy = PointerType::get(Ctx, 0);
247 SmallVector<Type *, 2> ArgTys = {SizeT};
248 if (LibcallImpl == RTLIB::impl_calloc)
249 ArgTys.push_back(SizeT);
250
251 return {FunctionType::get(PtrTy, ArgTys, false), Attrs};
252 }
253 case RTLIB::impl_free: {
254 // TODO: Set memory attribute
255 AttrBuilder FuncAttrBuilder(Ctx);
256 for (Attribute::AttrKind Attr : MemoryFnAttrs)
257 FuncAttrBuilder.addAttribute(Attr);
258
259 FuncAttrBuilder.addAllocKindAttr(AllocFnKind::Free);
260 FuncAttrBuilder.addAttribute("alloc-family", "malloc");
261
262 AttributeList Attrs;
263 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
264
265 {
266 AttrBuilder ArgAttrBuilder(Ctx);
267 ArgAttrBuilder.addAttribute(Attribute::NoUndef);
268 ArgAttrBuilder.addAttribute(Attribute::AllocatedPointer);
269 ArgAttrBuilder.addCapturesAttr(CaptureInfo::none());
270 Attrs = Attrs.addParamAttributes(Ctx, 0, ArgAttrBuilder);
271 }
272
273 return {FunctionType::get(Type::getVoidTy(Ctx), {PointerType::get(Ctx, 0)},
274 false),
275 Attrs};
276 }
277 case RTLIB::impl___aeabi_idivmod:
278 case RTLIB::impl___aeabi_uidivmod:
279 case RTLIB::impl___aeabi_ldivmod:
280 case RTLIB::impl___aeabi_uldivmod:
281 case RTLIB::impl___rt_sdiv:
282 case RTLIB::impl___rt_udiv:
283 case RTLIB::impl___rt_sdiv64:
284 case RTLIB::impl___rt_udiv64: {
285 // The ARM AEABI (__aeabi_*divmod) and Windows (__rt_*div*) divmod functions
286 // return both values modeled as an inreg { iN, iN } struct (quotient,
287 // remainder). The __rt_*div* cases pass the arguments in opposite order,
288 // though this doesn't affect the declaration.
289 bool IsSigned;
290 unsigned Bits;
291 switch (LibcallImpl) {
292 case RTLIB::impl___aeabi_idivmod:
293 case RTLIB::impl___rt_sdiv:
294 IsSigned = true;
295 Bits = 32;
296 break;
297 case RTLIB::impl___aeabi_uidivmod:
298 case RTLIB::impl___rt_udiv:
299 IsSigned = false;
300 Bits = 32;
301 break;
302 case RTLIB::impl___aeabi_ldivmod:
303 case RTLIB::impl___rt_sdiv64:
304 IsSigned = true;
305 Bits = 64;
306 break;
307 case RTLIB::impl___aeabi_uldivmod:
308 case RTLIB::impl___rt_udiv64:
309 IsSigned = false;
310 Bits = 64;
311 break;
312 default:
313 llvm_unreachable("unexpected divmod libcall");
314 }
315
316 Type *IntTy = IntegerType::get(Ctx, Bits);
317 StructType *RetTy = StructType::get(IntTy, IntTy);
318 FunctionType *FuncTy = FunctionType::get(RetTy, {IntTy, IntTy}, false);
319
320 AttrBuilder FuncAttrBuilder(Ctx);
321 for (Attribute::AttrKind Attr : CommonFnAttrs)
322 FuncAttrBuilder.addAttribute(Attr);
323 FuncAttrBuilder.addMemoryAttr(MemoryEffects::none());
324
325 AttributeList Attrs;
326 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
327
328 Attribute::AttrKind ExtKind = IsSigned ? Attribute::SExt : Attribute::ZExt;
329 Attrs = Attrs.addRetAttribute(Ctx, Attribute::InReg);
330 Attrs = Attrs.addParamAttribute(Ctx, 0, ExtKind);
331 Attrs = Attrs.addParamAttribute(Ctx, 1, ExtKind);
332
333 return {FuncTy, Attrs};
334 }
335 case RTLIB::impl_sqrtf:
336 case RTLIB::impl_sqrt: {
337 AttrBuilder FuncAttrBuilder(Ctx);
338
339 for (Attribute::AttrKind Attr : CommonFnAttrs)
340 FuncAttrBuilder.addAttribute(Attr);
341 FuncAttrBuilder.addMemoryAttr(MemoryEffects::errnoMemOnly(ModRefInfo::Mod));
342
343 AttributeList Attrs;
344 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
345
346 Type *ScalarTy = LibcallImpl == RTLIB::impl_sqrtf ? Type::getFloatTy(Ctx)
347 : Type::getDoubleTy(Ctx);
348 FunctionType *FuncTy = FunctionType::get(ScalarTy, {ScalarTy}, false);
349
350 Attrs = Attrs.addRetAttribute(
352 fcNegNormal));
353 return {FuncTy, Attrs};
354 }
355 case RTLIB::impl__ZGVnN2vv_fmod:
356 case RTLIB::impl__ZGVnN4vv_fmodf:
357 case RTLIB::impl__ZGVsMxvv_fmod:
358 case RTLIB::impl__ZGVsMxvv_fmodf:
359 case RTLIB::impl_armpl_vfmodq_f32:
360 case RTLIB::impl_armpl_vfmodq_f64:
361 case RTLIB::impl_armpl_svfmod_f32_x:
362 case RTLIB::impl_armpl_svfmod_f64_x:
363 case RTLIB::impl_armpl_vpowq_f32:
364 case RTLIB::impl_armpl_vpowq_f64:
365 case RTLIB::impl_armpl_svpow_f32_x:
366 case RTLIB::impl_armpl_svpow_f64_x:
367 case RTLIB::impl_armpl_vcbrtq_f32:
368 case RTLIB::impl_armpl_vcbrtq_f64:
369 case RTLIB::impl_armpl_svcbrt_f32_x:
370 case RTLIB::impl_armpl_svcbrt_f64_x: {
371 bool IsF32 = LibcallImpl == RTLIB::impl__ZGVnN4vv_fmodf ||
372 LibcallImpl == RTLIB::impl__ZGVsMxvv_fmodf ||
373 LibcallImpl == RTLIB::impl_armpl_svfmod_f32_x ||
374 LibcallImpl == RTLIB::impl_armpl_vfmodq_f32 ||
375 LibcallImpl == RTLIB::impl_armpl_vpowq_f32 ||
376 LibcallImpl == RTLIB::impl_armpl_svpow_f32_x ||
377 LibcallImpl == RTLIB::impl_armpl_vcbrtq_f32 ||
378 LibcallImpl == RTLIB::impl_armpl_svcbrt_f32_x;
379
380 bool IsScalable = LibcallImpl == RTLIB::impl__ZGVsMxvv_fmod ||
381 LibcallImpl == RTLIB::impl__ZGVsMxvv_fmodf ||
382 LibcallImpl == RTLIB::impl_armpl_svfmod_f32_x ||
383 LibcallImpl == RTLIB::impl_armpl_svfmod_f64_x ||
384 LibcallImpl == RTLIB::impl_armpl_svpow_f32_x ||
385 LibcallImpl == RTLIB::impl_armpl_svpow_f64_x ||
386 LibcallImpl == RTLIB::impl_armpl_svcbrt_f32_x ||
387 LibcallImpl == RTLIB::impl_armpl_svcbrt_f64_x;
388
389 bool HasOneArg = LibcallImpl == RTLIB::impl_armpl_vcbrtq_f32 ||
390 LibcallImpl == RTLIB::impl_armpl_vcbrtq_f64 ||
391 LibcallImpl == RTLIB::impl_armpl_svcbrt_f32_x ||
392 LibcallImpl == RTLIB::impl_armpl_svcbrt_f64_x;
393
394 AttrBuilder FuncAttrBuilder(Ctx);
395
396 for (Attribute::AttrKind Attr : CommonFnAttrs)
397 FuncAttrBuilder.addAttribute(Attr);
398
399 AttributeList Attrs;
400 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
401
402 Type *ScalarTy = IsF32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
403 unsigned EC = IsF32 ? 4 : 2;
404 VectorType *VecTy = VectorType::get(ScalarTy, EC, IsScalable);
405
406 SmallVector<Type *, 3> ArgTys(HasOneArg ? 1 : 2, VecTy);
407 if (hasVectorMaskArgument(LibcallImpl))
408 ArgTys.push_back(VectorType::get(Type::getInt1Ty(Ctx), EC, IsScalable));
409
410 FunctionType *FuncTy = FunctionType::get(VecTy, ArgTys, false);
411 return {FuncTy, Attrs};
412 }
413 case RTLIB::impl__ZGVnN2vl8_modf:
414 case RTLIB::impl__ZGVnN4vl4_modff:
415 case RTLIB::impl__ZGVsNxvl8_modf:
416 case RTLIB::impl__ZGVsNxvl4_modff:
417 case RTLIB::impl_armpl_vmodfq_f64:
418 case RTLIB::impl_armpl_vmodfq_f32:
419 case RTLIB::impl_armpl_svmodf_f64_x:
420 case RTLIB::impl_armpl_svmodf_f32_x: {
421 AttrBuilder FuncAttrBuilder(Ctx);
422
423 bool IsF32 = LibcallImpl == RTLIB::impl__ZGVnN4vl4_modff ||
424 LibcallImpl == RTLIB::impl__ZGVsNxvl4_modff ||
425 LibcallImpl == RTLIB::impl_armpl_vmodfq_f32 ||
426 LibcallImpl == RTLIB::impl_armpl_svmodf_f32_x;
427
428 bool IsScalable = LibcallImpl == RTLIB::impl__ZGVsNxvl8_modf ||
429 LibcallImpl == RTLIB::impl__ZGVsNxvl4_modff ||
430 LibcallImpl == RTLIB::impl_armpl_svmodf_f64_x ||
431 LibcallImpl == RTLIB::impl_armpl_svmodf_f32_x;
432
433 Type *ScalarTy = IsF32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
434 unsigned EC = IsF32 ? 4 : 2;
435 VectorType *VecTy = VectorType::get(ScalarTy, EC, IsScalable);
436
437 for (Attribute::AttrKind Attr : CommonFnAttrs)
438 FuncAttrBuilder.addAttribute(Attr);
439 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Mod));
440
441 AttributeList Attrs;
442 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
443
444 {
445 AttrBuilder ArgAttrBuilder(Ctx);
446 for (Attribute::AttrKind AK : CommonPtrArgAttrs)
447 ArgAttrBuilder.addAttribute(AK);
448 ArgAttrBuilder.addAlignmentAttr(DL.getABITypeAlign(VecTy));
449 Attrs = Attrs.addParamAttributes(Ctx, 1, ArgAttrBuilder);
450 }
451
452 PointerType *PtrTy = PointerType::get(Ctx, 0);
453 SmallVector<Type *, 4> ArgTys = {VecTy, PtrTy};
454 if (hasVectorMaskArgument(LibcallImpl))
455 ArgTys.push_back(VectorType::get(Type::getInt1Ty(Ctx), EC, IsScalable));
456
457 return {FunctionType::get(VecTy, ArgTys, false), Attrs};
458 }
459 case RTLIB::impl__ZGVnN2vl8l8_sincos:
460 case RTLIB::impl__ZGVnN4vl4l4_sincosf:
461 case RTLIB::impl__ZGVsNxvl8l8_sincos:
462 case RTLIB::impl__ZGVsNxvl4l4_sincosf:
463 case RTLIB::impl_armpl_vsincosq_f64:
464 case RTLIB::impl_armpl_vsincosq_f32:
465 case RTLIB::impl_armpl_svsincos_f64_x:
466 case RTLIB::impl_armpl_svsincos_f32_x:
467 case RTLIB::impl__ZGVnN4vl4l4_sincospif:
468 case RTLIB::impl__ZGVnN2vl8l8_sincospi:
469 case RTLIB::impl__ZGVsNxvl4l4_sincospif:
470 case RTLIB::impl__ZGVsNxvl8l8_sincospi:
471 case RTLIB::impl_armpl_vsincospiq_f32:
472 case RTLIB::impl_armpl_vsincospiq_f64:
473 case RTLIB::impl_armpl_svsincospi_f32_x:
474 case RTLIB::impl_armpl_svsincospi_f64_x: {
475 AttrBuilder FuncAttrBuilder(Ctx);
476
477 bool IsF32 = LibcallImpl == RTLIB::impl__ZGVnN4vl4l4_sincospif ||
478 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincospif ||
479 LibcallImpl == RTLIB::impl_armpl_vsincospiq_f32 ||
480 LibcallImpl == RTLIB::impl_armpl_svsincospi_f32_x ||
481 LibcallImpl == RTLIB::impl__ZGVnN4vl4l4_sincosf ||
482 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincosf ||
483 LibcallImpl == RTLIB::impl_armpl_vsincosq_f32 ||
484 LibcallImpl == RTLIB::impl_armpl_svsincos_f32_x;
485
486 Type *ScalarTy = IsF32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
487 unsigned EC = IsF32 ? 4 : 2;
488
489 bool IsScalable = LibcallImpl == RTLIB::impl__ZGVsNxvl8l8_sincos ||
490 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincosf ||
491 LibcallImpl == RTLIB::impl_armpl_svsincos_f32_x ||
492 LibcallImpl == RTLIB::impl_armpl_svsincos_f64_x ||
493 LibcallImpl == RTLIB::impl__ZGVsNxvl4l4_sincospif ||
494 LibcallImpl == RTLIB::impl__ZGVsNxvl8l8_sincospi ||
495 LibcallImpl == RTLIB::impl_armpl_svsincospi_f32_x ||
496 LibcallImpl == RTLIB::impl_armpl_svsincospi_f64_x;
497 VectorType *VecTy = VectorType::get(ScalarTy, EC, IsScalable);
498
499 for (Attribute::AttrKind Attr : CommonFnAttrs)
500 FuncAttrBuilder.addAttribute(Attr);
501 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Mod));
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 ArgAttrBuilder.addAlignmentAttr(DL.getABITypeAlign(VecTy));
511 Attrs = Attrs.addParamAttributes(Ctx, 1, ArgAttrBuilder);
512 Attrs = Attrs.addParamAttributes(Ctx, 2, ArgAttrBuilder);
513 }
514
515 PointerType *PtrTy = PointerType::get(Ctx, 0);
516 SmallVector<Type *, 4> ArgTys = {VecTy, PtrTy, PtrTy};
517 if (hasVectorMaskArgument(LibcallImpl))
518 ArgTys.push_back(VectorType::get(Type::getInt1Ty(Ctx), EC, IsScalable));
519
520 return {FunctionType::get(Type::getVoidTy(Ctx), ArgTys, false), Attrs};
521 }
522 default:
523 return {};
524 }
525
526 return {};
527}
528
529bool RuntimeLibcallsInfo::hasVectorMaskArgument(RTLIB::LibcallImpl Impl) {
530 /// FIXME: This should be generated by tablegen and support the argument at an
531 /// arbitrary position
532 switch (Impl) {
533 case RTLIB::impl_armpl_svfmod_f32_x:
534 case RTLIB::impl_armpl_svfmod_f64_x:
535 case RTLIB::impl_armpl_svmodf_f64_x:
536 case RTLIB::impl_armpl_svmodf_f32_x:
537 case RTLIB::impl_armpl_svsincos_f32_x:
538 case RTLIB::impl_armpl_svsincos_f64_x:
539 case RTLIB::impl_armpl_svsincospi_f32_x:
540 case RTLIB::impl_armpl_svsincospi_f64_x:
541 case RTLIB::impl__ZGVsMxvv_fmod:
542 case RTLIB::impl__ZGVsMxvv_fmodf:
543 case RTLIB::impl_armpl_svpow_f32_x:
544 case RTLIB::impl_armpl_svpow_f64_x:
545 case RTLIB::impl_armpl_svcbrt_f32_x:
546 case RTLIB::impl_armpl_svcbrt_f64_x:
547 return true;
548 default:
549 return false;
550 }
551}
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:369
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:125
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: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
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
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 Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
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 * getFloatTy(LLVMContext &C)
Definition Type.cpp:276
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.
#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="")
@ AArch64_VectorCall
Used between AArch64 Advanced SIMD functions.
This is an optimization pass for GlobalISel generic memory operations.
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.
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.