blob: 71316ce8f7583981cc37a2d28a28cffa886016c4 [file] [log] [blame]
Eric Christopher87abfc52010-03-05 22:25:30 +00001//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Eric Christopher87abfc52010-03-05 22:25:30 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements some functions that will create standard C libcalls.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/Transforms/Utils/BuildLibCalls.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000014#include "llvm/ADT/SmallString.h"
Ahmed Bougachab0624a22016-04-27 19:04:40 +000015#include "llvm/ADT/Statistic.h"
Weiming Zhao45d4cb92015-11-24 18:57:06 +000016#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000017#include "llvm/IR/Constants.h"
18#include "llvm/IR/DataLayout.h"
19#include "llvm/IR/Function.h"
20#include "llvm/IR/IRBuilder.h"
21#include "llvm/IR/Intrinsics.h"
22#include "llvm/IR/LLVMContext.h"
23#include "llvm/IR/Module.h"
24#include "llvm/IR/Type.h"
Brian Homerdingb4b21d82019-07-08 15:57:56 +000025#include "llvm/Analysis/MemoryBuiltins.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
David Bolvansky0e0fbae2019-08-14 16:50:06 +000091static bool setDoesNotAlias(Function &F, unsigned ArgNo) {
92 if (F.hasParamAttribute(ArgNo, Attribute::NoAlias))
93 return false;
94 F.addParamAttr(ArgNo, Attribute::NoAlias);
95 ++NumNoAlias;
96 return true;
97}
98
Reid Klecknera0b45f42017-05-03 18:17:31 +000099static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
100 if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))
101 return false;
102 F.addParamAttr(ArgNo, Attribute::ReadOnly);
103 ++NumReadOnlyArg;
104 return true;
105}
106
107static bool setRetNonNull(Function &F) {
108 assert(F.getReturnType()->isPointerTy() &&
109 "nonnull applies only to pointers");
110 if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull))
111 return false;
112 F.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000113 ++NumNonNull;
114 return true;
115}
116
David Bolvansky8715e032018-08-23 05:18:23 +0000117static bool setReturnedArg(Function &F, unsigned ArgNo) {
118 if (F.hasParamAttribute(ArgNo, Attribute::Returned))
119 return false;
120 F.addParamAttr(ArgNo, Attribute::Returned);
121 ++NumReturnedArg;
122 return true;
123}
124
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000125static bool setNonLazyBind(Function &F) {
126 if (F.hasFnAttribute(Attribute::NonLazyBind))
127 return false;
128 F.addFnAttr(Attribute::NonLazyBind);
129 return true;
130}
131
Brian Homerdingb4b21d82019-07-08 15:57:56 +0000132static bool setDoesNotFreeMemory(Function &F) {
133 if (F.hasFnAttribute(Attribute::NoFree))
134 return false;
135 F.addFnAttr(Attribute::NoFree);
136 return true;
137}
138
David Bolvansky7c7760d2018-10-16 21:18:31 +0000139bool llvm::inferLibFuncAttributes(Module *M, StringRef Name,
David Bolvanskye8b3bba2018-10-13 15:21:55 +0000140 const TargetLibraryInfo &TLI) {
David Bolvansky7c7760d2018-10-16 21:18:31 +0000141 Function *F = M->getFunction(Name);
142 if (!F)
David Bolvanskye8b3bba2018-10-13 15:21:55 +0000143 return false;
David Bolvansky7c7760d2018-10-16 21:18:31 +0000144 return inferLibFuncAttributes(*F, TLI);
145}
146
147bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000148 LibFunc TheLibFunc;
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000149 if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
150 return false;
151
152 bool Changed = false;
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000153
Brian Homerdingb4b21d82019-07-08 15:57:56 +0000154 if(!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F, &TLI))
155 Changed |= setDoesNotFreeMemory(F);
156
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000157 if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
158 Changed |= setNonLazyBind(F);
159
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000160 switch (TheLibFunc) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000161 case LibFunc_strlen:
Matthias Braun60b40b82017-05-05 20:25:50 +0000162 case LibFunc_wcslen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000163 Changed |= setOnlyReadsMemory(F);
164 Changed |= setDoesNotThrow(F);
Xin Tong9d2a5b12017-06-18 03:10:26 +0000165 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000166 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000167 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000168 case LibFunc_strchr:
169 case LibFunc_strrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000170 Changed |= setOnlyReadsMemory(F);
171 Changed |= setDoesNotThrow(F);
172 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000173 case LibFunc_strtol:
174 case LibFunc_strtod:
175 case LibFunc_strtof:
176 case LibFunc_strtoul:
177 case LibFunc_strtoll:
178 case LibFunc_strtold:
179 case LibFunc_strtoull:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000180 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000181 Changed |= setDoesNotCapture(F, 1);
182 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000183 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000184 case LibFunc_strcpy:
David Bolvansky8715e032018-08-23 05:18:23 +0000185 case LibFunc_strncpy:
David Bolvansky0e0fbae2019-08-14 16:50:06 +0000186 Changed |= setDoesNotAlias(F, 0);
187 Changed |= setDoesNotAlias(F, 1);
188 LLVM_FALLTHROUGH;
David L. Jonesd21529f2017-01-23 23:16:46 +0000189 case LibFunc_strcat:
190 case LibFunc_strncat:
David Bolvansky8715e032018-08-23 05:18:23 +0000191 Changed |= setReturnedArg(F, 0);
192 LLVM_FALLTHROUGH;
193 case LibFunc_stpcpy:
David L. Jonesd21529f2017-01-23 23:16:46 +0000194 case LibFunc_stpncpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000195 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000196 Changed |= setDoesNotCapture(F, 1);
197 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000198 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000199 case LibFunc_strxfrm:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000200 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000201 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000202 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000203 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000204 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000205 case LibFunc_strcmp: // 0,1
206 case LibFunc_strspn: // 0,1
207 case LibFunc_strncmp: // 0,1
208 case LibFunc_strcspn: // 0,1
209 case LibFunc_strcoll: // 0,1
210 case LibFunc_strcasecmp: // 0,1
211 case LibFunc_strncasecmp: //
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000212 Changed |= setOnlyReadsMemory(F);
213 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000214 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000215 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000216 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000217 case LibFunc_strstr:
218 case LibFunc_strpbrk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000219 Changed |= setOnlyReadsMemory(F);
220 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000221 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000222 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000223 case LibFunc_strtok:
224 case LibFunc_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000225 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000226 Changed |= setDoesNotCapture(F, 1);
227 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000228 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000229 case LibFunc_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000230 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000231 Changed |= setDoesNotCapture(F, 0);
232 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000233 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000234 case LibFunc_setbuf:
235 case LibFunc_setvbuf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000236 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000237 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000238 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000239 case LibFunc_strdup:
240 case LibFunc_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000241 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000242 Changed |= setRetDoesNotAlias(F);
243 Changed |= setDoesNotCapture(F, 0);
244 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000245 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000246 case LibFunc_stat:
247 case LibFunc_statvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000248 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000249 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000250 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000251 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000252 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000253 case LibFunc_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000254 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000255 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000256 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000257 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000258 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000259 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000260 case LibFunc_sprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000261 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000262 Changed |= setDoesNotCapture(F, 0);
David Bolvansky0e0fbae2019-08-14 16:50:06 +0000263 Changed |= setDoesNotAlias(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000264 Changed |= setDoesNotCapture(F, 1);
265 Changed |= setOnlyReadsMemory(F, 1);
266 return Changed;
Reid Klecknera0b45f42017-05-03 18:17:31 +0000267 case LibFunc_snprintf:
268 Changed |= setDoesNotThrow(F);
269 Changed |= setDoesNotCapture(F, 0);
David Bolvansky0e0fbae2019-08-14 16:50:06 +0000270 Changed |= setDoesNotAlias(F, 0);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000271 Changed |= setDoesNotCapture(F, 2);
272 Changed |= setOnlyReadsMemory(F, 2);
273 return Changed;
274 case LibFunc_setitimer:
275 Changed |= setDoesNotThrow(F);
276 Changed |= setDoesNotCapture(F, 1);
277 Changed |= setDoesNotCapture(F, 2);
278 Changed |= setOnlyReadsMemory(F, 1);
279 return Changed;
280 case LibFunc_system:
281 // May throw; "system" is a valid pthread cancellation point.
282 Changed |= setDoesNotCapture(F, 0);
283 Changed |= setOnlyReadsMemory(F, 0);
284 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000285 case LibFunc_malloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000286 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000287 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000288 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000289 case LibFunc_memcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000290 Changed |= setOnlyReadsMemory(F);
291 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000292 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000293 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000294 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000295 case LibFunc_memchr:
296 case LibFunc_memrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000297 Changed |= setOnlyReadsMemory(F);
298 Changed |= setDoesNotThrow(F);
299 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000300 case LibFunc_modf:
301 case LibFunc_modff:
302 case LibFunc_modfl:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000303 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000304 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000305 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000306 case LibFunc_memcpy:
David Bolvansky0e0fbae2019-08-14 16:50:06 +0000307 Changed |= setDoesNotAlias(F, 0);
308 Changed |= setDoesNotAlias(F, 1);
David Bolvanskya05e6712019-09-30 19:43:48 +0000309 Changed |= setReturnedArg(F, 0);
310 Changed |= setDoesNotThrow(F);
311 Changed |= setDoesNotCapture(F, 1);
312 Changed |= setOnlyReadsMemory(F, 1);
313 return Changed;
David Bolvansky8715e032018-08-23 05:18:23 +0000314 case LibFunc_memmove:
315 Changed |= setReturnedArg(F, 0);
David Bolvanskya05e6712019-09-30 19:43:48 +0000316 Changed |= setDoesNotThrow(F);
317 Changed |= setDoesNotCapture(F, 1);
318 Changed |= setOnlyReadsMemory(F, 1);
319 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000320 case LibFunc_mempcpy:
321 case LibFunc_memccpy:
David Bolvanskya05e6712019-09-30 19:43:48 +0000322 Changed |= setDoesNotAlias(F, 0);
323 Changed |= setDoesNotAlias(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000324 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000325 Changed |= setDoesNotCapture(F, 1);
326 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000327 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000328 case LibFunc_memcpy_chk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000329 Changed |= setDoesNotThrow(F);
330 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000331 case LibFunc_memalign:
Reid Klecknera0b45f42017-05-03 18:17:31 +0000332 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000333 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000334 case LibFunc_mkdir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000335 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000336 Changed |= setDoesNotCapture(F, 0);
337 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000338 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000339 case LibFunc_mktime:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000340 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000341 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000342 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000343 case LibFunc_realloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000344 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000345 Changed |= setRetDoesNotAlias(F);
346 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000347 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000348 case LibFunc_read:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000349 // May throw; "read" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000350 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000351 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000352 case LibFunc_rewind:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000353 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000354 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000355 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000356 case LibFunc_rmdir:
357 case LibFunc_remove:
358 case LibFunc_realpath:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000359 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000360 Changed |= setDoesNotCapture(F, 0);
361 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000362 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000363 case LibFunc_rename:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000364 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000365 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000366 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000367 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000368 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000369 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000370 case LibFunc_readlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000371 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000372 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000373 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000374 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000375 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000376 case LibFunc_write:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000377 // May throw; "write" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000378 Changed |= setDoesNotCapture(F, 1);
379 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000380 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000381 case LibFunc_bcopy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000382 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000383 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000384 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000385 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000386 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000387 case LibFunc_bcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000388 Changed |= setDoesNotThrow(F);
389 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000390 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000391 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000392 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000393 case LibFunc_bzero:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000394 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000395 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000396 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000397 case LibFunc_calloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000398 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000399 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000400 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000401 case LibFunc_chmod:
402 case LibFunc_chown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000403 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000404 Changed |= setDoesNotCapture(F, 0);
405 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000406 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000407 case LibFunc_ctermid:
408 case LibFunc_clearerr:
409 case LibFunc_closedir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000410 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000411 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000412 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000413 case LibFunc_atoi:
414 case LibFunc_atol:
415 case LibFunc_atof:
416 case LibFunc_atoll:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000417 Changed |= setDoesNotThrow(F);
418 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000419 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000420 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000421 case LibFunc_access:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000422 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000423 Changed |= setDoesNotCapture(F, 0);
424 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000425 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000426 case LibFunc_fopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000427 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000428 Changed |= setRetDoesNotAlias(F);
429 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000430 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000431 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000432 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000433 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000434 case LibFunc_fdopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000435 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000436 Changed |= setRetDoesNotAlias(F);
437 Changed |= setDoesNotCapture(F, 1);
438 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000439 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000440 case LibFunc_feof:
441 case LibFunc_free:
442 case LibFunc_fseek:
443 case LibFunc_ftell:
444 case LibFunc_fgetc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000445 case LibFunc_fgetc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000446 case LibFunc_fseeko:
447 case LibFunc_ftello:
448 case LibFunc_fileno:
449 case LibFunc_fflush:
450 case LibFunc_fclose:
451 case LibFunc_fsetpos:
452 case LibFunc_flockfile:
453 case LibFunc_funlockfile:
454 case LibFunc_ftrylockfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000455 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000456 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000457 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000458 case LibFunc_ferror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000459 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000460 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000461 Changed |= setOnlyReadsMemory(F);
462 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000463 case LibFunc_fputc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000464 case LibFunc_fputc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000465 case LibFunc_fstat:
466 case LibFunc_frexp:
467 case LibFunc_frexpf:
468 case LibFunc_frexpl:
469 case LibFunc_fstatvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000470 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000471 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000472 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000473 case LibFunc_fgets:
David Bolvanskyca22d422018-05-16 11:39:52 +0000474 case LibFunc_fgets_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000475 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000476 Changed |= setDoesNotCapture(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000477 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000478 case LibFunc_fread:
David Bolvanskyca22d422018-05-16 11:39:52 +0000479 case LibFunc_fread_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000480 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000481 Changed |= setDoesNotCapture(F, 0);
482 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000483 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000484 case LibFunc_fwrite:
David Bolvanskyca22d422018-05-16 11:39:52 +0000485 case LibFunc_fwrite_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000486 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000487 Changed |= setDoesNotCapture(F, 0);
488 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000489 // FIXME: readonly #1?
490 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000491 case LibFunc_fputs:
David Bolvanskyca22d422018-05-16 11:39:52 +0000492 case LibFunc_fputs_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000493 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000494 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000495 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000496 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000497 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000498 case LibFunc_fscanf:
499 case LibFunc_fprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000500 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000501 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000502 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +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_fgetpos:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000506 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000507 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +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_getc:
511 case LibFunc_getlogin_r:
512 case LibFunc_getc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000513 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000514 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000515 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000516 case LibFunc_getenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000517 Changed |= setDoesNotThrow(F);
518 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000519 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000520 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000521 case LibFunc_gets:
522 case LibFunc_getchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000523 case LibFunc_getchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000524 Changed |= setDoesNotThrow(F);
525 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000526 case LibFunc_getitimer:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000527 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000528 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000529 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000530 case LibFunc_getpwnam:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000531 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000532 Changed |= setDoesNotCapture(F, 0);
533 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000534 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000535 case LibFunc_ungetc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000536 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000537 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000538 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000539 case LibFunc_uname:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000540 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000541 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000542 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000543 case LibFunc_unlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000544 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000545 Changed |= setDoesNotCapture(F, 0);
546 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000547 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000548 case LibFunc_unsetenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000549 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000550 Changed |= setDoesNotCapture(F, 0);
551 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000552 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000553 case LibFunc_utime:
554 case LibFunc_utimes:
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, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000559 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000560 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000561 case LibFunc_putc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000562 case LibFunc_putc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000563 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000564 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000565 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000566 case LibFunc_puts:
567 case LibFunc_printf:
568 case LibFunc_perror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000569 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000570 Changed |= setDoesNotCapture(F, 0);
571 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000572 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000573 case LibFunc_pread:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000574 // May throw; "pread" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000575 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000576 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000577 case LibFunc_pwrite:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000578 // May throw; "pwrite" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000579 Changed |= setDoesNotCapture(F, 1);
580 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000581 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000582 case LibFunc_putchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000583 case LibFunc_putchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000584 Changed |= setDoesNotThrow(F);
585 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000586 case LibFunc_popen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000587 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000588 Changed |= setRetDoesNotAlias(F);
589 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000590 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000591 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000592 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000593 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000594 case LibFunc_pclose:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000595 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000596 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000597 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000598 case LibFunc_vscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000599 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000600 Changed |= setDoesNotCapture(F, 0);
601 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000602 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000603 case LibFunc_vsscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000604 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000605 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000606 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000607 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000608 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000609 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000610 case LibFunc_vfscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000611 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000612 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000613 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000614 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000615 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000616 case LibFunc_valloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000617 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000618 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000619 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000620 case LibFunc_vprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000621 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000622 Changed |= setDoesNotCapture(F, 0);
623 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000624 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000625 case LibFunc_vfprintf:
626 case LibFunc_vsprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000627 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000628 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000629 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000630 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000631 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000632 case LibFunc_vsnprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000633 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000634 Changed |= setDoesNotCapture(F, 0);
635 Changed |= setDoesNotCapture(F, 2);
636 Changed |= setOnlyReadsMemory(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000637 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000638 case LibFunc_open:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000639 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000640 Changed |= setDoesNotCapture(F, 0);
641 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000642 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000643 case LibFunc_opendir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000644 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000645 Changed |= setRetDoesNotAlias(F);
646 Changed |= setDoesNotCapture(F, 0);
647 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000648 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000649 case LibFunc_tmpfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000650 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000651 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000652 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000653 case LibFunc_times:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000654 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000655 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000656 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000657 case LibFunc_htonl:
658 case LibFunc_htons:
659 case LibFunc_ntohl:
660 case LibFunc_ntohs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000661 Changed |= setDoesNotThrow(F);
662 Changed |= setDoesNotAccessMemory(F);
663 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000664 case LibFunc_lstat:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000665 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000666 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 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000670 case LibFunc_lchown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000671 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000672 Changed |= setDoesNotCapture(F, 0);
673 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000674 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000675 case LibFunc_qsort:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000676 // May throw; places call through function pointer.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000677 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000678 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000679 case LibFunc_dunder_strdup:
680 case LibFunc_dunder_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000681 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000682 Changed |= setRetDoesNotAlias(F);
683 Changed |= setDoesNotCapture(F, 0);
684 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000685 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000686 case LibFunc_dunder_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000687 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000688 Changed |= setDoesNotCapture(F, 1);
689 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000690 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000691 case LibFunc_under_IO_getc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000692 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000693 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000694 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000695 case LibFunc_under_IO_putc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000696 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000697 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000698 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000699 case LibFunc_dunder_isoc99_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000700 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000701 Changed |= setDoesNotCapture(F, 0);
702 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000703 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000704 case LibFunc_stat64:
705 case LibFunc_lstat64:
706 case LibFunc_statvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000707 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000708 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000709 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000710 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000711 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000712 case LibFunc_dunder_isoc99_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000713 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000714 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000715 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000716 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000717 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000718 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000719 case LibFunc_fopen64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000720 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000721 Changed |= setRetDoesNotAlias(F);
722 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000723 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000724 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000725 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000726 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000727 case LibFunc_fseeko64:
728 case LibFunc_ftello64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000729 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000730 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000731 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000732 case LibFunc_tmpfile64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000733 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000734 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000735 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000736 case LibFunc_fstat64:
737 case LibFunc_fstatvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000738 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000739 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000740 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000741 case LibFunc_open64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000742 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000743 Changed |= setDoesNotCapture(F, 0);
744 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000745 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000746 case LibFunc_gettimeofday:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000747 // Currently some platforms have the restrict keyword on the arguments to
748 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
749 // arguments.
750 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000751 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000752 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000753 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000754 case LibFunc_Znwj: // new(unsigned int)
755 case LibFunc_Znwm: // new(unsigned long)
756 case LibFunc_Znaj: // new[](unsigned int)
757 case LibFunc_Znam: // new[](unsigned long)
758 case LibFunc_msvc_new_int: // new(unsigned int)
759 case LibFunc_msvc_new_longlong: // new(unsigned long long)
760 case LibFunc_msvc_new_array_int: // new[](unsigned int)
761 case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000762 // Operator new always returns a nonnull noalias pointer
Reid Klecknera0b45f42017-05-03 18:17:31 +0000763 Changed |= setRetNonNull(F);
764 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000765 return Changed;
David Bolvansky3ea50f92018-04-25 04:33:36 +0000766 // TODO: add LibFunc entries for:
767 // case LibFunc_memset_pattern4:
768 // case LibFunc_memset_pattern8:
David L. Jonesd21529f2017-01-23 23:16:46 +0000769 case LibFunc_memset_pattern16:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000770 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000771 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougacha44c19872016-04-27 19:04:43 +0000772 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000773 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000774 return Changed;
775 // int __nvvm_reflect(const char *)
David L. Jonesd21529f2017-01-23 23:16:46 +0000776 case LibFunc_nvvm_reflect:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000777 Changed |= setDoesNotAccessMemory(F);
778 Changed |= setDoesNotThrow(F);
779 return Changed;
780
781 default:
782 // FIXME: It'd be really nice to cover all the library functions we're
783 // aware of here.
784 return false;
785 }
786}
787
Evandro Menezesc6c00cd2019-08-09 16:04:18 +0000788bool llvm::hasFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
789 LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) {
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000790 switch (Ty->getTypeID()) {
Benjamin Kramere5e1ea72018-09-19 12:01:38 +0000791 case Type::HalfTyID:
792 return false;
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000793 case Type::FloatTyID:
794 return TLI->has(FloatFn);
795 case Type::DoubleTyID:
796 return TLI->has(DoubleFn);
797 default:
798 return TLI->has(LongDoubleFn);
799 }
800}
801
Evandro Menezesc6c00cd2019-08-09 16:04:18 +0000802StringRef llvm::getFloatFnName(const TargetLibraryInfo *TLI, Type *Ty,
803 LibFunc DoubleFn, LibFunc FloatFn,
804 LibFunc LongDoubleFn) {
805 assert(hasFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
Mikael Holmene3605d02018-10-18 06:27:53 +0000806 "Cannot get name for unavailable function!");
807
808 switch (Ty->getTypeID()) {
809 case Type::HalfTyID:
810 llvm_unreachable("No name for HalfTy!");
811 case Type::FloatTyID:
812 return TLI->getName(FloatFn);
813 case Type::DoubleTyID:
814 return TLI->getName(DoubleFn);
815 default:
816 return TLI->getName(LongDoubleFn);
817 }
818}
819
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000820//- Emit LibCalls ------------------------------------------------------------//
821
Sanjay Pateld3112a52016-01-19 19:46:10 +0000822Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
Matt Arsenaultbe558882014-04-23 20:58:57 +0000823 unsigned AS = V->getType()->getPointerAddressSpace();
824 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
Eric Christopher87abfc52010-03-05 22:25:30 +0000825}
826
Erik Pilkington52349212019-05-31 22:41:31 +0000827static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType,
828 ArrayRef<Type *> ParamTypes,
829 ArrayRef<Value *> Operands, IRBuilder<> &B,
830 const TargetLibraryInfo *TLI,
831 bool IsVaArgs = false) {
832 if (!TLI->has(TheLibFunc))
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();
Erik Pilkington52349212019-05-31 22:41:31 +0000836 StringRef FuncName = TLI->getName(TheLibFunc);
837 FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs);
838 FunctionCallee Callee = M->getOrInsertFunction(FuncName, FuncType);
839 inferLibFuncAttributes(M, FuncName, *TLI);
840 CallInst *CI = B.CreateCall(Callee, Operands, FuncName);
James Y Knight13680222019-02-01 02:28:03 +0000841 if (const Function *F =
Erik Pilkington52349212019-05-31 22:41:31 +0000842 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000843 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000844 return CI;
845}
846
Erik Pilkington52349212019-05-31 22:41:31 +0000847Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
848 const TargetLibraryInfo *TLI) {
849 LLVMContext &Context = B.GetInsertBlock()->getContext();
850 return emitLibCall(LibFunc_strlen, DL.getIntPtrType(Context),
851 B.getInt8PtrTy(), castToCStr(Ptr, B), B, TLI);
852}
853
David Bolvansky8d520162019-09-23 18:20:01 +0000854Value *llvm::emitStrDup(Value *Ptr, IRBuilder<> &B,
855 const TargetLibraryInfo *TLI) {
856 return emitLibCall(LibFunc_strdup, B.getInt8PtrTy(), B.getInt8PtrTy(),
857 castToCStr(Ptr, B), B, TLI);
858}
859
Sanjay Pateld3112a52016-01-19 19:46:10 +0000860Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000861 const TargetLibraryInfo *TLI) {
Chris Lattner229907c2011-07-18 04:54:35 +0000862 Type *I8Ptr = B.getInt8PtrTy();
863 Type *I32Ty = B.getInt32Ty();
Erik Pilkington52349212019-05-31 22:41:31 +0000864 return emitLibCall(LibFunc_strchr, I8Ptr, {I8Ptr, I32Ty},
865 {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, B, TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000866}
867
Sanjay Pateld3112a52016-01-19 19:46:10 +0000868Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000869 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Chandler Carruth7ec50852012-11-01 08:07:29 +0000870 LLVMContext &Context = B.GetInsertBlock()->getContext();
Erik Pilkington52349212019-05-31 22:41:31 +0000871 return emitLibCall(
872 LibFunc_strncmp, B.getInt32Ty(),
873 {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
874 {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
Benjamin Kramer11188602010-06-15 21:34:25 +0000875}
876
Sanjay Pateld3112a52016-01-19 19:46:10 +0000877Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Erik Pilkington52349212019-05-31 22:41:31 +0000878 const TargetLibraryInfo *TLI) {
Chris Lattner229907c2011-07-18 04:54:35 +0000879 Type *I8Ptr = B.getInt8PtrTy();
Erik Pilkington52349212019-05-31 22:41:31 +0000880 return emitLibCall(LibFunc_strcpy, I8Ptr, {I8Ptr, I8Ptr},
881 {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI);
882}
883
884Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilder<> &B,
885 const TargetLibraryInfo *TLI) {
886 Type *I8Ptr = B.getInt8PtrTy();
887 return emitLibCall(LibFunc_stpcpy, I8Ptr, {I8Ptr, I8Ptr},
888 {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000889}
890
Sanjay Pateld3112a52016-01-19 19:46:10 +0000891Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
Erik Pilkington52349212019-05-31 22:41:31 +0000892 const TargetLibraryInfo *TLI) {
Chris Lattner229907c2011-07-18 04:54:35 +0000893 Type *I8Ptr = B.getInt8PtrTy();
Erik Pilkington52349212019-05-31 22:41:31 +0000894 return emitLibCall(LibFunc_strncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()},
895 {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI);
896}
897
898Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
899 const TargetLibraryInfo *TLI) {
900 Type *I8Ptr = B.getInt8PtrTy();
901 return emitLibCall(LibFunc_stpncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()},
902 {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI);
Eric Christopher43dc11c2010-03-11 01:25:07 +0000903}
904
Sanjay Pateld3112a52016-01-19 19:46:10 +0000905Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000906 IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000907 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000908 if (!TLI->has(LibFunc_memcpy_chk))
Craig Topperf40110f2014-04-25 05:29:35 +0000909 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000910
Sanjay Pateld4af2972016-01-19 19:58:49 +0000911 Module *M = B.GetInsertBlock()->getModule();
Reid Klecknerb5180542017-03-21 16:57:19 +0000912 AttributeList AS;
913 AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
914 Attribute::NoUnwind);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000915 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +0000916 FunctionCallee MemCpy = M->getOrInsertFunction(
Reid Klecknerb5180542017-03-21 16:57:19 +0000917 "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000918 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000919 DL.getIntPtrType(Context));
Sanjay Pateld3112a52016-01-19 19:46:10 +0000920 Dst = castToCStr(Dst, B);
921 Src = castToCStr(Src, B);
David Blaikieff6409d2015-05-18 22:13:54 +0000922 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
James Y Knight13680222019-02-01 02:28:03 +0000923 if (const Function *F =
924 dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000925 CI->setCallingConv(F->getCallingConv());
Evan Chengd9e82232010-03-23 15:48:04 +0000926 return CI;
927}
928
Sanjay Pateld3112a52016-01-19 19:46:10 +0000929Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000930 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Chandler Carruth7ec50852012-11-01 08:07:29 +0000931 LLVMContext &Context = B.GetInsertBlock()->getContext();
Erik Pilkington52349212019-05-31 22:41:31 +0000932 return emitLibCall(
933 LibFunc_memchr, B.getInt8PtrTy(),
934 {B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context)},
935 {castToCStr(Ptr, B), Val, Len}, B, TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000936}
937
Clement Courbet8e16d732019-03-08 09:07:45 +0000938Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
939 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Erik Pilkington52349212019-05-31 22:41:31 +0000940 LLVMContext &Context = B.GetInsertBlock()->getContext();
941 return emitLibCall(
942 LibFunc_memcmp, B.getInt32Ty(),
943 {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
944 {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
Clement Courbet8e16d732019-03-08 09:07:45 +0000945}
946
947Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
948 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Erik Pilkington52349212019-05-31 22:41:31 +0000949 LLVMContext &Context = B.GetInsertBlock()->getContext();
950 return emitLibCall(
951 LibFunc_bcmp, B.getInt32Ty(),
952 {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
953 {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
Clement Courbet8e16d732019-03-08 09:07:45 +0000954}
955
Erik Pilkingtonabb2a932019-05-31 22:41:36 +0000956Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
957 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
958 return emitLibCall(
959 LibFunc_memccpy, B.getInt8PtrTy(),
960 {B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), Len->getType()},
961 {Ptr1, Ptr2, Val, Len}, B, TLI);
962}
963
964Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
965 ArrayRef<Value *> VariadicArgs, IRBuilder<> &B,
966 const TargetLibraryInfo *TLI) {
967 SmallVector<Value *, 8> Args{castToCStr(Dest, B), Size, castToCStr(Fmt, B)};
968 Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end());
969 return emitLibCall(LibFunc_snprintf, B.getInt32Ty(),
970 {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy()},
971 Args, B, TLI, /*IsVaArgs=*/true);
972}
973
974Value *llvm::emitSPrintf(Value *Dest, Value *Fmt,
975 ArrayRef<Value *> VariadicArgs, IRBuilder<> &B,
976 const TargetLibraryInfo *TLI) {
977 SmallVector<Value *, 8> Args{castToCStr(Dest, B), castToCStr(Fmt, B)};
978 Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end());
979 return emitLibCall(LibFunc_sprintf, B.getInt32Ty(),
980 {B.getInt8PtrTy(), B.getInt8PtrTy()}, Args, B, TLI,
981 /*IsVaArgs=*/true);
982}
983
984Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilder<> &B,
985 const TargetLibraryInfo *TLI) {
986 return emitLibCall(LibFunc_strcat, B.getInt8PtrTy(),
987 {B.getInt8PtrTy(), B.getInt8PtrTy()},
988 {castToCStr(Dest, B), castToCStr(Src, B)}, B, TLI);
989}
990
991Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
992 const TargetLibraryInfo *TLI) {
993 return emitLibCall(LibFunc_strlcpy, Size->getType(),
994 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
995 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
996}
997
998Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
999 const TargetLibraryInfo *TLI) {
1000 return emitLibCall(LibFunc_strlcat, Size->getType(),
1001 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
1002 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
1003}
1004
1005Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
1006 const TargetLibraryInfo *TLI) {
1007 return emitLibCall(LibFunc_strncat, B.getInt8PtrTy(),
1008 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
1009 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
1010}
1011
1012Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
1013 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1014 return emitLibCall(
1015 LibFunc_vsnprintf, B.getInt32Ty(),
1016 {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy(), VAList->getType()},
1017 {castToCStr(Dest, B), Size, castToCStr(Fmt, B), VAList}, B, TLI);
1018}
1019
1020Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList,
1021 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1022 return emitLibCall(LibFunc_vsprintf, B.getInt32Ty(),
1023 {B.getInt8PtrTy(), B.getInt8PtrTy(), VAList->getType()},
1024 {castToCStr(Dest, B), castToCStr(Fmt, B), VAList}, B, TLI);
1025}
1026
Yi Jiang6ab044e2013-12-16 22:42:40 +00001027/// Append a suffix to the function name according to the type of 'Op'.
Sanjay Pateld3112a52016-01-19 19:46:10 +00001028static void appendTypeSuffix(Value *Op, StringRef &Name,
Sanjay Patelb50325e2016-01-19 19:17:47 +00001029 SmallString<20> &NameBuffer) {
Yi Jiang6ab044e2013-12-16 22:42:40 +00001030 if (!Op->getType()->isDoubleTy()) {
1031 NameBuffer += Name;
1032
1033 if (Op->getType()->isFloatTy())
1034 NameBuffer += 'f';
1035 else
1036 NameBuffer += 'l';
1037
1038 Name = NameBuffer;
Fangrui Songf78650a2018-07-30 19:41:25 +00001039 }
Yi Jiang6ab044e2013-12-16 22:42:40 +00001040}
1041
Mikael Holmene3605d02018-10-18 06:27:53 +00001042static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
1043 IRBuilder<> &B,
1044 const AttributeList &Attrs) {
1045 assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
Eric Christopher87abfc52010-03-05 22:25:30 +00001046
Sanjay Pateld4af2972016-01-19 19:58:49 +00001047 Module *M = B.GetInsertBlock()->getModule();
James Y Knight13680222019-02-01 02:28:03 +00001048 FunctionCallee Callee =
1049 M->getOrInsertFunction(Name, Op->getType(), Op->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001050 CallInst *CI = B.CreateCall(Callee, Op, Name);
Matt Arsenault6a288c12017-05-03 02:26:10 +00001051
1052 // The incoming attribute set may have come from a speculatable intrinsic, but
1053 // is being replaced with a library call which is not allowed to be
1054 // speculatable.
1055 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
1056 AttributeList::FunctionIndex,
1057 Attribute::Speculatable));
James Y Knight13680222019-02-01 02:28:03 +00001058 if (const Function *F =
1059 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001060 CI->setCallingConv(F->getCallingConv());
1061
Eric Christopher87abfc52010-03-05 22:25:30 +00001062 return CI;
1063}
1064
Mikael Holmene3605d02018-10-18 06:27:53 +00001065Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
1066 const AttributeList &Attrs) {
1067 SmallString<20> NameBuffer;
1068 appendTypeSuffix(Op, Name, NameBuffer);
1069
1070 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1071}
1072
1073Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
1074 LibFunc DoubleFn, LibFunc FloatFn,
1075 LibFunc LongDoubleFn, IRBuilder<> &B,
1076 const AttributeList &Attrs) {
1077 // Get the name of the function according to TLI.
Evandro Menezesc6c00cd2019-08-09 16:04:18 +00001078 StringRef Name = getFloatFnName(TLI, Op->getType(),
1079 DoubleFn, FloatFn, LongDoubleFn);
Mikael Holmene3605d02018-10-18 06:27:53 +00001080
1081 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1082}
1083
Evandro Menezes8a212142019-08-09 17:06:46 +00001084static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2,
1085 StringRef Name, IRBuilder<> &B,
1086 const AttributeList &Attrs) {
1087 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1088
1089 Module *M = B.GetInsertBlock()->getModule();
1090 FunctionCallee Callee = M->getOrInsertFunction(Name, Op1->getType(),
1091 Op1->getType(), Op2->getType());
1092 CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name);
1093
1094 // The incoming attribute set may have come from a speculatable intrinsic, but
1095 // is being replaced with a library call which is not allowed to be
1096 // speculatable.
1097 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
1098 AttributeList::FunctionIndex,
1099 Attribute::Speculatable));
1100 if (const Function *F =
1101 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
1102 CI->setCallingConv(F->getCallingConv());
1103
1104 return CI;
1105}
1106
Sanjay Pateld3112a52016-01-19 19:46:10 +00001107Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
Reid Klecknerb5180542017-03-21 16:57:19 +00001108 IRBuilder<> &B, const AttributeList &Attrs) {
Mikael Holmene3605d02018-10-18 06:27:53 +00001109 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1110
Yi Jiang6ab044e2013-12-16 22:42:40 +00001111 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +00001112 appendTypeSuffix(Op1, Name, NameBuffer);
Yi Jiang6ab044e2013-12-16 22:42:40 +00001113
Evandro Menezes8a212142019-08-09 17:06:46 +00001114 return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs);
1115}
Evan Chengad6efbf2014-03-12 18:09:37 +00001116
Evandro Menezes8a212142019-08-09 17:06:46 +00001117Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,
1118 const TargetLibraryInfo *TLI,
1119 LibFunc DoubleFn, LibFunc FloatFn,
1120 LibFunc LongDoubleFn, IRBuilder<> &B,
1121 const AttributeList &Attrs) {
1122 // Get the name of the function according to TLI.
1123 StringRef Name = getFloatFnName(TLI, Op1->getType(),
1124 DoubleFn, FloatFn, LongDoubleFn);
1125
1126 return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs);
Yi Jiang6ab044e2013-12-16 22:42:40 +00001127}
1128
Sanjay Pateld3112a52016-01-19 19:46:10 +00001129Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +00001130 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001131 if (!TLI->has(LibFunc_putchar))
Craig Topperf40110f2014-04-25 05:29:35 +00001132 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001133
Sanjay Pateld4af2972016-01-19 19:58:49 +00001134 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001135 StringRef PutCharName = TLI->getName(LibFunc_putchar);
James Y Knight13680222019-02-01 02:28:03 +00001136 FunctionCallee PutChar =
1137 M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty());
David Bolvansky7c7760d2018-10-16 21:18:31 +00001138 inferLibFuncAttributes(M, PutCharName, *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001139 CallInst *CI = B.CreateCall(PutChar,
1140 B.CreateIntCast(Char,
1141 B.getInt32Ty(),
1142 /*isSigned*/true,
1143 "chari"),
David Bolvansky7c7760d2018-10-16 21:18:31 +00001144 PutCharName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001145
James Y Knight13680222019-02-01 02:28:03 +00001146 if (const Function *F =
1147 dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001148 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +00001149 return CI;
1150}
1151
Sanjay Pateld3112a52016-01-19 19:46:10 +00001152Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +00001153 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001154 if (!TLI->has(LibFunc_puts))
Craig Topperf40110f2014-04-25 05:29:35 +00001155 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001156
Sanjay Pateld4af2972016-01-19 19:58:49 +00001157 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001158 StringRef PutsName = TLI->getName(LibFunc_puts);
James Y Knight13680222019-02-01 02:28:03 +00001159 FunctionCallee PutS =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001160 M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy());
1161 inferLibFuncAttributes(M, PutsName, *TLI);
1162 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName);
James Y Knight13680222019-02-01 02:28:03 +00001163 if (const Function *F =
1164 dyn_cast<Function>(PutS.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001165 CI->setCallingConv(F->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001166 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001167}
1168
Sanjay Pateld3112a52016-01-19 19:46:10 +00001169Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001170 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001171 if (!TLI->has(LibFunc_fputc))
Craig Topperf40110f2014-04-25 05:29:35 +00001172 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001173
Sanjay Pateld4af2972016-01-19 19:58:49 +00001174 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001175 StringRef FPutcName = TLI->getName(LibFunc_fputc);
James Y Knight13680222019-02-01 02:28:03 +00001176 FunctionCallee F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(),
1177 B.getInt32Ty(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001178 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001179 inferLibFuncAttributes(M, FPutcName, *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001180 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
1181 "chari");
David Bolvansky7c7760d2018-10-16 21:18:31 +00001182 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001183
James Y Knight13680222019-02-01 02:28:03 +00001184 if (const Function *Fn =
1185 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001186 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001187 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001188}
1189
David Bolvanskyca22d422018-05-16 11:39:52 +00001190Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
1191 const TargetLibraryInfo *TLI) {
1192 if (!TLI->has(LibFunc_fputc_unlocked))
1193 return nullptr;
1194
1195 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001196 StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001197 FunctionCallee F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(),
1198 B.getInt32Ty(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001199 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001200 inferLibFuncAttributes(M, FPutcUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001201 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
David Bolvansky7c7760d2018-10-16 21:18:31 +00001202 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001203
James Y Knight13680222019-02-01 02:28:03 +00001204 if (const Function *Fn =
1205 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001206 CI->setCallingConv(Fn->getCallingConv());
1207 return CI;
1208}
1209
Sanjay Pateld3112a52016-01-19 19:46:10 +00001210Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001211 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001212 if (!TLI->has(LibFunc_fputs))
Craig Topperf40110f2014-04-25 05:29:35 +00001213 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001214
Sanjay Pateld4af2972016-01-19 19:58:49 +00001215 Module *M = B.GetInsertBlock()->getModule();
David L. Jonesd21529f2017-01-23 23:16:46 +00001216 StringRef FPutsName = TLI->getName(LibFunc_fputs);
James Y Knight13680222019-02-01 02:28:03 +00001217 FunctionCallee F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
1218 B.getInt8PtrTy(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001219 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001220 inferLibFuncAttributes(M, FPutsName, *TLI);
1221 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001222
James Y Knight13680222019-02-01 02:28:03 +00001223 if (const Function *Fn =
1224 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001225 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001226 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001227}
1228
David Bolvanskyca22d422018-05-16 11:39:52 +00001229Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
1230 const TargetLibraryInfo *TLI) {
1231 if (!TLI->has(LibFunc_fputs_unlocked))
1232 return nullptr;
1233
1234 Module *M = B.GetInsertBlock()->getModule();
1235 StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001236 FunctionCallee F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
1237 B.getInt8PtrTy(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001238 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001239 inferLibFuncAttributes(M, FPutsUnlockedName, *TLI);
1240 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001241
James Y Knight13680222019-02-01 02:28:03 +00001242 if (const Function *Fn =
1243 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001244 CI->setCallingConv(Fn->getCallingConv());
1245 return CI;
1246}
1247
Sanjay Pateld3112a52016-01-19 19:46:10 +00001248Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001249 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001250 if (!TLI->has(LibFunc_fwrite))
Craig Topperf40110f2014-04-25 05:29:35 +00001251 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001252
Sanjay Pateld4af2972016-01-19 19:58:49 +00001253 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +00001254 LLVMContext &Context = B.GetInsertBlock()->getContext();
David L. Jonesd21529f2017-01-23 23:16:46 +00001255 StringRef FWriteName = TLI->getName(LibFunc_fwrite);
James Y Knight13680222019-02-01 02:28:03 +00001256 FunctionCallee F = M->getOrInsertFunction(
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001257 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001258 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1259
Eric Christopher87abfc52010-03-05 22:25:30 +00001260 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001261 inferLibFuncAttributes(M, FWriteName, *TLI);
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001262 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +00001263 B.CreateCall(F, {castToCStr(Ptr, B), Size,
David Blaikieff6409d2015-05-18 22:13:54 +00001264 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
Evan Chengad6efbf2014-03-12 18:09:37 +00001265
James Y Knight13680222019-02-01 02:28:03 +00001266 if (const Function *Fn =
1267 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001268 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001269 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001270}
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001271
1272Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
1273 const TargetLibraryInfo *TLI) {
1274 if (!TLI->has(LibFunc_malloc))
1275 return nullptr;
1276
1277 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001278 StringRef MallocName = TLI->getName(LibFunc_malloc);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001279 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +00001280 FunctionCallee Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(),
1281 DL.getIntPtrType(Context));
David Bolvansky7c7760d2018-10-16 21:18:31 +00001282 inferLibFuncAttributes(M, MallocName, *TLI);
1283 CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001284
James Y Knight13680222019-02-01 02:28:03 +00001285 if (const Function *F =
1286 dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts()))
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001287 CI->setCallingConv(F->getCallingConv());
1288
1289 return CI;
1290}
1291
1292Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
1293 IRBuilder<> &B, const TargetLibraryInfo &TLI) {
1294 if (!TLI.has(LibFunc_calloc))
1295 return nullptr;
1296
1297 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001298 StringRef CallocName = TLI.getName(LibFunc_calloc);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001299 const DataLayout &DL = M->getDataLayout();
1300 IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
James Y Knight13680222019-02-01 02:28:03 +00001301 FunctionCallee Calloc = M->getOrInsertFunction(
1302 CallocName, Attrs, B.getInt8PtrTy(), PtrType, PtrType);
David Bolvansky7c7760d2018-10-16 21:18:31 +00001303 inferLibFuncAttributes(M, CallocName, TLI);
1304 CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001305
James Y Knight13680222019-02-01 02:28:03 +00001306 if (const auto *F =
1307 dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts()))
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001308 CI->setCallingConv(F->getCallingConv());
1309
1310 return CI;
1311}
David Bolvanskyca22d422018-05-16 11:39:52 +00001312
1313Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1314 IRBuilder<> &B, const DataLayout &DL,
1315 const TargetLibraryInfo *TLI) {
1316 if (!TLI->has(LibFunc_fwrite_unlocked))
1317 return nullptr;
1318
1319 Module *M = B.GetInsertBlock()->getModule();
1320 LLVMContext &Context = B.GetInsertBlock()->getContext();
1321 StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001322 FunctionCallee F = M->getOrInsertFunction(
David Bolvanskyca22d422018-05-16 11:39:52 +00001323 FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1324 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1325
1326 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001327 inferLibFuncAttributes(M, FWriteUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001328 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1329
James Y Knight13680222019-02-01 02:28:03 +00001330 if (const Function *Fn =
1331 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001332 CI->setCallingConv(Fn->getCallingConv());
1333 return CI;
1334}
1335
1336Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
1337 const TargetLibraryInfo *TLI) {
1338 if (!TLI->has(LibFunc_fgetc_unlocked))
1339 return nullptr;
1340
1341 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001342 StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001343 FunctionCallee F = M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(),
1344 File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001345 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001346 inferLibFuncAttributes(M, FGetCUnlockedName, *TLI);
1347 CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001348
James Y Knight13680222019-02-01 02:28:03 +00001349 if (const Function *Fn =
1350 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001351 CI->setCallingConv(Fn->getCallingConv());
1352 return CI;
1353}
1354
1355Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
1356 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1357 if (!TLI->has(LibFunc_fgets_unlocked))
1358 return nullptr;
1359
1360 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001361 StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001362 FunctionCallee F =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001363 M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(),
Benjamin Kramer8ac15bf2018-05-16 21:45:39 +00001364 B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
David Bolvansky7c7760d2018-10-16 21:18:31 +00001365 inferLibFuncAttributes(M, FGetSUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001366 CallInst *CI =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001367 B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001368
James Y Knight13680222019-02-01 02:28:03 +00001369 if (const Function *Fn =
1370 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001371 CI->setCallingConv(Fn->getCallingConv());
1372 return CI;
1373}
1374
1375Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1376 IRBuilder<> &B, const DataLayout &DL,
1377 const TargetLibraryInfo *TLI) {
1378 if (!TLI->has(LibFunc_fread_unlocked))
1379 return nullptr;
1380
1381 Module *M = B.GetInsertBlock()->getModule();
1382 LLVMContext &Context = B.GetInsertBlock()->getContext();
1383 StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001384 FunctionCallee F = M->getOrInsertFunction(
David Bolvanskyca22d422018-05-16 11:39:52 +00001385 FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1386 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1387
1388 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001389 inferLibFuncAttributes(M, FReadUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001390 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1391
James Y Knight13680222019-02-01 02:28:03 +00001392 if (const Function *Fn =
1393 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001394 CI->setCallingConv(Fn->getCallingConv());
1395 return CI;
1396}