1//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
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//
9// This file implements some functions that will create standard C libcalls.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/Transforms/Utils/BuildLibCalls.h"
14#include "llvm/ADT/SmallString.h"
15#include "llvm/ADT/Statistic.h"
16#include "llvm/Analysis/MemoryBuiltins.h"
17#include "llvm/Analysis/TargetLibraryInfo.h"
18#include "llvm/IR/Argument.h"
19#include "llvm/IR/CallingConv.h"
20#include "llvm/IR/Constants.h"
21#include "llvm/IR/DataLayout.h"
22#include "llvm/IR/DerivedTypes.h"
23#include "llvm/IR/Function.h"
24#include "llvm/IR/IRBuilder.h"
25#include "llvm/IR/Module.h"
26#include "llvm/IR/Type.h"
27#include "llvm/Support/TypeSize.h"
28#include <optional>
29
30using namespace llvm;
31
32#define DEBUG_TYPE "build-libcalls"
33
34//- Infer Attributes ---------------------------------------------------------//
35
36STATISTIC(NumReadNone, "Number of functions inferred as readnone");
37STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
38STATISTIC(NumWriteOnly, "Number of functions inferred as writeonly");
39STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
40STATISTIC(NumWriteErrnoMemOnly,
41 "Number of functions inferred as memory(errnomem: write)");
42STATISTIC(NumInaccessibleMemOrArgMemOnly,
43 "Number of functions inferred as inaccessiblemem_or_argmemonly");
44STATISTIC(NumInaccessibleMemOrErrnoMemOnly,
45 "Number of functions inferred as memory(inaccessiblemem: readwrite, "
46 "errnomem: write)");
47STATISTIC(NumInaccessibleMemOrArgMemOrErrnoMemOnly,
48 "Number of functions inferred as memory(argmem: readwrite, "
49 "inaccessiblemem: readwrite, errnomem: write)");
50STATISTIC(
51 NumWriteArgumentMemOrErrnoMemOnly,
52 "Number of functions inferred as memory(argmem: write, errnomem: write)");
53STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
54STATISTIC(NumNoCallback, "Number of functions inferred as nocallback");
55STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
56STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly");
57STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
58STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
59STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns");
60STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
61STATISTIC(NumWillReturn, "Number of functions inferred as willreturn");
62STATISTIC(NumCold, "Number of functions inferred as cold");
63STATISTIC(NumNoReturn, "Number of functions inferred as no return");
64
65static bool setDoesNotAccessMemory(Function &F) {
66 if (F.doesNotAccessMemory())
67 return false;
68 F.setDoesNotAccessMemory();
69 ++NumReadNone;
70 return true;
71}
72
73static bool setIsCold(Function &F) {
74 if (F.hasFnAttribute(Kind: Attribute::Cold))
75 return false;
76 F.addFnAttr(Kind: Attribute::Cold);
77 ++NumCold;
78 return true;
79}
80
81static bool setNoReturn(Function &F) {
82 if (F.hasFnAttribute(Kind: Attribute::NoReturn))
83 return false;
84 F.addFnAttr(Kind: Attribute::NoReturn);
85 ++NumNoReturn;
86 return true;
87}
88
89static bool setMemoryEffects(Function &F, MemoryEffects ME) {
90 MemoryEffects OrigME = F.getMemoryEffects();
91 MemoryEffects NewME = OrigME & ME;
92 if (OrigME == NewME)
93 return false;
94 F.setMemoryEffects(NewME);
95 return true;
96}
97
98static bool setOnlyReadsMemory(Function &F) {
99 if (!setMemoryEffects(F, ME: MemoryEffects::readOnly()))
100 return false;
101 ++NumReadOnly;
102 return true;
103}
104
105static bool setOnlyWritesMemory(Function &F) {
106 if (!setMemoryEffects(F, ME: MemoryEffects::writeOnly()))
107 return false;
108 ++NumWriteOnly;
109 return true;
110}
111
112static bool setOnlyAccessesArgMemory(Function &F) {
113 if (!setMemoryEffects(F, ME: MemoryEffects::argMemOnly()))
114 return false;
115 ++NumArgMemOnly;
116 return true;
117}
118
119static bool setOnlyAccessesInaccessibleMemOrArgMem(Function &F) {
120 if (!setMemoryEffects(F, ME: MemoryEffects::inaccessibleOrArgMemOnly()))
121 return false;
122 ++NumInaccessibleMemOrArgMemOnly;
123 return true;
124}
125
126static bool setOnlyAccessesInaccessibleMemOrErrnoMem(Function &F) {
127 if (!setMemoryEffects(F, ME: MemoryEffects::inaccessibleOrErrnoMemOnly(
128 InaccessibleMR: ModRefInfo::ModRef, ErrnoMR: ModRefInfo::Mod)))
129 return false;
130 ++NumInaccessibleMemOrErrnoMemOnly;
131 return true;
132}
133
134static bool setOnlyAccessesInaccessibleMemOrArgMemOrErrnoMem(Function &F) {
135 if (!setMemoryEffects(F, ME: MemoryEffects::inaccessibleOrArgOrErrnoMemOnly(
136 InaccessibleOrArgMR: ModRefInfo::ModRef, ErrnoMR: ModRefInfo::Mod)))
137 return false;
138 ++NumInaccessibleMemOrArgMemOrErrnoMemOnly;
139 return true;
140}
141
142static bool setOnlyWritesErrnoMemory(Function &F) {
143 if (!setMemoryEffects(F, ME: MemoryEffects::errnoMemOnly(MR: ModRefInfo::Mod)))
144 return false;
145 ++NumWriteErrnoMemOnly;
146 return true;
147}
148
149static bool setOnlyWritesArgMemOrErrnoMem(Function &F) {
150 if (!setMemoryEffects(F, ME: MemoryEffects::argumentOrErrnoMemOnly(
151 ArgMR: ModRefInfo::Mod, ErrnoMR: ModRefInfo::Mod)))
152 return false;
153 ++NumWriteArgumentMemOrErrnoMemOnly;
154 return true;
155}
156
157static bool setDoesNotThrow(Function &F) {
158 if (F.doesNotThrow())
159 return false;
160 F.setDoesNotThrow();
161 ++NumNoUnwind;
162 return true;
163}
164
165static bool setDoesNotCallback(Function &F) {
166 if (F.hasFnAttribute(Kind: Attribute::NoCallback))
167 return false;
168 F.addFnAttr(Kind: Attribute::NoCallback);
169 ++NumNoCallback;
170 return true;
171}
172
173static bool setRetDoesNotAlias(Function &F) {
174 if (F.hasRetAttribute(Kind: Attribute::NoAlias))
175 return false;
176 F.addRetAttr(Kind: Attribute::NoAlias);
177 ++NumNoAlias;
178 return true;
179}
180
181static bool setDoesNotCapture(Function &F, unsigned ArgNo) {
182 if (F.hasParamAttribute(ArgNo, Kind: Attribute::Captures))
183 return false;
184 F.addParamAttr(ArgNo, Attr: Attribute::getWithCaptureInfo(Context&: F.getContext(),
185 CI: CaptureInfo::none()));
186 ++NumNoCapture;
187 return true;
188}
189
190static bool setDoesNotAlias(Function &F, unsigned ArgNo) {
191 if (F.hasParamAttribute(ArgNo, Kind: Attribute::NoAlias))
192 return false;
193 F.addParamAttr(ArgNo, Kind: Attribute::NoAlias);
194 ++NumNoAlias;
195 return true;
196}
197
198static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
199 if (F.hasParamAttribute(ArgNo, Kind: Attribute::ReadOnly))
200 return false;
201 F.addParamAttr(ArgNo, Kind: Attribute::ReadOnly);
202 ++NumReadOnlyArg;
203 return true;
204}
205
206static bool setOnlyWritesMemory(Function &F, unsigned ArgNo) {
207 if (F.hasParamAttribute(ArgNo, Kind: Attribute::WriteOnly))
208 return false;
209 F.addParamAttr(ArgNo, Kind: Attribute::WriteOnly);
210 ++NumWriteOnlyArg;
211 return true;
212}
213
214static bool setRetNoUndef(Function &F) {
215 if (!F.getReturnType()->isVoidTy() &&
216 !F.hasRetAttribute(Kind: Attribute::NoUndef)) {
217 F.addRetAttr(Kind: Attribute::NoUndef);
218 ++NumNoUndef;
219 return true;
220 }
221 return false;
222}
223
224static bool setArgsNoUndef(Function &F) {
225 bool Changed = false;
226 for (unsigned ArgNo = 0; ArgNo < F.arg_size(); ++ArgNo) {
227 if (!F.hasParamAttribute(ArgNo, Kind: Attribute::NoUndef)) {
228 F.addParamAttr(ArgNo, Kind: Attribute::NoUndef);
229 ++NumNoUndef;
230 Changed = true;
231 }
232 }
233 return Changed;
234}
235
236static bool setArgNoUndef(Function &F, unsigned ArgNo) {
237 if (F.hasParamAttribute(ArgNo, Kind: Attribute::NoUndef))
238 return false;
239 F.addParamAttr(ArgNo, Kind: Attribute::NoUndef);
240 ++NumNoUndef;
241 return true;
242}
243
244static bool setRetAndArgsNoUndef(Function &F) {
245 bool UndefAdded = false;
246 UndefAdded |= setRetNoUndef(F);
247 UndefAdded |= setArgsNoUndef(F);
248 return UndefAdded;
249}
250
251static bool setReturnedArg(Function &F, unsigned ArgNo) {
252 if (F.hasParamAttribute(ArgNo, Kind: Attribute::Returned))
253 return false;
254 F.addParamAttr(ArgNo, Kind: Attribute::Returned);
255 ++NumReturnedArg;
256 return true;
257}
258
259static bool setNonLazyBind(Function &F) {
260 if (F.hasFnAttribute(Kind: Attribute::NonLazyBind))
261 return false;
262 F.addFnAttr(Kind: Attribute::NonLazyBind);
263 return true;
264}
265
266static bool setDoesNotFreeMemory(Function &F) {
267 if (F.hasFnAttribute(Kind: Attribute::NoFree))
268 return false;
269 F.addFnAttr(Kind: Attribute::NoFree);
270 return true;
271}
272
273static bool setWillReturn(Function &F) {
274 if (F.hasFnAttribute(Kind: Attribute::WillReturn))
275 return false;
276 F.addFnAttr(Kind: Attribute::WillReturn);
277 ++NumWillReturn;
278 return true;
279}
280
281static bool setAlignedAllocParam(Function &F, unsigned ArgNo) {
282 if (F.hasParamAttribute(ArgNo, Kind: Attribute::AllocAlign))
283 return false;
284 F.addParamAttr(ArgNo, Kind: Attribute::AllocAlign);
285 return true;
286}
287
288static bool setAllocatedPointerParam(Function &F, unsigned ArgNo) {
289 if (F.hasParamAttribute(ArgNo, Kind: Attribute::AllocatedPointer))
290 return false;
291 F.addParamAttr(ArgNo, Kind: Attribute::AllocatedPointer);
292 return true;
293}
294
295static bool setAllocSize(Function &F, unsigned ElemSizeArg,
296 std::optional<unsigned> NumElemsArg) {
297 if (F.hasFnAttribute(Kind: Attribute::AllocSize))
298 return false;
299 F.addFnAttr(Attr: Attribute::getWithAllocSizeArgs(Context&: F.getContext(), ElemSizeArg,
300 NumElemsArg));
301 return true;
302}
303
304static bool setAllocFamily(Function &F, StringRef Family) {
305 if (F.hasFnAttribute(Kind: "alloc-family"))
306 return false;
307 F.addFnAttr(Kind: "alloc-family", Val: Family);
308 return true;
309}
310
311static bool setAllocKind(Function &F, AllocFnKind K) {
312 if (F.hasFnAttribute(Kind: Attribute::AllocKind))
313 return false;
314 F.addFnAttr(
315 Attr: Attribute::get(Context&: F.getContext(), Kind: Attribute::AllocKind, Val: uint64_t(K)));
316 return true;
317}
318
319bool llvm::inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name,
320 const TargetLibraryInfo &TLI) {
321 Function *F = M->getFunction(Name);
322 if (!F)
323 return false;
324 return inferNonMandatoryLibFuncAttrs(F&: *F, TLI);
325}
326
327bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
328 const TargetLibraryInfo &TLI) {
329 LibFunc TheLibFunc;
330 if (!(TLI.getLibFunc(FDecl: F, F&: TheLibFunc) && TLI.has(F: TheLibFunc)))
331 return false;
332
333 bool Changed = false;
334
335 if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
336 Changed |= setNonLazyBind(F);
337
338 switch (TheLibFunc) {
339 case LibFunc_nan:
340 case LibFunc_nanf:
341 case LibFunc_nanl:
342 case LibFunc_strlen:
343 case LibFunc_strnlen:
344 case LibFunc_wcslen:
345 Changed |= setOnlyReadsMemory(F);
346 Changed |= setDoesNotThrow(F);
347 Changed |= setDoesNotCallback(F);
348 Changed |= setOnlyAccessesArgMemory(F);
349 Changed |= setWillReturn(F);
350 Changed |= setDoesNotCapture(F, ArgNo: 0);
351 break;
352 case LibFunc_strchr:
353 case LibFunc_strrchr:
354 Changed |= setOnlyAccessesArgMemory(F);
355 Changed |= setOnlyReadsMemory(F);
356 Changed |= setDoesNotThrow(F);
357 Changed |= setDoesNotCallback(F);
358 Changed |= setWillReturn(F);
359 break;
360 case LibFunc_strtol:
361 case LibFunc_strtod:
362 case LibFunc_strtof:
363 case LibFunc_strtoul:
364 case LibFunc_strtoll:
365 case LibFunc_strtold:
366 case LibFunc_strtoull:
367 Changed |= setDoesNotThrow(F);
368 Changed |= setDoesNotCallback(F);
369 Changed |= setWillReturn(F);
370 Changed |= setDoesNotCapture(F, ArgNo: 1);
371 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
372 break;
373 case LibFunc_strcat:
374 case LibFunc_strncat:
375 Changed |= setOnlyAccessesArgMemory(F);
376 Changed |= setDoesNotThrow(F);
377 Changed |= setDoesNotCallback(F);
378 Changed |= setWillReturn(F);
379 Changed |= setReturnedArg(F, ArgNo: 0);
380 Changed |= setDoesNotCapture(F, ArgNo: 1);
381 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
382 Changed |= setDoesNotAlias(F, ArgNo: 0);
383 Changed |= setDoesNotAlias(F, ArgNo: 1);
384 break;
385 case LibFunc_strcpy:
386 case LibFunc_strncpy:
387 Changed |= setReturnedArg(F, ArgNo: 0);
388 [[fallthrough]];
389 case LibFunc_stpcpy:
390 case LibFunc_stpncpy:
391 Changed |= setOnlyAccessesArgMemory(F);
392 Changed |= setDoesNotThrow(F);
393 Changed |= setDoesNotCallback(F);
394 Changed |= setWillReturn(F);
395 Changed |= setDoesNotCapture(F, ArgNo: 1);
396 Changed |= setOnlyWritesMemory(F, ArgNo: 0);
397 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
398 Changed |= setDoesNotAlias(F, ArgNo: 0);
399 Changed |= setDoesNotAlias(F, ArgNo: 1);
400 break;
401 case LibFunc_strxfrm:
402 Changed |= setDoesNotThrow(F);
403 Changed |= setDoesNotCallback(F);
404 Changed |= setWillReturn(F);
405 Changed |= setDoesNotCapture(F, ArgNo: 0);
406 Changed |= setDoesNotCapture(F, ArgNo: 1);
407 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
408 break;
409 case LibFunc_strcmp: // 0,1
410 case LibFunc_strspn: // 0,1
411 case LibFunc_strncmp: // 0,1
412 case LibFunc_strcspn: // 0,1
413 Changed |= setDoesNotThrow(F);
414 Changed |= setDoesNotCallback(F);
415 Changed |= setOnlyAccessesArgMemory(F);
416 Changed |= setWillReturn(F);
417 Changed |= setOnlyReadsMemory(F);
418 Changed |= setDoesNotCapture(F, ArgNo: 0);
419 Changed |= setDoesNotCapture(F, ArgNo: 1);
420 break;
421 case LibFunc_strcoll:
422 case LibFunc_strcasecmp: // 0,1
423 case LibFunc_strncasecmp: //
424 // Those functions may depend on the locale, which may be accessed through
425 // global memory.
426 Changed |= setOnlyReadsMemory(F);
427 Changed |= setDoesNotThrow(F);
428 Changed |= setDoesNotCallback(F);
429 Changed |= setWillReturn(F);
430 Changed |= setDoesNotCapture(F, ArgNo: 0);
431 Changed |= setDoesNotCapture(F, ArgNo: 1);
432 break;
433 case LibFunc_strstr:
434 case LibFunc_strpbrk:
435 Changed |= setOnlyAccessesArgMemory(F);
436 Changed |= setOnlyReadsMemory(F);
437 Changed |= setDoesNotThrow(F);
438 Changed |= setDoesNotCallback(F);
439 Changed |= setWillReturn(F);
440 Changed |= setDoesNotCapture(F, ArgNo: 1);
441 break;
442 case LibFunc_strtok:
443 case LibFunc_strtok_r:
444 Changed |= setDoesNotThrow(F);
445 Changed |= setDoesNotCallback(F);
446 Changed |= setWillReturn(F);
447 Changed |= setDoesNotCapture(F, ArgNo: 1);
448 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
449 break;
450 case LibFunc_scanf:
451 Changed |= setRetAndArgsNoUndef(F);
452 Changed |= setDoesNotThrow(F);
453 Changed |= setDoesNotCapture(F, ArgNo: 0);
454 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
455 break;
456 case LibFunc_setbuf:
457 case LibFunc_setvbuf:
458 Changed |= setRetAndArgsNoUndef(F);
459 Changed |= setDoesNotThrow(F);
460 Changed |= setDoesNotCapture(F, ArgNo: 0);
461 break;
462 case LibFunc_strndup:
463 Changed |= setArgNoUndef(F, ArgNo: 1);
464 [[fallthrough]];
465 case LibFunc_strdup:
466 Changed |= setAllocFamily(F, Family: "malloc");
467 Changed |= setOnlyAccessesInaccessibleMemOrArgMemOrErrnoMem(F);
468 Changed |= setDoesNotThrow(F);
469 Changed |= setRetDoesNotAlias(F);
470 Changed |= setWillReturn(F);
471 Changed |= setDoesNotCapture(F, ArgNo: 0);
472 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
473 break;
474 case LibFunc_stat:
475 case LibFunc_statvfs:
476 Changed |= setRetAndArgsNoUndef(F);
477 Changed |= setDoesNotThrow(F);
478 Changed |= setDoesNotCapture(F, ArgNo: 0);
479 Changed |= setDoesNotCapture(F, ArgNo: 1);
480 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
481 break;
482 case LibFunc_sscanf:
483 Changed |= setRetAndArgsNoUndef(F);
484 Changed |= setDoesNotThrow(F);
485 Changed |= setDoesNotCapture(F, ArgNo: 0);
486 Changed |= setDoesNotCapture(F, ArgNo: 1);
487 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
488 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
489 break;
490 case LibFunc_sprintf:
491 Changed |= setRetAndArgsNoUndef(F);
492 Changed |= setDoesNotThrow(F);
493 Changed |= setDoesNotCapture(F, ArgNo: 0);
494 Changed |= setDoesNotAlias(F, ArgNo: 0);
495 Changed |= setOnlyWritesMemory(F, ArgNo: 0);
496 Changed |= setDoesNotCapture(F, ArgNo: 1);
497 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
498 break;
499 case LibFunc_snprintf:
500 Changed |= setRetAndArgsNoUndef(F);
501 Changed |= setDoesNotThrow(F);
502 Changed |= setDoesNotCapture(F, ArgNo: 0);
503 Changed |= setDoesNotAlias(F, ArgNo: 0);
504 Changed |= setOnlyWritesMemory(F, ArgNo: 0);
505 Changed |= setDoesNotCapture(F, ArgNo: 2);
506 Changed |= setOnlyReadsMemory(F, ArgNo: 2);
507 break;
508 case LibFunc_setitimer:
509 Changed |= setRetAndArgsNoUndef(F);
510 Changed |= setDoesNotThrow(F);
511 Changed |= setWillReturn(F);
512 Changed |= setDoesNotCapture(F, ArgNo: 1);
513 Changed |= setDoesNotCapture(F, ArgNo: 2);
514 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
515 break;
516 case LibFunc_system:
517 // May throw; "system" is a valid pthread cancellation point.
518 Changed |= setRetAndArgsNoUndef(F);
519 Changed |= setDoesNotCapture(F, ArgNo: 0);
520 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
521 break;
522 case LibFunc_aligned_alloc:
523 Changed |= setAlignedAllocParam(F, ArgNo: 0);
524 Changed |= setAllocSize(F, ElemSizeArg: 1, NumElemsArg: std::nullopt);
525 Changed |= setAllocKind(F, K: AllocFnKind::Alloc | AllocFnKind::Uninitialized | AllocFnKind::Aligned);
526 [[fallthrough]];
527 case LibFunc_valloc:
528 case LibFunc_malloc:
529 case LibFunc_vec_malloc:
530 Changed |= setAllocSize(F, ElemSizeArg: 0, NumElemsArg: std::nullopt);
531 [[fallthrough]];
532 case LibFunc_pvalloc:
533 Changed |= setAllocFamily(F, Family: TheLibFunc == LibFunc_vec_malloc ? "vec_malloc"
534 : "malloc");
535 Changed |= setAllocKind(F, K: AllocFnKind::Alloc | AllocFnKind::Uninitialized);
536 Changed |= setOnlyAccessesInaccessibleMemOrErrnoMem(F);
537 Changed |= setRetAndArgsNoUndef(F);
538 Changed |= setDoesNotThrow(F);
539 Changed |= setRetDoesNotAlias(F);
540 Changed |= setWillReturn(F);
541 break;
542 case LibFunc_memcmp:
543 Changed |= setOnlyAccessesArgMemory(F);
544 Changed |= setOnlyReadsMemory(F);
545 Changed |= setDoesNotThrow(F);
546 Changed |= setDoesNotCallback(F);
547 Changed |= setWillReturn(F);
548 Changed |= setDoesNotCapture(F, ArgNo: 0);
549 Changed |= setDoesNotCapture(F, ArgNo: 1);
550 break;
551 case LibFunc_memchr:
552 case LibFunc_memrchr:
553 Changed |= setDoesNotThrow(F);
554 Changed |= setDoesNotCallback(F);
555 Changed |= setOnlyAccessesArgMemory(F);
556 Changed |= setOnlyReadsMemory(F);
557 Changed |= setWillReturn(F);
558 break;
559 case LibFunc_modf:
560 case LibFunc_modff:
561 case LibFunc_modfl:
562 Changed |= setDoesNotThrow(F);
563 Changed |= setDoesNotCallback(F);
564 Changed |= setWillReturn(F);
565 Changed |= setOnlyAccessesArgMemory(F);
566 Changed |= setOnlyWritesMemory(F);
567 Changed |= setDoesNotCapture(F, ArgNo: 1);
568 break;
569 case LibFunc_memcpy:
570 Changed |= setDoesNotThrow(F);
571 Changed |= setDoesNotCallback(F);
572 Changed |= setOnlyAccessesArgMemory(F);
573 Changed |= setWillReturn(F);
574 Changed |= setDoesNotAlias(F, ArgNo: 0);
575 Changed |= setReturnedArg(F, ArgNo: 0);
576 Changed |= setOnlyWritesMemory(F, ArgNo: 0);
577 Changed |= setDoesNotAlias(F, ArgNo: 1);
578 Changed |= setDoesNotCapture(F, ArgNo: 1);
579 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
580 break;
581 case LibFunc_memmove:
582 Changed |= setDoesNotThrow(F);
583 Changed |= setDoesNotCallback(F);
584 Changed |= setOnlyAccessesArgMemory(F);
585 Changed |= setWillReturn(F);
586 Changed |= setReturnedArg(F, ArgNo: 0);
587 Changed |= setOnlyWritesMemory(F, ArgNo: 0);
588 Changed |= setDoesNotCapture(F, ArgNo: 1);
589 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
590 break;
591 case LibFunc_mempcpy:
592 case LibFunc_memccpy:
593 Changed |= setWillReturn(F);
594 [[fallthrough]];
595 case LibFunc_memcpy_chk:
596 Changed |= setDoesNotThrow(F);
597 Changed |= setDoesNotCallback(F);
598 Changed |= setOnlyAccessesArgMemory(F);
599 Changed |= setDoesNotAlias(F, ArgNo: 0);
600 Changed |= setOnlyWritesMemory(F, ArgNo: 0);
601 Changed |= setDoesNotAlias(F, ArgNo: 1);
602 Changed |= setDoesNotCapture(F, ArgNo: 1);
603 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
604 break;
605 case LibFunc_memalign:
606 Changed |= setAllocFamily(F, Family: "malloc");
607 Changed |= setAllocKind(F, K: AllocFnKind::Alloc | AllocFnKind::Aligned |
608 AllocFnKind::Uninitialized);
609 Changed |= setAllocSize(F, ElemSizeArg: 1, NumElemsArg: std::nullopt);
610 Changed |= setAlignedAllocParam(F, ArgNo: 0);
611 Changed |= setOnlyAccessesInaccessibleMemOrErrnoMem(F);
612 Changed |= setRetNoUndef(F);
613 Changed |= setDoesNotThrow(F);
614 Changed |= setRetDoesNotAlias(F);
615 Changed |= setWillReturn(F);
616 break;
617 case LibFunc_mkdir:
618 Changed |= setRetAndArgsNoUndef(F);
619 Changed |= setDoesNotThrow(F);
620 Changed |= setDoesNotCapture(F, ArgNo: 0);
621 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
622 break;
623 case LibFunc_mktime:
624 Changed |= setRetAndArgsNoUndef(F);
625 Changed |= setDoesNotThrow(F);
626 Changed |= setWillReturn(F);
627 Changed |= setDoesNotCapture(F, ArgNo: 0);
628 break;
629 case LibFunc_realloc:
630 case LibFunc_reallocf:
631 case LibFunc_vec_realloc:
632 Changed |= setAllocFamily(
633 F, Family: TheLibFunc == LibFunc_vec_realloc ? "vec_malloc" : "malloc");
634 Changed |= setAllocKind(F, K: AllocFnKind::Realloc);
635 Changed |= setAllocatedPointerParam(F, ArgNo: 0);
636 Changed |= setAllocSize(F, ElemSizeArg: 1, NumElemsArg: std::nullopt);
637 Changed |= setOnlyAccessesInaccessibleMemOrArgMemOrErrnoMem(F);
638 Changed |= setRetNoUndef(F);
639 Changed |= setDoesNotThrow(F);
640 Changed |= setRetDoesNotAlias(F);
641 Changed |= setWillReturn(F);
642 Changed |= setDoesNotCapture(F, ArgNo: 0);
643 Changed |= setArgNoUndef(F, ArgNo: 1);
644 break;
645 case LibFunc_reallocarray:
646 Changed |= setAllocFamily(F, Family: "malloc");
647 Changed |= setAllocKind(F, K: AllocFnKind::Realloc);
648 Changed |= setAllocatedPointerParam(F, ArgNo: 0);
649 Changed |= setAllocSize(F, ElemSizeArg: 1, NumElemsArg: 2);
650 Changed |= setOnlyAccessesInaccessibleMemOrArgMemOrErrnoMem(F);
651 Changed |= setRetNoUndef(F);
652 Changed |= setDoesNotThrow(F);
653 Changed |= setRetDoesNotAlias(F);
654 Changed |= setWillReturn(F);
655 Changed |= setDoesNotCapture(F, ArgNo: 0);
656 Changed |= setArgNoUndef(F, ArgNo: 1);
657 Changed |= setArgNoUndef(F, ArgNo: 2);
658 break;
659 case LibFunc_read:
660 // May throw; "read" is a valid pthread cancellation point.
661 Changed |= setRetAndArgsNoUndef(F);
662 Changed |= setDoesNotCapture(F, ArgNo: 1);
663 break;
664 case LibFunc_rewind:
665 Changed |= setRetAndArgsNoUndef(F);
666 Changed |= setDoesNotThrow(F);
667 Changed |= setDoesNotCapture(F, ArgNo: 0);
668 break;
669 case LibFunc_rmdir:
670 case LibFunc_remove:
671 case LibFunc_realpath:
672 Changed |= setRetAndArgsNoUndef(F);
673 Changed |= setDoesNotThrow(F);
674 Changed |= setDoesNotCapture(F, ArgNo: 0);
675 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
676 break;
677 case LibFunc_rename:
678 Changed |= setRetAndArgsNoUndef(F);
679 Changed |= setDoesNotThrow(F);
680 Changed |= setDoesNotCapture(F, ArgNo: 0);
681 Changed |= setDoesNotCapture(F, ArgNo: 1);
682 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
683 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
684 break;
685 case LibFunc_readlink:
686 Changed |= setRetAndArgsNoUndef(F);
687 Changed |= setDoesNotThrow(F);
688 Changed |= setDoesNotCapture(F, ArgNo: 0);
689 Changed |= setDoesNotCapture(F, ArgNo: 1);
690 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
691 break;
692 case LibFunc_write:
693 // May throw; "write" is a valid pthread cancellation point.
694 Changed |= setRetAndArgsNoUndef(F);
695 Changed |= setDoesNotCapture(F, ArgNo: 1);
696 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
697 break;
698 case LibFunc_bcopy:
699 Changed |= setDoesNotThrow(F);
700 Changed |= setDoesNotCallback(F);
701 Changed |= setOnlyAccessesArgMemory(F);
702 Changed |= setWillReturn(F);
703 Changed |= setDoesNotCapture(F, ArgNo: 0);
704 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
705 Changed |= setOnlyWritesMemory(F, ArgNo: 1);
706 Changed |= setDoesNotCapture(F, ArgNo: 1);
707 break;
708 case LibFunc_bcmp:
709 Changed |= setDoesNotThrow(F);
710 Changed |= setDoesNotCallback(F);
711 Changed |= setOnlyAccessesArgMemory(F);
712 Changed |= setOnlyReadsMemory(F);
713 Changed |= setWillReturn(F);
714 Changed |= setDoesNotCapture(F, ArgNo: 0);
715 Changed |= setDoesNotCapture(F, ArgNo: 1);
716 break;
717 case LibFunc_bzero:
718 Changed |= setDoesNotThrow(F);
719 Changed |= setDoesNotCallback(F);
720 Changed |= setOnlyAccessesArgMemory(F);
721 Changed |= setWillReturn(F);
722 Changed |= setDoesNotCapture(F, ArgNo: 0);
723 Changed |= setOnlyWritesMemory(F, ArgNo: 0);
724 break;
725 case LibFunc_calloc:
726 case LibFunc_vec_calloc:
727 Changed |= setAllocFamily(F, Family: TheLibFunc == LibFunc_vec_calloc ? "vec_malloc"
728 : "malloc");
729 Changed |= setAllocKind(F, K: AllocFnKind::Alloc | AllocFnKind::Zeroed);
730 Changed |= setAllocSize(F, ElemSizeArg: 0, NumElemsArg: 1);
731 Changed |= setOnlyAccessesInaccessibleMemOrErrnoMem(F);
732 Changed |= setRetAndArgsNoUndef(F);
733 Changed |= setDoesNotThrow(F);
734 Changed |= setRetDoesNotAlias(F);
735 Changed |= setWillReturn(F);
736 break;
737 case LibFunc_chmod:
738 case LibFunc_chown:
739 Changed |= setRetAndArgsNoUndef(F);
740 Changed |= setDoesNotThrow(F);
741 Changed |= setDoesNotCapture(F, ArgNo: 0);
742 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
743 break;
744 case LibFunc_ctermid:
745 case LibFunc_clearerr:
746 case LibFunc_closedir:
747 Changed |= setRetAndArgsNoUndef(F);
748 Changed |= setDoesNotThrow(F);
749 Changed |= setDoesNotCapture(F, ArgNo: 0);
750 break;
751 case LibFunc_atoi:
752 case LibFunc_atol:
753 case LibFunc_atof:
754 case LibFunc_atoll:
755 Changed |= setDoesNotThrow(F);
756 Changed |= setDoesNotCallback(F);
757 Changed |= setOnlyReadsMemory(F);
758 Changed |= setWillReturn(F);
759 Changed |= setDoesNotCapture(F, ArgNo: 0);
760 break;
761 case LibFunc_access:
762 Changed |= setRetAndArgsNoUndef(F);
763 Changed |= setDoesNotThrow(F);
764 Changed |= setDoesNotCapture(F, ArgNo: 0);
765 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
766 break;
767 case LibFunc_fopen:
768 Changed |= setRetAndArgsNoUndef(F);
769 Changed |= setDoesNotThrow(F);
770 Changed |= setRetDoesNotAlias(F);
771 Changed |= setDoesNotCapture(F, ArgNo: 0);
772 Changed |= setDoesNotCapture(F, ArgNo: 1);
773 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
774 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
775 break;
776 case LibFunc_fdopen:
777 Changed |= setRetAndArgsNoUndef(F);
778 Changed |= setDoesNotThrow(F);
779 Changed |= setRetDoesNotAlias(F);
780 Changed |= setDoesNotCapture(F, ArgNo: 1);
781 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
782 break;
783 case LibFunc_feof:
784 Changed |= setRetAndArgsNoUndef(F);
785 Changed |= setDoesNotThrow(F);
786 Changed |= setDoesNotCapture(F, ArgNo: 0);
787 break;
788 case LibFunc_free:
789 case LibFunc_vec_free:
790 Changed |= setAllocFamily(F, Family: TheLibFunc == LibFunc_vec_free ? "vec_malloc"
791 : "malloc");
792 Changed |= setAllocKind(F, K: AllocFnKind::Free);
793 Changed |= setAllocatedPointerParam(F, ArgNo: 0);
794 Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
795 Changed |= setArgsNoUndef(F);
796 Changed |= setDoesNotThrow(F);
797 Changed |= setWillReturn(F);
798 Changed |= setDoesNotCapture(F, ArgNo: 0);
799 break;
800 case LibFunc_fseek:
801 case LibFunc_ftell:
802 case LibFunc_fgetc:
803 case LibFunc_fgetc_unlocked:
804 case LibFunc_fseeko:
805 case LibFunc_ftello:
806 case LibFunc_fileno:
807 case LibFunc_fflush:
808 case LibFunc_fclose:
809 case LibFunc_fsetpos:
810 case LibFunc_flockfile:
811 case LibFunc_funlockfile:
812 case LibFunc_ftrylockfile:
813 Changed |= setRetAndArgsNoUndef(F);
814 Changed |= setDoesNotThrow(F);
815 Changed |= setDoesNotCapture(F, ArgNo: 0);
816 break;
817 case LibFunc_ferror:
818 Changed |= setRetAndArgsNoUndef(F);
819 Changed |= setDoesNotThrow(F);
820 Changed |= setDoesNotCapture(F, ArgNo: 0);
821 Changed |= setOnlyReadsMemory(F);
822 break;
823 case LibFunc_fputc:
824 case LibFunc_fputc_unlocked:
825 case LibFunc_fstat:
826 Changed |= setRetAndArgsNoUndef(F);
827 Changed |= setDoesNotThrow(F);
828 Changed |= setDoesNotCapture(F, ArgNo: 1);
829 break;
830 case LibFunc_frexp:
831 case LibFunc_frexpf:
832 case LibFunc_frexpl:
833 Changed |= setDoesNotThrow(F);
834 Changed |= setDoesNotCallback(F);
835 Changed |= setWillReturn(F);
836 Changed |= setOnlyAccessesArgMemory(F);
837 Changed |= setOnlyWritesMemory(F);
838 Changed |= setDoesNotCapture(F, ArgNo: 1);
839 break;
840 case LibFunc_fstatvfs:
841 Changed |= setRetAndArgsNoUndef(F);
842 Changed |= setDoesNotThrow(F);
843 Changed |= setDoesNotCapture(F, ArgNo: 1);
844 break;
845 case LibFunc_fgets:
846 case LibFunc_fgets_unlocked:
847 Changed |= setRetAndArgsNoUndef(F);
848 Changed |= setDoesNotThrow(F);
849 Changed |= setDoesNotCapture(F, ArgNo: 2);
850 Changed |= setOnlyWritesMemory(F, ArgNo: 0);
851 break;
852 case LibFunc_fread:
853 case LibFunc_fread_unlocked:
854 Changed |= setRetAndArgsNoUndef(F);
855 Changed |= setDoesNotThrow(F);
856 Changed |= setDoesNotCapture(F, ArgNo: 0);
857 Changed |= setDoesNotCapture(F, ArgNo: 3);
858 Changed |= setOnlyWritesMemory(F, ArgNo: 0);
859 break;
860 case LibFunc_fwrite:
861 case LibFunc_fwrite_unlocked:
862 Changed |= setRetAndArgsNoUndef(F);
863 Changed |= setDoesNotThrow(F);
864 Changed |= setDoesNotCapture(F, ArgNo: 0);
865 Changed |= setDoesNotCapture(F, ArgNo: 3);
866 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
867 break;
868 case LibFunc_fputs:
869 case LibFunc_fputs_unlocked:
870 Changed |= setRetAndArgsNoUndef(F);
871 Changed |= setDoesNotThrow(F);
872 Changed |= setDoesNotCapture(F, ArgNo: 0);
873 Changed |= setDoesNotCapture(F, ArgNo: 1);
874 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
875 break;
876 case LibFunc_fscanf:
877 case LibFunc_fprintf:
878 Changed |= setRetAndArgsNoUndef(F);
879 Changed |= setDoesNotThrow(F);
880 Changed |= setDoesNotCapture(F, ArgNo: 0);
881 Changed |= setDoesNotCapture(F, ArgNo: 1);
882 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
883 break;
884 case LibFunc_fgetpos:
885 Changed |= setRetAndArgsNoUndef(F);
886 Changed |= setDoesNotThrow(F);
887 Changed |= setDoesNotCapture(F, ArgNo: 0);
888 Changed |= setDoesNotCapture(F, ArgNo: 1);
889 break;
890 case LibFunc_getc:
891 Changed |= setRetAndArgsNoUndef(F);
892 Changed |= setDoesNotThrow(F);
893 Changed |= setDoesNotCapture(F, ArgNo: 0);
894 break;
895 case LibFunc_getlogin_r:
896 Changed |= setRetAndArgsNoUndef(F);
897 Changed |= setDoesNotThrow(F);
898 Changed |= setDoesNotCapture(F, ArgNo: 0);
899 break;
900 case LibFunc_getc_unlocked:
901 Changed |= setRetAndArgsNoUndef(F);
902 Changed |= setDoesNotThrow(F);
903 Changed |= setDoesNotCapture(F, ArgNo: 0);
904 break;
905 case LibFunc_getenv:
906 Changed |= setRetAndArgsNoUndef(F);
907 Changed |= setDoesNotThrow(F);
908 Changed |= setOnlyReadsMemory(F);
909 Changed |= setDoesNotCapture(F, ArgNo: 0);
910 break;
911 case LibFunc_gets:
912 case LibFunc_getchar:
913 case LibFunc_getchar_unlocked:
914 Changed |= setRetAndArgsNoUndef(F);
915 Changed |= setDoesNotThrow(F);
916 break;
917 case LibFunc_getitimer:
918 Changed |= setRetAndArgsNoUndef(F);
919 Changed |= setDoesNotThrow(F);
920 Changed |= setDoesNotCapture(F, ArgNo: 1);
921 break;
922 case LibFunc_getpwnam:
923 Changed |= setRetAndArgsNoUndef(F);
924 Changed |= setDoesNotThrow(F);
925 Changed |= setDoesNotCapture(F, ArgNo: 0);
926 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
927 break;
928 case LibFunc_ungetc:
929 Changed |= setRetAndArgsNoUndef(F);
930 Changed |= setDoesNotThrow(F);
931 Changed |= setDoesNotCapture(F, ArgNo: 1);
932 break;
933 case LibFunc_uname:
934 Changed |= setRetAndArgsNoUndef(F);
935 Changed |= setDoesNotThrow(F);
936 Changed |= setDoesNotCapture(F, ArgNo: 0);
937 break;
938 case LibFunc_unlink:
939 Changed |= setRetAndArgsNoUndef(F);
940 Changed |= setDoesNotThrow(F);
941 Changed |= setDoesNotCapture(F, ArgNo: 0);
942 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
943 break;
944 case LibFunc_unsetenv:
945 Changed |= setRetAndArgsNoUndef(F);
946 Changed |= setDoesNotThrow(F);
947 Changed |= setDoesNotCapture(F, ArgNo: 0);
948 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
949 break;
950 case LibFunc_utime:
951 case LibFunc_utimes:
952 Changed |= setRetAndArgsNoUndef(F);
953 Changed |= setDoesNotThrow(F);
954 Changed |= setDoesNotCapture(F, ArgNo: 0);
955 Changed |= setDoesNotCapture(F, ArgNo: 1);
956 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
957 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
958 break;
959 case LibFunc_putc:
960 case LibFunc_putc_unlocked:
961 Changed |= setRetAndArgsNoUndef(F);
962 Changed |= setDoesNotThrow(F);
963 Changed |= setDoesNotCapture(F, ArgNo: 1);
964 break;
965 case LibFunc_puts:
966 case LibFunc_printf:
967 case LibFunc_perror:
968 Changed |= setRetAndArgsNoUndef(F);
969 Changed |= setDoesNotThrow(F);
970 Changed |= setDoesNotCapture(F, ArgNo: 0);
971 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
972 break;
973 case LibFunc_pread:
974 // May throw; "pread" is a valid pthread cancellation point.
975 Changed |= setRetAndArgsNoUndef(F);
976 Changed |= setDoesNotCapture(F, ArgNo: 1);
977 break;
978 case LibFunc_pwrite:
979 // May throw; "pwrite" is a valid pthread cancellation point.
980 Changed |= setRetAndArgsNoUndef(F);
981 Changed |= setDoesNotCapture(F, ArgNo: 1);
982 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
983 break;
984 case LibFunc_putchar:
985 case LibFunc_putchar_unlocked:
986 Changed |= setRetAndArgsNoUndef(F);
987 Changed |= setDoesNotThrow(F);
988 break;
989 case LibFunc_popen:
990 Changed |= setRetAndArgsNoUndef(F);
991 Changed |= setDoesNotThrow(F);
992 Changed |= setRetDoesNotAlias(F);
993 Changed |= setDoesNotCapture(F, ArgNo: 0);
994 Changed |= setDoesNotCapture(F, ArgNo: 1);
995 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
996 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
997 break;
998 case LibFunc_pclose:
999 Changed |= setRetAndArgsNoUndef(F);
1000 Changed |= setDoesNotThrow(F);
1001 Changed |= setDoesNotCapture(F, ArgNo: 0);
1002 break;
1003 case LibFunc_vscanf:
1004 Changed |= setRetAndArgsNoUndef(F);
1005 Changed |= setDoesNotThrow(F);
1006 Changed |= setDoesNotCapture(F, ArgNo: 0);
1007 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1008 break;
1009 case LibFunc_vsscanf:
1010 Changed |= setRetAndArgsNoUndef(F);
1011 Changed |= setDoesNotThrow(F);
1012 Changed |= setDoesNotCapture(F, ArgNo: 0);
1013 Changed |= setDoesNotCapture(F, ArgNo: 1);
1014 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1015 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
1016 break;
1017 case LibFunc_vfscanf:
1018 Changed |= setRetAndArgsNoUndef(F);
1019 Changed |= setDoesNotThrow(F);
1020 Changed |= setDoesNotCapture(F, ArgNo: 0);
1021 Changed |= setDoesNotCapture(F, ArgNo: 1);
1022 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
1023 break;
1024 case LibFunc_vprintf:
1025 Changed |= setRetAndArgsNoUndef(F);
1026 Changed |= setDoesNotThrow(F);
1027 Changed |= setDoesNotCapture(F, ArgNo: 0);
1028 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1029 break;
1030 case LibFunc_vfprintf:
1031 case LibFunc_vsprintf:
1032 Changed |= setRetAndArgsNoUndef(F);
1033 Changed |= setDoesNotThrow(F);
1034 Changed |= setDoesNotCapture(F, ArgNo: 0);
1035 Changed |= setDoesNotCapture(F, ArgNo: 1);
1036 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
1037 break;
1038 case LibFunc_vsnprintf:
1039 Changed |= setRetAndArgsNoUndef(F);
1040 Changed |= setDoesNotThrow(F);
1041 Changed |= setDoesNotCapture(F, ArgNo: 0);
1042 Changed |= setDoesNotCapture(F, ArgNo: 2);
1043 Changed |= setOnlyReadsMemory(F, ArgNo: 2);
1044 break;
1045 case LibFunc_open:
1046 // May throw; "open" is a valid pthread cancellation point.
1047 Changed |= setRetAndArgsNoUndef(F);
1048 Changed |= setDoesNotCapture(F, ArgNo: 0);
1049 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1050 break;
1051 case LibFunc_opendir:
1052 Changed |= setRetAndArgsNoUndef(F);
1053 Changed |= setDoesNotThrow(F);
1054 Changed |= setRetDoesNotAlias(F);
1055 Changed |= setDoesNotCapture(F, ArgNo: 0);
1056 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1057 break;
1058 case LibFunc_tmpfile:
1059 Changed |= setRetAndArgsNoUndef(F);
1060 Changed |= setDoesNotThrow(F);
1061 Changed |= setRetDoesNotAlias(F);
1062 break;
1063 case LibFunc_times:
1064 Changed |= setRetAndArgsNoUndef(F);
1065 Changed |= setDoesNotThrow(F);
1066 Changed |= setDoesNotCapture(F, ArgNo: 0);
1067 break;
1068 case LibFunc_htonl:
1069 case LibFunc_htons:
1070 case LibFunc_ntohl:
1071 case LibFunc_ntohs:
1072 Changed |= setDoesNotThrow(F);
1073 Changed |= setDoesNotCallback(F);
1074 Changed |= setDoesNotAccessMemory(F);
1075 break;
1076 case LibFunc_lstat:
1077 Changed |= setRetAndArgsNoUndef(F);
1078 Changed |= setDoesNotThrow(F);
1079 Changed |= setDoesNotCapture(F, ArgNo: 0);
1080 Changed |= setDoesNotCapture(F, ArgNo: 1);
1081 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1082 break;
1083 case LibFunc_lchown:
1084 Changed |= setRetAndArgsNoUndef(F);
1085 Changed |= setDoesNotThrow(F);
1086 Changed |= setDoesNotCapture(F, ArgNo: 0);
1087 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1088 break;
1089 case LibFunc_qsort:
1090 // May throw/callback; places call through function pointer.
1091 // Cannot give undef pointer/size
1092 Changed |= setRetAndArgsNoUndef(F);
1093 Changed |= setDoesNotCapture(F, ArgNo: 3);
1094 break;
1095 case LibFunc_dunder_strndup:
1096 Changed |= setArgNoUndef(F, ArgNo: 1);
1097 [[fallthrough]];
1098 case LibFunc_dunder_strdup:
1099 Changed |= setDoesNotThrow(F);
1100 Changed |= setRetDoesNotAlias(F);
1101 Changed |= setWillReturn(F);
1102 Changed |= setDoesNotCapture(F, ArgNo: 0);
1103 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1104 break;
1105 case LibFunc_dunder_strtok_r:
1106 Changed |= setDoesNotThrow(F);
1107 Changed |= setDoesNotCallback(F);
1108 Changed |= setDoesNotCapture(F, ArgNo: 1);
1109 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
1110 break;
1111 case LibFunc_under_IO_getc:
1112 Changed |= setRetAndArgsNoUndef(F);
1113 Changed |= setDoesNotThrow(F);
1114 Changed |= setDoesNotCapture(F, ArgNo: 0);
1115 break;
1116 case LibFunc_under_IO_putc:
1117 Changed |= setRetAndArgsNoUndef(F);
1118 Changed |= setDoesNotThrow(F);
1119 Changed |= setDoesNotCapture(F, ArgNo: 1);
1120 break;
1121 case LibFunc_dunder_isoc99_scanf:
1122 Changed |= setRetAndArgsNoUndef(F);
1123 Changed |= setDoesNotThrow(F);
1124 Changed |= setDoesNotCapture(F, ArgNo: 0);
1125 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1126 break;
1127 case LibFunc_stat64:
1128 case LibFunc_lstat64:
1129 case LibFunc_statvfs64:
1130 Changed |= setRetAndArgsNoUndef(F);
1131 Changed |= setDoesNotThrow(F);
1132 Changed |= setDoesNotCapture(F, ArgNo: 0);
1133 Changed |= setDoesNotCapture(F, ArgNo: 1);
1134 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1135 break;
1136 case LibFunc_dunder_isoc99_sscanf:
1137 Changed |= setRetAndArgsNoUndef(F);
1138 Changed |= setDoesNotThrow(F);
1139 Changed |= setDoesNotCapture(F, ArgNo: 0);
1140 Changed |= setDoesNotCapture(F, ArgNo: 1);
1141 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1142 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
1143 break;
1144 case LibFunc_fopen64:
1145 Changed |= setRetAndArgsNoUndef(F);
1146 Changed |= setDoesNotThrow(F);
1147 Changed |= setRetDoesNotAlias(F);
1148 Changed |= setDoesNotCapture(F, ArgNo: 0);
1149 Changed |= setDoesNotCapture(F, ArgNo: 1);
1150 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1151 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
1152 break;
1153 case LibFunc_fseeko64:
1154 case LibFunc_ftello64:
1155 Changed |= setRetAndArgsNoUndef(F);
1156 Changed |= setDoesNotThrow(F);
1157 Changed |= setDoesNotCapture(F, ArgNo: 0);
1158 break;
1159 case LibFunc_tmpfile64:
1160 Changed |= setRetAndArgsNoUndef(F);
1161 Changed |= setDoesNotThrow(F);
1162 Changed |= setRetDoesNotAlias(F);
1163 break;
1164 case LibFunc_fstat64:
1165 case LibFunc_fstatvfs64:
1166 Changed |= setRetAndArgsNoUndef(F);
1167 Changed |= setDoesNotThrow(F);
1168 Changed |= setDoesNotCapture(F, ArgNo: 1);
1169 break;
1170 case LibFunc_open64:
1171 // May throw; "open" is a valid pthread cancellation point.
1172 Changed |= setRetAndArgsNoUndef(F);
1173 Changed |= setDoesNotCapture(F, ArgNo: 0);
1174 Changed |= setOnlyReadsMemory(F, ArgNo: 0);
1175 break;
1176 case LibFunc_gettimeofday:
1177 // Currently some platforms have the restrict keyword on the arguments to
1178 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
1179 // arguments.
1180 Changed |= setRetAndArgsNoUndef(F);
1181 Changed |= setDoesNotThrow(F);
1182 Changed |= setDoesNotCapture(F, ArgNo: 0);
1183 Changed |= setDoesNotCapture(F, ArgNo: 1);
1184 break;
1185 case LibFunc_memset_pattern4:
1186 case LibFunc_memset_pattern8:
1187 case LibFunc_memset_pattern16:
1188 Changed |= setDoesNotCapture(F, ArgNo: 0);
1189 Changed |= setDoesNotCapture(F, ArgNo: 1);
1190 Changed |= setOnlyReadsMemory(F, ArgNo: 1);
1191 [[fallthrough]];
1192 case LibFunc_memset:
1193 Changed |= setWillReturn(F);
1194 [[fallthrough]];
1195 case LibFunc_memset_chk:
1196 Changed |= setOnlyAccessesArgMemory(F);
1197 Changed |= setOnlyWritesMemory(F, ArgNo: 0);
1198 Changed |= setDoesNotThrow(F);
1199 Changed |= setDoesNotCallback(F);
1200 break;
1201 case LibFunc_abort:
1202 Changed |= setIsCold(F);
1203 Changed |= setNoReturn(F);
1204 Changed |= setDoesNotThrow(F);
1205 break;
1206 case LibFunc_terminate:
1207 // May callback; terminate_handler may be called
1208 Changed |= setIsCold(F);
1209 Changed |= setNoReturn(F);
1210 break;
1211 case LibFunc_cxa_throw:
1212 Changed |= setIsCold(F);
1213 Changed |= setNoReturn(F);
1214 // Don't add `nofree` on `__cxa_throw`
1215 return Changed;
1216 // int __nvvm_reflect(const char *)
1217 case LibFunc_nvvm_reflect:
1218 Changed |= setRetAndArgsNoUndef(F);
1219 Changed |= setDoesNotAccessMemory(F);
1220 Changed |= setDoesNotThrow(F);
1221 break;
1222 case LibFunc_acos:
1223 case LibFunc_acosf:
1224 case LibFunc_acosh:
1225 case LibFunc_acoshf:
1226 case LibFunc_acoshl:
1227 case LibFunc_acosl:
1228 case LibFunc_asin:
1229 case LibFunc_asinf:
1230 case LibFunc_asinh:
1231 case LibFunc_asinhf:
1232 case LibFunc_asinhl:
1233 case LibFunc_asinl:
1234 case LibFunc_atan:
1235 case LibFunc_atan2:
1236 case LibFunc_atan2f:
1237 case LibFunc_atan2l:
1238 case LibFunc_atanf:
1239 case LibFunc_atanh:
1240 case LibFunc_atanhf:
1241 case LibFunc_atanhl:
1242 case LibFunc_atanl:
1243 case LibFunc_cos:
1244 case LibFunc_cosh:
1245 case LibFunc_coshf:
1246 case LibFunc_coshl:
1247 case LibFunc_cosf:
1248 case LibFunc_cosl:
1249 case LibFunc_cospi:
1250 case LibFunc_cospif:
1251 case LibFunc_erf:
1252 case LibFunc_erff:
1253 case LibFunc_erfl:
1254 case LibFunc_tgamma:
1255 case LibFunc_tgammaf:
1256 case LibFunc_tgammal:
1257 case LibFunc_exp:
1258 case LibFunc_expf:
1259 case LibFunc_expl:
1260 case LibFunc_exp2:
1261 case LibFunc_exp2f:
1262 case LibFunc_exp2l:
1263 case LibFunc_expm1:
1264 case LibFunc_expm1f:
1265 case LibFunc_expm1l:
1266 case LibFunc_fdim:
1267 case LibFunc_fdiml:
1268 case LibFunc_fdimf:
1269 case LibFunc_fmod:
1270 case LibFunc_fmodf:
1271 case LibFunc_fmodl:
1272 case LibFunc_hypot:
1273 case LibFunc_hypotf:
1274 case LibFunc_hypotl:
1275 case LibFunc_ldexp:
1276 case LibFunc_ldexpf:
1277 case LibFunc_ldexpl:
1278 case LibFunc_log:
1279 case LibFunc_log10:
1280 case LibFunc_log10f:
1281 case LibFunc_log10l:
1282 case LibFunc_log1p:
1283 case LibFunc_log1pf:
1284 case LibFunc_log1pl:
1285 case LibFunc_log2:
1286 case LibFunc_log2f:
1287 case LibFunc_log2l:
1288 case LibFunc_logb:
1289 case LibFunc_logbf:
1290 case LibFunc_logbl:
1291 case LibFunc_ilogb:
1292 case LibFunc_ilogbf:
1293 case LibFunc_ilogbl:
1294 case LibFunc_logf:
1295 case LibFunc_logl:
1296 case LibFunc_nextafter:
1297 case LibFunc_nextafterf:
1298 case LibFunc_nextafterl:
1299 case LibFunc_nexttoward:
1300 case LibFunc_nexttowardf:
1301 case LibFunc_nexttowardl:
1302 case LibFunc_pow:
1303 case LibFunc_powf:
1304 case LibFunc_powl:
1305 case LibFunc_remainder:
1306 case LibFunc_remainderf:
1307 case LibFunc_remainderl:
1308 case LibFunc_rint:
1309 case LibFunc_rintf:
1310 case LibFunc_rintl:
1311 case LibFunc_scalbln:
1312 case LibFunc_scalblnf:
1313 case LibFunc_scalblnl:
1314 case LibFunc_scalbn:
1315 case LibFunc_scalbnf:
1316 case LibFunc_scalbnl:
1317 case LibFunc_sin:
1318 case LibFunc_sincospif_stret:
1319 case LibFunc_sinf:
1320 case LibFunc_sinh:
1321 case LibFunc_sinhf:
1322 case LibFunc_sinhl:
1323 case LibFunc_sinl:
1324 case LibFunc_sinpi:
1325 case LibFunc_sinpif:
1326 case LibFunc_sqrt:
1327 case LibFunc_sqrtf:
1328 case LibFunc_sqrtl:
1329 case LibFunc_tan:
1330 case LibFunc_tanf:
1331 case LibFunc_tanh:
1332 case LibFunc_tanhf:
1333 case LibFunc_tanhl:
1334 case LibFunc_tanl:
1335 Changed |= setDoesNotThrow(F);
1336 Changed |= setDoesNotCallback(F);
1337 Changed |= setDoesNotFreeMemory(F);
1338 Changed |= setWillReturn(F);
1339 Changed |= setOnlyWritesErrnoMemory(F);
1340 break;
1341 case LibFunc_abs:
1342 case LibFunc_cbrt:
1343 case LibFunc_cbrtf:
1344 case LibFunc_cbrtl:
1345 case LibFunc_copysign:
1346 case LibFunc_copysignf:
1347 case LibFunc_copysignl:
1348 case LibFunc_ceil:
1349 case LibFunc_ceilf:
1350 case LibFunc_ceill:
1351 case LibFunc_fabs:
1352 case LibFunc_fabsf:
1353 case LibFunc_fabsl:
1354 case LibFunc_ffs:
1355 case LibFunc_ffsl:
1356 case LibFunc_ffsll:
1357 case LibFunc_floor:
1358 case LibFunc_floorf:
1359 case LibFunc_floorl:
1360 case LibFunc_fls:
1361 case LibFunc_flsl:
1362 case LibFunc_flsll:
1363 case LibFunc_fmax:
1364 case LibFunc_fmaxf:
1365 case LibFunc_fmaxl:
1366 case LibFunc_fmin:
1367 case LibFunc_fminf:
1368 case LibFunc_fminl:
1369 case LibFunc_fmaximum_num:
1370 case LibFunc_fmaximum_numf:
1371 case LibFunc_fmaximum_numl:
1372 case LibFunc_fminimum_num:
1373 case LibFunc_fminimum_numf:
1374 case LibFunc_fminimum_numl:
1375 case LibFunc_labs:
1376 case LibFunc_llabs:
1377 case LibFunc_nearbyint:
1378 case LibFunc_nearbyintf:
1379 case LibFunc_nearbyintl:
1380 case LibFunc_round:
1381 case LibFunc_roundf:
1382 case LibFunc_roundl:
1383 case LibFunc_roundeven:
1384 case LibFunc_roundevenf:
1385 case LibFunc_roundevenl:
1386 case LibFunc_toascii:
1387 case LibFunc_trunc:
1388 case LibFunc_truncf:
1389 case LibFunc_truncl:
1390 Changed |= setDoesNotAccessMemory(F);
1391 [[fallthrough]];
1392 case LibFunc_isascii:
1393 case LibFunc_isdigit:
1394 Changed |= setDoesNotThrow(F);
1395 Changed |= setDoesNotCallback(F);
1396 Changed |= setDoesNotFreeMemory(F);
1397 Changed |= setWillReturn(F);
1398 break;
1399 case LibFunc_sincos:
1400 case LibFunc_sincosf:
1401 case LibFunc_sincosl:
1402 Changed |= setDoesNotCapture(F, ArgNo: 1);
1403 Changed |= setOnlyWritesMemory(F, ArgNo: 1);
1404 [[fallthrough]];
1405 case LibFunc_remquo:
1406 case LibFunc_remquof:
1407 case LibFunc_remquol:
1408 Changed |= setDoesNotThrow(F);
1409 Changed |= setDoesNotCallback(F);
1410 Changed |= setDoesNotFreeMemory(F);
1411 Changed |= setOnlyWritesMemory(F, ArgNo: 2);
1412 Changed |= setDoesNotCapture(F, ArgNo: 2);
1413 Changed |= setWillReturn(F);
1414 Changed |= setOnlyWritesArgMemOrErrnoMem(F);
1415 break;
1416 default:
1417 // FIXME: It'd be really nice to cover all the library functions we're
1418 // aware of here.
1419 break;
1420 }
1421 // We have to do this step after AllocKind has been inferred on functions so
1422 // we can reliably identify free-like and realloc-like functions.
1423 if (!isLibFreeFunction(F: &F, TLIFn: TheLibFunc) && !isReallocLikeFn(F: &F))
1424 Changed |= setDoesNotFreeMemory(F);
1425 return Changed;
1426}
1427
1428static void setArgExtAttr(Function &F, unsigned ArgNo,
1429 const TargetLibraryInfo &TLI, bool Signed = true) {
1430 Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Param(Signed);
1431 if (ExtAttr != Attribute::None && !F.hasParamAttribute(ArgNo, Kind: ExtAttr))
1432 F.addParamAttr(ArgNo, Kind: ExtAttr);
1433}
1434
1435static void setRetExtAttr(Function &F,
1436 const TargetLibraryInfo &TLI, bool Signed = true) {
1437 Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Return(Signed);
1438 if (ExtAttr != Attribute::None && !F.hasRetAttribute(Kind: ExtAttr))
1439 F.addRetAttr(Kind: ExtAttr);
1440}
1441
1442// Modeled after X86TargetLowering::markLibCallAttributes.
1443void llvm::markRegisterParameterAttributes(Function *F) {
1444 if (!F->arg_size() || F->isVarArg())
1445 return;
1446
1447 const CallingConv::ID CC = F->getCallingConv();
1448 if (CC != CallingConv::C && CC != CallingConv::X86_StdCall)
1449 return;
1450
1451 const Module *M = F->getParent();
1452 unsigned N = M->getNumberRegisterParameters();
1453 if (!N)
1454 return;
1455
1456 const DataLayout &DL = M->getDataLayout();
1457
1458 for (Argument &A : F->args()) {
1459 Type *T = A.getType();
1460 if (!T->isIntOrPtrTy())
1461 continue;
1462
1463 const TypeSize &TS = DL.getTypeAllocSize(Ty: T);
1464 if (TS > 8)
1465 continue;
1466
1467 assert(TS <= 4 && "Need to account for parameters larger than word size");
1468 const unsigned NumRegs = TS > 4 ? 2 : 1;
1469 if (N < NumRegs)
1470 return;
1471
1472 N -= NumRegs;
1473 F->addParamAttr(ArgNo: A.getArgNo(), Kind: Attribute::InReg);
1474 }
1475}
1476
1477FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,
1478 LibFunc TheLibFunc, FunctionType *T,
1479 AttributeList AttributeList) {
1480 assert(TLI.has(TheLibFunc) &&
1481 "Creating call to non-existing library function.");
1482 StringRef Name = TLI.getName(F: TheLibFunc);
1483 FunctionCallee C = M->getOrInsertFunction(Name, T, AttributeList);
1484
1485 // Make sure any mandatory argument attributes are added.
1486
1487 // Any outgoing i32 argument should be handled with setArgExtAttr() which
1488 // will add an extension attribute if the target ABI requires it. Adding
1489 // argument extensions is typically done by the front end but when an
1490 // optimizer is building a library call on its own it has to take care of
1491 // this. Each such generated function must be handled here with sign or
1492 // zero extensions as needed. F is retreived with cast<> because we demand
1493 // of the caller to have called isLibFuncEmittable() first.
1494 Function *F = cast<Function>(Val: C.getCallee());
1495 assert(F->getFunctionType() == T && "Function type does not match.");
1496 switch (TheLibFunc) {
1497 case LibFunc_fputc:
1498 case LibFunc_putchar:
1499 setArgExtAttr(F&: *F, ArgNo: 0, TLI);
1500 break;
1501 case LibFunc_ldexp:
1502 case LibFunc_ldexpf:
1503 case LibFunc_ldexpl:
1504 case LibFunc_memchr:
1505 case LibFunc_memrchr:
1506 case LibFunc_strchr:
1507 setArgExtAttr(F&: *F, ArgNo: 1, TLI);
1508 break;
1509 case LibFunc_memccpy:
1510 setArgExtAttr(F&: *F, ArgNo: 2, TLI);
1511 break;
1512
1513 // These are functions that are known to not need any argument extension
1514 // on any target: A size_t argument (which may be an i32 on some targets)
1515 // should not trigger the assert below.
1516 case LibFunc_bcmp:
1517 setRetExtAttr(F&: *F, TLI);
1518 break;
1519 case LibFunc_calloc:
1520 case LibFunc_fwrite:
1521 case LibFunc_malloc:
1522 case LibFunc_memcmp:
1523 case LibFunc_memcpy_chk:
1524 case LibFunc_mempcpy:
1525 case LibFunc_memset_pattern16:
1526 case LibFunc_snprintf:
1527 case LibFunc_stpncpy:
1528 case LibFunc_strlcat:
1529 case LibFunc_strlcpy:
1530 case LibFunc_strncat:
1531 case LibFunc_strncmp:
1532 case LibFunc_strncpy:
1533 case LibFunc_vsnprintf:
1534 break;
1535
1536 default:
1537#ifndef NDEBUG
1538 for (unsigned i = 0; i < T->getNumParams(); i++)
1539 assert(!isa<IntegerType>(T->getParamType(i)) &&
1540 "Unhandled integer argument.");
1541#endif
1542 break;
1543 }
1544
1545 markRegisterParameterAttributes(F);
1546
1547 return C;
1548}
1549
1550FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,
1551 LibFunc TheLibFunc, FunctionType *T) {
1552 return getOrInsertLibFunc(M, TLI, TheLibFunc, T, AttributeList: AttributeList());
1553}
1554
1555bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,
1556 LibFunc TheLibFunc) {
1557 StringRef FuncName = TLI->getName(F: TheLibFunc);
1558 if (!TLI->has(F: TheLibFunc))
1559 return false;
1560
1561 // Check if the Module already has a GlobalValue with the same name, in
1562 // which case it must be a Function with the expected type.
1563 if (GlobalValue *GV = M->getNamedValue(Name: FuncName)) {
1564 if (auto *F = dyn_cast<Function>(Val: GV))
1565 return TLI->isValidProtoForLibFunc(FTy: *F->getFunctionType(), F: TheLibFunc, M: *M);
1566 return false;
1567 }
1568
1569 return true;
1570}
1571
1572bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,
1573 StringRef Name) {
1574 LibFunc TheLibFunc;
1575 return TLI->getLibFunc(funcName: Name, F&: TheLibFunc) &&
1576 isLibFuncEmittable(M, TLI, TheLibFunc);
1577}
1578
1579bool llvm::hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty,
1580 LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) {
1581 switch (Ty->getTypeID()) {
1582 case Type::HalfTyID:
1583 return false;
1584 case Type::FloatTyID:
1585 return isLibFuncEmittable(M, TLI, TheLibFunc: FloatFn);
1586 case Type::DoubleTyID:
1587 return isLibFuncEmittable(M, TLI, TheLibFunc: DoubleFn);
1588 default:
1589 return isLibFuncEmittable(M, TLI, TheLibFunc: LongDoubleFn);
1590 }
1591}
1592
1593StringRef llvm::getFloatFn(const Module *M, const TargetLibraryInfo *TLI,
1594 Type *Ty, LibFunc DoubleFn, LibFunc FloatFn,
1595 LibFunc LongDoubleFn, LibFunc &TheLibFunc) {
1596 assert(hasFloatFn(M, TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
1597 "Cannot get name for unavailable function!");
1598
1599 switch (Ty->getTypeID()) {
1600 case Type::HalfTyID:
1601 llvm_unreachable("No name for HalfTy!");
1602 case Type::FloatTyID:
1603 TheLibFunc = FloatFn;
1604 return TLI->getName(F: FloatFn);
1605 case Type::DoubleTyID:
1606 TheLibFunc = DoubleFn;
1607 return TLI->getName(F: DoubleFn);
1608 default:
1609 TheLibFunc = LongDoubleFn;
1610 return TLI->getName(F: LongDoubleFn);
1611 }
1612}
1613
1614//- Emit LibCalls ------------------------------------------------------------//
1615
1616static IntegerType *getIntTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) {
1617 return B.getIntNTy(N: TLI->getIntSize());
1618}
1619
1620static IntegerType *getSizeTTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) {
1621 const Module *M = B.GetInsertBlock()->getModule();
1622 return B.getIntNTy(N: TLI->getSizeTSize(M: *M));
1623}
1624
1625static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType,
1626 ArrayRef<Type *> ParamTypes,
1627 ArrayRef<Value *> Operands, IRBuilderBase &B,
1628 const TargetLibraryInfo *TLI,
1629 bool IsVaArgs = false) {
1630 Module *M = B.GetInsertBlock()->getModule();
1631 if (!isLibFuncEmittable(M, TLI, TheLibFunc))
1632 return nullptr;
1633
1634 StringRef FuncName = TLI->getName(F: TheLibFunc);
1635 FunctionType *FuncType = FunctionType::get(Result: ReturnType, Params: ParamTypes, isVarArg: IsVaArgs);
1636 FunctionCallee Callee = getOrInsertLibFunc(M, TLI: *TLI, TheLibFunc, T: FuncType);
1637 inferNonMandatoryLibFuncAttrs(M, Name: FuncName, TLI: *TLI);
1638 CallInst *CI = B.CreateCall(Callee, Args: Operands, Name: FuncName);
1639 if (const Function *F =
1640 dyn_cast<Function>(Val: Callee.getCallee()->stripPointerCasts()))
1641 CI->setCallingConv(F->getCallingConv());
1642 return CI;
1643}
1644
1645Value *llvm::emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,
1646 const TargetLibraryInfo *TLI) {
1647 Type *CharPtrTy = B.getPtrTy();
1648 Type *SizeTTy = getSizeTTy(B, TLI);
1649 return emitLibCall(TheLibFunc: LibFunc_strlen, ReturnType: SizeTTy, ParamTypes: CharPtrTy, Operands: Ptr, B, TLI);
1650}
1651
1652Value *llvm::emitWcsLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,
1653 const TargetLibraryInfo *TLI) {
1654 assert(Ptr && Ptr->getType()->isPointerTy() &&
1655 "Argument to wcslen intrinsic must be a pointer.");
1656 Type *PtrTy = B.getPtrTy();
1657 Type *SizeTTy = getSizeTTy(B, TLI);
1658 return emitLibCall(TheLibFunc: LibFunc_wcslen, ReturnType: SizeTTy, ParamTypes: PtrTy, Operands: Ptr, B, TLI);
1659}
1660
1661Value *llvm::emitStrDup(Value *Ptr, IRBuilderBase &B,
1662 const TargetLibraryInfo *TLI) {
1663 Type *CharPtrTy = B.getPtrTy();
1664 return emitLibCall(TheLibFunc: LibFunc_strdup, ReturnType: CharPtrTy, ParamTypes: CharPtrTy, Operands: Ptr, B, TLI);
1665}
1666
1667Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilderBase &B,
1668 const TargetLibraryInfo *TLI) {
1669 Type *CharPtrTy = B.getPtrTy();
1670 Type *IntTy = getIntTy(B, TLI);
1671 return emitLibCall(TheLibFunc: LibFunc_strchr, ReturnType: CharPtrTy, ParamTypes: {CharPtrTy, IntTy},
1672 Operands: {Ptr, ConstantInt::get(Ty: IntTy, V: C)}, B, TLI);
1673}
1674
1675Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
1676 const DataLayout &DL, const TargetLibraryInfo *TLI) {
1677 Type *CharPtrTy = B.getPtrTy();
1678 Type *IntTy = getIntTy(B, TLI);
1679 Type *SizeTTy = getSizeTTy(B, TLI);
1680 return emitLibCall(
1681 TheLibFunc: LibFunc_strncmp, ReturnType: IntTy,
1682 ParamTypes: {CharPtrTy, CharPtrTy, SizeTTy},
1683 Operands: {Ptr1, Ptr2, Len}, B, TLI);
1684}
1685
1686Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B,
1687 const TargetLibraryInfo *TLI) {
1688 Type *CharPtrTy = Dst->getType();
1689 return emitLibCall(TheLibFunc: LibFunc_strcpy, ReturnType: CharPtrTy, ParamTypes: {CharPtrTy, CharPtrTy},
1690 Operands: {Dst, Src}, B, TLI);
1691}
1692
1693Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B,
1694 const TargetLibraryInfo *TLI) {
1695 Type *CharPtrTy = B.getPtrTy();
1696 return emitLibCall(TheLibFunc: LibFunc_stpcpy, ReturnType: CharPtrTy, ParamTypes: {CharPtrTy, CharPtrTy},
1697 Operands: {Dst, Src}, B, TLI);
1698}
1699
1700Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
1701 const TargetLibraryInfo *TLI) {
1702 Type *CharPtrTy = B.getPtrTy();
1703 Type *SizeTTy = getSizeTTy(B, TLI);
1704 return emitLibCall(TheLibFunc: LibFunc_strncpy, ReturnType: CharPtrTy, ParamTypes: {CharPtrTy, CharPtrTy, SizeTTy},
1705 Operands: {Dst, Src, Len}, B, TLI);
1706}
1707
1708Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
1709 const TargetLibraryInfo *TLI) {
1710 Type *CharPtrTy = B.getPtrTy();
1711 Type *SizeTTy = getSizeTTy(B, TLI);
1712 return emitLibCall(TheLibFunc: LibFunc_stpncpy, ReturnType: CharPtrTy, ParamTypes: {CharPtrTy, CharPtrTy, SizeTTy},
1713 Operands: {Dst, Src, Len}, B, TLI);
1714}
1715
1716Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
1717 IRBuilderBase &B, const DataLayout &DL,
1718 const TargetLibraryInfo *TLI) {
1719 Module *M = B.GetInsertBlock()->getModule();
1720 if (!isLibFuncEmittable(M, TLI, TheLibFunc: LibFunc_memcpy_chk))
1721 return nullptr;
1722
1723 AttributeList AS;
1724 AS = AttributeList::get(C&: M->getContext(), Index: AttributeList::FunctionIndex,
1725 Kinds: Attribute::NoUnwind);
1726 Type *VoidPtrTy = B.getPtrTy();
1727 Type *SizeTTy = getSizeTTy(B, TLI);
1728 FunctionCallee MemCpy = getOrInsertLibFunc(M, TLI: *TLI, TheLibFunc: LibFunc_memcpy_chk,
1729 AttributeList: AttributeList::get(C&: M->getContext(), Attrs: AS), RetTy: VoidPtrTy,
1730 Args: VoidPtrTy, Args: VoidPtrTy, Args: SizeTTy, Args: SizeTTy);
1731 CallInst *CI = B.CreateCall(Callee: MemCpy, Args: {Dst, Src, Len, ObjSize});
1732 if (const Function *F =
1733 dyn_cast<Function>(Val: MemCpy.getCallee()->stripPointerCasts()))
1734 CI->setCallingConv(F->getCallingConv());
1735 return CI;
1736}
1737
1738Value *llvm::emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
1739 const DataLayout &DL, const TargetLibraryInfo *TLI) {
1740 Type *VoidPtrTy = B.getPtrTy();
1741 Type *SizeTTy = getSizeTTy(B, TLI);
1742 return emitLibCall(TheLibFunc: LibFunc_mempcpy, ReturnType: VoidPtrTy,
1743 ParamTypes: {VoidPtrTy, VoidPtrTy, SizeTTy},
1744 Operands: {Dst, Src, Len}, B, TLI);
1745}
1746
1747Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
1748 const DataLayout &DL, const TargetLibraryInfo *TLI) {
1749 Type *VoidPtrTy = B.getPtrTy();
1750 Type *IntTy = getIntTy(B, TLI);
1751 Type *SizeTTy = getSizeTTy(B, TLI);
1752 return emitLibCall(TheLibFunc: LibFunc_memchr, ReturnType: VoidPtrTy,
1753 ParamTypes: {VoidPtrTy, IntTy, SizeTTy},
1754 Operands: {Ptr, Val, Len}, B, TLI);
1755}
1756
1757Value *llvm::emitMemRChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
1758 const DataLayout &DL, const TargetLibraryInfo *TLI) {
1759 Type *VoidPtrTy = B.getPtrTy();
1760 Type *IntTy = getIntTy(B, TLI);
1761 Type *SizeTTy = getSizeTTy(B, TLI);
1762 return emitLibCall(TheLibFunc: LibFunc_memrchr, ReturnType: VoidPtrTy,
1763 ParamTypes: {VoidPtrTy, IntTy, SizeTTy},
1764 Operands: {Ptr, Val, Len}, B, TLI);
1765}
1766
1767Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
1768 const DataLayout &DL, const TargetLibraryInfo *TLI) {
1769 Type *VoidPtrTy = B.getPtrTy();
1770 Type *IntTy = getIntTy(B, TLI);
1771 Type *SizeTTy = getSizeTTy(B, TLI);
1772 return emitLibCall(TheLibFunc: LibFunc_memcmp, ReturnType: IntTy,
1773 ParamTypes: {VoidPtrTy, VoidPtrTy, SizeTTy},
1774 Operands: {Ptr1, Ptr2, Len}, B, TLI);
1775}
1776
1777Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
1778 const DataLayout &DL, const TargetLibraryInfo *TLI) {
1779 Type *VoidPtrTy = B.getPtrTy();
1780 Type *IntTy = getIntTy(B, TLI);
1781 Type *SizeTTy = getSizeTTy(B, TLI);
1782 return emitLibCall(TheLibFunc: LibFunc_bcmp, ReturnType: IntTy,
1783 ParamTypes: {VoidPtrTy, VoidPtrTy, SizeTTy},
1784 Operands: {Ptr1, Ptr2, Len}, B, TLI);
1785}
1786
1787Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
1788 IRBuilderBase &B, const TargetLibraryInfo *TLI) {
1789 Type *VoidPtrTy = B.getPtrTy();
1790 Type *IntTy = getIntTy(B, TLI);
1791 Type *SizeTTy = getSizeTTy(B, TLI);
1792 return emitLibCall(TheLibFunc: LibFunc_memccpy, ReturnType: VoidPtrTy,
1793 ParamTypes: {VoidPtrTy, VoidPtrTy, IntTy, SizeTTy},
1794 Operands: {Ptr1, Ptr2, Val, Len}, B, TLI);
1795}
1796
1797Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
1798 ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,
1799 const TargetLibraryInfo *TLI) {
1800 Type *CharPtrTy = B.getPtrTy();
1801 Type *IntTy = getIntTy(B, TLI);
1802 Type *SizeTTy = getSizeTTy(B, TLI);
1803 SmallVector<Value *, 8> Args{Dest, Size, Fmt};
1804 llvm::append_range(C&: Args, R&: VariadicArgs);
1805 return emitLibCall(TheLibFunc: LibFunc_snprintf, ReturnType: IntTy,
1806 ParamTypes: {CharPtrTy, SizeTTy, CharPtrTy},
1807 Operands: Args, B, TLI, /*IsVaArgs=*/true);
1808}
1809
1810Value *llvm::emitSPrintf(Value *Dest, Value *Fmt,
1811 ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,
1812 const TargetLibraryInfo *TLI) {
1813 Type *CharPtrTy = B.getPtrTy();
1814 Type *IntTy = getIntTy(B, TLI);
1815 SmallVector<Value *, 8> Args{Dest, Fmt};
1816 llvm::append_range(C&: Args, R&: VariadicArgs);
1817 return emitLibCall(TheLibFunc: LibFunc_sprintf, ReturnType: IntTy,
1818 ParamTypes: {CharPtrTy, CharPtrTy}, Operands: Args, B, TLI,
1819 /*IsVaArgs=*/true);
1820}
1821
1822Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B,
1823 const TargetLibraryInfo *TLI) {
1824 Type *CharPtrTy = B.getPtrTy();
1825 return emitLibCall(TheLibFunc: LibFunc_strcat, ReturnType: CharPtrTy,
1826 ParamTypes: {CharPtrTy, CharPtrTy},
1827 Operands: {Dest, Src}, B, TLI);
1828}
1829
1830Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
1831 const TargetLibraryInfo *TLI) {
1832 Type *CharPtrTy = B.getPtrTy();
1833 Type *SizeTTy = getSizeTTy(B, TLI);
1834 return emitLibCall(TheLibFunc: LibFunc_strlcpy, ReturnType: SizeTTy,
1835 ParamTypes: {CharPtrTy, CharPtrTy, SizeTTy},
1836 Operands: {Dest, Src, Size}, B, TLI);
1837}
1838
1839Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
1840 const TargetLibraryInfo *TLI) {
1841 Type *CharPtrTy = B.getPtrTy();
1842 Type *SizeTTy = getSizeTTy(B, TLI);
1843 return emitLibCall(TheLibFunc: LibFunc_strlcat, ReturnType: SizeTTy,
1844 ParamTypes: {CharPtrTy, CharPtrTy, SizeTTy},
1845 Operands: {Dest, Src, Size}, B, TLI);
1846}
1847
1848Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
1849 const TargetLibraryInfo *TLI) {
1850 Type *CharPtrTy = B.getPtrTy();
1851 Type *SizeTTy = getSizeTTy(B, TLI);
1852 return emitLibCall(TheLibFunc: LibFunc_strncat, ReturnType: CharPtrTy,
1853 ParamTypes: {CharPtrTy, CharPtrTy, SizeTTy},
1854 Operands: {Dest, Src, Size}, B, TLI);
1855}
1856
1857Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
1858 IRBuilderBase &B, const TargetLibraryInfo *TLI) {
1859 Type *CharPtrTy = B.getPtrTy();
1860 Type *IntTy = getIntTy(B, TLI);
1861 Type *SizeTTy = getSizeTTy(B, TLI);
1862 return emitLibCall(
1863 TheLibFunc: LibFunc_vsnprintf, ReturnType: IntTy,
1864 ParamTypes: {CharPtrTy, SizeTTy, CharPtrTy, VAList->getType()},
1865 Operands: {Dest, Size, Fmt, VAList}, B, TLI);
1866}
1867
1868Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList,
1869 IRBuilderBase &B, const TargetLibraryInfo *TLI) {
1870 Type *CharPtrTy = B.getPtrTy();
1871 Type *IntTy = getIntTy(B, TLI);
1872 return emitLibCall(TheLibFunc: LibFunc_vsprintf, ReturnType: IntTy,
1873 ParamTypes: {CharPtrTy, CharPtrTy, VAList->getType()},
1874 Operands: {Dest, Fmt, VAList}, B, TLI);
1875}
1876
1877/// Append a suffix to the function name according to the type of 'Op'.
1878static void appendTypeSuffix(Value *Op, StringRef &Name,
1879 SmallString<20> &NameBuffer) {
1880 if (!Op->getType()->isDoubleTy()) {
1881 NameBuffer += Name;
1882
1883 if (Op->getType()->isFloatTy())
1884 NameBuffer += 'f';
1885 else
1886 NameBuffer += 'l';
1887
1888 Name = NameBuffer;
1889 }
1890}
1891
1892static Value *emitUnaryFloatFnCallHelper(Value *Op, LibFunc TheLibFunc,
1893 StringRef Name, IRBuilderBase &B,
1894 const AttributeList &Attrs,
1895 const TargetLibraryInfo *TLI) {
1896 assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
1897
1898 Module *M = B.GetInsertBlock()->getModule();
1899 FunctionCallee Callee = getOrInsertLibFunc(M, TLI: *TLI, TheLibFunc, RetTy: Op->getType(),
1900 Args: Op->getType());
1901 CallInst *CI = B.CreateCall(Callee, Args: Op, Name);
1902
1903 // The incoming attribute set may have come from a speculatable intrinsic, but
1904 // is being replaced with a library call which is not allowed to be
1905 // speculatable.
1906 CI->setAttributes(
1907 Attrs.removeFnAttribute(C&: B.getContext(), Kind: Attribute::Speculatable));
1908 if (const Function *F =
1909 dyn_cast<Function>(Val: Callee.getCallee()->stripPointerCasts()))
1910 CI->setCallingConv(F->getCallingConv());
1911
1912 return CI;
1913}
1914
1915Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
1916 StringRef Name, IRBuilderBase &B,
1917 const AttributeList &Attrs) {
1918 SmallString<20> NameBuffer;
1919 appendTypeSuffix(Op, Name, NameBuffer);
1920
1921 LibFunc TheLibFunc;
1922 TLI->getLibFunc(funcName: Name, F&: TheLibFunc);
1923
1924 return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI);
1925}
1926
1927Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
1928 LibFunc DoubleFn, LibFunc FloatFn,
1929 LibFunc LongDoubleFn, IRBuilderBase &B,
1930 const AttributeList &Attrs) {
1931 // Get the name of the function according to TLI.
1932 Module *M = B.GetInsertBlock()->getModule();
1933 LibFunc TheLibFunc;
1934 StringRef Name = getFloatFn(M, TLI, Ty: Op->getType(), DoubleFn, FloatFn,
1935 LongDoubleFn, TheLibFunc);
1936
1937 return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI);
1938}
1939
1940static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2,
1941 LibFunc TheLibFunc,
1942 StringRef Name, IRBuilderBase &B,
1943 const AttributeList &Attrs,
1944 const TargetLibraryInfo *TLI) {
1945 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1946
1947 Module *M = B.GetInsertBlock()->getModule();
1948 FunctionCallee Callee = getOrInsertLibFunc(M, TLI: *TLI, TheLibFunc, RetTy: Op1->getType(),
1949 Args: Op1->getType(), Args: Op2->getType());
1950 inferNonMandatoryLibFuncAttrs(M, Name, TLI: *TLI);
1951 CallInst *CI = B.CreateCall(Callee, Args: { Op1, Op2 }, Name);
1952
1953 // The incoming attribute set may have come from a speculatable intrinsic, but
1954 // is being replaced with a library call which is not allowed to be
1955 // speculatable.
1956 CI->setAttributes(
1957 Attrs.removeFnAttribute(C&: B.getContext(), Kind: Attribute::Speculatable));
1958 if (const Function *F =
1959 dyn_cast<Function>(Val: Callee.getCallee()->stripPointerCasts()))
1960 CI->setCallingConv(F->getCallingConv());
1961
1962 return CI;
1963}
1964
1965Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,
1966 const TargetLibraryInfo *TLI,
1967 StringRef Name, IRBuilderBase &B,
1968 const AttributeList &Attrs) {
1969 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1970
1971 SmallString<20> NameBuffer;
1972 appendTypeSuffix(Op: Op1, Name, NameBuffer);
1973
1974 LibFunc TheLibFunc;
1975 TLI->getLibFunc(funcName: Name, F&: TheLibFunc);
1976
1977 return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI);
1978}
1979
1980Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,
1981 const TargetLibraryInfo *TLI,
1982 LibFunc DoubleFn, LibFunc FloatFn,
1983 LibFunc LongDoubleFn, IRBuilderBase &B,
1984 const AttributeList &Attrs) {
1985 // Get the name of the function according to TLI.
1986 Module *M = B.GetInsertBlock()->getModule();
1987 LibFunc TheLibFunc;
1988 StringRef Name = getFloatFn(M, TLI, Ty: Op1->getType(), DoubleFn, FloatFn,
1989 LongDoubleFn, TheLibFunc);
1990
1991 return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI);
1992}
1993
1994// Emit a call to putchar(int) with Char as the argument. Char must have
1995// the same precision as int, which need not be 32 bits.
1996Value *llvm::emitPutChar(Value *Char, IRBuilderBase &B,
1997 const TargetLibraryInfo *TLI) {
1998 Module *M = B.GetInsertBlock()->getModule();
1999 if (!isLibFuncEmittable(M, TLI, TheLibFunc: LibFunc_putchar))
2000 return nullptr;
2001
2002 Type *IntTy = getIntTy(B, TLI);
2003 StringRef PutCharName = TLI->getName(F: LibFunc_putchar);
2004 FunctionCallee PutChar = getOrInsertLibFunc(M, TLI: *TLI, TheLibFunc: LibFunc_putchar,
2005 RetTy: IntTy, Args: IntTy);
2006 inferNonMandatoryLibFuncAttrs(M, Name: PutCharName, TLI: *TLI);
2007 CallInst *CI = B.CreateCall(Callee: PutChar, Args: Char, Name: PutCharName);
2008
2009 if (const Function *F =
2010 dyn_cast<Function>(Val: PutChar.getCallee()->stripPointerCasts()))
2011 CI->setCallingConv(F->getCallingConv());
2012 return CI;
2013}
2014
2015Value *llvm::emitPutS(Value *Str, IRBuilderBase &B,
2016 const TargetLibraryInfo *TLI) {
2017 Module *M = B.GetInsertBlock()->getModule();
2018 if (!isLibFuncEmittable(M, TLI, TheLibFunc: LibFunc_puts))
2019 return nullptr;
2020
2021 Type *IntTy = getIntTy(B, TLI);
2022 StringRef PutsName = TLI->getName(F: LibFunc_puts);
2023 FunctionCallee PutS =
2024 getOrInsertLibFunc(M, TLI: *TLI, TheLibFunc: LibFunc_puts, RetTy: IntTy, Args: B.getPtrTy());
2025 inferNonMandatoryLibFuncAttrs(M, Name: PutsName, TLI: *TLI);
2026 CallInst *CI = B.CreateCall(Callee: PutS, Args: Str, Name: PutsName);
2027 if (const Function *F =
2028 dyn_cast<Function>(Val: PutS.getCallee()->stripPointerCasts()))
2029 CI->setCallingConv(F->getCallingConv());
2030 return CI;
2031}
2032
2033Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilderBase &B,
2034 const TargetLibraryInfo *TLI) {
2035 Module *M = B.GetInsertBlock()->getModule();
2036 if (!isLibFuncEmittable(M, TLI, TheLibFunc: LibFunc_fputc))
2037 return nullptr;
2038
2039 Type *IntTy = getIntTy(B, TLI);
2040 StringRef FPutcName = TLI->getName(F: LibFunc_fputc);
2041 FunctionCallee F = getOrInsertLibFunc(M, TLI: *TLI, TheLibFunc: LibFunc_fputc, RetTy: IntTy,
2042 Args: IntTy, Args: File->getType());
2043 if (File->getType()->isPointerTy())
2044 inferNonMandatoryLibFuncAttrs(M, Name: FPutcName, TLI: *TLI);
2045 CallInst *CI = B.CreateCall(Callee: F, Args: {Char, File}, Name: FPutcName);
2046
2047 if (const Function *Fn =
2048 dyn_cast<Function>(Val: F.getCallee()->stripPointerCasts()))
2049 CI->setCallingConv(Fn->getCallingConv());
2050 return CI;
2051}
2052
2053Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilderBase &B,
2054 const TargetLibraryInfo *TLI) {
2055 Module *M = B.GetInsertBlock()->getModule();
2056 if (!isLibFuncEmittable(M, TLI, TheLibFunc: LibFunc_fputs))
2057 return nullptr;
2058
2059 Type *IntTy = getIntTy(B, TLI);
2060 StringRef FPutsName = TLI->getName(F: LibFunc_fputs);
2061 FunctionCallee F = getOrInsertLibFunc(M, TLI: *TLI, TheLibFunc: LibFunc_fputs, RetTy: IntTy,
2062 Args: B.getPtrTy(), Args: File->getType());
2063 if (File->getType()->isPointerTy())
2064 inferNonMandatoryLibFuncAttrs(M, Name: FPutsName, TLI: *TLI);
2065 CallInst *CI = B.CreateCall(Callee: F, Args: {Str, File}, Name: FPutsName);
2066
2067 if (const Function *Fn =
2068 dyn_cast<Function>(Val: F.getCallee()->stripPointerCasts()))
2069 CI->setCallingConv(Fn->getCallingConv());
2070 return CI;
2071}
2072
2073Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B,
2074 const DataLayout &DL, const TargetLibraryInfo *TLI) {
2075 Module *M = B.GetInsertBlock()->getModule();
2076 if (!isLibFuncEmittable(M, TLI, TheLibFunc: LibFunc_fwrite))
2077 return nullptr;
2078
2079 Type *SizeTTy = getSizeTTy(B, TLI);
2080 StringRef FWriteName = TLI->getName(F: LibFunc_fwrite);
2081 FunctionCallee F =
2082 getOrInsertLibFunc(M, TLI: *TLI, TheLibFunc: LibFunc_fwrite, RetTy: SizeTTy, Args: B.getPtrTy(),
2083 Args: SizeTTy, Args: SizeTTy, Args: File->getType());
2084
2085 if (File->getType()->isPointerTy())
2086 inferNonMandatoryLibFuncAttrs(M, Name: FWriteName, TLI: *TLI);
2087 CallInst *CI =
2088 B.CreateCall(Callee: F, Args: {Ptr, Size,
2089 ConstantInt::get(Ty: SizeTTy, V: 1), File});
2090
2091 if (const Function *Fn =
2092 dyn_cast<Function>(Val: F.getCallee()->stripPointerCasts()))
2093 CI->setCallingConv(Fn->getCallingConv());
2094 return CI;
2095}
2096
2097Value *llvm::emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL,
2098 const TargetLibraryInfo *TLI) {
2099 Module *M = B.GetInsertBlock()->getModule();
2100 if (!isLibFuncEmittable(M, TLI, TheLibFunc: LibFunc_malloc))
2101 return nullptr;
2102
2103 StringRef MallocName = TLI->getName(F: LibFunc_malloc);
2104 Type *SizeTTy = getSizeTTy(B, TLI);
2105 FunctionCallee Malloc =
2106 getOrInsertLibFunc(M, TLI: *TLI, TheLibFunc: LibFunc_malloc, RetTy: B.getPtrTy(), Args: SizeTTy);
2107 inferNonMandatoryLibFuncAttrs(M, Name: MallocName, TLI: *TLI);
2108 CallInst *CI = B.CreateCall(Callee: Malloc, Args: Num, Name: MallocName);
2109
2110 if (const Function *F =
2111 dyn_cast<Function>(Val: Malloc.getCallee()->stripPointerCasts()))
2112 CI->setCallingConv(F->getCallingConv());
2113
2114 return CI;
2115}
2116
2117Value *llvm::emitCalloc(Value *Num, Value *Size, IRBuilderBase &B,
2118 const TargetLibraryInfo &TLI, unsigned AddrSpace) {
2119 Module *M = B.GetInsertBlock()->getModule();
2120 if (!isLibFuncEmittable(M, TLI: &TLI, TheLibFunc: LibFunc_calloc))
2121 return nullptr;
2122
2123 StringRef CallocName = TLI.getName(F: LibFunc_calloc);
2124 Type *SizeTTy = getSizeTTy(B, TLI: &TLI);
2125 FunctionCallee Calloc = getOrInsertLibFunc(
2126 M, TLI, TheLibFunc: LibFunc_calloc, RetTy: B.getPtrTy(AddrSpace), Args: SizeTTy, Args: SizeTTy);
2127 inferNonMandatoryLibFuncAttrs(M, Name: CallocName, TLI);
2128 CallInst *CI = B.CreateCall(Callee: Calloc, Args: {Num, Size}, Name: CallocName);
2129
2130 if (const auto *F =
2131 dyn_cast<Function>(Val: Calloc.getCallee()->stripPointerCasts()))
2132 CI->setCallingConv(F->getCallingConv());
2133
2134 return CI;
2135}
2136
2137Value *llvm::emitHotColdSizeReturningNew(Value *Num, IRBuilderBase &B,
2138 const TargetLibraryInfo *TLI,
2139 LibFunc SizeFeedbackNewFunc,
2140 uint8_t HotCold) {
2141 Module *M = B.GetInsertBlock()->getModule();
2142 if (!isLibFuncEmittable(M, TLI, TheLibFunc: SizeFeedbackNewFunc))
2143 return nullptr;
2144
2145 StringRef Name = TLI->getName(F: SizeFeedbackNewFunc);
2146
2147 // __sized_ptr_t struct return type { void*, size_t }
2148 StructType *SizedPtrT =
2149 StructType::get(Context&: M->getContext(), Elements: {B.getPtrTy(), Num->getType()});
2150 FunctionCallee Func =
2151 M->getOrInsertFunction(Name, RetTy: SizedPtrT, Args: Num->getType(), Args: B.getInt8Ty());
2152 inferNonMandatoryLibFuncAttrs(M, Name, TLI: *TLI);
2153 CallInst *CI = B.CreateCall(Callee: Func, Args: {Num, B.getInt8(C: HotCold)}, Name: "sized_ptr");
2154
2155 if (const Function *F = dyn_cast<Function>(Val: Func.getCallee()))
2156 CI->setCallingConv(F->getCallingConv());
2157
2158 return CI;
2159}
2160
2161Value *llvm::emitHotColdSizeReturningNewAligned(Value *Num, Value *Align,
2162 IRBuilderBase &B,
2163 const TargetLibraryInfo *TLI,
2164 LibFunc SizeFeedbackNewFunc,
2165 uint8_t HotCold) {
2166 Module *M = B.GetInsertBlock()->getModule();
2167 if (!isLibFuncEmittable(M, TLI, TheLibFunc: SizeFeedbackNewFunc))
2168 return nullptr;
2169
2170 StringRef Name = TLI->getName(F: SizeFeedbackNewFunc);
2171
2172 // __sized_ptr_t struct return type { void*, size_t }
2173 StructType *SizedPtrT =
2174 StructType::get(Context&: M->getContext(), Elements: {B.getPtrTy(), Num->getType()});
2175 FunctionCallee Func = M->getOrInsertFunction(Name, RetTy: SizedPtrT, Args: Num->getType(),
2176 Args: Align->getType(), Args: B.getInt8Ty());
2177 inferNonMandatoryLibFuncAttrs(M, Name, TLI: *TLI);
2178 CallInst *CI =
2179 B.CreateCall(Callee: Func, Args: {Num, Align, B.getInt8(C: HotCold)}, Name: "sized_ptr");
2180
2181 if (const Function *F = dyn_cast<Function>(Val: Func.getCallee()))
2182 CI->setCallingConv(F->getCallingConv());
2183
2184 return CI;
2185}
2186
2187Value *llvm::emitHotColdNew(Value *Num, IRBuilderBase &B,
2188 const TargetLibraryInfo *TLI, LibFunc NewFunc,
2189 uint8_t HotCold) {
2190 Module *M = B.GetInsertBlock()->getModule();
2191 if (!isLibFuncEmittable(M, TLI, TheLibFunc: NewFunc))
2192 return nullptr;
2193
2194 StringRef Name = TLI->getName(F: NewFunc);
2195 FunctionCallee Func =
2196 M->getOrInsertFunction(Name, RetTy: B.getPtrTy(), Args: Num->getType(), Args: B.getInt8Ty());
2197 inferNonMandatoryLibFuncAttrs(M, Name, TLI: *TLI);
2198 CallInst *CI = B.CreateCall(Callee: Func, Args: {Num, B.getInt8(C: HotCold)}, Name);
2199
2200 if (const Function *F =
2201 dyn_cast<Function>(Val: Func.getCallee()->stripPointerCasts()))
2202 CI->setCallingConv(F->getCallingConv());
2203
2204 return CI;
2205}
2206
2207Value *llvm::emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B,
2208 const TargetLibraryInfo *TLI,
2209 LibFunc NewFunc, uint8_t HotCold) {
2210 Module *M = B.GetInsertBlock()->getModule();
2211 if (!isLibFuncEmittable(M, TLI, TheLibFunc: NewFunc))
2212 return nullptr;
2213
2214 StringRef Name = TLI->getName(F: NewFunc);
2215 FunctionCallee Func = M->getOrInsertFunction(
2216 Name, RetTy: B.getPtrTy(), Args: Num->getType(), Args: NoThrow->getType(), Args: B.getInt8Ty());
2217 inferNonMandatoryLibFuncAttrs(M, Name, TLI: *TLI);
2218 CallInst *CI = B.CreateCall(Callee: Func, Args: {Num, NoThrow, B.getInt8(C: HotCold)}, Name);
2219
2220 if (const Function *F =
2221 dyn_cast<Function>(Val: Func.getCallee()->stripPointerCasts()))
2222 CI->setCallingConv(F->getCallingConv());
2223
2224 return CI;
2225}
2226
2227Value *llvm::emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B,
2228 const TargetLibraryInfo *TLI,
2229 LibFunc NewFunc, uint8_t HotCold) {
2230 Module *M = B.GetInsertBlock()->getModule();
2231 if (!isLibFuncEmittable(M, TLI, TheLibFunc: NewFunc))
2232 return nullptr;
2233
2234 StringRef Name = TLI->getName(F: NewFunc);
2235 FunctionCallee Func = M->getOrInsertFunction(
2236 Name, RetTy: B.getPtrTy(), Args: Num->getType(), Args: Align->getType(), Args: B.getInt8Ty());
2237 inferNonMandatoryLibFuncAttrs(M, Name, TLI: *TLI);
2238 CallInst *CI = B.CreateCall(Callee: Func, Args: {Num, Align, B.getInt8(C: HotCold)}, Name);
2239
2240 if (const Function *F =
2241 dyn_cast<Function>(Val: Func.getCallee()->stripPointerCasts()))
2242 CI->setCallingConv(F->getCallingConv());
2243
2244 return CI;
2245}
2246
2247Value *llvm::emitHotColdNewAlignedNoThrow(Value *Num, Value *Align,
2248 Value *NoThrow, IRBuilderBase &B,
2249 const TargetLibraryInfo *TLI,
2250 LibFunc NewFunc, uint8_t HotCold) {
2251 Module *M = B.GetInsertBlock()->getModule();
2252 if (!isLibFuncEmittable(M, TLI, TheLibFunc: NewFunc))
2253 return nullptr;
2254
2255 StringRef Name = TLI->getName(F: NewFunc);
2256 FunctionCallee Func = M->getOrInsertFunction(
2257 Name, RetTy: B.getPtrTy(), Args: Num->getType(), Args: Align->getType(), Args: NoThrow->getType(),
2258 Args: B.getInt8Ty());
2259 inferNonMandatoryLibFuncAttrs(M, Name, TLI: *TLI);
2260 CallInst *CI =
2261 B.CreateCall(Callee: Func, Args: {Num, Align, NoThrow, B.getInt8(C: HotCold)}, Name);
2262
2263 if (const Function *F =
2264 dyn_cast<Function>(Val: Func.getCallee()->stripPointerCasts()))
2265 CI->setCallingConv(F->getCallingConv());
2266
2267 return CI;
2268}
2269