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 
setDoesNotAccessMemory(Function & F)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 
setOnlyAccessesInaccessibleMemory(Function & F)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 
setOnlyReadsMemory(Function & F)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 
setOnlyWritesMemory(Function & F)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 
setOnlyAccessesArgMemory(Function & F)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 
setOnlyAccessesInaccessibleMemOrArgMem(Function & F)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 
setDoesNotThrow(Function & F)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 
setRetDoesNotAlias(Function & F)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 
setDoesNotCapture(Function & F,unsigned ArgNo)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 
setDoesNotAlias(Function & F,unsigned ArgNo)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 
setOnlyReadsMemory(Function & F,unsigned ArgNo)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 
setOnlyWritesMemory(Function & F,unsigned ArgNo)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 
setRetNoUndef(Function & F)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 
setArgsNoUndef(Function & F)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 
setArgNoUndef(Function & F,unsigned ArgNo)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 
setRetAndArgsNoUndef(Function & F)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 
setReturnedArg(Function & F,unsigned ArgNo)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 
setNonLazyBind(Function & F)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 
setDoesNotFreeMemory(Function & F)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 
setWillReturn(Function & F)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 
setAlignedAllocParam(Function & F,unsigned ArgNo)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 
setAllocatedPointerParam(Function & F,unsigned ArgNo)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 
setAllocSize(Function & F,unsigned ElemSizeArg,std::optional<unsigned> NumElemsArg)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 
setAllocFamily(Function & F,StringRef Family)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 
setAllocKind(Function & F,AllocFnKind K)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 
inferNonMandatoryLibFuncAttrs(Module * M,StringRef Name,const TargetLibraryInfo & TLI)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 
inferNonMandatoryLibFuncAttrs(Function & F,const TargetLibraryInfo & TLI)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;
1101e8d8bef9SDimitry Andric   case LibFunc_abs:
1102e8d8bef9SDimitry Andric   case LibFunc_acos:
1103e8d8bef9SDimitry Andric   case LibFunc_acosf:
1104e8d8bef9SDimitry Andric   case LibFunc_acosh:
1105e8d8bef9SDimitry Andric   case LibFunc_acoshf:
1106e8d8bef9SDimitry Andric   case LibFunc_acoshl:
1107e8d8bef9SDimitry Andric   case LibFunc_acosl:
1108e8d8bef9SDimitry Andric   case LibFunc_asin:
1109e8d8bef9SDimitry Andric   case LibFunc_asinf:
1110e8d8bef9SDimitry Andric   case LibFunc_asinh:
1111e8d8bef9SDimitry Andric   case LibFunc_asinhf:
1112e8d8bef9SDimitry Andric   case LibFunc_asinhl:
1113e8d8bef9SDimitry Andric   case LibFunc_asinl:
1114e8d8bef9SDimitry Andric   case LibFunc_atan:
1115e8d8bef9SDimitry Andric   case LibFunc_atan2:
1116e8d8bef9SDimitry Andric   case LibFunc_atan2f:
1117e8d8bef9SDimitry Andric   case LibFunc_atan2l:
1118e8d8bef9SDimitry Andric   case LibFunc_atanf:
1119e8d8bef9SDimitry Andric   case LibFunc_atanh:
1120e8d8bef9SDimitry Andric   case LibFunc_atanhf:
1121e8d8bef9SDimitry Andric   case LibFunc_atanhl:
1122e8d8bef9SDimitry Andric   case LibFunc_atanl:
1123e8d8bef9SDimitry Andric   case LibFunc_cbrt:
1124e8d8bef9SDimitry Andric   case LibFunc_cbrtf:
1125e8d8bef9SDimitry Andric   case LibFunc_cbrtl:
1126e8d8bef9SDimitry Andric   case LibFunc_ceil:
1127e8d8bef9SDimitry Andric   case LibFunc_ceilf:
1128e8d8bef9SDimitry Andric   case LibFunc_ceill:
1129e8d8bef9SDimitry Andric   case LibFunc_copysign:
1130e8d8bef9SDimitry Andric   case LibFunc_copysignf:
1131e8d8bef9SDimitry Andric   case LibFunc_copysignl:
1132e8d8bef9SDimitry Andric   case LibFunc_cos:
1133e8d8bef9SDimitry Andric   case LibFunc_cosh:
1134e8d8bef9SDimitry Andric   case LibFunc_coshf:
1135e8d8bef9SDimitry Andric   case LibFunc_coshl:
1136e8d8bef9SDimitry Andric   case LibFunc_cosf:
1137e8d8bef9SDimitry Andric   case LibFunc_cosl:
1138e8d8bef9SDimitry Andric   case LibFunc_cospi:
1139e8d8bef9SDimitry Andric   case LibFunc_cospif:
1140e8d8bef9SDimitry Andric   case LibFunc_exp:
1141e8d8bef9SDimitry Andric   case LibFunc_expf:
1142e8d8bef9SDimitry Andric   case LibFunc_expl:
1143e8d8bef9SDimitry Andric   case LibFunc_exp2:
1144e8d8bef9SDimitry Andric   case LibFunc_exp2f:
1145e8d8bef9SDimitry Andric   case LibFunc_exp2l:
1146e8d8bef9SDimitry Andric   case LibFunc_expm1:
1147e8d8bef9SDimitry Andric   case LibFunc_expm1f:
1148e8d8bef9SDimitry Andric   case LibFunc_expm1l:
1149e8d8bef9SDimitry Andric   case LibFunc_fabs:
1150e8d8bef9SDimitry Andric   case LibFunc_fabsf:
1151e8d8bef9SDimitry Andric   case LibFunc_fabsl:
1152e8d8bef9SDimitry Andric   case LibFunc_ffs:
1153e8d8bef9SDimitry Andric   case LibFunc_ffsl:
1154e8d8bef9SDimitry Andric   case LibFunc_ffsll:
1155e8d8bef9SDimitry Andric   case LibFunc_floor:
1156e8d8bef9SDimitry Andric   case LibFunc_floorf:
1157e8d8bef9SDimitry Andric   case LibFunc_floorl:
1158e8d8bef9SDimitry Andric   case LibFunc_fls:
1159e8d8bef9SDimitry Andric   case LibFunc_flsl:
1160e8d8bef9SDimitry Andric   case LibFunc_flsll:
1161e8d8bef9SDimitry Andric   case LibFunc_fmax:
1162e8d8bef9SDimitry Andric   case LibFunc_fmaxf:
1163e8d8bef9SDimitry Andric   case LibFunc_fmaxl:
1164e8d8bef9SDimitry Andric   case LibFunc_fmin:
1165e8d8bef9SDimitry Andric   case LibFunc_fminf:
1166e8d8bef9SDimitry Andric   case LibFunc_fminl:
1167e8d8bef9SDimitry Andric   case LibFunc_fmod:
1168e8d8bef9SDimitry Andric   case LibFunc_fmodf:
1169e8d8bef9SDimitry Andric   case LibFunc_fmodl:
1170e8d8bef9SDimitry Andric   case LibFunc_isascii:
1171e8d8bef9SDimitry Andric   case LibFunc_isdigit:
1172e8d8bef9SDimitry Andric   case LibFunc_labs:
1173e8d8bef9SDimitry Andric   case LibFunc_llabs:
1174e8d8bef9SDimitry Andric   case LibFunc_log:
1175e8d8bef9SDimitry Andric   case LibFunc_log10:
1176e8d8bef9SDimitry Andric   case LibFunc_log10f:
1177e8d8bef9SDimitry Andric   case LibFunc_log10l:
1178e8d8bef9SDimitry Andric   case LibFunc_log1p:
1179e8d8bef9SDimitry Andric   case LibFunc_log1pf:
1180e8d8bef9SDimitry Andric   case LibFunc_log1pl:
1181e8d8bef9SDimitry Andric   case LibFunc_log2:
1182e8d8bef9SDimitry Andric   case LibFunc_log2f:
1183e8d8bef9SDimitry Andric   case LibFunc_log2l:
1184e8d8bef9SDimitry Andric   case LibFunc_logb:
1185e8d8bef9SDimitry Andric   case LibFunc_logbf:
1186e8d8bef9SDimitry Andric   case LibFunc_logbl:
1187e8d8bef9SDimitry Andric   case LibFunc_logf:
1188e8d8bef9SDimitry Andric   case LibFunc_logl:
1189e8d8bef9SDimitry Andric   case LibFunc_nearbyint:
1190e8d8bef9SDimitry Andric   case LibFunc_nearbyintf:
1191e8d8bef9SDimitry Andric   case LibFunc_nearbyintl:
1192e8d8bef9SDimitry Andric   case LibFunc_pow:
1193e8d8bef9SDimitry Andric   case LibFunc_powf:
1194e8d8bef9SDimitry Andric   case LibFunc_powl:
1195e8d8bef9SDimitry Andric   case LibFunc_rint:
1196e8d8bef9SDimitry Andric   case LibFunc_rintf:
1197e8d8bef9SDimitry Andric   case LibFunc_rintl:
1198e8d8bef9SDimitry Andric   case LibFunc_round:
1199e8d8bef9SDimitry Andric   case LibFunc_roundf:
1200e8d8bef9SDimitry Andric   case LibFunc_roundl:
1201e8d8bef9SDimitry Andric   case LibFunc_sin:
1202e8d8bef9SDimitry Andric   case LibFunc_sincospif_stret:
1203e8d8bef9SDimitry Andric   case LibFunc_sinf:
1204e8d8bef9SDimitry Andric   case LibFunc_sinh:
1205e8d8bef9SDimitry Andric   case LibFunc_sinhf:
1206e8d8bef9SDimitry Andric   case LibFunc_sinhl:
1207e8d8bef9SDimitry Andric   case LibFunc_sinl:
1208e8d8bef9SDimitry Andric   case LibFunc_sinpi:
1209e8d8bef9SDimitry Andric   case LibFunc_sinpif:
1210e8d8bef9SDimitry Andric   case LibFunc_sqrt:
1211e8d8bef9SDimitry Andric   case LibFunc_sqrtf:
1212e8d8bef9SDimitry Andric   case LibFunc_sqrtl:
1213e8d8bef9SDimitry Andric   case LibFunc_tan:
1214e8d8bef9SDimitry Andric   case LibFunc_tanf:
1215e8d8bef9SDimitry Andric   case LibFunc_tanh:
1216e8d8bef9SDimitry Andric   case LibFunc_tanhf:
1217e8d8bef9SDimitry Andric   case LibFunc_tanhl:
1218e8d8bef9SDimitry Andric   case LibFunc_tanl:
1219e8d8bef9SDimitry Andric   case LibFunc_toascii:
1220e8d8bef9SDimitry Andric   case LibFunc_trunc:
1221e8d8bef9SDimitry Andric   case LibFunc_truncf:
1222e8d8bef9SDimitry Andric   case LibFunc_truncl:
1223e8d8bef9SDimitry Andric     Changed |= setDoesNotThrow(F);
1224e8d8bef9SDimitry Andric     Changed |= setDoesNotFreeMemory(F);
122504eeddc0SDimitry Andric     Changed |= setOnlyWritesMemory(F);
1226e8d8bef9SDimitry Andric     Changed |= setWillReturn(F);
1227fcaf7f86SDimitry Andric     break;
12280b57cec5SDimitry Andric   default:
12290b57cec5SDimitry Andric     // FIXME: It'd be really nice to cover all the library functions we're
12300b57cec5SDimitry Andric     // aware of here.
1231fcaf7f86SDimitry Andric     break;
12320b57cec5SDimitry Andric   }
1233fcaf7f86SDimitry Andric   // We have to do this step after AllocKind has been inferred on functions so
1234fcaf7f86SDimitry Andric   // we can reliably identify free-like and realloc-like functions.
1235bdd1243dSDimitry Andric   if (!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F))
1236fcaf7f86SDimitry Andric     Changed |= setDoesNotFreeMemory(F);
1237fcaf7f86SDimitry Andric   return Changed;
12380b57cec5SDimitry Andric }
12390b57cec5SDimitry Andric 
setArgExtAttr(Function & F,unsigned ArgNo,const TargetLibraryInfo & TLI,bool Signed=true)124081ad6265SDimitry Andric static void setArgExtAttr(Function &F, unsigned ArgNo,
124181ad6265SDimitry Andric                           const TargetLibraryInfo &TLI, bool Signed = true) {
124281ad6265SDimitry Andric   Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Param(Signed);
124381ad6265SDimitry Andric   if (ExtAttr != Attribute::None && !F.hasParamAttribute(ArgNo, ExtAttr))
124481ad6265SDimitry Andric     F.addParamAttr(ArgNo, ExtAttr);
124581ad6265SDimitry Andric }
124681ad6265SDimitry Andric 
setRetExtAttr(Function & F,const TargetLibraryInfo & TLI,bool Signed=true)1247bdd1243dSDimitry Andric static void setRetExtAttr(Function &F,
1248bdd1243dSDimitry Andric                           const TargetLibraryInfo &TLI, bool Signed = true) {
1249bdd1243dSDimitry Andric   Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Return(Signed);
1250bdd1243dSDimitry Andric   if (ExtAttr != Attribute::None && !F.hasRetAttribute(ExtAttr))
1251bdd1243dSDimitry Andric     F.addRetAttr(ExtAttr);
1252bdd1243dSDimitry Andric }
1253bdd1243dSDimitry Andric 
125481ad6265SDimitry Andric // Modeled after X86TargetLowering::markLibCallAttributes.
markRegisterParameterAttributes(Function * F)125581ad6265SDimitry Andric static void markRegisterParameterAttributes(Function *F) {
125681ad6265SDimitry Andric   if (!F->arg_size() || F->isVarArg())
125781ad6265SDimitry Andric     return;
125881ad6265SDimitry Andric 
125981ad6265SDimitry Andric   const CallingConv::ID CC = F->getCallingConv();
126081ad6265SDimitry Andric   if (CC != CallingConv::C && CC != CallingConv::X86_StdCall)
126181ad6265SDimitry Andric     return;
126281ad6265SDimitry Andric 
126381ad6265SDimitry Andric   const Module *M = F->getParent();
126481ad6265SDimitry Andric   unsigned N = M->getNumberRegisterParameters();
126581ad6265SDimitry Andric   if (!N)
126681ad6265SDimitry Andric     return;
126781ad6265SDimitry Andric 
126881ad6265SDimitry Andric   const DataLayout &DL = M->getDataLayout();
126981ad6265SDimitry Andric 
127081ad6265SDimitry Andric   for (Argument &A : F->args()) {
127181ad6265SDimitry Andric     Type *T = A.getType();
127281ad6265SDimitry Andric     if (!T->isIntOrPtrTy())
127381ad6265SDimitry Andric       continue;
127481ad6265SDimitry Andric 
127581ad6265SDimitry Andric     const TypeSize &TS = DL.getTypeAllocSize(T);
127681ad6265SDimitry Andric     if (TS > 8)
127781ad6265SDimitry Andric       continue;
127881ad6265SDimitry Andric 
127981ad6265SDimitry Andric     assert(TS <= 4 && "Need to account for parameters larger than word size");
128081ad6265SDimitry Andric     const unsigned NumRegs = TS > 4 ? 2 : 1;
128181ad6265SDimitry Andric     if (N < NumRegs)
128281ad6265SDimitry Andric       return;
128381ad6265SDimitry Andric 
128481ad6265SDimitry Andric     N -= NumRegs;
128581ad6265SDimitry Andric     F->addParamAttr(A.getArgNo(), Attribute::InReg);
128681ad6265SDimitry Andric   }
128781ad6265SDimitry Andric }
128881ad6265SDimitry Andric 
getOrInsertLibFunc(Module * M,const TargetLibraryInfo & TLI,LibFunc TheLibFunc,FunctionType * T,AttributeList AttributeList)128981ad6265SDimitry Andric FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,
129081ad6265SDimitry Andric                                         LibFunc TheLibFunc, FunctionType *T,
129181ad6265SDimitry Andric                                         AttributeList AttributeList) {
129281ad6265SDimitry Andric   assert(TLI.has(TheLibFunc) &&
129381ad6265SDimitry Andric          "Creating call to non-existing library function.");
129481ad6265SDimitry Andric   StringRef Name = TLI.getName(TheLibFunc);
129581ad6265SDimitry Andric   FunctionCallee C = M->getOrInsertFunction(Name, T, AttributeList);
129681ad6265SDimitry Andric 
129781ad6265SDimitry Andric   // Make sure any mandatory argument attributes are added.
129881ad6265SDimitry Andric 
129981ad6265SDimitry Andric   // Any outgoing i32 argument should be handled with setArgExtAttr() which
130081ad6265SDimitry Andric   // will add an extension attribute if the target ABI requires it. Adding
130181ad6265SDimitry Andric   // argument extensions is typically done by the front end but when an
130281ad6265SDimitry Andric   // optimizer is building a library call on its own it has to take care of
130381ad6265SDimitry Andric   // this. Each such generated function must be handled here with sign or
130481ad6265SDimitry Andric   // zero extensions as needed.  F is retreived with cast<> because we demand
130581ad6265SDimitry Andric   // of the caller to have called isLibFuncEmittable() first.
130681ad6265SDimitry Andric   Function *F = cast<Function>(C.getCallee());
130781ad6265SDimitry Andric   assert(F->getFunctionType() == T && "Function type does not match.");
130881ad6265SDimitry Andric   switch (TheLibFunc) {
130981ad6265SDimitry Andric   case LibFunc_fputc:
131081ad6265SDimitry Andric   case LibFunc_putchar:
131181ad6265SDimitry Andric     setArgExtAttr(*F, 0, TLI);
131281ad6265SDimitry Andric     break;
131381ad6265SDimitry Andric   case LibFunc_ldexp:
131481ad6265SDimitry Andric   case LibFunc_ldexpf:
131581ad6265SDimitry Andric   case LibFunc_ldexpl:
131681ad6265SDimitry Andric   case LibFunc_memchr:
131781ad6265SDimitry Andric   case LibFunc_memrchr:
131881ad6265SDimitry Andric   case LibFunc_strchr:
131981ad6265SDimitry Andric     setArgExtAttr(*F, 1, TLI);
132081ad6265SDimitry Andric     break;
132181ad6265SDimitry Andric   case LibFunc_memccpy:
132281ad6265SDimitry Andric     setArgExtAttr(*F, 2, TLI);
132381ad6265SDimitry Andric     break;
132481ad6265SDimitry Andric 
132581ad6265SDimitry Andric     // These are functions that are known to not need any argument extension
132681ad6265SDimitry Andric     // on any target: A size_t argument (which may be an i32 on some targets)
132781ad6265SDimitry Andric     // should not trigger the assert below.
132881ad6265SDimitry Andric   case LibFunc_bcmp:
1329bdd1243dSDimitry Andric     setRetExtAttr(*F, TLI);
1330bdd1243dSDimitry Andric     break;
133181ad6265SDimitry Andric   case LibFunc_calloc:
133281ad6265SDimitry Andric   case LibFunc_fwrite:
133381ad6265SDimitry Andric   case LibFunc_malloc:
133481ad6265SDimitry Andric   case LibFunc_memcmp:
133581ad6265SDimitry Andric   case LibFunc_memcpy_chk:
133681ad6265SDimitry Andric   case LibFunc_mempcpy:
133781ad6265SDimitry Andric   case LibFunc_memset_pattern16:
133881ad6265SDimitry Andric   case LibFunc_snprintf:
133981ad6265SDimitry Andric   case LibFunc_stpncpy:
134081ad6265SDimitry Andric   case LibFunc_strlcat:
134181ad6265SDimitry Andric   case LibFunc_strlcpy:
134281ad6265SDimitry Andric   case LibFunc_strncat:
134381ad6265SDimitry Andric   case LibFunc_strncmp:
134481ad6265SDimitry Andric   case LibFunc_strncpy:
134581ad6265SDimitry Andric   case LibFunc_vsnprintf:
134681ad6265SDimitry Andric     break;
134781ad6265SDimitry Andric 
134881ad6265SDimitry Andric   default:
134981ad6265SDimitry Andric #ifndef NDEBUG
135081ad6265SDimitry Andric     for (unsigned i = 0; i < T->getNumParams(); i++)
135181ad6265SDimitry Andric       assert(!isa<IntegerType>(T->getParamType(i)) &&
135281ad6265SDimitry Andric              "Unhandled integer argument.");
135381ad6265SDimitry Andric #endif
135481ad6265SDimitry Andric     break;
135581ad6265SDimitry Andric   }
135681ad6265SDimitry Andric 
135781ad6265SDimitry Andric   markRegisterParameterAttributes(F);
135881ad6265SDimitry Andric 
135981ad6265SDimitry Andric   return C;
136081ad6265SDimitry Andric }
136181ad6265SDimitry Andric 
getOrInsertLibFunc(Module * M,const TargetLibraryInfo & TLI,LibFunc TheLibFunc,FunctionType * T)136281ad6265SDimitry Andric FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,
136381ad6265SDimitry Andric                                         LibFunc TheLibFunc, FunctionType *T) {
136481ad6265SDimitry Andric   return getOrInsertLibFunc(M, TLI, TheLibFunc, T, AttributeList());
136581ad6265SDimitry Andric }
136681ad6265SDimitry Andric 
isLibFuncEmittable(const Module * M,const TargetLibraryInfo * TLI,LibFunc TheLibFunc)136781ad6265SDimitry Andric bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,
136881ad6265SDimitry Andric                               LibFunc TheLibFunc) {
136981ad6265SDimitry Andric   StringRef FuncName = TLI->getName(TheLibFunc);
137081ad6265SDimitry Andric   if (!TLI->has(TheLibFunc))
137181ad6265SDimitry Andric     return false;
137281ad6265SDimitry Andric 
137381ad6265SDimitry Andric   // Check if the Module already has a GlobalValue with the same name, in
137481ad6265SDimitry Andric   // which case it must be a Function with the expected type.
137581ad6265SDimitry Andric   if (GlobalValue *GV = M->getNamedValue(FuncName)) {
137681ad6265SDimitry Andric     if (auto *F = dyn_cast<Function>(GV))
137781ad6265SDimitry Andric       return TLI->isValidProtoForLibFunc(*F->getFunctionType(), TheLibFunc, *M);
137881ad6265SDimitry Andric     return false;
137981ad6265SDimitry Andric   }
138081ad6265SDimitry Andric 
138181ad6265SDimitry Andric   return true;
138281ad6265SDimitry Andric }
138381ad6265SDimitry Andric 
isLibFuncEmittable(const Module * M,const TargetLibraryInfo * TLI,StringRef Name)138481ad6265SDimitry Andric bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,
138581ad6265SDimitry Andric                               StringRef Name) {
138681ad6265SDimitry Andric   LibFunc TheLibFunc;
138781ad6265SDimitry Andric   return TLI->getLibFunc(Name, TheLibFunc) &&
138881ad6265SDimitry Andric          isLibFuncEmittable(M, TLI, TheLibFunc);
138981ad6265SDimitry Andric }
139081ad6265SDimitry Andric 
hasFloatFn(const Module * M,const TargetLibraryInfo * TLI,Type * Ty,LibFunc DoubleFn,LibFunc FloatFn,LibFunc LongDoubleFn)139181ad6265SDimitry Andric bool llvm::hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty,
13928bcb0991SDimitry Andric                       LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) {
13930b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
13940b57cec5SDimitry Andric   case Type::HalfTyID:
13950b57cec5SDimitry Andric     return false;
13960b57cec5SDimitry Andric   case Type::FloatTyID:
139781ad6265SDimitry Andric     return isLibFuncEmittable(M, TLI, FloatFn);
13980b57cec5SDimitry Andric   case Type::DoubleTyID:
139981ad6265SDimitry Andric     return isLibFuncEmittable(M, TLI, DoubleFn);
14000b57cec5SDimitry Andric   default:
140181ad6265SDimitry Andric     return isLibFuncEmittable(M, TLI, LongDoubleFn);
14020b57cec5SDimitry Andric   }
14030b57cec5SDimitry Andric }
14040b57cec5SDimitry Andric 
getFloatFn(const Module * M,const TargetLibraryInfo * TLI,Type * Ty,LibFunc DoubleFn,LibFunc FloatFn,LibFunc LongDoubleFn,LibFunc & TheLibFunc)140581ad6265SDimitry Andric StringRef llvm::getFloatFn(const Module *M, const TargetLibraryInfo *TLI,
140681ad6265SDimitry Andric                            Type *Ty, LibFunc DoubleFn, LibFunc FloatFn,
140781ad6265SDimitry Andric                            LibFunc LongDoubleFn, LibFunc &TheLibFunc) {
140881ad6265SDimitry Andric   assert(hasFloatFn(M, TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
14090b57cec5SDimitry Andric          "Cannot get name for unavailable function!");
14100b57cec5SDimitry Andric 
14110b57cec5SDimitry Andric   switch (Ty->getTypeID()) {
14120b57cec5SDimitry Andric   case Type::HalfTyID:
14130b57cec5SDimitry Andric     llvm_unreachable("No name for HalfTy!");
14140b57cec5SDimitry Andric   case Type::FloatTyID:
141581ad6265SDimitry Andric     TheLibFunc = FloatFn;
14160b57cec5SDimitry Andric     return TLI->getName(FloatFn);
14170b57cec5SDimitry Andric   case Type::DoubleTyID:
141881ad6265SDimitry Andric     TheLibFunc = DoubleFn;
14190b57cec5SDimitry Andric     return TLI->getName(DoubleFn);
14200b57cec5SDimitry Andric   default:
142181ad6265SDimitry Andric     TheLibFunc = LongDoubleFn;
14220b57cec5SDimitry Andric     return TLI->getName(LongDoubleFn);
14230b57cec5SDimitry Andric   }
14240b57cec5SDimitry Andric }
14250b57cec5SDimitry Andric 
14260b57cec5SDimitry Andric //- Emit LibCalls ------------------------------------------------------------//
14270b57cec5SDimitry Andric 
getIntTy(IRBuilderBase & B,const TargetLibraryInfo * TLI)1428bdd1243dSDimitry Andric static IntegerType *getIntTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) {
1429bdd1243dSDimitry Andric   return B.getIntNTy(TLI->getIntSize());
1430bdd1243dSDimitry Andric }
1431bdd1243dSDimitry Andric 
getSizeTTy(IRBuilderBase & B,const TargetLibraryInfo * TLI)1432bdd1243dSDimitry Andric static IntegerType *getSizeTTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) {
1433bdd1243dSDimitry Andric   const Module *M = B.GetInsertBlock()->getModule();
1434bdd1243dSDimitry Andric   return B.getIntNTy(TLI->getSizeTSize(*M));
1435bdd1243dSDimitry Andric }
1436bdd1243dSDimitry Andric 
emitLibCall(LibFunc TheLibFunc,Type * ReturnType,ArrayRef<Type * > ParamTypes,ArrayRef<Value * > Operands,IRBuilderBase & B,const TargetLibraryInfo * TLI,bool IsVaArgs=false)14370b57cec5SDimitry Andric static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType,
14380b57cec5SDimitry Andric                           ArrayRef<Type *> ParamTypes,
14395ffd83dbSDimitry Andric                           ArrayRef<Value *> Operands, IRBuilderBase &B,
14400b57cec5SDimitry Andric                           const TargetLibraryInfo *TLI,
14410b57cec5SDimitry Andric                           bool IsVaArgs = false) {
144281ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
144381ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, TheLibFunc))
14440b57cec5SDimitry Andric     return nullptr;
14450b57cec5SDimitry Andric 
14460b57cec5SDimitry Andric   StringRef FuncName = TLI->getName(TheLibFunc);
14470b57cec5SDimitry Andric   FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs);
144881ad6265SDimitry Andric   FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, FuncType);
144981ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, FuncName, *TLI);
14500b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(Callee, Operands, FuncName);
14510b57cec5SDimitry Andric   if (const Function *F =
14520b57cec5SDimitry Andric           dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
14530b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
14540b57cec5SDimitry Andric   return CI;
14550b57cec5SDimitry Andric }
14560b57cec5SDimitry Andric 
emitStrLen(Value * Ptr,IRBuilderBase & B,const DataLayout & DL,const TargetLibraryInfo * TLI)14575ffd83dbSDimitry Andric Value *llvm::emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,
14580b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
14595f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1460bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
14615f757f3fSDimitry Andric   return emitLibCall(LibFunc_strlen, SizeTTy, CharPtrTy, Ptr, B, TLI);
14620b57cec5SDimitry Andric }
14630b57cec5SDimitry Andric 
emitStrDup(Value * Ptr,IRBuilderBase & B,const TargetLibraryInfo * TLI)14645ffd83dbSDimitry Andric Value *llvm::emitStrDup(Value *Ptr, IRBuilderBase &B,
14658bcb0991SDimitry Andric                         const TargetLibraryInfo *TLI) {
14665f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
14675f757f3fSDimitry Andric   return emitLibCall(LibFunc_strdup, CharPtrTy, CharPtrTy, Ptr, B, TLI);
14688bcb0991SDimitry Andric }
14698bcb0991SDimitry Andric 
emitStrChr(Value * Ptr,char C,IRBuilderBase & B,const TargetLibraryInfo * TLI)14705ffd83dbSDimitry Andric Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilderBase &B,
14710b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
14725f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1473bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
14745f757f3fSDimitry Andric   return emitLibCall(LibFunc_strchr, CharPtrTy, {CharPtrTy, IntTy},
14755f757f3fSDimitry Andric                      {Ptr, ConstantInt::get(IntTy, C)}, B, TLI);
14760b57cec5SDimitry Andric }
14770b57cec5SDimitry Andric 
emitStrNCmp(Value * Ptr1,Value * Ptr2,Value * Len,IRBuilderBase & B,const DataLayout & DL,const TargetLibraryInfo * TLI)14785ffd83dbSDimitry Andric Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
14790b57cec5SDimitry Andric                          const DataLayout &DL, const TargetLibraryInfo *TLI) {
14805f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1481bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1482bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
14830b57cec5SDimitry Andric   return emitLibCall(
1484bdd1243dSDimitry Andric       LibFunc_strncmp, IntTy,
14855f757f3fSDimitry Andric       {CharPtrTy, CharPtrTy, SizeTTy},
14865f757f3fSDimitry Andric       {Ptr1, Ptr2, Len}, B, TLI);
14870b57cec5SDimitry Andric }
14880b57cec5SDimitry Andric 
emitStrCpy(Value * Dst,Value * Src,IRBuilderBase & B,const TargetLibraryInfo * TLI)14895ffd83dbSDimitry Andric Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B,
14900b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
14915f757f3fSDimitry Andric   Type *CharPtrTy = Dst->getType();
14925f757f3fSDimitry Andric   return emitLibCall(LibFunc_strcpy, CharPtrTy, {CharPtrTy, CharPtrTy},
14935f757f3fSDimitry Andric                      {Dst, Src}, B, TLI);
14940b57cec5SDimitry Andric }
14950b57cec5SDimitry Andric 
emitStpCpy(Value * Dst,Value * Src,IRBuilderBase & B,const TargetLibraryInfo * TLI)14965ffd83dbSDimitry Andric Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B,
14970b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
14985f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
14995f757f3fSDimitry Andric   return emitLibCall(LibFunc_stpcpy, CharPtrTy, {CharPtrTy, CharPtrTy},
15005f757f3fSDimitry Andric                      {Dst, Src}, B, TLI);
15010b57cec5SDimitry Andric }
15020b57cec5SDimitry Andric 
emitStrNCpy(Value * Dst,Value * Src,Value * Len,IRBuilderBase & B,const TargetLibraryInfo * TLI)15035ffd83dbSDimitry Andric Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
15040b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
15055f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1506bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15075f757f3fSDimitry Andric   return emitLibCall(LibFunc_strncpy, CharPtrTy, {CharPtrTy, CharPtrTy, SizeTTy},
15085f757f3fSDimitry Andric                      {Dst, Src, Len}, B, TLI);
15090b57cec5SDimitry Andric }
15100b57cec5SDimitry Andric 
emitStpNCpy(Value * Dst,Value * Src,Value * Len,IRBuilderBase & B,const TargetLibraryInfo * TLI)15115ffd83dbSDimitry Andric Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
15120b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
15135f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1514bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15155f757f3fSDimitry Andric   return emitLibCall(LibFunc_stpncpy, CharPtrTy, {CharPtrTy, CharPtrTy, SizeTTy},
15165f757f3fSDimitry Andric                      {Dst, Src, Len}, B, TLI);
15170b57cec5SDimitry Andric }
15180b57cec5SDimitry Andric 
emitMemCpyChk(Value * Dst,Value * Src,Value * Len,Value * ObjSize,IRBuilderBase & B,const DataLayout & DL,const TargetLibraryInfo * TLI)15190b57cec5SDimitry Andric Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
15205ffd83dbSDimitry Andric                            IRBuilderBase &B, const DataLayout &DL,
15210b57cec5SDimitry Andric                            const TargetLibraryInfo *TLI) {
152281ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
152381ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_memcpy_chk))
15240b57cec5SDimitry Andric     return nullptr;
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric   AttributeList AS;
15270b57cec5SDimitry Andric   AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
15280b57cec5SDimitry Andric                           Attribute::NoUnwind);
15295f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1530bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
153181ad6265SDimitry Andric   FunctionCallee MemCpy = getOrInsertLibFunc(M, *TLI, LibFunc_memcpy_chk,
15325f757f3fSDimitry Andric       AttributeList::get(M->getContext(), AS), VoidPtrTy,
15335f757f3fSDimitry Andric       VoidPtrTy, VoidPtrTy, SizeTTy, SizeTTy);
15340b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
15350b57cec5SDimitry Andric   if (const Function *F =
15360b57cec5SDimitry Andric           dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts()))
15370b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
15380b57cec5SDimitry Andric   return CI;
15390b57cec5SDimitry Andric }
15400b57cec5SDimitry Andric 
emitMemPCpy(Value * Dst,Value * Src,Value * Len,IRBuilderBase & B,const DataLayout & DL,const TargetLibraryInfo * TLI)1541e8d8bef9SDimitry Andric Value *llvm::emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
1542e8d8bef9SDimitry Andric                          const DataLayout &DL, const TargetLibraryInfo *TLI) {
15435f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1544bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15455f757f3fSDimitry Andric   return emitLibCall(LibFunc_mempcpy, VoidPtrTy,
15465f757f3fSDimitry Andric                      {VoidPtrTy, VoidPtrTy, SizeTTy},
1547e8d8bef9SDimitry Andric                      {Dst, Src, Len}, B, TLI);
1548e8d8bef9SDimitry Andric }
1549e8d8bef9SDimitry Andric 
emitMemChr(Value * Ptr,Value * Val,Value * Len,IRBuilderBase & B,const DataLayout & DL,const TargetLibraryInfo * TLI)15505ffd83dbSDimitry Andric Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
15510b57cec5SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
15525f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1553bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1554bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15555f757f3fSDimitry Andric   return emitLibCall(LibFunc_memchr, VoidPtrTy,
15565f757f3fSDimitry Andric                      {VoidPtrTy, IntTy, SizeTTy},
15575f757f3fSDimitry Andric                      {Ptr, Val, Len}, B, TLI);
15580b57cec5SDimitry Andric }
15590b57cec5SDimitry Andric 
emitMemRChr(Value * Ptr,Value * Val,Value * Len,IRBuilderBase & B,const DataLayout & DL,const TargetLibraryInfo * TLI)156081ad6265SDimitry Andric Value *llvm::emitMemRChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
156181ad6265SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
15625f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1563bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1564bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15655f757f3fSDimitry Andric   return emitLibCall(LibFunc_memrchr, VoidPtrTy,
15665f757f3fSDimitry Andric                      {VoidPtrTy, IntTy, SizeTTy},
15675f757f3fSDimitry Andric                      {Ptr, Val, Len}, B, TLI);
156881ad6265SDimitry Andric }
156981ad6265SDimitry Andric 
emitMemCmp(Value * Ptr1,Value * Ptr2,Value * Len,IRBuilderBase & B,const DataLayout & DL,const TargetLibraryInfo * TLI)15705ffd83dbSDimitry Andric Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
15710b57cec5SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
15725f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1573bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1574bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
1575bdd1243dSDimitry Andric   return emitLibCall(LibFunc_memcmp, IntTy,
15765f757f3fSDimitry Andric                      {VoidPtrTy, VoidPtrTy, SizeTTy},
15775f757f3fSDimitry Andric                      {Ptr1, Ptr2, Len}, B, TLI);
15780b57cec5SDimitry Andric }
15790b57cec5SDimitry Andric 
emitBCmp(Value * Ptr1,Value * Ptr2,Value * Len,IRBuilderBase & B,const DataLayout & DL,const TargetLibraryInfo * TLI)15805ffd83dbSDimitry Andric Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
15810b57cec5SDimitry Andric                       const DataLayout &DL, const TargetLibraryInfo *TLI) {
15825f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1583bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1584bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
1585bdd1243dSDimitry Andric   return emitLibCall(LibFunc_bcmp, IntTy,
15865f757f3fSDimitry Andric                      {VoidPtrTy, VoidPtrTy, SizeTTy},
15875f757f3fSDimitry Andric                      {Ptr1, Ptr2, Len}, B, TLI);
15880b57cec5SDimitry Andric }
15890b57cec5SDimitry Andric 
emitMemCCpy(Value * Ptr1,Value * Ptr2,Value * Val,Value * Len,IRBuilderBase & B,const TargetLibraryInfo * TLI)15900b57cec5SDimitry Andric Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
15915ffd83dbSDimitry Andric                          IRBuilderBase &B, const TargetLibraryInfo *TLI) {
15925f757f3fSDimitry Andric   Type *VoidPtrTy = B.getPtrTy();
1593bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1594bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
15955f757f3fSDimitry Andric   return emitLibCall(LibFunc_memccpy, VoidPtrTy,
15965f757f3fSDimitry Andric                      {VoidPtrTy, VoidPtrTy, IntTy, SizeTTy},
15970b57cec5SDimitry Andric                      {Ptr1, Ptr2, Val, Len}, B, TLI);
15980b57cec5SDimitry Andric }
15990b57cec5SDimitry Andric 
emitSNPrintf(Value * Dest,Value * Size,Value * Fmt,ArrayRef<Value * > VariadicArgs,IRBuilderBase & B,const TargetLibraryInfo * TLI)16000b57cec5SDimitry Andric Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
16015ffd83dbSDimitry Andric                           ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,
16020b57cec5SDimitry Andric                           const TargetLibraryInfo *TLI) {
16035f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1604bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1605bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
16065f757f3fSDimitry Andric   SmallVector<Value *, 8> Args{Dest, Size, Fmt};
1607e8d8bef9SDimitry Andric   llvm::append_range(Args, VariadicArgs);
1608bdd1243dSDimitry Andric   return emitLibCall(LibFunc_snprintf, IntTy,
16095f757f3fSDimitry Andric                      {CharPtrTy, SizeTTy, CharPtrTy},
16100b57cec5SDimitry Andric                      Args, B, TLI, /*IsVaArgs=*/true);
16110b57cec5SDimitry Andric }
16120b57cec5SDimitry Andric 
emitSPrintf(Value * Dest,Value * Fmt,ArrayRef<Value * > VariadicArgs,IRBuilderBase & B,const TargetLibraryInfo * TLI)16130b57cec5SDimitry Andric Value *llvm::emitSPrintf(Value *Dest, Value *Fmt,
16145ffd83dbSDimitry Andric                          ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,
16150b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
16165f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1617bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
16185f757f3fSDimitry Andric   SmallVector<Value *, 8> Args{Dest, Fmt};
1619e8d8bef9SDimitry Andric   llvm::append_range(Args, VariadicArgs);
1620bdd1243dSDimitry Andric   return emitLibCall(LibFunc_sprintf, IntTy,
16215f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy}, Args, B, TLI,
16220b57cec5SDimitry Andric                      /*IsVaArgs=*/true);
16230b57cec5SDimitry Andric }
16240b57cec5SDimitry Andric 
emitStrCat(Value * Dest,Value * Src,IRBuilderBase & B,const TargetLibraryInfo * TLI)16255ffd83dbSDimitry Andric Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B,
16260b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
16275f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
16285f757f3fSDimitry Andric   return emitLibCall(LibFunc_strcat, CharPtrTy,
16295f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy},
16305f757f3fSDimitry Andric                      {Dest, Src}, B, TLI);
16310b57cec5SDimitry Andric }
16320b57cec5SDimitry Andric 
emitStrLCpy(Value * Dest,Value * Src,Value * Size,IRBuilderBase & B,const TargetLibraryInfo * TLI)16335ffd83dbSDimitry Andric Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
16340b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
16355f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1636bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
1637bdd1243dSDimitry Andric   return emitLibCall(LibFunc_strlcpy, SizeTTy,
16385f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy, SizeTTy},
16395f757f3fSDimitry Andric                      {Dest, Src, Size}, B, TLI);
16400b57cec5SDimitry Andric }
16410b57cec5SDimitry Andric 
emitStrLCat(Value * Dest,Value * Src,Value * Size,IRBuilderBase & B,const TargetLibraryInfo * TLI)16425ffd83dbSDimitry Andric Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
16430b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
16445f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1645bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
1646bdd1243dSDimitry Andric   return emitLibCall(LibFunc_strlcat, SizeTTy,
16475f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy, SizeTTy},
16485f757f3fSDimitry Andric                      {Dest, Src, Size}, B, TLI);
16490b57cec5SDimitry Andric }
16500b57cec5SDimitry Andric 
emitStrNCat(Value * Dest,Value * Src,Value * Size,IRBuilderBase & B,const TargetLibraryInfo * TLI)16515ffd83dbSDimitry Andric Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
16520b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
16535f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1654bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
16555f757f3fSDimitry Andric   return emitLibCall(LibFunc_strncat, CharPtrTy,
16565f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy, SizeTTy},
16575f757f3fSDimitry Andric                      {Dest, Src, Size}, B, TLI);
16580b57cec5SDimitry Andric }
16590b57cec5SDimitry Andric 
emitVSNPrintf(Value * Dest,Value * Size,Value * Fmt,Value * VAList,IRBuilderBase & B,const TargetLibraryInfo * TLI)16600b57cec5SDimitry Andric Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
16615ffd83dbSDimitry Andric                            IRBuilderBase &B, const TargetLibraryInfo *TLI) {
16625f757f3fSDimitry Andric   Type *CharPtrTy = B.getPtrTy();
1663bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
1664bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
16650b57cec5SDimitry Andric   return emitLibCall(
1666bdd1243dSDimitry Andric       LibFunc_vsnprintf, IntTy,
16675f757f3fSDimitry Andric       {CharPtrTy, SizeTTy, CharPtrTy, VAList->getType()},
16685f757f3fSDimitry Andric       {Dest, Size, Fmt, VAList}, B, TLI);
16690b57cec5SDimitry Andric }
16700b57cec5SDimitry Andric 
emitVSPrintf(Value * Dest,Value * Fmt,Value * VAList,IRBuilderBase & B,const TargetLibraryInfo * TLI)16710b57cec5SDimitry Andric Value *llvm::emitVSPrintf(Value *Dest, 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   return emitLibCall(LibFunc_vsprintf, IntTy,
16765f757f3fSDimitry Andric                      {CharPtrTy, CharPtrTy, VAList->getType()},
16775f757f3fSDimitry Andric                      {Dest, Fmt, VAList}, B, TLI);
16780b57cec5SDimitry Andric }
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric /// Append a suffix to the function name according to the type of 'Op'.
appendTypeSuffix(Value * Op,StringRef & Name,SmallString<20> & NameBuffer)16810b57cec5SDimitry Andric static void appendTypeSuffix(Value *Op, StringRef &Name,
16820b57cec5SDimitry Andric                              SmallString<20> &NameBuffer) {
16830b57cec5SDimitry Andric   if (!Op->getType()->isDoubleTy()) {
16840b57cec5SDimitry Andric       NameBuffer += Name;
16850b57cec5SDimitry Andric 
16860b57cec5SDimitry Andric     if (Op->getType()->isFloatTy())
16870b57cec5SDimitry Andric       NameBuffer += 'f';
16880b57cec5SDimitry Andric     else
16890b57cec5SDimitry Andric       NameBuffer += 'l';
16900b57cec5SDimitry Andric 
16910b57cec5SDimitry Andric     Name = NameBuffer;
16920b57cec5SDimitry Andric   }
16930b57cec5SDimitry Andric }
16940b57cec5SDimitry Andric 
emitUnaryFloatFnCallHelper(Value * Op,LibFunc TheLibFunc,StringRef Name,IRBuilderBase & B,const AttributeList & Attrs,const TargetLibraryInfo * TLI)169581ad6265SDimitry Andric static Value *emitUnaryFloatFnCallHelper(Value *Op, LibFunc TheLibFunc,
169681ad6265SDimitry Andric                                          StringRef Name, IRBuilderBase &B,
169781ad6265SDimitry Andric                                          const AttributeList &Attrs,
169881ad6265SDimitry Andric                                          const TargetLibraryInfo *TLI) {
16990b57cec5SDimitry Andric   assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
17000b57cec5SDimitry Andric 
17010b57cec5SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
170281ad6265SDimitry Andric   FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op->getType(),
170381ad6265SDimitry Andric                                              Op->getType());
17040b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(Callee, Op, Name);
17050b57cec5SDimitry Andric 
17060b57cec5SDimitry Andric   // The incoming attribute set may have come from a speculatable intrinsic, but
17070b57cec5SDimitry Andric   // is being replaced with a library call which is not allowed to be
17080b57cec5SDimitry Andric   // speculatable.
1709349cc55cSDimitry Andric   CI->setAttributes(
1710349cc55cSDimitry Andric       Attrs.removeFnAttribute(B.getContext(), Attribute::Speculatable));
17110b57cec5SDimitry Andric   if (const Function *F =
17120b57cec5SDimitry Andric           dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
17130b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
17140b57cec5SDimitry Andric 
17150b57cec5SDimitry Andric   return CI;
17160b57cec5SDimitry Andric }
17170b57cec5SDimitry Andric 
emitUnaryFloatFnCall(Value * Op,const TargetLibraryInfo * TLI,StringRef Name,IRBuilderBase & B,const AttributeList & Attrs)171881ad6265SDimitry Andric Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
171981ad6265SDimitry Andric                                   StringRef Name, IRBuilderBase &B,
17200b57cec5SDimitry Andric                                   const AttributeList &Attrs) {
17210b57cec5SDimitry Andric   SmallString<20> NameBuffer;
17220b57cec5SDimitry Andric   appendTypeSuffix(Op, Name, NameBuffer);
17230b57cec5SDimitry Andric 
172481ad6265SDimitry Andric   LibFunc TheLibFunc;
172581ad6265SDimitry Andric   TLI->getLibFunc(Name, TheLibFunc);
172681ad6265SDimitry Andric 
172781ad6265SDimitry Andric   return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI);
17280b57cec5SDimitry Andric }
17290b57cec5SDimitry Andric 
emitUnaryFloatFnCall(Value * Op,const TargetLibraryInfo * TLI,LibFunc DoubleFn,LibFunc FloatFn,LibFunc LongDoubleFn,IRBuilderBase & B,const AttributeList & Attrs)17300b57cec5SDimitry Andric Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
17310b57cec5SDimitry Andric                                   LibFunc DoubleFn, LibFunc FloatFn,
17325ffd83dbSDimitry Andric                                   LibFunc LongDoubleFn, IRBuilderBase &B,
17330b57cec5SDimitry Andric                                   const AttributeList &Attrs) {
17340b57cec5SDimitry Andric   // Get the name of the function according to TLI.
173581ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
173681ad6265SDimitry Andric   LibFunc TheLibFunc;
173781ad6265SDimitry Andric   StringRef Name = getFloatFn(M, TLI, Op->getType(), DoubleFn, FloatFn,
173881ad6265SDimitry Andric                               LongDoubleFn, TheLibFunc);
17390b57cec5SDimitry Andric 
174081ad6265SDimitry Andric   return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI);
17410b57cec5SDimitry Andric }
17420b57cec5SDimitry Andric 
emitBinaryFloatFnCallHelper(Value * Op1,Value * Op2,LibFunc TheLibFunc,StringRef Name,IRBuilderBase & B,const AttributeList & Attrs,const TargetLibraryInfo * TLI)17438bcb0991SDimitry Andric static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2,
174481ad6265SDimitry Andric                                           LibFunc TheLibFunc,
17455ffd83dbSDimitry Andric                                           StringRef Name, IRBuilderBase &B,
1746e8d8bef9SDimitry Andric                                           const AttributeList &Attrs,
174781ad6265SDimitry Andric                                           const TargetLibraryInfo *TLI) {
17488bcb0991SDimitry Andric   assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
17498bcb0991SDimitry Andric 
17508bcb0991SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
175181ad6265SDimitry Andric   FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op1->getType(),
17528bcb0991SDimitry Andric                                              Op1->getType(), Op2->getType());
175381ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, Name, *TLI);
17548bcb0991SDimitry Andric   CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name);
17558bcb0991SDimitry Andric 
17568bcb0991SDimitry Andric   // The incoming attribute set may have come from a speculatable intrinsic, but
17578bcb0991SDimitry Andric   // is being replaced with a library call which is not allowed to be
17588bcb0991SDimitry Andric   // speculatable.
1759349cc55cSDimitry Andric   CI->setAttributes(
1760349cc55cSDimitry Andric       Attrs.removeFnAttribute(B.getContext(), Attribute::Speculatable));
17618bcb0991SDimitry Andric   if (const Function *F =
17628bcb0991SDimitry Andric           dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
17638bcb0991SDimitry Andric     CI->setCallingConv(F->getCallingConv());
17648bcb0991SDimitry Andric 
17658bcb0991SDimitry Andric   return CI;
17668bcb0991SDimitry Andric }
17678bcb0991SDimitry Andric 
emitBinaryFloatFnCall(Value * Op1,Value * Op2,const TargetLibraryInfo * TLI,StringRef Name,IRBuilderBase & B,const AttributeList & Attrs)176881ad6265SDimitry Andric Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,
176981ad6265SDimitry Andric                                    const TargetLibraryInfo *TLI,
177081ad6265SDimitry Andric                                    StringRef Name, IRBuilderBase &B,
17715ffd83dbSDimitry Andric                                    const AttributeList &Attrs) {
17720b57cec5SDimitry Andric   assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
17730b57cec5SDimitry Andric 
17740b57cec5SDimitry Andric   SmallString<20> NameBuffer;
17750b57cec5SDimitry Andric   appendTypeSuffix(Op1, Name, NameBuffer);
17760b57cec5SDimitry Andric 
177781ad6265SDimitry Andric   LibFunc TheLibFunc;
177881ad6265SDimitry Andric   TLI->getLibFunc(Name, TheLibFunc);
177981ad6265SDimitry Andric 
178081ad6265SDimitry Andric   return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI);
17818bcb0991SDimitry Andric }
17820b57cec5SDimitry Andric 
emitBinaryFloatFnCall(Value * Op1,Value * Op2,const TargetLibraryInfo * TLI,LibFunc DoubleFn,LibFunc FloatFn,LibFunc LongDoubleFn,IRBuilderBase & B,const AttributeList & Attrs)17838bcb0991SDimitry Andric Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,
17848bcb0991SDimitry Andric                                    const TargetLibraryInfo *TLI,
17858bcb0991SDimitry Andric                                    LibFunc DoubleFn, LibFunc FloatFn,
17865ffd83dbSDimitry Andric                                    LibFunc LongDoubleFn, IRBuilderBase &B,
17878bcb0991SDimitry Andric                                    const AttributeList &Attrs) {
17888bcb0991SDimitry Andric   // Get the name of the function according to TLI.
178981ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
179081ad6265SDimitry Andric   LibFunc TheLibFunc;
179181ad6265SDimitry Andric   StringRef Name = getFloatFn(M, TLI, Op1->getType(), DoubleFn, FloatFn,
179281ad6265SDimitry Andric                               LongDoubleFn, TheLibFunc);
17938bcb0991SDimitry Andric 
179481ad6265SDimitry Andric   return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI);
17950b57cec5SDimitry Andric }
17960b57cec5SDimitry Andric 
1797bdd1243dSDimitry Andric // Emit a call to putchar(int) with Char as the argument.  Char must have
1798bdd1243dSDimitry Andric // the same precision as int, which need not be 32 bits.
emitPutChar(Value * Char,IRBuilderBase & B,const TargetLibraryInfo * TLI)17995ffd83dbSDimitry Andric Value *llvm::emitPutChar(Value *Char, IRBuilderBase &B,
18000b57cec5SDimitry Andric                          const TargetLibraryInfo *TLI) {
180181ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
180281ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_putchar))
18030b57cec5SDimitry Andric     return nullptr;
18040b57cec5SDimitry Andric 
1805bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
18060b57cec5SDimitry Andric   StringRef PutCharName = TLI->getName(LibFunc_putchar);
180781ad6265SDimitry Andric   FunctionCallee PutChar = getOrInsertLibFunc(M, *TLI, LibFunc_putchar,
1808bdd1243dSDimitry Andric                                               IntTy, IntTy);
180981ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, PutCharName, *TLI);
1810bdd1243dSDimitry Andric   CallInst *CI = B.CreateCall(PutChar, Char, PutCharName);
18110b57cec5SDimitry Andric 
18120b57cec5SDimitry Andric   if (const Function *F =
18130b57cec5SDimitry Andric           dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts()))
18140b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
18150b57cec5SDimitry Andric   return CI;
18160b57cec5SDimitry Andric }
18170b57cec5SDimitry Andric 
emitPutS(Value * Str,IRBuilderBase & B,const TargetLibraryInfo * TLI)18185ffd83dbSDimitry Andric Value *llvm::emitPutS(Value *Str, IRBuilderBase &B,
18190b57cec5SDimitry Andric                       const TargetLibraryInfo *TLI) {
182081ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
182181ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_puts))
18220b57cec5SDimitry Andric     return nullptr;
18230b57cec5SDimitry Andric 
1824bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
18250b57cec5SDimitry Andric   StringRef PutsName = TLI->getName(LibFunc_puts);
1826bdd1243dSDimitry Andric   FunctionCallee PutS = getOrInsertLibFunc(M, *TLI, LibFunc_puts, IntTy,
18275f757f3fSDimitry Andric                                            B.getPtrTy());
182881ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, PutsName, *TLI);
18295f757f3fSDimitry Andric   CallInst *CI = B.CreateCall(PutS, Str, PutsName);
18300b57cec5SDimitry Andric   if (const Function *F =
18310b57cec5SDimitry Andric           dyn_cast<Function>(PutS.getCallee()->stripPointerCasts()))
18320b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
18330b57cec5SDimitry Andric   return CI;
18340b57cec5SDimitry Andric }
18350b57cec5SDimitry Andric 
emitFPutC(Value * Char,Value * File,IRBuilderBase & B,const TargetLibraryInfo * TLI)18365ffd83dbSDimitry Andric Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilderBase &B,
18370b57cec5SDimitry Andric                        const TargetLibraryInfo *TLI) {
183881ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
183981ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_fputc))
18400b57cec5SDimitry Andric     return nullptr;
18410b57cec5SDimitry Andric 
1842bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
18430b57cec5SDimitry Andric   StringRef FPutcName = TLI->getName(LibFunc_fputc);
1844bdd1243dSDimitry Andric   FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputc, IntTy,
1845bdd1243dSDimitry Andric                                         IntTy, File->getType());
18460b57cec5SDimitry Andric   if (File->getType()->isPointerTy())
184781ad6265SDimitry Andric     inferNonMandatoryLibFuncAttrs(M, FPutcName, *TLI);
18480b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
18490b57cec5SDimitry Andric 
18500b57cec5SDimitry Andric   if (const Function *Fn =
18510b57cec5SDimitry Andric           dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
18520b57cec5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
18530b57cec5SDimitry Andric   return CI;
18540b57cec5SDimitry Andric }
18550b57cec5SDimitry Andric 
emitFPutS(Value * Str,Value * File,IRBuilderBase & B,const TargetLibraryInfo * TLI)18565ffd83dbSDimitry Andric Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilderBase &B,
18570b57cec5SDimitry Andric                        const TargetLibraryInfo *TLI) {
185881ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
185981ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_fputs))
18600b57cec5SDimitry Andric     return nullptr;
18610b57cec5SDimitry Andric 
1862bdd1243dSDimitry Andric   Type *IntTy = getIntTy(B, TLI);
18630b57cec5SDimitry Andric   StringRef FPutsName = TLI->getName(LibFunc_fputs);
1864bdd1243dSDimitry Andric   FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputs, IntTy,
18655f757f3fSDimitry Andric                                         B.getPtrTy(), File->getType());
18660b57cec5SDimitry Andric   if (File->getType()->isPointerTy())
186781ad6265SDimitry Andric     inferNonMandatoryLibFuncAttrs(M, FPutsName, *TLI);
18685f757f3fSDimitry Andric   CallInst *CI = B.CreateCall(F, {Str, File}, FPutsName);
18690b57cec5SDimitry Andric 
18700b57cec5SDimitry Andric   if (const Function *Fn =
18710b57cec5SDimitry Andric           dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
18720b57cec5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
18730b57cec5SDimitry Andric   return CI;
18740b57cec5SDimitry Andric }
18750b57cec5SDimitry Andric 
emitFWrite(Value * Ptr,Value * Size,Value * File,IRBuilderBase & B,const DataLayout & DL,const TargetLibraryInfo * TLI)18765ffd83dbSDimitry Andric Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B,
18770b57cec5SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
187881ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
187981ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_fwrite))
18800b57cec5SDimitry Andric     return nullptr;
18810b57cec5SDimitry Andric 
1882bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
18830b57cec5SDimitry Andric   StringRef FWriteName = TLI->getName(LibFunc_fwrite);
188481ad6265SDimitry Andric   FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fwrite,
18855f757f3fSDimitry Andric                                         SizeTTy, B.getPtrTy(), SizeTTy,
1886bdd1243dSDimitry Andric                                         SizeTTy, File->getType());
18870b57cec5SDimitry Andric 
18880b57cec5SDimitry Andric   if (File->getType()->isPointerTy())
188981ad6265SDimitry Andric     inferNonMandatoryLibFuncAttrs(M, FWriteName, *TLI);
18900b57cec5SDimitry Andric   CallInst *CI =
18915f757f3fSDimitry Andric       B.CreateCall(F, {Ptr, Size,
1892bdd1243dSDimitry Andric                        ConstantInt::get(SizeTTy, 1), File});
18930b57cec5SDimitry Andric 
18940b57cec5SDimitry Andric   if (const Function *Fn =
18950b57cec5SDimitry Andric           dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
18960b57cec5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
18970b57cec5SDimitry Andric   return CI;
18980b57cec5SDimitry Andric }
18990b57cec5SDimitry Andric 
emitMalloc(Value * Num,IRBuilderBase & B,const DataLayout & DL,const TargetLibraryInfo * TLI)19005ffd83dbSDimitry Andric Value *llvm::emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL,
19010b57cec5SDimitry Andric                         const TargetLibraryInfo *TLI) {
190281ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
190381ad6265SDimitry Andric   if (!isLibFuncEmittable(M, TLI, LibFunc_malloc))
19040b57cec5SDimitry Andric     return nullptr;
19050b57cec5SDimitry Andric 
19060b57cec5SDimitry Andric   StringRef MallocName = TLI->getName(LibFunc_malloc);
1907bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, TLI);
190881ad6265SDimitry Andric   FunctionCallee Malloc = getOrInsertLibFunc(M, *TLI, LibFunc_malloc,
19095f757f3fSDimitry Andric                                              B.getPtrTy(), SizeTTy);
191081ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, MallocName, *TLI);
19110b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
19120b57cec5SDimitry Andric 
19130b57cec5SDimitry Andric   if (const Function *F =
19140b57cec5SDimitry Andric           dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts()))
19150b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
19160b57cec5SDimitry Andric 
19170b57cec5SDimitry Andric   return CI;
19180b57cec5SDimitry Andric }
19190b57cec5SDimitry Andric 
emitCalloc(Value * Num,Value * Size,IRBuilderBase & B,const TargetLibraryInfo & TLI)1920349cc55cSDimitry Andric Value *llvm::emitCalloc(Value *Num, Value *Size, IRBuilderBase &B,
1921349cc55cSDimitry Andric                         const TargetLibraryInfo &TLI) {
192281ad6265SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
192381ad6265SDimitry Andric   if (!isLibFuncEmittable(M, &TLI, LibFunc_calloc))
19240b57cec5SDimitry Andric     return nullptr;
19250b57cec5SDimitry Andric 
19260b57cec5SDimitry Andric   StringRef CallocName = TLI.getName(LibFunc_calloc);
1927bdd1243dSDimitry Andric   Type *SizeTTy = getSizeTTy(B, &TLI);
192881ad6265SDimitry Andric   FunctionCallee Calloc = getOrInsertLibFunc(M, TLI, LibFunc_calloc,
19295f757f3fSDimitry Andric                                              B.getPtrTy(), SizeTTy, SizeTTy);
193081ad6265SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, CallocName, TLI);
19310b57cec5SDimitry Andric   CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
19320b57cec5SDimitry Andric 
19330b57cec5SDimitry Andric   if (const auto *F =
19340b57cec5SDimitry Andric           dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts()))
19350b57cec5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
19360b57cec5SDimitry Andric 
19370b57cec5SDimitry Andric   return CI;
19380b57cec5SDimitry Andric }
193906c3fb27SDimitry Andric 
emitHotColdNew(Value * Num,IRBuilderBase & B,const TargetLibraryInfo * TLI,LibFunc NewFunc,uint8_t HotCold)194006c3fb27SDimitry Andric Value *llvm::emitHotColdNew(Value *Num, IRBuilderBase &B,
194106c3fb27SDimitry Andric                             const TargetLibraryInfo *TLI, LibFunc NewFunc,
194206c3fb27SDimitry Andric                             uint8_t HotCold) {
194306c3fb27SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
194406c3fb27SDimitry Andric   if (!isLibFuncEmittable(M, TLI, NewFunc))
194506c3fb27SDimitry Andric     return nullptr;
194606c3fb27SDimitry Andric 
194706c3fb27SDimitry Andric   StringRef Name = TLI->getName(NewFunc);
19485f757f3fSDimitry Andric   FunctionCallee Func = M->getOrInsertFunction(Name, B.getPtrTy(),
194906c3fb27SDimitry Andric                                                Num->getType(), B.getInt8Ty());
195006c3fb27SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, Name, *TLI);
195106c3fb27SDimitry Andric   CallInst *CI = B.CreateCall(Func, {Num, B.getInt8(HotCold)}, Name);
195206c3fb27SDimitry Andric 
195306c3fb27SDimitry Andric   if (const Function *F =
195406c3fb27SDimitry Andric           dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))
195506c3fb27SDimitry Andric     CI->setCallingConv(F->getCallingConv());
195606c3fb27SDimitry Andric 
195706c3fb27SDimitry Andric   return CI;
195806c3fb27SDimitry Andric }
195906c3fb27SDimitry Andric 
emitHotColdNewNoThrow(Value * Num,Value * NoThrow,IRBuilderBase & B,const TargetLibraryInfo * TLI,LibFunc NewFunc,uint8_t HotCold)196006c3fb27SDimitry Andric Value *llvm::emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B,
196106c3fb27SDimitry Andric                                    const TargetLibraryInfo *TLI,
196206c3fb27SDimitry Andric                                    LibFunc NewFunc, uint8_t HotCold) {
196306c3fb27SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
196406c3fb27SDimitry Andric   if (!isLibFuncEmittable(M, TLI, NewFunc))
196506c3fb27SDimitry Andric     return nullptr;
196606c3fb27SDimitry Andric 
196706c3fb27SDimitry Andric   StringRef Name = TLI->getName(NewFunc);
196806c3fb27SDimitry Andric   FunctionCallee Func =
19695f757f3fSDimitry Andric       M->getOrInsertFunction(Name, B.getPtrTy(), Num->getType(),
197006c3fb27SDimitry Andric                              NoThrow->getType(), B.getInt8Ty());
197106c3fb27SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, Name, *TLI);
197206c3fb27SDimitry Andric   CallInst *CI = B.CreateCall(Func, {Num, NoThrow, B.getInt8(HotCold)}, Name);
197306c3fb27SDimitry Andric 
197406c3fb27SDimitry Andric   if (const Function *F =
197506c3fb27SDimitry Andric           dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))
197606c3fb27SDimitry Andric     CI->setCallingConv(F->getCallingConv());
197706c3fb27SDimitry Andric 
197806c3fb27SDimitry Andric   return CI;
197906c3fb27SDimitry Andric }
198006c3fb27SDimitry Andric 
emitHotColdNewAligned(Value * Num,Value * Align,IRBuilderBase & B,const TargetLibraryInfo * TLI,LibFunc NewFunc,uint8_t HotCold)198106c3fb27SDimitry Andric Value *llvm::emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B,
198206c3fb27SDimitry Andric                                    const TargetLibraryInfo *TLI,
198306c3fb27SDimitry Andric                                    LibFunc NewFunc, uint8_t HotCold) {
198406c3fb27SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
198506c3fb27SDimitry Andric   if (!isLibFuncEmittable(M, TLI, NewFunc))
198606c3fb27SDimitry Andric     return nullptr;
198706c3fb27SDimitry Andric 
198806c3fb27SDimitry Andric   StringRef Name = TLI->getName(NewFunc);
198906c3fb27SDimitry Andric   FunctionCallee Func = M->getOrInsertFunction(
19905f757f3fSDimitry Andric       Name, B.getPtrTy(), Num->getType(), Align->getType(), B.getInt8Ty());
199106c3fb27SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, Name, *TLI);
199206c3fb27SDimitry Andric   CallInst *CI = B.CreateCall(Func, {Num, Align, B.getInt8(HotCold)}, Name);
199306c3fb27SDimitry Andric 
199406c3fb27SDimitry Andric   if (const Function *F =
199506c3fb27SDimitry Andric           dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))
199606c3fb27SDimitry Andric     CI->setCallingConv(F->getCallingConv());
199706c3fb27SDimitry Andric 
199806c3fb27SDimitry Andric   return CI;
199906c3fb27SDimitry Andric }
200006c3fb27SDimitry Andric 
emitHotColdNewAlignedNoThrow(Value * Num,Value * Align,Value * NoThrow,IRBuilderBase & B,const TargetLibraryInfo * TLI,LibFunc NewFunc,uint8_t HotCold)200106c3fb27SDimitry Andric Value *llvm::emitHotColdNewAlignedNoThrow(Value *Num, Value *Align,
200206c3fb27SDimitry Andric                                           Value *NoThrow, IRBuilderBase &B,
200306c3fb27SDimitry Andric                                           const TargetLibraryInfo *TLI,
200406c3fb27SDimitry Andric                                           LibFunc NewFunc, uint8_t HotCold) {
200506c3fb27SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
200606c3fb27SDimitry Andric   if (!isLibFuncEmittable(M, TLI, NewFunc))
200706c3fb27SDimitry Andric     return nullptr;
200806c3fb27SDimitry Andric 
200906c3fb27SDimitry Andric   StringRef Name = TLI->getName(NewFunc);
201006c3fb27SDimitry Andric   FunctionCallee Func = M->getOrInsertFunction(
20115f757f3fSDimitry Andric       Name, B.getPtrTy(), Num->getType(), Align->getType(),
201206c3fb27SDimitry Andric       NoThrow->getType(), B.getInt8Ty());
201306c3fb27SDimitry Andric   inferNonMandatoryLibFuncAttrs(M, Name, *TLI);
201406c3fb27SDimitry Andric   CallInst *CI =
201506c3fb27SDimitry Andric       B.CreateCall(Func, {Num, Align, NoThrow, B.getInt8(HotCold)}, Name);
201606c3fb27SDimitry Andric 
201706c3fb27SDimitry Andric   if (const Function *F =
201806c3fb27SDimitry Andric           dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))
201906c3fb27SDimitry Andric     CI->setCallingConv(F->getCallingConv());
202006c3fb27SDimitry Andric 
202106c3fb27SDimitry Andric   return CI;
202206c3fb27SDimitry Andric }
2023