blob: 3466dedd3236e1b1cc1d37d40f3aa69258996b14 [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
David Bolvansky7c7760d2018-10-16 21:18:31 +0000124bool llvm::inferLibFuncAttributes(Module *M, StringRef Name,
David Bolvanskye8b3bba2018-10-13 15:21:55 +0000125 const TargetLibraryInfo &TLI) {
David Bolvansky7c7760d2018-10-16 21:18:31 +0000126 Function *F = M->getFunction(Name);
127 if (!F)
David Bolvanskye8b3bba2018-10-13 15:21:55 +0000128 return false;
David Bolvansky7c7760d2018-10-16 21:18:31 +0000129 return inferLibFuncAttributes(*F, TLI);
130}
131
132bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000133 LibFunc TheLibFunc;
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000134 if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
135 return false;
136
137 bool Changed = false;
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000138
139 if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
140 Changed |= setNonLazyBind(F);
141
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000142 switch (TheLibFunc) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000143 case LibFunc_strlen:
Matthias Braun60b40b82017-05-05 20:25:50 +0000144 case LibFunc_wcslen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000145 Changed |= setOnlyReadsMemory(F);
146 Changed |= setDoesNotThrow(F);
Xin Tong9d2a5b12017-06-18 03:10:26 +0000147 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000148 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000149 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000150 case LibFunc_strchr:
151 case LibFunc_strrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000152 Changed |= setOnlyReadsMemory(F);
153 Changed |= setDoesNotThrow(F);
154 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000155 case LibFunc_strtol:
156 case LibFunc_strtod:
157 case LibFunc_strtof:
158 case LibFunc_strtoul:
159 case LibFunc_strtoll:
160 case LibFunc_strtold:
161 case LibFunc_strtoull:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000162 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000163 Changed |= setDoesNotCapture(F, 1);
164 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000165 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000166 case LibFunc_strcpy:
David Bolvansky8715e032018-08-23 05:18:23 +0000167 case LibFunc_strncpy:
David L. Jonesd21529f2017-01-23 23:16:46 +0000168 case LibFunc_strcat:
169 case LibFunc_strncat:
David Bolvansky8715e032018-08-23 05:18:23 +0000170 Changed |= setReturnedArg(F, 0);
171 LLVM_FALLTHROUGH;
172 case LibFunc_stpcpy:
David L. Jonesd21529f2017-01-23 23:16:46 +0000173 case LibFunc_stpncpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000174 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000175 Changed |= setDoesNotCapture(F, 1);
176 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000177 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000178 case LibFunc_strxfrm:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000179 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000180 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000181 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000182 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000183 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000184 case LibFunc_strcmp: // 0,1
185 case LibFunc_strspn: // 0,1
186 case LibFunc_strncmp: // 0,1
187 case LibFunc_strcspn: // 0,1
188 case LibFunc_strcoll: // 0,1
189 case LibFunc_strcasecmp: // 0,1
190 case LibFunc_strncasecmp: //
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000191 Changed |= setOnlyReadsMemory(F);
192 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000193 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000194 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000195 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000196 case LibFunc_strstr:
197 case LibFunc_strpbrk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000198 Changed |= setOnlyReadsMemory(F);
199 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000200 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000201 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000202 case LibFunc_strtok:
203 case LibFunc_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000204 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000205 Changed |= setDoesNotCapture(F, 1);
206 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000207 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000208 case LibFunc_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000209 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000210 Changed |= setDoesNotCapture(F, 0);
211 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_setbuf:
214 case LibFunc_setvbuf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000215 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000216 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000217 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000218 case LibFunc_strdup:
219 case LibFunc_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000220 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000221 Changed |= setRetDoesNotAlias(F);
222 Changed |= setDoesNotCapture(F, 0);
223 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000224 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000225 case LibFunc_stat:
226 case LibFunc_statvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000227 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000228 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000229 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000230 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000231 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000232 case LibFunc_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000233 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000234 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000235 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000236 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000237 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000238 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000239 case LibFunc_sprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000240 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000241 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000242 Changed |= setDoesNotCapture(F, 1);
243 Changed |= setOnlyReadsMemory(F, 1);
244 return Changed;
Reid Klecknera0b45f42017-05-03 18:17:31 +0000245 case LibFunc_snprintf:
246 Changed |= setDoesNotThrow(F);
247 Changed |= setDoesNotCapture(F, 0);
248 Changed |= setDoesNotCapture(F, 2);
249 Changed |= setOnlyReadsMemory(F, 2);
250 return Changed;
251 case LibFunc_setitimer:
252 Changed |= setDoesNotThrow(F);
253 Changed |= setDoesNotCapture(F, 1);
254 Changed |= setDoesNotCapture(F, 2);
255 Changed |= setOnlyReadsMemory(F, 1);
256 return Changed;
257 case LibFunc_system:
258 // May throw; "system" is a valid pthread cancellation point.
259 Changed |= setDoesNotCapture(F, 0);
260 Changed |= setOnlyReadsMemory(F, 0);
261 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000262 case LibFunc_malloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000263 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000264 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000265 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000266 case LibFunc_memcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000267 Changed |= setOnlyReadsMemory(F);
268 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000269 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000270 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000271 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000272 case LibFunc_memchr:
273 case LibFunc_memrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000274 Changed |= setOnlyReadsMemory(F);
275 Changed |= setDoesNotThrow(F);
276 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000277 case LibFunc_modf:
278 case LibFunc_modff:
279 case LibFunc_modfl:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000280 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000281 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000282 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000283 case LibFunc_memcpy:
David Bolvansky8715e032018-08-23 05:18:23 +0000284 case LibFunc_memmove:
285 Changed |= setReturnedArg(F, 0);
286 LLVM_FALLTHROUGH;
David L. Jonesd21529f2017-01-23 23:16:46 +0000287 case LibFunc_mempcpy:
288 case LibFunc_memccpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000289 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000290 Changed |= setDoesNotCapture(F, 1);
291 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000292 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000293 case LibFunc_memcpy_chk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000294 Changed |= setDoesNotThrow(F);
295 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000296 case LibFunc_memalign:
Reid Klecknera0b45f42017-05-03 18:17:31 +0000297 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000298 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000299 case LibFunc_mkdir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000300 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000301 Changed |= setDoesNotCapture(F, 0);
302 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000303 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000304 case LibFunc_mktime:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000305 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000306 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000307 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000308 case LibFunc_realloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000309 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000310 Changed |= setRetDoesNotAlias(F);
311 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_read:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000314 // May throw; "read" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000315 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000316 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000317 case LibFunc_rewind:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000318 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000319 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000320 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000321 case LibFunc_rmdir:
322 case LibFunc_remove:
323 case LibFunc_realpath:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000324 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000325 Changed |= setDoesNotCapture(F, 0);
326 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000327 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000328 case LibFunc_rename:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000329 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000330 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000331 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000332 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000333 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000334 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000335 case LibFunc_readlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000336 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000337 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000338 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000339 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000340 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000341 case LibFunc_write:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000342 // May throw; "write" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000343 Changed |= setDoesNotCapture(F, 1);
344 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000345 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000346 case LibFunc_bcopy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000347 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000348 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000349 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000350 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000351 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000352 case LibFunc_bcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000353 Changed |= setDoesNotThrow(F);
354 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000355 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000356 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000357 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000358 case LibFunc_bzero:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000359 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000360 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000361 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000362 case LibFunc_calloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000363 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000364 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000365 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000366 case LibFunc_chmod:
367 case LibFunc_chown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000368 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000369 Changed |= setDoesNotCapture(F, 0);
370 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000371 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000372 case LibFunc_ctermid:
373 case LibFunc_clearerr:
374 case LibFunc_closedir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000375 Changed |= setDoesNotThrow(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_atoi:
379 case LibFunc_atol:
380 case LibFunc_atof:
381 case LibFunc_atoll:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000382 Changed |= setDoesNotThrow(F);
383 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000384 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000385 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000386 case LibFunc_access:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000387 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000388 Changed |= setDoesNotCapture(F, 0);
389 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000390 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000391 case LibFunc_fopen:
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, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000395 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000396 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000397 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000398 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000399 case LibFunc_fdopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000400 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000401 Changed |= setRetDoesNotAlias(F);
402 Changed |= setDoesNotCapture(F, 1);
403 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000404 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000405 case LibFunc_feof:
406 case LibFunc_free:
407 case LibFunc_fseek:
408 case LibFunc_ftell:
409 case LibFunc_fgetc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000410 case LibFunc_fgetc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000411 case LibFunc_fseeko:
412 case LibFunc_ftello:
413 case LibFunc_fileno:
414 case LibFunc_fflush:
415 case LibFunc_fclose:
416 case LibFunc_fsetpos:
417 case LibFunc_flockfile:
418 case LibFunc_funlockfile:
419 case LibFunc_ftrylockfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000420 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000421 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000422 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000423 case LibFunc_ferror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000424 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000425 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000426 Changed |= setOnlyReadsMemory(F);
427 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000428 case LibFunc_fputc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000429 case LibFunc_fputc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000430 case LibFunc_fstat:
431 case LibFunc_frexp:
432 case LibFunc_frexpf:
433 case LibFunc_frexpl:
434 case LibFunc_fstatvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000435 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000436 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000437 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000438 case LibFunc_fgets:
David Bolvanskyca22d422018-05-16 11:39:52 +0000439 case LibFunc_fgets_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000440 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000441 Changed |= setDoesNotCapture(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000442 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000443 case LibFunc_fread:
David Bolvanskyca22d422018-05-16 11:39:52 +0000444 case LibFunc_fread_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000445 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000446 Changed |= setDoesNotCapture(F, 0);
447 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000448 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000449 case LibFunc_fwrite:
David Bolvanskyca22d422018-05-16 11:39:52 +0000450 case LibFunc_fwrite_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000451 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000452 Changed |= setDoesNotCapture(F, 0);
453 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000454 // FIXME: readonly #1?
455 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000456 case LibFunc_fputs:
David Bolvanskyca22d422018-05-16 11:39:52 +0000457 case LibFunc_fputs_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000458 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000459 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000460 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000461 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000462 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000463 case LibFunc_fscanf:
464 case LibFunc_fprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000465 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000466 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000467 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000468 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000469 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000470 case LibFunc_fgetpos:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000471 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000472 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000473 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000474 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000475 case LibFunc_getc:
476 case LibFunc_getlogin_r:
477 case LibFunc_getc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000478 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000479 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000480 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000481 case LibFunc_getenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000482 Changed |= setDoesNotThrow(F);
483 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000484 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000485 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000486 case LibFunc_gets:
487 case LibFunc_getchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000488 case LibFunc_getchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000489 Changed |= setDoesNotThrow(F);
490 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000491 case LibFunc_getitimer:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000492 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000493 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000494 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000495 case LibFunc_getpwnam:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000496 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000497 Changed |= setDoesNotCapture(F, 0);
498 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000499 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000500 case LibFunc_ungetc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000501 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000502 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000503 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000504 case LibFunc_uname:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000505 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000506 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000507 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000508 case LibFunc_unlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000509 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000510 Changed |= setDoesNotCapture(F, 0);
511 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000512 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000513 case LibFunc_unsetenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000514 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000515 Changed |= setDoesNotCapture(F, 0);
516 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000517 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000518 case LibFunc_utime:
519 case LibFunc_utimes:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000520 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000521 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000522 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000523 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000524 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_putc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000527 case LibFunc_putc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000528 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000529 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000530 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000531 case LibFunc_puts:
532 case LibFunc_printf:
533 case LibFunc_perror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000534 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000535 Changed |= setDoesNotCapture(F, 0);
536 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000537 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000538 case LibFunc_pread:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000539 // May throw; "pread" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000540 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000541 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000542 case LibFunc_pwrite:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000543 // May throw; "pwrite" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000544 Changed |= setDoesNotCapture(F, 1);
545 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000546 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000547 case LibFunc_putchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000548 case LibFunc_putchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000549 Changed |= setDoesNotThrow(F);
550 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000551 case LibFunc_popen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000552 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000553 Changed |= setRetDoesNotAlias(F);
554 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000555 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000556 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000557 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000558 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000559 case LibFunc_pclose:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000560 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000561 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000562 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000563 case LibFunc_vscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000564 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000565 Changed |= setDoesNotCapture(F, 0);
566 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000567 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000568 case LibFunc_vsscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000569 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000570 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000571 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000572 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000573 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000574 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000575 case LibFunc_vfscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000576 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000577 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000578 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000579 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000580 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000581 case LibFunc_valloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000582 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000583 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000584 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000585 case LibFunc_vprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000586 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000587 Changed |= setDoesNotCapture(F, 0);
588 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000589 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000590 case LibFunc_vfprintf:
591 case LibFunc_vsprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000592 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000593 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000594 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000595 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000596 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000597 case LibFunc_vsnprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000598 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000599 Changed |= setDoesNotCapture(F, 0);
600 Changed |= setDoesNotCapture(F, 2);
601 Changed |= setOnlyReadsMemory(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000602 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000603 case LibFunc_open:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000604 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000605 Changed |= setDoesNotCapture(F, 0);
606 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000607 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000608 case LibFunc_opendir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000609 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000610 Changed |= setRetDoesNotAlias(F);
611 Changed |= setDoesNotCapture(F, 0);
612 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_tmpfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000615 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000616 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000617 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000618 case LibFunc_times:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000619 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000620 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000621 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000622 case LibFunc_htonl:
623 case LibFunc_htons:
624 case LibFunc_ntohl:
625 case LibFunc_ntohs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000626 Changed |= setDoesNotThrow(F);
627 Changed |= setDoesNotAccessMemory(F);
628 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000629 case LibFunc_lstat:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000630 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000631 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000632 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000633 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000634 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000635 case LibFunc_lchown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000636 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000637 Changed |= setDoesNotCapture(F, 0);
638 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000639 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000640 case LibFunc_qsort:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000641 // May throw; places call through function pointer.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000642 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000643 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000644 case LibFunc_dunder_strdup:
645 case LibFunc_dunder_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000646 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000647 Changed |= setRetDoesNotAlias(F);
648 Changed |= setDoesNotCapture(F, 0);
649 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000650 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000651 case LibFunc_dunder_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000652 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000653 Changed |= setDoesNotCapture(F, 1);
654 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000655 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000656 case LibFunc_under_IO_getc:
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 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000660 case LibFunc_under_IO_putc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000661 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000662 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000663 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000664 case LibFunc_dunder_isoc99_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000665 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000666 Changed |= setDoesNotCapture(F, 0);
667 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_stat64:
670 case LibFunc_lstat64:
671 case LibFunc_statvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000672 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000673 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000674 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000675 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000676 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000677 case LibFunc_dunder_isoc99_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000678 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000679 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_fopen64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000685 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000686 Changed |= setRetDoesNotAlias(F);
687 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000688 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000689 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000690 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000691 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000692 case LibFunc_fseeko64:
693 case LibFunc_ftello64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000694 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000695 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000696 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000697 case LibFunc_tmpfile64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000698 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000699 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000700 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000701 case LibFunc_fstat64:
702 case LibFunc_fstatvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000703 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000704 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000705 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000706 case LibFunc_open64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000707 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000708 Changed |= setDoesNotCapture(F, 0);
709 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000710 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000711 case LibFunc_gettimeofday:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000712 // Currently some platforms have the restrict keyword on the arguments to
713 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
714 // arguments.
715 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000716 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000717 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000718 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000719 case LibFunc_Znwj: // new(unsigned int)
720 case LibFunc_Znwm: // new(unsigned long)
721 case LibFunc_Znaj: // new[](unsigned int)
722 case LibFunc_Znam: // new[](unsigned long)
723 case LibFunc_msvc_new_int: // new(unsigned int)
724 case LibFunc_msvc_new_longlong: // new(unsigned long long)
725 case LibFunc_msvc_new_array_int: // new[](unsigned int)
726 case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000727 // Operator new always returns a nonnull noalias pointer
Reid Klecknera0b45f42017-05-03 18:17:31 +0000728 Changed |= setRetNonNull(F);
729 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000730 return Changed;
David Bolvansky3ea50f92018-04-25 04:33:36 +0000731 // TODO: add LibFunc entries for:
732 // case LibFunc_memset_pattern4:
733 // case LibFunc_memset_pattern8:
David L. Jonesd21529f2017-01-23 23:16:46 +0000734 case LibFunc_memset_pattern16:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000735 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000736 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougacha44c19872016-04-27 19:04:43 +0000737 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000738 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000739 return Changed;
740 // int __nvvm_reflect(const char *)
David L. Jonesd21529f2017-01-23 23:16:46 +0000741 case LibFunc_nvvm_reflect:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000742 Changed |= setDoesNotAccessMemory(F);
743 Changed |= setDoesNotThrow(F);
744 return Changed;
745
746 default:
747 // FIXME: It'd be really nice to cover all the library functions we're
748 // aware of here.
749 return false;
750 }
751}
752
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000753bool llvm::hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
754 LibFunc DoubleFn, LibFunc FloatFn,
755 LibFunc LongDoubleFn) {
756 switch (Ty->getTypeID()) {
Benjamin Kramere5e1ea72018-09-19 12:01:38 +0000757 case Type::HalfTyID:
758 return false;
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000759 case Type::FloatTyID:
760 return TLI->has(FloatFn);
761 case Type::DoubleTyID:
762 return TLI->has(DoubleFn);
763 default:
764 return TLI->has(LongDoubleFn);
765 }
766}
767
Mikael Holmene3605d02018-10-18 06:27:53 +0000768StringRef llvm::getUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
769 LibFunc DoubleFn, LibFunc FloatFn,
770 LibFunc LongDoubleFn) {
771 assert(hasUnaryFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
772 "Cannot get name for unavailable function!");
773
774 switch (Ty->getTypeID()) {
775 case Type::HalfTyID:
776 llvm_unreachable("No name for HalfTy!");
777 case Type::FloatTyID:
778 return TLI->getName(FloatFn);
779 case Type::DoubleTyID:
780 return TLI->getName(DoubleFn);
781 default:
782 return TLI->getName(LongDoubleFn);
783 }
784}
785
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000786//- Emit LibCalls ------------------------------------------------------------//
787
Sanjay Pateld3112a52016-01-19 19:46:10 +0000788Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
Matt Arsenaultbe558882014-04-23 20:58:57 +0000789 unsigned AS = V->getType()->getPointerAddressSpace();
790 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
Eric Christopher87abfc52010-03-05 22:25:30 +0000791}
792
Sanjay Pateld3112a52016-01-19 19:46:10 +0000793Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000794 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000795 if (!TLI->has(LibFunc_strlen))
Craig Topperf40110f2014-04-25 05:29:35 +0000796 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000797
Sanjay Pateld4af2972016-01-19 19:58:49 +0000798 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000799 StringRef StrlenName = TLI->getName(LibFunc_strlen);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000800 LLVMContext &Context = B.GetInsertBlock()->getContext();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000801 Constant *StrLen = M->getOrInsertFunction(StrlenName, DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000802 B.getInt8PtrTy());
David Bolvansky7c7760d2018-10-16 21:18:31 +0000803 inferLibFuncAttributes(M, StrlenName, *TLI);
804 CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), StrlenName);
Evan Chengad6efbf2014-03-12 18:09:37 +0000805 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
806 CI->setCallingConv(F->getCallingConv());
807
Eric Christopher87abfc52010-03-05 22:25:30 +0000808 return CI;
809}
810
Sanjay Pateld3112a52016-01-19 19:46:10 +0000811Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000812 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000813 if (!TLI->has(LibFunc_strchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000814 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000815
Sanjay Pateld4af2972016-01-19 19:58:49 +0000816 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000817 StringRef StrChrName = TLI->getName(LibFunc_strchr);
Chris Lattner229907c2011-07-18 04:54:35 +0000818 Type *I8Ptr = B.getInt8PtrTy();
819 Type *I32Ty = B.getInt32Ty();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000820 Constant *StrChr =
David Bolvansky7c7760d2018-10-16 21:18:31 +0000821 M->getOrInsertFunction(StrChrName, I8Ptr, I8Ptr, I32Ty);
822 inferLibFuncAttributes(M, StrChrName, *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000823 CallInst *CI = B.CreateCall(
David Bolvansky7c7760d2018-10-16 21:18:31 +0000824 StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, StrChrName);
Evan Chengad6efbf2014-03-12 18:09:37 +0000825 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
826 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000827 return CI;
828}
829
Sanjay Pateld3112a52016-01-19 19:46:10 +0000830Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000831 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000832 if (!TLI->has(LibFunc_strncmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000833 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000834
Sanjay Pateld4af2972016-01-19 19:58:49 +0000835 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000836 StringRef StrNCmpName = TLI->getName(LibFunc_strncmp);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000837 LLVMContext &Context = B.GetInsertBlock()->getContext();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000838 Value *StrNCmp = M->getOrInsertFunction(StrNCmpName, B.getInt32Ty(),
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000839 B.getInt8PtrTy(), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000840 DL.getIntPtrType(Context));
David Bolvansky7c7760d2018-10-16 21:18:31 +0000841 inferLibFuncAttributes(M, StrNCmpName, *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000842 CallInst *CI = B.CreateCall(
David Bolvansky7c7760d2018-10-16 21:18:31 +0000843 StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, StrNCmpName);
Evan Chengad6efbf2014-03-12 18:09:37 +0000844
845 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
846 CI->setCallingConv(F->getCallingConv());
847
Benjamin Kramer11188602010-06-15 21:34:25 +0000848 return CI;
849}
850
Sanjay Pateld3112a52016-01-19 19:46:10 +0000851Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000852 const TargetLibraryInfo *TLI, StringRef Name) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000853 if (!TLI->has(LibFunc_strcpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000854 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000855
Sanjay Pateld4af2972016-01-19 19:58:49 +0000856 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000857 Type *I8Ptr = B.getInt8PtrTy();
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000858 Value *StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr);
David Bolvansky7c7760d2018-10-16 21:18:31 +0000859 inferLibFuncAttributes(M, Name, *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000860 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +0000861 B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
Evan Chengad6efbf2014-03-12 18:09:37 +0000862 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
863 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000864 return CI;
865}
866
Sanjay Pateld3112a52016-01-19 19:46:10 +0000867Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000868 const TargetLibraryInfo *TLI, StringRef Name) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000869 if (!TLI->has(LibFunc_strncpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000870 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000871
Sanjay Pateld4af2972016-01-19 19:58:49 +0000872 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000873 Type *I8Ptr = B.getInt8PtrTy();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000874 Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr,
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000875 Len->getType());
David Bolvansky7c7760d2018-10-16 21:18:31 +0000876 inferLibFuncAttributes(M, Name, *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000877 CallInst *CI = B.CreateCall(
David Bolvansky7c7760d2018-10-16 21:18:31 +0000878 StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, Name);
Evan Chengad6efbf2014-03-12 18:09:37 +0000879 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
880 CI->setCallingConv(F->getCallingConv());
Eric Christopher43dc11c2010-03-11 01:25:07 +0000881 return CI;
882}
883
Sanjay Pateld3112a52016-01-19 19:46:10 +0000884Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000885 IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000886 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000887 if (!TLI->has(LibFunc_memcpy_chk))
Craig Topperf40110f2014-04-25 05:29:35 +0000888 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000889
Sanjay Pateld4af2972016-01-19 19:58:49 +0000890 Module *M = B.GetInsertBlock()->getModule();
Reid Klecknerb5180542017-03-21 16:57:19 +0000891 AttributeList AS;
892 AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
893 Attribute::NoUnwind);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000894 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000895 Value *MemCpy = M->getOrInsertFunction(
Reid Klecknerb5180542017-03-21 16:57:19 +0000896 "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000897 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000898 DL.getIntPtrType(Context));
Sanjay Pateld3112a52016-01-19 19:46:10 +0000899 Dst = castToCStr(Dst, B);
900 Src = castToCStr(Src, B);
David Blaikieff6409d2015-05-18 22:13:54 +0000901 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
Evan Chengad6efbf2014-03-12 18:09:37 +0000902 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
903 CI->setCallingConv(F->getCallingConv());
Evan Chengd9e82232010-03-23 15:48:04 +0000904 return CI;
905}
906
Sanjay Pateld3112a52016-01-19 19:46:10 +0000907Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000908 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000909 if (!TLI->has(LibFunc_memchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000910 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000911
Sanjay Pateld4af2972016-01-19 19:58:49 +0000912 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000913 StringRef MemChrName = TLI->getName(LibFunc_memchr);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000914 LLVMContext &Context = B.GetInsertBlock()->getContext();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000915 Value *MemChr = M->getOrInsertFunction(MemChrName, B.getInt8PtrTy(),
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000916 B.getInt8PtrTy(), B.getInt32Ty(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000917 DL.getIntPtrType(Context));
David Bolvansky7c7760d2018-10-16 21:18:31 +0000918 inferLibFuncAttributes(M, MemChrName, *TLI);
919 CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, MemChrName);
Evan Chengad6efbf2014-03-12 18:09:37 +0000920
921 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
922 CI->setCallingConv(F->getCallingConv());
923
Eric Christopher87abfc52010-03-05 22:25:30 +0000924 return CI;
925}
926
Sanjay Pateld3112a52016-01-19 19:46:10 +0000927Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000928 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000929 if (!TLI->has(LibFunc_memcmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000930 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000931
Sanjay Pateld4af2972016-01-19 19:58:49 +0000932 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000933 StringRef MemCmpName = TLI->getName(LibFunc_memcmp);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000934 LLVMContext &Context = B.GetInsertBlock()->getContext();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000935 Value *MemCmp = M->getOrInsertFunction(MemCmpName, B.getInt32Ty(),
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000936 B.getInt8PtrTy(), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000937 DL.getIntPtrType(Context));
David Bolvansky7c7760d2018-10-16 21:18:31 +0000938 inferLibFuncAttributes(M, MemCmpName, *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000939 CallInst *CI = B.CreateCall(
David Bolvansky7c7760d2018-10-16 21:18:31 +0000940 MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, MemCmpName);
Evan Chengad6efbf2014-03-12 18:09:37 +0000941
942 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
943 CI->setCallingConv(F->getCallingConv());
944
Eric Christopher87abfc52010-03-05 22:25:30 +0000945 return CI;
946}
947
Yi Jiang6ab044e2013-12-16 22:42:40 +0000948/// Append a suffix to the function name according to the type of 'Op'.
Sanjay Pateld3112a52016-01-19 19:46:10 +0000949static void appendTypeSuffix(Value *Op, StringRef &Name,
Sanjay Patelb50325e2016-01-19 19:17:47 +0000950 SmallString<20> &NameBuffer) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000951 if (!Op->getType()->isDoubleTy()) {
952 NameBuffer += Name;
953
954 if (Op->getType()->isFloatTy())
955 NameBuffer += 'f';
956 else
957 NameBuffer += 'l';
958
959 Name = NameBuffer;
Fangrui Songf78650a2018-07-30 19:41:25 +0000960 }
Yi Jiang6ab044e2013-12-16 22:42:40 +0000961}
962
Mikael Holmene3605d02018-10-18 06:27:53 +0000963static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
964 IRBuilder<> &B,
965 const AttributeList &Attrs) {
966 assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
Eric Christopher87abfc52010-03-05 22:25:30 +0000967
Sanjay Pateld4af2972016-01-19 19:58:49 +0000968 Module *M = B.GetInsertBlock()->getModule();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000969 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000970 Op->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +0000971 CallInst *CI = B.CreateCall(Callee, Op, Name);
Matt Arsenault6a288c12017-05-03 02:26:10 +0000972
973 // The incoming attribute set may have come from a speculatable intrinsic, but
974 // is being replaced with a library call which is not allowed to be
975 // speculatable.
976 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
977 AttributeList::FunctionIndex,
978 Attribute::Speculatable));
Evan Chengad6efbf2014-03-12 18:09:37 +0000979 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
980 CI->setCallingConv(F->getCallingConv());
981
Eric Christopher87abfc52010-03-05 22:25:30 +0000982 return CI;
983}
984
Mikael Holmene3605d02018-10-18 06:27:53 +0000985Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
986 const AttributeList &Attrs) {
987 SmallString<20> NameBuffer;
988 appendTypeSuffix(Op, Name, NameBuffer);
989
990 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
991}
992
993Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
994 LibFunc DoubleFn, LibFunc FloatFn,
995 LibFunc LongDoubleFn, IRBuilder<> &B,
996 const AttributeList &Attrs) {
997 // Get the name of the function according to TLI.
998 StringRef Name = getUnaryFloatFn(TLI, Op->getType(),
999 DoubleFn, FloatFn, LongDoubleFn);
1000
1001 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1002}
1003
Sanjay Pateld3112a52016-01-19 19:46:10 +00001004Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
Reid Klecknerb5180542017-03-21 16:57:19 +00001005 IRBuilder<> &B, const AttributeList &Attrs) {
Mikael Holmene3605d02018-10-18 06:27:53 +00001006 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1007
Yi Jiang6ab044e2013-12-16 22:42:40 +00001008 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +00001009 appendTypeSuffix(Op1, Name, NameBuffer);
Yi Jiang6ab044e2013-12-16 22:42:40 +00001010
Sanjay Pateld4af2972016-01-19 19:58:49 +00001011 Module *M = B.GetInsertBlock()->getModule();
Sanjay Patelb50325e2016-01-19 19:17:47 +00001012 Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001013 Op2->getType());
David Blaikieff6409d2015-05-18 22:13:54 +00001014 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
Yi Jiang6ab044e2013-12-16 22:42:40 +00001015 CI->setAttributes(Attrs);
Evan Chengad6efbf2014-03-12 18:09:37 +00001016 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
1017 CI->setCallingConv(F->getCallingConv());
1018
Yi Jiang6ab044e2013-12-16 22:42:40 +00001019 return CI;
1020}
1021
Sanjay Pateld3112a52016-01-19 19:46:10 +00001022Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +00001023 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001024 if (!TLI->has(LibFunc_putchar))
Craig Topperf40110f2014-04-25 05:29:35 +00001025 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001026
Sanjay Pateld4af2972016-01-19 19:58:49 +00001027 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001028 StringRef PutCharName = TLI->getName(LibFunc_putchar);
1029 Value *PutChar = M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty());
1030 inferLibFuncAttributes(M, PutCharName, *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001031 CallInst *CI = B.CreateCall(PutChar,
1032 B.CreateIntCast(Char,
1033 B.getInt32Ty(),
1034 /*isSigned*/true,
1035 "chari"),
David Bolvansky7c7760d2018-10-16 21:18:31 +00001036 PutCharName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001037
1038 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
1039 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +00001040 return CI;
1041}
1042
Sanjay Pateld3112a52016-01-19 19:46:10 +00001043Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +00001044 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001045 if (!TLI->has(LibFunc_puts))
Craig Topperf40110f2014-04-25 05:29:35 +00001046 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001047
Sanjay Pateld4af2972016-01-19 19:58:49 +00001048 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001049 StringRef PutsName = TLI->getName(LibFunc_puts);
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001050 Value *PutS =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001051 M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy());
1052 inferLibFuncAttributes(M, PutsName, *TLI);
1053 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001054 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
1055 CI->setCallingConv(F->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001056 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001057}
1058
Sanjay Pateld3112a52016-01-19 19:46:10 +00001059Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001060 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001061 if (!TLI->has(LibFunc_fputc))
Craig Topperf40110f2014-04-25 05:29:35 +00001062 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001063
Sanjay Pateld4af2972016-01-19 19:58:49 +00001064 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001065 StringRef FPutcName = TLI->getName(LibFunc_fputc);
1066 Constant *F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(), B.getInt32Ty(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001067 File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001068 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001069 inferLibFuncAttributes(M, FPutcName, *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001070 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
1071 "chari");
David Bolvansky7c7760d2018-10-16 21:18:31 +00001072 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001073
1074 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1075 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001076 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001077}
1078
David Bolvanskyca22d422018-05-16 11:39:52 +00001079Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
1080 const TargetLibraryInfo *TLI) {
1081 if (!TLI->has(LibFunc_fputc_unlocked))
1082 return nullptr;
1083
1084 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001085 StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked);
1086 Constant *F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(),
David Bolvanskyca22d422018-05-16 11:39:52 +00001087 B.getInt32Ty(), File->getType());
1088 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001089 inferLibFuncAttributes(M, FPutcUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001090 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
David Bolvansky7c7760d2018-10-16 21:18:31 +00001091 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001092
1093 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1094 CI->setCallingConv(Fn->getCallingConv());
1095 return CI;
1096}
1097
Sanjay Pateld3112a52016-01-19 19:46:10 +00001098Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001099 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001100 if (!TLI->has(LibFunc_fputs))
Craig Topperf40110f2014-04-25 05:29:35 +00001101 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001102
Sanjay Pateld4af2972016-01-19 19:58:49 +00001103 Module *M = B.GetInsertBlock()->getModule();
David L. Jonesd21529f2017-01-23 23:16:46 +00001104 StringRef FPutsName = TLI->getName(LibFunc_fputs);
Mehdi Aminidb11fdf2017-04-06 20:23:57 +00001105 Constant *F = M->getOrInsertFunction(
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001106 FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001107 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001108 inferLibFuncAttributes(M, FPutsName, *TLI);
1109 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001110
1111 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1112 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001113 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001114}
1115
David Bolvanskyca22d422018-05-16 11:39:52 +00001116Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
1117 const TargetLibraryInfo *TLI) {
1118 if (!TLI->has(LibFunc_fputs_unlocked))
1119 return nullptr;
1120
1121 Module *M = B.GetInsertBlock()->getModule();
1122 StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
1123 Constant *F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
1124 B.getInt8PtrTy(), File->getType());
1125 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001126 inferLibFuncAttributes(M, FPutsUnlockedName, *TLI);
1127 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001128
1129 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1130 CI->setCallingConv(Fn->getCallingConv());
1131 return CI;
1132}
1133
Sanjay Pateld3112a52016-01-19 19:46:10 +00001134Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001135 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001136 if (!TLI->has(LibFunc_fwrite))
Craig Topperf40110f2014-04-25 05:29:35 +00001137 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001138
Sanjay Pateld4af2972016-01-19 19:58:49 +00001139 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +00001140 LLVMContext &Context = B.GetInsertBlock()->getContext();
David L. Jonesd21529f2017-01-23 23:16:46 +00001141 StringRef FWriteName = TLI->getName(LibFunc_fwrite);
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001142 Constant *F = M->getOrInsertFunction(
1143 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001144 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1145
Eric Christopher87abfc52010-03-05 22:25:30 +00001146 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001147 inferLibFuncAttributes(M, FWriteName, *TLI);
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001148 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +00001149 B.CreateCall(F, {castToCStr(Ptr, B), Size,
David Blaikieff6409d2015-05-18 22:13:54 +00001150 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
Evan Chengad6efbf2014-03-12 18:09:37 +00001151
1152 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1153 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001154 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001155}
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001156
1157Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
1158 const TargetLibraryInfo *TLI) {
1159 if (!TLI->has(LibFunc_malloc))
1160 return nullptr;
1161
1162 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001163 StringRef MallocName = TLI->getName(LibFunc_malloc);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001164 LLVMContext &Context = B.GetInsertBlock()->getContext();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001165 Value *Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(),
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001166 DL.getIntPtrType(Context));
David Bolvansky7c7760d2018-10-16 21:18:31 +00001167 inferLibFuncAttributes(M, MallocName, *TLI);
1168 CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001169
1170 if (const Function *F = dyn_cast<Function>(Malloc->stripPointerCasts()))
1171 CI->setCallingConv(F->getCallingConv());
1172
1173 return CI;
1174}
1175
1176Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
1177 IRBuilder<> &B, const TargetLibraryInfo &TLI) {
1178 if (!TLI.has(LibFunc_calloc))
1179 return nullptr;
1180
1181 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001182 StringRef CallocName = TLI.getName(LibFunc_calloc);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001183 const DataLayout &DL = M->getDataLayout();
1184 IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
David Bolvansky7c7760d2018-10-16 21:18:31 +00001185 Value *Calloc = M->getOrInsertFunction(CallocName, Attrs, B.getInt8PtrTy(),
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001186 PtrType, PtrType);
David Bolvansky7c7760d2018-10-16 21:18:31 +00001187 inferLibFuncAttributes(M, CallocName, TLI);
1188 CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001189
1190 if (const auto *F = dyn_cast<Function>(Calloc->stripPointerCasts()))
1191 CI->setCallingConv(F->getCallingConv());
1192
1193 return CI;
1194}
David Bolvanskyca22d422018-05-16 11:39:52 +00001195
1196Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1197 IRBuilder<> &B, const DataLayout &DL,
1198 const TargetLibraryInfo *TLI) {
1199 if (!TLI->has(LibFunc_fwrite_unlocked))
1200 return nullptr;
1201
1202 Module *M = B.GetInsertBlock()->getModule();
1203 LLVMContext &Context = B.GetInsertBlock()->getContext();
1204 StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
1205 Constant *F = M->getOrInsertFunction(
1206 FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1207 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1208
1209 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001210 inferLibFuncAttributes(M, FWriteUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001211 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1212
1213 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1214 CI->setCallingConv(Fn->getCallingConv());
1215 return CI;
1216}
1217
1218Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
1219 const TargetLibraryInfo *TLI) {
1220 if (!TLI->has(LibFunc_fgetc_unlocked))
1221 return nullptr;
1222
1223 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001224 StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked);
David Bolvanskyca22d422018-05-16 11:39:52 +00001225 Constant *F =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001226 M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001227 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001228 inferLibFuncAttributes(M, FGetCUnlockedName, *TLI);
1229 CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001230
1231 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1232 CI->setCallingConv(Fn->getCallingConv());
1233 return CI;
1234}
1235
1236Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
1237 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1238 if (!TLI->has(LibFunc_fgets_unlocked))
1239 return nullptr;
1240
1241 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001242 StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked);
David Bolvanskyca22d422018-05-16 11:39:52 +00001243 Constant *F =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001244 M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(),
Benjamin Kramer8ac15bf2018-05-16 21:45:39 +00001245 B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
David Bolvansky7c7760d2018-10-16 21:18:31 +00001246 inferLibFuncAttributes(M, FGetSUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001247 CallInst *CI =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001248 B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001249
1250 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1251 CI->setCallingConv(Fn->getCallingConv());
1252 return CI;
1253}
1254
1255Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1256 IRBuilder<> &B, const DataLayout &DL,
1257 const TargetLibraryInfo *TLI) {
1258 if (!TLI->has(LibFunc_fread_unlocked))
1259 return nullptr;
1260
1261 Module *M = B.GetInsertBlock()->getModule();
1262 LLVMContext &Context = B.GetInsertBlock()->getContext();
1263 StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
1264 Constant *F = M->getOrInsertFunction(
1265 FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1266 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1267
1268 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001269 inferLibFuncAttributes(M, FReadUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001270 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1271
1272 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1273 CI->setCallingConv(Fn->getCallingConv());
1274 return CI;
1275}