blob: b782641383add83b9eaa54be294c4a0a005fb9a6 [file] [log] [blame]
Eric Christopher87abfc52010-03-05 22:25:30 +00001//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements some functions that will create standard C libcalls.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Transforms/Utils/BuildLibCalls.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000015#include "llvm/ADT/SmallString.h"
Ahmed Bougachab0624a22016-04-27 19:04:40 +000016#include "llvm/ADT/Statistic.h"
Weiming Zhao45d4cb92015-11-24 18:57:06 +000017#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000018#include "llvm/IR/Constants.h"
19#include "llvm/IR/DataLayout.h"
20#include "llvm/IR/Function.h"
21#include "llvm/IR/IRBuilder.h"
22#include "llvm/IR/Intrinsics.h"
23#include "llvm/IR/LLVMContext.h"
24#include "llvm/IR/Module.h"
25#include "llvm/IR/Type.h"
Eric Christopher87abfc52010-03-05 22:25:30 +000026
27using namespace llvm;
28
Ahmed Bougachab0624a22016-04-27 19:04:40 +000029#define DEBUG_TYPE "build-libcalls"
30
31//- Infer Attributes ---------------------------------------------------------//
32
33STATISTIC(NumReadNone, "Number of functions inferred as readnone");
34STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
35STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
36STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
37STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
38STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
39STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
40STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
David Bolvansky8715e032018-08-23 05:18:23 +000041STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
Ahmed Bougachab0624a22016-04-27 19:04:40 +000042
43static bool setDoesNotAccessMemory(Function &F) {
44 if (F.doesNotAccessMemory())
45 return false;
46 F.setDoesNotAccessMemory();
47 ++NumReadNone;
48 return true;
49}
50
51static bool setOnlyReadsMemory(Function &F) {
52 if (F.onlyReadsMemory())
53 return false;
54 F.setOnlyReadsMemory();
55 ++NumReadOnly;
56 return true;
57}
58
59static bool setOnlyAccessesArgMemory(Function &F) {
60 if (F.onlyAccessesArgMemory())
61 return false;
Reid Klecknera0b45f42017-05-03 18:17:31 +000062 F.setOnlyAccessesArgMemory();
Ahmed Bougachab0624a22016-04-27 19:04:40 +000063 ++NumArgMemOnly;
64 return true;
65}
66
67static bool setDoesNotThrow(Function &F) {
68 if (F.doesNotThrow())
69 return false;
70 F.setDoesNotThrow();
71 ++NumNoUnwind;
72 return true;
73}
74
Reid Klecknera0b45f42017-05-03 18:17:31 +000075static bool setRetDoesNotAlias(Function &F) {
76 if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias))
Ahmed Bougachab0624a22016-04-27 19:04:40 +000077 return false;
Reid Klecknera0b45f42017-05-03 18:17:31 +000078 F.addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
Ahmed Bougachab0624a22016-04-27 19:04:40 +000079 ++NumNoAlias;
80 return true;
81}
82
Reid Klecknera0b45f42017-05-03 18:17:31 +000083static bool setDoesNotCapture(Function &F, unsigned ArgNo) {
84 if (F.hasParamAttribute(ArgNo, Attribute::NoCapture))
Ahmed Bougachab0624a22016-04-27 19:04:40 +000085 return false;
Reid Klecknera0b45f42017-05-03 18:17:31 +000086 F.addParamAttr(ArgNo, Attribute::NoCapture);
87 ++NumNoCapture;
88 return true;
89}
90
91static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
92 if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))
93 return false;
94 F.addParamAttr(ArgNo, Attribute::ReadOnly);
95 ++NumReadOnlyArg;
96 return true;
97}
98
99static bool setRetNonNull(Function &F) {
100 assert(F.getReturnType()->isPointerTy() &&
101 "nonnull applies only to pointers");
102 if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull))
103 return false;
104 F.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000105 ++NumNonNull;
106 return true;
107}
108
David Bolvansky8715e032018-08-23 05:18:23 +0000109static bool setReturnedArg(Function &F, unsigned ArgNo) {
110 if (F.hasParamAttribute(ArgNo, Attribute::Returned))
111 return false;
112 F.addParamAttr(ArgNo, Attribute::Returned);
113 ++NumReturnedArg;
114 return true;
115}
116
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000117static bool setNonLazyBind(Function &F) {
118 if (F.hasFnAttribute(Attribute::NonLazyBind))
119 return false;
120 F.addFnAttr(Attribute::NonLazyBind);
121 return true;
122}
123
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000124bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000125 LibFunc TheLibFunc;
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000126 if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
127 return false;
128
129 bool Changed = false;
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000130
131 if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
132 Changed |= setNonLazyBind(F);
133
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000134 switch (TheLibFunc) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000135 case LibFunc_strlen:
Matthias Braun60b40b82017-05-05 20:25:50 +0000136 case LibFunc_wcslen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000137 Changed |= setOnlyReadsMemory(F);
138 Changed |= setDoesNotThrow(F);
Xin Tong9d2a5b12017-06-18 03:10:26 +0000139 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000140 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000141 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000142 case LibFunc_strchr:
143 case LibFunc_strrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000144 Changed |= setOnlyReadsMemory(F);
145 Changed |= setDoesNotThrow(F);
146 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000147 case LibFunc_strtol:
148 case LibFunc_strtod:
149 case LibFunc_strtof:
150 case LibFunc_strtoul:
151 case LibFunc_strtoll:
152 case LibFunc_strtold:
153 case LibFunc_strtoull:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000154 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000155 Changed |= setDoesNotCapture(F, 1);
156 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000157 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000158 case LibFunc_strcpy:
David Bolvansky8715e032018-08-23 05:18:23 +0000159 case LibFunc_strncpy:
David L. Jonesd21529f2017-01-23 23:16:46 +0000160 case LibFunc_strcat:
161 case LibFunc_strncat:
David Bolvansky8715e032018-08-23 05:18:23 +0000162 Changed |= setReturnedArg(F, 0);
163 LLVM_FALLTHROUGH;
164 case LibFunc_stpcpy:
David L. Jonesd21529f2017-01-23 23:16:46 +0000165 case LibFunc_stpncpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000166 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000167 Changed |= setDoesNotCapture(F, 1);
168 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000169 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000170 case LibFunc_strxfrm:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000171 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000172 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000173 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000174 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000175 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000176 case LibFunc_strcmp: // 0,1
177 case LibFunc_strspn: // 0,1
178 case LibFunc_strncmp: // 0,1
179 case LibFunc_strcspn: // 0,1
180 case LibFunc_strcoll: // 0,1
181 case LibFunc_strcasecmp: // 0,1
182 case LibFunc_strncasecmp: //
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000183 Changed |= setOnlyReadsMemory(F);
184 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000185 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000186 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000187 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000188 case LibFunc_strstr:
189 case LibFunc_strpbrk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000190 Changed |= setOnlyReadsMemory(F);
191 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000192 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000193 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000194 case LibFunc_strtok:
195 case LibFunc_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000196 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000197 Changed |= setDoesNotCapture(F, 1);
198 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000199 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000200 case LibFunc_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000201 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000202 Changed |= setDoesNotCapture(F, 0);
203 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000204 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000205 case LibFunc_setbuf:
206 case LibFunc_setvbuf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000207 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000208 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000209 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000210 case LibFunc_strdup:
211 case LibFunc_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000212 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000213 Changed |= setRetDoesNotAlias(F);
214 Changed |= setDoesNotCapture(F, 0);
215 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000216 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000217 case LibFunc_stat:
218 case LibFunc_statvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000219 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000220 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000221 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000222 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000223 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000224 case LibFunc_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000225 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000226 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000227 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000228 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000229 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000230 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000231 case LibFunc_sprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000232 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000233 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000234 Changed |= setDoesNotCapture(F, 1);
235 Changed |= setOnlyReadsMemory(F, 1);
236 return Changed;
Reid Klecknera0b45f42017-05-03 18:17:31 +0000237 case LibFunc_snprintf:
238 Changed |= setDoesNotThrow(F);
239 Changed |= setDoesNotCapture(F, 0);
240 Changed |= setDoesNotCapture(F, 2);
241 Changed |= setOnlyReadsMemory(F, 2);
242 return Changed;
243 case LibFunc_setitimer:
244 Changed |= setDoesNotThrow(F);
245 Changed |= setDoesNotCapture(F, 1);
246 Changed |= setDoesNotCapture(F, 2);
247 Changed |= setOnlyReadsMemory(F, 1);
248 return Changed;
249 case LibFunc_system:
250 // May throw; "system" is a valid pthread cancellation point.
251 Changed |= setDoesNotCapture(F, 0);
252 Changed |= setOnlyReadsMemory(F, 0);
253 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000254 case LibFunc_malloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000255 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000256 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000257 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000258 case LibFunc_memcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000259 Changed |= setOnlyReadsMemory(F);
260 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000261 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000262 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000263 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000264 case LibFunc_memchr:
265 case LibFunc_memrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000266 Changed |= setOnlyReadsMemory(F);
267 Changed |= setDoesNotThrow(F);
268 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000269 case LibFunc_modf:
270 case LibFunc_modff:
271 case LibFunc_modfl:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000272 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000273 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000274 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000275 case LibFunc_memcpy:
David Bolvansky8715e032018-08-23 05:18:23 +0000276 case LibFunc_memmove:
277 Changed |= setReturnedArg(F, 0);
278 LLVM_FALLTHROUGH;
David L. Jonesd21529f2017-01-23 23:16:46 +0000279 case LibFunc_mempcpy:
280 case LibFunc_memccpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000281 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000282 Changed |= setDoesNotCapture(F, 1);
283 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000284 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000285 case LibFunc_memcpy_chk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000286 Changed |= setDoesNotThrow(F);
287 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000288 case LibFunc_memalign:
Reid Klecknera0b45f42017-05-03 18:17:31 +0000289 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000290 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000291 case LibFunc_mkdir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000292 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000293 Changed |= setDoesNotCapture(F, 0);
294 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000295 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000296 case LibFunc_mktime:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000297 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000298 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000299 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000300 case LibFunc_realloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000301 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000302 Changed |= setRetDoesNotAlias(F);
303 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000304 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000305 case LibFunc_read:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000306 // May throw; "read" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000307 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000308 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000309 case LibFunc_rewind:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000310 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000311 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000312 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000313 case LibFunc_rmdir:
314 case LibFunc_remove:
315 case LibFunc_realpath:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000316 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000317 Changed |= setDoesNotCapture(F, 0);
318 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000319 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000320 case LibFunc_rename:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000321 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000322 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000323 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000324 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000325 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000326 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000327 case LibFunc_readlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000328 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000329 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000330 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000331 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000332 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000333 case LibFunc_write:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000334 // May throw; "write" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000335 Changed |= setDoesNotCapture(F, 1);
336 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000337 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000338 case LibFunc_bcopy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000339 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000340 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000341 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000342 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000343 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000344 case LibFunc_bcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000345 Changed |= setDoesNotThrow(F);
346 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000347 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000348 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000349 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000350 case LibFunc_bzero:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000351 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000352 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000353 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000354 case LibFunc_calloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000355 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000356 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000357 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000358 case LibFunc_chmod:
359 case LibFunc_chown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000360 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000361 Changed |= setDoesNotCapture(F, 0);
362 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000363 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000364 case LibFunc_ctermid:
365 case LibFunc_clearerr:
366 case LibFunc_closedir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000367 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000368 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000369 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000370 case LibFunc_atoi:
371 case LibFunc_atol:
372 case LibFunc_atof:
373 case LibFunc_atoll:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000374 Changed |= setDoesNotThrow(F);
375 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000376 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000377 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000378 case LibFunc_access:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000379 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000380 Changed |= setDoesNotCapture(F, 0);
381 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000382 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000383 case LibFunc_fopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000384 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000385 Changed |= setRetDoesNotAlias(F);
386 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000387 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000388 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000389 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000390 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000391 case LibFunc_fdopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000392 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000393 Changed |= setRetDoesNotAlias(F);
394 Changed |= setDoesNotCapture(F, 1);
395 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000396 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000397 case LibFunc_feof:
398 case LibFunc_free:
399 case LibFunc_fseek:
400 case LibFunc_ftell:
401 case LibFunc_fgetc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000402 case LibFunc_fgetc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000403 case LibFunc_fseeko:
404 case LibFunc_ftello:
405 case LibFunc_fileno:
406 case LibFunc_fflush:
407 case LibFunc_fclose:
408 case LibFunc_fsetpos:
409 case LibFunc_flockfile:
410 case LibFunc_funlockfile:
411 case LibFunc_ftrylockfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000412 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000413 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000414 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000415 case LibFunc_ferror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000416 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000417 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000418 Changed |= setOnlyReadsMemory(F);
419 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000420 case LibFunc_fputc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000421 case LibFunc_fputc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000422 case LibFunc_fstat:
423 case LibFunc_frexp:
424 case LibFunc_frexpf:
425 case LibFunc_frexpl:
426 case LibFunc_fstatvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000427 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000428 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000429 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000430 case LibFunc_fgets:
David Bolvanskyca22d422018-05-16 11:39:52 +0000431 case LibFunc_fgets_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000432 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000433 Changed |= setDoesNotCapture(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000434 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000435 case LibFunc_fread:
David Bolvanskyca22d422018-05-16 11:39:52 +0000436 case LibFunc_fread_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000437 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000438 Changed |= setDoesNotCapture(F, 0);
439 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000440 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000441 case LibFunc_fwrite:
David Bolvanskyca22d422018-05-16 11:39:52 +0000442 case LibFunc_fwrite_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000443 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000444 Changed |= setDoesNotCapture(F, 0);
445 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000446 // FIXME: readonly #1?
447 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000448 case LibFunc_fputs:
David Bolvanskyca22d422018-05-16 11:39:52 +0000449 case LibFunc_fputs_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000450 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000451 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000452 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000453 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000454 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000455 case LibFunc_fscanf:
456 case LibFunc_fprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000457 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000458 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000459 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000460 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000461 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000462 case LibFunc_fgetpos:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000463 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000464 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000465 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000466 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000467 case LibFunc_getc:
468 case LibFunc_getlogin_r:
469 case LibFunc_getc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000470 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000471 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000472 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000473 case LibFunc_getenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000474 Changed |= setDoesNotThrow(F);
475 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000476 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000477 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000478 case LibFunc_gets:
479 case LibFunc_getchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000480 case LibFunc_getchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000481 Changed |= setDoesNotThrow(F);
482 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000483 case LibFunc_getitimer:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000484 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000485 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000486 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000487 case LibFunc_getpwnam:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000488 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000489 Changed |= setDoesNotCapture(F, 0);
490 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000491 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000492 case LibFunc_ungetc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000493 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000494 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000495 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000496 case LibFunc_uname:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000497 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000498 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000499 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000500 case LibFunc_unlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000501 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000502 Changed |= setDoesNotCapture(F, 0);
503 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000504 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000505 case LibFunc_unsetenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000506 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000507 Changed |= setDoesNotCapture(F, 0);
508 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000509 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000510 case LibFunc_utime:
511 case LibFunc_utimes:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000512 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000513 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000514 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000515 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000516 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000517 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000518 case LibFunc_putc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000519 case LibFunc_putc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000520 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000521 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000522 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000523 case LibFunc_puts:
524 case LibFunc_printf:
525 case LibFunc_perror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000526 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000527 Changed |= setDoesNotCapture(F, 0);
528 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000529 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000530 case LibFunc_pread:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000531 // May throw; "pread" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000532 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000533 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000534 case LibFunc_pwrite:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000535 // May throw; "pwrite" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000536 Changed |= setDoesNotCapture(F, 1);
537 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000538 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000539 case LibFunc_putchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000540 case LibFunc_putchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000541 Changed |= setDoesNotThrow(F);
542 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000543 case LibFunc_popen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000544 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000545 Changed |= setRetDoesNotAlias(F);
546 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000547 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000548 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000549 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000550 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000551 case LibFunc_pclose:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000552 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000553 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000554 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000555 case LibFunc_vscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000556 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000557 Changed |= setDoesNotCapture(F, 0);
558 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000559 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000560 case LibFunc_vsscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000561 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000562 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000563 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000564 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000565 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000566 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000567 case LibFunc_vfscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000568 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000569 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000570 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000571 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000572 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000573 case LibFunc_valloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000574 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000575 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000576 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000577 case LibFunc_vprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000578 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000579 Changed |= setDoesNotCapture(F, 0);
580 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000581 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000582 case LibFunc_vfprintf:
583 case LibFunc_vsprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000584 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000585 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000586 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000587 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000588 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000589 case LibFunc_vsnprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000590 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000591 Changed |= setDoesNotCapture(F, 0);
592 Changed |= setDoesNotCapture(F, 2);
593 Changed |= setOnlyReadsMemory(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000594 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000595 case LibFunc_open:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000596 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000597 Changed |= setDoesNotCapture(F, 0);
598 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000599 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000600 case LibFunc_opendir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000601 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000602 Changed |= setRetDoesNotAlias(F);
603 Changed |= setDoesNotCapture(F, 0);
604 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000605 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000606 case LibFunc_tmpfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000607 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000608 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000609 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000610 case LibFunc_times:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000611 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000612 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000613 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000614 case LibFunc_htonl:
615 case LibFunc_htons:
616 case LibFunc_ntohl:
617 case LibFunc_ntohs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000618 Changed |= setDoesNotThrow(F);
619 Changed |= setDoesNotAccessMemory(F);
620 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000621 case LibFunc_lstat:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000622 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000623 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000624 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000625 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000626 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000627 case LibFunc_lchown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000628 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000629 Changed |= setDoesNotCapture(F, 0);
630 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000631 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000632 case LibFunc_qsort:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000633 // May throw; places call through function pointer.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000634 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000635 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000636 case LibFunc_dunder_strdup:
637 case LibFunc_dunder_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000638 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000639 Changed |= setRetDoesNotAlias(F);
640 Changed |= setDoesNotCapture(F, 0);
641 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000642 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000643 case LibFunc_dunder_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000644 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000645 Changed |= setDoesNotCapture(F, 1);
646 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000647 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000648 case LibFunc_under_IO_getc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000649 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000650 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000651 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000652 case LibFunc_under_IO_putc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000653 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000654 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000655 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000656 case LibFunc_dunder_isoc99_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000657 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000658 Changed |= setDoesNotCapture(F, 0);
659 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000660 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000661 case LibFunc_stat64:
662 case LibFunc_lstat64:
663 case LibFunc_statvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000664 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000665 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000666 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000667 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000668 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000669 case LibFunc_dunder_isoc99_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000670 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000671 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000672 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000673 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000674 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000675 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000676 case LibFunc_fopen64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000677 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000678 Changed |= setRetDoesNotAlias(F);
679 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000680 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000681 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000682 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000683 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000684 case LibFunc_fseeko64:
685 case LibFunc_ftello64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000686 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000687 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000688 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000689 case LibFunc_tmpfile64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000690 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000691 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000692 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000693 case LibFunc_fstat64:
694 case LibFunc_fstatvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000695 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000696 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000697 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000698 case LibFunc_open64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000699 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000700 Changed |= setDoesNotCapture(F, 0);
701 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000702 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000703 case LibFunc_gettimeofday:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000704 // Currently some platforms have the restrict keyword on the arguments to
705 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
706 // arguments.
707 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000708 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000709 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000710 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000711 case LibFunc_Znwj: // new(unsigned int)
712 case LibFunc_Znwm: // new(unsigned long)
713 case LibFunc_Znaj: // new[](unsigned int)
714 case LibFunc_Znam: // new[](unsigned long)
715 case LibFunc_msvc_new_int: // new(unsigned int)
716 case LibFunc_msvc_new_longlong: // new(unsigned long long)
717 case LibFunc_msvc_new_array_int: // new[](unsigned int)
718 case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000719 // Operator new always returns a nonnull noalias pointer
Reid Klecknera0b45f42017-05-03 18:17:31 +0000720 Changed |= setRetNonNull(F);
721 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000722 return Changed;
David Bolvansky3ea50f92018-04-25 04:33:36 +0000723 // TODO: add LibFunc entries for:
724 // case LibFunc_memset_pattern4:
725 // case LibFunc_memset_pattern8:
David L. Jonesd21529f2017-01-23 23:16:46 +0000726 case LibFunc_memset_pattern16:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000727 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000728 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougacha44c19872016-04-27 19:04:43 +0000729 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000730 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000731 return Changed;
732 // int __nvvm_reflect(const char *)
David L. Jonesd21529f2017-01-23 23:16:46 +0000733 case LibFunc_nvvm_reflect:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000734 Changed |= setDoesNotAccessMemory(F);
735 Changed |= setDoesNotThrow(F);
736 return Changed;
737
738 default:
739 // FIXME: It'd be really nice to cover all the library functions we're
740 // aware of here.
741 return false;
742 }
743}
744
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000745bool llvm::hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
746 LibFunc DoubleFn, LibFunc FloatFn,
747 LibFunc LongDoubleFn) {
748 switch (Ty->getTypeID()) {
749 case Type::FloatTyID:
750 return TLI->has(FloatFn);
751 case Type::DoubleTyID:
752 return TLI->has(DoubleFn);
753 default:
754 return TLI->has(LongDoubleFn);
755 }
756}
757
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000758//- Emit LibCalls ------------------------------------------------------------//
759
Sanjay Pateld3112a52016-01-19 19:46:10 +0000760Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
Matt Arsenaultbe558882014-04-23 20:58:57 +0000761 unsigned AS = V->getType()->getPointerAddressSpace();
762 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
Eric Christopher87abfc52010-03-05 22:25:30 +0000763}
764
Sanjay Pateld3112a52016-01-19 19:46:10 +0000765Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000766 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000767 if (!TLI->has(LibFunc_strlen))
Craig Topperf40110f2014-04-25 05:29:35 +0000768 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000769
Sanjay Pateld4af2972016-01-19 19:58:49 +0000770 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000771 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000772 Constant *StrLen = M->getOrInsertFunction("strlen", DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000773 B.getInt8PtrTy());
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000774 inferLibFuncAttributes(*M->getFunction("strlen"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000775 CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), "strlen");
Evan Chengad6efbf2014-03-12 18:09:37 +0000776 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
777 CI->setCallingConv(F->getCallingConv());
778
Eric Christopher87abfc52010-03-05 22:25:30 +0000779 return CI;
780}
781
Sanjay Pateld3112a52016-01-19 19:46:10 +0000782Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000783 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000784 if (!TLI->has(LibFunc_strchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000785 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000786
Sanjay Pateld4af2972016-01-19 19:58:49 +0000787 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000788 Type *I8Ptr = B.getInt8PtrTy();
789 Type *I32Ty = B.getInt32Ty();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000790 Constant *StrChr =
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000791 M->getOrInsertFunction("strchr", I8Ptr, I8Ptr, I32Ty);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000792 inferLibFuncAttributes(*M->getFunction("strchr"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000793 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000794 StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, "strchr");
Evan Chengad6efbf2014-03-12 18:09:37 +0000795 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
796 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000797 return CI;
798}
799
Sanjay Pateld3112a52016-01-19 19:46:10 +0000800Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000801 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000802 if (!TLI->has(LibFunc_strncmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000803 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000804
Sanjay Pateld4af2972016-01-19 19:58:49 +0000805 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000806 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000807 Value *StrNCmp = M->getOrInsertFunction("strncmp", B.getInt32Ty(),
808 B.getInt8PtrTy(), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000809 DL.getIntPtrType(Context));
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000810 inferLibFuncAttributes(*M->getFunction("strncmp"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000811 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000812 StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "strncmp");
Evan Chengad6efbf2014-03-12 18:09:37 +0000813
814 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
815 CI->setCallingConv(F->getCallingConv());
816
Benjamin Kramer11188602010-06-15 21:34:25 +0000817 return CI;
818}
819
Sanjay Pateld3112a52016-01-19 19:46:10 +0000820Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000821 const TargetLibraryInfo *TLI, StringRef Name) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000822 if (!TLI->has(LibFunc_strcpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000823 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000824
Sanjay Pateld4af2972016-01-19 19:58:49 +0000825 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000826 Type *I8Ptr = B.getInt8PtrTy();
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000827 Value *StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000828 inferLibFuncAttributes(*M->getFunction(Name), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000829 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +0000830 B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
Evan Chengad6efbf2014-03-12 18:09:37 +0000831 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
832 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000833 return CI;
834}
835
Sanjay Pateld3112a52016-01-19 19:46:10 +0000836Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000837 const TargetLibraryInfo *TLI, StringRef Name) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000838 if (!TLI->has(LibFunc_strncpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000839 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000840
Sanjay Pateld4af2972016-01-19 19:58:49 +0000841 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000842 Type *I8Ptr = B.getInt8PtrTy();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000843 Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr,
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000844 Len->getType());
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000845 inferLibFuncAttributes(*M->getFunction(Name), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000846 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000847 StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, "strncpy");
Evan Chengad6efbf2014-03-12 18:09:37 +0000848 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
849 CI->setCallingConv(F->getCallingConv());
Eric Christopher43dc11c2010-03-11 01:25:07 +0000850 return CI;
851}
852
Sanjay Pateld3112a52016-01-19 19:46:10 +0000853Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000854 IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000855 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000856 if (!TLI->has(LibFunc_memcpy_chk))
Craig Topperf40110f2014-04-25 05:29:35 +0000857 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000858
Sanjay Pateld4af2972016-01-19 19:58:49 +0000859 Module *M = B.GetInsertBlock()->getModule();
Reid Klecknerb5180542017-03-21 16:57:19 +0000860 AttributeList AS;
861 AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
862 Attribute::NoUnwind);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000863 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000864 Value *MemCpy = M->getOrInsertFunction(
Reid Klecknerb5180542017-03-21 16:57:19 +0000865 "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000866 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000867 DL.getIntPtrType(Context));
Sanjay Pateld3112a52016-01-19 19:46:10 +0000868 Dst = castToCStr(Dst, B);
869 Src = castToCStr(Src, B);
David Blaikieff6409d2015-05-18 22:13:54 +0000870 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
Evan Chengad6efbf2014-03-12 18:09:37 +0000871 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
872 CI->setCallingConv(F->getCallingConv());
Evan Chengd9e82232010-03-23 15:48:04 +0000873 return CI;
874}
875
Sanjay Pateld3112a52016-01-19 19:46:10 +0000876Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000877 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000878 if (!TLI->has(LibFunc_memchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000879 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000880
Sanjay Pateld4af2972016-01-19 19:58:49 +0000881 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000882 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000883 Value *MemChr = M->getOrInsertFunction("memchr", B.getInt8PtrTy(),
884 B.getInt8PtrTy(), B.getInt32Ty(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000885 DL.getIntPtrType(Context));
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000886 inferLibFuncAttributes(*M->getFunction("memchr"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000887 CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, "memchr");
Evan Chengad6efbf2014-03-12 18:09:37 +0000888
889 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
890 CI->setCallingConv(F->getCallingConv());
891
Eric Christopher87abfc52010-03-05 22:25:30 +0000892 return CI;
893}
894
Sanjay Pateld3112a52016-01-19 19:46:10 +0000895Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000896 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000897 if (!TLI->has(LibFunc_memcmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000898 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000899
Sanjay Pateld4af2972016-01-19 19:58:49 +0000900 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000901 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000902 Value *MemCmp = M->getOrInsertFunction("memcmp", B.getInt32Ty(),
903 B.getInt8PtrTy(), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000904 DL.getIntPtrType(Context));
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000905 inferLibFuncAttributes(*M->getFunction("memcmp"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000906 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000907 MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "memcmp");
Evan Chengad6efbf2014-03-12 18:09:37 +0000908
909 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
910 CI->setCallingConv(F->getCallingConv());
911
Eric Christopher87abfc52010-03-05 22:25:30 +0000912 return CI;
913}
914
Yi Jiang6ab044e2013-12-16 22:42:40 +0000915/// Append a suffix to the function name according to the type of 'Op'.
Sanjay Pateld3112a52016-01-19 19:46:10 +0000916static void appendTypeSuffix(Value *Op, StringRef &Name,
Sanjay Patelb50325e2016-01-19 19:17:47 +0000917 SmallString<20> &NameBuffer) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000918 if (!Op->getType()->isDoubleTy()) {
919 NameBuffer += Name;
920
921 if (Op->getType()->isFloatTy())
922 NameBuffer += 'f';
923 else
924 NameBuffer += 'l';
925
926 Name = NameBuffer;
Fangrui Songf78650a2018-07-30 19:41:25 +0000927 }
Yi Jiang6ab044e2013-12-16 22:42:40 +0000928}
929
Sanjay Pateld3112a52016-01-19 19:46:10 +0000930Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
Reid Klecknerb5180542017-03-21 16:57:19 +0000931 const AttributeList &Attrs) {
Benjamin Kramerb106bcc2011-11-15 19:12:09 +0000932 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +0000933 appendTypeSuffix(Op, Name, NameBuffer);
Eric Christopher87abfc52010-03-05 22:25:30 +0000934
Sanjay Pateld4af2972016-01-19 19:58:49 +0000935 Module *M = B.GetInsertBlock()->getModule();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000936 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000937 Op->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +0000938 CallInst *CI = B.CreateCall(Callee, Op, Name);
Matt Arsenault6a288c12017-05-03 02:26:10 +0000939
940 // The incoming attribute set may have come from a speculatable intrinsic, but
941 // is being replaced with a library call which is not allowed to be
942 // speculatable.
943 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
944 AttributeList::FunctionIndex,
945 Attribute::Speculatable));
Evan Chengad6efbf2014-03-12 18:09:37 +0000946 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
947 CI->setCallingConv(F->getCallingConv());
948
Eric Christopher87abfc52010-03-05 22:25:30 +0000949 return CI;
950}
951
Sanjay Pateld3112a52016-01-19 19:46:10 +0000952Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
Reid Klecknerb5180542017-03-21 16:57:19 +0000953 IRBuilder<> &B, const AttributeList &Attrs) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000954 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +0000955 appendTypeSuffix(Op1, Name, NameBuffer);
Yi Jiang6ab044e2013-12-16 22:42:40 +0000956
Sanjay Pateld4af2972016-01-19 19:58:49 +0000957 Module *M = B.GetInsertBlock()->getModule();
Sanjay Patelb50325e2016-01-19 19:17:47 +0000958 Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000959 Op2->getType());
David Blaikieff6409d2015-05-18 22:13:54 +0000960 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
Yi Jiang6ab044e2013-12-16 22:42:40 +0000961 CI->setAttributes(Attrs);
Evan Chengad6efbf2014-03-12 18:09:37 +0000962 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
963 CI->setCallingConv(F->getCallingConv());
964
Yi Jiang6ab044e2013-12-16 22:42:40 +0000965 return CI;
966}
967
Sanjay Pateld3112a52016-01-19 19:46:10 +0000968Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000969 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000970 if (!TLI->has(LibFunc_putchar))
Craig Topperf40110f2014-04-25 05:29:35 +0000971 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000972
Sanjay Pateld4af2972016-01-19 19:58:49 +0000973 Module *M = B.GetInsertBlock()->getModule();
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000974 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(), B.getInt32Ty());
Craig Topper0f5063c2017-03-17 23:48:02 +0000975 inferLibFuncAttributes(*M->getFunction("putchar"), *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000976 CallInst *CI = B.CreateCall(PutChar,
977 B.CreateIntCast(Char,
978 B.getInt32Ty(),
979 /*isSigned*/true,
980 "chari"),
981 "putchar");
Evan Chengad6efbf2014-03-12 18:09:37 +0000982
983 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
984 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000985 return CI;
986}
987
Sanjay Pateld3112a52016-01-19 19:46:10 +0000988Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000989 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000990 if (!TLI->has(LibFunc_puts))
Craig Topperf40110f2014-04-25 05:29:35 +0000991 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000992
Sanjay Pateld4af2972016-01-19 19:58:49 +0000993 Module *M = B.GetInsertBlock()->getModule();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000994 Value *PutS =
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000995 M->getOrInsertFunction("puts", B.getInt32Ty(), B.getInt8PtrTy());
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000996 inferLibFuncAttributes(*M->getFunction("puts"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000997 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), "puts");
Evan Chengad6efbf2014-03-12 18:09:37 +0000998 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
999 CI->setCallingConv(F->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001000 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001001}
1002
Sanjay Pateld3112a52016-01-19 19:46:10 +00001003Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001004 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001005 if (!TLI->has(LibFunc_fputc))
Craig Topperf40110f2014-04-25 05:29:35 +00001006 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001007
Sanjay Pateld4af2972016-01-19 19:58:49 +00001008 Module *M = B.GetInsertBlock()->getModule();
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001009 Constant *F = M->getOrInsertFunction("fputc", B.getInt32Ty(), B.getInt32Ty(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001010 File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001011 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001012 inferLibFuncAttributes(*M->getFunction("fputc"), *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001013 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
1014 "chari");
David Blaikieff6409d2015-05-18 22:13:54 +00001015 CallInst *CI = B.CreateCall(F, {Char, File}, "fputc");
Evan Chengad6efbf2014-03-12 18:09:37 +00001016
1017 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1018 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001019 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001020}
1021
David Bolvanskyca22d422018-05-16 11:39:52 +00001022Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
1023 const TargetLibraryInfo *TLI) {
1024 if (!TLI->has(LibFunc_fputc_unlocked))
1025 return nullptr;
1026
1027 Module *M = B.GetInsertBlock()->getModule();
1028 Constant *F = M->getOrInsertFunction("fputc_unlocked", B.getInt32Ty(),
1029 B.getInt32Ty(), File->getType());
1030 if (File->getType()->isPointerTy())
1031 inferLibFuncAttributes(*M->getFunction("fputc_unlocked"), *TLI);
1032 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
1033 CallInst *CI = B.CreateCall(F, {Char, File}, "fputc_unlocked");
1034
1035 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1036 CI->setCallingConv(Fn->getCallingConv());
1037 return CI;
1038}
1039
Sanjay Pateld3112a52016-01-19 19:46:10 +00001040Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001041 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001042 if (!TLI->has(LibFunc_fputs))
Craig Topperf40110f2014-04-25 05:29:35 +00001043 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001044
Sanjay Pateld4af2972016-01-19 19:58:49 +00001045 Module *M = B.GetInsertBlock()->getModule();
David L. Jonesd21529f2017-01-23 23:16:46 +00001046 StringRef FPutsName = TLI->getName(LibFunc_fputs);
Mehdi Aminidb11fdf2017-04-06 20:23:57 +00001047 Constant *F = M->getOrInsertFunction(
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001048 FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001049 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001050 inferLibFuncAttributes(*M->getFunction(FPutsName), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +00001051 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs");
Evan Chengad6efbf2014-03-12 18:09:37 +00001052
1053 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1054 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001055 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001056}
1057
David Bolvanskyca22d422018-05-16 11:39:52 +00001058Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
1059 const TargetLibraryInfo *TLI) {
1060 if (!TLI->has(LibFunc_fputs_unlocked))
1061 return nullptr;
1062
1063 Module *M = B.GetInsertBlock()->getModule();
1064 StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
1065 Constant *F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
1066 B.getInt8PtrTy(), File->getType());
1067 if (File->getType()->isPointerTy())
1068 inferLibFuncAttributes(*M->getFunction(FPutsUnlockedName), *TLI);
1069 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs_unlocked");
1070
1071 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1072 CI->setCallingConv(Fn->getCallingConv());
1073 return CI;
1074}
1075
Sanjay Pateld3112a52016-01-19 19:46:10 +00001076Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001077 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001078 if (!TLI->has(LibFunc_fwrite))
Craig Topperf40110f2014-04-25 05:29:35 +00001079 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001080
Sanjay Pateld4af2972016-01-19 19:58:49 +00001081 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +00001082 LLVMContext &Context = B.GetInsertBlock()->getContext();
David L. Jonesd21529f2017-01-23 23:16:46 +00001083 StringRef FWriteName = TLI->getName(LibFunc_fwrite);
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001084 Constant *F = M->getOrInsertFunction(
1085 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001086 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1087
Eric Christopher87abfc52010-03-05 22:25:30 +00001088 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001089 inferLibFuncAttributes(*M->getFunction(FWriteName), *TLI);
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001090 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +00001091 B.CreateCall(F, {castToCStr(Ptr, B), Size,
David Blaikieff6409d2015-05-18 22:13:54 +00001092 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
Evan Chengad6efbf2014-03-12 18:09:37 +00001093
1094 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1095 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001096 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001097}
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001098
1099Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
1100 const TargetLibraryInfo *TLI) {
1101 if (!TLI->has(LibFunc_malloc))
1102 return nullptr;
1103
1104 Module *M = B.GetInsertBlock()->getModule();
1105 LLVMContext &Context = B.GetInsertBlock()->getContext();
1106 Value *Malloc = M->getOrInsertFunction("malloc", B.getInt8PtrTy(),
1107 DL.getIntPtrType(Context));
1108 inferLibFuncAttributes(*M->getFunction("malloc"), *TLI);
1109 CallInst *CI = B.CreateCall(Malloc, Num, "malloc");
1110
1111 if (const Function *F = dyn_cast<Function>(Malloc->stripPointerCasts()))
1112 CI->setCallingConv(F->getCallingConv());
1113
1114 return CI;
1115}
1116
1117Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
1118 IRBuilder<> &B, const TargetLibraryInfo &TLI) {
1119 if (!TLI.has(LibFunc_calloc))
1120 return nullptr;
1121
1122 Module *M = B.GetInsertBlock()->getModule();
1123 const DataLayout &DL = M->getDataLayout();
1124 IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
1125 Value *Calloc = M->getOrInsertFunction("calloc", Attrs, B.getInt8PtrTy(),
1126 PtrType, PtrType);
1127 inferLibFuncAttributes(*M->getFunction("calloc"), TLI);
1128 CallInst *CI = B.CreateCall(Calloc, {Num, Size}, "calloc");
1129
1130 if (const auto *F = dyn_cast<Function>(Calloc->stripPointerCasts()))
1131 CI->setCallingConv(F->getCallingConv());
1132
1133 return CI;
1134}
David Bolvanskyca22d422018-05-16 11:39:52 +00001135
1136Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1137 IRBuilder<> &B, const DataLayout &DL,
1138 const TargetLibraryInfo *TLI) {
1139 if (!TLI->has(LibFunc_fwrite_unlocked))
1140 return nullptr;
1141
1142 Module *M = B.GetInsertBlock()->getModule();
1143 LLVMContext &Context = B.GetInsertBlock()->getContext();
1144 StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
1145 Constant *F = M->getOrInsertFunction(
1146 FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1147 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1148
1149 if (File->getType()->isPointerTy())
1150 inferLibFuncAttributes(*M->getFunction(FWriteUnlockedName), *TLI);
1151 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1152
1153 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1154 CI->setCallingConv(Fn->getCallingConv());
1155 return CI;
1156}
1157
1158Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
1159 const TargetLibraryInfo *TLI) {
1160 if (!TLI->has(LibFunc_fgetc_unlocked))
1161 return nullptr;
1162
1163 Module *M = B.GetInsertBlock()->getModule();
1164 Constant *F =
1165 M->getOrInsertFunction("fgetc_unlocked", B.getInt32Ty(), File->getType());
1166 if (File->getType()->isPointerTy())
1167 inferLibFuncAttributes(*M->getFunction("fgetc_unlocked"), *TLI);
1168 CallInst *CI = B.CreateCall(F, File, "fgetc_unlocked");
1169
1170 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1171 CI->setCallingConv(Fn->getCallingConv());
1172 return CI;
1173}
1174
1175Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
1176 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1177 if (!TLI->has(LibFunc_fgets_unlocked))
1178 return nullptr;
1179
1180 Module *M = B.GetInsertBlock()->getModule();
1181 Constant *F =
Benjamin Kramer8ac15bf2018-05-16 21:45:39 +00001182 M->getOrInsertFunction("fgets_unlocked", B.getInt8PtrTy(),
1183 B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001184 inferLibFuncAttributes(*M->getFunction("fgets_unlocked"), *TLI);
1185 CallInst *CI =
1186 B.CreateCall(F, {castToCStr(Str, B), Size, File}, "fgets_unlocked");
1187
1188 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1189 CI->setCallingConv(Fn->getCallingConv());
1190 return CI;
1191}
1192
1193Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1194 IRBuilder<> &B, const DataLayout &DL,
1195 const TargetLibraryInfo *TLI) {
1196 if (!TLI->has(LibFunc_fread_unlocked))
1197 return nullptr;
1198
1199 Module *M = B.GetInsertBlock()->getModule();
1200 LLVMContext &Context = B.GetInsertBlock()->getContext();
1201 StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
1202 Constant *F = M->getOrInsertFunction(
1203 FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1204 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1205
1206 if (File->getType()->isPointerTy())
1207 inferLibFuncAttributes(*M->getFunction(FReadUnlockedName), *TLI);
1208 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1209
1210 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1211 CI->setCallingConv(Fn->getCallingConv());
1212 return CI;
1213}