blob: a5f8ab8c9a29a478e36703fbfdc8be606de82c4c [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
91static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
92 if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))
93 return false;
94 F.addParamAttr(ArgNo, Attribute::ReadOnly);
95 ++NumReadOnlyArg;
96 return true;
97}
98
99static bool setRetNonNull(Function &F) {
100 assert(F.getReturnType()->isPointerTy() &&
101 "nonnull applies only to pointers");
102 if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull))
103 return false;
104 F.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000105 ++NumNonNull;
106 return true;
107}
108
David Bolvansky8715e032018-08-23 05:18:23 +0000109static bool setReturnedArg(Function &F, unsigned ArgNo) {
110 if (F.hasParamAttribute(ArgNo, Attribute::Returned))
111 return false;
112 F.addParamAttr(ArgNo, Attribute::Returned);
113 ++NumReturnedArg;
114 return true;
115}
116
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000117static bool setNonLazyBind(Function &F) {
118 if (F.hasFnAttribute(Attribute::NonLazyBind))
119 return false;
120 F.addFnAttr(Attribute::NonLazyBind);
121 return true;
122}
123
Brian Homerdingb4b21d82019-07-08 15:57:56 +0000124static bool setDoesNotFreeMemory(Function &F) {
125 if (F.hasFnAttribute(Attribute::NoFree))
126 return false;
127 F.addFnAttr(Attribute::NoFree);
128 return true;
129}
130
David Bolvansky7c7760d2018-10-16 21:18:31 +0000131bool llvm::inferLibFuncAttributes(Module *M, StringRef Name,
David Bolvanskye8b3bba2018-10-13 15:21:55 +0000132 const TargetLibraryInfo &TLI) {
David Bolvansky7c7760d2018-10-16 21:18:31 +0000133 Function *F = M->getFunction(Name);
134 if (!F)
David Bolvanskye8b3bba2018-10-13 15:21:55 +0000135 return false;
David Bolvansky7c7760d2018-10-16 21:18:31 +0000136 return inferLibFuncAttributes(*F, TLI);
137}
138
139bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000140 LibFunc TheLibFunc;
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000141 if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
142 return false;
143
144 bool Changed = false;
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000145
Brian Homerdingb4b21d82019-07-08 15:57:56 +0000146 if(!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F, &TLI))
147 Changed |= setDoesNotFreeMemory(F);
148
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000149 if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
150 Changed |= setNonLazyBind(F);
151
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000152 switch (TheLibFunc) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000153 case LibFunc_strlen:
Matthias Braun60b40b82017-05-05 20:25:50 +0000154 case LibFunc_wcslen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000155 Changed |= setOnlyReadsMemory(F);
156 Changed |= setDoesNotThrow(F);
Xin Tong9d2a5b12017-06-18 03:10:26 +0000157 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000158 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000159 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000160 case LibFunc_strchr:
161 case LibFunc_strrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000162 Changed |= setOnlyReadsMemory(F);
163 Changed |= setDoesNotThrow(F);
164 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000165 case LibFunc_strtol:
166 case LibFunc_strtod:
167 case LibFunc_strtof:
168 case LibFunc_strtoul:
169 case LibFunc_strtoll:
170 case LibFunc_strtold:
171 case LibFunc_strtoull:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000172 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000173 Changed |= setDoesNotCapture(F, 1);
174 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000175 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000176 case LibFunc_strcpy:
David Bolvansky8715e032018-08-23 05:18:23 +0000177 case LibFunc_strncpy:
David L. Jonesd21529f2017-01-23 23:16:46 +0000178 case LibFunc_strcat:
179 case LibFunc_strncat:
David Bolvansky8715e032018-08-23 05:18:23 +0000180 Changed |= setReturnedArg(F, 0);
181 LLVM_FALLTHROUGH;
182 case LibFunc_stpcpy:
David L. Jonesd21529f2017-01-23 23:16:46 +0000183 case LibFunc_stpncpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000184 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000185 Changed |= setDoesNotCapture(F, 1);
186 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000187 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000188 case LibFunc_strxfrm:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000189 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000190 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000191 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000192 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000193 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000194 case LibFunc_strcmp: // 0,1
195 case LibFunc_strspn: // 0,1
196 case LibFunc_strncmp: // 0,1
197 case LibFunc_strcspn: // 0,1
198 case LibFunc_strcoll: // 0,1
199 case LibFunc_strcasecmp: // 0,1
200 case LibFunc_strncasecmp: //
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000201 Changed |= setOnlyReadsMemory(F);
202 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000203 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000204 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000205 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000206 case LibFunc_strstr:
207 case LibFunc_strpbrk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000208 Changed |= setOnlyReadsMemory(F);
209 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000210 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000211 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000212 case LibFunc_strtok:
213 case LibFunc_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000214 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000215 Changed |= setDoesNotCapture(F, 1);
216 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000217 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000218 case LibFunc_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000219 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000220 Changed |= setDoesNotCapture(F, 0);
221 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000222 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000223 case LibFunc_setbuf:
224 case LibFunc_setvbuf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000225 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000226 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000227 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000228 case LibFunc_strdup:
229 case LibFunc_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000230 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000231 Changed |= setRetDoesNotAlias(F);
232 Changed |= setDoesNotCapture(F, 0);
233 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000234 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000235 case LibFunc_stat:
236 case LibFunc_statvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000237 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000238 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000239 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000240 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000241 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000242 case LibFunc_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000243 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000244 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000245 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000246 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000247 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000248 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000249 case LibFunc_sprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000250 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000251 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000252 Changed |= setDoesNotCapture(F, 1);
253 Changed |= setOnlyReadsMemory(F, 1);
254 return Changed;
Reid Klecknera0b45f42017-05-03 18:17:31 +0000255 case LibFunc_snprintf:
256 Changed |= setDoesNotThrow(F);
257 Changed |= setDoesNotCapture(F, 0);
258 Changed |= setDoesNotCapture(F, 2);
259 Changed |= setOnlyReadsMemory(F, 2);
260 return Changed;
261 case LibFunc_setitimer:
262 Changed |= setDoesNotThrow(F);
263 Changed |= setDoesNotCapture(F, 1);
264 Changed |= setDoesNotCapture(F, 2);
265 Changed |= setOnlyReadsMemory(F, 1);
266 return Changed;
267 case LibFunc_system:
268 // May throw; "system" is a valid pthread cancellation point.
269 Changed |= setDoesNotCapture(F, 0);
270 Changed |= setOnlyReadsMemory(F, 0);
271 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000272 case LibFunc_malloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000273 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000274 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000275 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000276 case LibFunc_memcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000277 Changed |= setOnlyReadsMemory(F);
278 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000279 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000280 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000281 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000282 case LibFunc_memchr:
283 case LibFunc_memrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000284 Changed |= setOnlyReadsMemory(F);
285 Changed |= setDoesNotThrow(F);
286 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000287 case LibFunc_modf:
288 case LibFunc_modff:
289 case LibFunc_modfl:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000290 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000291 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000292 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000293 case LibFunc_memcpy:
David Bolvansky8715e032018-08-23 05:18:23 +0000294 case LibFunc_memmove:
295 Changed |= setReturnedArg(F, 0);
296 LLVM_FALLTHROUGH;
David L. Jonesd21529f2017-01-23 23:16:46 +0000297 case LibFunc_mempcpy:
298 case LibFunc_memccpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000299 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000300 Changed |= setDoesNotCapture(F, 1);
301 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000302 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000303 case LibFunc_memcpy_chk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000304 Changed |= setDoesNotThrow(F);
305 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000306 case LibFunc_memalign:
Reid Klecknera0b45f42017-05-03 18:17:31 +0000307 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000308 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000309 case LibFunc_mkdir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000310 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000311 Changed |= setDoesNotCapture(F, 0);
312 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000313 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000314 case LibFunc_mktime:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000315 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000316 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000317 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000318 case LibFunc_realloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000319 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000320 Changed |= setRetDoesNotAlias(F);
321 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000322 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000323 case LibFunc_read:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000324 // May throw; "read" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000325 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000326 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000327 case LibFunc_rewind:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000328 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000329 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000330 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000331 case LibFunc_rmdir:
332 case LibFunc_remove:
333 case LibFunc_realpath:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000334 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000335 Changed |= setDoesNotCapture(F, 0);
336 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000337 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000338 case LibFunc_rename:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000339 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000340 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000341 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000342 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000343 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000344 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000345 case LibFunc_readlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000346 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000347 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000348 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000349 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000350 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000351 case LibFunc_write:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000352 // May throw; "write" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000353 Changed |= setDoesNotCapture(F, 1);
354 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000355 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000356 case LibFunc_bcopy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000357 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000358 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000359 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000360 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000361 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000362 case LibFunc_bcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000363 Changed |= setDoesNotThrow(F);
364 Changed |= setOnlyReadsMemory(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);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000367 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000368 case LibFunc_bzero:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000369 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000370 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000371 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000372 case LibFunc_calloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000373 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000374 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000375 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000376 case LibFunc_chmod:
377 case LibFunc_chown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000378 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000379 Changed |= setDoesNotCapture(F, 0);
380 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000381 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000382 case LibFunc_ctermid:
383 case LibFunc_clearerr:
384 case LibFunc_closedir:
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_atoi:
389 case LibFunc_atol:
390 case LibFunc_atof:
391 case LibFunc_atoll:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000392 Changed |= setDoesNotThrow(F);
393 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000394 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000395 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000396 case LibFunc_access:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000397 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000398 Changed |= setDoesNotCapture(F, 0);
399 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000400 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000401 case LibFunc_fopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000402 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000403 Changed |= setRetDoesNotAlias(F);
404 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000405 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000406 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000407 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000408 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000409 case LibFunc_fdopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000410 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000411 Changed |= setRetDoesNotAlias(F);
412 Changed |= setDoesNotCapture(F, 1);
413 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000414 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000415 case LibFunc_feof:
416 case LibFunc_free:
417 case LibFunc_fseek:
418 case LibFunc_ftell:
419 case LibFunc_fgetc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000420 case LibFunc_fgetc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000421 case LibFunc_fseeko:
422 case LibFunc_ftello:
423 case LibFunc_fileno:
424 case LibFunc_fflush:
425 case LibFunc_fclose:
426 case LibFunc_fsetpos:
427 case LibFunc_flockfile:
428 case LibFunc_funlockfile:
429 case LibFunc_ftrylockfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000430 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000431 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000432 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000433 case LibFunc_ferror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000434 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000435 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000436 Changed |= setOnlyReadsMemory(F);
437 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000438 case LibFunc_fputc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000439 case LibFunc_fputc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000440 case LibFunc_fstat:
441 case LibFunc_frexp:
442 case LibFunc_frexpf:
443 case LibFunc_frexpl:
444 case LibFunc_fstatvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000445 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000446 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000447 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000448 case LibFunc_fgets:
David Bolvanskyca22d422018-05-16 11:39:52 +0000449 case LibFunc_fgets_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000450 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000451 Changed |= setDoesNotCapture(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000452 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000453 case LibFunc_fread:
David Bolvanskyca22d422018-05-16 11:39:52 +0000454 case LibFunc_fread_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000455 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000456 Changed |= setDoesNotCapture(F, 0);
457 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000458 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000459 case LibFunc_fwrite:
David Bolvanskyca22d422018-05-16 11:39:52 +0000460 case LibFunc_fwrite_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000461 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000462 Changed |= setDoesNotCapture(F, 0);
463 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000464 // FIXME: readonly #1?
465 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000466 case LibFunc_fputs:
David Bolvanskyca22d422018-05-16 11:39:52 +0000467 case LibFunc_fputs_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000468 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000469 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000470 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000471 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000472 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000473 case LibFunc_fscanf:
474 case LibFunc_fprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000475 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000476 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000477 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000478 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000479 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000480 case LibFunc_fgetpos:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000481 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000482 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000483 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000484 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000485 case LibFunc_getc:
486 case LibFunc_getlogin_r:
487 case LibFunc_getc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000488 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000489 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000490 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000491 case LibFunc_getenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000492 Changed |= setDoesNotThrow(F);
493 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000494 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000495 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000496 case LibFunc_gets:
497 case LibFunc_getchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000498 case LibFunc_getchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000499 Changed |= setDoesNotThrow(F);
500 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000501 case LibFunc_getitimer:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000502 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000503 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000504 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000505 case LibFunc_getpwnam:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000506 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000507 Changed |= setDoesNotCapture(F, 0);
508 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000509 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000510 case LibFunc_ungetc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000511 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000512 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000513 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000514 case LibFunc_uname:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000515 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000516 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000517 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000518 case LibFunc_unlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000519 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000520 Changed |= setDoesNotCapture(F, 0);
521 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000522 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000523 case LibFunc_unsetenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000524 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000525 Changed |= setDoesNotCapture(F, 0);
526 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000527 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000528 case LibFunc_utime:
529 case LibFunc_utimes:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000530 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000531 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000532 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000533 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000534 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000535 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000536 case LibFunc_putc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000537 case LibFunc_putc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000538 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000539 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000540 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000541 case LibFunc_puts:
542 case LibFunc_printf:
543 case LibFunc_perror:
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_pread:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000549 // May throw; "pread" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000550 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000551 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000552 case LibFunc_pwrite:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000553 // May throw; "pwrite" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000554 Changed |= setDoesNotCapture(F, 1);
555 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000556 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000557 case LibFunc_putchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000558 case LibFunc_putchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000559 Changed |= setDoesNotThrow(F);
560 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000561 case LibFunc_popen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000562 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000563 Changed |= setRetDoesNotAlias(F);
564 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000565 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000566 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000567 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000568 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000569 case LibFunc_pclose:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000570 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000571 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000572 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000573 case LibFunc_vscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000574 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000575 Changed |= setDoesNotCapture(F, 0);
576 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000577 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000578 case LibFunc_vsscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000579 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000580 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_vfscanf:
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 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000589 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000590 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000591 case LibFunc_valloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000592 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000593 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000594 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000595 case LibFunc_vprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000596 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000597 Changed |= setDoesNotCapture(F, 0);
598 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000599 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000600 case LibFunc_vfprintf:
601 case LibFunc_vsprintf:
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_vsnprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000608 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000609 Changed |= setDoesNotCapture(F, 0);
610 Changed |= setDoesNotCapture(F, 2);
611 Changed |= setOnlyReadsMemory(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000612 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000613 case LibFunc_open:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000614 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000615 Changed |= setDoesNotCapture(F, 0);
616 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000617 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000618 case LibFunc_opendir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000619 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000620 Changed |= setRetDoesNotAlias(F);
621 Changed |= setDoesNotCapture(F, 0);
622 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000623 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000624 case LibFunc_tmpfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000625 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000626 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000627 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000628 case LibFunc_times:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000629 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000630 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000631 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000632 case LibFunc_htonl:
633 case LibFunc_htons:
634 case LibFunc_ntohl:
635 case LibFunc_ntohs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000636 Changed |= setDoesNotThrow(F);
637 Changed |= setDoesNotAccessMemory(F);
638 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000639 case LibFunc_lstat:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000640 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000641 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000642 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000643 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000644 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000645 case LibFunc_lchown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000646 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000647 Changed |= setDoesNotCapture(F, 0);
648 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000649 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000650 case LibFunc_qsort:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000651 // May throw; places call through function pointer.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000652 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000653 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000654 case LibFunc_dunder_strdup:
655 case LibFunc_dunder_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000656 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000657 Changed |= setRetDoesNotAlias(F);
658 Changed |= setDoesNotCapture(F, 0);
659 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000660 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000661 case LibFunc_dunder_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000662 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000663 Changed |= setDoesNotCapture(F, 1);
664 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000665 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000666 case LibFunc_under_IO_getc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000667 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000668 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000669 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000670 case LibFunc_under_IO_putc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000671 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000672 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000673 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000674 case LibFunc_dunder_isoc99_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000675 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000676 Changed |= setDoesNotCapture(F, 0);
677 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000678 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000679 case LibFunc_stat64:
680 case LibFunc_lstat64:
681 case LibFunc_statvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000682 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000683 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000684 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000685 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000686 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000687 case LibFunc_dunder_isoc99_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000688 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000689 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000690 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000691 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000692 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000693 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000694 case LibFunc_fopen64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000695 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000696 Changed |= setRetDoesNotAlias(F);
697 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000698 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000699 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000700 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000701 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000702 case LibFunc_fseeko64:
703 case LibFunc_ftello64:
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 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000707 case LibFunc_tmpfile64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000708 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000709 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000710 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000711 case LibFunc_fstat64:
712 case LibFunc_fstatvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000713 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000714 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000715 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000716 case LibFunc_open64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000717 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000718 Changed |= setDoesNotCapture(F, 0);
719 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000720 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000721 case LibFunc_gettimeofday:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000722 // Currently some platforms have the restrict keyword on the arguments to
723 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
724 // arguments.
725 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000726 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000727 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000728 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000729 case LibFunc_Znwj: // new(unsigned int)
730 case LibFunc_Znwm: // new(unsigned long)
731 case LibFunc_Znaj: // new[](unsigned int)
732 case LibFunc_Znam: // new[](unsigned long)
733 case LibFunc_msvc_new_int: // new(unsigned int)
734 case LibFunc_msvc_new_longlong: // new(unsigned long long)
735 case LibFunc_msvc_new_array_int: // new[](unsigned int)
736 case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000737 // Operator new always returns a nonnull noalias pointer
Reid Klecknera0b45f42017-05-03 18:17:31 +0000738 Changed |= setRetNonNull(F);
739 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000740 return Changed;
David Bolvansky3ea50f92018-04-25 04:33:36 +0000741 // TODO: add LibFunc entries for:
742 // case LibFunc_memset_pattern4:
743 // case LibFunc_memset_pattern8:
David L. Jonesd21529f2017-01-23 23:16:46 +0000744 case LibFunc_memset_pattern16:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000745 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000746 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougacha44c19872016-04-27 19:04:43 +0000747 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000748 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000749 return Changed;
750 // int __nvvm_reflect(const char *)
David L. Jonesd21529f2017-01-23 23:16:46 +0000751 case LibFunc_nvvm_reflect:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000752 Changed |= setDoesNotAccessMemory(F);
753 Changed |= setDoesNotThrow(F);
754 return Changed;
755
756 default:
757 // FIXME: It'd be really nice to cover all the library functions we're
758 // aware of here.
759 return false;
760 }
761}
762
Evandro Menezesc6c00cd2019-08-09 16:04:18 +0000763bool llvm::hasFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
764 LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) {
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000765 switch (Ty->getTypeID()) {
Benjamin Kramere5e1ea72018-09-19 12:01:38 +0000766 case Type::HalfTyID:
767 return false;
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000768 case Type::FloatTyID:
769 return TLI->has(FloatFn);
770 case Type::DoubleTyID:
771 return TLI->has(DoubleFn);
772 default:
773 return TLI->has(LongDoubleFn);
774 }
775}
776
Evandro Menezesc6c00cd2019-08-09 16:04:18 +0000777StringRef llvm::getFloatFnName(const TargetLibraryInfo *TLI, Type *Ty,
778 LibFunc DoubleFn, LibFunc FloatFn,
779 LibFunc LongDoubleFn) {
780 assert(hasFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
Mikael Holmene3605d02018-10-18 06:27:53 +0000781 "Cannot get name for unavailable function!");
782
783 switch (Ty->getTypeID()) {
784 case Type::HalfTyID:
785 llvm_unreachable("No name for HalfTy!");
786 case Type::FloatTyID:
787 return TLI->getName(FloatFn);
788 case Type::DoubleTyID:
789 return TLI->getName(DoubleFn);
790 default:
791 return TLI->getName(LongDoubleFn);
792 }
793}
794
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000795//- Emit LibCalls ------------------------------------------------------------//
796
Sanjay Pateld3112a52016-01-19 19:46:10 +0000797Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
Matt Arsenaultbe558882014-04-23 20:58:57 +0000798 unsigned AS = V->getType()->getPointerAddressSpace();
799 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
Eric Christopher87abfc52010-03-05 22:25:30 +0000800}
801
Erik Pilkington52349212019-05-31 22:41:31 +0000802static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType,
803 ArrayRef<Type *> ParamTypes,
804 ArrayRef<Value *> Operands, IRBuilder<> &B,
805 const TargetLibraryInfo *TLI,
806 bool IsVaArgs = false) {
807 if (!TLI->has(TheLibFunc))
Craig Topperf40110f2014-04-25 05:29:35 +0000808 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000809
Sanjay Pateld4af2972016-01-19 19:58:49 +0000810 Module *M = B.GetInsertBlock()->getModule();
Erik Pilkington52349212019-05-31 22:41:31 +0000811 StringRef FuncName = TLI->getName(TheLibFunc);
812 FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs);
813 FunctionCallee Callee = M->getOrInsertFunction(FuncName, FuncType);
814 inferLibFuncAttributes(M, FuncName, *TLI);
815 CallInst *CI = B.CreateCall(Callee, Operands, FuncName);
James Y Knight13680222019-02-01 02:28:03 +0000816 if (const Function *F =
Erik Pilkington52349212019-05-31 22:41:31 +0000817 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000818 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000819 return CI;
820}
821
Erik Pilkington52349212019-05-31 22:41:31 +0000822Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
823 const TargetLibraryInfo *TLI) {
824 LLVMContext &Context = B.GetInsertBlock()->getContext();
825 return emitLibCall(LibFunc_strlen, DL.getIntPtrType(Context),
826 B.getInt8PtrTy(), castToCStr(Ptr, B), B, TLI);
827}
828
Sanjay Pateld3112a52016-01-19 19:46:10 +0000829Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000830 const TargetLibraryInfo *TLI) {
Chris Lattner229907c2011-07-18 04:54:35 +0000831 Type *I8Ptr = B.getInt8PtrTy();
832 Type *I32Ty = B.getInt32Ty();
Erik Pilkington52349212019-05-31 22:41:31 +0000833 return emitLibCall(LibFunc_strchr, I8Ptr, {I8Ptr, I32Ty},
834 {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, B, TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000835}
836
Sanjay Pateld3112a52016-01-19 19:46:10 +0000837Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000838 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Chandler Carruth7ec50852012-11-01 08:07:29 +0000839 LLVMContext &Context = B.GetInsertBlock()->getContext();
Erik Pilkington52349212019-05-31 22:41:31 +0000840 return emitLibCall(
841 LibFunc_strncmp, B.getInt32Ty(),
842 {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
843 {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
Benjamin Kramer11188602010-06-15 21:34:25 +0000844}
845
Sanjay Pateld3112a52016-01-19 19:46:10 +0000846Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Erik Pilkington52349212019-05-31 22:41:31 +0000847 const TargetLibraryInfo *TLI) {
Chris Lattner229907c2011-07-18 04:54:35 +0000848 Type *I8Ptr = B.getInt8PtrTy();
Erik Pilkington52349212019-05-31 22:41:31 +0000849 return emitLibCall(LibFunc_strcpy, I8Ptr, {I8Ptr, I8Ptr},
850 {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI);
851}
852
853Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilder<> &B,
854 const TargetLibraryInfo *TLI) {
855 Type *I8Ptr = B.getInt8PtrTy();
856 return emitLibCall(LibFunc_stpcpy, I8Ptr, {I8Ptr, I8Ptr},
857 {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000858}
859
Sanjay Pateld3112a52016-01-19 19:46:10 +0000860Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
Erik Pilkington52349212019-05-31 22:41:31 +0000861 const TargetLibraryInfo *TLI) {
Chris Lattner229907c2011-07-18 04:54:35 +0000862 Type *I8Ptr = B.getInt8PtrTy();
Erik Pilkington52349212019-05-31 22:41:31 +0000863 return emitLibCall(LibFunc_strncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()},
864 {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI);
865}
866
867Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
868 const TargetLibraryInfo *TLI) {
869 Type *I8Ptr = B.getInt8PtrTy();
870 return emitLibCall(LibFunc_stpncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()},
871 {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI);
Eric Christopher43dc11c2010-03-11 01:25:07 +0000872}
873
Sanjay Pateld3112a52016-01-19 19:46:10 +0000874Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000875 IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000876 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000877 if (!TLI->has(LibFunc_memcpy_chk))
Craig Topperf40110f2014-04-25 05:29:35 +0000878 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000879
Sanjay Pateld4af2972016-01-19 19:58:49 +0000880 Module *M = B.GetInsertBlock()->getModule();
Reid Klecknerb5180542017-03-21 16:57:19 +0000881 AttributeList AS;
882 AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
883 Attribute::NoUnwind);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000884 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +0000885 FunctionCallee MemCpy = M->getOrInsertFunction(
Reid Klecknerb5180542017-03-21 16:57:19 +0000886 "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000887 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000888 DL.getIntPtrType(Context));
Sanjay Pateld3112a52016-01-19 19:46:10 +0000889 Dst = castToCStr(Dst, B);
890 Src = castToCStr(Src, B);
David Blaikieff6409d2015-05-18 22:13:54 +0000891 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
James Y Knight13680222019-02-01 02:28:03 +0000892 if (const Function *F =
893 dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000894 CI->setCallingConv(F->getCallingConv());
Evan Chengd9e82232010-03-23 15:48:04 +0000895 return CI;
896}
897
Sanjay Pateld3112a52016-01-19 19:46:10 +0000898Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000899 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Chandler Carruth7ec50852012-11-01 08:07:29 +0000900 LLVMContext &Context = B.GetInsertBlock()->getContext();
Erik Pilkington52349212019-05-31 22:41:31 +0000901 return emitLibCall(
902 LibFunc_memchr, B.getInt8PtrTy(),
903 {B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context)},
904 {castToCStr(Ptr, B), Val, Len}, B, TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000905}
906
Clement Courbet8e16d732019-03-08 09:07:45 +0000907Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
908 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Erik Pilkington52349212019-05-31 22:41:31 +0000909 LLVMContext &Context = B.GetInsertBlock()->getContext();
910 return emitLibCall(
911 LibFunc_memcmp, B.getInt32Ty(),
912 {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
913 {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
Clement Courbet8e16d732019-03-08 09:07:45 +0000914}
915
916Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
917 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Erik Pilkington52349212019-05-31 22:41:31 +0000918 LLVMContext &Context = B.GetInsertBlock()->getContext();
919 return emitLibCall(
920 LibFunc_bcmp, B.getInt32Ty(),
921 {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
922 {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
Clement Courbet8e16d732019-03-08 09:07:45 +0000923}
924
Erik Pilkingtonabb2a932019-05-31 22:41:36 +0000925Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
926 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
927 return emitLibCall(
928 LibFunc_memccpy, B.getInt8PtrTy(),
929 {B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), Len->getType()},
930 {Ptr1, Ptr2, Val, Len}, B, TLI);
931}
932
933Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
934 ArrayRef<Value *> VariadicArgs, IRBuilder<> &B,
935 const TargetLibraryInfo *TLI) {
936 SmallVector<Value *, 8> Args{castToCStr(Dest, B), Size, castToCStr(Fmt, B)};
937 Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end());
938 return emitLibCall(LibFunc_snprintf, B.getInt32Ty(),
939 {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy()},
940 Args, B, TLI, /*IsVaArgs=*/true);
941}
942
943Value *llvm::emitSPrintf(Value *Dest, Value *Fmt,
944 ArrayRef<Value *> VariadicArgs, IRBuilder<> &B,
945 const TargetLibraryInfo *TLI) {
946 SmallVector<Value *, 8> Args{castToCStr(Dest, B), castToCStr(Fmt, B)};
947 Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end());
948 return emitLibCall(LibFunc_sprintf, B.getInt32Ty(),
949 {B.getInt8PtrTy(), B.getInt8PtrTy()}, Args, B, TLI,
950 /*IsVaArgs=*/true);
951}
952
953Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilder<> &B,
954 const TargetLibraryInfo *TLI) {
955 return emitLibCall(LibFunc_strcat, B.getInt8PtrTy(),
956 {B.getInt8PtrTy(), B.getInt8PtrTy()},
957 {castToCStr(Dest, B), castToCStr(Src, B)}, B, TLI);
958}
959
960Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
961 const TargetLibraryInfo *TLI) {
962 return emitLibCall(LibFunc_strlcpy, Size->getType(),
963 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
964 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
965}
966
967Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
968 const TargetLibraryInfo *TLI) {
969 return emitLibCall(LibFunc_strlcat, Size->getType(),
970 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
971 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
972}
973
974Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
975 const TargetLibraryInfo *TLI) {
976 return emitLibCall(LibFunc_strncat, B.getInt8PtrTy(),
977 {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
978 {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
979}
980
981Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
982 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
983 return emitLibCall(
984 LibFunc_vsnprintf, B.getInt32Ty(),
985 {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy(), VAList->getType()},
986 {castToCStr(Dest, B), Size, castToCStr(Fmt, B), VAList}, B, TLI);
987}
988
989Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList,
990 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
991 return emitLibCall(LibFunc_vsprintf, B.getInt32Ty(),
992 {B.getInt8PtrTy(), B.getInt8PtrTy(), VAList->getType()},
993 {castToCStr(Dest, B), castToCStr(Fmt, B), VAList}, B, TLI);
994}
995
Yi Jiang6ab044e2013-12-16 22:42:40 +0000996/// Append a suffix to the function name according to the type of 'Op'.
Sanjay Pateld3112a52016-01-19 19:46:10 +0000997static void appendTypeSuffix(Value *Op, StringRef &Name,
Sanjay Patelb50325e2016-01-19 19:17:47 +0000998 SmallString<20> &NameBuffer) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000999 if (!Op->getType()->isDoubleTy()) {
1000 NameBuffer += Name;
1001
1002 if (Op->getType()->isFloatTy())
1003 NameBuffer += 'f';
1004 else
1005 NameBuffer += 'l';
1006
1007 Name = NameBuffer;
Fangrui Songf78650a2018-07-30 19:41:25 +00001008 }
Yi Jiang6ab044e2013-12-16 22:42:40 +00001009}
1010
Mikael Holmene3605d02018-10-18 06:27:53 +00001011static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
1012 IRBuilder<> &B,
1013 const AttributeList &Attrs) {
1014 assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
Eric Christopher87abfc52010-03-05 22:25:30 +00001015
Sanjay Pateld4af2972016-01-19 19:58:49 +00001016 Module *M = B.GetInsertBlock()->getModule();
James Y Knight13680222019-02-01 02:28:03 +00001017 FunctionCallee Callee =
1018 M->getOrInsertFunction(Name, Op->getType(), Op->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001019 CallInst *CI = B.CreateCall(Callee, Op, Name);
Matt Arsenault6a288c12017-05-03 02:26:10 +00001020
1021 // The incoming attribute set may have come from a speculatable intrinsic, but
1022 // is being replaced with a library call which is not allowed to be
1023 // speculatable.
1024 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
1025 AttributeList::FunctionIndex,
1026 Attribute::Speculatable));
James Y Knight13680222019-02-01 02:28:03 +00001027 if (const Function *F =
1028 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001029 CI->setCallingConv(F->getCallingConv());
1030
Eric Christopher87abfc52010-03-05 22:25:30 +00001031 return CI;
1032}
1033
Mikael Holmene3605d02018-10-18 06:27:53 +00001034Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
1035 const AttributeList &Attrs) {
1036 SmallString<20> NameBuffer;
1037 appendTypeSuffix(Op, Name, NameBuffer);
1038
1039 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1040}
1041
1042Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
1043 LibFunc DoubleFn, LibFunc FloatFn,
1044 LibFunc LongDoubleFn, IRBuilder<> &B,
1045 const AttributeList &Attrs) {
1046 // Get the name of the function according to TLI.
Evandro Menezesc6c00cd2019-08-09 16:04:18 +00001047 StringRef Name = getFloatFnName(TLI, Op->getType(),
1048 DoubleFn, FloatFn, LongDoubleFn);
Mikael Holmene3605d02018-10-18 06:27:53 +00001049
1050 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1051}
1052
Sanjay Pateld3112a52016-01-19 19:46:10 +00001053Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
Reid Klecknerb5180542017-03-21 16:57:19 +00001054 IRBuilder<> &B, const AttributeList &Attrs) {
Mikael Holmene3605d02018-10-18 06:27:53 +00001055 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1056
Yi Jiang6ab044e2013-12-16 22:42:40 +00001057 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +00001058 appendTypeSuffix(Op1, Name, NameBuffer);
Yi Jiang6ab044e2013-12-16 22:42:40 +00001059
Sanjay Pateld4af2972016-01-19 19:58:49 +00001060 Module *M = B.GetInsertBlock()->getModule();
James Y Knight13680222019-02-01 02:28:03 +00001061 FunctionCallee Callee = M->getOrInsertFunction(
1062 Name, Op1->getType(), Op1->getType(), Op2->getType());
David Blaikieff6409d2015-05-18 22:13:54 +00001063 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
Yi Jiang6ab044e2013-12-16 22:42:40 +00001064 CI->setAttributes(Attrs);
James Y Knight13680222019-02-01 02:28:03 +00001065 if (const Function *F =
1066 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001067 CI->setCallingConv(F->getCallingConv());
1068
Yi Jiang6ab044e2013-12-16 22:42:40 +00001069 return CI;
1070}
1071
Sanjay Pateld3112a52016-01-19 19:46:10 +00001072Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +00001073 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001074 if (!TLI->has(LibFunc_putchar))
Craig Topperf40110f2014-04-25 05:29:35 +00001075 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001076
Sanjay Pateld4af2972016-01-19 19:58:49 +00001077 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001078 StringRef PutCharName = TLI->getName(LibFunc_putchar);
James Y Knight13680222019-02-01 02:28:03 +00001079 FunctionCallee PutChar =
1080 M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty());
David Bolvansky7c7760d2018-10-16 21:18:31 +00001081 inferLibFuncAttributes(M, PutCharName, *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001082 CallInst *CI = B.CreateCall(PutChar,
1083 B.CreateIntCast(Char,
1084 B.getInt32Ty(),
1085 /*isSigned*/true,
1086 "chari"),
David Bolvansky7c7760d2018-10-16 21:18:31 +00001087 PutCharName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001088
James Y Knight13680222019-02-01 02:28:03 +00001089 if (const Function *F =
1090 dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001091 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +00001092 return CI;
1093}
1094
Sanjay Pateld3112a52016-01-19 19:46:10 +00001095Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +00001096 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001097 if (!TLI->has(LibFunc_puts))
Craig Topperf40110f2014-04-25 05:29:35 +00001098 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001099
Sanjay Pateld4af2972016-01-19 19:58:49 +00001100 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001101 StringRef PutsName = TLI->getName(LibFunc_puts);
James Y Knight13680222019-02-01 02:28:03 +00001102 FunctionCallee PutS =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001103 M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy());
1104 inferLibFuncAttributes(M, PutsName, *TLI);
1105 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName);
James Y Knight13680222019-02-01 02:28:03 +00001106 if (const Function *F =
1107 dyn_cast<Function>(PutS.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001108 CI->setCallingConv(F->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001109 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001110}
1111
Sanjay Pateld3112a52016-01-19 19:46:10 +00001112Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001113 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001114 if (!TLI->has(LibFunc_fputc))
Craig Topperf40110f2014-04-25 05:29:35 +00001115 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001116
Sanjay Pateld4af2972016-01-19 19:58:49 +00001117 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001118 StringRef FPutcName = TLI->getName(LibFunc_fputc);
James Y Knight13680222019-02-01 02:28:03 +00001119 FunctionCallee F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(),
1120 B.getInt32Ty(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001121 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001122 inferLibFuncAttributes(M, FPutcName, *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001123 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
1124 "chari");
David Bolvansky7c7760d2018-10-16 21:18:31 +00001125 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001126
James Y Knight13680222019-02-01 02:28:03 +00001127 if (const Function *Fn =
1128 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001129 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001130 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001131}
1132
David Bolvanskyca22d422018-05-16 11:39:52 +00001133Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
1134 const TargetLibraryInfo *TLI) {
1135 if (!TLI->has(LibFunc_fputc_unlocked))
1136 return nullptr;
1137
1138 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001139 StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001140 FunctionCallee F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(),
1141 B.getInt32Ty(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001142 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001143 inferLibFuncAttributes(M, FPutcUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001144 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
David Bolvansky7c7760d2018-10-16 21:18:31 +00001145 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001146
James Y Knight13680222019-02-01 02:28:03 +00001147 if (const Function *Fn =
1148 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001149 CI->setCallingConv(Fn->getCallingConv());
1150 return CI;
1151}
1152
Sanjay Pateld3112a52016-01-19 19:46:10 +00001153Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001154 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001155 if (!TLI->has(LibFunc_fputs))
Craig Topperf40110f2014-04-25 05:29:35 +00001156 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001157
Sanjay Pateld4af2972016-01-19 19:58:49 +00001158 Module *M = B.GetInsertBlock()->getModule();
David L. Jonesd21529f2017-01-23 23:16:46 +00001159 StringRef FPutsName = TLI->getName(LibFunc_fputs);
James Y Knight13680222019-02-01 02:28:03 +00001160 FunctionCallee F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
1161 B.getInt8PtrTy(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001162 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001163 inferLibFuncAttributes(M, FPutsName, *TLI);
1164 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001165
James Y Knight13680222019-02-01 02:28:03 +00001166 if (const Function *Fn =
1167 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001168 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001169 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001170}
1171
David Bolvanskyca22d422018-05-16 11:39:52 +00001172Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
1173 const TargetLibraryInfo *TLI) {
1174 if (!TLI->has(LibFunc_fputs_unlocked))
1175 return nullptr;
1176
1177 Module *M = B.GetInsertBlock()->getModule();
1178 StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001179 FunctionCallee F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
1180 B.getInt8PtrTy(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001181 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001182 inferLibFuncAttributes(M, FPutsUnlockedName, *TLI);
1183 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001184
James Y Knight13680222019-02-01 02:28:03 +00001185 if (const Function *Fn =
1186 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001187 CI->setCallingConv(Fn->getCallingConv());
1188 return CI;
1189}
1190
Sanjay Pateld3112a52016-01-19 19:46:10 +00001191Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001192 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001193 if (!TLI->has(LibFunc_fwrite))
Craig Topperf40110f2014-04-25 05:29:35 +00001194 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001195
Sanjay Pateld4af2972016-01-19 19:58:49 +00001196 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +00001197 LLVMContext &Context = B.GetInsertBlock()->getContext();
David L. Jonesd21529f2017-01-23 23:16:46 +00001198 StringRef FWriteName = TLI->getName(LibFunc_fwrite);
James Y Knight13680222019-02-01 02:28:03 +00001199 FunctionCallee F = M->getOrInsertFunction(
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001200 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001201 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1202
Eric Christopher87abfc52010-03-05 22:25:30 +00001203 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001204 inferLibFuncAttributes(M, FWriteName, *TLI);
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001205 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +00001206 B.CreateCall(F, {castToCStr(Ptr, B), Size,
David Blaikieff6409d2015-05-18 22:13:54 +00001207 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
Evan Chengad6efbf2014-03-12 18:09:37 +00001208
James Y Knight13680222019-02-01 02:28:03 +00001209 if (const Function *Fn =
1210 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001211 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001212 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001213}
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001214
1215Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
1216 const TargetLibraryInfo *TLI) {
1217 if (!TLI->has(LibFunc_malloc))
1218 return nullptr;
1219
1220 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001221 StringRef MallocName = TLI->getName(LibFunc_malloc);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001222 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +00001223 FunctionCallee Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(),
1224 DL.getIntPtrType(Context));
David Bolvansky7c7760d2018-10-16 21:18:31 +00001225 inferLibFuncAttributes(M, MallocName, *TLI);
1226 CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001227
James Y Knight13680222019-02-01 02:28:03 +00001228 if (const Function *F =
1229 dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts()))
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001230 CI->setCallingConv(F->getCallingConv());
1231
1232 return CI;
1233}
1234
1235Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
1236 IRBuilder<> &B, const TargetLibraryInfo &TLI) {
1237 if (!TLI.has(LibFunc_calloc))
1238 return nullptr;
1239
1240 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001241 StringRef CallocName = TLI.getName(LibFunc_calloc);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001242 const DataLayout &DL = M->getDataLayout();
1243 IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
James Y Knight13680222019-02-01 02:28:03 +00001244 FunctionCallee Calloc = M->getOrInsertFunction(
1245 CallocName, Attrs, B.getInt8PtrTy(), PtrType, PtrType);
David Bolvansky7c7760d2018-10-16 21:18:31 +00001246 inferLibFuncAttributes(M, CallocName, TLI);
1247 CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001248
James Y Knight13680222019-02-01 02:28:03 +00001249 if (const auto *F =
1250 dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts()))
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001251 CI->setCallingConv(F->getCallingConv());
1252
1253 return CI;
1254}
David Bolvanskyca22d422018-05-16 11:39:52 +00001255
1256Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1257 IRBuilder<> &B, const DataLayout &DL,
1258 const TargetLibraryInfo *TLI) {
1259 if (!TLI->has(LibFunc_fwrite_unlocked))
1260 return nullptr;
1261
1262 Module *M = B.GetInsertBlock()->getModule();
1263 LLVMContext &Context = B.GetInsertBlock()->getContext();
1264 StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001265 FunctionCallee F = M->getOrInsertFunction(
David Bolvanskyca22d422018-05-16 11:39:52 +00001266 FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1267 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1268
1269 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001270 inferLibFuncAttributes(M, FWriteUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001271 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1272
James Y Knight13680222019-02-01 02:28:03 +00001273 if (const Function *Fn =
1274 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001275 CI->setCallingConv(Fn->getCallingConv());
1276 return CI;
1277}
1278
1279Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
1280 const TargetLibraryInfo *TLI) {
1281 if (!TLI->has(LibFunc_fgetc_unlocked))
1282 return nullptr;
1283
1284 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001285 StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001286 FunctionCallee F = M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(),
1287 File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001288 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001289 inferLibFuncAttributes(M, FGetCUnlockedName, *TLI);
1290 CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001291
James Y Knight13680222019-02-01 02:28:03 +00001292 if (const Function *Fn =
1293 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001294 CI->setCallingConv(Fn->getCallingConv());
1295 return CI;
1296}
1297
1298Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
1299 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1300 if (!TLI->has(LibFunc_fgets_unlocked))
1301 return nullptr;
1302
1303 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001304 StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001305 FunctionCallee F =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001306 M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(),
Benjamin Kramer8ac15bf2018-05-16 21:45:39 +00001307 B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
David Bolvansky7c7760d2018-10-16 21:18:31 +00001308 inferLibFuncAttributes(M, FGetSUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001309 CallInst *CI =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001310 B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001311
James Y Knight13680222019-02-01 02:28:03 +00001312 if (const Function *Fn =
1313 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001314 CI->setCallingConv(Fn->getCallingConv());
1315 return CI;
1316}
1317
1318Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1319 IRBuilder<> &B, const DataLayout &DL,
1320 const TargetLibraryInfo *TLI) {
1321 if (!TLI->has(LibFunc_fread_unlocked))
1322 return nullptr;
1323
1324 Module *M = B.GetInsertBlock()->getModule();
1325 LLVMContext &Context = B.GetInsertBlock()->getContext();
1326 StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001327 FunctionCallee F = M->getOrInsertFunction(
David Bolvanskyca22d422018-05-16 11:39:52 +00001328 FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1329 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1330
1331 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001332 inferLibFuncAttributes(M, FReadUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001333 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1334
James Y Knight13680222019-02-01 02:28:03 +00001335 if (const Function *Fn =
1336 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001337 CI->setCallingConv(Fn->getCallingConv());
1338 return CI;
1339}