blob: d0396e6ce47d9c5bfb7a7e3038c5f0370d4f9e70 [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");
41
42static bool setDoesNotAccessMemory(Function &F) {
43 if (F.doesNotAccessMemory())
44 return false;
45 F.setDoesNotAccessMemory();
46 ++NumReadNone;
47 return true;
48}
49
50static bool setOnlyReadsMemory(Function &F) {
51 if (F.onlyReadsMemory())
52 return false;
53 F.setOnlyReadsMemory();
54 ++NumReadOnly;
55 return true;
56}
57
58static bool setOnlyAccessesArgMemory(Function &F) {
59 if (F.onlyAccessesArgMemory())
60 return false;
Reid Klecknera0b45f42017-05-03 18:17:31 +000061 F.setOnlyAccessesArgMemory();
Ahmed Bougachab0624a22016-04-27 19:04:40 +000062 ++NumArgMemOnly;
63 return true;
64}
65
66static bool setDoesNotThrow(Function &F) {
67 if (F.doesNotThrow())
68 return false;
69 F.setDoesNotThrow();
70 ++NumNoUnwind;
71 return true;
72}
73
Reid Klecknera0b45f42017-05-03 18:17:31 +000074static bool setRetDoesNotAlias(Function &F) {
75 if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias))
Ahmed Bougachab0624a22016-04-27 19:04:40 +000076 return false;
Reid Klecknera0b45f42017-05-03 18:17:31 +000077 F.addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
Ahmed Bougachab0624a22016-04-27 19:04:40 +000078 ++NumNoAlias;
79 return true;
80}
81
Reid Klecknera0b45f42017-05-03 18:17:31 +000082static bool setDoesNotCapture(Function &F, unsigned ArgNo) {
83 if (F.hasParamAttribute(ArgNo, Attribute::NoCapture))
Ahmed Bougachab0624a22016-04-27 19:04:40 +000084 return false;
Reid Klecknera0b45f42017-05-03 18:17:31 +000085 F.addParamAttr(ArgNo, Attribute::NoCapture);
86 ++NumNoCapture;
87 return true;
88}
89
90static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
91 if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))
92 return false;
93 F.addParamAttr(ArgNo, Attribute::ReadOnly);
94 ++NumReadOnlyArg;
95 return true;
96}
97
98static bool setRetNonNull(Function &F) {
99 assert(F.getReturnType()->isPointerTy() &&
100 "nonnull applies only to pointers");
101 if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull))
102 return false;
103 F.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000104 ++NumNonNull;
105 return true;
106}
107
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000108static bool setNonLazyBind(Function &F) {
109 if (F.hasFnAttribute(Attribute::NonLazyBind))
110 return false;
111 F.addFnAttr(Attribute::NonLazyBind);
112 return true;
113}
114
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000115bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000116 LibFunc TheLibFunc;
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000117 if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
118 return false;
119
120 bool Changed = false;
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000121
122 if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
123 Changed |= setNonLazyBind(F);
124
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000125 switch (TheLibFunc) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000126 case LibFunc_strlen:
Matthias Braun60b40b82017-05-05 20:25:50 +0000127 case LibFunc_wcslen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000128 Changed |= setOnlyReadsMemory(F);
129 Changed |= setDoesNotThrow(F);
Xin Tong9d2a5b12017-06-18 03:10:26 +0000130 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000131 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000132 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000133 case LibFunc_strchr:
134 case LibFunc_strrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000135 Changed |= setOnlyReadsMemory(F);
136 Changed |= setDoesNotThrow(F);
137 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000138 case LibFunc_strtol:
139 case LibFunc_strtod:
140 case LibFunc_strtof:
141 case LibFunc_strtoul:
142 case LibFunc_strtoll:
143 case LibFunc_strtold:
144 case LibFunc_strtoull:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000145 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000146 Changed |= setDoesNotCapture(F, 1);
147 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000148 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000149 case LibFunc_strcpy:
150 case LibFunc_stpcpy:
151 case LibFunc_strcat:
152 case LibFunc_strncat:
153 case LibFunc_strncpy:
154 case LibFunc_stpncpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000155 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000156 Changed |= setDoesNotCapture(F, 1);
157 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000158 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000159 case LibFunc_strxfrm:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000160 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000161 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000162 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000163 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000164 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000165 case LibFunc_strcmp: // 0,1
166 case LibFunc_strspn: // 0,1
167 case LibFunc_strncmp: // 0,1
168 case LibFunc_strcspn: // 0,1
169 case LibFunc_strcoll: // 0,1
170 case LibFunc_strcasecmp: // 0,1
171 case LibFunc_strncasecmp: //
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000172 Changed |= setOnlyReadsMemory(F);
173 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000174 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000175 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000176 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000177 case LibFunc_strstr:
178 case LibFunc_strpbrk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000179 Changed |= setOnlyReadsMemory(F);
180 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000181 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000182 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000183 case LibFunc_strtok:
184 case LibFunc_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000185 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000186 Changed |= setDoesNotCapture(F, 1);
187 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000188 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000189 case LibFunc_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000190 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000191 Changed |= setDoesNotCapture(F, 0);
192 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000193 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000194 case LibFunc_setbuf:
195 case LibFunc_setvbuf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000196 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000197 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000198 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000199 case LibFunc_strdup:
200 case LibFunc_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000201 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000202 Changed |= setRetDoesNotAlias(F);
203 Changed |= setDoesNotCapture(F, 0);
204 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000205 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000206 case LibFunc_stat:
207 case LibFunc_statvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000208 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000209 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000210 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000211 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000212 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000213 case LibFunc_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000214 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000215 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000216 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000217 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000218 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000219 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000220 case LibFunc_sprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000221 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000222 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000223 Changed |= setDoesNotCapture(F, 1);
224 Changed |= setOnlyReadsMemory(F, 1);
225 return Changed;
Reid Klecknera0b45f42017-05-03 18:17:31 +0000226 case LibFunc_snprintf:
227 Changed |= setDoesNotThrow(F);
228 Changed |= setDoesNotCapture(F, 0);
229 Changed |= setDoesNotCapture(F, 2);
230 Changed |= setOnlyReadsMemory(F, 2);
231 return Changed;
232 case LibFunc_setitimer:
233 Changed |= setDoesNotThrow(F);
234 Changed |= setDoesNotCapture(F, 1);
235 Changed |= setDoesNotCapture(F, 2);
236 Changed |= setOnlyReadsMemory(F, 1);
237 return Changed;
238 case LibFunc_system:
239 // May throw; "system" is a valid pthread cancellation point.
240 Changed |= setDoesNotCapture(F, 0);
241 Changed |= setOnlyReadsMemory(F, 0);
242 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000243 case LibFunc_malloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000244 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000245 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000246 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000247 case LibFunc_memcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000248 Changed |= setOnlyReadsMemory(F);
249 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000250 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000251 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000252 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000253 case LibFunc_memchr:
254 case LibFunc_memrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000255 Changed |= setOnlyReadsMemory(F);
256 Changed |= setDoesNotThrow(F);
257 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000258 case LibFunc_modf:
259 case LibFunc_modff:
260 case LibFunc_modfl:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000261 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +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_memcpy:
265 case LibFunc_mempcpy:
266 case LibFunc_memccpy:
267 case LibFunc_memmove:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000268 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000269 Changed |= setDoesNotCapture(F, 1);
270 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000271 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000272 case LibFunc_memcpy_chk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000273 Changed |= setDoesNotThrow(F);
274 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000275 case LibFunc_memalign:
Reid Klecknera0b45f42017-05-03 18:17:31 +0000276 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000277 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000278 case LibFunc_mkdir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000279 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000280 Changed |= setDoesNotCapture(F, 0);
281 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000282 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000283 case LibFunc_mktime:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000284 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000285 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000286 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000287 case LibFunc_realloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000288 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000289 Changed |= setRetDoesNotAlias(F);
290 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000291 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000292 case LibFunc_read:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000293 // May throw; "read" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000294 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000295 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000296 case LibFunc_rewind:
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_rmdir:
301 case LibFunc_remove:
302 case LibFunc_realpath:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000303 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000304 Changed |= setDoesNotCapture(F, 0);
305 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000306 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000307 case LibFunc_rename:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000308 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000309 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000310 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000311 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000312 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000313 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000314 case LibFunc_readlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000315 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000316 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000317 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000318 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_write:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000321 // May throw; "write" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000322 Changed |= setDoesNotCapture(F, 1);
323 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000324 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000325 case LibFunc_bcopy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000326 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000327 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000328 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000329 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000330 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000331 case LibFunc_bcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000332 Changed |= setDoesNotThrow(F);
333 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000334 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000335 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000336 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000337 case LibFunc_bzero:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000338 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000339 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000340 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000341 case LibFunc_calloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000342 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000343 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000344 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000345 case LibFunc_chmod:
346 case LibFunc_chown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000347 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000348 Changed |= setDoesNotCapture(F, 0);
349 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000350 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000351 case LibFunc_ctermid:
352 case LibFunc_clearerr:
353 case LibFunc_closedir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000354 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000355 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000356 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000357 case LibFunc_atoi:
358 case LibFunc_atol:
359 case LibFunc_atof:
360 case LibFunc_atoll:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000361 Changed |= setDoesNotThrow(F);
362 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000363 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000364 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000365 case LibFunc_access:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000366 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000367 Changed |= setDoesNotCapture(F, 0);
368 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000369 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000370 case LibFunc_fopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000371 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000372 Changed |= setRetDoesNotAlias(F);
373 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000374 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000375 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000376 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000377 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000378 case LibFunc_fdopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000379 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000380 Changed |= setRetDoesNotAlias(F);
381 Changed |= setDoesNotCapture(F, 1);
382 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000383 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000384 case LibFunc_feof:
385 case LibFunc_free:
386 case LibFunc_fseek:
387 case LibFunc_ftell:
388 case LibFunc_fgetc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000389 case LibFunc_fgetc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000390 case LibFunc_fseeko:
391 case LibFunc_ftello:
392 case LibFunc_fileno:
393 case LibFunc_fflush:
394 case LibFunc_fclose:
395 case LibFunc_fsetpos:
396 case LibFunc_flockfile:
397 case LibFunc_funlockfile:
398 case LibFunc_ftrylockfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000399 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000400 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000401 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000402 case LibFunc_ferror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000403 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000404 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000405 Changed |= setOnlyReadsMemory(F);
406 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000407 case LibFunc_fputc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000408 case LibFunc_fputc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000409 case LibFunc_fstat:
410 case LibFunc_frexp:
411 case LibFunc_frexpf:
412 case LibFunc_frexpl:
413 case LibFunc_fstatvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000414 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000415 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000416 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000417 case LibFunc_fgets:
David Bolvanskyca22d422018-05-16 11:39:52 +0000418 case LibFunc_fgets_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000419 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000420 Changed |= setDoesNotCapture(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000421 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000422 case LibFunc_fread:
David Bolvanskyca22d422018-05-16 11:39:52 +0000423 case LibFunc_fread_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000424 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000425 Changed |= setDoesNotCapture(F, 0);
426 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000427 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000428 case LibFunc_fwrite:
David Bolvanskyca22d422018-05-16 11:39:52 +0000429 case LibFunc_fwrite_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000430 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000431 Changed |= setDoesNotCapture(F, 0);
432 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000433 // FIXME: readonly #1?
434 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000435 case LibFunc_fputs:
David Bolvanskyca22d422018-05-16 11:39:52 +0000436 case LibFunc_fputs_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000437 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000438 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000439 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000440 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000441 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000442 case LibFunc_fscanf:
443 case LibFunc_fprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000444 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000445 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000446 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000447 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000448 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000449 case LibFunc_fgetpos:
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);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000453 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000454 case LibFunc_getc:
455 case LibFunc_getlogin_r:
456 case LibFunc_getc_unlocked:
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 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000460 case LibFunc_getenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000461 Changed |= setDoesNotThrow(F);
462 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000463 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000464 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000465 case LibFunc_gets:
466 case LibFunc_getchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000467 case LibFunc_getchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000468 Changed |= setDoesNotThrow(F);
469 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000470 case LibFunc_getitimer:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000471 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000472 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000473 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000474 case LibFunc_getpwnam:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000475 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000476 Changed |= setDoesNotCapture(F, 0);
477 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000478 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000479 case LibFunc_ungetc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000480 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000481 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000482 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000483 case LibFunc_uname:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000484 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000485 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000486 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000487 case LibFunc_unlink:
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_unsetenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000493 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000494 Changed |= setDoesNotCapture(F, 0);
495 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000496 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000497 case LibFunc_utime:
498 case LibFunc_utimes:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000499 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000500 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000501 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000502 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000503 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000504 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000505 case LibFunc_putc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000506 case LibFunc_putc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000507 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000508 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000509 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000510 case LibFunc_puts:
511 case LibFunc_printf:
512 case LibFunc_perror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000513 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000514 Changed |= setDoesNotCapture(F, 0);
515 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000516 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000517 case LibFunc_pread:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000518 // May throw; "pread" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000519 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000520 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000521 case LibFunc_pwrite:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000522 // May throw; "pwrite" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000523 Changed |= setDoesNotCapture(F, 1);
524 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000525 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000526 case LibFunc_putchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000527 case LibFunc_putchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000528 Changed |= setDoesNotThrow(F);
529 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000530 case LibFunc_popen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000531 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000532 Changed |= setRetDoesNotAlias(F);
533 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000534 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000535 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000536 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000537 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000538 case LibFunc_pclose:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000539 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000540 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000541 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000542 case LibFunc_vscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000543 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000544 Changed |= setDoesNotCapture(F, 0);
545 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000546 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000547 case LibFunc_vsscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000548 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000549 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000550 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000551 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000552 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000553 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000554 case LibFunc_vfscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000555 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000556 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000557 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000558 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000559 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000560 case LibFunc_valloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000561 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000562 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000563 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000564 case LibFunc_vprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000565 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000566 Changed |= setDoesNotCapture(F, 0);
567 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000568 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000569 case LibFunc_vfprintf:
570 case LibFunc_vsprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000571 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000572 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000573 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000574 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000575 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000576 case LibFunc_vsnprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000577 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000578 Changed |= setDoesNotCapture(F, 0);
579 Changed |= setDoesNotCapture(F, 2);
580 Changed |= setOnlyReadsMemory(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000581 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000582 case LibFunc_open:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000583 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000584 Changed |= setDoesNotCapture(F, 0);
585 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000586 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000587 case LibFunc_opendir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000588 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000589 Changed |= setRetDoesNotAlias(F);
590 Changed |= setDoesNotCapture(F, 0);
591 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000592 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000593 case LibFunc_tmpfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000594 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000595 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000596 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000597 case LibFunc_times:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000598 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000599 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000600 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000601 case LibFunc_htonl:
602 case LibFunc_htons:
603 case LibFunc_ntohl:
604 case LibFunc_ntohs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000605 Changed |= setDoesNotThrow(F);
606 Changed |= setDoesNotAccessMemory(F);
607 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000608 case LibFunc_lstat:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000609 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000610 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000611 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000612 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000613 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000614 case LibFunc_lchown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000615 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000616 Changed |= setDoesNotCapture(F, 0);
617 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000618 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000619 case LibFunc_qsort:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000620 // May throw; places call through function pointer.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000621 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000622 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000623 case LibFunc_dunder_strdup:
624 case LibFunc_dunder_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000625 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000626 Changed |= setRetDoesNotAlias(F);
627 Changed |= setDoesNotCapture(F, 0);
628 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000629 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000630 case LibFunc_dunder_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000631 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000632 Changed |= setDoesNotCapture(F, 1);
633 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000634 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000635 case LibFunc_under_IO_getc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000636 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000637 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000638 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000639 case LibFunc_under_IO_putc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000640 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000641 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000642 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000643 case LibFunc_dunder_isoc99_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000644 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000645 Changed |= setDoesNotCapture(F, 0);
646 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000647 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000648 case LibFunc_stat64:
649 case LibFunc_lstat64:
650 case LibFunc_statvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000651 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000652 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000653 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000654 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000655 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000656 case LibFunc_dunder_isoc99_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000657 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000658 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000659 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000660 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000661 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000662 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000663 case LibFunc_fopen64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000664 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000665 Changed |= setRetDoesNotAlias(F);
666 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000667 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000668 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000669 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000670 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000671 case LibFunc_fseeko64:
672 case LibFunc_ftello64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000673 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000674 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000675 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000676 case LibFunc_tmpfile64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000677 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000678 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000679 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000680 case LibFunc_fstat64:
681 case LibFunc_fstatvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000682 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000683 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000684 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000685 case LibFunc_open64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000686 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000687 Changed |= setDoesNotCapture(F, 0);
688 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000689 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000690 case LibFunc_gettimeofday:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000691 // Currently some platforms have the restrict keyword on the arguments to
692 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
693 // arguments.
694 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000695 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +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_Znwj: // new(unsigned int)
699 case LibFunc_Znwm: // new(unsigned long)
700 case LibFunc_Znaj: // new[](unsigned int)
701 case LibFunc_Znam: // new[](unsigned long)
702 case LibFunc_msvc_new_int: // new(unsigned int)
703 case LibFunc_msvc_new_longlong: // new(unsigned long long)
704 case LibFunc_msvc_new_array_int: // new[](unsigned int)
705 case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000706 // Operator new always returns a nonnull noalias pointer
Reid Klecknera0b45f42017-05-03 18:17:31 +0000707 Changed |= setRetNonNull(F);
708 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000709 return Changed;
David Bolvansky3ea50f92018-04-25 04:33:36 +0000710 // TODO: add LibFunc entries for:
711 // case LibFunc_memset_pattern4:
712 // case LibFunc_memset_pattern8:
David L. Jonesd21529f2017-01-23 23:16:46 +0000713 case LibFunc_memset_pattern16:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000714 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000715 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougacha44c19872016-04-27 19:04:43 +0000716 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000717 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000718 return Changed;
719 // int __nvvm_reflect(const char *)
David L. Jonesd21529f2017-01-23 23:16:46 +0000720 case LibFunc_nvvm_reflect:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000721 Changed |= setDoesNotAccessMemory(F);
722 Changed |= setDoesNotThrow(F);
723 return Changed;
724
725 default:
726 // FIXME: It'd be really nice to cover all the library functions we're
727 // aware of here.
728 return false;
729 }
730}
731
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000732bool llvm::hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
733 LibFunc DoubleFn, LibFunc FloatFn,
734 LibFunc LongDoubleFn) {
735 switch (Ty->getTypeID()) {
736 case Type::FloatTyID:
737 return TLI->has(FloatFn);
738 case Type::DoubleTyID:
739 return TLI->has(DoubleFn);
740 default:
741 return TLI->has(LongDoubleFn);
742 }
743}
744
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000745//- Emit LibCalls ------------------------------------------------------------//
746
Sanjay Pateld3112a52016-01-19 19:46:10 +0000747Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
Matt Arsenaultbe558882014-04-23 20:58:57 +0000748 unsigned AS = V->getType()->getPointerAddressSpace();
749 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
Eric Christopher87abfc52010-03-05 22:25:30 +0000750}
751
Sanjay Pateld3112a52016-01-19 19:46:10 +0000752Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000753 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000754 if (!TLI->has(LibFunc_strlen))
Craig Topperf40110f2014-04-25 05:29:35 +0000755 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000756
Sanjay Pateld4af2972016-01-19 19:58:49 +0000757 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000758 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000759 Constant *StrLen = M->getOrInsertFunction("strlen", DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000760 B.getInt8PtrTy());
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000761 inferLibFuncAttributes(*M->getFunction("strlen"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000762 CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), "strlen");
Evan Chengad6efbf2014-03-12 18:09:37 +0000763 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
764 CI->setCallingConv(F->getCallingConv());
765
Eric Christopher87abfc52010-03-05 22:25:30 +0000766 return CI;
767}
768
Sanjay Pateld3112a52016-01-19 19:46:10 +0000769Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000770 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000771 if (!TLI->has(LibFunc_strchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000772 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000773
Sanjay Pateld4af2972016-01-19 19:58:49 +0000774 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000775 Type *I8Ptr = B.getInt8PtrTy();
776 Type *I32Ty = B.getInt32Ty();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000777 Constant *StrChr =
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000778 M->getOrInsertFunction("strchr", I8Ptr, I8Ptr, I32Ty);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000779 inferLibFuncAttributes(*M->getFunction("strchr"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000780 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000781 StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, "strchr");
Evan Chengad6efbf2014-03-12 18:09:37 +0000782 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
783 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000784 return CI;
785}
786
Sanjay Pateld3112a52016-01-19 19:46:10 +0000787Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000788 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000789 if (!TLI->has(LibFunc_strncmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000790 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000791
Sanjay Pateld4af2972016-01-19 19:58:49 +0000792 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000793 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000794 Value *StrNCmp = M->getOrInsertFunction("strncmp", B.getInt32Ty(),
795 B.getInt8PtrTy(), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000796 DL.getIntPtrType(Context));
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000797 inferLibFuncAttributes(*M->getFunction("strncmp"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000798 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000799 StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "strncmp");
Evan Chengad6efbf2014-03-12 18:09:37 +0000800
801 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
802 CI->setCallingConv(F->getCallingConv());
803
Benjamin Kramer11188602010-06-15 21:34:25 +0000804 return CI;
805}
806
Sanjay Pateld3112a52016-01-19 19:46:10 +0000807Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000808 const TargetLibraryInfo *TLI, StringRef Name) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000809 if (!TLI->has(LibFunc_strcpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000810 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000811
Sanjay Pateld4af2972016-01-19 19:58:49 +0000812 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000813 Type *I8Ptr = B.getInt8PtrTy();
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000814 Value *StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000815 inferLibFuncAttributes(*M->getFunction(Name), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000816 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +0000817 B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
Evan Chengad6efbf2014-03-12 18:09:37 +0000818 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
819 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000820 return CI;
821}
822
Sanjay Pateld3112a52016-01-19 19:46:10 +0000823Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000824 const TargetLibraryInfo *TLI, StringRef Name) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000825 if (!TLI->has(LibFunc_strncpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000826 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000827
Sanjay Pateld4af2972016-01-19 19:58:49 +0000828 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000829 Type *I8Ptr = B.getInt8PtrTy();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000830 Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr,
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000831 Len->getType());
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000832 inferLibFuncAttributes(*M->getFunction(Name), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000833 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000834 StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, "strncpy");
Evan Chengad6efbf2014-03-12 18:09:37 +0000835 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
836 CI->setCallingConv(F->getCallingConv());
Eric Christopher43dc11c2010-03-11 01:25:07 +0000837 return CI;
838}
839
Sanjay Pateld3112a52016-01-19 19:46:10 +0000840Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000841 IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000842 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000843 if (!TLI->has(LibFunc_memcpy_chk))
Craig Topperf40110f2014-04-25 05:29:35 +0000844 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000845
Sanjay Pateld4af2972016-01-19 19:58:49 +0000846 Module *M = B.GetInsertBlock()->getModule();
Reid Klecknerb5180542017-03-21 16:57:19 +0000847 AttributeList AS;
848 AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
849 Attribute::NoUnwind);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000850 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000851 Value *MemCpy = M->getOrInsertFunction(
Reid Klecknerb5180542017-03-21 16:57:19 +0000852 "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000853 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000854 DL.getIntPtrType(Context));
Sanjay Pateld3112a52016-01-19 19:46:10 +0000855 Dst = castToCStr(Dst, B);
856 Src = castToCStr(Src, B);
David Blaikieff6409d2015-05-18 22:13:54 +0000857 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
Evan Chengad6efbf2014-03-12 18:09:37 +0000858 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
859 CI->setCallingConv(F->getCallingConv());
Evan Chengd9e82232010-03-23 15:48:04 +0000860 return CI;
861}
862
Sanjay Pateld3112a52016-01-19 19:46:10 +0000863Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000864 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000865 if (!TLI->has(LibFunc_memchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000866 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000867
Sanjay Pateld4af2972016-01-19 19:58:49 +0000868 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000869 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000870 Value *MemChr = M->getOrInsertFunction("memchr", B.getInt8PtrTy(),
871 B.getInt8PtrTy(), B.getInt32Ty(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000872 DL.getIntPtrType(Context));
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000873 inferLibFuncAttributes(*M->getFunction("memchr"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000874 CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, "memchr");
Evan Chengad6efbf2014-03-12 18:09:37 +0000875
876 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
877 CI->setCallingConv(F->getCallingConv());
878
Eric Christopher87abfc52010-03-05 22:25:30 +0000879 return CI;
880}
881
Sanjay Pateld3112a52016-01-19 19:46:10 +0000882Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000883 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000884 if (!TLI->has(LibFunc_memcmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000885 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000886
Sanjay Pateld4af2972016-01-19 19:58:49 +0000887 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000888 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000889 Value *MemCmp = M->getOrInsertFunction("memcmp", B.getInt32Ty(),
890 B.getInt8PtrTy(), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000891 DL.getIntPtrType(Context));
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000892 inferLibFuncAttributes(*M->getFunction("memcmp"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000893 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000894 MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "memcmp");
Evan Chengad6efbf2014-03-12 18:09:37 +0000895
896 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
897 CI->setCallingConv(F->getCallingConv());
898
Eric Christopher87abfc52010-03-05 22:25:30 +0000899 return CI;
900}
901
Yi Jiang6ab044e2013-12-16 22:42:40 +0000902/// Append a suffix to the function name according to the type of 'Op'.
Sanjay Pateld3112a52016-01-19 19:46:10 +0000903static void appendTypeSuffix(Value *Op, StringRef &Name,
Sanjay Patelb50325e2016-01-19 19:17:47 +0000904 SmallString<20> &NameBuffer) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000905 if (!Op->getType()->isDoubleTy()) {
906 NameBuffer += Name;
907
908 if (Op->getType()->isFloatTy())
909 NameBuffer += 'f';
910 else
911 NameBuffer += 'l';
912
913 Name = NameBuffer;
Fangrui Songf78650a2018-07-30 19:41:25 +0000914 }
Yi Jiang6ab044e2013-12-16 22:42:40 +0000915}
916
Sanjay Pateld3112a52016-01-19 19:46:10 +0000917Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
Reid Klecknerb5180542017-03-21 16:57:19 +0000918 const AttributeList &Attrs) {
Benjamin Kramerb106bcc2011-11-15 19:12:09 +0000919 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +0000920 appendTypeSuffix(Op, Name, NameBuffer);
Eric Christopher87abfc52010-03-05 22:25:30 +0000921
Sanjay Pateld4af2972016-01-19 19:58:49 +0000922 Module *M = B.GetInsertBlock()->getModule();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000923 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000924 Op->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +0000925 CallInst *CI = B.CreateCall(Callee, Op, Name);
Matt Arsenault6a288c12017-05-03 02:26:10 +0000926
927 // The incoming attribute set may have come from a speculatable intrinsic, but
928 // is being replaced with a library call which is not allowed to be
929 // speculatable.
930 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
931 AttributeList::FunctionIndex,
932 Attribute::Speculatable));
Evan Chengad6efbf2014-03-12 18:09:37 +0000933 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
934 CI->setCallingConv(F->getCallingConv());
935
Eric Christopher87abfc52010-03-05 22:25:30 +0000936 return CI;
937}
938
Sanjay Pateld3112a52016-01-19 19:46:10 +0000939Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
Reid Klecknerb5180542017-03-21 16:57:19 +0000940 IRBuilder<> &B, const AttributeList &Attrs) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000941 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +0000942 appendTypeSuffix(Op1, Name, NameBuffer);
Yi Jiang6ab044e2013-12-16 22:42:40 +0000943
Sanjay Pateld4af2972016-01-19 19:58:49 +0000944 Module *M = B.GetInsertBlock()->getModule();
Sanjay Patelb50325e2016-01-19 19:17:47 +0000945 Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000946 Op2->getType());
David Blaikieff6409d2015-05-18 22:13:54 +0000947 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
Yi Jiang6ab044e2013-12-16 22:42:40 +0000948 CI->setAttributes(Attrs);
Evan Chengad6efbf2014-03-12 18:09:37 +0000949 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
950 CI->setCallingConv(F->getCallingConv());
951
Yi Jiang6ab044e2013-12-16 22:42:40 +0000952 return CI;
953}
954
Sanjay Pateld3112a52016-01-19 19:46:10 +0000955Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000956 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000957 if (!TLI->has(LibFunc_putchar))
Craig Topperf40110f2014-04-25 05:29:35 +0000958 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000959
Sanjay Pateld4af2972016-01-19 19:58:49 +0000960 Module *M = B.GetInsertBlock()->getModule();
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000961 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(), B.getInt32Ty());
Craig Topper0f5063c2017-03-17 23:48:02 +0000962 inferLibFuncAttributes(*M->getFunction("putchar"), *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000963 CallInst *CI = B.CreateCall(PutChar,
964 B.CreateIntCast(Char,
965 B.getInt32Ty(),
966 /*isSigned*/true,
967 "chari"),
968 "putchar");
Evan Chengad6efbf2014-03-12 18:09:37 +0000969
970 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
971 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000972 return CI;
973}
974
Sanjay Pateld3112a52016-01-19 19:46:10 +0000975Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000976 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000977 if (!TLI->has(LibFunc_puts))
Craig Topperf40110f2014-04-25 05:29:35 +0000978 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000979
Sanjay Pateld4af2972016-01-19 19:58:49 +0000980 Module *M = B.GetInsertBlock()->getModule();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000981 Value *PutS =
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000982 M->getOrInsertFunction("puts", B.getInt32Ty(), B.getInt8PtrTy());
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000983 inferLibFuncAttributes(*M->getFunction("puts"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000984 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), "puts");
Evan Chengad6efbf2014-03-12 18:09:37 +0000985 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
986 CI->setCallingConv(F->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +0000987 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +0000988}
989
Sanjay Pateld3112a52016-01-19 19:46:10 +0000990Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000991 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000992 if (!TLI->has(LibFunc_fputc))
Craig Topperf40110f2014-04-25 05:29:35 +0000993 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000994
Sanjay Pateld4af2972016-01-19 19:58:49 +0000995 Module *M = B.GetInsertBlock()->getModule();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000996 Constant *F = M->getOrInsertFunction("fputc", B.getInt32Ty(), B.getInt32Ty(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000997 File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +0000998 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000999 inferLibFuncAttributes(*M->getFunction("fputc"), *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001000 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
1001 "chari");
David Blaikieff6409d2015-05-18 22:13:54 +00001002 CallInst *CI = B.CreateCall(F, {Char, File}, "fputc");
Evan Chengad6efbf2014-03-12 18:09:37 +00001003
1004 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1005 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001006 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001007}
1008
David Bolvanskyca22d422018-05-16 11:39:52 +00001009Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
1010 const TargetLibraryInfo *TLI) {
1011 if (!TLI->has(LibFunc_fputc_unlocked))
1012 return nullptr;
1013
1014 Module *M = B.GetInsertBlock()->getModule();
1015 Constant *F = M->getOrInsertFunction("fputc_unlocked", B.getInt32Ty(),
1016 B.getInt32Ty(), File->getType());
1017 if (File->getType()->isPointerTy())
1018 inferLibFuncAttributes(*M->getFunction("fputc_unlocked"), *TLI);
1019 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
1020 CallInst *CI = B.CreateCall(F, {Char, File}, "fputc_unlocked");
1021
1022 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1023 CI->setCallingConv(Fn->getCallingConv());
1024 return CI;
1025}
1026
Sanjay Pateld3112a52016-01-19 19:46:10 +00001027Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001028 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001029 if (!TLI->has(LibFunc_fputs))
Craig Topperf40110f2014-04-25 05:29:35 +00001030 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001031
Sanjay Pateld4af2972016-01-19 19:58:49 +00001032 Module *M = B.GetInsertBlock()->getModule();
David L. Jonesd21529f2017-01-23 23:16:46 +00001033 StringRef FPutsName = TLI->getName(LibFunc_fputs);
Mehdi Aminidb11fdf2017-04-06 20:23:57 +00001034 Constant *F = M->getOrInsertFunction(
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001035 FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001036 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001037 inferLibFuncAttributes(*M->getFunction(FPutsName), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +00001038 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs");
Evan Chengad6efbf2014-03-12 18:09:37 +00001039
1040 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1041 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001042 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001043}
1044
David Bolvanskyca22d422018-05-16 11:39:52 +00001045Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
1046 const TargetLibraryInfo *TLI) {
1047 if (!TLI->has(LibFunc_fputs_unlocked))
1048 return nullptr;
1049
1050 Module *M = B.GetInsertBlock()->getModule();
1051 StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
1052 Constant *F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
1053 B.getInt8PtrTy(), File->getType());
1054 if (File->getType()->isPointerTy())
1055 inferLibFuncAttributes(*M->getFunction(FPutsUnlockedName), *TLI);
1056 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs_unlocked");
1057
1058 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1059 CI->setCallingConv(Fn->getCallingConv());
1060 return CI;
1061}
1062
Sanjay Pateld3112a52016-01-19 19:46:10 +00001063Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001064 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001065 if (!TLI->has(LibFunc_fwrite))
Craig Topperf40110f2014-04-25 05:29:35 +00001066 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001067
Sanjay Pateld4af2972016-01-19 19:58:49 +00001068 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +00001069 LLVMContext &Context = B.GetInsertBlock()->getContext();
David L. Jonesd21529f2017-01-23 23:16:46 +00001070 StringRef FWriteName = TLI->getName(LibFunc_fwrite);
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001071 Constant *F = M->getOrInsertFunction(
1072 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001073 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1074
Eric Christopher87abfc52010-03-05 22:25:30 +00001075 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001076 inferLibFuncAttributes(*M->getFunction(FWriteName), *TLI);
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001077 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +00001078 B.CreateCall(F, {castToCStr(Ptr, B), Size,
David Blaikieff6409d2015-05-18 22:13:54 +00001079 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
Evan Chengad6efbf2014-03-12 18:09:37 +00001080
1081 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1082 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001083 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001084}
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001085
1086Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
1087 const TargetLibraryInfo *TLI) {
1088 if (!TLI->has(LibFunc_malloc))
1089 return nullptr;
1090
1091 Module *M = B.GetInsertBlock()->getModule();
1092 LLVMContext &Context = B.GetInsertBlock()->getContext();
1093 Value *Malloc = M->getOrInsertFunction("malloc", B.getInt8PtrTy(),
1094 DL.getIntPtrType(Context));
1095 inferLibFuncAttributes(*M->getFunction("malloc"), *TLI);
1096 CallInst *CI = B.CreateCall(Malloc, Num, "malloc");
1097
1098 if (const Function *F = dyn_cast<Function>(Malloc->stripPointerCasts()))
1099 CI->setCallingConv(F->getCallingConv());
1100
1101 return CI;
1102}
1103
1104Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
1105 IRBuilder<> &B, const TargetLibraryInfo &TLI) {
1106 if (!TLI.has(LibFunc_calloc))
1107 return nullptr;
1108
1109 Module *M = B.GetInsertBlock()->getModule();
1110 const DataLayout &DL = M->getDataLayout();
1111 IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
1112 Value *Calloc = M->getOrInsertFunction("calloc", Attrs, B.getInt8PtrTy(),
1113 PtrType, PtrType);
1114 inferLibFuncAttributes(*M->getFunction("calloc"), TLI);
1115 CallInst *CI = B.CreateCall(Calloc, {Num, Size}, "calloc");
1116
1117 if (const auto *F = dyn_cast<Function>(Calloc->stripPointerCasts()))
1118 CI->setCallingConv(F->getCallingConv());
1119
1120 return CI;
1121}
David Bolvanskyca22d422018-05-16 11:39:52 +00001122
1123Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1124 IRBuilder<> &B, const DataLayout &DL,
1125 const TargetLibraryInfo *TLI) {
1126 if (!TLI->has(LibFunc_fwrite_unlocked))
1127 return nullptr;
1128
1129 Module *M = B.GetInsertBlock()->getModule();
1130 LLVMContext &Context = B.GetInsertBlock()->getContext();
1131 StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
1132 Constant *F = M->getOrInsertFunction(
1133 FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1134 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1135
1136 if (File->getType()->isPointerTy())
1137 inferLibFuncAttributes(*M->getFunction(FWriteUnlockedName), *TLI);
1138 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1139
1140 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1141 CI->setCallingConv(Fn->getCallingConv());
1142 return CI;
1143}
1144
1145Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
1146 const TargetLibraryInfo *TLI) {
1147 if (!TLI->has(LibFunc_fgetc_unlocked))
1148 return nullptr;
1149
1150 Module *M = B.GetInsertBlock()->getModule();
1151 Constant *F =
1152 M->getOrInsertFunction("fgetc_unlocked", B.getInt32Ty(), File->getType());
1153 if (File->getType()->isPointerTy())
1154 inferLibFuncAttributes(*M->getFunction("fgetc_unlocked"), *TLI);
1155 CallInst *CI = B.CreateCall(F, File, "fgetc_unlocked");
1156
1157 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1158 CI->setCallingConv(Fn->getCallingConv());
1159 return CI;
1160}
1161
1162Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
1163 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1164 if (!TLI->has(LibFunc_fgets_unlocked))
1165 return nullptr;
1166
1167 Module *M = B.GetInsertBlock()->getModule();
1168 Constant *F =
Benjamin Kramer8ac15bf2018-05-16 21:45:39 +00001169 M->getOrInsertFunction("fgets_unlocked", B.getInt8PtrTy(),
1170 B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001171 inferLibFuncAttributes(*M->getFunction("fgets_unlocked"), *TLI);
1172 CallInst *CI =
1173 B.CreateCall(F, {castToCStr(Str, B), Size, File}, "fgets_unlocked");
1174
1175 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1176 CI->setCallingConv(Fn->getCallingConv());
1177 return CI;
1178}
1179
1180Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1181 IRBuilder<> &B, const DataLayout &DL,
1182 const TargetLibraryInfo *TLI) {
1183 if (!TLI->has(LibFunc_fread_unlocked))
1184 return nullptr;
1185
1186 Module *M = B.GetInsertBlock()->getModule();
1187 LLVMContext &Context = B.GetInsertBlock()->getContext();
1188 StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
1189 Constant *F = M->getOrInsertFunction(
1190 FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1191 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1192
1193 if (File->getType()->isPointerTy())
1194 inferLibFuncAttributes(*M->getFunction(FReadUnlockedName), *TLI);
1195 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1196
1197 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1198 CI->setCallingConv(Fn->getCallingConv());
1199 return CI;
1200}