xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/Utils/BuildLibCalls.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements some functions that will create standard C libcalls.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BuildLibCalls.h"
140b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
150b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
1681ad6265SDimitry Andric #include "llvm/Analysis/MemoryBuiltins.h"
170b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h"
1881ad6265SDimitry Andric #include "llvm/IR/Argument.h"
1981ad6265SDimitry Andric #include "llvm/IR/CallingConv.h"
200b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
210b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
220b57cec5SDimitry Andric #include "llvm/IR/Function.h"
230b57cec5SDimitry Andric #include "llvm/IR/IRBuilder.h"
240b57cec5SDimitry Andric #include "llvm/IR/Module.h"
250b57cec5SDimitry Andric #include "llvm/IR/Type.h"
2681ad6265SDimitry Andric #include "llvm/Support/TypeSize.h"
27bdd1243dSDimitry Andric #include <optional>
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric using namespace llvm;
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric #define DEBUG_TYPE "build-libcalls"
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric //- Infer Attributes ---------------------------------------------------------//
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric STATISTIC(NumReadNone, "Number of functions inferred as readnone");
36e8d8bef9SDimitry Andric STATISTIC(NumInaccessibleMemOnly,
37e8d8bef9SDimitry Andric           "Number of functions inferred as inaccessiblememonly");
380b57cec5SDimitry Andric STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
3904eeddc0SDimitry Andric STATISTIC(NumWriteOnly, "Number of functions inferred as writeonly");
400b57cec5SDimitry Andric STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
41e8d8bef9SDimitry Andric STATISTIC(NumInaccessibleMemOrArgMemOnly,
42e8d8bef9SDimitry Andric           "Number of functions inferred as inaccessiblemem_or_argmemonly");
430b57cec5SDimitry Andric STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
440b57cec5SDimitry Andric STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
45e8d8bef9SDimitry Andric STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly");
460b57cec5SDimitry Andric STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
470b57cec5SDimitry Andric STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
48e8d8bef9SDimitry Andric STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns");
490b57cec5SDimitry Andric STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
50e8d8bef9SDimitry Andric STATISTIC(NumWillReturn, "Number of functions inferred as willreturn");
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric static bool setDoesNotAccessMemory(Function &F) {
530b57cec5SDimitry Andric   if (F.doesNotAccessMemory())
540b57cec5SDimitry Andric     return false;
550b57cec5SDimitry Andric   F.setDoesNotAccessMemory();
560b57cec5SDimitry Andric   ++NumReadNone;
570b57cec5SDimitry Andric   return true;
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric 
60e8d8bef9SDimitry Andric static bool setOnlyAccessesInaccessibleMemory(Function &F) {
61e8d8bef9SDimitry Andric   if (F.onlyAccessesInaccessibleMemory())
62e8d8bef9SDimitry Andric     return false;
63e8d8bef9SDimitry Andric   F.setOnlyAccessesInaccessibleMemory();
64e8d8bef9SDimitry Andric   ++NumInaccessibleMemOnly;
65e8d8bef9SDimitry Andric   return true;
66e8d8bef9SDimitry Andric }
67e8d8bef9SDimitry Andric 
680b57cec5SDimitry Andric static bool setOnlyReadsMemory(Function &F) {
690b57cec5SDimitry Andric   if (F.onlyReadsMemory())
700b57cec5SDimitry Andric     return false;
710b57cec5SDimitry Andric   F.setOnlyReadsMemory();
720b57cec5SDimitry Andric   ++NumReadOnly;
730b57cec5SDimitry Andric   return true;
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric 
7604eeddc0SDimitry Andric static bool setOnlyWritesMemory(Function &F) {
7704eeddc0SDimitry Andric   if (F.onlyWritesMemory()) // writeonly or readnone
7804eeddc0SDimitry Andric     return false;
7904eeddc0SDimitry Andric   ++NumWriteOnly;
8004eeddc0SDimitry Andric   F.setOnlyWritesMemory();
8104eeddc0SDimitry Andric   return true;
8204eeddc0SDimitry Andric }
8304eeddc0SDimitry Andric 
840b57cec5SDimitry Andric static bool setOnlyAccessesArgMemory(Function &F) {
850b57cec5SDimitry Andric   if (F.onlyAccessesArgMemory())
860b57cec5SDimitry Andric     return false;
870b57cec5SDimitry Andric   F.setOnlyAccessesArgMemory();
880b57cec5SDimitry Andric   ++NumArgMemOnly;
890b57cec5SDimitry Andric   return true;
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric 
92e8d8bef9SDimitry Andric static bool setOnlyAccessesInaccessibleMemOrArgMem(Function &F) {
93e8d8bef9SDimitry Andric   if (F.onlyAccessesInaccessibleMemOrArgMem())
94e8d8bef9SDimitry Andric     return false;
95e8d8bef9SDimitry Andric   F.setOnlyAccessesInaccessibleMemOrArgMem();
96e8d8bef9SDimitry Andric   ++NumInaccessibleMemOrArgMemOnly;
97e8d8bef9SDimitry Andric   return true;
98e8d8bef9SDimitry Andric }
99e8d8bef9SDimitry Andric 
1000b57cec5SDimitry Andric static bool setDoesNotThrow(Function &F) {
1010b57cec5SDimitry Andric   if (F.doesNotThrow())
1020b57cec5SDimitry Andric     return false;
1030b57cec5SDimitry Andric   F.setDoesNotThrow();
1040b57cec5SDimitry Andric   ++NumNoUnwind;
1050b57cec5SDimitry Andric   return true;
1060b57cec5SDimitry Andric }
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric static bool setRetDoesNotAlias(Function &F) {
109349cc55cSDimitry Andric   if (F.hasRetAttribute(Attribute::NoAlias))
1100b57cec5SDimitry Andric     return false;
111349cc55cSDimitry Andric   F.addRetAttr(Attribute::NoAlias);
1120b57cec5SDimitry Andric   ++NumNoAlias;
1130b57cec5SDimitry Andric   return true;
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric static bool setDoesNotCapture(Function &F, unsigned ArgNo) {
1170b57cec5SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::NoCapture))
1180b57cec5SDimitry Andric     return false;
1190b57cec5SDimitry Andric   F.addParamAttr(ArgNo, Attribute::NoCapture);
1200b57cec5SDimitry Andric   ++NumNoCapture;
1210b57cec5SDimitry Andric   return true;
1220b57cec5SDimitry Andric }
1230b57cec5SDimitry Andric 
1248bcb0991SDimitry Andric static bool setDoesNotAlias(Function &F, unsigned ArgNo) {
1258bcb0991SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::NoAlias))
1268bcb0991SDimitry Andric     return false;
1278bcb0991SDimitry Andric   F.addParamAttr(ArgNo, Attribute::NoAlias);
1288bcb0991SDimitry Andric   ++NumNoAlias;
1298bcb0991SDimitry Andric   return true;
1308bcb0991SDimitry Andric }
1318bcb0991SDimitry Andric 
1320b57cec5SDimitry Andric static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
1330b57cec5SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))
1340b57cec5SDimitry Andric     return false;
1350b57cec5SDimitry Andric   F.addParamAttr(ArgNo, Attribute::ReadOnly);
1360b57cec5SDimitry Andric   ++NumReadOnlyArg;
1370b57cec5SDimitry Andric   return true;
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric 
140e8d8bef9SDimitry Andric static bool setOnlyWritesMemory(Function &F, unsigned ArgNo) {
141e8d8bef9SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::WriteOnly))
142e8d8bef9SDimitry Andric     return false;
143e8d8bef9SDimitry Andric   F.addParamAttr(ArgNo, Attribute::WriteOnly);
144e8d8bef9SDimitry Andric   ++NumWriteOnlyArg;
145e8d8bef9SDimitry Andric   return true;
146e8d8bef9SDimitry Andric }
147e8d8bef9SDimitry Andric 
148e8d8bef9SDimitry Andric static bool setRetNoUndef(Function &F) {
149e8d8bef9SDimitry Andric   if (!F.getReturnType()->isVoidTy() &&
150349cc55cSDimitry Andric       !F.hasRetAttribute(Attribute::NoUndef)) {
151349cc55cSDimitry Andric     F.addRetAttr(Attribute::NoUndef);
152e8d8bef9SDimitry Andric     ++NumNoUndef;
153e8d8bef9SDimitry Andric     return true;
154e8d8bef9SDimitry Andric   }
155e8d8bef9SDimitry Andric   return false;
156e8d8bef9SDimitry Andric }
157e8d8bef9SDimitry Andric 
158e8d8bef9SDimitry Andric static bool setArgsNoUndef(Function &F) {
159e8d8bef9SDimitry Andric   bool Changed = false;
160e8d8bef9SDimitry Andric   for (unsigned ArgNo = 0; ArgNo < F.arg_size(); ++ArgNo) {
161e8d8bef9SDimitry Andric     if (!F.hasParamAttribute(ArgNo, Attribute::NoUndef)) {
162e8d8bef9SDimitry Andric       F.addParamAttr(ArgNo, Attribute::NoUndef);
163e8d8bef9SDimitry Andric       ++NumNoUndef;
164e8d8bef9SDimitry Andric       Changed = true;
165e8d8bef9SDimitry Andric     }
166e8d8bef9SDimitry Andric   }
167e8d8bef9SDimitry Andric   return Changed;
168e8d8bef9SDimitry Andric }
169e8d8bef9SDimitry Andric 
170fe6060f1SDimitry Andric static bool setArgNoUndef(Function &F, unsigned ArgNo) {
171fe6060f1SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::NoUndef))
172fe6060f1SDimitry Andric     return false;
173fe6060f1SDimitry Andric   F.addParamAttr(ArgNo, Attribute::NoUndef);
174fe6060f1SDimitry Andric   ++NumNoUndef;
175fe6060f1SDimitry Andric   return true;
176fe6060f1SDimitry Andric }
177fe6060f1SDimitry Andric 
178e8d8bef9SDimitry Andric static bool setRetAndArgsNoUndef(Function &F) {
179349cc55cSDimitry Andric   bool UndefAdded = false;
180349cc55cSDimitry Andric   UndefAdded |= setRetNoUndef(F);
181349cc55cSDimitry Andric   UndefAdded |= setArgsNoUndef(F);
182349cc55cSDimitry Andric   return UndefAdded;
183e8d8bef9SDimitry Andric }
184e8d8bef9SDimitry Andric 
1850b57cec5SDimitry Andric static bool setReturnedArg(Function &F, unsigned ArgNo) {
1860b57cec5SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::Returned))
1870b57cec5SDimitry Andric     return false;
1880b57cec5SDimitry Andric   F.addParamAttr(ArgNo, Attribute::Returned);
1890b57cec5SDimitry Andric   ++NumReturnedArg;
1900b57cec5SDimitry Andric   return true;
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric static bool setNonLazyBind(Function &F) {
1940b57cec5SDimitry Andric   if (F.hasFnAttribute(Attribute::NonLazyBind))
1950b57cec5SDimitry Andric     return false;
1960b57cec5SDimitry Andric   F.addFnAttr(Attribute::NonLazyBind);
1970b57cec5SDimitry Andric   return true;
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric static bool setDoesNotFreeMemory(Function &F) {
2010b57cec5SDimitry Andric   if (F.hasFnAttribute(Attribute::NoFree))
2020b57cec5SDimitry Andric     return false;
2030b57cec5SDimitry Andric   F.addFnAttr(Attribute::NoFree);
2040b57cec5SDimitry Andric   return true;
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric 
207e8d8bef9SDimitry Andric static bool setWillReturn(Function &F) {
208e8d8bef9SDimitry Andric   if (F.hasFnAttribute(Attribute::WillReturn))
209e8d8bef9SDimitry Andric     return false;
210e8d8bef9SDimitry Andric   F.addFnAttr(Attribute::WillReturn);
211e8d8bef9SDimitry Andric   ++NumWillReturn;
212e8d8bef9SDimitry Andric   return true;
213e8d8bef9SDimitry Andric }
214e8d8bef9SDimitry Andric 
21581ad6265SDimitry Andric static bool setAlignedAllocParam(Function &F, unsigned ArgNo) {
21681ad6265SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::AllocAlign))
21781ad6265SDimitry Andric     return false;
21881ad6265SDimitry Andric   F.addParamAttr(ArgNo, Attribute::AllocAlign);
21981ad6265SDimitry Andric   return true;
22081ad6265SDimitry Andric }
22181ad6265SDimitry Andric 
22281ad6265SDimitry Andric static bool setAllocatedPointerParam(Function &F, unsigned ArgNo) {
22381ad6265SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::AllocatedPointer))
22481ad6265SDimitry Andric     return false;
22581ad6265SDimitry Andric   F.addParamAttr(ArgNo, Attribute::AllocatedPointer);
22681ad6265SDimitry Andric   return true;
22781ad6265SDimitry Andric }
22881ad6265SDimitry Andric 
22981ad6265SDimitry Andric static bool setAllocSize(Function &F, unsigned ElemSizeArg,
230bdd1243dSDimitry Andric                          std::optional<unsigned> NumElemsArg) {
23181ad6265SDimitry Andric   if (F.hasFnAttribute(Attribute::AllocSize))
23281ad6265SDimitry Andric     return false;
23381ad6265SDimitry Andric   F.addFnAttr(Attribute::getWithAllocSizeArgs(F.getContext(), ElemSizeArg,
23481ad6265SDimitry Andric                                               NumElemsArg));
23581ad6265SDimitry Andric   return true;
23681ad6265SDimitry Andric }
23781ad6265SDimitry Andric 
23881ad6265SDimitry Andric static bool setAllocFamily(Function &F, StringRef Family) {
23981ad6265SDimitry Andric   if (F.hasFnAttribute("alloc-family"))
24081ad6265SDimitry Andric     return false;
24181ad6265SDimitry Andric   F.addFnAttr("alloc-family", Family);
24281ad6265SDimitry Andric   return true;
24381ad6265SDimitry Andric }
24481ad6265SDimitry Andric 
24581ad6265SDimitry Andric static bool setAllocKind(Function &F, AllocFnKind K) {
24681ad6265SDimitry Andric   if (F.hasFnAttribute(Attribute::AllocKind))
24781ad6265SDimitry Andric     return false;
24881ad6265SDimitry Andric   F.addFnAttr(
24981ad6265SDimitry Andric       Attribute::get(F.getContext(), Attribute::AllocKind, uint64_t(K)));
25081ad6265SDimitry Andric   return true;
25181ad6265SDimitry Andric }
25281ad6265SDimitry Andric 
25381ad6265SDimitry Andric bool llvm::inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name,
2540b57cec5SDimitry Andric                                          const TargetLibraryInfo &TLI) {
2550b57cec5SDimitry Andric   Function *F = M->getFunction(Name);
2560b57cec5SDimitry Andric   if (!F)
2570b57cec5SDimitry Andric     return false;
25881ad6265SDimitry Andric   return inferNonMandatoryLibFuncAttrs(*F, TLI);
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric 
26181ad6265SDimitry Andric bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
26281ad6265SDimitry Andric                                          const TargetLibraryInfo &TLI) {
2630b57cec5SDimitry Andric   LibFunc TheLibFunc;
2640b57cec5SDimitry Andric   if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
2650b57cec5SDimitry Andric     return false;
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric   bool Changed = false;
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric   if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
2700b57cec5SDimitry Andric     Changed |= setNonLazyBind(F);
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric   switch (TheLibFunc) {
2730b57cec5SDimitry Andric   case LibFunc_strlen:
27404eeddc0SDimitry Andric   case LibFunc_strnlen:
2750b57cec5SDimitry Andric   case LibFunc_wcslen:
2760b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F);
2770b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
2780b57cec5SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
279e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
2800b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
281fcaf7f86SDimitry Andric     break;
2820b57cec5SDimitry Andric   case LibFunc_strchr:
2830b57cec5SDimitry Andric   case LibFunc_strrchr:
284e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
2850b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F);
2860b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
287e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
288fcaf7f86SDimitry Andric     break;
2890b57cec5SDimitry Andric   case LibFunc_strtol:
2900b57cec5SDimitry Andric   case LibFunc_strtod:
2910b57cec5SDimitry Andric   case LibFunc_strtof:
2920b57cec5SDimitry Andric   case LibFunc_strtoul:
2930b57cec5SDimitry Andric   case LibFunc_strtoll:
2940b57cec5SDimitry Andric   case LibFunc_strtold:
2950b57cec5SDimitry Andric   case LibFunc_strtoull:
2960b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
297e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
2980b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
2990b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
300fcaf7f86SDimitry Andric     break;
3010b57cec5SDimitry Andric   case LibFunc_strcat:
3020b57cec5SDimitry Andric   case LibFunc_strncat:
303fe6060f1SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
304fe6060f1SDimitry Andric     Changed |= setDoesNotThrow(F);
305e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
3060b57cec5SDimitry Andric     Changed |= setReturnedArg(F, 0);
307fe6060f1SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
308fe6060f1SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
309fe6060f1SDimitry Andric     Changed |= setDoesNotAlias(F, 0);
310fe6060f1SDimitry Andric     Changed |= setDoesNotAlias(F, 1);
311fcaf7f86SDimitry Andric     break;
312fe6060f1SDimitry Andric   case LibFunc_strcpy:
313fe6060f1SDimitry Andric   case LibFunc_strncpy:
314fe6060f1SDimitry Andric     Changed |= setReturnedArg(F, 0);
315bdd1243dSDimitry Andric     [[fallthrough]];
3160b57cec5SDimitry Andric   case LibFunc_stpcpy:
3170b57cec5SDimitry Andric   case LibFunc_stpncpy:
318e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
3190b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
320e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
3210b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
322e8d8bef9SDimitry Andric     Changed |= setOnlyWritesMemory(F, 0);
3230b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
324e8d8bef9SDimitry Andric     Changed |= setDoesNotAlias(F, 0);
325e8d8bef9SDimitry Andric     Changed |= setDoesNotAlias(F, 1);
326fcaf7f86SDimitry Andric     break;
3270b57cec5SDimitry Andric   case LibFunc_strxfrm:
3280b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
329e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
3300b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3310b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
3320b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
333fcaf7f86SDimitry Andric     break;
3340b57cec5SDimitry Andric   case LibFunc_strcmp:      // 0,1
3350b57cec5SDimitry Andric   case LibFunc_strspn:      // 0,1
3360b57cec5SDimitry Andric   case LibFunc_strncmp:     // 0,1
3370b57cec5SDimitry Andric   case LibFunc_strcspn:     // 0,1
338e8d8bef9SDimitry Andric     Changed |= setDoesNotThrow(F);
339e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
340e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
341e8d8bef9SDimitry Andric     Changed |= setOnlyReadsMemory(F);
342e8d8bef9SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
343e8d8bef9SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
344fcaf7f86SDimitry Andric     break;
345e8d8bef9SDimitry Andric   case LibFunc_strcoll:
3460b57cec5SDimitry Andric   case LibFunc_strcasecmp:  // 0,1
3470b57cec5SDimitry Andric   case LibFunc_strncasecmp: //
348e8d8bef9SDimitry Andric     // Those functions may depend on the locale, which may be accessed through
349e8d8bef9SDimitry Andric     // global memory.
3500b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F);
3510b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
352e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
3530b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3540b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
355fcaf7f86SDimitry Andric     break;
3560b57cec5SDimitry Andric   case LibFunc_strstr:
3570b57cec5SDimitry Andric   case LibFunc_strpbrk:
358e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
3590b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F);
3600b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
361e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
3620b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
363fcaf7f86SDimitry Andric     break;
3640b57cec5SDimitry Andric   case LibFunc_strtok:
3650b57cec5SDimitry Andric   case LibFunc_strtok_r:
3660b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
367e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
3680b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
3690b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
370fcaf7f86SDimitry Andric     break;
3710b57cec5SDimitry Andric   case LibFunc_scanf:
372e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
3730b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
3740b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3750b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
376fcaf7f86SDimitry Andric     break;
3770b57cec5SDimitry Andric   case LibFunc_setbuf:
3780b57cec5SDimitry Andric   case LibFunc_setvbuf:
379e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
3800b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
3810b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
382fcaf7f86SDimitry Andric     break;
3830b57cec5SDimitry Andric   case LibFunc_strndup:
384fe6060f1SDimitry Andric     Changed |= setArgNoUndef(F, 1);
385bdd1243dSDimitry Andric     [[fallthrough]];
386fe6060f1SDimitry Andric   case LibFunc_strdup:
38781ad6265SDimitry Andric     Changed |= setAllocFamily(F, "malloc");
388e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
3890b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
3900b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
391e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
3920b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3930b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
394fcaf7f86SDimitry Andric     break;
3950b57cec5SDimitry Andric   case LibFunc_stat:
3960b57cec5SDimitry Andric   case LibFunc_statvfs:
397e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
3980b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
3990b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4000b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
4010b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
402fcaf7f86SDimitry Andric     break;
4030b57cec5SDimitry Andric   case LibFunc_sscanf:
404e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
4050b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
4060b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4070b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
4080b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
4090b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
410fcaf7f86SDimitry Andric     break;
4110b57cec5SDimitry Andric   case LibFunc_sprintf:
412e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
4130b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
4140b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4158bcb0991SDimitry Andric     Changed |= setDoesNotAlias(F, 0);
416e8d8bef9SDimitry Andric     Changed |= setOnlyWritesMemory(F, 0);
4170b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
4180b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
419fcaf7f86SDimitry Andric     break;
4200b57cec5SDimitry Andric   case LibFunc_snprintf:
421e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
4220b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
4230b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4248bcb0991SDimitry Andric     Changed |= setDoesNotAlias(F, 0);
425e8d8bef9SDimitry Andric     Changed |= setOnlyWritesMemory(F, 0);
4260b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 2);
4270b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 2);
428fcaf7f86SDimitry Andric     break;
4290b57cec5SDimitry Andric   case LibFunc_setitimer:
430e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
4310b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
432e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
4330b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
4340b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 2);
4350b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
436fcaf7f86SDimitry Andric     break;
4370b57cec5SDimitry Andric   case LibFunc_system:
4380b57cec5SDimitry Andric     // May throw; "system" is a valid pthread cancellation point.
439e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
4400b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4410b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
442fcaf7f86SDimitry Andric     break;
44304eeddc0SDimitry Andric   case LibFunc_aligned_alloc:
44481ad6265SDimitry Andric     Changed |= setAlignedAllocParam(F, 0);
445bdd1243dSDimitry Andric     Changed |= setAllocSize(F, 1, std::nullopt);
44681ad6265SDimitry Andric     Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Uninitialized | AllocFnKind::Aligned);
447bdd1243dSDimitry Andric     [[fallthrough]];
44804eeddc0SDimitry Andric   case LibFunc_valloc:
4490b57cec5SDimitry Andric   case LibFunc_malloc:
450e8d8bef9SDimitry Andric   case LibFunc_vec_malloc:
45181ad6265SDimitry Andric     Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_malloc ? "vec_malloc"
45281ad6265SDimitry Andric                                                                   : "malloc");
45381ad6265SDimitry Andric     Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Uninitialized);
454bdd1243dSDimitry Andric     Changed |= setAllocSize(F, 0, std::nullopt);
455e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesInaccessibleMemory(F);
456fe6060f1SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
4570b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
4580b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
459e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
460fcaf7f86SDimitry Andric     break;
4610b57cec5SDimitry Andric   case LibFunc_memcmp:
462e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
4630b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F);
4640b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
465e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
4660b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4670b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
468fcaf7f86SDimitry Andric     break;
4690b57cec5SDimitry Andric   case LibFunc_memchr:
4700b57cec5SDimitry Andric   case LibFunc_memrchr:
4710b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
472e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
473e8d8bef9SDimitry Andric     Changed |= setOnlyReadsMemory(F);
474e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
475fcaf7f86SDimitry Andric     break;
4760b57cec5SDimitry Andric   case LibFunc_modf:
4770b57cec5SDimitry Andric   case LibFunc_modff:
4780b57cec5SDimitry Andric   case LibFunc_modfl:
4790b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
480e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
48106c3fb27SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
48206c3fb27SDimitry Andric     Changed |= setOnlyWritesMemory(F);
4830b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
484fcaf7f86SDimitry Andric     break;
4850b57cec5SDimitry Andric   case LibFunc_memcpy:
4868bcb0991SDimitry Andric     Changed |= setDoesNotThrow(F);
487e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
488e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
489e8d8bef9SDimitry Andric     Changed |= setDoesNotAlias(F, 0);
490e8d8bef9SDimitry Andric     Changed |= setReturnedArg(F, 0);
491e8d8bef9SDimitry Andric     Changed |= setOnlyWritesMemory(F, 0);
492e8d8bef9SDimitry Andric     Changed |= setDoesNotAlias(F, 1);
4938bcb0991SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
4948bcb0991SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
495fcaf7f86SDimitry Andric     break;
4960b57cec5SDimitry Andric   case LibFunc_memmove:
4978bcb0991SDimitry Andric     Changed |= setDoesNotThrow(F);
498e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
499e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
500e8d8bef9SDimitry Andric     Changed |= setReturnedArg(F, 0);
501e8d8bef9SDimitry Andric     Changed |= setOnlyWritesMemory(F, 0);
5028bcb0991SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
5038bcb0991SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
504fcaf7f86SDimitry Andric     break;
5050b57cec5SDimitry Andric   case LibFunc_mempcpy:
5060b57cec5SDimitry Andric   case LibFunc_memccpy:
5074824e7fdSDimitry Andric     Changed |= setWillReturn(F);
508bdd1243dSDimitry Andric     [[fallthrough]];
5094824e7fdSDimitry Andric   case LibFunc_memcpy_chk:
5100b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
511e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
512e8d8bef9SDimitry Andric     Changed |= setDoesNotAlias(F, 0);
513e8d8bef9SDimitry Andric     Changed |= setOnlyWritesMemory(F, 0);
514e8d8bef9SDimitry Andric     Changed |= setDoesNotAlias(F, 1);
5150b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
5160b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
517fcaf7f86SDimitry Andric     break;
5180b57cec5SDimitry Andric   case LibFunc_memalign:
51981ad6265SDimitry Andric     Changed |= setAllocFamily(F, "malloc");
52081ad6265SDimitry Andric     Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Aligned |
52181ad6265SDimitry Andric                                    AllocFnKind::Uninitialized);
522bdd1243dSDimitry Andric     Changed |= setAllocSize(F, 1, std::nullopt);
52381ad6265SDimitry Andric     Changed |= setAlignedAllocParam(F, 0);
524e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesInaccessibleMemory(F);
525e8d8bef9SDimitry Andric     Changed |= setRetNoUndef(F);
526e8d8bef9SDimitry Andric     Changed |= setDoesNotThrow(F);
5270b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
528e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
529fcaf7f86SDimitry Andric     break;
5300b57cec5SDimitry Andric   case LibFunc_mkdir:
531e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
5320b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
5330b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5340b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
535fcaf7f86SDimitry Andric     break;
5360b57cec5SDimitry Andric   case LibFunc_mktime:
537e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
5380b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
539e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
5400b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
541fcaf7f86SDimitry Andric     break;
5420b57cec5SDimitry Andric   case LibFunc_realloc:
54304eeddc0SDimitry Andric   case LibFunc_reallocf:
54481ad6265SDimitry Andric   case LibFunc_vec_realloc:
54581ad6265SDimitry Andric     Changed |= setAllocFamily(
54681ad6265SDimitry Andric         F, TheLibFunc == LibFunc_vec_realloc ? "vec_malloc" : "malloc");
54781ad6265SDimitry Andric     Changed |= setAllocKind(F, AllocFnKind::Realloc);
54881ad6265SDimitry Andric     Changed |= setAllocatedPointerParam(F, 0);
549bdd1243dSDimitry Andric     Changed |= setAllocSize(F, 1, std::nullopt);
550e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
551e8d8bef9SDimitry Andric     Changed |= setRetNoUndef(F);
5520b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
5530b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
554e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
5550b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
556fe6060f1SDimitry Andric     Changed |= setArgNoUndef(F, 1);
557fcaf7f86SDimitry Andric     break;
5580b57cec5SDimitry Andric   case LibFunc_read:
5590b57cec5SDimitry Andric     // May throw; "read" is a valid pthread cancellation point.
560e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
5610b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
562fcaf7f86SDimitry Andric     break;
5630b57cec5SDimitry Andric   case LibFunc_rewind:
564e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
5650b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
5660b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
567fcaf7f86SDimitry Andric     break;
5680b57cec5SDimitry Andric   case LibFunc_rmdir:
5690b57cec5SDimitry Andric   case LibFunc_remove:
5700b57cec5SDimitry Andric   case LibFunc_realpath:
571e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
5720b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
5730b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5740b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
575fcaf7f86SDimitry Andric     break;
5760b57cec5SDimitry Andric   case LibFunc_rename:
577e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
5780b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
5790b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5800b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
5810b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
5820b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
583fcaf7f86SDimitry Andric     break;
5840b57cec5SDimitry Andric   case LibFunc_readlink:
585e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
5860b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
5870b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5880b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
5890b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
590fcaf7f86SDimitry Andric     break;
5910b57cec5SDimitry Andric   case LibFunc_write:
5920b57cec5SDimitry Andric     // May throw; "write" is a valid pthread cancellation point.
593e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
5940b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
5950b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
596fcaf7f86SDimitry Andric     break;
5970b57cec5SDimitry Andric   case LibFunc_bcopy:
5980b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
599e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
600e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
6010b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6020b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
603e8d8bef9SDimitry Andric     Changed |= setOnlyWritesMemory(F, 1);
604e8d8bef9SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
605fcaf7f86SDimitry Andric     break;
6060b57cec5SDimitry Andric   case LibFunc_bcmp:
6070b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
608e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
6090b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F);
610e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
6110b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6120b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
613fcaf7f86SDimitry Andric     break;
6140b57cec5SDimitry Andric   case LibFunc_bzero:
6150b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
616e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
617e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
6180b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
619e8d8bef9SDimitry Andric     Changed |= setOnlyWritesMemory(F, 0);
620fcaf7f86SDimitry Andric     break;
6210b57cec5SDimitry Andric   case LibFunc_calloc:
622e8d8bef9SDimitry Andric   case LibFunc_vec_calloc:
62381ad6265SDimitry Andric     Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_calloc ? "vec_malloc"
62481ad6265SDimitry Andric                                                                   : "malloc");
62581ad6265SDimitry Andric     Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Zeroed);
62681ad6265SDimitry Andric     Changed |= setAllocSize(F, 0, 1);
62704eeddc0SDimitry Andric     Changed |= setOnlyAccessesInaccessibleMemory(F);
628fe6060f1SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
6290b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
6300b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
631e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
632fcaf7f86SDimitry Andric     break;
6330b57cec5SDimitry Andric   case LibFunc_chmod:
6340b57cec5SDimitry Andric   case LibFunc_chown:
635e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
6360b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
6370b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6380b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
639fcaf7f86SDimitry Andric     break;
6400b57cec5SDimitry Andric   case LibFunc_ctermid:
6410b57cec5SDimitry Andric   case LibFunc_clearerr:
6420b57cec5SDimitry Andric   case LibFunc_closedir:
643e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
6440b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
6450b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
646fcaf7f86SDimitry Andric     break;
6470b57cec5SDimitry Andric   case LibFunc_atoi:
6480b57cec5SDimitry Andric   case LibFunc_atol:
6490b57cec5SDimitry Andric   case LibFunc_atof:
6500b57cec5SDimitry Andric   case LibFunc_atoll:
6510b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
6520b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F);
653e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
6540b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
655fcaf7f86SDimitry Andric     break;
6560b57cec5SDimitry Andric   case LibFunc_access:
657e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
6580b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
6590b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6600b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
661fcaf7f86SDimitry Andric     break;
6620b57cec5SDimitry Andric   case LibFunc_fopen:
663e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
6640b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
6650b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
6660b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6670b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
6680b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
6690b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
670fcaf7f86SDimitry Andric     break;
6710b57cec5SDimitry Andric   case LibFunc_fdopen:
672e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
6730b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
6740b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
6750b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
6760b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
677fcaf7f86SDimitry Andric     break;
6780b57cec5SDimitry Andric   case LibFunc_feof:
679e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
680e8d8bef9SDimitry Andric     Changed |= setDoesNotThrow(F);
681e8d8bef9SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
682fcaf7f86SDimitry Andric     break;
6830b57cec5SDimitry Andric   case LibFunc_free:
684e8d8bef9SDimitry Andric   case LibFunc_vec_free:
68581ad6265SDimitry Andric     Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_free ? "vec_malloc"
68681ad6265SDimitry Andric                                                                 : "malloc");
68781ad6265SDimitry Andric     Changed |= setAllocKind(F, AllocFnKind::Free);
68881ad6265SDimitry Andric     Changed |= setAllocatedPointerParam(F, 0);
689e8d8bef9SDimitry Andric     Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);
690e8d8bef9SDimitry Andric     Changed |= setArgsNoUndef(F);
691e8d8bef9SDimitry Andric     Changed |= setDoesNotThrow(F);
692e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
693e8d8bef9SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
694fcaf7f86SDimitry Andric     break;
6950b57cec5SDimitry Andric   case LibFunc_fseek:
6960b57cec5SDimitry Andric   case LibFunc_ftell:
6970b57cec5SDimitry Andric   case LibFunc_fgetc:
6980b57cec5SDimitry Andric   case LibFunc_fgetc_unlocked:
6990b57cec5SDimitry Andric   case LibFunc_fseeko:
7000b57cec5SDimitry Andric   case LibFunc_ftello:
7010b57cec5SDimitry Andric   case LibFunc_fileno:
7020b57cec5SDimitry Andric   case LibFunc_fflush:
7030b57cec5SDimitry Andric   case LibFunc_fclose:
7040b57cec5SDimitry Andric   case LibFunc_fsetpos:
7050b57cec5SDimitry Andric   case LibFunc_flockfile:
7060b57cec5SDimitry Andric   case LibFunc_funlockfile:
7070b57cec5SDimitry Andric   case LibFunc_ftrylockfile:
708e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7090b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
7100b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
711fcaf7f86SDimitry Andric     break;
7120b57cec5SDimitry Andric   case LibFunc_ferror:
713e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7140b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
7150b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
7160b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F);
717fcaf7f86SDimitry Andric     break;
7180b57cec5SDimitry Andric   case LibFunc_fputc:
7190b57cec5SDimitry Andric   case LibFunc_fputc_unlocked:
7200b57cec5SDimitry Andric   case LibFunc_fstat:
721e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
722e8d8bef9SDimitry Andric     Changed |= setDoesNotThrow(F);
723e8d8bef9SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
724fcaf7f86SDimitry Andric     break;
7250b57cec5SDimitry Andric   case LibFunc_frexp:
7260b57cec5SDimitry Andric   case LibFunc_frexpf:
7270b57cec5SDimitry Andric   case LibFunc_frexpl:
728e8d8bef9SDimitry Andric     Changed |= setDoesNotThrow(F);
729e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
73006c3fb27SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
73106c3fb27SDimitry Andric     Changed |= setOnlyWritesMemory(F);
732e8d8bef9SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
733fcaf7f86SDimitry Andric     break;
7340b57cec5SDimitry Andric   case LibFunc_fstatvfs:
735e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7360b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
7370b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
738fcaf7f86SDimitry Andric     break;
7390b57cec5SDimitry Andric   case LibFunc_fgets:
7400b57cec5SDimitry Andric   case LibFunc_fgets_unlocked:
741e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7420b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
7430b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 2);
744fcaf7f86SDimitry Andric     break;
7450b57cec5SDimitry Andric   case LibFunc_fread:
7460b57cec5SDimitry Andric   case LibFunc_fread_unlocked:
747e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7480b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
7490b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
7500b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 3);
751fcaf7f86SDimitry Andric     break;
7520b57cec5SDimitry Andric   case LibFunc_fwrite:
7530b57cec5SDimitry Andric   case LibFunc_fwrite_unlocked:
754e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7550b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
7560b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
7570b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 3);
7580b57cec5SDimitry Andric     // FIXME: readonly #1?
759fcaf7f86SDimitry Andric     break;
7600b57cec5SDimitry Andric   case LibFunc_fputs:
7610b57cec5SDimitry Andric   case LibFunc_fputs_unlocked:
762e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7630b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
7640b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
7650b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
7660b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
767fcaf7f86SDimitry Andric     break;
7680b57cec5SDimitry Andric   case LibFunc_fscanf:
7690b57cec5SDimitry Andric   case LibFunc_fprintf:
770e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7710b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
7720b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
7730b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
7740b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
775fcaf7f86SDimitry Andric     break;
7760b57cec5SDimitry Andric   case LibFunc_fgetpos:
777e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7780b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
7790b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
7800b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
781fcaf7f86SDimitry Andric     break;
7820b57cec5SDimitry Andric   case LibFunc_getc:
783e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
784e8d8bef9SDimitry Andric     Changed |= setDoesNotThrow(F);
785e8d8bef9SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
786fcaf7f86SDimitry Andric     break;
7870b57cec5SDimitry Andric   case LibFunc_getlogin_r:
788e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
789e8d8bef9SDimitry Andric     Changed |= setDoesNotThrow(F);
790e8d8bef9SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
791fcaf7f86SDimitry Andric     break;
7920b57cec5SDimitry Andric   case LibFunc_getc_unlocked:
793e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7940b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
7950b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
796fcaf7f86SDimitry Andric     break;
7970b57cec5SDimitry Andric   case LibFunc_getenv:
798e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
7990b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8000b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F);
8010b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
802fcaf7f86SDimitry Andric     break;
8030b57cec5SDimitry Andric   case LibFunc_gets:
8040b57cec5SDimitry Andric   case LibFunc_getchar:
8050b57cec5SDimitry Andric   case LibFunc_getchar_unlocked:
806e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8070b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
808fcaf7f86SDimitry Andric     break;
8090b57cec5SDimitry Andric   case LibFunc_getitimer:
810e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8110b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8120b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
813fcaf7f86SDimitry Andric     break;
8140b57cec5SDimitry Andric   case LibFunc_getpwnam:
815e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8160b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8170b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
8180b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
819fcaf7f86SDimitry Andric     break;
8200b57cec5SDimitry Andric   case LibFunc_ungetc:
821e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8220b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8230b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
824fcaf7f86SDimitry Andric     break;
8250b57cec5SDimitry Andric   case LibFunc_uname:
826e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8270b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8280b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
829fcaf7f86SDimitry Andric     break;
8300b57cec5SDimitry Andric   case LibFunc_unlink:
831e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8320b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8330b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
8340b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
835fcaf7f86SDimitry Andric     break;
8360b57cec5SDimitry Andric   case LibFunc_unsetenv:
837e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8380b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8390b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
8400b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
841fcaf7f86SDimitry Andric     break;
8420b57cec5SDimitry Andric   case LibFunc_utime:
8430b57cec5SDimitry Andric   case LibFunc_utimes:
844e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8450b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8460b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
8470b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
8480b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
8490b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
850fcaf7f86SDimitry Andric     break;
8510b57cec5SDimitry Andric   case LibFunc_putc:
8520b57cec5SDimitry Andric   case LibFunc_putc_unlocked:
853e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8540b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8550b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
856fcaf7f86SDimitry Andric     break;
8570b57cec5SDimitry Andric   case LibFunc_puts:
8580b57cec5SDimitry Andric   case LibFunc_printf:
8590b57cec5SDimitry Andric   case LibFunc_perror:
860e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8610b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8620b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
8630b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
864fcaf7f86SDimitry Andric     break;
8650b57cec5SDimitry Andric   case LibFunc_pread:
8660b57cec5SDimitry Andric     // May throw; "pread" is a valid pthread cancellation point.
867e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8680b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
869fcaf7f86SDimitry Andric     break;
8700b57cec5SDimitry Andric   case LibFunc_pwrite:
8710b57cec5SDimitry Andric     // May throw; "pwrite" is a valid pthread cancellation point.
872e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8730b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
8740b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
875fcaf7f86SDimitry Andric     break;
8760b57cec5SDimitry Andric   case LibFunc_putchar:
8770b57cec5SDimitry Andric   case LibFunc_putchar_unlocked:
878e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8790b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
880fcaf7f86SDimitry Andric     break;
8810b57cec5SDimitry Andric   case LibFunc_popen:
882e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8830b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8840b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
8850b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
8860b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
8870b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
8880b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
889fcaf7f86SDimitry Andric     break;
8900b57cec5SDimitry Andric   case LibFunc_pclose:
891e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8920b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8930b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
894fcaf7f86SDimitry Andric     break;
8950b57cec5SDimitry Andric   case LibFunc_vscanf:
896e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
8970b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
8980b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
8990b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
900fcaf7f86SDimitry Andric     break;
9010b57cec5SDimitry Andric   case LibFunc_vsscanf:
902e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9030b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9040b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
9050b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
9060b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
9070b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
908fcaf7f86SDimitry Andric     break;
9090b57cec5SDimitry Andric   case LibFunc_vfscanf:
910e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9110b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9120b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
9130b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
9140b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
915fcaf7f86SDimitry Andric     break;
9160b57cec5SDimitry Andric   case LibFunc_vprintf:
917e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9180b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9190b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
9200b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
921fcaf7f86SDimitry Andric     break;
9220b57cec5SDimitry Andric   case LibFunc_vfprintf:
9230b57cec5SDimitry Andric   case LibFunc_vsprintf:
924e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9250b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9260b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
9270b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
9280b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
929fcaf7f86SDimitry Andric     break;
9300b57cec5SDimitry Andric   case LibFunc_vsnprintf:
931e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9320b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9330b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
9340b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 2);
9350b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 2);
936fcaf7f86SDimitry Andric     break;
9370b57cec5SDimitry Andric   case LibFunc_open:
9380b57cec5SDimitry Andric     // May throw; "open" is a valid pthread cancellation point.
939e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9400b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
9410b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
942fcaf7f86SDimitry Andric     break;
9430b57cec5SDimitry Andric   case LibFunc_opendir:
944e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9450b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9460b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
9470b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
9480b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
949fcaf7f86SDimitry Andric     break;
9500b57cec5SDimitry Andric   case LibFunc_tmpfile:
951e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9520b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9530b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
954fcaf7f86SDimitry Andric     break;
9550b57cec5SDimitry Andric   case LibFunc_times:
956e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9570b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9580b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
959fcaf7f86SDimitry Andric     break;
9600b57cec5SDimitry Andric   case LibFunc_htonl:
9610b57cec5SDimitry Andric   case LibFunc_htons:
9620b57cec5SDimitry Andric   case LibFunc_ntohl:
9630b57cec5SDimitry Andric   case LibFunc_ntohs:
9640b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9650b57cec5SDimitry Andric     Changed |= setDoesNotAccessMemory(F);
966fcaf7f86SDimitry Andric     break;
9670b57cec5SDimitry Andric   case LibFunc_lstat:
968e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9690b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9700b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
9710b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
9720b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
973fcaf7f86SDimitry Andric     break;
9740b57cec5SDimitry Andric   case LibFunc_lchown:
975e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9760b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9770b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
9780b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
979fcaf7f86SDimitry Andric     break;
9800b57cec5SDimitry Andric   case LibFunc_qsort:
9810b57cec5SDimitry Andric     // May throw; places call through function pointer.
982e8d8bef9SDimitry Andric     // Cannot give undef pointer/size
983e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
9840b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 3);
985fcaf7f86SDimitry Andric     break;
9860b57cec5SDimitry Andric   case LibFunc_dunder_strndup:
987fe6060f1SDimitry Andric     Changed |= setArgNoUndef(F, 1);
988bdd1243dSDimitry Andric     [[fallthrough]];
989fe6060f1SDimitry Andric   case LibFunc_dunder_strdup:
9900b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9910b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
992e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
9930b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
9940b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
995fcaf7f86SDimitry Andric     break;
9960b57cec5SDimitry Andric   case LibFunc_dunder_strtok_r:
9970b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
9980b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
9990b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
1000fcaf7f86SDimitry Andric     break;
10010b57cec5SDimitry Andric   case LibFunc_under_IO_getc:
1002e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10030b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
10040b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
1005fcaf7f86SDimitry Andric     break;
10060b57cec5SDimitry Andric   case LibFunc_under_IO_putc:
1007e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10080b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
10090b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
1010fcaf7f86SDimitry Andric     break;
10110b57cec5SDimitry Andric   case LibFunc_dunder_isoc99_scanf:
1012e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10130b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
10140b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
10150b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
1016fcaf7f86SDimitry Andric     break;
10170b57cec5SDimitry Andric   case LibFunc_stat64:
10180b57cec5SDimitry Andric   case LibFunc_lstat64:
10190b57cec5SDimitry Andric   case LibFunc_statvfs64:
1020e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10210b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
10220b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
10230b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
10240b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
1025fcaf7f86SDimitry Andric     break;
10260b57cec5SDimitry Andric   case LibFunc_dunder_isoc99_sscanf:
1027e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10280b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
10290b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
10300b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
10310b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
10320b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
1033fcaf7f86SDimitry Andric     break;
10340b57cec5SDimitry Andric   case LibFunc_fopen64:
1035e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10360b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
10370b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
10380b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
10390b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
10400b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
10410b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
1042fcaf7f86SDimitry Andric     break;
10430b57cec5SDimitry Andric   case LibFunc_fseeko64:
10440b57cec5SDimitry Andric   case LibFunc_ftello64:
1045e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10460b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
10470b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
1048fcaf7f86SDimitry Andric     break;
10490b57cec5SDimitry Andric   case LibFunc_tmpfile64:
1050e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10510b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
10520b57cec5SDimitry Andric     Changed |= setRetDoesNotAlias(F);
1053fcaf7f86SDimitry Andric     break;
10540b57cec5SDimitry Andric   case LibFunc_fstat64:
10550b57cec5SDimitry Andric   case LibFunc_fstatvfs64:
1056e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10570b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
10580b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
1059fcaf7f86SDimitry Andric     break;
10600b57cec5SDimitry Andric   case LibFunc_open64:
10610b57cec5SDimitry Andric     // May throw; "open" is a valid pthread cancellation point.
1062e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10630b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
10640b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
1065fcaf7f86SDimitry Andric     break;
10660b57cec5SDimitry Andric   case LibFunc_gettimeofday:
10670b57cec5SDimitry Andric     // Currently some platforms have the restrict keyword on the arguments to
10680b57cec5SDimitry Andric     // gettimeofday. To be conservative, do not add noalias to gettimeofday's
10690b57cec5SDimitry Andric     // arguments.
1070e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10710b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
10720b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
10730b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
1074fcaf7f86SDimitry Andric     break;
10754824e7fdSDimitry Andric   case LibFunc_memset_pattern4:
10764824e7fdSDimitry Andric   case LibFunc_memset_pattern8:
10770b57cec5SDimitry Andric   case LibFunc_memset_pattern16:
10780b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
10790b57cec5SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
10800b57cec5SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
1081bdd1243dSDimitry Andric     [[fallthrough]];
1082e8d8bef9SDimitry Andric   case LibFunc_memset:
1083e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
1084bdd1243dSDimitry Andric     [[fallthrough]];
10854824e7fdSDimitry Andric   case LibFunc_memset_chk:
10864824e7fdSDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
1087e8d8bef9SDimitry Andric     Changed |= setOnlyWritesMemory(F, 0);
10884824e7fdSDimitry Andric     Changed |= setDoesNotThrow(F);
1089fcaf7f86SDimitry Andric     break;
10900b57cec5SDimitry Andric   // int __nvvm_reflect(const char *)
10910b57cec5SDimitry Andric   case LibFunc_nvvm_reflect:
1092e8d8bef9SDimitry Andric     Changed |= setRetAndArgsNoUndef(F);
10930b57cec5SDimitry Andric     Changed |= setDoesNotAccessMemory(F);
10940b57cec5SDimitry Andric     Changed |= setDoesNotThrow(F);
1095fcaf7f86SDimitry Andric     break;
1096e8d8bef9SDimitry Andric   case LibFunc_ldexp:
1097e8d8bef9SDimitry Andric   case LibFunc_ldexpf:
1098e8d8bef9SDimitry Andric   case LibFunc_ldexpl:
1099e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
1100fcaf7f86SDimitry Andric     break;
1101*0fca6ea1SDimitry Andric   case LibFunc_remquo:
1102*0fca6ea1SDimitry Andric   case LibFunc_remquof:
1103*0fca6ea1SDimitry Andric   case LibFunc_remquol:
1104*0fca6ea1SDimitry Andric     Changed |= setDoesNotCapture(F, 2);
1105*0fca6ea1SDimitry Andric     [[fallthrough]];
1106e8d8bef9SDimitry Andric   case LibFunc_abs:
1107e8d8bef9SDimitry Andric   case LibFunc_acos:
1108e8d8bef9SDimitry Andric   case LibFunc_acosf:
1109e8d8bef9SDimitry Andric   case LibFunc_acosh:
1110e8d8bef9SDimitry Andric   case LibFunc_acoshf:
1111e8d8bef9SDimitry Andric   case LibFunc_acoshl:
1112e8d8bef9SDimitry Andric   case LibFunc_acosl:
1113e8d8bef9SDimitry Andric   case LibFunc_asin:
1114e8d8bef9SDimitry Andric   case LibFunc_asinf:
1115e8d8bef9SDimitry Andric   case LibFunc_asinh:
1116e8d8bef9SDimitry Andric   case LibFunc_asinhf:
1117e8d8bef9SDimitry Andric   case LibFunc_asinhl:
1118e8d8bef9SDimitry Andric   case LibFunc_asinl:
1119e8d8bef9SDimitry Andric   case LibFunc_atan:
1120e8d8bef9SDimitry Andric   case LibFunc_atan2:
1121e8d8bef9SDimitry Andric   case LibFunc_atan2f:
1122e8d8bef9SDimitry Andric   case LibFunc_atan2l:
1123e8d8bef9SDimitry Andric   case LibFunc_atanf:
1124e8d8bef9SDimitry Andric   case LibFunc_atanh:
1125e8d8bef9SDimitry Andric   case LibFunc_atanhf:
1126e8d8bef9SDimitry Andric   case LibFunc_atanhl:
1127e8d8bef9SDimitry Andric   case LibFunc_atanl:
1128e8d8bef9SDimitry Andric   case LibFunc_cbrt:
1129e8d8bef9SDimitry Andric   case LibFunc_cbrtf:
1130e8d8bef9SDimitry Andric   case LibFunc_cbrtl:
1131e8d8bef9SDimitry Andric   case LibFunc_ceil:
1132e8d8bef9SDimitry Andric   case LibFunc_ceilf:
1133e8d8bef9SDimitry Andric   case LibFunc_ceill:
1134e8d8bef9SDimitry Andric   case LibFunc_copysign:
1135e8d8bef9SDimitry Andric   case LibFunc_copysignf:
1136e8d8bef9SDimitry Andric   case LibFunc_copysignl:
1137e8d8bef9SDimitry Andric   case LibFunc_cos:
1138e8d8bef9SDimitry Andric   case LibFunc_cosh:
1139e8d8bef9SDimitry Andric   case LibFunc_coshf:
1140e8d8bef9SDimitry Andric   case LibFunc_coshl:
1141e8d8bef9SDimitry Andric   case LibFunc_cosf:
1142e8d8bef9SDimitry Andric   case LibFunc_cosl:
1143e8d8bef9SDimitry Andric   case LibFunc_cospi:
1144e8d8bef9SDimitry Andric   case LibFunc_cospif:
1145*0fca6ea1SDimitry Andric   case LibFunc_erf:
1146*0fca6ea1SDimitry Andric   case LibFunc_erff:
1147*0fca6ea1SDimitry Andric   case LibFunc_erfl:
1148e8d8bef9SDimitry Andric   case LibFunc_exp:
1149e8d8bef9SDimitry Andric   case LibFunc_expf:
1150e8d8bef9SDimitry Andric   case LibFunc_expl:
1151e8d8bef9SDimitry Andric   case LibFunc_exp2:
1152e8d8bef9SDimitry Andric   case LibFunc_exp2f:
1153e8d8bef9SDimitry Andric   case LibFunc_exp2l:
1154e8d8bef9SDimitry Andric   case LibFunc_expm1:
1155e8d8bef9SDimitry Andric   case LibFunc_expm1f:
1156e8d8bef9SDimitry Andric   case LibFunc_expm1l:
1157e8d8bef9SDimitry Andric   case LibFunc_fabs:
1158e8d8bef9SDimitry Andric   case LibFunc_fabsf:
1159e8d8bef9SDimitry Andric   case LibFunc_fabsl:
1160e8d8bef9SDimitry Andric   case LibFunc_ffs:
1161e8d8bef9SDimitry Andric   case LibFunc_ffsl:
1162e8d8bef9SDimitry Andric   case LibFunc_ffsll:
1163e8d8bef9SDimitry Andric   case LibFunc_floor:
1164e8d8bef9SDimitry Andric   case LibFunc_floorf:
1165e8d8bef9SDimitry Andric   case LibFunc_floorl:
1166e8d8bef9SDimitry Andric   case LibFunc_fls:
1167e8d8bef9SDimitry Andric   case LibFunc_flsl:
1168e8d8bef9SDimitry Andric   case LibFunc_flsll:
1169e8d8bef9SDimitry Andric   case LibFunc_fmax:
1170e8d8bef9SDimitry Andric   case LibFunc_fmaxf:
1171e8d8bef9SDimitry Andric   case LibFunc_fmaxl:
1172e8d8bef9SDimitry Andric   case LibFunc_fmin:
1173e8d8bef9SDimitry Andric   case LibFunc_fminf:
1174e8d8bef9SDimitry Andric   case LibFunc_fminl:
1175e8d8bef9SDimitry Andric   case LibFunc_fmod:
1176e8d8bef9SDimitry Andric   case LibFunc_fmodf:
1177e8d8bef9SDimitry Andric   case LibFunc_fmodl:
1178e8d8bef9SDimitry Andric   case LibFunc_isascii:
1179e8d8bef9SDimitry Andric   case LibFunc_isdigit:
1180e8d8bef9SDimitry Andric   case LibFunc_labs:
1181e8d8bef9SDimitry Andric   case LibFunc_llabs:
1182e8d8bef9SDimitry Andric   case LibFunc_log:
1183e8d8bef9SDimitry Andric   case LibFunc_log10:
1184e8d8bef9SDimitry Andric   case LibFunc_log10f:
1185e8d8bef9SDimitry Andric   case LibFunc_log10l:
1186e8d8bef9SDimitry Andric   case LibFunc_log1p:
1187e8d8bef9SDimitry Andric   case LibFunc_log1pf:
1188e8d8bef9SDimitry Andric   case LibFunc_log1pl:
1189e8d8bef9SDimitry Andric   case LibFunc_log2:
1190e8d8bef9SDimitry Andric   case LibFunc_log2f:
1191e8d8bef9SDimitry Andric   case LibFunc_log2l:
1192e8d8bef9SDimitry Andric   case LibFunc_logb:
1193e8d8bef9SDimitry Andric   case LibFunc_logbf:
1194e8d8bef9SDimitry Andric   case LibFunc_logbl:
1195e8d8bef9SDimitry Andric   case LibFunc_logf:
1196e8d8bef9SDimitry Andric   case LibFunc_logl:
1197e8d8bef9SDimitry Andric   case LibFunc_nearbyint:
1198e8d8bef9SDimitry Andric   case LibFunc_nearbyintf:
1199e8d8bef9SDimitry Andric   case LibFunc_nearbyintl:
1200e8d8bef9SDimitry Andric   case LibFunc_pow:
1201e8d8bef9SDimitry Andric   case LibFunc_powf:
1202e8d8bef9SDimitry Andric   case LibFunc_powl:
1203*0fca6ea1SDimitry Andric   case LibFunc_remainder:
1204*0fca6ea1SDimitry Andric   case LibFunc_remainderf:
1205*0fca6ea1SDimitry Andric   case LibFunc_remainderl:
1206e8d8bef9SDimitry Andric   case LibFunc_rint:
1207e8d8bef9SDimitry Andric   case LibFunc_rintf:
1208e8d8bef9SDimitry Andric   case LibFunc_rintl:
1209e8d8bef9SDimitry Andric   case LibFunc_round:
1210e8d8bef9SDimitry Andric   case LibFunc_roundf:
1211e8d8bef9SDimitry Andric   case LibFunc_roundl:
1212e8d8bef9SDimitry Andric   case LibFunc_sin:
1213e8d8bef9SDimitry Andric   case LibFunc_sincospif_stret:
1214e8d8bef9SDimitry Andric   case LibFunc_sinf:
1215e8d8bef9SDimitry Andric   case LibFunc_sinh:
1216e8d8bef9SDimitry Andric   case LibFunc_sinhf:
1217e8d8bef9SDimitry Andric   case LibFunc_sinhl:
1218e8d8bef9SDimitry Andric   case LibFunc_sinl:
1219e8d8bef9SDimitry Andric   case LibFunc_sinpi:
1220e8d8bef9SDimitry Andric   case LibFunc_sinpif:
1221e8d8bef9SDimitry Andric   case LibFunc_sqrt:
1222e8d8bef9SDimitry Andric   case LibFunc_sqrtf:
1223e8d8bef9SDimitry Andric   case LibFunc_sqrtl:
1224e8d8bef9SDimitry Andric   case LibFunc_tan:
1225e8d8bef9SDimitry Andric   case LibFunc_tanf:
1226e8d8bef9SDimitry Andric   case LibFunc_tanh:
1227e8d8bef9SDimitry Andric   case LibFunc_tanhf:
1228e8d8bef9SDimitry Andric   case LibFunc_tanhl:
1229e8d8bef9SDimitry Andric   case LibFunc_tanl:
1230e8d8bef9SDimitry Andric   case LibFunc_toascii:
1231e8d8bef9SDimitry Andric   case LibFunc_trunc:
1232e8d8bef9SDimitry Andric   case LibFunc_truncf:
1233e8d8bef9SDimitry Andric   case LibFunc_truncl:
1234e8d8bef9SDimitry Andric     Changed |= setDoesNotThrow(F);
1235e8d8bef9SDimitry Andric     Changed |= setDoesNotFreeMemory(F);
123604eeddc0SDimitry Andric     Changed |= setOnlyWritesMemory(F);
1237e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
1238fcaf7f86SDimitry Andric     break;
12390b57cec5SDimitry Andric   default:
12400b57cec5SDimitry Andric     // FIXME: It'd be really nice to cover all the library functions we're
12410b57cec5SDimitry Andric     // aware of here.
1242fcaf7f86SDimitry Andric     break;
12430b57cec5SDimitry Andric   }
1244fcaf7f86SDimitry Andric   // We have to do this step after AllocKind has been inferred on functions so
1245fcaf7f86SDimitry Andric   // we can reliably identify free-like and realloc-like functions.
1246bdd1243dSDimitry Andric   if (!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F))
1247fcaf7f86SDimitry Andric     Changed |= setDoesNotFreeMemory(F);
1248fcaf7f86SDimitry Andric   return Changed;
12490b57cec5SDimitry Andric }
12500b57cec5SDimitry Andric 
125181ad6265SDimitry Andric static void setArgExtAttr(Function &F, unsigned ArgNo,
125281ad6265SDimitry Andric                           const TargetLibraryInfo &TLI, bool Signed = true) {
125381ad6265SDimitry Andric   Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Param(Signed);
125481ad6265SDimitry Andric   if (ExtAttr != Attribute::None && !F.hasParamAttribute(ArgNo, ExtAttr))
125581ad6265SDimitry Andric     F.addParamAttr(ArgNo, ExtAttr);
125681ad6265SDimitry Andric }
125781ad6265SDimitry Andric 
1258bdd1243dSDimitry Andric static void setRetExtAttr(Function &F,
1259bdd1243dSDimitry Andric                           const TargetLibraryInfo &TLI, bool Signed = true) {
1260bdd1243dSDimitry Andric   Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Return(Signed);
1261bdd1243dSDimitry Andric   if (ExtAttr != Attribute::None && !F.hasRetAttribute(ExtAttr))
1262bdd1243dSDimitry Andric     F.addRetAttr(ExtAttr);
1263bdd1243dSDimitry Andric }
1264bdd1243dSDimitry Andric 
126581ad6265SDimitry Andric // Modeled after X86TargetLowering::markLibCallAttributes.
1266*0fca6ea1SDimitry Andric void llvm::markRegisterParameterAttributes(Function *F) {
126781ad6265SDimitry Andric   if (!F->arg_size() || F->isVarArg())
126881ad6265SDimitry Andric     return;
126981ad6265SDimitry Andric 
127081ad6265SDimitry Andric   const CallingConv::ID CC = F->getCallingConv();
127181ad6265SDimitry Andric   if (CC != CallingConv::C && CC != CallingConv::X86_StdCall)
127281ad6265SDimitry Andric     return;
127381ad6265SDimitry Andric 
127481ad6265SDimitry Andric   const Module *M = F->getParent();
127581ad6265SDimitry Andric   unsigned N = M->getNumberRegisterParameters();
127681ad6265SDimitry Andric   if (!N)
127781ad6265SDimitry Andric     return;
127881ad6265SDimitry Andric 
127981ad6265SDimitry Andric   const DataLayout &DL = M->getDataLayout();
128081ad6265SDimitry Andric 
128181ad6265SDimitry Andric   for (Argument &A : F->args()) {
128281ad6265SDimitry Andric     Type *T = A.getType();
128381ad6265SDimitry Andric     if (!T->isIntOrPtrTy())
128481ad6265SDimitry Andric       continue;
128581ad6265SDimitry Andric 
128681ad6265SDimitry Andric     const TypeSize &TS = DL.getTypeAllocSize(T);
128781ad6265SDimitry Andric     if (TS > 8)
128881ad6265SDimitry Andric       continue;
128981ad6265SDimitry Andric 
129081ad6265SDimitry Andric     assert(TS <= 4 && "Need to account for parameters larger than word size");
129181ad6265SDimitry Andric     const unsigned NumRegs = TS > 4 ? 2 : 1;
129281ad6265SDimitry Andric     if (N < NumRegs)
129381ad6265SDimitry Andric       return;
129481ad6265SDimitry Andric 
129581ad6265SDimitry Andric     N -= NumRegs;
129681ad6265SDimitry Andric     F->addParamAttr(A.getArgNo(), Attribute::InReg);
129781ad6265SDimitry Andric   }
129881ad6265SDimitry Andric }
129981ad6265SDimitry Andric 
130081ad6265SDimitry Andric FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,
130181ad6265SDimitry Andric                                         LibFunc TheLibFunc, FunctionType *T,
130281ad6265SDimitry Andric                                         AttributeList AttributeList) {
130381ad6265SDimitry Andric   assert(TLI.has(TheLibFunc) &&
130481ad6265SDimitry Andric          "Creating call to non-existing library function.");
130581ad6265SDimitry Andric   StringRef Name = TLI.getName(TheLibFunc);
130681ad6265SDimitry Andric   FunctionCallee C = M->getOrInsertFunction(Name, T, AttributeList);
130781ad6265SDimitry Andric 
130881ad6265SDimitry Andric   // Make sure any mandatory argument attributes are added.
130981ad6265SDimitry Andric 
131081ad6265SDimitry Andric   // Any outgoing i32 argument should be handled with setArgExtAttr() which
131181ad6265SDimitry Andric   // will add an extension attribute if the target ABI requires it. Adding
131281ad6265SDimitry Andric   // argument extensions is typically done by the front end but when an
131381ad6265SDimitry Andric   // optimizer is building a library call on its own it has to take care of
131481ad6265SDimitry Andric   // this. Each such generated function must be handled here with sign or
131581ad6265SDimitry Andric   // zero extensions as needed.  F is retreived with cast<> because we demand
131681ad6265SDimitry Andric   // of the caller to have called isLibFuncEmittable() first.
131781ad6265SDimitry Andric   Function *F = cast<Function>(C.getCallee());
131881ad6265SDimitry Andric   assert(F->getFunctionType() == T && "Function type does not match.");
131981ad6265SDimitry Andric   switch (TheLibFunc) {
132081ad6265SDimitry Andric   case LibFunc_fputc:
132181ad6265SDimitry Andric   case LibFunc_putchar:
132281ad6265SDimitry Andric     setArgExtAttr(*F, 0, TLI);
132381ad6265SDimitry Andric     break;
132481ad6265SDimitry Andric   case LibFunc_ldexp:
132581ad6265SDimitry Andric   case LibFunc_ldexpf:
132681ad6265SDimitry Andric   case LibFunc_ldexpl:
132781ad6265SDimitry Andric   case LibFunc_memchr:
132881ad6265SDimitry Andric   case LibFunc_memrchr:
132981ad6265SDimitry Andric   case LibFunc_strchr:
133081ad6265SDimitry Andric     setArgExtAttr(*F, 1, TLI);
133181ad6265SDimitry Andric     break;
133281ad6265SDimitry Andric   case LibFunc_memccpy:
133381ad6265SDimitry Andric     setArgExtAttr(*F, 2, TLI);
133481ad6265SDimitry Andric     break;
133581ad6265SDimitry Andric 
133681ad6265SDimitry Andric     // These are functions that are known to not need any argument extension
133781ad6265SDimitry Andric     // on any target: A size_t argument (which may be an i32 on some targets)
133881ad6265SDimitry Andric     // should not trigger the assert below.
133981ad6265SDimitry Andric   case LibFunc_bcmp:
1340bdd1243dSDimitry Andric     setRetExtAttr(*F, TLI);
1341bdd1243dSDimitry Andric     break;
134281ad6265SDimitry Andric   case LibFunc_calloc:
134381ad6265SDimitry Andric   case LibFunc_fwrite:
134481ad6265SDimitry Andric   case LibFunc_malloc:
134581ad6265SDimitry Andric   case LibFunc_memcmp:
134681ad6265SDimitry Andric   case LibFunc_memcpy_chk:
134781ad6265SDimitry Andric   case LibFunc_mempcpy:
134881ad6265SDimitry Andric   case LibFunc_memset_pattern16:
134981ad6265SDimitry Andric   case LibFunc_snprintf:
135081ad6265SDimitry Andric   case LibFunc_stpncpy:
135181ad6265SDimitry Andric   case LibFunc_strlcat:
135281ad6265SDimitry Andric   case LibFunc_strlcpy:
135381ad6265SDimitry Andric   case LibFunc_strncat:
135481ad6265SDimitry Andric   case LibFunc_strncmp:
135581ad6265SDimitry Andric   case LibFunc_strncpy:
135681ad6265SDimitry Andric   case LibFunc_vsnprintf:
135781ad6265SDimitry Andric     break;
135881ad6265SDimitry Andric 
135981ad6265SDimitry Andric   default:
136081ad6265SDimitry Andric #ifndef NDEBUG
136181ad6265SDimitry Andric     for (unsigned i = 0; i < T->getNumParams(); i++)
136281ad6265SDimitry Andric       assert(!isa<IntegerType>(T->getParamType(i)) &&
136381ad6265SDimitry Andric              "Unhandled integer argument.");
136481ad6265SDimitry Andric #endif
136581ad6265SDimitry Andric     break;
136681ad6265SDimitry Andric   }
136781ad6265SDimitry Andric 
136881ad6265SDimitry Andric   markRegisterParameterAttributes(F);
136981ad6265SDimitry Andric 
137081ad6265SDimitry Andric   return C;
137181ad6265SDimitry Andric }
137281ad6265SDimitry Andric 
137381ad6265SDimitry Andric FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,
137481ad6265SDimitry Andric                                         LibFunc TheLibFunc, FunctionType *T) {
137581ad6265SDimitry Andric   return getOrInsertLibFunc(M, TLI, TheLibFunc, T, AttributeList());
137681ad6265SDimitry Andric }
137781ad6265SDimitry Andric 
137881ad6265SDimitry Andric bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,
137981ad6265SDimitry Andric                               LibFunc TheLibFunc) {
138081ad6265SDimitry Andric   StringRef FuncName = TLI->getName(TheLibFunc);
138181ad6265SDimitry Andric   if (!TLI->has(TheLibFunc))
138281ad6265SDimitry Andric     return false;
138381ad6265SDimitry Andric 
138481ad6265SDimitry Andric   // Check if the Module already has a GlobalValue with the same name, in
138581ad6265SDimitry Andric   // which case it must be a Function with the expected type.
138681ad6265SDimitry Andric   if (GlobalValue *GV = M->getNamedValue(FuncName)) {
138781ad6265SDimitry Andric     if (auto *F = dyn_cast<Function>(GV))
138881ad6265SDimitry Andric       return TLI->isValidProtoForLibFunc(*F->getFunctionType(), TheLibFunc, *M);
138981ad6265SDimitry Andric     return false;
139081ad6265SDimitry Andric   }
139181ad6265SDimitry Andric 
139281ad6265SDimitry Andric   return true;
139381ad6265SDimitry Andric }
139481ad6265SDimitry Andric 
139581ad6265SDimitry Andric bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,
139681ad6265SDimitry Andric                               StringRef Name) {
139781ad6265SDimitry Andric   LibFunc TheLibFunc;
139881ad6265SDimitry Andric   return TLI->getLibFunc(Name, TheLibFunc) &&
139981ad6265SDimitry Andric          isLibFuncEmittable(M, TLI, TheLibFunc);
140081ad6265SDimitry Andric }
140181ad6265SDimitry Andric 
140281ad6265SDimitry Andric bool llvm::hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty,
14038bcb0991SDimitry Andric                       LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) {
14040b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
14050b57cec5SDimitry Andric   case Type::HalfTyID:
14060b57cec5SDimitry Andric     return false;
14070b57cec5SDimitry Andric   case Type::FloatTyID:
140881ad6265SDimitry Andric     return isLibFuncEmittable(M, TLI, FloatFn);
14090b57cec5SDimitry Andric   case Type::DoubleTyID:
141081ad6265SDimitry Andric     return isLibFuncEmittable(M, TLI, DoubleFn);
14110b57cec5SDimitry Andric   default:
141281ad6265SDimitry Andric     return isLibFuncEmittable(M, TLI, LongDoubleFn);
14130b57cec5SDimitry Andric   }
14140b57cec5SDimitry Andric }
14150b57cec5SDimitry Andric 
141681ad6265SDimitry Andric StringRef llvm::getFloatFn(const Module *M, const TargetLibraryInfo *TLI,
141781ad6265SDimitry Andric                            Type *Ty, LibFunc DoubleFn, LibFunc FloatFn,
141881ad6265SDimitry Andric                            LibFunc LongDoubleFn, LibFunc &TheLibFunc) {
141981ad6265SDimitry Andric   assert(hasFloatFn(M, TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
14200b57cec5SDimitry Andric          "Cannot get name for unavailable function!");
14210b57cec5SDimitry Andric 
14220b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
14230b57cec5SDimitry Andric   case Type::HalfTyID:
14240b57cec5SDimitry Andric     llvm_unreachable("No name for HalfTy!");
14250b57cec5SDimitry Andric   case Type::FloatTyID:
142681ad6265SDimitry Andric     TheLibFunc = FloatFn;
14270b57cec5SDimitry Andric     return TLI->getName(FloatFn);
14280b57cec5SDimitry Andric   case Type::DoubleTyID:
142981ad6265SDimitry Andric     TheLibFunc = DoubleFn;
14300b57cec5SDimitry Andric     return TLI->getName(DoubleFn);
14310b57cec5SDimitry Andric   default:
143281ad6265SDimitry Andric     TheLibFunc = LongDoubleFn;
14330b57cec5SDimitry Andric     return TLI->getName(LongDoubleFn);
14340b57cec5SDimitry Andric   }
14350b57cec5SDimitry Andric }
14360b57cec5SDimitry Andric 
14370b57cec5SDimitry Andric //- Emit LibCalls ------------------------------------------------------------//
14380b57cec5SDimitry Andric 
1439bdd1243dSDimitry Andric static IntegerType *getIntTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) {
1440bdd1243dSDimitry Andric   return B.getIntNTy(TLI->getIntSize());
1441bdd1243dSDimitry Andric }
1442bdd1243dSDimitry Andric 
1443bdd1243dSDimitry Andric static IntegerType *getSizeTTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) {
1444bdd1243dSDimitry Andric   const Module *M = B.GetInsertBlock()->getModule();
1445bdd1243dSDimitry Andric   return B.getIntNTy(TLI->getSizeTSize(*M));
1446bdd1243dSDimitry Andric }
1447bdd1243dSDimitry Andric 
14480b57cec5SDimitry Andric static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType,
14490b57cec5SDimitry Andric                           ArrayRef<Type *> ParamTypes,
14505ffd83dbSDimitry Andric                           ArrayRef<Value *> Operands, IRBuilderBase &B,
14510b57cec5SDimitry Andric                           const TargetLibraryInfo *TLI,
14520b57cec5SDimitry Andric                           bool IsVaArgs = false) {
145381ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
145481ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, TheLibFunc))
14550b57cec5SDimitry Andric     return nullptr;
14560b57cec5SDimitry Andric 
14570b57cec5SDimitry Andric   StringRef FuncName = TLI->getName(TheLibFunc);
14580b57cec5SDimitry Andric   FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs);
145981ad6265SDimitry Andric   FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, FuncType);
146081ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, FuncName, *TLI);
14610b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(Callee, Operands, FuncName);
14620b57cec5SDimitry Andric   if (const Function *F =
14630b57cec5SDimitry Andric           dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
14640b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
14650b57cec5SDimitry Andric   return CI;
14660b57cec5SDimitry Andric }
14670b57cec5SDimitry Andric 
14685ffd83dbSDimitry Andric Value *llvm::emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,
14690b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
14705f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1471bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
14725f757f3fSDimitry Andric   return emitLibCall(LibFunc_strlen, SizeTTy, CharPtrTy, Ptr, B, TLI);
14730b57cec5SDimitry Andric }
14740b57cec5SDimitry Andric 
14755ffd83dbSDimitry Andric Value *llvm::emitStrDup(Value *Ptr, IRBuilderBase &B,
14768bcb0991SDimitry Andric                         const TargetLibraryInfo *TLI) {
14775f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
14785f757f3fSDimitry Andric   return emitLibCall(LibFunc_strdup, CharPtrTy, CharPtrTy, Ptr, B, TLI);
14798bcb0991SDimitry Andric }
14808bcb0991SDimitry Andric 
14815ffd83dbSDimitry Andric Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilderBase &B,
14820b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
14835f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1484bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
14855f757f3fSDimitry Andric   return emitLibCall(LibFunc_strchr, CharPtrTy, {CharPtrTy, IntTy},
14865f757f3fSDimitry Andric                      {Ptr, ConstantInt::get(IntTy, C)}, B, TLI);
14870b57cec5SDimitry Andric }
14880b57cec5SDimitry Andric 
14895ffd83dbSDimitry Andric Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
14900b57cec5SDimitry Andric                          const DataLayout &DL, const TargetLibraryInfo *TLI) {
14915f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1492bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1493bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
14940b57cec5SDimitry Andric   return emitLibCall(
1495bdd1243dSDimitry Andric       LibFunc_strncmp, IntTy,
14965f757f3fSDimitry Andric       {CharPtrTy, CharPtrTy, SizeTTy},
14975f757f3fSDimitry Andric       {Ptr1, Ptr2, Len}, B, TLI);
14980b57cec5SDimitry Andric }
14990b57cec5SDimitry Andric 
15005ffd83dbSDimitry Andric Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B,
15010b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
15025f757f3fSDimitry Andric   Type *CharPtrTy = Dst->getType();
15035f757f3fSDimitry Andric   return emitLibCall(LibFunc_strcpy, CharPtrTy, {CharPtrTy, CharPtrTy},
15045f757f3fSDimitry Andric                      {Dst, Src}, B, TLI);
15050b57cec5SDimitry Andric }
15060b57cec5SDimitry Andric 
15075ffd83dbSDimitry Andric Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B,
15080b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
15095f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
15105f757f3fSDimitry Andric   return emitLibCall(LibFunc_stpcpy, CharPtrTy, {CharPtrTy, CharPtrTy},
15115f757f3fSDimitry Andric                      {Dst, Src}, B, TLI);
15120b57cec5SDimitry Andric }
15130b57cec5SDimitry Andric 
15145ffd83dbSDimitry Andric Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
15150b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
15165f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1517bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15185f757f3fSDimitry Andric   return emitLibCall(LibFunc_strncpy, CharPtrTy, {CharPtrTy, CharPtrTy, SizeTTy},
15195f757f3fSDimitry Andric                      {Dst, Src, Len}, B, TLI);
15200b57cec5SDimitry Andric }
15210b57cec5SDimitry Andric 
15225ffd83dbSDimitry Andric Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
15230b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
15245f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1525bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15265f757f3fSDimitry Andric   return emitLibCall(LibFunc_stpncpy, CharPtrTy, {CharPtrTy, CharPtrTy, SizeTTy},
15275f757f3fSDimitry Andric                      {Dst, Src, Len}, B, TLI);
15280b57cec5SDimitry Andric }
15290b57cec5SDimitry Andric 
15300b57cec5SDimitry Andric Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
15315ffd83dbSDimitry Andric                            IRBuilderBase &B, const DataLayout &DL,
15320b57cec5SDimitry Andric                            const TargetLibraryInfo *TLI) {
153381ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
153481ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_memcpy_chk))
15350b57cec5SDimitry Andric     return nullptr;
15360b57cec5SDimitry Andric 
15370b57cec5SDimitry Andric   AttributeList AS;
15380b57cec5SDimitry Andric   AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
15390b57cec5SDimitry Andric                           Attribute::NoUnwind);
15405f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1541bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
154281ad6265SDimitry Andric   FunctionCallee MemCpy = getOrInsertLibFunc(M, *TLI, LibFunc_memcpy_chk,
15435f757f3fSDimitry Andric       AttributeList::get(M->getContext(), AS), VoidPtrTy,
15445f757f3fSDimitry Andric       VoidPtrTy, VoidPtrTy, SizeTTy, SizeTTy);
15450b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
15460b57cec5SDimitry Andric   if (const Function *F =
15470b57cec5SDimitry Andric           dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts()))
15480b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
15490b57cec5SDimitry Andric   return CI;
15500b57cec5SDimitry Andric }
15510b57cec5SDimitry Andric 
1552e8d8bef9SDimitry Andric Value *llvm::emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
1553e8d8bef9SDimitry Andric                          const DataLayout &DL, const TargetLibraryInfo *TLI) {
15545f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1555bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15565f757f3fSDimitry Andric   return emitLibCall(LibFunc_mempcpy, VoidPtrTy,
15575f757f3fSDimitry Andric                      {VoidPtrTy, VoidPtrTy, SizeTTy},
1558e8d8bef9SDimitry Andric                      {Dst, Src, Len}, B, TLI);
1559e8d8bef9SDimitry Andric }
1560e8d8bef9SDimitry Andric 
15615ffd83dbSDimitry Andric Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
15620b57cec5SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
15635f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1564bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1565bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15665f757f3fSDimitry Andric   return emitLibCall(LibFunc_memchr, VoidPtrTy,
15675f757f3fSDimitry Andric                      {VoidPtrTy, IntTy, SizeTTy},
15685f757f3fSDimitry Andric                      {Ptr, Val, Len}, B, TLI);
15690b57cec5SDimitry Andric }
15700b57cec5SDimitry Andric 
157181ad6265SDimitry Andric Value *llvm::emitMemRChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
157281ad6265SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
15735f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1574bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1575bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15765f757f3fSDimitry Andric   return emitLibCall(LibFunc_memrchr, VoidPtrTy,
15775f757f3fSDimitry Andric                      {VoidPtrTy, IntTy, SizeTTy},
15785f757f3fSDimitry Andric                      {Ptr, Val, Len}, B, TLI);
157981ad6265SDimitry Andric }
158081ad6265SDimitry Andric 
15815ffd83dbSDimitry Andric Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
15820b57cec5SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
15835f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1584bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1585bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
1586bdd1243dSDimitry Andric   return emitLibCall(LibFunc_memcmp, IntTy,
15875f757f3fSDimitry Andric                      {VoidPtrTy, VoidPtrTy, SizeTTy},
15885f757f3fSDimitry Andric                      {Ptr1, Ptr2, Len}, B, TLI);
15890b57cec5SDimitry Andric }
15900b57cec5SDimitry Andric 
15915ffd83dbSDimitry Andric Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
15920b57cec5SDimitry Andric                       const DataLayout &DL, const TargetLibraryInfo *TLI) {
15935f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1594bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1595bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
1596bdd1243dSDimitry Andric   return emitLibCall(LibFunc_bcmp, IntTy,
15975f757f3fSDimitry Andric                      {VoidPtrTy, VoidPtrTy, SizeTTy},
15985f757f3fSDimitry Andric                      {Ptr1, Ptr2, Len}, B, TLI);
15990b57cec5SDimitry Andric }
16000b57cec5SDimitry Andric 
16010b57cec5SDimitry Andric Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
16025ffd83dbSDimitry Andric                          IRBuilderBase &B, const TargetLibraryInfo *TLI) {
16035f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1604bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1605bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
16065f757f3fSDimitry Andric   return emitLibCall(LibFunc_memccpy, VoidPtrTy,
16075f757f3fSDimitry Andric                      {VoidPtrTy, VoidPtrTy, IntTy, SizeTTy},
16080b57cec5SDimitry Andric                      {Ptr1, Ptr2, Val, Len}, B, TLI);
16090b57cec5SDimitry Andric }
16100b57cec5SDimitry Andric 
16110b57cec5SDimitry Andric Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
16125ffd83dbSDimitry Andric                           ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,
16130b57cec5SDimitry Andric                           const TargetLibraryInfo *TLI) {
16145f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1615bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1616bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
16175f757f3fSDimitry Andric   SmallVector<Value *, 8> Args{Dest, Size, Fmt};
1618e8d8bef9SDimitry Andric   llvm::append_range(Args, VariadicArgs);
1619bdd1243dSDimitry Andric   return emitLibCall(LibFunc_snprintf, IntTy,
16205f757f3fSDimitry Andric                      {CharPtrTy, SizeTTy, CharPtrTy},
16210b57cec5SDimitry Andric                      Args, B, TLI, /*IsVaArgs=*/true);
16220b57cec5SDimitry Andric }
16230b57cec5SDimitry Andric 
16240b57cec5SDimitry Andric Value *llvm::emitSPrintf(Value *Dest, Value *Fmt,
16255ffd83dbSDimitry Andric                          ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,
16260b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
16275f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1628bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
16295f757f3fSDimitry Andric   SmallVector<Value *, 8> Args{Dest, Fmt};
1630e8d8bef9SDimitry Andric   llvm::append_range(Args, VariadicArgs);
1631bdd1243dSDimitry Andric   return emitLibCall(LibFunc_sprintf, IntTy,
16325f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy}, Args, B, TLI,
16330b57cec5SDimitry Andric                      /*IsVaArgs=*/true);
16340b57cec5SDimitry Andric }
16350b57cec5SDimitry Andric 
16365ffd83dbSDimitry Andric Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B,
16370b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
16385f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
16395f757f3fSDimitry Andric   return emitLibCall(LibFunc_strcat, CharPtrTy,
16405f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy},
16415f757f3fSDimitry Andric                      {Dest, Src}, B, TLI);
16420b57cec5SDimitry Andric }
16430b57cec5SDimitry Andric 
16445ffd83dbSDimitry Andric Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
16450b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
16465f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1647bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
1648bdd1243dSDimitry Andric   return emitLibCall(LibFunc_strlcpy, SizeTTy,
16495f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy, SizeTTy},
16505f757f3fSDimitry Andric                      {Dest, Src, Size}, B, TLI);
16510b57cec5SDimitry Andric }
16520b57cec5SDimitry Andric 
16535ffd83dbSDimitry Andric Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
16540b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
16555f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1656bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
1657bdd1243dSDimitry Andric   return emitLibCall(LibFunc_strlcat, SizeTTy,
16585f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy, SizeTTy},
16595f757f3fSDimitry Andric                      {Dest, Src, Size}, B, TLI);
16600b57cec5SDimitry Andric }
16610b57cec5SDimitry Andric 
16625ffd83dbSDimitry Andric Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
16630b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
16645f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1665bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
16665f757f3fSDimitry Andric   return emitLibCall(LibFunc_strncat, CharPtrTy,
16675f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy, SizeTTy},
16685f757f3fSDimitry Andric                      {Dest, Src, Size}, B, TLI);
16690b57cec5SDimitry Andric }
16700b57cec5SDimitry Andric 
16710b57cec5SDimitry Andric Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
16725ffd83dbSDimitry Andric                            IRBuilderBase &B, const TargetLibraryInfo *TLI) {
16735f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1674bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1675bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
16760b57cec5SDimitry Andric   return emitLibCall(
1677bdd1243dSDimitry Andric       LibFunc_vsnprintf, IntTy,
16785f757f3fSDimitry Andric       {CharPtrTy, SizeTTy, CharPtrTy, VAList->getType()},
16795f757f3fSDimitry Andric       {Dest, Size, Fmt, VAList}, B, TLI);
16800b57cec5SDimitry Andric }
16810b57cec5SDimitry Andric 
16820b57cec5SDimitry Andric Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList,
16835ffd83dbSDimitry Andric                           IRBuilderBase &B, const TargetLibraryInfo *TLI) {
16845f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1685bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1686bdd1243dSDimitry Andric   return emitLibCall(LibFunc_vsprintf, IntTy,
16875f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy, VAList->getType()},
16885f757f3fSDimitry Andric                      {Dest, Fmt, VAList}, B, TLI);
16890b57cec5SDimitry Andric }
16900b57cec5SDimitry Andric 
16910b57cec5SDimitry Andric /// Append a suffix to the function name according to the type of 'Op'.
16920b57cec5SDimitry Andric static void appendTypeSuffix(Value *Op, StringRef &Name,
16930b57cec5SDimitry Andric                              SmallString<20> &NameBuffer) {
16940b57cec5SDimitry Andric   if (!Op->getType()->isDoubleTy()) {
16950b57cec5SDimitry Andric       NameBuffer += Name;
16960b57cec5SDimitry Andric 
16970b57cec5SDimitry Andric     if (Op->getType()->isFloatTy())
16980b57cec5SDimitry Andric       NameBuffer += 'f';
16990b57cec5SDimitry Andric     else
17000b57cec5SDimitry Andric       NameBuffer += 'l';
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric     Name = NameBuffer;
17030b57cec5SDimitry Andric   }
17040b57cec5SDimitry Andric }
17050b57cec5SDimitry Andric 
170681ad6265SDimitry Andric static Value *emitUnaryFloatFnCallHelper(Value *Op, LibFunc TheLibFunc,
170781ad6265SDimitry Andric                                          StringRef Name, IRBuilderBase &B,
170881ad6265SDimitry Andric                                          const AttributeList &Attrs,
170981ad6265SDimitry Andric                                          const TargetLibraryInfo *TLI) {
17100b57cec5SDimitry Andric   assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
17110b57cec5SDimitry Andric 
17120b57cec5SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
171381ad6265SDimitry Andric   FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op->getType(),
171481ad6265SDimitry Andric                                              Op->getType());
17150b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(Callee, Op, Name);
17160b57cec5SDimitry Andric 
17170b57cec5SDimitry Andric   // The incoming attribute set may have come from a speculatable intrinsic, but
17180b57cec5SDimitry Andric   // is being replaced with a library call which is not allowed to be
17190b57cec5SDimitry Andric   // speculatable.
1720349cc55cSDimitry Andric   CI->setAttributes(
1721349cc55cSDimitry Andric       Attrs.removeFnAttribute(B.getContext(), Attribute::Speculatable));
17220b57cec5SDimitry Andric   if (const Function *F =
17230b57cec5SDimitry Andric           dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
17240b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
17250b57cec5SDimitry Andric 
17260b57cec5SDimitry Andric   return CI;
17270b57cec5SDimitry Andric }
17280b57cec5SDimitry Andric 
172981ad6265SDimitry Andric Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
173081ad6265SDimitry Andric                                   StringRef Name, IRBuilderBase &B,
17310b57cec5SDimitry Andric                                   const AttributeList &Attrs) {
17320b57cec5SDimitry Andric   SmallString<20> NameBuffer;
17330b57cec5SDimitry Andric   appendTypeSuffix(Op, Name, NameBuffer);
17340b57cec5SDimitry Andric 
173581ad6265SDimitry Andric   LibFunc TheLibFunc;
173681ad6265SDimitry Andric   TLI->getLibFunc(Name, TheLibFunc);
173781ad6265SDimitry Andric 
173881ad6265SDimitry Andric   return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI);
17390b57cec5SDimitry Andric }
17400b57cec5SDimitry Andric 
17410b57cec5SDimitry Andric Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
17420b57cec5SDimitry Andric                                   LibFunc DoubleFn, LibFunc FloatFn,
17435ffd83dbSDimitry Andric                                   LibFunc LongDoubleFn, IRBuilderBase &B,
17440b57cec5SDimitry Andric                                   const AttributeList &Attrs) {
17450b57cec5SDimitry Andric   // Get the name of the function according to TLI.
174681ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
174781ad6265SDimitry Andric   LibFunc TheLibFunc;
174881ad6265SDimitry Andric   StringRef Name = getFloatFn(M, TLI, Op->getType(), DoubleFn, FloatFn,
174981ad6265SDimitry Andric                               LongDoubleFn, TheLibFunc);
17500b57cec5SDimitry Andric 
175181ad6265SDimitry Andric   return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI);
17520b57cec5SDimitry Andric }
17530b57cec5SDimitry Andric 
17548bcb0991SDimitry Andric static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2,
175581ad6265SDimitry Andric                                           LibFunc TheLibFunc,
17565ffd83dbSDimitry Andric                                           StringRef Name, IRBuilderBase &B,
1757e8d8bef9SDimitry Andric                                           const AttributeList &Attrs,
175881ad6265SDimitry Andric                                           const TargetLibraryInfo *TLI) {
17598bcb0991SDimitry Andric   assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
17608bcb0991SDimitry Andric 
17618bcb0991SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
176281ad6265SDimitry Andric   FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op1->getType(),
17638bcb0991SDimitry Andric                                              Op1->getType(), Op2->getType());
176481ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, Name, *TLI);
17658bcb0991SDimitry Andric   CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name);
17668bcb0991SDimitry Andric 
17678bcb0991SDimitry Andric   // The incoming attribute set may have come from a speculatable intrinsic, but
17688bcb0991SDimitry Andric   // is being replaced with a library call which is not allowed to be
17698bcb0991SDimitry Andric   // speculatable.
1770349cc55cSDimitry Andric   CI->setAttributes(
1771349cc55cSDimitry Andric       Attrs.removeFnAttribute(B.getContext(), Attribute::Speculatable));
17728bcb0991SDimitry Andric   if (const Function *F =
17738bcb0991SDimitry Andric           dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
17748bcb0991SDimitry Andric     CI->setCallingConv(F->getCallingConv());
17758bcb0991SDimitry Andric 
17768bcb0991SDimitry Andric   return CI;
17778bcb0991SDimitry Andric }
17788bcb0991SDimitry Andric 
177981ad6265SDimitry Andric Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,
178081ad6265SDimitry Andric                                    const TargetLibraryInfo *TLI,
178181ad6265SDimitry Andric                                    StringRef Name, IRBuilderBase &B,
17825ffd83dbSDimitry Andric                                    const AttributeList &Attrs) {
17830b57cec5SDimitry Andric   assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
17840b57cec5SDimitry Andric 
17850b57cec5SDimitry Andric   SmallString<20> NameBuffer;
17860b57cec5SDimitry Andric   appendTypeSuffix(Op1, Name, NameBuffer);
17870b57cec5SDimitry Andric 
178881ad6265SDimitry Andric   LibFunc TheLibFunc;
178981ad6265SDimitry Andric   TLI->getLibFunc(Name, TheLibFunc);
179081ad6265SDimitry Andric 
179181ad6265SDimitry Andric   return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI);
17928bcb0991SDimitry Andric }
17930b57cec5SDimitry Andric 
17948bcb0991SDimitry Andric Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,
17958bcb0991SDimitry Andric                                    const TargetLibraryInfo *TLI,
17968bcb0991SDimitry Andric                                    LibFunc DoubleFn, LibFunc FloatFn,
17975ffd83dbSDimitry Andric                                    LibFunc LongDoubleFn, IRBuilderBase &B,
17988bcb0991SDimitry Andric                                    const AttributeList &Attrs) {
17998bcb0991SDimitry Andric   // Get the name of the function according to TLI.
180081ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
180181ad6265SDimitry Andric   LibFunc TheLibFunc;
180281ad6265SDimitry Andric   StringRef Name = getFloatFn(M, TLI, Op1->getType(), DoubleFn, FloatFn,
180381ad6265SDimitry Andric                               LongDoubleFn, TheLibFunc);
18048bcb0991SDimitry Andric 
180581ad6265SDimitry Andric   return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI);
18060b57cec5SDimitry Andric }
18070b57cec5SDimitry Andric 
1808bdd1243dSDimitry Andric // Emit a call to putchar(int) with Char as the argument.  Char must have
1809bdd1243dSDimitry Andric // the same precision as int, which need not be 32 bits.
18105ffd83dbSDimitry Andric Value *llvm::emitPutChar(Value *Char, IRBuilderBase &B,
18110b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
181281ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
181381ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_putchar))
18140b57cec5SDimitry Andric     return nullptr;
18150b57cec5SDimitry Andric 
1816bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
18170b57cec5SDimitry Andric   StringRef PutCharName = TLI->getName(LibFunc_putchar);
181881ad6265SDimitry Andric   FunctionCallee PutChar = getOrInsertLibFunc(M, *TLI, LibFunc_putchar,
1819bdd1243dSDimitry Andric                                               IntTy, IntTy);
182081ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, PutCharName, *TLI);
1821bdd1243dSDimitry Andric   CallInst *CI = B.CreateCall(PutChar, Char, PutCharName);
18220b57cec5SDimitry Andric 
18230b57cec5SDimitry Andric   if (const Function *F =
18240b57cec5SDimitry Andric           dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts()))
18250b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
18260b57cec5SDimitry Andric   return CI;
18270b57cec5SDimitry Andric }
18280b57cec5SDimitry Andric 
18295ffd83dbSDimitry Andric Value *llvm::emitPutS(Value *Str, IRBuilderBase &B,
18300b57cec5SDimitry Andric                       const TargetLibraryInfo *TLI) {
183181ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
183281ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_puts))
18330b57cec5SDimitry Andric     return nullptr;
18340b57cec5SDimitry Andric 
1835bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
18360b57cec5SDimitry Andric   StringRef PutsName = TLI->getName(LibFunc_puts);
1837bdd1243dSDimitry Andric   FunctionCallee PutS = getOrInsertLibFunc(M, *TLI, LibFunc_puts, IntTy,
18385f757f3fSDimitry Andric                                            B.getPtrTy());
183981ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, PutsName, *TLI);
18405f757f3fSDimitry Andric   CallInst *CI = B.CreateCall(PutS, Str, PutsName);
18410b57cec5SDimitry Andric   if (const Function *F =
18420b57cec5SDimitry Andric           dyn_cast<Function>(PutS.getCallee()->stripPointerCasts()))
18430b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
18440b57cec5SDimitry Andric   return CI;
18450b57cec5SDimitry Andric }
18460b57cec5SDimitry Andric 
18475ffd83dbSDimitry Andric Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilderBase &B,
18480b57cec5SDimitry Andric                        const TargetLibraryInfo *TLI) {
184981ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
185081ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_fputc))
18510b57cec5SDimitry Andric     return nullptr;
18520b57cec5SDimitry Andric 
1853bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
18540b57cec5SDimitry Andric   StringRef FPutcName = TLI->getName(LibFunc_fputc);
1855bdd1243dSDimitry Andric   FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputc, IntTy,
1856bdd1243dSDimitry Andric                                         IntTy, File->getType());
18570b57cec5SDimitry Andric   if (File->getType()->isPointerTy())
185881ad6265SDimitry Andric     inferNonMandatoryLibFuncAttrs(M, FPutcName, *TLI);
18590b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
18600b57cec5SDimitry Andric 
18610b57cec5SDimitry Andric   if (const Function *Fn =
18620b57cec5SDimitry Andric           dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
18630b57cec5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
18640b57cec5SDimitry Andric   return CI;
18650b57cec5SDimitry Andric }
18660b57cec5SDimitry Andric 
18675ffd83dbSDimitry Andric Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilderBase &B,
18680b57cec5SDimitry Andric                        const TargetLibraryInfo *TLI) {
186981ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
187081ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_fputs))
18710b57cec5SDimitry Andric     return nullptr;
18720b57cec5SDimitry Andric 
1873bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
18740b57cec5SDimitry Andric   StringRef FPutsName = TLI->getName(LibFunc_fputs);
1875bdd1243dSDimitry Andric   FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputs, IntTy,
18765f757f3fSDimitry Andric                                         B.getPtrTy(), File->getType());
18770b57cec5SDimitry Andric   if (File->getType()->isPointerTy())
187881ad6265SDimitry Andric     inferNonMandatoryLibFuncAttrs(M, FPutsName, *TLI);
18795f757f3fSDimitry Andric   CallInst *CI = B.CreateCall(F, {Str, File}, FPutsName);
18800b57cec5SDimitry Andric 
18810b57cec5SDimitry Andric   if (const Function *Fn =
18820b57cec5SDimitry Andric           dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
18830b57cec5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
18840b57cec5SDimitry Andric   return CI;
18850b57cec5SDimitry Andric }
18860b57cec5SDimitry Andric 
18875ffd83dbSDimitry Andric Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B,
18880b57cec5SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
188981ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
189081ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_fwrite))
18910b57cec5SDimitry Andric     return nullptr;
18920b57cec5SDimitry Andric 
1893bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
18940b57cec5SDimitry Andric   StringRef FWriteName = TLI->getName(LibFunc_fwrite);
189581ad6265SDimitry Andric   FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fwrite,
18965f757f3fSDimitry Andric                                         SizeTTy, B.getPtrTy(), SizeTTy,
1897bdd1243dSDimitry Andric                                         SizeTTy, File->getType());
18980b57cec5SDimitry Andric 
18990b57cec5SDimitry Andric   if (File->getType()->isPointerTy())
190081ad6265SDimitry Andric     inferNonMandatoryLibFuncAttrs(M, FWriteName, *TLI);
19010b57cec5SDimitry Andric   CallInst *CI =
19025f757f3fSDimitry Andric       B.CreateCall(F, {Ptr, Size,
1903bdd1243dSDimitry Andric                        ConstantInt::get(SizeTTy, 1), File});
19040b57cec5SDimitry Andric 
19050b57cec5SDimitry Andric   if (const Function *Fn =
19060b57cec5SDimitry Andric           dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
19070b57cec5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
19080b57cec5SDimitry Andric   return CI;
19090b57cec5SDimitry Andric }
19100b57cec5SDimitry Andric 
19115ffd83dbSDimitry Andric Value *llvm::emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL,
19120b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
191381ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
191481ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_malloc))
19150b57cec5SDimitry Andric     return nullptr;
19160b57cec5SDimitry Andric 
19170b57cec5SDimitry Andric   StringRef MallocName = TLI->getName(LibFunc_malloc);
1918bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
191981ad6265SDimitry Andric   FunctionCallee Malloc = getOrInsertLibFunc(M, *TLI, LibFunc_malloc,
19205f757f3fSDimitry Andric                                              B.getPtrTy(), SizeTTy);
192181ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, MallocName, *TLI);
19220b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
19230b57cec5SDimitry Andric 
19240b57cec5SDimitry Andric   if (const Function *F =
19250b57cec5SDimitry Andric           dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts()))
19260b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
19270b57cec5SDimitry Andric 
19280b57cec5SDimitry Andric   return CI;
19290b57cec5SDimitry Andric }
19300b57cec5SDimitry Andric 
1931349cc55cSDimitry Andric Value *llvm::emitCalloc(Value *Num, Value *Size, IRBuilderBase &B,
1932349cc55cSDimitry Andric                         const TargetLibraryInfo &TLI) {
193381ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
193481ad6265SDimitry Andric   if (!isLibFuncEmittable(M, &TLI, LibFunc_calloc))
19350b57cec5SDimitry Andric     return nullptr;
19360b57cec5SDimitry Andric 
19370b57cec5SDimitry Andric   StringRef CallocName = TLI.getName(LibFunc_calloc);
1938bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, &TLI);
193981ad6265SDimitry Andric   FunctionCallee Calloc = getOrInsertLibFunc(M, TLI, LibFunc_calloc,
19405f757f3fSDimitry Andric                                              B.getPtrTy(), SizeTTy, SizeTTy);
194181ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, CallocName, TLI);
19420b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
19430b57cec5SDimitry Andric 
19440b57cec5SDimitry Andric   if (const auto *F =
19450b57cec5SDimitry Andric           dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts()))
19460b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
19470b57cec5SDimitry Andric 
19480b57cec5SDimitry Andric   return CI;
19490b57cec5SDimitry Andric }
195006c3fb27SDimitry Andric 
195106c3fb27SDimitry Andric Value *llvm::emitHotColdNew(Value *Num, IRBuilderBase &B,
195206c3fb27SDimitry Andric                             const TargetLibraryInfo *TLI, LibFunc NewFunc,
195306c3fb27SDimitry Andric                             uint8_t HotCold) {
195406c3fb27SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
195506c3fb27SDimitry Andric   if (!isLibFuncEmittable(M, TLI, NewFunc))
195606c3fb27SDimitry Andric     return nullptr;
195706c3fb27SDimitry Andric 
195806c3fb27SDimitry Andric   StringRef Name = TLI->getName(NewFunc);
19595f757f3fSDimitry Andric   FunctionCallee Func = M->getOrInsertFunction(Name, B.getPtrTy(),
196006c3fb27SDimitry Andric                                                Num->getType(), B.getInt8Ty());
196106c3fb27SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, Name, *TLI);
196206c3fb27SDimitry Andric   CallInst *CI = B.CreateCall(Func, {Num, B.getInt8(HotCold)}, Name);
196306c3fb27SDimitry Andric 
196406c3fb27SDimitry Andric   if (const Function *F =
196506c3fb27SDimitry Andric           dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))
196606c3fb27SDimitry Andric     CI->setCallingConv(F->getCallingConv());
196706c3fb27SDimitry Andric 
196806c3fb27SDimitry Andric   return CI;
196906c3fb27SDimitry Andric }
197006c3fb27SDimitry Andric 
197106c3fb27SDimitry Andric Value *llvm::emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B,
197206c3fb27SDimitry Andric                                    const TargetLibraryInfo *TLI,
197306c3fb27SDimitry Andric                                    LibFunc NewFunc, uint8_t HotCold) {
197406c3fb27SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
197506c3fb27SDimitry Andric   if (!isLibFuncEmittable(M, TLI, NewFunc))
197606c3fb27SDimitry Andric     return nullptr;
197706c3fb27SDimitry Andric 
197806c3fb27SDimitry Andric   StringRef Name = TLI->getName(NewFunc);
197906c3fb27SDimitry Andric   FunctionCallee Func =
19805f757f3fSDimitry Andric       M->getOrInsertFunction(Name, B.getPtrTy(), Num->getType(),
198106c3fb27SDimitry Andric                              NoThrow->getType(), B.getInt8Ty());
198206c3fb27SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, Name, *TLI);
198306c3fb27SDimitry Andric   CallInst *CI = B.CreateCall(Func, {Num, NoThrow, B.getInt8(HotCold)}, Name);
198406c3fb27SDimitry Andric 
198506c3fb27SDimitry Andric   if (const Function *F =
198606c3fb27SDimitry Andric           dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))
198706c3fb27SDimitry Andric     CI->setCallingConv(F->getCallingConv());
198806c3fb27SDimitry Andric 
198906c3fb27SDimitry Andric   return CI;
199006c3fb27SDimitry Andric }
199106c3fb27SDimitry Andric 
199206c3fb27SDimitry Andric Value *llvm::emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B,
199306c3fb27SDimitry Andric                                    const TargetLibraryInfo *TLI,
199406c3fb27SDimitry Andric                                    LibFunc NewFunc, uint8_t HotCold) {
199506c3fb27SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
199606c3fb27SDimitry Andric   if (!isLibFuncEmittable(M, TLI, NewFunc))
199706c3fb27SDimitry Andric     return nullptr;
199806c3fb27SDimitry Andric 
199906c3fb27SDimitry Andric   StringRef Name = TLI->getName(NewFunc);
200006c3fb27SDimitry Andric   FunctionCallee Func = M->getOrInsertFunction(
20015f757f3fSDimitry Andric       Name, B.getPtrTy(), Num->getType(), Align->getType(), B.getInt8Ty());
200206c3fb27SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, Name, *TLI);
200306c3fb27SDimitry Andric   CallInst *CI = B.CreateCall(Func, {Num, Align, B.getInt8(HotCold)}, Name);
200406c3fb27SDimitry Andric 
200506c3fb27SDimitry Andric   if (const Function *F =
200606c3fb27SDimitry Andric           dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))
200706c3fb27SDimitry Andric     CI->setCallingConv(F->getCallingConv());
200806c3fb27SDimitry Andric 
200906c3fb27SDimitry Andric   return CI;
201006c3fb27SDimitry Andric }
201106c3fb27SDimitry Andric 
201206c3fb27SDimitry Andric Value *llvm::emitHotColdNewAlignedNoThrow(Value *Num, Value *Align,
201306c3fb27SDimitry Andric                                           Value *NoThrow, IRBuilderBase &B,
201406c3fb27SDimitry Andric                                           const TargetLibraryInfo *TLI,
201506c3fb27SDimitry Andric                                           LibFunc NewFunc, uint8_t HotCold) {
201606c3fb27SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
201706c3fb27SDimitry Andric   if (!isLibFuncEmittable(M, TLI, NewFunc))
201806c3fb27SDimitry Andric     return nullptr;
201906c3fb27SDimitry Andric 
202006c3fb27SDimitry Andric   StringRef Name = TLI->getName(NewFunc);
202106c3fb27SDimitry Andric   FunctionCallee Func = M->getOrInsertFunction(
20225f757f3fSDimitry Andric       Name, B.getPtrTy(), Num->getType(), Align->getType(),
202306c3fb27SDimitry Andric       NoThrow->getType(), B.getInt8Ty());
202406c3fb27SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, Name, *TLI);
202506c3fb27SDimitry Andric   CallInst *CI =
202606c3fb27SDimitry Andric       B.CreateCall(Func, {Num, Align, NoThrow, B.getInt8(HotCold)}, Name);
202706c3fb27SDimitry Andric 
202806c3fb27SDimitry Andric   if (const Function *F =
202906c3fb27SDimitry Andric           dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))
203006c3fb27SDimitry Andric     CI->setCallingConv(F->getCallingConv());
203106c3fb27SDimitry Andric 
203206c3fb27SDimitry Andric   return CI;
203306c3fb27SDimitry Andric }
2034