1f22ef01cSRoman Divacky //===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file implements some functions that will create standard C libcalls.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14f22ef01cSRoman Divacky #include "llvm/Transforms/Utils/BuildLibCalls.h"
157ae0e2c9SDimitry Andric #include "llvm/ADT/SmallString.h"
163ca95b02SDimitry Andric #include "llvm/ADT/Statistic.h"
177d523365SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h"
18139f7f9bSDimitry Andric #include "llvm/IR/Constants.h"
19139f7f9bSDimitry Andric #include "llvm/IR/DataLayout.h"
20139f7f9bSDimitry Andric #include "llvm/IR/Function.h"
21139f7f9bSDimitry Andric #include "llvm/IR/IRBuilder.h"
22139f7f9bSDimitry Andric #include "llvm/IR/Intrinsics.h"
23139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h"
24139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
25139f7f9bSDimitry Andric #include "llvm/IR/Type.h"
26f22ef01cSRoman Divacky 
27f22ef01cSRoman Divacky using namespace llvm;
28f22ef01cSRoman Divacky 
293ca95b02SDimitry Andric #define DEBUG_TYPE "build-libcalls"
303ca95b02SDimitry Andric 
313ca95b02SDimitry Andric //- Infer Attributes ---------------------------------------------------------//
323ca95b02SDimitry Andric 
333ca95b02SDimitry Andric STATISTIC(NumReadNone, "Number of functions inferred as readnone");
343ca95b02SDimitry Andric STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
353ca95b02SDimitry Andric STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
363ca95b02SDimitry Andric STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
373ca95b02SDimitry Andric STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
383ca95b02SDimitry Andric STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
393ca95b02SDimitry Andric STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
403ca95b02SDimitry Andric STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
41*b5893f02SDimitry Andric STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
423ca95b02SDimitry Andric 
setDoesNotAccessMemory(Function & F)433ca95b02SDimitry Andric static bool setDoesNotAccessMemory(Function &F) {
443ca95b02SDimitry Andric   if (F.doesNotAccessMemory())
453ca95b02SDimitry Andric     return false;
463ca95b02SDimitry Andric   F.setDoesNotAccessMemory();
473ca95b02SDimitry Andric   ++NumReadNone;
483ca95b02SDimitry Andric   return true;
493ca95b02SDimitry Andric }
503ca95b02SDimitry Andric 
setOnlyReadsMemory(Function & F)513ca95b02SDimitry Andric static bool setOnlyReadsMemory(Function &F) {
523ca95b02SDimitry Andric   if (F.onlyReadsMemory())
533ca95b02SDimitry Andric     return false;
543ca95b02SDimitry Andric   F.setOnlyReadsMemory();
553ca95b02SDimitry Andric   ++NumReadOnly;
563ca95b02SDimitry Andric   return true;
573ca95b02SDimitry Andric }
583ca95b02SDimitry Andric 
setOnlyAccessesArgMemory(Function & F)593ca95b02SDimitry Andric static bool setOnlyAccessesArgMemory(Function &F) {
603ca95b02SDimitry Andric   if (F.onlyAccessesArgMemory())
613ca95b02SDimitry Andric     return false;
623ca95b02SDimitry Andric   F.setOnlyAccessesArgMemory();
633ca95b02SDimitry Andric   ++NumArgMemOnly;
643ca95b02SDimitry Andric   return true;
653ca95b02SDimitry Andric }
663ca95b02SDimitry Andric 
setDoesNotThrow(Function & F)673ca95b02SDimitry Andric static bool setDoesNotThrow(Function &F) {
683ca95b02SDimitry Andric   if (F.doesNotThrow())
693ca95b02SDimitry Andric     return false;
703ca95b02SDimitry Andric   F.setDoesNotThrow();
713ca95b02SDimitry Andric   ++NumNoUnwind;
723ca95b02SDimitry Andric   return true;
733ca95b02SDimitry Andric }
743ca95b02SDimitry Andric 
setRetDoesNotAlias(Function & F)75f37b6182SDimitry Andric static bool setRetDoesNotAlias(Function &F) {
76f37b6182SDimitry Andric   if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias))
773ca95b02SDimitry Andric     return false;
78f37b6182SDimitry Andric   F.addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
793ca95b02SDimitry Andric   ++NumNoAlias;
803ca95b02SDimitry Andric   return true;
813ca95b02SDimitry Andric }
823ca95b02SDimitry Andric 
setDoesNotCapture(Function & F,unsigned ArgNo)83f37b6182SDimitry Andric static bool setDoesNotCapture(Function &F, unsigned ArgNo) {
84f37b6182SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::NoCapture))
853ca95b02SDimitry Andric     return false;
86f37b6182SDimitry Andric   F.addParamAttr(ArgNo, Attribute::NoCapture);
87f37b6182SDimitry Andric   ++NumNoCapture;
88f37b6182SDimitry Andric   return true;
89f37b6182SDimitry Andric }
90f37b6182SDimitry Andric 
setOnlyReadsMemory(Function & F,unsigned ArgNo)91f37b6182SDimitry Andric static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
92f37b6182SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))
93f37b6182SDimitry Andric     return false;
94f37b6182SDimitry Andric   F.addParamAttr(ArgNo, Attribute::ReadOnly);
95f37b6182SDimitry Andric   ++NumReadOnlyArg;
96f37b6182SDimitry Andric   return true;
97f37b6182SDimitry Andric }
98f37b6182SDimitry Andric 
setRetNonNull(Function & F)99f37b6182SDimitry Andric static bool setRetNonNull(Function &F) {
100f37b6182SDimitry Andric   assert(F.getReturnType()->isPointerTy() &&
101f37b6182SDimitry Andric          "nonnull applies only to pointers");
102f37b6182SDimitry Andric   if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull))
103f37b6182SDimitry Andric     return false;
104f37b6182SDimitry Andric   F.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
1053ca95b02SDimitry Andric   ++NumNonNull;
1063ca95b02SDimitry Andric   return true;
1073ca95b02SDimitry Andric }
1083ca95b02SDimitry Andric 
setReturnedArg(Function & F,unsigned ArgNo)109*b5893f02SDimitry Andric static bool setReturnedArg(Function &F, unsigned ArgNo) {
110*b5893f02SDimitry Andric   if (F.hasParamAttribute(ArgNo, Attribute::Returned))
111*b5893f02SDimitry Andric     return false;
112*b5893f02SDimitry Andric   F.addParamAttr(ArgNo, Attribute::Returned);
113*b5893f02SDimitry Andric   ++NumReturnedArg;
114*b5893f02SDimitry Andric   return true;
115*b5893f02SDimitry Andric }
116*b5893f02SDimitry Andric 
setNonLazyBind(Function & F)1174ba319b5SDimitry Andric static bool setNonLazyBind(Function &F) {
1184ba319b5SDimitry Andric   if (F.hasFnAttribute(Attribute::NonLazyBind))
1194ba319b5SDimitry Andric     return false;
1204ba319b5SDimitry Andric   F.addFnAttr(Attribute::NonLazyBind);
1214ba319b5SDimitry Andric   return true;
1224ba319b5SDimitry Andric }
1234ba319b5SDimitry Andric 
inferLibFuncAttributes(Module * M,StringRef Name,const TargetLibraryInfo & TLI)1244ba319b5SDimitry Andric bool llvm::inferLibFuncAttributes(Module *M, StringRef Name,
1254ba319b5SDimitry Andric                                   const TargetLibraryInfo &TLI) {
1264ba319b5SDimitry Andric   Function *F = M->getFunction(Name);
1274ba319b5SDimitry Andric   if (!F)
1284ba319b5SDimitry Andric     return false;
1294ba319b5SDimitry Andric   return inferLibFuncAttributes(*F, TLI);
1304ba319b5SDimitry Andric }
1314ba319b5SDimitry Andric 
inferLibFuncAttributes(Function & F,const TargetLibraryInfo & TLI)1323ca95b02SDimitry Andric bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
1337a7e6055SDimitry Andric   LibFunc TheLibFunc;
1343ca95b02SDimitry Andric   if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
1353ca95b02SDimitry Andric     return false;
1363ca95b02SDimitry Andric 
1373ca95b02SDimitry Andric   bool Changed = false;
1384ba319b5SDimitry Andric 
1394ba319b5SDimitry Andric   if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
1404ba319b5SDimitry Andric     Changed |= setNonLazyBind(F);
1414ba319b5SDimitry Andric 
1423ca95b02SDimitry Andric   switch (TheLibFunc) {
1437a7e6055SDimitry Andric   case LibFunc_strlen:
1440f5676f4SDimitry Andric   case LibFunc_wcslen:
1453ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F);
1463ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
147edd7eaddSDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
148f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
1493ca95b02SDimitry Andric     return Changed;
1507a7e6055SDimitry Andric   case LibFunc_strchr:
1517a7e6055SDimitry Andric   case LibFunc_strrchr:
1523ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F);
1533ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
1543ca95b02SDimitry Andric     return Changed;
1557a7e6055SDimitry Andric   case LibFunc_strtol:
1567a7e6055SDimitry Andric   case LibFunc_strtod:
1577a7e6055SDimitry Andric   case LibFunc_strtof:
1587a7e6055SDimitry Andric   case LibFunc_strtoul:
1597a7e6055SDimitry Andric   case LibFunc_strtoll:
1607a7e6055SDimitry Andric   case LibFunc_strtold:
1617a7e6055SDimitry Andric   case LibFunc_strtoull:
1623ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
163f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
164f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
1653ca95b02SDimitry Andric     return Changed;
1667a7e6055SDimitry Andric   case LibFunc_strcpy:
167*b5893f02SDimitry Andric   case LibFunc_strncpy:
1687a7e6055SDimitry Andric   case LibFunc_strcat:
1697a7e6055SDimitry Andric   case LibFunc_strncat:
170*b5893f02SDimitry Andric     Changed |= setReturnedArg(F, 0);
171*b5893f02SDimitry Andric     LLVM_FALLTHROUGH;
172*b5893f02SDimitry Andric   case LibFunc_stpcpy:
1737a7e6055SDimitry Andric   case LibFunc_stpncpy:
1743ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
175f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
176f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
1773ca95b02SDimitry Andric     return Changed;
1787a7e6055SDimitry Andric   case LibFunc_strxfrm:
1793ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
180f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
1813ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
182f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
1833ca95b02SDimitry Andric     return Changed;
1847a7e6055SDimitry Andric   case LibFunc_strcmp:      // 0,1
1857a7e6055SDimitry Andric   case LibFunc_strspn:      // 0,1
1867a7e6055SDimitry Andric   case LibFunc_strncmp:     // 0,1
1877a7e6055SDimitry Andric   case LibFunc_strcspn:     // 0,1
1887a7e6055SDimitry Andric   case LibFunc_strcoll:     // 0,1
1897a7e6055SDimitry Andric   case LibFunc_strcasecmp:  // 0,1
1907a7e6055SDimitry Andric   case LibFunc_strncasecmp: //
1913ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F);
1923ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
193f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
1943ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
1953ca95b02SDimitry Andric     return Changed;
1967a7e6055SDimitry Andric   case LibFunc_strstr:
1977a7e6055SDimitry Andric   case LibFunc_strpbrk:
1983ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F);
1993ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
200f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
2013ca95b02SDimitry Andric     return Changed;
2027a7e6055SDimitry Andric   case LibFunc_strtok:
2037a7e6055SDimitry Andric   case LibFunc_strtok_r:
2043ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
205f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
206f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
2073ca95b02SDimitry Andric     return Changed;
2087a7e6055SDimitry Andric   case LibFunc_scanf:
2093ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
210f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
211f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
2123ca95b02SDimitry Andric     return Changed;
2137a7e6055SDimitry Andric   case LibFunc_setbuf:
2147a7e6055SDimitry Andric   case LibFunc_setvbuf:
2153ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
216f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
2173ca95b02SDimitry Andric     return Changed;
2187a7e6055SDimitry Andric   case LibFunc_strdup:
2197a7e6055SDimitry Andric   case LibFunc_strndup:
2203ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
221f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
222f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
223f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
2243ca95b02SDimitry Andric     return Changed;
2257a7e6055SDimitry Andric   case LibFunc_stat:
2267a7e6055SDimitry Andric   case LibFunc_statvfs:
2273ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
228f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
2293ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
230f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
2313ca95b02SDimitry Andric     return Changed;
2327a7e6055SDimitry Andric   case LibFunc_sscanf:
2333ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
234f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
2353ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
236f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
2373ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
2383ca95b02SDimitry Andric     return Changed;
2397a7e6055SDimitry Andric   case LibFunc_sprintf:
2403ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
241f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
2423ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
2433ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
2443ca95b02SDimitry Andric     return Changed;
245f37b6182SDimitry Andric   case LibFunc_snprintf:
246f37b6182SDimitry Andric     Changed |= setDoesNotThrow(F);
247f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
248f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 2);
249f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 2);
250f37b6182SDimitry Andric     return Changed;
251f37b6182SDimitry Andric   case LibFunc_setitimer:
252f37b6182SDimitry Andric     Changed |= setDoesNotThrow(F);
253f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
254f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 2);
255f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
256f37b6182SDimitry Andric     return Changed;
257f37b6182SDimitry Andric   case LibFunc_system:
258f37b6182SDimitry Andric     // May throw; "system" is a valid pthread cancellation point.
259f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
260f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
261f37b6182SDimitry Andric     return Changed;
2627a7e6055SDimitry Andric   case LibFunc_malloc:
2633ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
264f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
2653ca95b02SDimitry Andric     return Changed;
2667a7e6055SDimitry Andric   case LibFunc_memcmp:
2673ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F);
2683ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
269f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
2703ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
2713ca95b02SDimitry Andric     return Changed;
2727a7e6055SDimitry Andric   case LibFunc_memchr:
2737a7e6055SDimitry Andric   case LibFunc_memrchr:
2743ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F);
2753ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
2763ca95b02SDimitry Andric     return Changed;
2777a7e6055SDimitry Andric   case LibFunc_modf:
2787a7e6055SDimitry Andric   case LibFunc_modff:
2797a7e6055SDimitry Andric   case LibFunc_modfl:
2803ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
281f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
2823ca95b02SDimitry Andric     return Changed;
2837a7e6055SDimitry Andric   case LibFunc_memcpy:
284*b5893f02SDimitry Andric   case LibFunc_memmove:
285*b5893f02SDimitry Andric     Changed |= setReturnedArg(F, 0);
286*b5893f02SDimitry Andric     LLVM_FALLTHROUGH;
2877a7e6055SDimitry Andric   case LibFunc_mempcpy:
2887a7e6055SDimitry Andric   case LibFunc_memccpy:
2893ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
290f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
291f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
2923ca95b02SDimitry Andric     return Changed;
2937a7e6055SDimitry Andric   case LibFunc_memcpy_chk:
2943ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
2953ca95b02SDimitry Andric     return Changed;
2967a7e6055SDimitry Andric   case LibFunc_memalign:
297f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
2983ca95b02SDimitry Andric     return Changed;
2997a7e6055SDimitry Andric   case LibFunc_mkdir:
3003ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
301f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
302f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
3033ca95b02SDimitry Andric     return Changed;
3047a7e6055SDimitry Andric   case LibFunc_mktime:
3053ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
306f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3073ca95b02SDimitry Andric     return Changed;
3087a7e6055SDimitry Andric   case LibFunc_realloc:
3093ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
310f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
311f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3123ca95b02SDimitry Andric     return Changed;
3137a7e6055SDimitry Andric   case LibFunc_read:
3143ca95b02SDimitry Andric     // May throw; "read" is a valid pthread cancellation point.
315f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
3163ca95b02SDimitry Andric     return Changed;
3177a7e6055SDimitry Andric   case LibFunc_rewind:
3183ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
319f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3203ca95b02SDimitry Andric     return Changed;
3217a7e6055SDimitry Andric   case LibFunc_rmdir:
3227a7e6055SDimitry Andric   case LibFunc_remove:
3237a7e6055SDimitry Andric   case LibFunc_realpath:
3243ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
325f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
326f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
3273ca95b02SDimitry Andric     return Changed;
3287a7e6055SDimitry Andric   case LibFunc_rename:
3293ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
330f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3313ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
332f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
3333ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
3343ca95b02SDimitry Andric     return Changed;
3357a7e6055SDimitry Andric   case LibFunc_readlink:
3363ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
337f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3383ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
339f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
3403ca95b02SDimitry Andric     return Changed;
3417a7e6055SDimitry Andric   case LibFunc_write:
3423ca95b02SDimitry Andric     // May throw; "write" is a valid pthread cancellation point.
343f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
344f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
3453ca95b02SDimitry Andric     return Changed;
3467a7e6055SDimitry Andric   case LibFunc_bcopy:
3473ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
348f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3493ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
350f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
3513ca95b02SDimitry Andric     return Changed;
3527a7e6055SDimitry Andric   case LibFunc_bcmp:
3533ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
3543ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F);
355f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3563ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
3573ca95b02SDimitry Andric     return Changed;
3587a7e6055SDimitry Andric   case LibFunc_bzero:
3593ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
360f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3613ca95b02SDimitry Andric     return Changed;
3627a7e6055SDimitry Andric   case LibFunc_calloc:
3633ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
364f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
3653ca95b02SDimitry Andric     return Changed;
3667a7e6055SDimitry Andric   case LibFunc_chmod:
3677a7e6055SDimitry Andric   case LibFunc_chown:
3683ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
369f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
370f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
3713ca95b02SDimitry Andric     return Changed;
3727a7e6055SDimitry Andric   case LibFunc_ctermid:
3737a7e6055SDimitry Andric   case LibFunc_clearerr:
3747a7e6055SDimitry Andric   case LibFunc_closedir:
3753ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
376f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3773ca95b02SDimitry Andric     return Changed;
3787a7e6055SDimitry Andric   case LibFunc_atoi:
3797a7e6055SDimitry Andric   case LibFunc_atol:
3807a7e6055SDimitry Andric   case LibFunc_atof:
3817a7e6055SDimitry Andric   case LibFunc_atoll:
3823ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
3833ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F);
384f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3853ca95b02SDimitry Andric     return Changed;
3867a7e6055SDimitry Andric   case LibFunc_access:
3873ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
388f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
389f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
3903ca95b02SDimitry Andric     return Changed;
3917a7e6055SDimitry Andric   case LibFunc_fopen:
3923ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
393f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
394f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
3953ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
396f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
3973ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
3983ca95b02SDimitry Andric     return Changed;
3997a7e6055SDimitry Andric   case LibFunc_fdopen:
4003ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
401f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
402f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
403f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
4043ca95b02SDimitry Andric     return Changed;
4057a7e6055SDimitry Andric   case LibFunc_feof:
4067a7e6055SDimitry Andric   case LibFunc_free:
4077a7e6055SDimitry Andric   case LibFunc_fseek:
4087a7e6055SDimitry Andric   case LibFunc_ftell:
4097a7e6055SDimitry Andric   case LibFunc_fgetc:
4104ba319b5SDimitry Andric   case LibFunc_fgetc_unlocked:
4117a7e6055SDimitry Andric   case LibFunc_fseeko:
4127a7e6055SDimitry Andric   case LibFunc_ftello:
4137a7e6055SDimitry Andric   case LibFunc_fileno:
4147a7e6055SDimitry Andric   case LibFunc_fflush:
4157a7e6055SDimitry Andric   case LibFunc_fclose:
4167a7e6055SDimitry Andric   case LibFunc_fsetpos:
4177a7e6055SDimitry Andric   case LibFunc_flockfile:
4187a7e6055SDimitry Andric   case LibFunc_funlockfile:
4197a7e6055SDimitry Andric   case LibFunc_ftrylockfile:
4203ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
421f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4223ca95b02SDimitry Andric     return Changed;
4237a7e6055SDimitry Andric   case LibFunc_ferror:
4243ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
425f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4263ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F);
4273ca95b02SDimitry Andric     return Changed;
4287a7e6055SDimitry Andric   case LibFunc_fputc:
4294ba319b5SDimitry Andric   case LibFunc_fputc_unlocked:
4307a7e6055SDimitry Andric   case LibFunc_fstat:
4317a7e6055SDimitry Andric   case LibFunc_frexp:
4327a7e6055SDimitry Andric   case LibFunc_frexpf:
4337a7e6055SDimitry Andric   case LibFunc_frexpl:
4347a7e6055SDimitry Andric   case LibFunc_fstatvfs:
4353ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
436f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
4373ca95b02SDimitry Andric     return Changed;
4387a7e6055SDimitry Andric   case LibFunc_fgets:
4394ba319b5SDimitry Andric   case LibFunc_fgets_unlocked:
4403ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
441f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 2);
4423ca95b02SDimitry Andric     return Changed;
4437a7e6055SDimitry Andric   case LibFunc_fread:
4444ba319b5SDimitry Andric   case LibFunc_fread_unlocked:
4453ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
446f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
447f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 3);
4483ca95b02SDimitry Andric     return Changed;
4497a7e6055SDimitry Andric   case LibFunc_fwrite:
4504ba319b5SDimitry Andric   case LibFunc_fwrite_unlocked:
4513ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
452f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
453f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 3);
4543ca95b02SDimitry Andric     // FIXME: readonly #1?
4553ca95b02SDimitry Andric     return Changed;
4567a7e6055SDimitry Andric   case LibFunc_fputs:
4574ba319b5SDimitry Andric   case LibFunc_fputs_unlocked:
4583ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
459f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4603ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
461f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
4623ca95b02SDimitry Andric     return Changed;
4637a7e6055SDimitry Andric   case LibFunc_fscanf:
4647a7e6055SDimitry Andric   case LibFunc_fprintf:
4653ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
466f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4673ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
468f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
4693ca95b02SDimitry Andric     return Changed;
4707a7e6055SDimitry Andric   case LibFunc_fgetpos:
4713ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
472f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4733ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
4743ca95b02SDimitry Andric     return Changed;
4757a7e6055SDimitry Andric   case LibFunc_getc:
4767a7e6055SDimitry Andric   case LibFunc_getlogin_r:
4777a7e6055SDimitry Andric   case LibFunc_getc_unlocked:
4783ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
479f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4803ca95b02SDimitry Andric     return Changed;
4817a7e6055SDimitry Andric   case LibFunc_getenv:
4823ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
4833ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F);
484f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
4853ca95b02SDimitry Andric     return Changed;
4867a7e6055SDimitry Andric   case LibFunc_gets:
4877a7e6055SDimitry Andric   case LibFunc_getchar:
4884ba319b5SDimitry Andric   case LibFunc_getchar_unlocked:
4893ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
4903ca95b02SDimitry Andric     return Changed;
4917a7e6055SDimitry Andric   case LibFunc_getitimer:
4923ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
493f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
4943ca95b02SDimitry Andric     return Changed;
4957a7e6055SDimitry Andric   case LibFunc_getpwnam:
4963ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
497f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
498f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
4993ca95b02SDimitry Andric     return Changed;
5007a7e6055SDimitry Andric   case LibFunc_ungetc:
5013ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
502f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
5033ca95b02SDimitry Andric     return Changed;
5047a7e6055SDimitry Andric   case LibFunc_uname:
5053ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
506f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5073ca95b02SDimitry Andric     return Changed;
5087a7e6055SDimitry Andric   case LibFunc_unlink:
5093ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
510f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
511f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
5123ca95b02SDimitry Andric     return Changed;
5137a7e6055SDimitry Andric   case LibFunc_unsetenv:
5143ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
515f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
516f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
5173ca95b02SDimitry Andric     return Changed;
5187a7e6055SDimitry Andric   case LibFunc_utime:
5197a7e6055SDimitry Andric   case LibFunc_utimes:
5203ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
521f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5223ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
523f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
5243ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
5253ca95b02SDimitry Andric     return Changed;
5267a7e6055SDimitry Andric   case LibFunc_putc:
5274ba319b5SDimitry Andric   case LibFunc_putc_unlocked:
5283ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
529f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
5303ca95b02SDimitry Andric     return Changed;
5317a7e6055SDimitry Andric   case LibFunc_puts:
5327a7e6055SDimitry Andric   case LibFunc_printf:
5337a7e6055SDimitry Andric   case LibFunc_perror:
5343ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
535f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
536f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
5373ca95b02SDimitry Andric     return Changed;
5387a7e6055SDimitry Andric   case LibFunc_pread:
5393ca95b02SDimitry Andric     // May throw; "pread" is a valid pthread cancellation point.
540f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
5413ca95b02SDimitry Andric     return Changed;
5427a7e6055SDimitry Andric   case LibFunc_pwrite:
5433ca95b02SDimitry Andric     // May throw; "pwrite" is a valid pthread cancellation point.
544f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
545f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
5463ca95b02SDimitry Andric     return Changed;
5477a7e6055SDimitry Andric   case LibFunc_putchar:
5484ba319b5SDimitry Andric   case LibFunc_putchar_unlocked:
5493ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
5503ca95b02SDimitry Andric     return Changed;
5517a7e6055SDimitry Andric   case LibFunc_popen:
5523ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
553f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
554f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5553ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
556f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
5573ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
5583ca95b02SDimitry Andric     return Changed;
5597a7e6055SDimitry Andric   case LibFunc_pclose:
5603ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
561f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5623ca95b02SDimitry Andric     return Changed;
5637a7e6055SDimitry Andric   case LibFunc_vscanf:
5643ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
565f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
566f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
5673ca95b02SDimitry Andric     return Changed;
5687a7e6055SDimitry Andric   case LibFunc_vsscanf:
5693ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
570f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5713ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
572f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
5733ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
5743ca95b02SDimitry Andric     return Changed;
5757a7e6055SDimitry Andric   case LibFunc_vfscanf:
5763ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
577f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5783ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
579f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
5803ca95b02SDimitry Andric     return Changed;
5817a7e6055SDimitry Andric   case LibFunc_valloc:
5823ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
583f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
5843ca95b02SDimitry Andric     return Changed;
5857a7e6055SDimitry Andric   case LibFunc_vprintf:
5863ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
587f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
588f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
5893ca95b02SDimitry Andric     return Changed;
5907a7e6055SDimitry Andric   case LibFunc_vfprintf:
5917a7e6055SDimitry Andric   case LibFunc_vsprintf:
5923ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
593f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
5943ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
595f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
5963ca95b02SDimitry Andric     return Changed;
5977a7e6055SDimitry Andric   case LibFunc_vsnprintf:
5983ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
599f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
600f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 2);
601f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 2);
6023ca95b02SDimitry Andric     return Changed;
6037a7e6055SDimitry Andric   case LibFunc_open:
6043ca95b02SDimitry Andric     // May throw; "open" is a valid pthread cancellation point.
605f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
606f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
6073ca95b02SDimitry Andric     return Changed;
6087a7e6055SDimitry Andric   case LibFunc_opendir:
6093ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
610f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
611f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
612f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
6133ca95b02SDimitry Andric     return Changed;
6147a7e6055SDimitry Andric   case LibFunc_tmpfile:
6153ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
616f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
6173ca95b02SDimitry Andric     return Changed;
6187a7e6055SDimitry Andric   case LibFunc_times:
6193ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
620f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6213ca95b02SDimitry Andric     return Changed;
6227a7e6055SDimitry Andric   case LibFunc_htonl:
6237a7e6055SDimitry Andric   case LibFunc_htons:
6247a7e6055SDimitry Andric   case LibFunc_ntohl:
6257a7e6055SDimitry Andric   case LibFunc_ntohs:
6263ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
6273ca95b02SDimitry Andric     Changed |= setDoesNotAccessMemory(F);
6283ca95b02SDimitry Andric     return Changed;
6297a7e6055SDimitry Andric   case LibFunc_lstat:
6303ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
631f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6323ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
633f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
6343ca95b02SDimitry Andric     return Changed;
6357a7e6055SDimitry Andric   case LibFunc_lchown:
6363ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
637f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
638f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
6393ca95b02SDimitry Andric     return Changed;
6407a7e6055SDimitry Andric   case LibFunc_qsort:
6413ca95b02SDimitry Andric     // May throw; places call through function pointer.
642f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 3);
6433ca95b02SDimitry Andric     return Changed;
6447a7e6055SDimitry Andric   case LibFunc_dunder_strdup:
6457a7e6055SDimitry Andric   case LibFunc_dunder_strndup:
6463ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
647f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
648f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
649f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
6503ca95b02SDimitry Andric     return Changed;
6517a7e6055SDimitry Andric   case LibFunc_dunder_strtok_r:
6523ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
653f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
654f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
6553ca95b02SDimitry Andric     return Changed;
6567a7e6055SDimitry Andric   case LibFunc_under_IO_getc:
6573ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
658f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6593ca95b02SDimitry Andric     return Changed;
6607a7e6055SDimitry Andric   case LibFunc_under_IO_putc:
6613ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
662f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
6633ca95b02SDimitry Andric     return Changed;
6647a7e6055SDimitry Andric   case LibFunc_dunder_isoc99_scanf:
6653ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
666f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
667f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
6683ca95b02SDimitry Andric     return Changed;
6697a7e6055SDimitry Andric   case LibFunc_stat64:
6707a7e6055SDimitry Andric   case LibFunc_lstat64:
6717a7e6055SDimitry Andric   case LibFunc_statvfs64:
6723ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
673f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6743ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
675f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
6763ca95b02SDimitry Andric     return Changed;
6777a7e6055SDimitry Andric   case LibFunc_dunder_isoc99_sscanf:
6783ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
679f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6803ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
681f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
6823ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
6833ca95b02SDimitry Andric     return Changed;
6847a7e6055SDimitry Andric   case LibFunc_fopen64:
6853ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
686f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
687f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6883ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
689f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
6903ca95b02SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
6913ca95b02SDimitry Andric     return Changed;
6927a7e6055SDimitry Andric   case LibFunc_fseeko64:
6937a7e6055SDimitry Andric   case LibFunc_ftello64:
6943ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
695f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
6963ca95b02SDimitry Andric     return Changed;
6977a7e6055SDimitry Andric   case LibFunc_tmpfile64:
6983ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
699f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
7003ca95b02SDimitry Andric     return Changed;
7017a7e6055SDimitry Andric   case LibFunc_fstat64:
7027a7e6055SDimitry Andric   case LibFunc_fstatvfs64:
7033ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
704f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
7053ca95b02SDimitry Andric     return Changed;
7067a7e6055SDimitry Andric   case LibFunc_open64:
7073ca95b02SDimitry Andric     // May throw; "open" is a valid pthread cancellation point.
708f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
709f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 0);
7103ca95b02SDimitry Andric     return Changed;
7117a7e6055SDimitry Andric   case LibFunc_gettimeofday:
7123ca95b02SDimitry Andric     // Currently some platforms have the restrict keyword on the arguments to
7133ca95b02SDimitry Andric     // gettimeofday. To be conservative, do not add noalias to gettimeofday's
7143ca95b02SDimitry Andric     // arguments.
7153ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
716f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
7173ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
7183ca95b02SDimitry Andric     return Changed;
7197a7e6055SDimitry Andric   case LibFunc_Znwj: // new(unsigned int)
7207a7e6055SDimitry Andric   case LibFunc_Znwm: // new(unsigned long)
7217a7e6055SDimitry Andric   case LibFunc_Znaj: // new[](unsigned int)
7227a7e6055SDimitry Andric   case LibFunc_Znam: // new[](unsigned long)
7237a7e6055SDimitry Andric   case LibFunc_msvc_new_int: // new(unsigned int)
7247a7e6055SDimitry Andric   case LibFunc_msvc_new_longlong: // new(unsigned long long)
7257a7e6055SDimitry Andric   case LibFunc_msvc_new_array_int: // new[](unsigned int)
7267a7e6055SDimitry Andric   case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
7273ca95b02SDimitry Andric     // Operator new always returns a nonnull noalias pointer
728f37b6182SDimitry Andric     Changed |= setRetNonNull(F);
729f37b6182SDimitry Andric     Changed |= setRetDoesNotAlias(F);
7303ca95b02SDimitry Andric     return Changed;
7313ca95b02SDimitry Andric   // TODO: add LibFunc entries for:
7327a7e6055SDimitry Andric   // case LibFunc_memset_pattern4:
7337a7e6055SDimitry Andric   // case LibFunc_memset_pattern8:
7347a7e6055SDimitry Andric   case LibFunc_memset_pattern16:
7353ca95b02SDimitry Andric     Changed |= setOnlyAccessesArgMemory(F);
736f37b6182SDimitry Andric     Changed |= setDoesNotCapture(F, 0);
7373ca95b02SDimitry Andric     Changed |= setDoesNotCapture(F, 1);
738f37b6182SDimitry Andric     Changed |= setOnlyReadsMemory(F, 1);
7393ca95b02SDimitry Andric     return Changed;
7403ca95b02SDimitry Andric   // int __nvvm_reflect(const char *)
7417a7e6055SDimitry Andric   case LibFunc_nvvm_reflect:
7423ca95b02SDimitry Andric     Changed |= setDoesNotAccessMemory(F);
7433ca95b02SDimitry Andric     Changed |= setDoesNotThrow(F);
7443ca95b02SDimitry Andric     return Changed;
7453ca95b02SDimitry Andric 
7463ca95b02SDimitry Andric   default:
7473ca95b02SDimitry Andric     // FIXME: It'd be really nice to cover all the library functions we're
7483ca95b02SDimitry Andric     // aware of here.
7493ca95b02SDimitry Andric     return false;
7503ca95b02SDimitry Andric   }
7513ca95b02SDimitry Andric }
7523ca95b02SDimitry Andric 
hasUnaryFloatFn(const TargetLibraryInfo * TLI,Type * Ty,LibFunc DoubleFn,LibFunc FloatFn,LibFunc LongDoubleFn)7534ba319b5SDimitry Andric bool llvm::hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
7544ba319b5SDimitry Andric                            LibFunc DoubleFn, LibFunc FloatFn,
7554ba319b5SDimitry Andric                            LibFunc LongDoubleFn) {
7564ba319b5SDimitry Andric   switch (Ty->getTypeID()) {
757*b5893f02SDimitry Andric   case Type::HalfTyID:
758*b5893f02SDimitry Andric     return false;
7594ba319b5SDimitry Andric   case Type::FloatTyID:
7604ba319b5SDimitry Andric     return TLI->has(FloatFn);
7614ba319b5SDimitry Andric   case Type::DoubleTyID:
7624ba319b5SDimitry Andric     return TLI->has(DoubleFn);
7634ba319b5SDimitry Andric   default:
7644ba319b5SDimitry Andric     return TLI->has(LongDoubleFn);
7654ba319b5SDimitry Andric   }
7664ba319b5SDimitry Andric }
7674ba319b5SDimitry Andric 
getUnaryFloatFn(const TargetLibraryInfo * TLI,Type * Ty,LibFunc DoubleFn,LibFunc FloatFn,LibFunc LongDoubleFn)768*b5893f02SDimitry Andric StringRef llvm::getUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
769*b5893f02SDimitry Andric                                 LibFunc DoubleFn, LibFunc FloatFn,
770*b5893f02SDimitry Andric                                 LibFunc LongDoubleFn) {
771*b5893f02SDimitry Andric   assert(hasUnaryFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
772*b5893f02SDimitry Andric          "Cannot get name for unavailable function!");
773*b5893f02SDimitry Andric 
774*b5893f02SDimitry Andric   switch (Ty->getTypeID()) {
775*b5893f02SDimitry Andric   case Type::HalfTyID:
776*b5893f02SDimitry Andric     llvm_unreachable("No name for HalfTy!");
777*b5893f02SDimitry Andric   case Type::FloatTyID:
778*b5893f02SDimitry Andric     return TLI->getName(FloatFn);
779*b5893f02SDimitry Andric   case Type::DoubleTyID:
780*b5893f02SDimitry Andric     return TLI->getName(DoubleFn);
781*b5893f02SDimitry Andric   default:
782*b5893f02SDimitry Andric     return TLI->getName(LongDoubleFn);
783*b5893f02SDimitry Andric   }
784*b5893f02SDimitry Andric }
785*b5893f02SDimitry Andric 
7863ca95b02SDimitry Andric //- Emit LibCalls ------------------------------------------------------------//
7873ca95b02SDimitry Andric 
castToCStr(Value * V,IRBuilder<> & B)7883ca95b02SDimitry Andric Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
78991bc56edSDimitry Andric   unsigned AS = V->getType()->getPointerAddressSpace();
79091bc56edSDimitry Andric   return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
791f22ef01cSRoman Divacky }
792f22ef01cSRoman Divacky 
emitStrLen(Value * Ptr,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)7933ca95b02SDimitry Andric Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
7947ae0e2c9SDimitry Andric                         const TargetLibraryInfo *TLI) {
7957a7e6055SDimitry Andric   if (!TLI->has(LibFunc_strlen))
79691bc56edSDimitry Andric     return nullptr;
7977ae0e2c9SDimitry Andric 
7983ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
7994ba319b5SDimitry Andric   StringRef StrlenName = TLI->getName(LibFunc_strlen);
800f22ef01cSRoman Divacky   LLVMContext &Context = B.GetInsertBlock()->getContext();
8014ba319b5SDimitry Andric   Constant *StrLen = M->getOrInsertFunction(StrlenName, DL.getIntPtrType(Context),
8027a7e6055SDimitry Andric                                             B.getInt8PtrTy());
8034ba319b5SDimitry Andric   inferLibFuncAttributes(M, StrlenName, *TLI);
8044ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), StrlenName);
805f22ef01cSRoman Divacky   if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
806f22ef01cSRoman Divacky     CI->setCallingConv(F->getCallingConv());
807f22ef01cSRoman Divacky 
808f22ef01cSRoman Divacky   return CI;
809f22ef01cSRoman Divacky }
810f22ef01cSRoman Divacky 
emitStrChr(Value * Ptr,char C,IRBuilder<> & B,const TargetLibraryInfo * TLI)8113ca95b02SDimitry Andric Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
812ff0cc061SDimitry Andric                         const TargetLibraryInfo *TLI) {
8137a7e6055SDimitry Andric   if (!TLI->has(LibFunc_strchr))
81491bc56edSDimitry Andric     return nullptr;
8157ae0e2c9SDimitry Andric 
8163ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
8174ba319b5SDimitry Andric   StringRef StrChrName = TLI->getName(LibFunc_strchr);
8186122f3e6SDimitry Andric   Type *I8Ptr = B.getInt8PtrTy();
8196122f3e6SDimitry Andric   Type *I32Ty = B.getInt32Ty();
8203ca95b02SDimitry Andric   Constant *StrChr =
8214ba319b5SDimitry Andric       M->getOrInsertFunction(StrChrName, I8Ptr, I8Ptr, I32Ty);
8224ba319b5SDimitry Andric   inferLibFuncAttributes(M, StrChrName, *TLI);
823ff0cc061SDimitry Andric   CallInst *CI = B.CreateCall(
8244ba319b5SDimitry Andric       StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, StrChrName);
825f22ef01cSRoman Divacky   if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
826f22ef01cSRoman Divacky     CI->setCallingConv(F->getCallingConv());
827f22ef01cSRoman Divacky   return CI;
828f22ef01cSRoman Divacky }
829f22ef01cSRoman Divacky 
emitStrNCmp(Value * Ptr1,Value * Ptr2,Value * Len,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)8303ca95b02SDimitry Andric Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
831ff0cc061SDimitry Andric                          const DataLayout &DL, const TargetLibraryInfo *TLI) {
8327a7e6055SDimitry Andric   if (!TLI->has(LibFunc_strncmp))
83391bc56edSDimitry Andric     return nullptr;
8347ae0e2c9SDimitry Andric 
8353ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
8364ba319b5SDimitry Andric   StringRef StrNCmpName = TLI->getName(LibFunc_strncmp);
837ffd1746dSEd Schouten   LLVMContext &Context = B.GetInsertBlock()->getContext();
8384ba319b5SDimitry Andric   Value *StrNCmp = M->getOrInsertFunction(StrNCmpName, B.getInt32Ty(),
8393ca95b02SDimitry Andric                                           B.getInt8PtrTy(), B.getInt8PtrTy(),
8407a7e6055SDimitry Andric                                           DL.getIntPtrType(Context));
8414ba319b5SDimitry Andric   inferLibFuncAttributes(M, StrNCmpName, *TLI);
842ff0cc061SDimitry Andric   CallInst *CI = B.CreateCall(
8434ba319b5SDimitry Andric       StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, StrNCmpName);
844ffd1746dSEd Schouten 
845ffd1746dSEd Schouten   if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
846ffd1746dSEd Schouten     CI->setCallingConv(F->getCallingConv());
847ffd1746dSEd Schouten 
848ffd1746dSEd Schouten   return CI;
849ffd1746dSEd Schouten }
850ffd1746dSEd Schouten 
emitStrCpy(Value * Dst,Value * Src,IRBuilder<> & B,const TargetLibraryInfo * TLI,StringRef Name)8513ca95b02SDimitry Andric Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
852ff0cc061SDimitry Andric                         const TargetLibraryInfo *TLI, StringRef Name) {
8537a7e6055SDimitry Andric   if (!TLI->has(LibFunc_strcpy))
85491bc56edSDimitry Andric     return nullptr;
8557ae0e2c9SDimitry Andric 
8563ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
8576122f3e6SDimitry Andric   Type *I8Ptr = B.getInt8PtrTy();
8587a7e6055SDimitry Andric   Value *StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr);
8594ba319b5SDimitry Andric   inferLibFuncAttributes(M, Name, *TLI);
860ff0cc061SDimitry Andric   CallInst *CI =
8613ca95b02SDimitry Andric       B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
862f22ef01cSRoman Divacky   if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
863f22ef01cSRoman Divacky     CI->setCallingConv(F->getCallingConv());
864f22ef01cSRoman Divacky   return CI;
865f22ef01cSRoman Divacky }
866f22ef01cSRoman Divacky 
emitStrNCpy(Value * Dst,Value * Src,Value * Len,IRBuilder<> & B,const TargetLibraryInfo * TLI,StringRef Name)8673ca95b02SDimitry Andric Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
8687ae0e2c9SDimitry Andric                          const TargetLibraryInfo *TLI, StringRef Name) {
8697a7e6055SDimitry Andric   if (!TLI->has(LibFunc_strncpy))
87091bc56edSDimitry Andric     return nullptr;
8717ae0e2c9SDimitry Andric 
8723ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
8736122f3e6SDimitry Andric   Type *I8Ptr = B.getInt8PtrTy();
8743ca95b02SDimitry Andric   Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr,
8757a7e6055SDimitry Andric                                           Len->getType());
8764ba319b5SDimitry Andric   inferLibFuncAttributes(M, Name, *TLI);
877ff0cc061SDimitry Andric   CallInst *CI = B.CreateCall(
8784ba319b5SDimitry Andric       StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, Name);
879f22ef01cSRoman Divacky   if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
880f22ef01cSRoman Divacky     CI->setCallingConv(F->getCallingConv());
881f22ef01cSRoman Divacky   return CI;
882f22ef01cSRoman Divacky }
883f22ef01cSRoman Divacky 
emitMemCpyChk(Value * Dst,Value * Src,Value * Len,Value * ObjSize,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)8843ca95b02SDimitry Andric Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
885ff0cc061SDimitry Andric                            IRBuilder<> &B, const DataLayout &DL,
8867ae0e2c9SDimitry Andric                            const TargetLibraryInfo *TLI) {
8877a7e6055SDimitry Andric   if (!TLI->has(LibFunc_memcpy_chk))
88891bc56edSDimitry Andric     return nullptr;
8897ae0e2c9SDimitry Andric 
8903ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
8917a7e6055SDimitry Andric   AttributeList AS;
8927a7e6055SDimitry Andric   AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
893139f7f9bSDimitry Andric                           Attribute::NoUnwind);
894f22ef01cSRoman Divacky   LLVMContext &Context = B.GetInsertBlock()->getContext();
895ff0cc061SDimitry Andric   Value *MemCpy = M->getOrInsertFunction(
8967a7e6055SDimitry Andric       "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
897ff0cc061SDimitry Andric       B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
8987a7e6055SDimitry Andric       DL.getIntPtrType(Context));
8993ca95b02SDimitry Andric   Dst = castToCStr(Dst, B);
9003ca95b02SDimitry Andric   Src = castToCStr(Src, B);
901ff0cc061SDimitry Andric   CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
902f22ef01cSRoman Divacky   if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
903f22ef01cSRoman Divacky     CI->setCallingConv(F->getCallingConv());
904f22ef01cSRoman Divacky   return CI;
905f22ef01cSRoman Divacky }
906f22ef01cSRoman Divacky 
emitMemChr(Value * Ptr,Value * Val,Value * Len,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)9073ca95b02SDimitry Andric Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
908ff0cc061SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
9097a7e6055SDimitry Andric   if (!TLI->has(LibFunc_memchr))
91091bc56edSDimitry Andric     return nullptr;
9117ae0e2c9SDimitry Andric 
9123ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
9134ba319b5SDimitry Andric   StringRef MemChrName = TLI->getName(LibFunc_memchr);
914f22ef01cSRoman Divacky   LLVMContext &Context = B.GetInsertBlock()->getContext();
9154ba319b5SDimitry Andric   Value *MemChr = M->getOrInsertFunction(MemChrName, B.getInt8PtrTy(),
9163ca95b02SDimitry Andric                                          B.getInt8PtrTy(), B.getInt32Ty(),
9177a7e6055SDimitry Andric                                          DL.getIntPtrType(Context));
9184ba319b5SDimitry Andric   inferLibFuncAttributes(M, MemChrName, *TLI);
9194ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, MemChrName);
920f22ef01cSRoman Divacky 
921f22ef01cSRoman Divacky   if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
922f22ef01cSRoman Divacky     CI->setCallingConv(F->getCallingConv());
923f22ef01cSRoman Divacky 
924f22ef01cSRoman Divacky   return CI;
925f22ef01cSRoman Divacky }
926f22ef01cSRoman Divacky 
emitMemCmp(Value * Ptr1,Value * Ptr2,Value * Len,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)9273ca95b02SDimitry Andric Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
928ff0cc061SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
9297a7e6055SDimitry Andric   if (!TLI->has(LibFunc_memcmp))
93091bc56edSDimitry Andric     return nullptr;
9317ae0e2c9SDimitry Andric 
9323ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
9334ba319b5SDimitry Andric   StringRef MemCmpName = TLI->getName(LibFunc_memcmp);
934f22ef01cSRoman Divacky   LLVMContext &Context = B.GetInsertBlock()->getContext();
9354ba319b5SDimitry Andric   Value *MemCmp = M->getOrInsertFunction(MemCmpName, B.getInt32Ty(),
9363ca95b02SDimitry Andric                                          B.getInt8PtrTy(), B.getInt8PtrTy(),
9377a7e6055SDimitry Andric                                          DL.getIntPtrType(Context));
9384ba319b5SDimitry Andric   inferLibFuncAttributes(M, MemCmpName, *TLI);
939ff0cc061SDimitry Andric   CallInst *CI = B.CreateCall(
9404ba319b5SDimitry Andric       MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, MemCmpName);
941f22ef01cSRoman Divacky 
942f22ef01cSRoman Divacky   if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
943f22ef01cSRoman Divacky     CI->setCallingConv(F->getCallingConv());
944f22ef01cSRoman Divacky 
945f22ef01cSRoman Divacky   return CI;
946f22ef01cSRoman Divacky }
947f22ef01cSRoman Divacky 
94891bc56edSDimitry Andric /// Append a suffix to the function name according to the type of 'Op'.
appendTypeSuffix(Value * Op,StringRef & Name,SmallString<20> & NameBuffer)9493ca95b02SDimitry Andric static void appendTypeSuffix(Value *Op, StringRef &Name,
9503ca95b02SDimitry Andric                              SmallString<20> &NameBuffer) {
95191bc56edSDimitry Andric   if (!Op->getType()->isDoubleTy()) {
95291bc56edSDimitry Andric       NameBuffer += Name;
95391bc56edSDimitry Andric 
95491bc56edSDimitry Andric     if (Op->getType()->isFloatTy())
95591bc56edSDimitry Andric       NameBuffer += 'f';
95691bc56edSDimitry Andric     else
95791bc56edSDimitry Andric       NameBuffer += 'l';
95891bc56edSDimitry Andric 
95991bc56edSDimitry Andric     Name = NameBuffer;
96091bc56edSDimitry Andric   }
96191bc56edSDimitry Andric }
96291bc56edSDimitry Andric 
emitUnaryFloatFnCallHelper(Value * Op,StringRef Name,IRBuilder<> & B,const AttributeList & Attrs)963*b5893f02SDimitry Andric static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
964*b5893f02SDimitry Andric                                          IRBuilder<> &B,
9657a7e6055SDimitry Andric                                          const AttributeList &Attrs) {
966*b5893f02SDimitry Andric   assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
967f22ef01cSRoman Divacky 
9683ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
969f22ef01cSRoman Divacky   Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
9707a7e6055SDimitry Andric                                          Op->getType());
971f22ef01cSRoman Divacky   CallInst *CI = B.CreateCall(Callee, Op, Name);
972f37b6182SDimitry Andric 
973f37b6182SDimitry Andric   // The incoming attribute set may have come from a speculatable intrinsic, but
974f37b6182SDimitry Andric   // is being replaced with a library call which is not allowed to be
975f37b6182SDimitry Andric   // speculatable.
976f37b6182SDimitry Andric   CI->setAttributes(Attrs.removeAttribute(B.getContext(),
977f37b6182SDimitry Andric                                           AttributeList::FunctionIndex,
978f37b6182SDimitry Andric                                           Attribute::Speculatable));
979f22ef01cSRoman Divacky   if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
980f22ef01cSRoman Divacky     CI->setCallingConv(F->getCallingConv());
981f22ef01cSRoman Divacky 
982f22ef01cSRoman Divacky   return CI;
983f22ef01cSRoman Divacky }
984f22ef01cSRoman Divacky 
emitUnaryFloatFnCall(Value * Op,StringRef Name,IRBuilder<> & B,const AttributeList & Attrs)985*b5893f02SDimitry Andric Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
986*b5893f02SDimitry Andric                                   const AttributeList &Attrs) {
987*b5893f02SDimitry Andric   SmallString<20> NameBuffer;
988*b5893f02SDimitry Andric   appendTypeSuffix(Op, Name, NameBuffer);
989*b5893f02SDimitry Andric 
990*b5893f02SDimitry Andric   return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
991*b5893f02SDimitry Andric }
992*b5893f02SDimitry Andric 
emitUnaryFloatFnCall(Value * Op,const TargetLibraryInfo * TLI,LibFunc DoubleFn,LibFunc FloatFn,LibFunc LongDoubleFn,IRBuilder<> & B,const AttributeList & Attrs)993*b5893f02SDimitry Andric Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
994*b5893f02SDimitry Andric                                   LibFunc DoubleFn, LibFunc FloatFn,
995*b5893f02SDimitry Andric                                   LibFunc LongDoubleFn, IRBuilder<> &B,
996*b5893f02SDimitry Andric                                   const AttributeList &Attrs) {
997*b5893f02SDimitry Andric   // Get the name of the function according to TLI.
998*b5893f02SDimitry Andric   StringRef Name = getUnaryFloatFn(TLI, Op->getType(),
999*b5893f02SDimitry Andric                                    DoubleFn, FloatFn, LongDoubleFn);
1000*b5893f02SDimitry Andric 
1001*b5893f02SDimitry Andric   return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1002*b5893f02SDimitry Andric }
1003*b5893f02SDimitry Andric 
emitBinaryFloatFnCall(Value * Op1,Value * Op2,StringRef Name,IRBuilder<> & B,const AttributeList & Attrs)10043ca95b02SDimitry Andric Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
10057a7e6055SDimitry Andric                                    IRBuilder<> &B, const AttributeList &Attrs) {
1006*b5893f02SDimitry Andric   assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1007*b5893f02SDimitry Andric 
100891bc56edSDimitry Andric   SmallString<20> NameBuffer;
10093ca95b02SDimitry Andric   appendTypeSuffix(Op1, Name, NameBuffer);
101091bc56edSDimitry Andric 
10113ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
10123ca95b02SDimitry Andric   Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(),
10137a7e6055SDimitry Andric                                          Op2->getType());
1014ff0cc061SDimitry Andric   CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
101591bc56edSDimitry Andric   CI->setAttributes(Attrs);
101691bc56edSDimitry Andric   if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
101791bc56edSDimitry Andric     CI->setCallingConv(F->getCallingConv());
101891bc56edSDimitry Andric 
101991bc56edSDimitry Andric   return CI;
102091bc56edSDimitry Andric }
102191bc56edSDimitry Andric 
emitPutChar(Value * Char,IRBuilder<> & B,const TargetLibraryInfo * TLI)10223ca95b02SDimitry Andric Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
10237ae0e2c9SDimitry Andric                          const TargetLibraryInfo *TLI) {
10247a7e6055SDimitry Andric   if (!TLI->has(LibFunc_putchar))
102591bc56edSDimitry Andric     return nullptr;
10267ae0e2c9SDimitry Andric 
10273ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
10284ba319b5SDimitry Andric   StringRef PutCharName = TLI->getName(LibFunc_putchar);
10294ba319b5SDimitry Andric   Value *PutChar = M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty());
10304ba319b5SDimitry Andric   inferLibFuncAttributes(M, PutCharName, *TLI);
1031f22ef01cSRoman Divacky   CallInst *CI = B.CreateCall(PutChar,
1032f22ef01cSRoman Divacky                               B.CreateIntCast(Char,
1033f22ef01cSRoman Divacky                               B.getInt32Ty(),
1034f22ef01cSRoman Divacky                               /*isSigned*/true,
1035f22ef01cSRoman Divacky                               "chari"),
10364ba319b5SDimitry Andric                               PutCharName);
1037f22ef01cSRoman Divacky 
1038f22ef01cSRoman Divacky   if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
1039f22ef01cSRoman Divacky     CI->setCallingConv(F->getCallingConv());
1040f22ef01cSRoman Divacky   return CI;
1041f22ef01cSRoman Divacky }
1042f22ef01cSRoman Divacky 
emitPutS(Value * Str,IRBuilder<> & B,const TargetLibraryInfo * TLI)10433ca95b02SDimitry Andric Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
10447ae0e2c9SDimitry Andric                       const TargetLibraryInfo *TLI) {
10457a7e6055SDimitry Andric   if (!TLI->has(LibFunc_puts))
104691bc56edSDimitry Andric     return nullptr;
10477ae0e2c9SDimitry Andric 
10483ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
10494ba319b5SDimitry Andric   StringRef PutsName = TLI->getName(LibFunc_puts);
10503ca95b02SDimitry Andric   Value *PutS =
10514ba319b5SDimitry Andric       M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy());
10524ba319b5SDimitry Andric   inferLibFuncAttributes(M, PutsName, *TLI);
10534ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName);
1054f22ef01cSRoman Divacky   if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
1055f22ef01cSRoman Divacky     CI->setCallingConv(F->getCallingConv());
10567ae0e2c9SDimitry Andric   return CI;
1057f22ef01cSRoman Divacky }
1058f22ef01cSRoman Divacky 
emitFPutC(Value * Char,Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)10593ca95b02SDimitry Andric Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
1060ff0cc061SDimitry Andric                        const TargetLibraryInfo *TLI) {
10617a7e6055SDimitry Andric   if (!TLI->has(LibFunc_fputc))
106291bc56edSDimitry Andric     return nullptr;
10637ae0e2c9SDimitry Andric 
10643ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
10654ba319b5SDimitry Andric   StringRef FPutcName = TLI->getName(LibFunc_fputc);
10664ba319b5SDimitry Andric   Constant *F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(), B.getInt32Ty(),
10677a7e6055SDimitry Andric                                        File->getType());
10683ca95b02SDimitry Andric   if (File->getType()->isPointerTy())
10694ba319b5SDimitry Andric     inferLibFuncAttributes(M, FPutcName, *TLI);
1070f22ef01cSRoman Divacky   Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
1071f22ef01cSRoman Divacky                          "chari");
10724ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
10734ba319b5SDimitry Andric 
10744ba319b5SDimitry Andric   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
10754ba319b5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
10764ba319b5SDimitry Andric   return CI;
10774ba319b5SDimitry Andric }
10784ba319b5SDimitry Andric 
emitFPutCUnlocked(Value * Char,Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)10794ba319b5SDimitry Andric Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
10804ba319b5SDimitry Andric                                const TargetLibraryInfo *TLI) {
10814ba319b5SDimitry Andric   if (!TLI->has(LibFunc_fputc_unlocked))
10824ba319b5SDimitry Andric     return nullptr;
10834ba319b5SDimitry Andric 
10844ba319b5SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
10854ba319b5SDimitry Andric   StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked);
10864ba319b5SDimitry Andric   Constant *F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(),
10874ba319b5SDimitry Andric                                        B.getInt32Ty(), File->getType());
10884ba319b5SDimitry Andric   if (File->getType()->isPointerTy())
10894ba319b5SDimitry Andric     inferLibFuncAttributes(M, FPutcUnlockedName, *TLI);
10904ba319b5SDimitry Andric   Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
10914ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName);
1092f22ef01cSRoman Divacky 
1093f22ef01cSRoman Divacky   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1094f22ef01cSRoman Divacky     CI->setCallingConv(Fn->getCallingConv());
10957ae0e2c9SDimitry Andric   return CI;
1096f22ef01cSRoman Divacky }
1097f22ef01cSRoman Divacky 
emitFPutS(Value * Str,Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)10983ca95b02SDimitry Andric Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
1099ff0cc061SDimitry Andric                        const TargetLibraryInfo *TLI) {
11007a7e6055SDimitry Andric   if (!TLI->has(LibFunc_fputs))
110191bc56edSDimitry Andric     return nullptr;
11027ae0e2c9SDimitry Andric 
11033ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
11047a7e6055SDimitry Andric   StringRef FPutsName = TLI->getName(LibFunc_fputs);
11053ca95b02SDimitry Andric   Constant *F = M->getOrInsertFunction(
11067a7e6055SDimitry Andric       FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType());
1107f22ef01cSRoman Divacky   if (File->getType()->isPointerTy())
11084ba319b5SDimitry Andric     inferLibFuncAttributes(M, FPutsName, *TLI);
11094ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName);
11104ba319b5SDimitry Andric 
11114ba319b5SDimitry Andric   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
11124ba319b5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
11134ba319b5SDimitry Andric   return CI;
11144ba319b5SDimitry Andric }
11154ba319b5SDimitry Andric 
emitFPutSUnlocked(Value * Str,Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)11164ba319b5SDimitry Andric Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
11174ba319b5SDimitry Andric                                const TargetLibraryInfo *TLI) {
11184ba319b5SDimitry Andric   if (!TLI->has(LibFunc_fputs_unlocked))
11194ba319b5SDimitry Andric     return nullptr;
11204ba319b5SDimitry Andric 
11214ba319b5SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
11224ba319b5SDimitry Andric   StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
11234ba319b5SDimitry Andric   Constant *F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
11244ba319b5SDimitry Andric                                        B.getInt8PtrTy(), File->getType());
11254ba319b5SDimitry Andric   if (File->getType()->isPointerTy())
11264ba319b5SDimitry Andric     inferLibFuncAttributes(M, FPutsUnlockedName, *TLI);
11274ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName);
1128f22ef01cSRoman Divacky 
1129f22ef01cSRoman Divacky   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1130f22ef01cSRoman Divacky     CI->setCallingConv(Fn->getCallingConv());
11317ae0e2c9SDimitry Andric   return CI;
1132f22ef01cSRoman Divacky }
1133f22ef01cSRoman Divacky 
emitFWrite(Value * Ptr,Value * Size,Value * File,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)11343ca95b02SDimitry Andric Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
1135ff0cc061SDimitry Andric                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
11367a7e6055SDimitry Andric   if (!TLI->has(LibFunc_fwrite))
113791bc56edSDimitry Andric     return nullptr;
11387ae0e2c9SDimitry Andric 
11393ca95b02SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
1140f22ef01cSRoman Divacky   LLVMContext &Context = B.GetInsertBlock()->getContext();
11417a7e6055SDimitry Andric   StringRef FWriteName = TLI->getName(LibFunc_fwrite);
11423ca95b02SDimitry Andric   Constant *F = M->getOrInsertFunction(
11433ca95b02SDimitry Andric       FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
11447a7e6055SDimitry Andric       DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
11457a7e6055SDimitry Andric 
11463ca95b02SDimitry Andric   if (File->getType()->isPointerTy())
11474ba319b5SDimitry Andric     inferLibFuncAttributes(M, FWriteName, *TLI);
1148ff0cc061SDimitry Andric   CallInst *CI =
11493ca95b02SDimitry Andric       B.CreateCall(F, {castToCStr(Ptr, B), Size,
1150ff0cc061SDimitry Andric                        ConstantInt::get(DL.getIntPtrType(Context), 1), File});
1151f22ef01cSRoman Divacky 
1152f22ef01cSRoman Divacky   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1153f22ef01cSRoman Divacky     CI->setCallingConv(Fn->getCallingConv());
11547ae0e2c9SDimitry Andric   return CI;
1155f22ef01cSRoman Divacky }
11564ba319b5SDimitry Andric 
emitMalloc(Value * Num,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)11574ba319b5SDimitry Andric Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
11584ba319b5SDimitry Andric                         const TargetLibraryInfo *TLI) {
11594ba319b5SDimitry Andric   if (!TLI->has(LibFunc_malloc))
11604ba319b5SDimitry Andric     return nullptr;
11614ba319b5SDimitry Andric 
11624ba319b5SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
11634ba319b5SDimitry Andric   StringRef MallocName = TLI->getName(LibFunc_malloc);
11644ba319b5SDimitry Andric   LLVMContext &Context = B.GetInsertBlock()->getContext();
11654ba319b5SDimitry Andric   Value *Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(),
11664ba319b5SDimitry Andric                                          DL.getIntPtrType(Context));
11674ba319b5SDimitry Andric   inferLibFuncAttributes(M, MallocName, *TLI);
11684ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
11694ba319b5SDimitry Andric 
11704ba319b5SDimitry Andric   if (const Function *F = dyn_cast<Function>(Malloc->stripPointerCasts()))
11714ba319b5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
11724ba319b5SDimitry Andric 
11734ba319b5SDimitry Andric   return CI;
11744ba319b5SDimitry Andric }
11754ba319b5SDimitry Andric 
emitCalloc(Value * Num,Value * Size,const AttributeList & Attrs,IRBuilder<> & B,const TargetLibraryInfo & TLI)11764ba319b5SDimitry Andric Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
11774ba319b5SDimitry Andric                         IRBuilder<> &B, const TargetLibraryInfo &TLI) {
11784ba319b5SDimitry Andric   if (!TLI.has(LibFunc_calloc))
11794ba319b5SDimitry Andric     return nullptr;
11804ba319b5SDimitry Andric 
11814ba319b5SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
11824ba319b5SDimitry Andric   StringRef CallocName = TLI.getName(LibFunc_calloc);
11834ba319b5SDimitry Andric   const DataLayout &DL = M->getDataLayout();
11844ba319b5SDimitry Andric   IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
11854ba319b5SDimitry Andric   Value *Calloc = M->getOrInsertFunction(CallocName, Attrs, B.getInt8PtrTy(),
11864ba319b5SDimitry Andric                                          PtrType, PtrType);
11874ba319b5SDimitry Andric   inferLibFuncAttributes(M, CallocName, TLI);
11884ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
11894ba319b5SDimitry Andric 
11904ba319b5SDimitry Andric   if (const auto *F = dyn_cast<Function>(Calloc->stripPointerCasts()))
11914ba319b5SDimitry Andric     CI->setCallingConv(F->getCallingConv());
11924ba319b5SDimitry Andric 
11934ba319b5SDimitry Andric   return CI;
11944ba319b5SDimitry Andric }
11954ba319b5SDimitry Andric 
emitFWriteUnlocked(Value * Ptr,Value * Size,Value * N,Value * File,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)11964ba319b5SDimitry Andric Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
11974ba319b5SDimitry Andric                                 IRBuilder<> &B, const DataLayout &DL,
11984ba319b5SDimitry Andric                                 const TargetLibraryInfo *TLI) {
11994ba319b5SDimitry Andric   if (!TLI->has(LibFunc_fwrite_unlocked))
12004ba319b5SDimitry Andric     return nullptr;
12014ba319b5SDimitry Andric 
12024ba319b5SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
12034ba319b5SDimitry Andric   LLVMContext &Context = B.GetInsertBlock()->getContext();
12044ba319b5SDimitry Andric   StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
12054ba319b5SDimitry Andric   Constant *F = M->getOrInsertFunction(
12064ba319b5SDimitry Andric       FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
12074ba319b5SDimitry Andric       DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
12084ba319b5SDimitry Andric 
12094ba319b5SDimitry Andric   if (File->getType()->isPointerTy())
12104ba319b5SDimitry Andric     inferLibFuncAttributes(M, FWriteUnlockedName, *TLI);
12114ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
12124ba319b5SDimitry Andric 
12134ba319b5SDimitry Andric   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
12144ba319b5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
12154ba319b5SDimitry Andric   return CI;
12164ba319b5SDimitry Andric }
12174ba319b5SDimitry Andric 
emitFGetCUnlocked(Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)12184ba319b5SDimitry Andric Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
12194ba319b5SDimitry Andric                                const TargetLibraryInfo *TLI) {
12204ba319b5SDimitry Andric   if (!TLI->has(LibFunc_fgetc_unlocked))
12214ba319b5SDimitry Andric     return nullptr;
12224ba319b5SDimitry Andric 
12234ba319b5SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
12244ba319b5SDimitry Andric   StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked);
12254ba319b5SDimitry Andric   Constant *F =
12264ba319b5SDimitry Andric       M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(), File->getType());
12274ba319b5SDimitry Andric   if (File->getType()->isPointerTy())
12284ba319b5SDimitry Andric     inferLibFuncAttributes(M, FGetCUnlockedName, *TLI);
12294ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName);
12304ba319b5SDimitry Andric 
12314ba319b5SDimitry Andric   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
12324ba319b5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
12334ba319b5SDimitry Andric   return CI;
12344ba319b5SDimitry Andric }
12354ba319b5SDimitry Andric 
emitFGetSUnlocked(Value * Str,Value * Size,Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)12364ba319b5SDimitry Andric Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
12374ba319b5SDimitry Andric                                IRBuilder<> &B, const TargetLibraryInfo *TLI) {
12384ba319b5SDimitry Andric   if (!TLI->has(LibFunc_fgets_unlocked))
12394ba319b5SDimitry Andric     return nullptr;
12404ba319b5SDimitry Andric 
12414ba319b5SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
12424ba319b5SDimitry Andric   StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked);
12434ba319b5SDimitry Andric   Constant *F =
12444ba319b5SDimitry Andric       M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(),
12454ba319b5SDimitry Andric                              B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
12464ba319b5SDimitry Andric   inferLibFuncAttributes(M, FGetSUnlockedName, *TLI);
12474ba319b5SDimitry Andric   CallInst *CI =
12484ba319b5SDimitry Andric       B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName);
12494ba319b5SDimitry Andric 
12504ba319b5SDimitry Andric   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
12514ba319b5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
12524ba319b5SDimitry Andric   return CI;
12534ba319b5SDimitry Andric }
12544ba319b5SDimitry Andric 
emitFReadUnlocked(Value * Ptr,Value * Size,Value * N,Value * File,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)12554ba319b5SDimitry Andric Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
12564ba319b5SDimitry Andric                                IRBuilder<> &B, const DataLayout &DL,
12574ba319b5SDimitry Andric                                const TargetLibraryInfo *TLI) {
12584ba319b5SDimitry Andric   if (!TLI->has(LibFunc_fread_unlocked))
12594ba319b5SDimitry Andric     return nullptr;
12604ba319b5SDimitry Andric 
12614ba319b5SDimitry Andric   Module *M = B.GetInsertBlock()->getModule();
12624ba319b5SDimitry Andric   LLVMContext &Context = B.GetInsertBlock()->getContext();
12634ba319b5SDimitry Andric   StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
12644ba319b5SDimitry Andric   Constant *F = M->getOrInsertFunction(
12654ba319b5SDimitry Andric       FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
12664ba319b5SDimitry Andric       DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
12674ba319b5SDimitry Andric 
12684ba319b5SDimitry Andric   if (File->getType()->isPointerTy())
12694ba319b5SDimitry Andric     inferLibFuncAttributes(M, FReadUnlockedName, *TLI);
12704ba319b5SDimitry Andric   CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
12714ba319b5SDimitry Andric 
12724ba319b5SDimitry Andric   if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
12734ba319b5SDimitry Andric     CI->setCallingConv(Fn->getCallingConv());
12744ba319b5SDimitry Andric   return CI;
12754ba319b5SDimitry Andric }
1276