blob: fe6c602ecd42718ba14460fabe64bab3e30808fe [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"
Eric Christopher87abfc52010-03-05 22:25:30 +000025
26using namespace llvm;
27
Ahmed Bougachab0624a22016-04-27 19:04:40 +000028#define DEBUG_TYPE "build-libcalls"
29
30//- Infer Attributes ---------------------------------------------------------//
31
32STATISTIC(NumReadNone, "Number of functions inferred as readnone");
33STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
34STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
35STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
36STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
37STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
38STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
39STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
David Bolvansky8715e032018-08-23 05:18:23 +000040STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
Ahmed Bougachab0624a22016-04-27 19:04:40 +000041
42static bool setDoesNotAccessMemory(Function &F) {
43 if (F.doesNotAccessMemory())
44 return false;
45 F.setDoesNotAccessMemory();
46 ++NumReadNone;
47 return true;
48}
49
50static bool setOnlyReadsMemory(Function &F) {
51 if (F.onlyReadsMemory())
52 return false;
53 F.setOnlyReadsMemory();
54 ++NumReadOnly;
55 return true;
56}
57
58static bool setOnlyAccessesArgMemory(Function &F) {
59 if (F.onlyAccessesArgMemory())
60 return false;
Reid Klecknera0b45f42017-05-03 18:17:31 +000061 F.setOnlyAccessesArgMemory();
Ahmed Bougachab0624a22016-04-27 19:04:40 +000062 ++NumArgMemOnly;
63 return true;
64}
65
66static bool setDoesNotThrow(Function &F) {
67 if (F.doesNotThrow())
68 return false;
69 F.setDoesNotThrow();
70 ++NumNoUnwind;
71 return true;
72}
73
Reid Klecknera0b45f42017-05-03 18:17:31 +000074static bool setRetDoesNotAlias(Function &F) {
75 if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias))
Ahmed Bougachab0624a22016-04-27 19:04:40 +000076 return false;
Reid Klecknera0b45f42017-05-03 18:17:31 +000077 F.addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
Ahmed Bougachab0624a22016-04-27 19:04:40 +000078 ++NumNoAlias;
79 return true;
80}
81
Reid Klecknera0b45f42017-05-03 18:17:31 +000082static bool setDoesNotCapture(Function &F, unsigned ArgNo) {
83 if (F.hasParamAttribute(ArgNo, Attribute::NoCapture))
Ahmed Bougachab0624a22016-04-27 19:04:40 +000084 return false;
Reid Klecknera0b45f42017-05-03 18:17:31 +000085 F.addParamAttr(ArgNo, Attribute::NoCapture);
86 ++NumNoCapture;
87 return true;
88}
89
90static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
91 if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))
92 return false;
93 F.addParamAttr(ArgNo, Attribute::ReadOnly);
94 ++NumReadOnlyArg;
95 return true;
96}
97
98static bool setRetNonNull(Function &F) {
99 assert(F.getReturnType()->isPointerTy() &&
100 "nonnull applies only to pointers");
101 if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull))
102 return false;
103 F.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000104 ++NumNonNull;
105 return true;
106}
107
David Bolvansky8715e032018-08-23 05:18:23 +0000108static bool setReturnedArg(Function &F, unsigned ArgNo) {
109 if (F.hasParamAttribute(ArgNo, Attribute::Returned))
110 return false;
111 F.addParamAttr(ArgNo, Attribute::Returned);
112 ++NumReturnedArg;
113 return true;
114}
115
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000116static bool setNonLazyBind(Function &F) {
117 if (F.hasFnAttribute(Attribute::NonLazyBind))
118 return false;
119 F.addFnAttr(Attribute::NonLazyBind);
120 return true;
121}
122
David Bolvansky7c7760d2018-10-16 21:18:31 +0000123bool llvm::inferLibFuncAttributes(Module *M, StringRef Name,
David Bolvanskye8b3bba2018-10-13 15:21:55 +0000124 const TargetLibraryInfo &TLI) {
David Bolvansky7c7760d2018-10-16 21:18:31 +0000125 Function *F = M->getFunction(Name);
126 if (!F)
David Bolvanskye8b3bba2018-10-13 15:21:55 +0000127 return false;
David Bolvansky7c7760d2018-10-16 21:18:31 +0000128 return inferLibFuncAttributes(*F, TLI);
129}
130
131bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000132 LibFunc TheLibFunc;
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000133 if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
134 return false;
135
136 bool Changed = false;
Sriraman Tallam182f2df2018-04-10 23:32:36 +0000137
138 if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
139 Changed |= setNonLazyBind(F);
140
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000141 switch (TheLibFunc) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000142 case LibFunc_strlen:
Matthias Braun60b40b82017-05-05 20:25:50 +0000143 case LibFunc_wcslen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000144 Changed |= setOnlyReadsMemory(F);
145 Changed |= setDoesNotThrow(F);
Xin Tong9d2a5b12017-06-18 03:10:26 +0000146 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000147 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000148 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000149 case LibFunc_strchr:
150 case LibFunc_strrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000151 Changed |= setOnlyReadsMemory(F);
152 Changed |= setDoesNotThrow(F);
153 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000154 case LibFunc_strtol:
155 case LibFunc_strtod:
156 case LibFunc_strtof:
157 case LibFunc_strtoul:
158 case LibFunc_strtoll:
159 case LibFunc_strtold:
160 case LibFunc_strtoull:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000161 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000162 Changed |= setDoesNotCapture(F, 1);
163 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000164 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000165 case LibFunc_strcpy:
David Bolvansky8715e032018-08-23 05:18:23 +0000166 case LibFunc_strncpy:
David L. Jonesd21529f2017-01-23 23:16:46 +0000167 case LibFunc_strcat:
168 case LibFunc_strncat:
David Bolvansky8715e032018-08-23 05:18:23 +0000169 Changed |= setReturnedArg(F, 0);
170 LLVM_FALLTHROUGH;
171 case LibFunc_stpcpy:
David L. Jonesd21529f2017-01-23 23:16:46 +0000172 case LibFunc_stpncpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000173 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000174 Changed |= setDoesNotCapture(F, 1);
175 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000176 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000177 case LibFunc_strxfrm:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000178 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000179 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000180 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000181 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000182 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000183 case LibFunc_strcmp: // 0,1
184 case LibFunc_strspn: // 0,1
185 case LibFunc_strncmp: // 0,1
186 case LibFunc_strcspn: // 0,1
187 case LibFunc_strcoll: // 0,1
188 case LibFunc_strcasecmp: // 0,1
189 case LibFunc_strncasecmp: //
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000190 Changed |= setOnlyReadsMemory(F);
191 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000192 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000193 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000194 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000195 case LibFunc_strstr:
196 case LibFunc_strpbrk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000197 Changed |= setOnlyReadsMemory(F);
198 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000199 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000200 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000201 case LibFunc_strtok:
202 case LibFunc_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000203 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000204 Changed |= setDoesNotCapture(F, 1);
205 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000206 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000207 case LibFunc_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000208 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000209 Changed |= setDoesNotCapture(F, 0);
210 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000211 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000212 case LibFunc_setbuf:
213 case LibFunc_setvbuf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000214 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000215 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000216 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000217 case LibFunc_strdup:
218 case LibFunc_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000219 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000220 Changed |= setRetDoesNotAlias(F);
221 Changed |= setDoesNotCapture(F, 0);
222 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000223 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000224 case LibFunc_stat:
225 case LibFunc_statvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000226 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000227 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000228 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000229 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000230 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000231 case LibFunc_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000232 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000233 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000234 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000235 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000236 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000237 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000238 case LibFunc_sprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000239 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000240 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000241 Changed |= setDoesNotCapture(F, 1);
242 Changed |= setOnlyReadsMemory(F, 1);
243 return Changed;
Reid Klecknera0b45f42017-05-03 18:17:31 +0000244 case LibFunc_snprintf:
245 Changed |= setDoesNotThrow(F);
246 Changed |= setDoesNotCapture(F, 0);
247 Changed |= setDoesNotCapture(F, 2);
248 Changed |= setOnlyReadsMemory(F, 2);
249 return Changed;
250 case LibFunc_setitimer:
251 Changed |= setDoesNotThrow(F);
252 Changed |= setDoesNotCapture(F, 1);
253 Changed |= setDoesNotCapture(F, 2);
254 Changed |= setOnlyReadsMemory(F, 1);
255 return Changed;
256 case LibFunc_system:
257 // May throw; "system" is a valid pthread cancellation point.
258 Changed |= setDoesNotCapture(F, 0);
259 Changed |= setOnlyReadsMemory(F, 0);
260 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000261 case LibFunc_malloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000262 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000263 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000264 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000265 case LibFunc_memcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000266 Changed |= setOnlyReadsMemory(F);
267 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000268 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000269 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000270 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000271 case LibFunc_memchr:
272 case LibFunc_memrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000273 Changed |= setOnlyReadsMemory(F);
274 Changed |= setDoesNotThrow(F);
275 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000276 case LibFunc_modf:
277 case LibFunc_modff:
278 case LibFunc_modfl:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000279 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +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_memcpy:
David Bolvansky8715e032018-08-23 05:18:23 +0000283 case LibFunc_memmove:
284 Changed |= setReturnedArg(F, 0);
285 LLVM_FALLTHROUGH;
David L. Jonesd21529f2017-01-23 23:16:46 +0000286 case LibFunc_mempcpy:
287 case LibFunc_memccpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000288 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000289 Changed |= setDoesNotCapture(F, 1);
290 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000291 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000292 case LibFunc_memcpy_chk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000293 Changed |= setDoesNotThrow(F);
294 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000295 case LibFunc_memalign:
Reid Klecknera0b45f42017-05-03 18:17:31 +0000296 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000297 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000298 case LibFunc_mkdir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000299 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000300 Changed |= setDoesNotCapture(F, 0);
301 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000302 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000303 case LibFunc_mktime:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000304 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000305 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000306 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000307 case LibFunc_realloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000308 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000309 Changed |= setRetDoesNotAlias(F);
310 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000311 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000312 case LibFunc_read:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000313 // May throw; "read" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000314 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000315 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000316 case LibFunc_rewind:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000317 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000318 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000319 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000320 case LibFunc_rmdir:
321 case LibFunc_remove:
322 case LibFunc_realpath:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000323 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000324 Changed |= setDoesNotCapture(F, 0);
325 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000326 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000327 case LibFunc_rename:
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 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000331 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000332 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000333 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000334 case LibFunc_readlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000335 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000336 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000337 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000338 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000339 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000340 case LibFunc_write:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000341 // May throw; "write" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000342 Changed |= setDoesNotCapture(F, 1);
343 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_bcopy:
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_bcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000352 Changed |= setDoesNotThrow(F);
353 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000354 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000355 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000356 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000357 case LibFunc_bzero:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000358 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000359 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000360 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000361 case LibFunc_calloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000362 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000363 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000364 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000365 case LibFunc_chmod:
366 case LibFunc_chown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000367 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000368 Changed |= setDoesNotCapture(F, 0);
369 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000370 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000371 case LibFunc_ctermid:
372 case LibFunc_clearerr:
373 case LibFunc_closedir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000374 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000375 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000376 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000377 case LibFunc_atoi:
378 case LibFunc_atol:
379 case LibFunc_atof:
380 case LibFunc_atoll:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000381 Changed |= setDoesNotThrow(F);
382 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000383 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000384 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000385 case LibFunc_access:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000386 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000387 Changed |= setDoesNotCapture(F, 0);
388 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000389 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000390 case LibFunc_fopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000391 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000392 Changed |= setRetDoesNotAlias(F);
393 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000394 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000395 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000396 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000397 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000398 case LibFunc_fdopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000399 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000400 Changed |= setRetDoesNotAlias(F);
401 Changed |= setDoesNotCapture(F, 1);
402 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000403 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000404 case LibFunc_feof:
405 case LibFunc_free:
406 case LibFunc_fseek:
407 case LibFunc_ftell:
408 case LibFunc_fgetc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000409 case LibFunc_fgetc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000410 case LibFunc_fseeko:
411 case LibFunc_ftello:
412 case LibFunc_fileno:
413 case LibFunc_fflush:
414 case LibFunc_fclose:
415 case LibFunc_fsetpos:
416 case LibFunc_flockfile:
417 case LibFunc_funlockfile:
418 case LibFunc_ftrylockfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000419 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000420 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000421 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000422 case LibFunc_ferror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000423 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000424 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000425 Changed |= setOnlyReadsMemory(F);
426 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000427 case LibFunc_fputc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000428 case LibFunc_fputc_unlocked:
David L. Jonesd21529f2017-01-23 23:16:46 +0000429 case LibFunc_fstat:
430 case LibFunc_frexp:
431 case LibFunc_frexpf:
432 case LibFunc_frexpl:
433 case LibFunc_fstatvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000434 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000435 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000436 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000437 case LibFunc_fgets:
David Bolvanskyca22d422018-05-16 11:39:52 +0000438 case LibFunc_fgets_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000439 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000440 Changed |= setDoesNotCapture(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000441 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000442 case LibFunc_fread:
David Bolvanskyca22d422018-05-16 11:39:52 +0000443 case LibFunc_fread_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000444 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000445 Changed |= setDoesNotCapture(F, 0);
446 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000447 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000448 case LibFunc_fwrite:
David Bolvanskyca22d422018-05-16 11:39:52 +0000449 case LibFunc_fwrite_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000450 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000451 Changed |= setDoesNotCapture(F, 0);
452 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000453 // FIXME: readonly #1?
454 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000455 case LibFunc_fputs:
David Bolvanskyca22d422018-05-16 11:39:52 +0000456 case LibFunc_fputs_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000457 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000458 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000459 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000460 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000461 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000462 case LibFunc_fscanf:
463 case LibFunc_fprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000464 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000465 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000466 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000467 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000468 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000469 case LibFunc_fgetpos:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000470 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000471 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000472 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000473 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000474 case LibFunc_getc:
475 case LibFunc_getlogin_r:
476 case LibFunc_getc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000477 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000478 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000479 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000480 case LibFunc_getenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000481 Changed |= setDoesNotThrow(F);
482 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000483 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000484 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000485 case LibFunc_gets:
486 case LibFunc_getchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000487 case LibFunc_getchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000488 Changed |= setDoesNotThrow(F);
489 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000490 case LibFunc_getitimer:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000491 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000492 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000493 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000494 case LibFunc_getpwnam:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000495 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000496 Changed |= setDoesNotCapture(F, 0);
497 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000498 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000499 case LibFunc_ungetc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000500 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000501 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000502 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000503 case LibFunc_uname:
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_unlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000508 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000509 Changed |= setDoesNotCapture(F, 0);
510 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000511 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000512 case LibFunc_unsetenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000513 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000514 Changed |= setDoesNotCapture(F, 0);
515 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000516 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000517 case LibFunc_utime:
518 case LibFunc_utimes:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000519 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000520 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000521 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000522 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000523 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000524 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000525 case LibFunc_putc:
David Bolvanskyca22d422018-05-16 11:39:52 +0000526 case LibFunc_putc_unlocked:
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_puts:
531 case LibFunc_printf:
532 case LibFunc_perror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000533 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000534 Changed |= setDoesNotCapture(F, 0);
535 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000536 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000537 case LibFunc_pread:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000538 // May throw; "pread" is a valid pthread cancellation point.
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_pwrite:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000542 // May throw; "pwrite" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000543 Changed |= setDoesNotCapture(F, 1);
544 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000545 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000546 case LibFunc_putchar:
David Bolvanskyca22d422018-05-16 11:39:52 +0000547 case LibFunc_putchar_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000548 Changed |= setDoesNotThrow(F);
549 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000550 case LibFunc_popen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000551 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000552 Changed |= setRetDoesNotAlias(F);
553 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000554 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000555 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000556 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000557 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000558 case LibFunc_pclose:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000559 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000560 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000561 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000562 case LibFunc_vscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000563 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000564 Changed |= setDoesNotCapture(F, 0);
565 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000566 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000567 case LibFunc_vsscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000568 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000569 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000570 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000571 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000572 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000573 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000574 case LibFunc_vfscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000575 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000576 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000577 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000578 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000579 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000580 case LibFunc_valloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000581 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000582 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000583 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000584 case LibFunc_vprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000585 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000586 Changed |= setDoesNotCapture(F, 0);
587 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000588 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000589 case LibFunc_vfprintf:
590 case LibFunc_vsprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000591 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000592 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000593 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000594 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000595 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000596 case LibFunc_vsnprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000597 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000598 Changed |= setDoesNotCapture(F, 0);
599 Changed |= setDoesNotCapture(F, 2);
600 Changed |= setOnlyReadsMemory(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000601 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000602 case LibFunc_open:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000603 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000604 Changed |= setDoesNotCapture(F, 0);
605 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000606 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000607 case LibFunc_opendir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000608 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000609 Changed |= setRetDoesNotAlias(F);
610 Changed |= setDoesNotCapture(F, 0);
611 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000612 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000613 case LibFunc_tmpfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000614 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000615 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000616 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000617 case LibFunc_times:
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 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000621 case LibFunc_htonl:
622 case LibFunc_htons:
623 case LibFunc_ntohl:
624 case LibFunc_ntohs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000625 Changed |= setDoesNotThrow(F);
626 Changed |= setDoesNotAccessMemory(F);
627 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000628 case LibFunc_lstat:
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 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000632 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_lchown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000635 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000636 Changed |= setDoesNotCapture(F, 0);
637 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000638 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000639 case LibFunc_qsort:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000640 // May throw; places call through function pointer.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000641 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000642 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000643 case LibFunc_dunder_strdup:
644 case LibFunc_dunder_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000645 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000646 Changed |= setRetDoesNotAlias(F);
647 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_dunder_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000651 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000652 Changed |= setDoesNotCapture(F, 1);
653 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000654 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000655 case LibFunc_under_IO_getc:
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 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000659 case LibFunc_under_IO_putc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000660 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000661 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000662 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000663 case LibFunc_dunder_isoc99_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000664 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000665 Changed |= setDoesNotCapture(F, 0);
666 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000667 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000668 case LibFunc_stat64:
669 case LibFunc_lstat64:
670 case LibFunc_statvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000671 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000672 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000673 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000674 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000675 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000676 case LibFunc_dunder_isoc99_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000677 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000678 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000679 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000680 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000681 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000682 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000683 case LibFunc_fopen64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000684 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000685 Changed |= setRetDoesNotAlias(F);
686 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000687 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000688 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000689 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000690 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000691 case LibFunc_fseeko64:
692 case LibFunc_ftello64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000693 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000694 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000695 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000696 case LibFunc_tmpfile64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000697 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000698 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000699 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000700 case LibFunc_fstat64:
701 case LibFunc_fstatvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000702 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000703 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000704 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000705 case LibFunc_open64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000706 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000707 Changed |= setDoesNotCapture(F, 0);
708 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000709 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000710 case LibFunc_gettimeofday:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000711 // Currently some platforms have the restrict keyword on the arguments to
712 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
713 // arguments.
714 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000715 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000716 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000717 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000718 case LibFunc_Znwj: // new(unsigned int)
719 case LibFunc_Znwm: // new(unsigned long)
720 case LibFunc_Znaj: // new[](unsigned int)
721 case LibFunc_Znam: // new[](unsigned long)
722 case LibFunc_msvc_new_int: // new(unsigned int)
723 case LibFunc_msvc_new_longlong: // new(unsigned long long)
724 case LibFunc_msvc_new_array_int: // new[](unsigned int)
725 case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000726 // Operator new always returns a nonnull noalias pointer
Reid Klecknera0b45f42017-05-03 18:17:31 +0000727 Changed |= setRetNonNull(F);
728 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000729 return Changed;
David Bolvansky3ea50f92018-04-25 04:33:36 +0000730 // TODO: add LibFunc entries for:
731 // case LibFunc_memset_pattern4:
732 // case LibFunc_memset_pattern8:
David L. Jonesd21529f2017-01-23 23:16:46 +0000733 case LibFunc_memset_pattern16:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000734 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000735 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougacha44c19872016-04-27 19:04:43 +0000736 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000737 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000738 return Changed;
739 // int __nvvm_reflect(const char *)
David L. Jonesd21529f2017-01-23 23:16:46 +0000740 case LibFunc_nvvm_reflect:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000741 Changed |= setDoesNotAccessMemory(F);
742 Changed |= setDoesNotThrow(F);
743 return Changed;
744
745 default:
746 // FIXME: It'd be really nice to cover all the library functions we're
747 // aware of here.
748 return false;
749 }
750}
751
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000752bool llvm::hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
753 LibFunc DoubleFn, LibFunc FloatFn,
754 LibFunc LongDoubleFn) {
755 switch (Ty->getTypeID()) {
Benjamin Kramere5e1ea72018-09-19 12:01:38 +0000756 case Type::HalfTyID:
757 return false;
Dmitry Venikove5fbf592018-01-11 06:33:00 +0000758 case Type::FloatTyID:
759 return TLI->has(FloatFn);
760 case Type::DoubleTyID:
761 return TLI->has(DoubleFn);
762 default:
763 return TLI->has(LongDoubleFn);
764 }
765}
766
Mikael Holmene3605d02018-10-18 06:27:53 +0000767StringRef llvm::getUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
768 LibFunc DoubleFn, LibFunc FloatFn,
769 LibFunc LongDoubleFn) {
770 assert(hasUnaryFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
771 "Cannot get name for unavailable function!");
772
773 switch (Ty->getTypeID()) {
774 case Type::HalfTyID:
775 llvm_unreachable("No name for HalfTy!");
776 case Type::FloatTyID:
777 return TLI->getName(FloatFn);
778 case Type::DoubleTyID:
779 return TLI->getName(DoubleFn);
780 default:
781 return TLI->getName(LongDoubleFn);
782 }
783}
784
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000785//- Emit LibCalls ------------------------------------------------------------//
786
Sanjay Pateld3112a52016-01-19 19:46:10 +0000787Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
Matt Arsenaultbe558882014-04-23 20:58:57 +0000788 unsigned AS = V->getType()->getPointerAddressSpace();
789 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
Eric Christopher87abfc52010-03-05 22:25:30 +0000790}
791
Sanjay Pateld3112a52016-01-19 19:46:10 +0000792Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000793 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000794 if (!TLI->has(LibFunc_strlen))
Craig Topperf40110f2014-04-25 05:29:35 +0000795 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000796
Sanjay Pateld4af2972016-01-19 19:58:49 +0000797 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000798 StringRef StrlenName = TLI->getName(LibFunc_strlen);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000799 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +0000800 FunctionCallee StrLen = M->getOrInsertFunction(
801 StrlenName, DL.getIntPtrType(Context), B.getInt8PtrTy());
David Bolvansky7c7760d2018-10-16 21:18:31 +0000802 inferLibFuncAttributes(M, StrlenName, *TLI);
803 CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), StrlenName);
James Y Knight13680222019-02-01 02:28:03 +0000804 if (const Function *F =
805 dyn_cast<Function>(StrLen.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000806 CI->setCallingConv(F->getCallingConv());
807
Eric Christopher87abfc52010-03-05 22:25:30 +0000808 return CI;
809}
810
Sanjay Pateld3112a52016-01-19 19:46:10 +0000811Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000812 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000813 if (!TLI->has(LibFunc_strchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000814 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000815
Sanjay Pateld4af2972016-01-19 19:58:49 +0000816 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000817 StringRef StrChrName = TLI->getName(LibFunc_strchr);
Chris Lattner229907c2011-07-18 04:54:35 +0000818 Type *I8Ptr = B.getInt8PtrTy();
819 Type *I32Ty = B.getInt32Ty();
James Y Knight13680222019-02-01 02:28:03 +0000820 FunctionCallee StrChr =
David Bolvansky7c7760d2018-10-16 21:18:31 +0000821 M->getOrInsertFunction(StrChrName, I8Ptr, I8Ptr, I32Ty);
822 inferLibFuncAttributes(M, StrChrName, *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000823 CallInst *CI = B.CreateCall(
David Bolvansky7c7760d2018-10-16 21:18:31 +0000824 StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, StrChrName);
James Y Knight13680222019-02-01 02:28:03 +0000825 if (const Function *F =
826 dyn_cast<Function>(StrChr.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000827 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000828 return CI;
829}
830
Sanjay Pateld3112a52016-01-19 19:46:10 +0000831Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000832 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000833 if (!TLI->has(LibFunc_strncmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000834 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000835
Sanjay Pateld4af2972016-01-19 19:58:49 +0000836 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000837 StringRef StrNCmpName = TLI->getName(LibFunc_strncmp);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000838 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +0000839 FunctionCallee StrNCmp =
840 M->getOrInsertFunction(StrNCmpName, B.getInt32Ty(), B.getInt8PtrTy(),
841 B.getInt8PtrTy(), DL.getIntPtrType(Context));
David Bolvansky7c7760d2018-10-16 21:18:31 +0000842 inferLibFuncAttributes(M, StrNCmpName, *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000843 CallInst *CI = B.CreateCall(
David Bolvansky7c7760d2018-10-16 21:18:31 +0000844 StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, StrNCmpName);
Evan Chengad6efbf2014-03-12 18:09:37 +0000845
James Y Knight13680222019-02-01 02:28:03 +0000846 if (const Function *F =
847 dyn_cast<Function>(StrNCmp.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000848 CI->setCallingConv(F->getCallingConv());
849
Benjamin Kramer11188602010-06-15 21:34:25 +0000850 return CI;
851}
852
Sanjay Pateld3112a52016-01-19 19:46:10 +0000853Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000854 const TargetLibraryInfo *TLI, StringRef Name) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000855 if (!TLI->has(LibFunc_strcpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000856 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000857
Sanjay Pateld4af2972016-01-19 19:58:49 +0000858 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000859 Type *I8Ptr = B.getInt8PtrTy();
James Y Knight13680222019-02-01 02:28:03 +0000860 FunctionCallee StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr);
David Bolvansky7c7760d2018-10-16 21:18:31 +0000861 inferLibFuncAttributes(M, Name, *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000862 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +0000863 B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
James Y Knight13680222019-02-01 02:28:03 +0000864 if (const Function *F =
865 dyn_cast<Function>(StrCpy.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000866 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000867 return CI;
868}
869
Sanjay Pateld3112a52016-01-19 19:46:10 +0000870Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000871 const TargetLibraryInfo *TLI, StringRef Name) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000872 if (!TLI->has(LibFunc_strncpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000873 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000874
Sanjay Pateld4af2972016-01-19 19:58:49 +0000875 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000876 Type *I8Ptr = B.getInt8PtrTy();
James Y Knight13680222019-02-01 02:28:03 +0000877 FunctionCallee StrNCpy =
878 M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr, Len->getType());
David Bolvansky7c7760d2018-10-16 21:18:31 +0000879 inferLibFuncAttributes(M, Name, *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000880 CallInst *CI = B.CreateCall(
David Bolvansky7c7760d2018-10-16 21:18:31 +0000881 StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, Name);
James Y Knight13680222019-02-01 02:28:03 +0000882 if (const Function *F =
883 dyn_cast<Function>(StrNCpy.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000884 CI->setCallingConv(F->getCallingConv());
Eric Christopher43dc11c2010-03-11 01:25:07 +0000885 return CI;
886}
887
Sanjay Pateld3112a52016-01-19 19:46:10 +0000888Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000889 IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000890 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000891 if (!TLI->has(LibFunc_memcpy_chk))
Craig Topperf40110f2014-04-25 05:29:35 +0000892 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000893
Sanjay Pateld4af2972016-01-19 19:58:49 +0000894 Module *M = B.GetInsertBlock()->getModule();
Reid Klecknerb5180542017-03-21 16:57:19 +0000895 AttributeList AS;
896 AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
897 Attribute::NoUnwind);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000898 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +0000899 FunctionCallee MemCpy = M->getOrInsertFunction(
Reid Klecknerb5180542017-03-21 16:57:19 +0000900 "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000901 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000902 DL.getIntPtrType(Context));
Sanjay Pateld3112a52016-01-19 19:46:10 +0000903 Dst = castToCStr(Dst, B);
904 Src = castToCStr(Src, B);
David Blaikieff6409d2015-05-18 22:13:54 +0000905 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
James Y Knight13680222019-02-01 02:28:03 +0000906 if (const Function *F =
907 dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000908 CI->setCallingConv(F->getCallingConv());
Evan Chengd9e82232010-03-23 15:48:04 +0000909 return CI;
910}
911
Sanjay Pateld3112a52016-01-19 19:46:10 +0000912Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000913 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000914 if (!TLI->has(LibFunc_memchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000915 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000916
Sanjay Pateld4af2972016-01-19 19:58:49 +0000917 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +0000918 StringRef MemChrName = TLI->getName(LibFunc_memchr);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000919 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +0000920 FunctionCallee MemChr =
921 M->getOrInsertFunction(MemChrName, B.getInt8PtrTy(), B.getInt8PtrTy(),
922 B.getInt32Ty(), DL.getIntPtrType(Context));
David Bolvansky7c7760d2018-10-16 21:18:31 +0000923 inferLibFuncAttributes(M, MemChrName, *TLI);
924 CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, MemChrName);
Evan Chengad6efbf2014-03-12 18:09:37 +0000925
James Y Knight13680222019-02-01 02:28:03 +0000926 if (const Function *F =
927 dyn_cast<Function>(MemChr.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000928 CI->setCallingConv(F->getCallingConv());
929
Eric Christopher87abfc52010-03-05 22:25:30 +0000930 return CI;
931}
932
Clement Courbet8e16d732019-03-08 09:07:45 +0000933// Common code for memcmp() and bcmp(), which have the exact same properties,
934// just a slight difference in semantics.
935static Value *emitMemCmpOrBcmp(llvm::LibFunc libfunc, Value *Ptr1, Value *Ptr2,
936 Value *Len, IRBuilder<> &B, const DataLayout &DL,
937 const TargetLibraryInfo *TLI) {
938 if (!TLI->has(libfunc))
Craig Topperf40110f2014-04-25 05:29:35 +0000939 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000940
Sanjay Pateld4af2972016-01-19 19:58:49 +0000941 Module *M = B.GetInsertBlock()->getModule();
Clement Courbet8e16d732019-03-08 09:07:45 +0000942 StringRef CmpFnName = TLI->getName(libfunc);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000943 LLVMContext &Context = B.GetInsertBlock()->getContext();
Clement Courbet8e16d732019-03-08 09:07:45 +0000944 FunctionCallee CmpFn =
945 M->getOrInsertFunction(CmpFnName, B.getInt32Ty(), B.getInt8PtrTy(),
James Y Knight13680222019-02-01 02:28:03 +0000946 B.getInt8PtrTy(), DL.getIntPtrType(Context));
Clement Courbet8e16d732019-03-08 09:07:45 +0000947 inferLibFuncAttributes(M, CmpFnName, *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000948 CallInst *CI = B.CreateCall(
Clement Courbet8e16d732019-03-08 09:07:45 +0000949 CmpFn, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, CmpFnName);
Evan Chengad6efbf2014-03-12 18:09:37 +0000950
James Y Knight13680222019-02-01 02:28:03 +0000951 if (const Function *F =
Clement Courbet8e16d732019-03-08 09:07:45 +0000952 dyn_cast<Function>(CmpFn.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +0000953 CI->setCallingConv(F->getCallingConv());
954
Eric Christopher87abfc52010-03-05 22:25:30 +0000955 return CI;
956}
957
Clement Courbet8e16d732019-03-08 09:07:45 +0000958Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
959 const DataLayout &DL, const TargetLibraryInfo *TLI) {
960 return emitMemCmpOrBcmp(LibFunc_memcmp, Ptr1, Ptr2, Len, B, DL, TLI);
961}
962
963Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
964 const DataLayout &DL, const TargetLibraryInfo *TLI) {
965 return emitMemCmpOrBcmp(LibFunc_bcmp, Ptr1, Ptr2, Len, B, DL, TLI);
966}
967
Yi Jiang6ab044e2013-12-16 22:42:40 +0000968/// Append a suffix to the function name according to the type of 'Op'.
Sanjay Pateld3112a52016-01-19 19:46:10 +0000969static void appendTypeSuffix(Value *Op, StringRef &Name,
Sanjay Patelb50325e2016-01-19 19:17:47 +0000970 SmallString<20> &NameBuffer) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000971 if (!Op->getType()->isDoubleTy()) {
972 NameBuffer += Name;
973
974 if (Op->getType()->isFloatTy())
975 NameBuffer += 'f';
976 else
977 NameBuffer += 'l';
978
979 Name = NameBuffer;
Fangrui Songf78650a2018-07-30 19:41:25 +0000980 }
Yi Jiang6ab044e2013-12-16 22:42:40 +0000981}
982
Mikael Holmene3605d02018-10-18 06:27:53 +0000983static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
984 IRBuilder<> &B,
985 const AttributeList &Attrs) {
986 assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
Eric Christopher87abfc52010-03-05 22:25:30 +0000987
Sanjay Pateld4af2972016-01-19 19:58:49 +0000988 Module *M = B.GetInsertBlock()->getModule();
James Y Knight13680222019-02-01 02:28:03 +0000989 FunctionCallee Callee =
990 M->getOrInsertFunction(Name, Op->getType(), Op->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +0000991 CallInst *CI = B.CreateCall(Callee, Op, Name);
Matt Arsenault6a288c12017-05-03 02:26:10 +0000992
993 // The incoming attribute set may have come from a speculatable intrinsic, but
994 // is being replaced with a library call which is not allowed to be
995 // speculatable.
996 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
997 AttributeList::FunctionIndex,
998 Attribute::Speculatable));
James Y Knight13680222019-02-01 02:28:03 +0000999 if (const Function *F =
1000 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001001 CI->setCallingConv(F->getCallingConv());
1002
Eric Christopher87abfc52010-03-05 22:25:30 +00001003 return CI;
1004}
1005
Mikael Holmene3605d02018-10-18 06:27:53 +00001006Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
1007 const AttributeList &Attrs) {
1008 SmallString<20> NameBuffer;
1009 appendTypeSuffix(Op, Name, NameBuffer);
1010
1011 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1012}
1013
1014Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
1015 LibFunc DoubleFn, LibFunc FloatFn,
1016 LibFunc LongDoubleFn, IRBuilder<> &B,
1017 const AttributeList &Attrs) {
1018 // Get the name of the function according to TLI.
1019 StringRef Name = getUnaryFloatFn(TLI, Op->getType(),
1020 DoubleFn, FloatFn, LongDoubleFn);
1021
1022 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1023}
1024
Sanjay Pateld3112a52016-01-19 19:46:10 +00001025Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
Reid Klecknerb5180542017-03-21 16:57:19 +00001026 IRBuilder<> &B, const AttributeList &Attrs) {
Mikael Holmene3605d02018-10-18 06:27:53 +00001027 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1028
Yi Jiang6ab044e2013-12-16 22:42:40 +00001029 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +00001030 appendTypeSuffix(Op1, Name, NameBuffer);
Yi Jiang6ab044e2013-12-16 22:42:40 +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 = M->getOrInsertFunction(
1034 Name, Op1->getType(), Op1->getType(), Op2->getType());
David Blaikieff6409d2015-05-18 22:13:54 +00001035 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
Yi Jiang6ab044e2013-12-16 22:42:40 +00001036 CI->setAttributes(Attrs);
James Y Knight13680222019-02-01 02:28:03 +00001037 if (const Function *F =
1038 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001039 CI->setCallingConv(F->getCallingConv());
1040
Yi Jiang6ab044e2013-12-16 22:42:40 +00001041 return CI;
1042}
1043
Sanjay Pateld3112a52016-01-19 19:46:10 +00001044Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +00001045 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001046 if (!TLI->has(LibFunc_putchar))
Craig Topperf40110f2014-04-25 05:29:35 +00001047 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001048
Sanjay Pateld4af2972016-01-19 19:58:49 +00001049 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001050 StringRef PutCharName = TLI->getName(LibFunc_putchar);
James Y Knight13680222019-02-01 02:28:03 +00001051 FunctionCallee PutChar =
1052 M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty());
David Bolvansky7c7760d2018-10-16 21:18:31 +00001053 inferLibFuncAttributes(M, PutCharName, *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001054 CallInst *CI = B.CreateCall(PutChar,
1055 B.CreateIntCast(Char,
1056 B.getInt32Ty(),
1057 /*isSigned*/true,
1058 "chari"),
David Bolvansky7c7760d2018-10-16 21:18:31 +00001059 PutCharName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001060
James Y Knight13680222019-02-01 02:28:03 +00001061 if (const Function *F =
1062 dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001063 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +00001064 return CI;
1065}
1066
Sanjay Pateld3112a52016-01-19 19:46:10 +00001067Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +00001068 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001069 if (!TLI->has(LibFunc_puts))
Craig Topperf40110f2014-04-25 05:29:35 +00001070 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001071
Sanjay Pateld4af2972016-01-19 19:58:49 +00001072 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001073 StringRef PutsName = TLI->getName(LibFunc_puts);
James Y Knight13680222019-02-01 02:28:03 +00001074 FunctionCallee PutS =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001075 M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy());
1076 inferLibFuncAttributes(M, PutsName, *TLI);
1077 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName);
James Y Knight13680222019-02-01 02:28:03 +00001078 if (const Function *F =
1079 dyn_cast<Function>(PutS.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001080 CI->setCallingConv(F->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001081 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001082}
1083
Sanjay Pateld3112a52016-01-19 19:46:10 +00001084Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001085 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001086 if (!TLI->has(LibFunc_fputc))
Craig Topperf40110f2014-04-25 05:29:35 +00001087 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001088
Sanjay Pateld4af2972016-01-19 19:58:49 +00001089 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001090 StringRef FPutcName = TLI->getName(LibFunc_fputc);
James Y Knight13680222019-02-01 02:28:03 +00001091 FunctionCallee F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(),
1092 B.getInt32Ty(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001093 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001094 inferLibFuncAttributes(M, FPutcName, *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +00001095 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
1096 "chari");
David Bolvansky7c7760d2018-10-16 21:18:31 +00001097 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001098
James Y Knight13680222019-02-01 02:28:03 +00001099 if (const Function *Fn =
1100 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001101 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001102 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001103}
1104
David Bolvanskyca22d422018-05-16 11:39:52 +00001105Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
1106 const TargetLibraryInfo *TLI) {
1107 if (!TLI->has(LibFunc_fputc_unlocked))
1108 return nullptr;
1109
1110 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001111 StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001112 FunctionCallee F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(),
1113 B.getInt32Ty(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001114 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001115 inferLibFuncAttributes(M, FPutcUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001116 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
David Bolvansky7c7760d2018-10-16 21:18:31 +00001117 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001118
James Y Knight13680222019-02-01 02:28:03 +00001119 if (const Function *Fn =
1120 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001121 CI->setCallingConv(Fn->getCallingConv());
1122 return CI;
1123}
1124
Sanjay Pateld3112a52016-01-19 19:46:10 +00001125Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001126 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001127 if (!TLI->has(LibFunc_fputs))
Craig Topperf40110f2014-04-25 05:29:35 +00001128 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001129
Sanjay Pateld4af2972016-01-19 19:58:49 +00001130 Module *M = B.GetInsertBlock()->getModule();
David L. Jonesd21529f2017-01-23 23:16:46 +00001131 StringRef FPutsName = TLI->getName(LibFunc_fputs);
James Y Knight13680222019-02-01 02:28:03 +00001132 FunctionCallee F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
1133 B.getInt8PtrTy(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +00001134 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001135 inferLibFuncAttributes(M, FPutsName, *TLI);
1136 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName);
Evan Chengad6efbf2014-03-12 18:09:37 +00001137
James Y Knight13680222019-02-01 02:28:03 +00001138 if (const Function *Fn =
1139 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001140 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001141 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001142}
1143
David Bolvanskyca22d422018-05-16 11:39:52 +00001144Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
1145 const TargetLibraryInfo *TLI) {
1146 if (!TLI->has(LibFunc_fputs_unlocked))
1147 return nullptr;
1148
1149 Module *M = B.GetInsertBlock()->getModule();
1150 StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001151 FunctionCallee F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
1152 B.getInt8PtrTy(), File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001153 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001154 inferLibFuncAttributes(M, FPutsUnlockedName, *TLI);
1155 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001156
James Y Knight13680222019-02-01 02:28:03 +00001157 if (const Function *Fn =
1158 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001159 CI->setCallingConv(Fn->getCallingConv());
1160 return CI;
1161}
1162
Sanjay Pateld3112a52016-01-19 19:46:10 +00001163Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001164 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +00001165 if (!TLI->has(LibFunc_fwrite))
Craig Topperf40110f2014-04-25 05:29:35 +00001166 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +00001167
Sanjay Pateld4af2972016-01-19 19:58:49 +00001168 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +00001169 LLVMContext &Context = B.GetInsertBlock()->getContext();
David L. Jonesd21529f2017-01-23 23:16:46 +00001170 StringRef FWriteName = TLI->getName(LibFunc_fwrite);
James Y Knight13680222019-02-01 02:28:03 +00001171 FunctionCallee F = M->getOrInsertFunction(
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001172 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001173 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1174
Eric Christopher87abfc52010-03-05 22:25:30 +00001175 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001176 inferLibFuncAttributes(M, FWriteName, *TLI);
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001177 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +00001178 B.CreateCall(F, {castToCStr(Ptr, B), Size,
David Blaikieff6409d2015-05-18 22:13:54 +00001179 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
Evan Chengad6efbf2014-03-12 18:09:37 +00001180
James Y Knight13680222019-02-01 02:28:03 +00001181 if (const Function *Fn =
1182 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
Evan Chengad6efbf2014-03-12 18:09:37 +00001183 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001184 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001185}
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001186
1187Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
1188 const TargetLibraryInfo *TLI) {
1189 if (!TLI->has(LibFunc_malloc))
1190 return nullptr;
1191
1192 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001193 StringRef MallocName = TLI->getName(LibFunc_malloc);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001194 LLVMContext &Context = B.GetInsertBlock()->getContext();
James Y Knight13680222019-02-01 02:28:03 +00001195 FunctionCallee Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(),
1196 DL.getIntPtrType(Context));
David Bolvansky7c7760d2018-10-16 21:18:31 +00001197 inferLibFuncAttributes(M, MallocName, *TLI);
1198 CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001199
James Y Knight13680222019-02-01 02:28:03 +00001200 if (const Function *F =
1201 dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts()))
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001202 CI->setCallingConv(F->getCallingConv());
1203
1204 return CI;
1205}
1206
1207Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
1208 IRBuilder<> &B, const TargetLibraryInfo &TLI) {
1209 if (!TLI.has(LibFunc_calloc))
1210 return nullptr;
1211
1212 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001213 StringRef CallocName = TLI.getName(LibFunc_calloc);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001214 const DataLayout &DL = M->getDataLayout();
1215 IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
James Y Knight13680222019-02-01 02:28:03 +00001216 FunctionCallee Calloc = M->getOrInsertFunction(
1217 CallocName, Attrs, B.getInt8PtrTy(), PtrType, PtrType);
David Bolvansky7c7760d2018-10-16 21:18:31 +00001218 inferLibFuncAttributes(M, CallocName, TLI);
1219 CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001220
James Y Knight13680222019-02-01 02:28:03 +00001221 if (const auto *F =
1222 dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts()))
Sanjay Patelb2ab3f22018-04-18 14:21:31 +00001223 CI->setCallingConv(F->getCallingConv());
1224
1225 return CI;
1226}
David Bolvanskyca22d422018-05-16 11:39:52 +00001227
1228Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1229 IRBuilder<> &B, const DataLayout &DL,
1230 const TargetLibraryInfo *TLI) {
1231 if (!TLI->has(LibFunc_fwrite_unlocked))
1232 return nullptr;
1233
1234 Module *M = B.GetInsertBlock()->getModule();
1235 LLVMContext &Context = B.GetInsertBlock()->getContext();
1236 StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001237 FunctionCallee F = M->getOrInsertFunction(
David Bolvanskyca22d422018-05-16 11:39:52 +00001238 FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1239 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1240
1241 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001242 inferLibFuncAttributes(M, FWriteUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001243 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1244
James Y Knight13680222019-02-01 02:28:03 +00001245 if (const Function *Fn =
1246 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001247 CI->setCallingConv(Fn->getCallingConv());
1248 return CI;
1249}
1250
1251Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
1252 const TargetLibraryInfo *TLI) {
1253 if (!TLI->has(LibFunc_fgetc_unlocked))
1254 return nullptr;
1255
1256 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001257 StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001258 FunctionCallee F = M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(),
1259 File->getType());
David Bolvanskyca22d422018-05-16 11:39:52 +00001260 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001261 inferLibFuncAttributes(M, FGetCUnlockedName, *TLI);
1262 CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001263
James Y Knight13680222019-02-01 02:28:03 +00001264 if (const Function *Fn =
1265 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001266 CI->setCallingConv(Fn->getCallingConv());
1267 return CI;
1268}
1269
1270Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
1271 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1272 if (!TLI->has(LibFunc_fgets_unlocked))
1273 return nullptr;
1274
1275 Module *M = B.GetInsertBlock()->getModule();
David Bolvansky7c7760d2018-10-16 21:18:31 +00001276 StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001277 FunctionCallee F =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001278 M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(),
Benjamin Kramer8ac15bf2018-05-16 21:45:39 +00001279 B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
David Bolvansky7c7760d2018-10-16 21:18:31 +00001280 inferLibFuncAttributes(M, FGetSUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001281 CallInst *CI =
David Bolvansky7c7760d2018-10-16 21:18:31 +00001282 B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName);
David Bolvanskyca22d422018-05-16 11:39:52 +00001283
James Y Knight13680222019-02-01 02:28:03 +00001284 if (const Function *Fn =
1285 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001286 CI->setCallingConv(Fn->getCallingConv());
1287 return CI;
1288}
1289
1290Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1291 IRBuilder<> &B, const DataLayout &DL,
1292 const TargetLibraryInfo *TLI) {
1293 if (!TLI->has(LibFunc_fread_unlocked))
1294 return nullptr;
1295
1296 Module *M = B.GetInsertBlock()->getModule();
1297 LLVMContext &Context = B.GetInsertBlock()->getContext();
1298 StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
James Y Knight13680222019-02-01 02:28:03 +00001299 FunctionCallee F = M->getOrInsertFunction(
David Bolvanskyca22d422018-05-16 11:39:52 +00001300 FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1301 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1302
1303 if (File->getType()->isPointerTy())
David Bolvansky7c7760d2018-10-16 21:18:31 +00001304 inferLibFuncAttributes(M, FReadUnlockedName, *TLI);
David Bolvanskyca22d422018-05-16 11:39:52 +00001305 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1306
James Y Knight13680222019-02-01 02:28:03 +00001307 if (const Function *Fn =
1308 dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
David Bolvanskyca22d422018-05-16 11:39:52 +00001309 CI->setCallingConv(Fn->getCallingConv());
1310 return CI;
1311}