blob: b60dfb4f3541ddc73d7747f73fcf1fc03c216169 [file] [log] [blame]
Eric Christopher87abfc52010-03-05 22:25:30 +00001//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements some functions that will create standard C libcalls.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Transforms/Utils/BuildLibCalls.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000015#include "llvm/ADT/SmallString.h"
Ahmed Bougachab0624a22016-04-27 19:04:40 +000016#include "llvm/ADT/Statistic.h"
Weiming Zhao45d4cb92015-11-24 18:57:06 +000017#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000018#include "llvm/IR/Constants.h"
19#include "llvm/IR/DataLayout.h"
20#include "llvm/IR/Function.h"
21#include "llvm/IR/IRBuilder.h"
22#include "llvm/IR/Intrinsics.h"
23#include "llvm/IR/LLVMContext.h"
24#include "llvm/IR/Module.h"
25#include "llvm/IR/Type.h"
Eric Christopher87abfc52010-03-05 22:25:30 +000026
27using namespace llvm;
28
Ahmed Bougachab0624a22016-04-27 19:04:40 +000029#define DEBUG_TYPE "build-libcalls"
30
31//- Infer Attributes ---------------------------------------------------------//
32
33STATISTIC(NumReadNone, "Number of functions inferred as readnone");
34STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
35STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
36STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
37STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
38STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
39STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
40STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
41
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
108bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000109 LibFunc TheLibFunc;
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000110 if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
111 return false;
112
113 bool Changed = false;
114 switch (TheLibFunc) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000115 case LibFunc_strlen:
Matthias Braun60b40b82017-05-05 20:25:50 +0000116 case LibFunc_wcslen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000117 Changed |= setOnlyReadsMemory(F);
118 Changed |= setDoesNotThrow(F);
Xin Tong9d2a5b12017-06-18 03:10:26 +0000119 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000120 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000121 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000122 case LibFunc_strchr:
123 case LibFunc_strrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000124 Changed |= setOnlyReadsMemory(F);
125 Changed |= setDoesNotThrow(F);
126 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000127 case LibFunc_strtol:
128 case LibFunc_strtod:
129 case LibFunc_strtof:
130 case LibFunc_strtoul:
131 case LibFunc_strtoll:
132 case LibFunc_strtold:
133 case LibFunc_strtoull:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000134 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000135 Changed |= setDoesNotCapture(F, 1);
136 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000137 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000138 case LibFunc_strcpy:
139 case LibFunc_stpcpy:
140 case LibFunc_strcat:
141 case LibFunc_strncat:
142 case LibFunc_strncpy:
143 case LibFunc_stpncpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000144 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000145 Changed |= setDoesNotCapture(F, 1);
146 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000147 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000148 case LibFunc_strxfrm:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000149 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000150 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000151 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000152 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000153 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000154 case LibFunc_strcmp: // 0,1
155 case LibFunc_strspn: // 0,1
156 case LibFunc_strncmp: // 0,1
157 case LibFunc_strcspn: // 0,1
158 case LibFunc_strcoll: // 0,1
159 case LibFunc_strcasecmp: // 0,1
160 case LibFunc_strncasecmp: //
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000161 Changed |= setOnlyReadsMemory(F);
162 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000163 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000164 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000165 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000166 case LibFunc_strstr:
167 case LibFunc_strpbrk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000168 Changed |= setOnlyReadsMemory(F);
169 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000170 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000171 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000172 case LibFunc_strtok:
173 case LibFunc_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000174 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000175 Changed |= setDoesNotCapture(F, 1);
176 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000177 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000178 case LibFunc_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000179 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000180 Changed |= setDoesNotCapture(F, 0);
181 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000182 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000183 case LibFunc_setbuf:
184 case LibFunc_setvbuf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000185 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000186 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000187 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000188 case LibFunc_strdup:
189 case LibFunc_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000190 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000191 Changed |= setRetDoesNotAlias(F);
192 Changed |= setDoesNotCapture(F, 0);
193 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000194 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000195 case LibFunc_stat:
196 case LibFunc_statvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000197 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000198 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000199 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000200 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000201 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000202 case LibFunc_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000203 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000204 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000205 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000206 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000207 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000208 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000209 case LibFunc_sprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000210 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000211 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000212 Changed |= setDoesNotCapture(F, 1);
213 Changed |= setOnlyReadsMemory(F, 1);
214 return Changed;
Reid Klecknera0b45f42017-05-03 18:17:31 +0000215 case LibFunc_snprintf:
216 Changed |= setDoesNotThrow(F);
217 Changed |= setDoesNotCapture(F, 0);
218 Changed |= setDoesNotCapture(F, 2);
219 Changed |= setOnlyReadsMemory(F, 2);
220 return Changed;
221 case LibFunc_setitimer:
222 Changed |= setDoesNotThrow(F);
223 Changed |= setDoesNotCapture(F, 1);
224 Changed |= setDoesNotCapture(F, 2);
225 Changed |= setOnlyReadsMemory(F, 1);
226 return Changed;
227 case LibFunc_system:
228 // May throw; "system" is a valid pthread cancellation point.
229 Changed |= setDoesNotCapture(F, 0);
230 Changed |= setOnlyReadsMemory(F, 0);
231 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000232 case LibFunc_malloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000233 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000234 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000235 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000236 case LibFunc_memcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000237 Changed |= setOnlyReadsMemory(F);
238 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000239 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000240 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000241 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000242 case LibFunc_memchr:
243 case LibFunc_memrchr:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000244 Changed |= setOnlyReadsMemory(F);
245 Changed |= setDoesNotThrow(F);
246 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000247 case LibFunc_modf:
248 case LibFunc_modff:
249 case LibFunc_modfl:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000250 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000251 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000252 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000253 case LibFunc_memcpy:
254 case LibFunc_mempcpy:
255 case LibFunc_memccpy:
256 case LibFunc_memmove:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000257 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000258 Changed |= setDoesNotCapture(F, 1);
259 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000260 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000261 case LibFunc_memcpy_chk:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000262 Changed |= setDoesNotThrow(F);
263 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000264 case LibFunc_memalign:
Reid Klecknera0b45f42017-05-03 18:17:31 +0000265 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000266 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000267 case LibFunc_mkdir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000268 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000269 Changed |= setDoesNotCapture(F, 0);
270 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000271 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000272 case LibFunc_mktime:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000273 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000274 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000275 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000276 case LibFunc_realloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000277 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000278 Changed |= setRetDoesNotAlias(F);
279 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000280 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000281 case LibFunc_read:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000282 // May throw; "read" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000283 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000284 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000285 case LibFunc_rewind:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000286 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000287 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000288 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000289 case LibFunc_rmdir:
290 case LibFunc_remove:
291 case LibFunc_realpath:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000292 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000293 Changed |= setDoesNotCapture(F, 0);
294 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000295 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000296 case LibFunc_rename:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000297 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000298 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000299 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000300 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000301 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_readlink:
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 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000307 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000308 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000309 case LibFunc_write:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000310 // May throw; "write" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000311 Changed |= setDoesNotCapture(F, 1);
312 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000313 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000314 case LibFunc_bcopy:
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 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000318 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000319 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000320 case LibFunc_bcmp:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000321 Changed |= setDoesNotThrow(F);
322 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000323 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000324 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000325 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000326 case LibFunc_bzero:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000327 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000328 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000329 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000330 case LibFunc_calloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000331 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000332 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000333 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000334 case LibFunc_chmod:
335 case LibFunc_chown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000336 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000337 Changed |= setDoesNotCapture(F, 0);
338 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_ctermid:
341 case LibFunc_clearerr:
342 case LibFunc_closedir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000343 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000344 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000345 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000346 case LibFunc_atoi:
347 case LibFunc_atol:
348 case LibFunc_atof:
349 case LibFunc_atoll:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000350 Changed |= setDoesNotThrow(F);
351 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000352 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000353 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000354 case LibFunc_access:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000355 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000356 Changed |= setDoesNotCapture(F, 0);
357 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000358 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000359 case LibFunc_fopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000360 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000361 Changed |= setRetDoesNotAlias(F);
362 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000363 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000364 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000365 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000366 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000367 case LibFunc_fdopen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000368 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000369 Changed |= setRetDoesNotAlias(F);
370 Changed |= setDoesNotCapture(F, 1);
371 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000372 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000373 case LibFunc_feof:
374 case LibFunc_free:
375 case LibFunc_fseek:
376 case LibFunc_ftell:
377 case LibFunc_fgetc:
378 case LibFunc_fseeko:
379 case LibFunc_ftello:
380 case LibFunc_fileno:
381 case LibFunc_fflush:
382 case LibFunc_fclose:
383 case LibFunc_fsetpos:
384 case LibFunc_flockfile:
385 case LibFunc_funlockfile:
386 case LibFunc_ftrylockfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000387 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000388 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000389 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000390 case LibFunc_ferror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000391 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000392 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000393 Changed |= setOnlyReadsMemory(F);
394 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000395 case LibFunc_fputc:
396 case LibFunc_fstat:
397 case LibFunc_frexp:
398 case LibFunc_frexpf:
399 case LibFunc_frexpl:
400 case LibFunc_fstatvfs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000401 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000402 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000403 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000404 case LibFunc_fgets:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000405 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000406 Changed |= setDoesNotCapture(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000407 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000408 case LibFunc_fread:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000409 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000410 Changed |= setDoesNotCapture(F, 0);
411 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000412 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000413 case LibFunc_fwrite:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000414 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000415 Changed |= setDoesNotCapture(F, 0);
416 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000417 // FIXME: readonly #1?
418 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000419 case LibFunc_fputs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000420 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000421 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000422 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000423 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000424 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000425 case LibFunc_fscanf:
426 case LibFunc_fprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000427 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000428 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000429 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000430 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000431 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000432 case LibFunc_fgetpos:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000433 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000434 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +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_getc:
438 case LibFunc_getlogin_r:
439 case LibFunc_getc_unlocked:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000440 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000441 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000442 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000443 case LibFunc_getenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000444 Changed |= setDoesNotThrow(F);
445 Changed |= setOnlyReadsMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000446 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000447 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000448 case LibFunc_gets:
449 case LibFunc_getchar:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000450 Changed |= setDoesNotThrow(F);
451 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000452 case LibFunc_getitimer:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000453 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000454 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000455 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000456 case LibFunc_getpwnam:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000457 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000458 Changed |= setDoesNotCapture(F, 0);
459 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000460 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000461 case LibFunc_ungetc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000462 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000463 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000464 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000465 case LibFunc_uname:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000466 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000467 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000468 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000469 case LibFunc_unlink:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000470 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000471 Changed |= setDoesNotCapture(F, 0);
472 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000473 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000474 case LibFunc_unsetenv:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000475 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000476 Changed |= setDoesNotCapture(F, 0);
477 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000478 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000479 case LibFunc_utime:
480 case LibFunc_utimes:
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);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000484 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000485 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000486 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000487 case LibFunc_putc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000488 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000489 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000490 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000491 case LibFunc_puts:
492 case LibFunc_printf:
493 case LibFunc_perror:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000494 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000495 Changed |= setDoesNotCapture(F, 0);
496 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000497 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000498 case LibFunc_pread:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000499 // May throw; "pread" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000500 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000501 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000502 case LibFunc_pwrite:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000503 // May throw; "pwrite" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000504 Changed |= setDoesNotCapture(F, 1);
505 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000506 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000507 case LibFunc_putchar:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000508 Changed |= setDoesNotThrow(F);
509 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000510 case LibFunc_popen:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000511 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000512 Changed |= setRetDoesNotAlias(F);
513 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000514 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000515 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000516 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000517 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000518 case LibFunc_pclose:
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 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000522 case LibFunc_vscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000523 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000524 Changed |= setDoesNotCapture(F, 0);
525 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000526 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000527 case LibFunc_vsscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000528 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000529 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000530 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000531 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000532 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000533 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000534 case LibFunc_vfscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000535 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000536 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000537 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000538 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000539 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000540 case LibFunc_valloc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000541 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000542 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000543 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000544 case LibFunc_vprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000545 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000546 Changed |= setDoesNotCapture(F, 0);
547 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000548 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000549 case LibFunc_vfprintf:
550 case LibFunc_vsprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000551 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000552 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000553 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000554 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000555 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000556 case LibFunc_vsnprintf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000557 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000558 Changed |= setDoesNotCapture(F, 0);
559 Changed |= setDoesNotCapture(F, 2);
560 Changed |= setOnlyReadsMemory(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000561 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000562 case LibFunc_open:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000563 // May throw; "open" is a valid pthread cancellation point.
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_opendir:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000568 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000569 Changed |= setRetDoesNotAlias(F);
570 Changed |= setDoesNotCapture(F, 0);
571 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000572 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000573 case LibFunc_tmpfile:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000574 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000575 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000576 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000577 case LibFunc_times:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000578 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000579 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000580 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000581 case LibFunc_htonl:
582 case LibFunc_htons:
583 case LibFunc_ntohl:
584 case LibFunc_ntohs:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000585 Changed |= setDoesNotThrow(F);
586 Changed |= setDoesNotAccessMemory(F);
587 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000588 case LibFunc_lstat:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000589 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000590 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000591 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000592 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000593 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000594 case LibFunc_lchown:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000595 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000596 Changed |= setDoesNotCapture(F, 0);
597 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000598 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000599 case LibFunc_qsort:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000600 // May throw; places call through function pointer.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000601 Changed |= setDoesNotCapture(F, 3);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000602 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000603 case LibFunc_dunder_strdup:
604 case LibFunc_dunder_strndup:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000605 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000606 Changed |= setRetDoesNotAlias(F);
607 Changed |= setDoesNotCapture(F, 0);
608 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000609 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000610 case LibFunc_dunder_strtok_r:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000611 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000612 Changed |= setDoesNotCapture(F, 1);
613 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000614 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000615 case LibFunc_under_IO_getc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000616 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000617 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000618 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000619 case LibFunc_under_IO_putc:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000620 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000621 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000622 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000623 case LibFunc_dunder_isoc99_scanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000624 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000625 Changed |= setDoesNotCapture(F, 0);
626 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000627 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000628 case LibFunc_stat64:
629 case LibFunc_lstat64:
630 case LibFunc_statvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000631 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000632 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000633 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000634 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000635 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000636 case LibFunc_dunder_isoc99_sscanf:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000637 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000638 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000639 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000640 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000641 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000642 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000643 case LibFunc_fopen64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000644 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000645 Changed |= setRetDoesNotAlias(F);
646 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000647 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000648 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000649 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000650 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000651 case LibFunc_fseeko64:
652 case LibFunc_ftello64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000653 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000654 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000655 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000656 case LibFunc_tmpfile64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000657 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000658 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000659 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000660 case LibFunc_fstat64:
661 case LibFunc_fstatvfs64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000662 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000663 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000664 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000665 case LibFunc_open64:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000666 // May throw; "open" is a valid pthread cancellation point.
Reid Klecknera0b45f42017-05-03 18:17:31 +0000667 Changed |= setDoesNotCapture(F, 0);
668 Changed |= setOnlyReadsMemory(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000669 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000670 case LibFunc_gettimeofday:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000671 // Currently some platforms have the restrict keyword on the arguments to
672 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
673 // arguments.
674 Changed |= setDoesNotThrow(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000675 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000676 Changed |= setDoesNotCapture(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000677 return Changed;
David L. Jonesd21529f2017-01-23 23:16:46 +0000678 case LibFunc_Znwj: // new(unsigned int)
679 case LibFunc_Znwm: // new(unsigned long)
680 case LibFunc_Znaj: // new[](unsigned int)
681 case LibFunc_Znam: // new[](unsigned long)
682 case LibFunc_msvc_new_int: // new(unsigned int)
683 case LibFunc_msvc_new_longlong: // new(unsigned long long)
684 case LibFunc_msvc_new_array_int: // new[](unsigned int)
685 case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000686 // Operator new always returns a nonnull noalias pointer
Reid Klecknera0b45f42017-05-03 18:17:31 +0000687 Changed |= setRetNonNull(F);
688 Changed |= setRetDoesNotAlias(F);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000689 return Changed;
690 //TODO: add LibFunc entries for:
David L. Jonesd21529f2017-01-23 23:16:46 +0000691 //case LibFunc_memset_pattern4:
692 //case LibFunc_memset_pattern8:
693 case LibFunc_memset_pattern16:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000694 Changed |= setOnlyAccessesArgMemory(F);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000695 Changed |= setDoesNotCapture(F, 0);
Ahmed Bougacha44c19872016-04-27 19:04:43 +0000696 Changed |= setDoesNotCapture(F, 1);
Reid Klecknera0b45f42017-05-03 18:17:31 +0000697 Changed |= setOnlyReadsMemory(F, 1);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000698 return Changed;
699 // int __nvvm_reflect(const char *)
David L. Jonesd21529f2017-01-23 23:16:46 +0000700 case LibFunc_nvvm_reflect:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000701 Changed |= setDoesNotAccessMemory(F);
702 Changed |= setDoesNotThrow(F);
703 return Changed;
704
705 default:
706 // FIXME: It'd be really nice to cover all the library functions we're
707 // aware of here.
708 return false;
709 }
710}
711
712//- Emit LibCalls ------------------------------------------------------------//
713
Sanjay Pateld3112a52016-01-19 19:46:10 +0000714Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
Matt Arsenaultbe558882014-04-23 20:58:57 +0000715 unsigned AS = V->getType()->getPointerAddressSpace();
716 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
Eric Christopher87abfc52010-03-05 22:25:30 +0000717}
718
Sanjay Pateld3112a52016-01-19 19:46:10 +0000719Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000720 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000721 if (!TLI->has(LibFunc_strlen))
Craig Topperf40110f2014-04-25 05:29:35 +0000722 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000723
Sanjay Pateld4af2972016-01-19 19:58:49 +0000724 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000725 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000726 Constant *StrLen = M->getOrInsertFunction("strlen", DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000727 B.getInt8PtrTy());
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000728 inferLibFuncAttributes(*M->getFunction("strlen"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000729 CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), "strlen");
Evan Chengad6efbf2014-03-12 18:09:37 +0000730 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
731 CI->setCallingConv(F->getCallingConv());
732
Eric Christopher87abfc52010-03-05 22:25:30 +0000733 return CI;
734}
735
Sanjay Pateld3112a52016-01-19 19:46:10 +0000736Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000737 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000738 if (!TLI->has(LibFunc_strchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000739 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000740
Sanjay Pateld4af2972016-01-19 19:58:49 +0000741 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000742 Type *I8Ptr = B.getInt8PtrTy();
743 Type *I32Ty = B.getInt32Ty();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000744 Constant *StrChr =
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000745 M->getOrInsertFunction("strchr", I8Ptr, I8Ptr, I32Ty);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000746 inferLibFuncAttributes(*M->getFunction("strchr"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000747 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000748 StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, "strchr");
Evan Chengad6efbf2014-03-12 18:09:37 +0000749 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
750 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000751 return CI;
752}
753
Sanjay Pateld3112a52016-01-19 19:46:10 +0000754Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000755 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000756 if (!TLI->has(LibFunc_strncmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000757 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000758
Sanjay Pateld4af2972016-01-19 19:58:49 +0000759 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000760 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000761 Value *StrNCmp = M->getOrInsertFunction("strncmp", B.getInt32Ty(),
762 B.getInt8PtrTy(), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000763 DL.getIntPtrType(Context));
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000764 inferLibFuncAttributes(*M->getFunction("strncmp"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000765 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000766 StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "strncmp");
Evan Chengad6efbf2014-03-12 18:09:37 +0000767
768 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
769 CI->setCallingConv(F->getCallingConv());
770
Benjamin Kramer11188602010-06-15 21:34:25 +0000771 return CI;
772}
773
Sanjay Pateld3112a52016-01-19 19:46:10 +0000774Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000775 const TargetLibraryInfo *TLI, StringRef Name) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000776 if (!TLI->has(LibFunc_strcpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000777 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000778
Sanjay Pateld4af2972016-01-19 19:58:49 +0000779 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000780 Type *I8Ptr = B.getInt8PtrTy();
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000781 Value *StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000782 inferLibFuncAttributes(*M->getFunction(Name), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000783 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +0000784 B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
Evan Chengad6efbf2014-03-12 18:09:37 +0000785 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
786 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000787 return CI;
788}
789
Sanjay Pateld3112a52016-01-19 19:46:10 +0000790Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000791 const TargetLibraryInfo *TLI, StringRef Name) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000792 if (!TLI->has(LibFunc_strncpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000793 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000794
Sanjay Pateld4af2972016-01-19 19:58:49 +0000795 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000796 Type *I8Ptr = B.getInt8PtrTy();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000797 Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr,
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000798 Len->getType());
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000799 inferLibFuncAttributes(*M->getFunction(Name), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000800 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000801 StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, "strncpy");
Evan Chengad6efbf2014-03-12 18:09:37 +0000802 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
803 CI->setCallingConv(F->getCallingConv());
Eric Christopher43dc11c2010-03-11 01:25:07 +0000804 return CI;
805}
806
Sanjay Pateld3112a52016-01-19 19:46:10 +0000807Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000808 IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000809 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000810 if (!TLI->has(LibFunc_memcpy_chk))
Craig Topperf40110f2014-04-25 05:29:35 +0000811 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000812
Sanjay Pateld4af2972016-01-19 19:58:49 +0000813 Module *M = B.GetInsertBlock()->getModule();
Reid Klecknerb5180542017-03-21 16:57:19 +0000814 AttributeList AS;
815 AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
816 Attribute::NoUnwind);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000817 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000818 Value *MemCpy = M->getOrInsertFunction(
Reid Klecknerb5180542017-03-21 16:57:19 +0000819 "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000820 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000821 DL.getIntPtrType(Context));
Sanjay Pateld3112a52016-01-19 19:46:10 +0000822 Dst = castToCStr(Dst, B);
823 Src = castToCStr(Src, B);
David Blaikieff6409d2015-05-18 22:13:54 +0000824 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
Evan Chengad6efbf2014-03-12 18:09:37 +0000825 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
826 CI->setCallingConv(F->getCallingConv());
Evan Chengd9e82232010-03-23 15:48:04 +0000827 return CI;
828}
829
Sanjay Pateld3112a52016-01-19 19:46:10 +0000830Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000831 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000832 if (!TLI->has(LibFunc_memchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000833 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000834
Sanjay Pateld4af2972016-01-19 19:58:49 +0000835 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000836 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000837 Value *MemChr = M->getOrInsertFunction("memchr", B.getInt8PtrTy(),
838 B.getInt8PtrTy(), B.getInt32Ty(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000839 DL.getIntPtrType(Context));
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000840 inferLibFuncAttributes(*M->getFunction("memchr"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000841 CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, "memchr");
Evan Chengad6efbf2014-03-12 18:09:37 +0000842
843 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
844 CI->setCallingConv(F->getCallingConv());
845
Eric Christopher87abfc52010-03-05 22:25:30 +0000846 return CI;
847}
848
Sanjay Pateld3112a52016-01-19 19:46:10 +0000849Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000850 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000851 if (!TLI->has(LibFunc_memcmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000852 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000853
Sanjay Pateld4af2972016-01-19 19:58:49 +0000854 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000855 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000856 Value *MemCmp = M->getOrInsertFunction("memcmp", B.getInt32Ty(),
857 B.getInt8PtrTy(), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000858 DL.getIntPtrType(Context));
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000859 inferLibFuncAttributes(*M->getFunction("memcmp"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000860 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000861 MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "memcmp");
Evan Chengad6efbf2014-03-12 18:09:37 +0000862
863 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
864 CI->setCallingConv(F->getCallingConv());
865
Eric Christopher87abfc52010-03-05 22:25:30 +0000866 return CI;
867}
868
Yi Jiang6ab044e2013-12-16 22:42:40 +0000869/// Append a suffix to the function name according to the type of 'Op'.
Sanjay Pateld3112a52016-01-19 19:46:10 +0000870static void appendTypeSuffix(Value *Op, StringRef &Name,
Sanjay Patelb50325e2016-01-19 19:17:47 +0000871 SmallString<20> &NameBuffer) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000872 if (!Op->getType()->isDoubleTy()) {
873 NameBuffer += Name;
874
875 if (Op->getType()->isFloatTy())
876 NameBuffer += 'f';
877 else
878 NameBuffer += 'l';
879
880 Name = NameBuffer;
881 }
Yi Jiang6ab044e2013-12-16 22:42:40 +0000882}
883
Sanjay Pateld3112a52016-01-19 19:46:10 +0000884Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
Reid Klecknerb5180542017-03-21 16:57:19 +0000885 const AttributeList &Attrs) {
Benjamin Kramerb106bcc2011-11-15 19:12:09 +0000886 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +0000887 appendTypeSuffix(Op, Name, NameBuffer);
Eric Christopher87abfc52010-03-05 22:25:30 +0000888
Sanjay Pateld4af2972016-01-19 19:58:49 +0000889 Module *M = B.GetInsertBlock()->getModule();
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000890 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000891 Op->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +0000892 CallInst *CI = B.CreateCall(Callee, Op, Name);
Matt Arsenault6a288c12017-05-03 02:26:10 +0000893
894 // The incoming attribute set may have come from a speculatable intrinsic, but
895 // is being replaced with a library call which is not allowed to be
896 // speculatable.
897 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
898 AttributeList::FunctionIndex,
899 Attribute::Speculatable));
Evan Chengad6efbf2014-03-12 18:09:37 +0000900 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
901 CI->setCallingConv(F->getCallingConv());
902
Eric Christopher87abfc52010-03-05 22:25:30 +0000903 return CI;
904}
905
Sanjay Pateld3112a52016-01-19 19:46:10 +0000906Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
Reid Klecknerb5180542017-03-21 16:57:19 +0000907 IRBuilder<> &B, const AttributeList &Attrs) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000908 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +0000909 appendTypeSuffix(Op1, Name, NameBuffer);
Yi Jiang6ab044e2013-12-16 22:42:40 +0000910
Sanjay Pateld4af2972016-01-19 19:58:49 +0000911 Module *M = B.GetInsertBlock()->getModule();
Sanjay Patelb50325e2016-01-19 19:17:47 +0000912 Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000913 Op2->getType());
David Blaikieff6409d2015-05-18 22:13:54 +0000914 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
Yi Jiang6ab044e2013-12-16 22:42:40 +0000915 CI->setAttributes(Attrs);
Evan Chengad6efbf2014-03-12 18:09:37 +0000916 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
917 CI->setCallingConv(F->getCallingConv());
918
Yi Jiang6ab044e2013-12-16 22:42:40 +0000919 return CI;
920}
921
Sanjay Pateld3112a52016-01-19 19:46:10 +0000922Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000923 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000924 if (!TLI->has(LibFunc_putchar))
Craig Topperf40110f2014-04-25 05:29:35 +0000925 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000926
Sanjay Pateld4af2972016-01-19 19:58:49 +0000927 Module *M = B.GetInsertBlock()->getModule();
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000928 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(), B.getInt32Ty());
Craig Topper0f5063c2017-03-17 23:48:02 +0000929 inferLibFuncAttributes(*M->getFunction("putchar"), *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000930 CallInst *CI = B.CreateCall(PutChar,
931 B.CreateIntCast(Char,
932 B.getInt32Ty(),
933 /*isSigned*/true,
934 "chari"),
935 "putchar");
Evan Chengad6efbf2014-03-12 18:09:37 +0000936
937 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
938 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000939 return CI;
940}
941
Sanjay Pateld3112a52016-01-19 19:46:10 +0000942Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000943 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000944 if (!TLI->has(LibFunc_puts))
Craig Topperf40110f2014-04-25 05:29:35 +0000945 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000946
Sanjay Pateld4af2972016-01-19 19:58:49 +0000947 Module *M = B.GetInsertBlock()->getModule();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000948 Value *PutS =
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000949 M->getOrInsertFunction("puts", B.getInt32Ty(), B.getInt8PtrTy());
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000950 inferLibFuncAttributes(*M->getFunction("puts"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000951 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), "puts");
Evan Chengad6efbf2014-03-12 18:09:37 +0000952 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
953 CI->setCallingConv(F->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +0000954 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +0000955}
956
Sanjay Pateld3112a52016-01-19 19:46:10 +0000957Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000958 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000959 if (!TLI->has(LibFunc_fputc))
Craig Topperf40110f2014-04-25 05:29:35 +0000960 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000961
Sanjay Pateld4af2972016-01-19 19:58:49 +0000962 Module *M = B.GetInsertBlock()->getModule();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000963 Constant *F = M->getOrInsertFunction("fputc", B.getInt32Ty(), B.getInt32Ty(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000964 File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +0000965 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000966 inferLibFuncAttributes(*M->getFunction("fputc"), *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000967 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
968 "chari");
David Blaikieff6409d2015-05-18 22:13:54 +0000969 CallInst *CI = B.CreateCall(F, {Char, File}, "fputc");
Evan Chengad6efbf2014-03-12 18:09:37 +0000970
971 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
972 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +0000973 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +0000974}
975
Sanjay Pateld3112a52016-01-19 19:46:10 +0000976Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000977 const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000978 if (!TLI->has(LibFunc_fputs))
Craig Topperf40110f2014-04-25 05:29:35 +0000979 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000980
Sanjay Pateld4af2972016-01-19 19:58:49 +0000981 Module *M = B.GetInsertBlock()->getModule();
David L. Jonesd21529f2017-01-23 23:16:46 +0000982 StringRef FPutsName = TLI->getName(LibFunc_fputs);
Mehdi Aminidb11fdf2017-04-06 20:23:57 +0000983 Constant *F = M->getOrInsertFunction(
Serge Guelton59a2d7b2017-04-11 15:01:18 +0000984 FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType());
Eric Christopher87abfc52010-03-05 22:25:30 +0000985 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000986 inferLibFuncAttributes(*M->getFunction(FPutsName), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000987 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs");
Evan Chengad6efbf2014-03-12 18:09:37 +0000988
989 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
990 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +0000991 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +0000992}
993
Sanjay Pateld3112a52016-01-19 19:46:10 +0000994Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000995 const DataLayout &DL, const TargetLibraryInfo *TLI) {
David L. Jonesd21529f2017-01-23 23:16:46 +0000996 if (!TLI->has(LibFunc_fwrite))
Craig Topperf40110f2014-04-25 05:29:35 +0000997 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000998
Sanjay Pateld4af2972016-01-19 19:58:49 +0000999 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +00001000 LLVMContext &Context = B.GetInsertBlock()->getContext();
David L. Jonesd21529f2017-01-23 23:16:46 +00001001 StringRef FWriteName = TLI->getName(LibFunc_fwrite);
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001002 Constant *F = M->getOrInsertFunction(
1003 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
Serge Guelton59a2d7b2017-04-11 15:01:18 +00001004 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1005
Eric Christopher87abfc52010-03-05 22:25:30 +00001006 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001007 inferLibFuncAttributes(*M->getFunction(FWriteName), *TLI);
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001008 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +00001009 B.CreateCall(F, {castToCStr(Ptr, B), Size,
David Blaikieff6409d2015-05-18 22:13:54 +00001010 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
Evan Chengad6efbf2014-03-12 18:09:37 +00001011
1012 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1013 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001014 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001015}