blob: ea1fbc9e73bbf824393e9339d4febe22d31d719f [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);
309 LLVM_FALLTHROUGH;
David Bolvansky8715e032018-08-23 05:18:23 +0000310 case LibFunc_memmove:
311 Changed |= setReturnedArg(F, 0);
312 LLVM_FALLTHROUGH;
David L. Jonesd21529f2017-01-23 23:16:46 +0000313 case LibFunc_mempcpy:
314 case LibFunc_memccpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000315 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000316 Changed |= setDoesNotCapture(F, 1);
317 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000318 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000319 case LibFunc_memcpy_chk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000320 Changed |= setDoesNotThrow(F);
321 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000322 case LibFunc_memalign:
Reid Klecknera0b45f42017-05-03 18:17:31 +0000323 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000324 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000325 case LibFunc_mkdir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000326 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000327 Changed |= setDoesNotCapture(F, 0);
328 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000329 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000330 case LibFunc_mktime:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000331 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000332 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000333 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000334 case LibFunc_realloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000335 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000336 Changed |= setRetDoesNotAlias(F);
337 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000338 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000339 case LibFunc_read:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000340 // May throw; "read" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000341 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000342 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000343 case LibFunc_rewind:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000344 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000345 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000346 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000347 case LibFunc_rmdir:
348 case LibFunc_remove:
349 case LibFunc_realpath:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000350 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000351 Changed |= setDoesNotCapture(F, 0);
352 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000353 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000354 case LibFunc_rename:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000355 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000356 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000357 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000358 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000359 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000360 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000361 case LibFunc_readlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000362 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000363 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000364 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000365 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000366 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000367 case LibFunc_write:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000368 // May throw; "write" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000369 Changed |= setDoesNotCapture(F, 1);
370 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000371 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000372 case LibFunc_bcopy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000373 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000374 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000375 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000376 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000377 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000378 case LibFunc_bcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000379 Changed |= setDoesNotThrow(F);
380 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000381 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000382 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000383 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000384 case LibFunc_bzero:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000385 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000386 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000387 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000388 case LibFunc_calloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000389 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000390 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000391 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000392 case LibFunc_chmod:
393 case LibFunc_chown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000394 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000395 Changed |= setDoesNotCapture(F, 0);
396 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000397 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000398 case LibFunc_ctermid:
399 case LibFunc_clearerr:
400 case LibFunc_closedir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000401 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000402 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000403 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000404 case LibFunc_atoi:
405 case LibFunc_atol:
406 case LibFunc_atof:
407 case LibFunc_atoll:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000408 Changed |= setDoesNotThrow(F);
409 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000410 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000411 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000412 case LibFunc_access:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000413 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000414 Changed |= setDoesNotCapture(F, 0);
415 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000416 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000417 case LibFunc_fopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000418 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000419 Changed |= setRetDoesNotAlias(F);
420 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000421 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000422 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000423 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000424 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000425 case LibFunc_fdopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000426 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000427 Changed |= setRetDoesNotAlias(F);
428 Changed |= setDoesNotCapture(F, 1);
429 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000430 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000431 case LibFunc_feof:
432 case LibFunc_free:
433 case LibFunc_fseek:
434 case LibFunc_ftell:
435 case LibFunc_fgetc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000436 case LibFunc_fgetc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000437 case LibFunc_fseeko:
438 case LibFunc_ftello:
439 case LibFunc_fileno:
440 case LibFunc_fflush:
441 case LibFunc_fclose:
442 case LibFunc_fsetpos:
443 case LibFunc_flockfile:
444 case LibFunc_funlockfile:
445 case LibFunc_ftrylockfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000446 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000447 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000448 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000449 case LibFunc_ferror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000450 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000451 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000452 Changed |= setOnlyReadsMemory(F);
453 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000454 case LibFunc_fputc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000455 case LibFunc_fputc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000456 case LibFunc_fstat:
457 case LibFunc_frexp:
458 case LibFunc_frexpf:
459 case LibFunc_frexpl:
460 case LibFunc_fstatvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000461 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000462 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000463 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000464 case LibFunc_fgets:
David Bolvanskyca22d422018-05-16 11:39:52 +0000465 case LibFunc_fgets_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000466 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000467 Changed |= setDoesNotCapture(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000468 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000469 case LibFunc_fread:
David Bolvanskyca22d422018-05-16 11:39:52 +0000470 case LibFunc_fread_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000471 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000472 Changed |= setDoesNotCapture(F, 0);
473 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000474 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000475 case LibFunc_fwrite:
David Bolvanskyca22d422018-05-16 11:39:52 +0000476 case LibFunc_fwrite_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000477 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000478 Changed |= setDoesNotCapture(F, 0);
479 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000480 // FIXME: readonly #1?
481 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000482 case LibFunc_fputs:
David Bolvanskyca22d422018-05-16 11:39:52 +0000483 case LibFunc_fputs_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000484 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000485 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000486 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000487 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000488 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000489 case LibFunc_fscanf:
490 case LibFunc_fprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000491 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000492 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000493 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000494 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000495 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000496 case LibFunc_fgetpos:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000497 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000498 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000499 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000500 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000501 case LibFunc_getc:
502 case LibFunc_getlogin_r:
503 case LibFunc_getc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000504 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000505 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000506 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000507 case LibFunc_getenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000508 Changed |= setDoesNotThrow(F);
509 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000510 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000511 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000512 case LibFunc_gets:
513 case LibFunc_getchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000514 case LibFunc_getchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000515 Changed |= setDoesNotThrow(F);
516 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000517 case LibFunc_getitimer:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000518 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000519 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000520 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000521 case LibFunc_getpwnam:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000522 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000523 Changed |= setDoesNotCapture(F, 0);
524 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000525 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000526 case LibFunc_ungetc:
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_uname:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000531 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000532 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000533 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000534 case LibFunc_unlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000535 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000536 Changed |= setDoesNotCapture(F, 0);
537 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000538 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000539 case LibFunc_unsetenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000540 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000541 Changed |= setDoesNotCapture(F, 0);
542 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000543 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000544 case LibFunc_utime:
545 case LibFunc_utimes:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000546 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000547 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000548 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000549 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000550 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000551 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000552 case LibFunc_putc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000553 case LibFunc_putc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000554 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000555 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000556 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000557 case LibFunc_puts:
558 case LibFunc_printf:
559 case LibFunc_perror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000560 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000561 Changed |= setDoesNotCapture(F, 0);
562 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000563 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000564 case LibFunc_pread:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000565 // May throw; "pread" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000566 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000567 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000568 case LibFunc_pwrite:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000569 // May throw; "pwrite" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000570 Changed |= setDoesNotCapture(F, 1);
571 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000572 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000573 case LibFunc_putchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000574 case LibFunc_putchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000575 Changed |= setDoesNotThrow(F);
576 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000577 case LibFunc_popen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000578 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000579 Changed |= setRetDoesNotAlias(F);
580 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000581 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000582 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000583 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000584 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000585 case LibFunc_pclose:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000586 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000587 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000588 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000589 case LibFunc_vscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000590 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000591 Changed |= setDoesNotCapture(F, 0);
592 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000593 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000594 case LibFunc_vsscanf:
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 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000598 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000599 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000600 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000601 case LibFunc_vfscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000602 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000603 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000604 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000605 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000606 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000607 case LibFunc_valloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000608 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000609 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000610 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000611 case LibFunc_vprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000612 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000613 Changed |= setDoesNotCapture(F, 0);
614 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000615 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000616 case LibFunc_vfprintf:
617 case LibFunc_vsprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000618 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000619 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000620 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000621 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000622 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000623 case LibFunc_vsnprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000624 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000625 Changed |= setDoesNotCapture(F, 0);
626 Changed |= setDoesNotCapture(F, 2);
627 Changed |= setOnlyReadsMemory(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000628 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000629 case LibFunc_open:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000630 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000631 Changed |= setDoesNotCapture(F, 0);
632 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000633 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000634 case LibFunc_opendir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000635 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000636 Changed |= setRetDoesNotAlias(F);
637 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_tmpfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000641 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000642 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000643 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000644 case LibFunc_times:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000645 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000646 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000647 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000648 case LibFunc_htonl:
649 case LibFunc_htons:
650 case LibFunc_ntohl:
651 case LibFunc_ntohs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000652 Changed |= setDoesNotThrow(F);
653 Changed |= setDoesNotAccessMemory(F);
654 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000655 case LibFunc_lstat:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000656 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000657 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000658 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000659 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000660 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000661 case LibFunc_lchown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000662 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000663 Changed |= setDoesNotCapture(F, 0);
664 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000665 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000666 case LibFunc_qsort:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000667 // May throw; places call through function pointer.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000668 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000669 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000670 case LibFunc_dunder_strdup:
671 case LibFunc_dunder_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000672 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000673 Changed |= setRetDoesNotAlias(F);
674 Changed |= setDoesNotCapture(F, 0);
675 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_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000678 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000679 Changed |= setDoesNotCapture(F, 1);
680 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000681 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000682 case LibFunc_under_IO_getc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000683 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000684 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000685 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000686 case LibFunc_under_IO_putc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000687 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000688 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000689 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000690 case LibFunc_dunder_isoc99_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000691 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000692 Changed |= setDoesNotCapture(F, 0);
693 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000694 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000695 case LibFunc_stat64:
696 case LibFunc_lstat64:
697 case LibFunc_statvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000698 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000699 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000700 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000701 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000702 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000703 case LibFunc_dunder_isoc99_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000704 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000705 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000706 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000707 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000708 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000709 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000710 case LibFunc_fopen64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000711 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000712 Changed |= setRetDoesNotAlias(F);
713 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000714 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000715 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000716 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000717 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000718 case LibFunc_fseeko64:
719 case LibFunc_ftello64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000720 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000721 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000722 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000723 case LibFunc_tmpfile64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000724 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000725 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000726 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000727 case LibFunc_fstat64:
728 case LibFunc_fstatvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000729 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000730 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000731 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000732 case LibFunc_open64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000733 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000734 Changed |= setDoesNotCapture(F, 0);
735 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000736 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000737 case LibFunc_gettimeofday:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000738 // Currently some platforms have the restrict keyword on the arguments to
739 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
740 // arguments.
741 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000742 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000743 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000744 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000745 case LibFunc_Znwj: // new(unsigned int)
746 case LibFunc_Znwm: // new(unsigned long)
747 case LibFunc_Znaj: // new[](unsigned int)
748 case LibFunc_Znam: // new[](unsigned long)
749 case LibFunc_msvc_new_int: // new(unsigned int)
750 case LibFunc_msvc_new_longlong: // new(unsigned long long)
751 case LibFunc_msvc_new_array_int: // new[](unsigned int)
752 case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000753 // Operator new always returns a nonnull noalias pointer
Reid Klecknera0b45f42017-05-03 18:17:31 +0000754 Changed |= setRetNonNull(F);
755 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000756 return Changed;
David Bolvansky3ea50f92018-04-25 04:33:36 +0000757 // TODO: add LibFunc entries for:
758 // case LibFunc_memset_pattern4:
759 // case LibFunc_memset_pattern8:
David L. Jonesd21529f2017-01-23 23:16:46 +0000760 case LibFunc_memset_pattern16:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000761 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000762 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougacha44c19872016-04-27 19:04:43 +0000763 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000764 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000765 return Changed;
766 // int __nvvm_reflect(const char *)
David L. Jonesd21529f2017-01-23 23:16:46 +0000767 case LibFunc_nvvm_reflect:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000768 Changed |= setDoesNotAccessMemory(F);
769 Changed |= setDoesNotThrow(F);
770 return Changed;
771
772 default:
773 // FIXME: It'd be really nice to cover all the library functions we're
774 // aware of here.
775 return false;
776 }
777}
778
Evandro Menezesc6c00cd2019-08-09 16:04:18 +0000779bool llvm::hasFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
780 LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) {
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000781 switch (Ty->getTypeID()) {
Benjamin Kramere5e1ea72018-09-19 12:01:38 +0000782 case Type::HalfTyID:
783 return false;
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000784 case Type::FloatTyID:
785 return TLI->has(FloatFn);
786 case Type::DoubleTyID:
787 return TLI->has(DoubleFn);
788 default:
789 return TLI->has(LongDoubleFn);
790 }
791}
792
Evandro Menezesc6c00cd2019-08-09 16:04:18 +0000793StringRef llvm::getFloatFnName(const TargetLibraryInfo *TLI, Type *Ty,
794 LibFunc DoubleFn, LibFunc FloatFn,
795 LibFunc LongDoubleFn) {
796 assert(hasFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
Mikael Holmene3605d02018-10-18 06:27:53 +0000797 "Cannot get name for unavailable function!");
798
799 switch (Ty->getTypeID()) {
800 case Type::HalfTyID:
801 llvm_unreachable("No name for HalfTy!");
802 case Type::FloatTyID:
803 return TLI->getName(FloatFn);
804 case Type::DoubleTyID:
805 return TLI->getName(DoubleFn);
806 default:
807 return TLI->getName(LongDoubleFn);
808 }
809}
810
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000811//- Emit LibCalls ------------------------------------------------------------//
812
Sanjay Pateld3112a52016-01-19 19:46:10 +0000813Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
Matt Arsenaultbe558882014-04-23 20:58:57 +0000814 unsigned AS = V->getType()->getPointerAddressSpace();
815 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
Eric Christopher87abfc52010-03-05 22:25:30 +0000816}
817
Erik Pilkington52349212019-05-31 22:41:31 +0000818static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType,
819 ArrayRef<Type *> ParamTypes,
820 ArrayRef<Value *> Operands, IRBuilder<> &B,
821 const TargetLibraryInfo *TLI,
822 bool IsVaArgs = false) {
823 if (!TLI->has(TheLibFunc))
Craig Topperf40110f2014-04-25 05:29:35 +0000824 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000825
Sanjay Pateld4af2972016-01-19 19:58:49 +0000826 Module *M = B.GetInsertBlock()->getModule();
Erik Pilkington52349212019-05-31 22:41:31 +0000827 StringRef FuncName = TLI->getName(TheLibFunc);
828 FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs);
829 FunctionCallee Callee = M->getOrInsertFunction(FuncName, FuncType);
830 inferLibFuncAttributes(M, FuncName, *TLI);
831 CallInst *CI = B.CreateCall(Callee, Operands, FuncName);
James Y Knight13680222019-02-01 02:28:03 +0000832 if (const Function *F =
Erik Pilkington52349212019-05-31 22:41:31 +0000833 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000834 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000835 return CI;
836}
837
Erik Pilkington52349212019-05-31 22:41:31 +0000838Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
839 const TargetLibraryInfo *TLI) {
840 LLVMContext &Context = B.GetInsertBlock()->getContext();
841 return emitLibCall(LibFunc_strlen, DL.getIntPtrType(Context),
842 B.getInt8PtrTy(), castToCStr(Ptr, B), B, TLI);
843}
844
Sanjay Pateld3112a52016-01-19 19:46:10 +0000845Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000846 const TargetLibraryInfo *TLI) {
Chris Lattner229907c2011-07-18 04:54:35 +0000847 Type *I8Ptr = B.getInt8PtrTy();
848 Type *I32Ty = B.getInt32Ty();
Erik Pilkington52349212019-05-31 22:41:31 +0000849 return emitLibCall(LibFunc_strchr, I8Ptr, {I8Ptr, I32Ty},
850 {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, B, TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000851}
852
Sanjay Pateld3112a52016-01-19 19:46:10 +0000853Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000854 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Chandler Carruth7ec50852012-11-01 08:07:29 +0000855 LLVMContext &Context = B.GetInsertBlock()->getContext();
Erik Pilkington52349212019-05-31 22:41:31 +0000856 return emitLibCall(
857 LibFunc_strncmp, B.getInt32Ty(),
858 {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
859 {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
Benjamin Kramer11188602010-06-15 21:34:25 +0000860}
861
Sanjay Pateld3112a52016-01-19 19:46:10 +0000862Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Erik Pilkington52349212019-05-31 22:41:31 +0000863 const TargetLibraryInfo *TLI) {
Chris Lattner229907c2011-07-18 04:54:35 +0000864 Type *I8Ptr = B.getInt8PtrTy();
Erik Pilkington52349212019-05-31 22:41:31 +0000865 return emitLibCall(LibFunc_strcpy, I8Ptr, {I8Ptr, I8Ptr},
866 {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI);
867}
868
869Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilder<> &B,
870 const TargetLibraryInfo *TLI) {
871 Type *I8Ptr = B.getInt8PtrTy();
872 return emitLibCall(LibFunc_stpcpy, I8Ptr, {I8Ptr, I8Ptr},
873 {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000874}
875
Sanjay Pateld3112a52016-01-19 19:46:10 +0000876Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
Erik Pilkington52349212019-05-31 22:41:31 +0000877 const TargetLibraryInfo *TLI) {
Chris Lattner229907c2011-07-18 04:54:35 +0000878 Type *I8Ptr = B.getInt8PtrTy();
Erik Pilkington52349212019-05-31 22:41:31 +0000879 return emitLibCall(LibFunc_strncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()},
880 {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI);
881}
882
883Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
884 const TargetLibraryInfo *TLI) {
885 Type *I8Ptr = B.getInt8PtrTy();
886 return emitLibCall(LibFunc_stpncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()},
887 {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI);
Eric Christopher43dc11c2010-03-11 01:25:07 +0000888}
889
Sanjay Pateld3112a52016-01-19 19:46:10 +0000890Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000891 IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000892 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000893 if (!TLI->has(LibFunc_memcpy_chk))
Craig Topperf40110f2014-04-25 05:29:35 +0000894 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000895
Sanjay Pateld4af2972016-01-19 19:58:49 +0000896 Module *M = B.GetInsertBlock()->getModule();
Reid Klecknerb5180542017-03-21 16:57:19 +0000897 AttributeList AS;
898 AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
899 Attribute::NoUnwind);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000900 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +0000901 FunctionCallee MemCpy = M->getOrInsertFunction(
Reid Klecknerb5180542017-03-21 16:57:19 +0000902 "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000903 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000904 DL.getIntPtrType(Context));
Sanjay Pateld3112a52016-01-19 19:46:10 +0000905 Dst = castToCStr(Dst, B);
906 Src = castToCStr(Src, B);
David Blaikieff6409d2015-05-18 22:13:54 +0000907 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
James Y Knight13680222019-02-01 02:28:03 +0000908 if (const Function *F =
909 dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000910 CI->setCallingConv(F->getCallingConv());
Evan Chengd9e82232010-03-23 15:48:04 +0000911 return CI;
912}
913
Sanjay Pateld3112a52016-01-19 19:46:10 +0000914Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000915 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Chandler Carruth7ec50852012-11-01 08:07:29 +0000916 LLVMContext &Context = B.GetInsertBlock()->getContext();
Erik Pilkington52349212019-05-31 22:41:31 +0000917 return emitLibCall(
918 LibFunc_memchr, B.getInt8PtrTy(),
919 {B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context)},
920 {castToCStr(Ptr, B), Val, Len}, B, TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000921}
922
Clement Courbet8e16d732019-03-08 09:07:45 +0000923Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
924 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Erik Pilkington52349212019-05-31 22:41:31 +0000925 LLVMContext &Context = B.GetInsertBlock()->getContext();
926 return emitLibCall(
927 LibFunc_memcmp, B.getInt32Ty(),
928 {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
929 {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
Clement Courbet8e16d732019-03-08 09:07:45 +0000930}
931
932Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
933 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Erik Pilkington52349212019-05-31 22:41:31 +0000934 LLVMContext &Context = B.GetInsertBlock()->getContext();
935 return emitLibCall(
936 LibFunc_bcmp, B.getInt32Ty(),
937 {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
938 {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
Clement Courbet8e16d732019-03-08 09:07:45 +0000939}
940
Erik Pilkingtonabb2a932019-05-31 22:41:36 +0000941Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
942 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
943 return emitLibCall(
944 LibFunc_memccpy, B.getInt8PtrTy(),
945 {B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), Len->getType()},
946 {Ptr1, Ptr2, Val, Len}, B, TLI);
947}
948
949Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
950 ArrayRef<Value *> VariadicArgs, IRBuilder<> &B,
951 const TargetLibraryInfo *TLI) {
952 SmallVector<Value *, 8> Args{castToCStr(Dest, B), Size, castToCStr(Fmt, B)};
953 Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end());
954 return emitLibCall(LibFunc_snprintf, B.getInt32Ty(),
955 {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy()},
956 Args, B, TLI, /*IsVaArgs=*/true);
957}
958
959Value *llvm::emitSPrintf(Value *Dest, Value *Fmt,
960 ArrayRef<Value *> VariadicArgs, IRBuilder<> &B,
961 const TargetLibraryInfo *TLI) {
962 SmallVector<Value *, 8> Args{castToCStr(Dest, B), castToCStr(Fmt, B)};
963 Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end());
964 return emitLibCall(LibFunc_sprintf, B.getInt32Ty(),
965 {B.getInt8PtrTy(), B.getInt8PtrTy()}, Args, B, TLI,
966 /*IsVaArgs=*/true);
967}
968
969Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilder<> &B,
970 const TargetLibraryInfo *TLI) {
971 return emitLibCall(LibFunc_strcat, B.getInt8PtrTy(),
972 {B.getInt8PtrTy(), B.getInt8PtrTy()},
973 {castToCStr(Dest, B), castToCStr(Src, B)}, B, TLI);
974}
975
976Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
977 const TargetLibraryInfo *TLI) {
978 return emitLibCall(LibFunc_strlcpy, Size->getType(),
979 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
980 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
981}
982
983Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
984 const TargetLibraryInfo *TLI) {
985 return emitLibCall(LibFunc_strlcat, Size->getType(),
986 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
987 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
988}
989
990Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
991 const TargetLibraryInfo *TLI) {
992 return emitLibCall(LibFunc_strncat, B.getInt8PtrTy(),
993 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
994 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
995}
996
997Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
998 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
999 return emitLibCall(
1000 LibFunc_vsnprintf, B.getInt32Ty(),
1001 {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy(), VAList->getType()},
1002 {castToCStr(Dest, B), Size, castToCStr(Fmt, B), VAList}, B, TLI);
1003}
1004
1005Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList,
1006 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1007 return emitLibCall(LibFunc_vsprintf, B.getInt32Ty(),
1008 {B.getInt8PtrTy(), B.getInt8PtrTy(), VAList->getType()},
1009 {castToCStr(Dest, B), castToCStr(Fmt, B), VAList}, B, TLI);
1010}
1011
Yi Jiang6ab044e2013-12-16 22:42:40 +00001012/// Append a suffix to the function name according to the type of 'Op'.
Sanjay Pateld3112a52016-01-19 19:46:10 +00001013static void appendTypeSuffix(Value *Op, StringRef &Name,
Sanjay Patelb50325e2016-01-19 19:17:47 +00001014 SmallString<20> &NameBuffer) {
Yi Jiang6ab044e2013-12-16 22:42:40 +00001015 if (!Op->getType()->isDoubleTy()) {
1016 NameBuffer += Name;
1017
1018 if (Op->getType()->isFloatTy())
1019 NameBuffer += 'f';
1020 else
1021 NameBuffer += 'l';
1022
1023 Name = NameBuffer;
Fangrui Songf78650a2018-07-30 19:41:25 +00001024 }
Yi Jiang6ab044e2013-12-16 22:42:40 +00001025}
1026
Mikael Holmene3605d02018-10-18 06:27:53 +00001027static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
1028 IRBuilder<> &B,
1029 const AttributeList &Attrs) {
1030 assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
Eric Christopher87abfc52010-03-05 22:25:30 +00001031
Sanjay Pateld4af2972016-01-19 19:58:49 +00001032 Module *M = B.GetInsertBlock()->getModule();
James Y Knight13680222019-02-01 02:28:03 +00001033 FunctionCallee Callee =
1034 M->getOrInsertFunction(Name, Op->getType(), Op->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001035 CallInst *CI = B.CreateCall(Callee, Op, Name);
Matt Arsenault6a288c12017-05-03 02:26:10 +00001036
1037 // The incoming attribute set may have come from a speculatable intrinsic, but
1038 // is being replaced with a library call which is not allowed to be
1039 // speculatable.
1040 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
1041 AttributeList::FunctionIndex,
1042 Attribute::Speculatable));
James Y Knight13680222019-02-01 02:28:03 +00001043 if (const Function *F =
1044 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001045 CI->setCallingConv(F->getCallingConv());
1046
Eric Christopher87abfc52010-03-05 22:25:30 +00001047 return CI;
1048}
1049
Mikael Holmene3605d02018-10-18 06:27:53 +00001050Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
1051 const AttributeList &Attrs) {
1052 SmallString<20> NameBuffer;
1053 appendTypeSuffix(Op, Name, NameBuffer);
1054
1055 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1056}
1057
1058Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
1059 LibFunc DoubleFn, LibFunc FloatFn,
1060 LibFunc LongDoubleFn, IRBuilder<> &B,
1061 const AttributeList &Attrs) {
1062 // Get the name of the function according to TLI.
Evandro Menezesc6c00cd2019-08-09 16:04:18 +00001063 StringRef Name = getFloatFnName(TLI, Op->getType(),
1064 DoubleFn, FloatFn, LongDoubleFn);
Mikael Holmene3605d02018-10-18 06:27:53 +00001065
1066 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1067}
1068
Evandro Menezes8a212142019-08-09 17:06:46 +00001069static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2,
1070 StringRef Name, IRBuilder<> &B,
1071 const AttributeList &Attrs) {
1072 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1073
1074 Module *M = B.GetInsertBlock()->getModule();
1075 FunctionCallee Callee = M->getOrInsertFunction(Name, Op1->getType(),
1076 Op1->getType(), Op2->getType());
1077 CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name);
1078
1079 // The incoming attribute set may have come from a speculatable intrinsic, but
1080 // is being replaced with a library call which is not allowed to be
1081 // speculatable.
1082 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
1083 AttributeList::FunctionIndex,
1084 Attribute::Speculatable));
1085 if (const Function *F =
1086 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
1087 CI->setCallingConv(F->getCallingConv());
1088
1089 return CI;
1090}
1091
Sanjay Pateld3112a52016-01-19 19:46:10 +00001092Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
Reid Klecknerb5180542017-03-21 16:57:19 +00001093 IRBuilder<> &B, const AttributeList &Attrs) {
Mikael Holmene3605d02018-10-18 06:27:53 +00001094 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1095
Yi Jiang6ab044e2013-12-16 22:42:40 +00001096 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +00001097 appendTypeSuffix(Op1, Name, NameBuffer);
Yi Jiang6ab044e2013-12-16 22:42:40 +00001098
Evandro Menezes8a212142019-08-09 17:06:46 +00001099 return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs);
1100}
Evan Chengad6efbf2014-03-12 18:09:37 +00001101
Evandro Menezes8a212142019-08-09 17:06:46 +00001102Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,
1103 const TargetLibraryInfo *TLI,
1104 LibFunc DoubleFn, LibFunc FloatFn,
1105 LibFunc LongDoubleFn, IRBuilder<> &B,
1106 const AttributeList &Attrs) {
1107 // Get the name of the function according to TLI.
1108 StringRef Name = getFloatFnName(TLI, Op1->getType(),
1109 DoubleFn, FloatFn, LongDoubleFn);
1110
1111 return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs);
Yi Jiang6ab044e2013-12-16 22:42:40 +00001112}
1113
Sanjay Pateld3112a52016-01-19 19:46:10 +00001114Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +00001115 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001116 if (!TLI->has(LibFunc_putchar))
Craig Topperf40110f2014-04-25 05:29:35 +00001117 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001118
Sanjay Pateld4af2972016-01-19 19:58:49 +00001119 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001120 StringRef PutCharName = TLI->getName(LibFunc_putchar);
James Y Knight13680222019-02-01 02:28:03 +00001121 FunctionCallee PutChar =
1122 M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty());
David Bolvansky7c7760d2018-10-16 21:18:31 +00001123 inferLibFuncAttributes(M, PutCharName, *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001124 CallInst *CI = B.CreateCall(PutChar,
1125 B.CreateIntCast(Char,
1126 B.getInt32Ty(),
1127 /*isSigned*/true,
1128 "chari"),
David Bolvansky7c7760d2018-10-16 21:18:31 +00001129 PutCharName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001130
James Y Knight13680222019-02-01 02:28:03 +00001131 if (const Function *F =
1132 dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001133 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +00001134 return CI;
1135}
1136
Sanjay Pateld3112a52016-01-19 19:46:10 +00001137Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +00001138 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001139 if (!TLI->has(LibFunc_puts))
Craig Topperf40110f2014-04-25 05:29:35 +00001140 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001141
Sanjay Pateld4af2972016-01-19 19:58:49 +00001142 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001143 StringRef PutsName = TLI->getName(LibFunc_puts);
James Y Knight13680222019-02-01 02:28:03 +00001144 FunctionCallee PutS =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001145 M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy());
1146 inferLibFuncAttributes(M, PutsName, *TLI);
1147 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName);
James Y Knight13680222019-02-01 02:28:03 +00001148 if (const Function *F =
1149 dyn_cast<Function>(PutS.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001150 CI->setCallingConv(F->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001151 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001152}
1153
Sanjay Pateld3112a52016-01-19 19:46:10 +00001154Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001155 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001156 if (!TLI->has(LibFunc_fputc))
Craig Topperf40110f2014-04-25 05:29:35 +00001157 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001158
Sanjay Pateld4af2972016-01-19 19:58:49 +00001159 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001160 StringRef FPutcName = TLI->getName(LibFunc_fputc);
James Y Knight13680222019-02-01 02:28:03 +00001161 FunctionCallee F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(),
1162 B.getInt32Ty(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001163 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001164 inferLibFuncAttributes(M, FPutcName, *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001165 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
1166 "chari");
David Bolvansky7c7760d2018-10-16 21:18:31 +00001167 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001168
James Y Knight13680222019-02-01 02:28:03 +00001169 if (const Function *Fn =
1170 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001171 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001172 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001173}
1174
David Bolvanskyca22d422018-05-16 11:39:52 +00001175Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
1176 const TargetLibraryInfo *TLI) {
1177 if (!TLI->has(LibFunc_fputc_unlocked))
1178 return nullptr;
1179
1180 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001181 StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001182 FunctionCallee F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(),
1183 B.getInt32Ty(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001184 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001185 inferLibFuncAttributes(M, FPutcUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001186 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
David Bolvansky7c7760d2018-10-16 21:18:31 +00001187 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001188
James Y Knight13680222019-02-01 02:28:03 +00001189 if (const Function *Fn =
1190 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001191 CI->setCallingConv(Fn->getCallingConv());
1192 return CI;
1193}
1194
Sanjay Pateld3112a52016-01-19 19:46:10 +00001195Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001196 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001197 if (!TLI->has(LibFunc_fputs))
Craig Topperf40110f2014-04-25 05:29:35 +00001198 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001199
Sanjay Pateld4af2972016-01-19 19:58:49 +00001200 Module *M = B.GetInsertBlock()->getModule();
David L. Jonesd21529f2017-01-23 23:16:46 +00001201 StringRef FPutsName = TLI->getName(LibFunc_fputs);
James Y Knight13680222019-02-01 02:28:03 +00001202 FunctionCallee F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
1203 B.getInt8PtrTy(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001204 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001205 inferLibFuncAttributes(M, FPutsName, *TLI);
1206 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001207
James Y Knight13680222019-02-01 02:28:03 +00001208 if (const Function *Fn =
1209 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001210 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001211 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001212}
1213
David Bolvanskyca22d422018-05-16 11:39:52 +00001214Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
1215 const TargetLibraryInfo *TLI) {
1216 if (!TLI->has(LibFunc_fputs_unlocked))
1217 return nullptr;
1218
1219 Module *M = B.GetInsertBlock()->getModule();
1220 StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001221 FunctionCallee F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
1222 B.getInt8PtrTy(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001223 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001224 inferLibFuncAttributes(M, FPutsUnlockedName, *TLI);
1225 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001226
James Y Knight13680222019-02-01 02:28:03 +00001227 if (const Function *Fn =
1228 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001229 CI->setCallingConv(Fn->getCallingConv());
1230 return CI;
1231}
1232
Sanjay Pateld3112a52016-01-19 19:46:10 +00001233Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001234 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001235 if (!TLI->has(LibFunc_fwrite))
Craig Topperf40110f2014-04-25 05:29:35 +00001236 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001237
Sanjay Pateld4af2972016-01-19 19:58:49 +00001238 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +00001239 LLVMContext &Context = B.GetInsertBlock()->getContext();
David L. Jonesd21529f2017-01-23 23:16:46 +00001240 StringRef FWriteName = TLI->getName(LibFunc_fwrite);
James Y Knight13680222019-02-01 02:28:03 +00001241 FunctionCallee F = M->getOrInsertFunction(
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001242 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001243 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1244
Eric Christopher87abfc52010-03-05 22:25:30 +00001245 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001246 inferLibFuncAttributes(M, FWriteName, *TLI);
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001247 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +00001248 B.CreateCall(F, {castToCStr(Ptr, B), Size,
David Blaikieff6409d2015-05-18 22:13:54 +00001249 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
Evan Chengad6efbf2014-03-12 18:09:37 +00001250
James Y Knight13680222019-02-01 02:28:03 +00001251 if (const Function *Fn =
1252 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001253 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001254 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001255}
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001256
1257Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
1258 const TargetLibraryInfo *TLI) {
1259 if (!TLI->has(LibFunc_malloc))
1260 return nullptr;
1261
1262 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001263 StringRef MallocName = TLI->getName(LibFunc_malloc);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001264 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +00001265 FunctionCallee Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(),
1266 DL.getIntPtrType(Context));
David Bolvansky7c7760d2018-10-16 21:18:31 +00001267 inferLibFuncAttributes(M, MallocName, *TLI);
1268 CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001269
James Y Knight13680222019-02-01 02:28:03 +00001270 if (const Function *F =
1271 dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts()))
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001272 CI->setCallingConv(F->getCallingConv());
1273
1274 return CI;
1275}
1276
1277Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
1278 IRBuilder<> &B, const TargetLibraryInfo &TLI) {
1279 if (!TLI.has(LibFunc_calloc))
1280 return nullptr;
1281
1282 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001283 StringRef CallocName = TLI.getName(LibFunc_calloc);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001284 const DataLayout &DL = M->getDataLayout();
1285 IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
James Y Knight13680222019-02-01 02:28:03 +00001286 FunctionCallee Calloc = M->getOrInsertFunction(
1287 CallocName, Attrs, B.getInt8PtrTy(), PtrType, PtrType);
David Bolvansky7c7760d2018-10-16 21:18:31 +00001288 inferLibFuncAttributes(M, CallocName, TLI);
1289 CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001290
James Y Knight13680222019-02-01 02:28:03 +00001291 if (const auto *F =
1292 dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts()))
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001293 CI->setCallingConv(F->getCallingConv());
1294
1295 return CI;
1296}
David Bolvanskyca22d422018-05-16 11:39:52 +00001297
1298Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1299 IRBuilder<> &B, const DataLayout &DL,
1300 const TargetLibraryInfo *TLI) {
1301 if (!TLI->has(LibFunc_fwrite_unlocked))
1302 return nullptr;
1303
1304 Module *M = B.GetInsertBlock()->getModule();
1305 LLVMContext &Context = B.GetInsertBlock()->getContext();
1306 StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001307 FunctionCallee F = M->getOrInsertFunction(
David Bolvanskyca22d422018-05-16 11:39:52 +00001308 FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1309 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1310
1311 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001312 inferLibFuncAttributes(M, FWriteUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001313 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1314
James Y Knight13680222019-02-01 02:28:03 +00001315 if (const Function *Fn =
1316 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001317 CI->setCallingConv(Fn->getCallingConv());
1318 return CI;
1319}
1320
1321Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
1322 const TargetLibraryInfo *TLI) {
1323 if (!TLI->has(LibFunc_fgetc_unlocked))
1324 return nullptr;
1325
1326 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001327 StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001328 FunctionCallee F = M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(),
1329 File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001330 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001331 inferLibFuncAttributes(M, FGetCUnlockedName, *TLI);
1332 CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001333
James Y Knight13680222019-02-01 02:28:03 +00001334 if (const Function *Fn =
1335 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001336 CI->setCallingConv(Fn->getCallingConv());
1337 return CI;
1338}
1339
1340Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
1341 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1342 if (!TLI->has(LibFunc_fgets_unlocked))
1343 return nullptr;
1344
1345 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001346 StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001347 FunctionCallee F =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001348 M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(),
Benjamin Kramer8ac15bf2018-05-16 21:45:39 +00001349 B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
David Bolvansky7c7760d2018-10-16 21:18:31 +00001350 inferLibFuncAttributes(M, FGetSUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001351 CallInst *CI =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001352 B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001353
James Y Knight13680222019-02-01 02:28:03 +00001354 if (const Function *Fn =
1355 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001356 CI->setCallingConv(Fn->getCallingConv());
1357 return CI;
1358}
1359
1360Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1361 IRBuilder<> &B, const DataLayout &DL,
1362 const TargetLibraryInfo *TLI) {
1363 if (!TLI->has(LibFunc_fread_unlocked))
1364 return nullptr;
1365
1366 Module *M = B.GetInsertBlock()->getModule();
1367 LLVMContext &Context = B.GetInsertBlock()->getContext();
1368 StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001369 FunctionCallee F = M->getOrInsertFunction(
David Bolvanskyca22d422018-05-16 11:39:52 +00001370 FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1371 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1372
1373 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001374 inferLibFuncAttributes(M, FReadUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001375 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1376
James Y Knight13680222019-02-01 02:28:03 +00001377 if (const Function *Fn =
1378 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001379 CI->setCallingConv(Fn->getCallingConv());
1380 return CI;
1381}