1204792Srdivacky//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
2204792Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6204792Srdivacky//
7204792Srdivacky//===----------------------------------------------------------------------===//
8204792Srdivacky//
9204792Srdivacky// This file implements some functions that will create standard C libcalls.
10204792Srdivacky//
11204792Srdivacky//===----------------------------------------------------------------------===//
12204792Srdivacky
13204792Srdivacky#include "llvm/Transforms/Utils/BuildLibCalls.h"
14239462Sdim#include "llvm/ADT/SmallString.h"
15309124Sdim#include "llvm/ADT/Statistic.h"
16296417Sdim#include "llvm/Analysis/TargetLibraryInfo.h"
17249423Sdim#include "llvm/IR/Constants.h"
18249423Sdim#include "llvm/IR/DataLayout.h"
19249423Sdim#include "llvm/IR/Function.h"
20249423Sdim#include "llvm/IR/IRBuilder.h"
21249423Sdim#include "llvm/IR/Intrinsics.h"
22249423Sdim#include "llvm/IR/LLVMContext.h"
23249423Sdim#include "llvm/IR/Module.h"
24249423Sdim#include "llvm/IR/Type.h"
25353358Sdim#include "llvm/Analysis/MemoryBuiltins.h"
26204792Srdivacky
27204792Srdivackyusing namespace llvm;
28204792Srdivacky
29309124Sdim#define DEBUG_TYPE "build-libcalls"
30309124Sdim
31309124Sdim//- Infer Attributes ---------------------------------------------------------//
32309124Sdim
33309124SdimSTATISTIC(NumReadNone, "Number of functions inferred as readnone");
34309124SdimSTATISTIC(NumReadOnly, "Number of functions inferred as readonly");
35309124SdimSTATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
36309124SdimSTATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
37309124SdimSTATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
38309124SdimSTATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
39309124SdimSTATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
40309124SdimSTATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
41344779SdimSTATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
42309124Sdim
43309124Sdimstatic bool setDoesNotAccessMemory(Function &F) {
44309124Sdim  if (F.doesNotAccessMemory())
45309124Sdim    return false;
46309124Sdim  F.setDoesNotAccessMemory();
47309124Sdim  ++NumReadNone;
48309124Sdim  return true;
49309124Sdim}
50309124Sdim
51309124Sdimstatic bool setOnlyReadsMemory(Function &F) {
52309124Sdim  if (F.onlyReadsMemory())
53309124Sdim    return false;
54309124Sdim  F.setOnlyReadsMemory();
55309124Sdim  ++NumReadOnly;
56309124Sdim  return true;
57309124Sdim}
58309124Sdim
59309124Sdimstatic bool setOnlyAccessesArgMemory(Function &F) {
60309124Sdim  if (F.onlyAccessesArgMemory())
61309124Sdim    return false;
62321369Sdim  F.setOnlyAccessesArgMemory();
63309124Sdim  ++NumArgMemOnly;
64309124Sdim  return true;
65309124Sdim}
66309124Sdim
67309124Sdimstatic bool setDoesNotThrow(Function &F) {
68309124Sdim  if (F.doesNotThrow())
69309124Sdim    return false;
70309124Sdim  F.setDoesNotThrow();
71309124Sdim  ++NumNoUnwind;
72309124Sdim  return true;
73309124Sdim}
74309124Sdim
75321369Sdimstatic bool setRetDoesNotAlias(Function &F) {
76321369Sdim  if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias))
77309124Sdim    return false;
78321369Sdim  F.addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
79321369Sdim  ++NumNoAlias;
80309124Sdim  return true;
81309124Sdim}
82309124Sdim
83321369Sdimstatic bool setDoesNotCapture(Function &F, unsigned ArgNo) {
84321369Sdim  if (F.hasParamAttribute(ArgNo, Attribute::NoCapture))
85309124Sdim    return false;
86321369Sdim  F.addParamAttr(ArgNo, Attribute::NoCapture);
87321369Sdim  ++NumNoCapture;
88309124Sdim  return true;
89309124Sdim}
90309124Sdim
91360784Sdimstatic bool setDoesNotAlias(Function &F, unsigned ArgNo) {
92360784Sdim  if (F.hasParamAttribute(ArgNo, Attribute::NoAlias))
93360784Sdim    return false;
94360784Sdim  F.addParamAttr(ArgNo, Attribute::NoAlias);
95360784Sdim  ++NumNoAlias;
96360784Sdim  return true;
97360784Sdim}
98360784Sdim
99321369Sdimstatic bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
100321369Sdim  if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))
101309124Sdim    return false;
102321369Sdim  F.addParamAttr(ArgNo, Attribute::ReadOnly);
103321369Sdim  ++NumReadOnlyArg;
104309124Sdim  return true;
105309124Sdim}
106309124Sdim
107321369Sdimstatic bool setRetNonNull(Function &F) {
108321369Sdim  assert(F.getReturnType()->isPointerTy() &&
109309124Sdim         "nonnull applies only to pointers");
110321369Sdim  if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull))
111309124Sdim    return false;
112321369Sdim  F.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
113309124Sdim  ++NumNonNull;
114309124Sdim  return true;
115309124Sdim}
116309124Sdim
117344779Sdimstatic bool setReturnedArg(Function &F, unsigned ArgNo) {
118344779Sdim  if (F.hasParamAttribute(ArgNo, Attribute::Returned))
119344779Sdim    return false;
120344779Sdim  F.addParamAttr(ArgNo, Attribute::Returned);
121344779Sdim  ++NumReturnedArg;
122344779Sdim  return true;
123344779Sdim}
124344779Sdim
125341825Sdimstatic bool setNonLazyBind(Function &F) {
126341825Sdim  if (F.hasFnAttribute(Attribute::NonLazyBind))
127341825Sdim    return false;
128341825Sdim  F.addFnAttr(Attribute::NonLazyBind);
129341825Sdim  return true;
130341825Sdim}
131341825Sdim
132353358Sdimstatic bool setDoesNotFreeMemory(Function &F) {
133353358Sdim  if (F.hasFnAttribute(Attribute::NoFree))
134353358Sdim    return false;
135353358Sdim  F.addFnAttr(Attribute::NoFree);
136353358Sdim  return true;
137353358Sdim}
138353358Sdim
139341825Sdimbool llvm::inferLibFuncAttributes(Module *M, StringRef Name,
140341825Sdim                                  const TargetLibraryInfo &TLI) {
141341825Sdim  Function *F = M->getFunction(Name);
142341825Sdim  if (!F)
143341825Sdim    return false;
144341825Sdim  return inferLibFuncAttributes(*F, TLI);
145341825Sdim}
146341825Sdim
147309124Sdimbool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
148321369Sdim  LibFunc TheLibFunc;
149309124Sdim  if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
150309124Sdim    return false;
151309124Sdim
152309124Sdim  bool Changed = false;
153341825Sdim
154353358Sdim  if(!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F,  &TLI))
155353358Sdim    Changed |= setDoesNotFreeMemory(F);
156353358Sdim
157341825Sdim  if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
158341825Sdim    Changed |= setNonLazyBind(F);
159341825Sdim
160309124Sdim  switch (TheLibFunc) {
161321369Sdim  case LibFunc_strlen:
162321369Sdim  case LibFunc_wcslen:
163309124Sdim    Changed |= setOnlyReadsMemory(F);
164309124Sdim    Changed |= setDoesNotThrow(F);
165321369Sdim    Changed |= setOnlyAccessesArgMemory(F);
166321369Sdim    Changed |= setDoesNotCapture(F, 0);
167309124Sdim    return Changed;
168321369Sdim  case LibFunc_strchr:
169321369Sdim  case LibFunc_strrchr:
170309124Sdim    Changed |= setOnlyReadsMemory(F);
171309124Sdim    Changed |= setDoesNotThrow(F);
172309124Sdim    return Changed;
173321369Sdim  case LibFunc_strtol:
174321369Sdim  case LibFunc_strtod:
175321369Sdim  case LibFunc_strtof:
176321369Sdim  case LibFunc_strtoul:
177321369Sdim  case LibFunc_strtoll:
178321369Sdim  case LibFunc_strtold:
179321369Sdim  case LibFunc_strtoull:
180309124Sdim    Changed |= setDoesNotThrow(F);
181321369Sdim    Changed |= setDoesNotCapture(F, 1);
182321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
183309124Sdim    return Changed;
184321369Sdim  case LibFunc_strcpy:
185344779Sdim  case LibFunc_strncpy:
186360784Sdim    Changed |= setDoesNotAlias(F, 0);
187360784Sdim    Changed |= setDoesNotAlias(F, 1);
188360784Sdim    LLVM_FALLTHROUGH;
189321369Sdim  case LibFunc_strcat:
190321369Sdim  case LibFunc_strncat:
191344779Sdim    Changed |= setReturnedArg(F, 0);
192344779Sdim    LLVM_FALLTHROUGH;
193344779Sdim  case LibFunc_stpcpy:
194321369Sdim  case LibFunc_stpncpy:
195309124Sdim    Changed |= setDoesNotThrow(F);
196321369Sdim    Changed |= setDoesNotCapture(F, 1);
197321369Sdim    Changed |= setOnlyReadsMemory(F, 1);
198309124Sdim    return Changed;
199321369Sdim  case LibFunc_strxfrm:
200309124Sdim    Changed |= setDoesNotThrow(F);
201321369Sdim    Changed |= setDoesNotCapture(F, 0);
202309124Sdim    Changed |= setDoesNotCapture(F, 1);
203321369Sdim    Changed |= setOnlyReadsMemory(F, 1);
204309124Sdim    return Changed;
205321369Sdim  case LibFunc_strcmp:      // 0,1
206321369Sdim  case LibFunc_strspn:      // 0,1
207321369Sdim  case LibFunc_strncmp:     // 0,1
208321369Sdim  case LibFunc_strcspn:     // 0,1
209321369Sdim  case LibFunc_strcoll:     // 0,1
210321369Sdim  case LibFunc_strcasecmp:  // 0,1
211321369Sdim  case LibFunc_strncasecmp: //
212309124Sdim    Changed |= setOnlyReadsMemory(F);
213309124Sdim    Changed |= setDoesNotThrow(F);
214321369Sdim    Changed |= setDoesNotCapture(F, 0);
215309124Sdim    Changed |= setDoesNotCapture(F, 1);
216309124Sdim    return Changed;
217321369Sdim  case LibFunc_strstr:
218321369Sdim  case LibFunc_strpbrk:
219309124Sdim    Changed |= setOnlyReadsMemory(F);
220309124Sdim    Changed |= setDoesNotThrow(F);
221321369Sdim    Changed |= setDoesNotCapture(F, 1);
222309124Sdim    return Changed;
223321369Sdim  case LibFunc_strtok:
224321369Sdim  case LibFunc_strtok_r:
225309124Sdim    Changed |= setDoesNotThrow(F);
226309124Sdim    Changed |= setDoesNotCapture(F, 1);
227309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
228309124Sdim    return Changed;
229321369Sdim  case LibFunc_scanf:
230309124Sdim    Changed |= setDoesNotThrow(F);
231321369Sdim    Changed |= setDoesNotCapture(F, 0);
232321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
233309124Sdim    return Changed;
234321369Sdim  case LibFunc_setbuf:
235321369Sdim  case LibFunc_setvbuf:
236309124Sdim    Changed |= setDoesNotThrow(F);
237321369Sdim    Changed |= setDoesNotCapture(F, 0);
238321369Sdim    return Changed;
239321369Sdim  case LibFunc_strdup:
240321369Sdim  case LibFunc_strndup:
241321369Sdim    Changed |= setDoesNotThrow(F);
242321369Sdim    Changed |= setRetDoesNotAlias(F);
243321369Sdim    Changed |= setDoesNotCapture(F, 0);
244321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
245321369Sdim    return Changed;
246321369Sdim  case LibFunc_stat:
247321369Sdim  case LibFunc_statvfs:
248321369Sdim    Changed |= setDoesNotThrow(F);
249321369Sdim    Changed |= setDoesNotCapture(F, 0);
250309124Sdim    Changed |= setDoesNotCapture(F, 1);
251321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
252309124Sdim    return Changed;
253321369Sdim  case LibFunc_sscanf:
254309124Sdim    Changed |= setDoesNotThrow(F);
255321369Sdim    Changed |= setDoesNotCapture(F, 0);
256309124Sdim    Changed |= setDoesNotCapture(F, 1);
257321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
258309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
259309124Sdim    return Changed;
260321369Sdim  case LibFunc_sprintf:
261309124Sdim    Changed |= setDoesNotThrow(F);
262321369Sdim    Changed |= setDoesNotCapture(F, 0);
263360784Sdim    Changed |= setDoesNotAlias(F, 0);
264309124Sdim    Changed |= setDoesNotCapture(F, 1);
265309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
266309124Sdim    return Changed;
267321369Sdim  case LibFunc_snprintf:
268309124Sdim    Changed |= setDoesNotThrow(F);
269321369Sdim    Changed |= setDoesNotCapture(F, 0);
270360784Sdim    Changed |= setDoesNotAlias(F, 0);
271309124Sdim    Changed |= setDoesNotCapture(F, 2);
272309124Sdim    Changed |= setOnlyReadsMemory(F, 2);
273309124Sdim    return Changed;
274321369Sdim  case LibFunc_setitimer:
275309124Sdim    Changed |= setDoesNotThrow(F);
276309124Sdim    Changed |= setDoesNotCapture(F, 1);
277309124Sdim    Changed |= setDoesNotCapture(F, 2);
278321369Sdim    Changed |= setOnlyReadsMemory(F, 1);
279309124Sdim    return Changed;
280321369Sdim  case LibFunc_system:
281309124Sdim    // May throw; "system" is a valid pthread cancellation point.
282321369Sdim    Changed |= setDoesNotCapture(F, 0);
283321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
284309124Sdim    return Changed;
285321369Sdim  case LibFunc_malloc:
286309124Sdim    Changed |= setDoesNotThrow(F);
287321369Sdim    Changed |= setRetDoesNotAlias(F);
288309124Sdim    return Changed;
289321369Sdim  case LibFunc_memcmp:
290309124Sdim    Changed |= setOnlyReadsMemory(F);
291309124Sdim    Changed |= setDoesNotThrow(F);
292321369Sdim    Changed |= setDoesNotCapture(F, 0);
293309124Sdim    Changed |= setDoesNotCapture(F, 1);
294309124Sdim    return Changed;
295321369Sdim  case LibFunc_memchr:
296321369Sdim  case LibFunc_memrchr:
297309124Sdim    Changed |= setOnlyReadsMemory(F);
298309124Sdim    Changed |= setDoesNotThrow(F);
299309124Sdim    return Changed;
300321369Sdim  case LibFunc_modf:
301321369Sdim  case LibFunc_modff:
302321369Sdim  case LibFunc_modfl:
303309124Sdim    Changed |= setDoesNotThrow(F);
304321369Sdim    Changed |= setDoesNotCapture(F, 1);
305309124Sdim    return Changed;
306321369Sdim  case LibFunc_memcpy:
307360784Sdim    Changed |= setDoesNotAlias(F, 0);
308360784Sdim    Changed |= setDoesNotAlias(F, 1);
309360784Sdim    Changed |= setReturnedArg(F, 0);
310360784Sdim    Changed |= setDoesNotThrow(F);
311360784Sdim    Changed |= setDoesNotCapture(F, 1);
312360784Sdim    Changed |= setOnlyReadsMemory(F, 1);
313360784Sdim    return Changed;
314344779Sdim  case LibFunc_memmove:
315344779Sdim    Changed |= setReturnedArg(F, 0);
316360784Sdim    Changed |= setDoesNotThrow(F);
317360784Sdim    Changed |= setDoesNotCapture(F, 1);
318360784Sdim    Changed |= setOnlyReadsMemory(F, 1);
319360784Sdim    return Changed;
320321369Sdim  case LibFunc_mempcpy:
321321369Sdim  case LibFunc_memccpy:
322360784Sdim    Changed |= setDoesNotAlias(F, 0);
323360784Sdim    Changed |= setDoesNotAlias(F, 1);
324309124Sdim    Changed |= setDoesNotThrow(F);
325321369Sdim    Changed |= setDoesNotCapture(F, 1);
326321369Sdim    Changed |= setOnlyReadsMemory(F, 1);
327309124Sdim    return Changed;
328321369Sdim  case LibFunc_memcpy_chk:
329309124Sdim    Changed |= setDoesNotThrow(F);
330309124Sdim    return Changed;
331321369Sdim  case LibFunc_memalign:
332321369Sdim    Changed |= setRetDoesNotAlias(F);
333309124Sdim    return Changed;
334321369Sdim  case LibFunc_mkdir:
335309124Sdim    Changed |= setDoesNotThrow(F);
336321369Sdim    Changed |= setDoesNotCapture(F, 0);
337321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
338309124Sdim    return Changed;
339321369Sdim  case LibFunc_mktime:
340309124Sdim    Changed |= setDoesNotThrow(F);
341321369Sdim    Changed |= setDoesNotCapture(F, 0);
342309124Sdim    return Changed;
343321369Sdim  case LibFunc_realloc:
344309124Sdim    Changed |= setDoesNotThrow(F);
345321369Sdim    Changed |= setRetDoesNotAlias(F);
346321369Sdim    Changed |= setDoesNotCapture(F, 0);
347309124Sdim    return Changed;
348321369Sdim  case LibFunc_read:
349309124Sdim    // May throw; "read" is a valid pthread cancellation point.
350321369Sdim    Changed |= setDoesNotCapture(F, 1);
351309124Sdim    return Changed;
352321369Sdim  case LibFunc_rewind:
353309124Sdim    Changed |= setDoesNotThrow(F);
354321369Sdim    Changed |= setDoesNotCapture(F, 0);
355309124Sdim    return Changed;
356321369Sdim  case LibFunc_rmdir:
357321369Sdim  case LibFunc_remove:
358321369Sdim  case LibFunc_realpath:
359309124Sdim    Changed |= setDoesNotThrow(F);
360321369Sdim    Changed |= setDoesNotCapture(F, 0);
361321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
362309124Sdim    return Changed;
363321369Sdim  case LibFunc_rename:
364309124Sdim    Changed |= setDoesNotThrow(F);
365321369Sdim    Changed |= setDoesNotCapture(F, 0);
366309124Sdim    Changed |= setDoesNotCapture(F, 1);
367321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
368309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
369309124Sdim    return Changed;
370321369Sdim  case LibFunc_readlink:
371309124Sdim    Changed |= setDoesNotThrow(F);
372321369Sdim    Changed |= setDoesNotCapture(F, 0);
373309124Sdim    Changed |= setDoesNotCapture(F, 1);
374321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
375309124Sdim    return Changed;
376321369Sdim  case LibFunc_write:
377309124Sdim    // May throw; "write" is a valid pthread cancellation point.
378321369Sdim    Changed |= setDoesNotCapture(F, 1);
379321369Sdim    Changed |= setOnlyReadsMemory(F, 1);
380309124Sdim    return Changed;
381321369Sdim  case LibFunc_bcopy:
382309124Sdim    Changed |= setDoesNotThrow(F);
383321369Sdim    Changed |= setDoesNotCapture(F, 0);
384309124Sdim    Changed |= setDoesNotCapture(F, 1);
385321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
386309124Sdim    return Changed;
387321369Sdim  case LibFunc_bcmp:
388309124Sdim    Changed |= setDoesNotThrow(F);
389309124Sdim    Changed |= setOnlyReadsMemory(F);
390321369Sdim    Changed |= setDoesNotCapture(F, 0);
391309124Sdim    Changed |= setDoesNotCapture(F, 1);
392309124Sdim    return Changed;
393321369Sdim  case LibFunc_bzero:
394309124Sdim    Changed |= setDoesNotThrow(F);
395321369Sdim    Changed |= setDoesNotCapture(F, 0);
396309124Sdim    return Changed;
397321369Sdim  case LibFunc_calloc:
398309124Sdim    Changed |= setDoesNotThrow(F);
399321369Sdim    Changed |= setRetDoesNotAlias(F);
400309124Sdim    return Changed;
401321369Sdim  case LibFunc_chmod:
402321369Sdim  case LibFunc_chown:
403309124Sdim    Changed |= setDoesNotThrow(F);
404321369Sdim    Changed |= setDoesNotCapture(F, 0);
405321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
406309124Sdim    return Changed;
407321369Sdim  case LibFunc_ctermid:
408321369Sdim  case LibFunc_clearerr:
409321369Sdim  case LibFunc_closedir:
410309124Sdim    Changed |= setDoesNotThrow(F);
411321369Sdim    Changed |= setDoesNotCapture(F, 0);
412309124Sdim    return Changed;
413321369Sdim  case LibFunc_atoi:
414321369Sdim  case LibFunc_atol:
415321369Sdim  case LibFunc_atof:
416321369Sdim  case LibFunc_atoll:
417309124Sdim    Changed |= setDoesNotThrow(F);
418309124Sdim    Changed |= setOnlyReadsMemory(F);
419321369Sdim    Changed |= setDoesNotCapture(F, 0);
420309124Sdim    return Changed;
421321369Sdim  case LibFunc_access:
422309124Sdim    Changed |= setDoesNotThrow(F);
423321369Sdim    Changed |= setDoesNotCapture(F, 0);
424321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
425321369Sdim    return Changed;
426321369Sdim  case LibFunc_fopen:
427321369Sdim    Changed |= setDoesNotThrow(F);
428321369Sdim    Changed |= setRetDoesNotAlias(F);
429321369Sdim    Changed |= setDoesNotCapture(F, 0);
430309124Sdim    Changed |= setDoesNotCapture(F, 1);
431321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
432309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
433309124Sdim    return Changed;
434321369Sdim  case LibFunc_fdopen:
435309124Sdim    Changed |= setDoesNotThrow(F);
436321369Sdim    Changed |= setRetDoesNotAlias(F);
437309124Sdim    Changed |= setDoesNotCapture(F, 1);
438309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
439309124Sdim    return Changed;
440321369Sdim  case LibFunc_feof:
441321369Sdim  case LibFunc_free:
442321369Sdim  case LibFunc_fseek:
443321369Sdim  case LibFunc_ftell:
444321369Sdim  case LibFunc_fgetc:
445341825Sdim  case LibFunc_fgetc_unlocked:
446321369Sdim  case LibFunc_fseeko:
447321369Sdim  case LibFunc_ftello:
448321369Sdim  case LibFunc_fileno:
449321369Sdim  case LibFunc_fflush:
450321369Sdim  case LibFunc_fclose:
451321369Sdim  case LibFunc_fsetpos:
452321369Sdim  case LibFunc_flockfile:
453321369Sdim  case LibFunc_funlockfile:
454321369Sdim  case LibFunc_ftrylockfile:
455309124Sdim    Changed |= setDoesNotThrow(F);
456321369Sdim    Changed |= setDoesNotCapture(F, 0);
457309124Sdim    return Changed;
458321369Sdim  case LibFunc_ferror:
459309124Sdim    Changed |= setDoesNotThrow(F);
460321369Sdim    Changed |= setDoesNotCapture(F, 0);
461321369Sdim    Changed |= setOnlyReadsMemory(F);
462309124Sdim    return Changed;
463321369Sdim  case LibFunc_fputc:
464341825Sdim  case LibFunc_fputc_unlocked:
465321369Sdim  case LibFunc_fstat:
466321369Sdim  case LibFunc_frexp:
467321369Sdim  case LibFunc_frexpf:
468321369Sdim  case LibFunc_frexpl:
469321369Sdim  case LibFunc_fstatvfs:
470309124Sdim    Changed |= setDoesNotThrow(F);
471309124Sdim    Changed |= setDoesNotCapture(F, 1);
472309124Sdim    return Changed;
473321369Sdim  case LibFunc_fgets:
474341825Sdim  case LibFunc_fgets_unlocked:
475309124Sdim    Changed |= setDoesNotThrow(F);
476309124Sdim    Changed |= setDoesNotCapture(F, 2);
477309124Sdim    return Changed;
478321369Sdim  case LibFunc_fread:
479341825Sdim  case LibFunc_fread_unlocked:
480309124Sdim    Changed |= setDoesNotThrow(F);
481321369Sdim    Changed |= setDoesNotCapture(F, 0);
482309124Sdim    Changed |= setDoesNotCapture(F, 3);
483309124Sdim    return Changed;
484321369Sdim  case LibFunc_fwrite:
485341825Sdim  case LibFunc_fwrite_unlocked:
486309124Sdim    Changed |= setDoesNotThrow(F);
487321369Sdim    Changed |= setDoesNotCapture(F, 0);
488321369Sdim    Changed |= setDoesNotCapture(F, 3);
489321369Sdim    // FIXME: readonly #1?
490309124Sdim    return Changed;
491321369Sdim  case LibFunc_fputs:
492341825Sdim  case LibFunc_fputs_unlocked:
493309124Sdim    Changed |= setDoesNotThrow(F);
494321369Sdim    Changed |= setDoesNotCapture(F, 0);
495309124Sdim    Changed |= setDoesNotCapture(F, 1);
496321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
497309124Sdim    return Changed;
498321369Sdim  case LibFunc_fscanf:
499321369Sdim  case LibFunc_fprintf:
500309124Sdim    Changed |= setDoesNotThrow(F);
501321369Sdim    Changed |= setDoesNotCapture(F, 0);
502309124Sdim    Changed |= setDoesNotCapture(F, 1);
503309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
504309124Sdim    return Changed;
505321369Sdim  case LibFunc_fgetpos:
506309124Sdim    Changed |= setDoesNotThrow(F);
507321369Sdim    Changed |= setDoesNotCapture(F, 0);
508309124Sdim    Changed |= setDoesNotCapture(F, 1);
509309124Sdim    return Changed;
510321369Sdim  case LibFunc_getc:
511321369Sdim  case LibFunc_getlogin_r:
512321369Sdim  case LibFunc_getc_unlocked:
513309124Sdim    Changed |= setDoesNotThrow(F);
514321369Sdim    Changed |= setDoesNotCapture(F, 0);
515309124Sdim    return Changed;
516321369Sdim  case LibFunc_getenv:
517309124Sdim    Changed |= setDoesNotThrow(F);
518321369Sdim    Changed |= setOnlyReadsMemory(F);
519321369Sdim    Changed |= setDoesNotCapture(F, 0);
520309124Sdim    return Changed;
521321369Sdim  case LibFunc_gets:
522321369Sdim  case LibFunc_getchar:
523341825Sdim  case LibFunc_getchar_unlocked:
524309124Sdim    Changed |= setDoesNotThrow(F);
525309124Sdim    return Changed;
526321369Sdim  case LibFunc_getitimer:
527309124Sdim    Changed |= setDoesNotThrow(F);
528321369Sdim    Changed |= setDoesNotCapture(F, 1);
529309124Sdim    return Changed;
530321369Sdim  case LibFunc_getpwnam:
531309124Sdim    Changed |= setDoesNotThrow(F);
532321369Sdim    Changed |= setDoesNotCapture(F, 0);
533321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
534309124Sdim    return Changed;
535321369Sdim  case LibFunc_ungetc:
536309124Sdim    Changed |= setDoesNotThrow(F);
537309124Sdim    Changed |= setDoesNotCapture(F, 1);
538309124Sdim    return Changed;
539321369Sdim  case LibFunc_uname:
540309124Sdim    Changed |= setDoesNotThrow(F);
541321369Sdim    Changed |= setDoesNotCapture(F, 0);
542309124Sdim    return Changed;
543321369Sdim  case LibFunc_unlink:
544309124Sdim    Changed |= setDoesNotThrow(F);
545321369Sdim    Changed |= setDoesNotCapture(F, 0);
546321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
547309124Sdim    return Changed;
548321369Sdim  case LibFunc_unsetenv:
549309124Sdim    Changed |= setDoesNotThrow(F);
550321369Sdim    Changed |= setDoesNotCapture(F, 0);
551321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
552309124Sdim    return Changed;
553321369Sdim  case LibFunc_utime:
554321369Sdim  case LibFunc_utimes:
555309124Sdim    Changed |= setDoesNotThrow(F);
556321369Sdim    Changed |= setDoesNotCapture(F, 0);
557309124Sdim    Changed |= setDoesNotCapture(F, 1);
558321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
559309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
560309124Sdim    return Changed;
561321369Sdim  case LibFunc_putc:
562341825Sdim  case LibFunc_putc_unlocked:
563309124Sdim    Changed |= setDoesNotThrow(F);
564309124Sdim    Changed |= setDoesNotCapture(F, 1);
565309124Sdim    return Changed;
566321369Sdim  case LibFunc_puts:
567321369Sdim  case LibFunc_printf:
568321369Sdim  case LibFunc_perror:
569309124Sdim    Changed |= setDoesNotThrow(F);
570321369Sdim    Changed |= setDoesNotCapture(F, 0);
571321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
572309124Sdim    return Changed;
573321369Sdim  case LibFunc_pread:
574321369Sdim    // May throw; "pread" is a valid pthread cancellation point.
575309124Sdim    Changed |= setDoesNotCapture(F, 1);
576309124Sdim    return Changed;
577321369Sdim  case LibFunc_pwrite:
578309124Sdim    // May throw; "pwrite" is a valid pthread cancellation point.
579321369Sdim    Changed |= setDoesNotCapture(F, 1);
580321369Sdim    Changed |= setOnlyReadsMemory(F, 1);
581309124Sdim    return Changed;
582321369Sdim  case LibFunc_putchar:
583341825Sdim  case LibFunc_putchar_unlocked:
584309124Sdim    Changed |= setDoesNotThrow(F);
585309124Sdim    return Changed;
586321369Sdim  case LibFunc_popen:
587309124Sdim    Changed |= setDoesNotThrow(F);
588321369Sdim    Changed |= setRetDoesNotAlias(F);
589321369Sdim    Changed |= setDoesNotCapture(F, 0);
590309124Sdim    Changed |= setDoesNotCapture(F, 1);
591321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
592309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
593309124Sdim    return Changed;
594321369Sdim  case LibFunc_pclose:
595309124Sdim    Changed |= setDoesNotThrow(F);
596321369Sdim    Changed |= setDoesNotCapture(F, 0);
597309124Sdim    return Changed;
598321369Sdim  case LibFunc_vscanf:
599309124Sdim    Changed |= setDoesNotThrow(F);
600321369Sdim    Changed |= setDoesNotCapture(F, 0);
601321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
602321369Sdim    return Changed;
603321369Sdim  case LibFunc_vsscanf:
604321369Sdim    Changed |= setDoesNotThrow(F);
605321369Sdim    Changed |= setDoesNotCapture(F, 0);
606309124Sdim    Changed |= setDoesNotCapture(F, 1);
607321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
608309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
609309124Sdim    return Changed;
610321369Sdim  case LibFunc_vfscanf:
611309124Sdim    Changed |= setDoesNotThrow(F);
612321369Sdim    Changed |= setDoesNotCapture(F, 0);
613309124Sdim    Changed |= setDoesNotCapture(F, 1);
614309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
615309124Sdim    return Changed;
616321369Sdim  case LibFunc_valloc:
617309124Sdim    Changed |= setDoesNotThrow(F);
618321369Sdim    Changed |= setRetDoesNotAlias(F);
619309124Sdim    return Changed;
620321369Sdim  case LibFunc_vprintf:
621309124Sdim    Changed |= setDoesNotThrow(F);
622321369Sdim    Changed |= setDoesNotCapture(F, 0);
623321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
624309124Sdim    return Changed;
625321369Sdim  case LibFunc_vfprintf:
626321369Sdim  case LibFunc_vsprintf:
627309124Sdim    Changed |= setDoesNotThrow(F);
628321369Sdim    Changed |= setDoesNotCapture(F, 0);
629309124Sdim    Changed |= setDoesNotCapture(F, 1);
630309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
631309124Sdim    return Changed;
632321369Sdim  case LibFunc_vsnprintf:
633309124Sdim    Changed |= setDoesNotThrow(F);
634321369Sdim    Changed |= setDoesNotCapture(F, 0);
635309124Sdim    Changed |= setDoesNotCapture(F, 2);
636309124Sdim    Changed |= setOnlyReadsMemory(F, 2);
637309124Sdim    return Changed;
638321369Sdim  case LibFunc_open:
639309124Sdim    // May throw; "open" is a valid pthread cancellation point.
640321369Sdim    Changed |= setDoesNotCapture(F, 0);
641321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
642309124Sdim    return Changed;
643321369Sdim  case LibFunc_opendir:
644309124Sdim    Changed |= setDoesNotThrow(F);
645321369Sdim    Changed |= setRetDoesNotAlias(F);
646321369Sdim    Changed |= setDoesNotCapture(F, 0);
647321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
648309124Sdim    return Changed;
649321369Sdim  case LibFunc_tmpfile:
650309124Sdim    Changed |= setDoesNotThrow(F);
651321369Sdim    Changed |= setRetDoesNotAlias(F);
652309124Sdim    return Changed;
653321369Sdim  case LibFunc_times:
654309124Sdim    Changed |= setDoesNotThrow(F);
655321369Sdim    Changed |= setDoesNotCapture(F, 0);
656309124Sdim    return Changed;
657321369Sdim  case LibFunc_htonl:
658321369Sdim  case LibFunc_htons:
659321369Sdim  case LibFunc_ntohl:
660321369Sdim  case LibFunc_ntohs:
661309124Sdim    Changed |= setDoesNotThrow(F);
662309124Sdim    Changed |= setDoesNotAccessMemory(F);
663309124Sdim    return Changed;
664321369Sdim  case LibFunc_lstat:
665309124Sdim    Changed |= setDoesNotThrow(F);
666321369Sdim    Changed |= setDoesNotCapture(F, 0);
667309124Sdim    Changed |= setDoesNotCapture(F, 1);
668321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
669309124Sdim    return Changed;
670321369Sdim  case LibFunc_lchown:
671309124Sdim    Changed |= setDoesNotThrow(F);
672321369Sdim    Changed |= setDoesNotCapture(F, 0);
673321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
674309124Sdim    return Changed;
675321369Sdim  case LibFunc_qsort:
676309124Sdim    // May throw; places call through function pointer.
677321369Sdim    Changed |= setDoesNotCapture(F, 3);
678309124Sdim    return Changed;
679321369Sdim  case LibFunc_dunder_strdup:
680321369Sdim  case LibFunc_dunder_strndup:
681309124Sdim    Changed |= setDoesNotThrow(F);
682321369Sdim    Changed |= setRetDoesNotAlias(F);
683321369Sdim    Changed |= setDoesNotCapture(F, 0);
684321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
685321369Sdim    return Changed;
686321369Sdim  case LibFunc_dunder_strtok_r:
687321369Sdim    Changed |= setDoesNotThrow(F);
688309124Sdim    Changed |= setDoesNotCapture(F, 1);
689309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
690309124Sdim    return Changed;
691321369Sdim  case LibFunc_under_IO_getc:
692309124Sdim    Changed |= setDoesNotThrow(F);
693321369Sdim    Changed |= setDoesNotCapture(F, 0);
694309124Sdim    return Changed;
695321369Sdim  case LibFunc_under_IO_putc:
696309124Sdim    Changed |= setDoesNotThrow(F);
697309124Sdim    Changed |= setDoesNotCapture(F, 1);
698309124Sdim    return Changed;
699321369Sdim  case LibFunc_dunder_isoc99_scanf:
700309124Sdim    Changed |= setDoesNotThrow(F);
701321369Sdim    Changed |= setDoesNotCapture(F, 0);
702321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
703309124Sdim    return Changed;
704321369Sdim  case LibFunc_stat64:
705321369Sdim  case LibFunc_lstat64:
706321369Sdim  case LibFunc_statvfs64:
707309124Sdim    Changed |= setDoesNotThrow(F);
708321369Sdim    Changed |= setDoesNotCapture(F, 0);
709309124Sdim    Changed |= setDoesNotCapture(F, 1);
710321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
711309124Sdim    return Changed;
712321369Sdim  case LibFunc_dunder_isoc99_sscanf:
713309124Sdim    Changed |= setDoesNotThrow(F);
714321369Sdim    Changed |= setDoesNotCapture(F, 0);
715309124Sdim    Changed |= setDoesNotCapture(F, 1);
716321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
717309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
718309124Sdim    return Changed;
719321369Sdim  case LibFunc_fopen64:
720309124Sdim    Changed |= setDoesNotThrow(F);
721321369Sdim    Changed |= setRetDoesNotAlias(F);
722321369Sdim    Changed |= setDoesNotCapture(F, 0);
723309124Sdim    Changed |= setDoesNotCapture(F, 1);
724321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
725309124Sdim    Changed |= setOnlyReadsMemory(F, 1);
726309124Sdim    return Changed;
727321369Sdim  case LibFunc_fseeko64:
728321369Sdim  case LibFunc_ftello64:
729309124Sdim    Changed |= setDoesNotThrow(F);
730321369Sdim    Changed |= setDoesNotCapture(F, 0);
731309124Sdim    return Changed;
732321369Sdim  case LibFunc_tmpfile64:
733309124Sdim    Changed |= setDoesNotThrow(F);
734321369Sdim    Changed |= setRetDoesNotAlias(F);
735309124Sdim    return Changed;
736321369Sdim  case LibFunc_fstat64:
737321369Sdim  case LibFunc_fstatvfs64:
738309124Sdim    Changed |= setDoesNotThrow(F);
739321369Sdim    Changed |= setDoesNotCapture(F, 1);
740309124Sdim    return Changed;
741321369Sdim  case LibFunc_open64:
742309124Sdim    // May throw; "open" is a valid pthread cancellation point.
743321369Sdim    Changed |= setDoesNotCapture(F, 0);
744321369Sdim    Changed |= setOnlyReadsMemory(F, 0);
745309124Sdim    return Changed;
746321369Sdim  case LibFunc_gettimeofday:
747309124Sdim    // Currently some platforms have the restrict keyword on the arguments to
748309124Sdim    // gettimeofday. To be conservative, do not add noalias to gettimeofday's
749309124Sdim    // arguments.
750309124Sdim    Changed |= setDoesNotThrow(F);
751321369Sdim    Changed |= setDoesNotCapture(F, 0);
752309124Sdim    Changed |= setDoesNotCapture(F, 1);
753309124Sdim    return Changed;
754321369Sdim  case LibFunc_Znwj: // new(unsigned int)
755321369Sdim  case LibFunc_Znwm: // new(unsigned long)
756321369Sdim  case LibFunc_Znaj: // new[](unsigned int)
757321369Sdim  case LibFunc_Znam: // new[](unsigned long)
758321369Sdim  case LibFunc_msvc_new_int: // new(unsigned int)
759321369Sdim  case LibFunc_msvc_new_longlong: // new(unsigned long long)
760321369Sdim  case LibFunc_msvc_new_array_int: // new[](unsigned int)
761321369Sdim  case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
762309124Sdim    // Operator new always returns a nonnull noalias pointer
763321369Sdim    Changed |= setRetNonNull(F);
764321369Sdim    Changed |= setRetDoesNotAlias(F);
765309124Sdim    return Changed;
766341825Sdim  // TODO: add LibFunc entries for:
767341825Sdim  // case LibFunc_memset_pattern4:
768341825Sdim  // case LibFunc_memset_pattern8:
769321369Sdim  case LibFunc_memset_pattern16:
770309124Sdim    Changed |= setOnlyAccessesArgMemory(F);
771321369Sdim    Changed |= setDoesNotCapture(F, 0);
772309124Sdim    Changed |= setDoesNotCapture(F, 1);
773321369Sdim    Changed |= setOnlyReadsMemory(F, 1);
774309124Sdim    return Changed;
775309124Sdim  // int __nvvm_reflect(const char *)
776321369Sdim  case LibFunc_nvvm_reflect:
777309124Sdim    Changed |= setDoesNotAccessMemory(F);
778309124Sdim    Changed |= setDoesNotThrow(F);
779309124Sdim    return Changed;
780309124Sdim
781309124Sdim  default:
782309124Sdim    // FIXME: It'd be really nice to cover all the library functions we're
783309124Sdim    // aware of here.
784309124Sdim    return false;
785309124Sdim  }
786309124Sdim}
787309124Sdim
788360784Sdimbool llvm::hasFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
789360784Sdim                      LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) {
790341825Sdim  switch (Ty->getTypeID()) {
791344779Sdim  case Type::HalfTyID:
792344779Sdim    return false;
793341825Sdim  case Type::FloatTyID:
794341825Sdim    return TLI->has(FloatFn);
795341825Sdim  case Type::DoubleTyID:
796341825Sdim    return TLI->has(DoubleFn);
797341825Sdim  default:
798341825Sdim    return TLI->has(LongDoubleFn);
799341825Sdim  }
800341825Sdim}
801341825Sdim
802360784SdimStringRef llvm::getFloatFnName(const TargetLibraryInfo *TLI, Type *Ty,
803360784Sdim                               LibFunc DoubleFn, LibFunc FloatFn,
804360784Sdim                               LibFunc LongDoubleFn) {
805360784Sdim  assert(hasFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
806344779Sdim         "Cannot get name for unavailable function!");
807344779Sdim
808344779Sdim  switch (Ty->getTypeID()) {
809344779Sdim  case Type::HalfTyID:
810344779Sdim    llvm_unreachable("No name for HalfTy!");
811344779Sdim  case Type::FloatTyID:
812344779Sdim    return TLI->getName(FloatFn);
813344779Sdim  case Type::DoubleTyID:
814344779Sdim    return TLI->getName(DoubleFn);
815344779Sdim  default:
816344779Sdim    return TLI->getName(LongDoubleFn);
817344779Sdim  }
818344779Sdim}
819344779Sdim
820309124Sdim//- Emit LibCalls ------------------------------------------------------------//
821309124Sdim
822309124SdimValue *llvm::castToCStr(Value *V, IRBuilder<> &B) {
823276479Sdim  unsigned AS = V->getType()->getPointerAddressSpace();
824276479Sdim  return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
825204792Srdivacky}
826204792Srdivacky
827353358Sdimstatic Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType,
828353358Sdim                          ArrayRef<Type *> ParamTypes,
829353358Sdim                          ArrayRef<Value *> Operands, IRBuilder<> &B,
830353358Sdim                          const TargetLibraryInfo *TLI,
831353358Sdim                          bool IsVaArgs = false) {
832353358Sdim  if (!TLI->has(TheLibFunc))
833276479Sdim    return nullptr;
834239462Sdim
835309124Sdim  Module *M = B.GetInsertBlock()->getModule();
836353358Sdim  StringRef FuncName = TLI->getName(TheLibFunc);
837353358Sdim  FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs);
838353358Sdim  FunctionCallee Callee = M->getOrInsertFunction(FuncName, FuncType);
839353358Sdim  inferLibFuncAttributes(M, FuncName, *TLI);
840353358Sdim  CallInst *CI = B.CreateCall(Callee, Operands, FuncName);
841353358Sdim  if (const Function *F =
842353358Sdim          dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
843204792Srdivacky    CI->setCallingConv(F->getCallingConv());
844204792Srdivacky  return CI;
845204792Srdivacky}
846204792Srdivacky
847353358SdimValue *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
848353358Sdim                        const TargetLibraryInfo *TLI) {
849353358Sdim  LLVMContext &Context = B.GetInsertBlock()->getContext();
850353358Sdim  return emitLibCall(LibFunc_strlen, DL.getIntPtrType(Context),
851353358Sdim                     B.getInt8PtrTy(), castToCStr(Ptr, B), B, TLI);
852353358Sdim}
853353358Sdim
854360784SdimValue *llvm::emitStrDup(Value *Ptr, IRBuilder<> &B,
855360784Sdim                        const TargetLibraryInfo *TLI) {
856360784Sdim  return emitLibCall(LibFunc_strdup, B.getInt8PtrTy(), B.getInt8PtrTy(),
857360784Sdim                     castToCStr(Ptr, B), B, TLI);
858360784Sdim}
859360784Sdim
860309124SdimValue *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
861288943Sdim                        const TargetLibraryInfo *TLI) {
862226633Sdim  Type *I8Ptr = B.getInt8PtrTy();
863226633Sdim  Type *I32Ty = B.getInt32Ty();
864353358Sdim  return emitLibCall(LibFunc_strchr, I8Ptr, {I8Ptr, I32Ty},
865353358Sdim                     {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, B, TLI);
866204792Srdivacky}
867204792Srdivacky
868309124SdimValue *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
869288943Sdim                         const DataLayout &DL, const TargetLibraryInfo *TLI) {
870210299Sed  LLVMContext &Context = B.GetInsertBlock()->getContext();
871353358Sdim  return emitLibCall(
872353358Sdim      LibFunc_strncmp, B.getInt32Ty(),
873353358Sdim      {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
874353358Sdim      {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
875210299Sed}
876210299Sed
877309124SdimValue *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
878353358Sdim                        const TargetLibraryInfo *TLI) {
879353358Sdim  Type *I8Ptr = B.getInt8PtrTy();
880353358Sdim  return emitLibCall(LibFunc_strcpy, I8Ptr, {I8Ptr, I8Ptr},
881353358Sdim                     {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI);
882353358Sdim}
883239462Sdim
884353358SdimValue *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilder<> &B,
885353358Sdim                        const TargetLibraryInfo *TLI) {
886226633Sdim  Type *I8Ptr = B.getInt8PtrTy();
887353358Sdim  return emitLibCall(LibFunc_stpcpy, I8Ptr, {I8Ptr, I8Ptr},
888353358Sdim                     {castToCStr(Dst, B), castToCStr(Src, B)}, B, TLI);
889204792Srdivacky}
890204792Srdivacky
891309124SdimValue *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
892353358Sdim                         const TargetLibraryInfo *TLI) {
893353358Sdim  Type *I8Ptr = B.getInt8PtrTy();
894353358Sdim  return emitLibCall(LibFunc_strncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()},
895353358Sdim                     {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI);
896353358Sdim}
897239462Sdim
898353358SdimValue *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
899353358Sdim                         const TargetLibraryInfo *TLI) {
900226633Sdim  Type *I8Ptr = B.getInt8PtrTy();
901353358Sdim  return emitLibCall(LibFunc_stpncpy, I8Ptr, {I8Ptr, I8Ptr, Len->getType()},
902353358Sdim                     {castToCStr(Dst, B), castToCStr(Src, B), Len}, B, TLI);
903205218Srdivacky}
904205218Srdivacky
905309124SdimValue *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
906288943Sdim                           IRBuilder<> &B, const DataLayout &DL,
907239462Sdim                           const TargetLibraryInfo *TLI) {
908321369Sdim  if (!TLI->has(LibFunc_memcpy_chk))
909276479Sdim    return nullptr;
910239462Sdim
911309124Sdim  Module *M = B.GetInsertBlock()->getModule();
912321369Sdim  AttributeList AS;
913321369Sdim  AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
914321369Sdim                          Attribute::NoUnwind);
915206083Srdivacky  LLVMContext &Context = B.GetInsertBlock()->getContext();
916353358Sdim  FunctionCallee MemCpy = M->getOrInsertFunction(
917321369Sdim      "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
918288943Sdim      B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
919321369Sdim      DL.getIntPtrType(Context));
920309124Sdim  Dst = castToCStr(Dst, B);
921309124Sdim  Src = castToCStr(Src, B);
922288943Sdim  CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
923353358Sdim  if (const Function *F =
924353358Sdim          dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts()))
925206083Srdivacky    CI->setCallingConv(F->getCallingConv());
926206083Srdivacky  return CI;
927206083Srdivacky}
928206083Srdivacky
929309124SdimValue *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
930288943Sdim                        const DataLayout &DL, const TargetLibraryInfo *TLI) {
931204792Srdivacky  LLVMContext &Context = B.GetInsertBlock()->getContext();
932353358Sdim  return emitLibCall(
933353358Sdim      LibFunc_memchr, B.getInt8PtrTy(),
934353358Sdim      {B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context)},
935353358Sdim      {castToCStr(Ptr, B), Val, Len}, B, TLI);
936204792Srdivacky}
937204792Srdivacky
938309124SdimValue *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
939288943Sdim                        const DataLayout &DL, const TargetLibraryInfo *TLI) {
940353358Sdim  LLVMContext &Context = B.GetInsertBlock()->getContext();
941353358Sdim  return emitLibCall(
942353358Sdim      LibFunc_memcmp, B.getInt32Ty(),
943353358Sdim      {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
944353358Sdim      {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
945353358Sdim}
946239462Sdim
947353358SdimValue *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
948353358Sdim                      const DataLayout &DL, const TargetLibraryInfo *TLI) {
949204792Srdivacky  LLVMContext &Context = B.GetInsertBlock()->getContext();
950353358Sdim  return emitLibCall(
951353358Sdim      LibFunc_bcmp, B.getInt32Ty(),
952353358Sdim      {B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)},
953353358Sdim      {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, B, TLI);
954353358Sdim}
955204792Srdivacky
956353358SdimValue *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
957353358Sdim                         IRBuilder<> &B, const TargetLibraryInfo *TLI) {
958353358Sdim  return emitLibCall(
959353358Sdim      LibFunc_memccpy, B.getInt8PtrTy(),
960353358Sdim      {B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), Len->getType()},
961353358Sdim      {Ptr1, Ptr2, Val, Len}, B, TLI);
962353358Sdim}
963204792Srdivacky
964353358SdimValue *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
965353358Sdim                          ArrayRef<Value *> VariadicArgs, IRBuilder<> &B,
966353358Sdim                          const TargetLibraryInfo *TLI) {
967353358Sdim  SmallVector<Value *, 8> Args{castToCStr(Dest, B), Size, castToCStr(Fmt, B)};
968353358Sdim  Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end());
969353358Sdim  return emitLibCall(LibFunc_snprintf, B.getInt32Ty(),
970353358Sdim                     {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy()},
971353358Sdim                     Args, B, TLI, /*IsVaArgs=*/true);
972204792Srdivacky}
973204792Srdivacky
974353358SdimValue *llvm::emitSPrintf(Value *Dest, Value *Fmt,
975353358Sdim                         ArrayRef<Value *> VariadicArgs, IRBuilder<> &B,
976353358Sdim                         const TargetLibraryInfo *TLI) {
977353358Sdim  SmallVector<Value *, 8> Args{castToCStr(Dest, B), castToCStr(Fmt, B)};
978353358Sdim  Args.insert(Args.end(), VariadicArgs.begin(), VariadicArgs.end());
979353358Sdim  return emitLibCall(LibFunc_sprintf, B.getInt32Ty(),
980353358Sdim                     {B.getInt8PtrTy(), B.getInt8PtrTy()}, Args, B, TLI,
981353358Sdim                     /*IsVaArgs=*/true);
982353358Sdim}
983353358Sdim
984353358SdimValue *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilder<> &B,
985353358Sdim                        const TargetLibraryInfo *TLI) {
986353358Sdim  return emitLibCall(LibFunc_strcat, B.getInt8PtrTy(),
987353358Sdim                     {B.getInt8PtrTy(), B.getInt8PtrTy()},
988353358Sdim                     {castToCStr(Dest, B), castToCStr(Src, B)}, B, TLI);
989353358Sdim}
990353358Sdim
991353358SdimValue *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
992353358Sdim                         const TargetLibraryInfo *TLI) {
993353358Sdim  return emitLibCall(LibFunc_strlcpy, Size->getType(),
994353358Sdim                     {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
995353358Sdim                     {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
996353358Sdim}
997353358Sdim
998353358SdimValue *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
999353358Sdim                         const TargetLibraryInfo *TLI) {
1000353358Sdim  return emitLibCall(LibFunc_strlcat, Size->getType(),
1001353358Sdim                     {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
1002353358Sdim                     {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
1003353358Sdim}
1004353358Sdim
1005353358SdimValue *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
1006353358Sdim                         const TargetLibraryInfo *TLI) {
1007353358Sdim  return emitLibCall(LibFunc_strncat, B.getInt8PtrTy(),
1008353358Sdim                     {B.getInt8PtrTy(), B.getInt8PtrTy(), Size->getType()},
1009353358Sdim                     {castToCStr(Dest, B), castToCStr(Src, B), Size}, B, TLI);
1010353358Sdim}
1011353358Sdim
1012353358SdimValue *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
1013353358Sdim                           IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1014353358Sdim  return emitLibCall(
1015353358Sdim      LibFunc_vsnprintf, B.getInt32Ty(),
1016353358Sdim      {B.getInt8PtrTy(), Size->getType(), B.getInt8PtrTy(), VAList->getType()},
1017353358Sdim      {castToCStr(Dest, B), Size, castToCStr(Fmt, B), VAList}, B, TLI);
1018353358Sdim}
1019353358Sdim
1020353358SdimValue *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList,
1021353358Sdim                          IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1022353358Sdim  return emitLibCall(LibFunc_vsprintf, B.getInt32Ty(),
1023353358Sdim                     {B.getInt8PtrTy(), B.getInt8PtrTy(), VAList->getType()},
1024353358Sdim                     {castToCStr(Dest, B), castToCStr(Fmt, B), VAList}, B, TLI);
1025353358Sdim}
1026353358Sdim
1027276479Sdim/// Append a suffix to the function name according to the type of 'Op'.
1028309124Sdimstatic void appendTypeSuffix(Value *Op, StringRef &Name,
1029309124Sdim                             SmallString<20> &NameBuffer) {
1030276479Sdim  if (!Op->getType()->isDoubleTy()) {
1031276479Sdim      NameBuffer += Name;
1032276479Sdim
1033276479Sdim    if (Op->getType()->isFloatTy())
1034276479Sdim      NameBuffer += 'f';
1035276479Sdim    else
1036276479Sdim      NameBuffer += 'l';
1037276479Sdim
1038276479Sdim    Name = NameBuffer;
1039341825Sdim  }
1040276479Sdim}
1041276479Sdim
1042344779Sdimstatic Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
1043344779Sdim                                         IRBuilder<> &B,
1044344779Sdim                                         const AttributeList &Attrs) {
1045344779Sdim  assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
1046204792Srdivacky
1047309124Sdim  Module *M = B.GetInsertBlock()->getModule();
1048353358Sdim  FunctionCallee Callee =
1049353358Sdim      M->getOrInsertFunction(Name, Op->getType(), Op->getType());
1050204792Srdivacky  CallInst *CI = B.CreateCall(Callee, Op, Name);
1051321369Sdim
1052321369Sdim  // The incoming attribute set may have come from a speculatable intrinsic, but
1053321369Sdim  // is being replaced with a library call which is not allowed to be
1054321369Sdim  // speculatable.
1055321369Sdim  CI->setAttributes(Attrs.removeAttribute(B.getContext(),
1056321369Sdim                                          AttributeList::FunctionIndex,
1057321369Sdim                                          Attribute::Speculatable));
1058353358Sdim  if (const Function *F =
1059353358Sdim          dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
1060204792Srdivacky    CI->setCallingConv(F->getCallingConv());
1061204792Srdivacky
1062204792Srdivacky  return CI;
1063204792Srdivacky}
1064204792Srdivacky
1065344779SdimValue *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
1066344779Sdim                                  const AttributeList &Attrs) {
1067344779Sdim  SmallString<20> NameBuffer;
1068344779Sdim  appendTypeSuffix(Op, Name, NameBuffer);
1069344779Sdim
1070344779Sdim  return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1071344779Sdim}
1072344779Sdim
1073344779SdimValue *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
1074344779Sdim                                  LibFunc DoubleFn, LibFunc FloatFn,
1075344779Sdim                                  LibFunc LongDoubleFn, IRBuilder<> &B,
1076344779Sdim                                  const AttributeList &Attrs) {
1077344779Sdim  // Get the name of the function according to TLI.
1078360784Sdim  StringRef Name = getFloatFnName(TLI, Op->getType(),
1079360784Sdim                                  DoubleFn, FloatFn, LongDoubleFn);
1080344779Sdim
1081344779Sdim  return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1082344779Sdim}
1083344779Sdim
1084360784Sdimstatic Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2,
1085360784Sdim                                          StringRef Name, IRBuilder<> &B,
1086360784Sdim                                          const AttributeList &Attrs) {
1087344779Sdim  assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1088344779Sdim
1089360784Sdim  Module *M = B.GetInsertBlock()->getModule();
1090360784Sdim  FunctionCallee Callee = M->getOrInsertFunction(Name, Op1->getType(),
1091360784Sdim                                                 Op1->getType(), Op2->getType());
1092360784Sdim  CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name);
1093276479Sdim
1094360784Sdim  // The incoming attribute set may have come from a speculatable intrinsic, but
1095360784Sdim  // is being replaced with a library call which is not allowed to be
1096360784Sdim  // speculatable.
1097360784Sdim  CI->setAttributes(Attrs.removeAttribute(B.getContext(),
1098360784Sdim                                          AttributeList::FunctionIndex,
1099360784Sdim                                          Attribute::Speculatable));
1100353358Sdim  if (const Function *F =
1101353358Sdim          dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))
1102276479Sdim    CI->setCallingConv(F->getCallingConv());
1103276479Sdim
1104276479Sdim  return CI;
1105276479Sdim}
1106276479Sdim
1107360784SdimValue *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
1108360784Sdim                                   IRBuilder<> &B, const AttributeList &Attrs) {
1109360784Sdim  assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1110360784Sdim
1111360784Sdim  SmallString<20> NameBuffer;
1112360784Sdim  appendTypeSuffix(Op1, Name, NameBuffer);
1113360784Sdim
1114360784Sdim  return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs);
1115360784Sdim}
1116360784Sdim
1117360784SdimValue *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,
1118360784Sdim                                   const TargetLibraryInfo *TLI,
1119360784Sdim                                   LibFunc DoubleFn, LibFunc FloatFn,
1120360784Sdim                                   LibFunc LongDoubleFn, IRBuilder<> &B,
1121360784Sdim                                   const AttributeList &Attrs) {
1122360784Sdim  // Get the name of the function according to TLI.
1123360784Sdim  StringRef Name = getFloatFnName(TLI, Op1->getType(),
1124360784Sdim                                  DoubleFn, FloatFn, LongDoubleFn);
1125360784Sdim
1126360784Sdim  return emitBinaryFloatFnCallHelper(Op1, Op2, Name, B, Attrs);
1127360784Sdim}
1128360784Sdim
1129309124SdimValue *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
1130239462Sdim                         const TargetLibraryInfo *TLI) {
1131321369Sdim  if (!TLI->has(LibFunc_putchar))
1132276479Sdim    return nullptr;
1133239462Sdim
1134309124Sdim  Module *M = B.GetInsertBlock()->getModule();
1135341825Sdim  StringRef PutCharName = TLI->getName(LibFunc_putchar);
1136353358Sdim  FunctionCallee PutChar =
1137353358Sdim      M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty());
1138341825Sdim  inferLibFuncAttributes(M, PutCharName, *TLI);
1139204792Srdivacky  CallInst *CI = B.CreateCall(PutChar,
1140204792Srdivacky                              B.CreateIntCast(Char,
1141204792Srdivacky                              B.getInt32Ty(),
1142204792Srdivacky                              /*isSigned*/true,
1143204792Srdivacky                              "chari"),
1144341825Sdim                              PutCharName);
1145204792Srdivacky
1146353358Sdim  if (const Function *F =
1147353358Sdim          dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts()))
1148204792Srdivacky    CI->setCallingConv(F->getCallingConv());
1149204792Srdivacky  return CI;
1150204792Srdivacky}
1151204792Srdivacky
1152309124SdimValue *llvm::emitPutS(Value *Str, IRBuilder<> &B,
1153239462Sdim                      const TargetLibraryInfo *TLI) {
1154321369Sdim  if (!TLI->has(LibFunc_puts))
1155276479Sdim    return nullptr;
1156239462Sdim
1157309124Sdim  Module *M = B.GetInsertBlock()->getModule();
1158341825Sdim  StringRef PutsName = TLI->getName(LibFunc_puts);
1159353358Sdim  FunctionCallee PutS =
1160341825Sdim      M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy());
1161341825Sdim  inferLibFuncAttributes(M, PutsName, *TLI);
1162341825Sdim  CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName);
1163353358Sdim  if (const Function *F =
1164353358Sdim          dyn_cast<Function>(PutS.getCallee()->stripPointerCasts()))
1165204792Srdivacky    CI->setCallingConv(F->getCallingConv());
1166239462Sdim  return CI;
1167204792Srdivacky}
1168204792Srdivacky
1169309124SdimValue *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
1170288943Sdim                       const TargetLibraryInfo *TLI) {
1171321369Sdim  if (!TLI->has(LibFunc_fputc))
1172276479Sdim    return nullptr;
1173239462Sdim
1174309124Sdim  Module *M = B.GetInsertBlock()->getModule();
1175341825Sdim  StringRef FPutcName = TLI->getName(LibFunc_fputc);
1176353358Sdim  FunctionCallee F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(),
1177353358Sdim                                            B.getInt32Ty(), File->getType());
1178204792Srdivacky  if (File->getType()->isPointerTy())
1179341825Sdim    inferLibFuncAttributes(M, FPutcName, *TLI);
1180204792Srdivacky  Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
1181204792Srdivacky                         "chari");
1182341825Sdim  CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
1183204792Srdivacky
1184353358Sdim  if (const Function *Fn =
1185353358Sdim          dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
1186204792Srdivacky    CI->setCallingConv(Fn->getCallingConv());
1187239462Sdim  return CI;
1188204792Srdivacky}
1189204792Srdivacky
1190341825SdimValue *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
1191341825Sdim                               const TargetLibraryInfo *TLI) {
1192341825Sdim  if (!TLI->has(LibFunc_fputc_unlocked))
1193341825Sdim    return nullptr;
1194341825Sdim
1195341825Sdim  Module *M = B.GetInsertBlock()->getModule();
1196341825Sdim  StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked);
1197353358Sdim  FunctionCallee F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(),
1198353358Sdim                                            B.getInt32Ty(), File->getType());
1199341825Sdim  if (File->getType()->isPointerTy())
1200341825Sdim    inferLibFuncAttributes(M, FPutcUnlockedName, *TLI);
1201341825Sdim  Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
1202341825Sdim  CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName);
1203341825Sdim
1204353358Sdim  if (const Function *Fn =
1205353358Sdim          dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
1206341825Sdim    CI->setCallingConv(Fn->getCallingConv());
1207341825Sdim  return CI;
1208341825Sdim}
1209341825Sdim
1210309124SdimValue *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
1211288943Sdim                       const TargetLibraryInfo *TLI) {
1212321369Sdim  if (!TLI->has(LibFunc_fputs))
1213276479Sdim    return nullptr;
1214239462Sdim
1215309124Sdim  Module *M = B.GetInsertBlock()->getModule();
1216321369Sdim  StringRef FPutsName = TLI->getName(LibFunc_fputs);
1217353358Sdim  FunctionCallee F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
1218353358Sdim                                            B.getInt8PtrTy(), File->getType());
1219204792Srdivacky  if (File->getType()->isPointerTy())
1220341825Sdim    inferLibFuncAttributes(M, FPutsName, *TLI);
1221341825Sdim  CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName);
1222204792Srdivacky
1223353358Sdim  if (const Function *Fn =
1224353358Sdim          dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
1225204792Srdivacky    CI->setCallingConv(Fn->getCallingConv());
1226239462Sdim  return CI;
1227204792Srdivacky}
1228204792Srdivacky
1229341825SdimValue *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
1230341825Sdim                               const TargetLibraryInfo *TLI) {
1231341825Sdim  if (!TLI->has(LibFunc_fputs_unlocked))
1232341825Sdim    return nullptr;
1233341825Sdim
1234341825Sdim  Module *M = B.GetInsertBlock()->getModule();
1235341825Sdim  StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
1236353358Sdim  FunctionCallee F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
1237353358Sdim                                            B.getInt8PtrTy(), File->getType());
1238341825Sdim  if (File->getType()->isPointerTy())
1239341825Sdim    inferLibFuncAttributes(M, FPutsUnlockedName, *TLI);
1240341825Sdim  CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName);
1241341825Sdim
1242353358Sdim  if (const Function *Fn =
1243353358Sdim          dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
1244341825Sdim    CI->setCallingConv(Fn->getCallingConv());
1245341825Sdim  return CI;
1246341825Sdim}
1247341825Sdim
1248309124SdimValue *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
1249288943Sdim                        const DataLayout &DL, const TargetLibraryInfo *TLI) {
1250321369Sdim  if (!TLI->has(LibFunc_fwrite))
1251276479Sdim    return nullptr;
1252239462Sdim
1253309124Sdim  Module *M = B.GetInsertBlock()->getModule();
1254204792Srdivacky  LLVMContext &Context = B.GetInsertBlock()->getContext();
1255321369Sdim  StringRef FWriteName = TLI->getName(LibFunc_fwrite);
1256353358Sdim  FunctionCallee F = M->getOrInsertFunction(
1257309124Sdim      FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1258321369Sdim      DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1259321369Sdim
1260204792Srdivacky  if (File->getType()->isPointerTy())
1261341825Sdim    inferLibFuncAttributes(M, FWriteName, *TLI);
1262288943Sdim  CallInst *CI =
1263309124Sdim      B.CreateCall(F, {castToCStr(Ptr, B), Size,
1264288943Sdim                       ConstantInt::get(DL.getIntPtrType(Context), 1), File});
1265204792Srdivacky
1266353358Sdim  if (const Function *Fn =
1267353358Sdim          dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
1268204792Srdivacky    CI->setCallingConv(Fn->getCallingConv());
1269239462Sdim  return CI;
1270204792Srdivacky}
1271341825Sdim
1272341825SdimValue *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
1273341825Sdim                        const TargetLibraryInfo *TLI) {
1274341825Sdim  if (!TLI->has(LibFunc_malloc))
1275341825Sdim    return nullptr;
1276341825Sdim
1277341825Sdim  Module *M = B.GetInsertBlock()->getModule();
1278341825Sdim  StringRef MallocName = TLI->getName(LibFunc_malloc);
1279341825Sdim  LLVMContext &Context = B.GetInsertBlock()->getContext();
1280353358Sdim  FunctionCallee Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(),
1281353358Sdim                                                 DL.getIntPtrType(Context));
1282341825Sdim  inferLibFuncAttributes(M, MallocName, *TLI);
1283341825Sdim  CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
1284341825Sdim
1285353358Sdim  if (const Function *F =
1286353358Sdim          dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts()))
1287341825Sdim    CI->setCallingConv(F->getCallingConv());
1288341825Sdim
1289341825Sdim  return CI;
1290341825Sdim}
1291341825Sdim
1292341825SdimValue *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
1293341825Sdim                        IRBuilder<> &B, const TargetLibraryInfo &TLI) {
1294341825Sdim  if (!TLI.has(LibFunc_calloc))
1295341825Sdim    return nullptr;
1296341825Sdim
1297341825Sdim  Module *M = B.GetInsertBlock()->getModule();
1298341825Sdim  StringRef CallocName = TLI.getName(LibFunc_calloc);
1299341825Sdim  const DataLayout &DL = M->getDataLayout();
1300341825Sdim  IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
1301353358Sdim  FunctionCallee Calloc = M->getOrInsertFunction(
1302353358Sdim      CallocName, Attrs, B.getInt8PtrTy(), PtrType, PtrType);
1303341825Sdim  inferLibFuncAttributes(M, CallocName, TLI);
1304341825Sdim  CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
1305341825Sdim
1306353358Sdim  if (const auto *F =
1307353358Sdim          dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts()))
1308341825Sdim    CI->setCallingConv(F->getCallingConv());
1309341825Sdim
1310341825Sdim  return CI;
1311341825Sdim}
1312341825Sdim
1313341825SdimValue *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1314341825Sdim                                IRBuilder<> &B, const DataLayout &DL,
1315341825Sdim                                const TargetLibraryInfo *TLI) {
1316341825Sdim  if (!TLI->has(LibFunc_fwrite_unlocked))
1317341825Sdim    return nullptr;
1318341825Sdim
1319341825Sdim  Module *M = B.GetInsertBlock()->getModule();
1320341825Sdim  LLVMContext &Context = B.GetInsertBlock()->getContext();
1321341825Sdim  StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
1322353358Sdim  FunctionCallee F = M->getOrInsertFunction(
1323341825Sdim      FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1324341825Sdim      DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1325341825Sdim
1326341825Sdim  if (File->getType()->isPointerTy())
1327341825Sdim    inferLibFuncAttributes(M, FWriteUnlockedName, *TLI);
1328341825Sdim  CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1329341825Sdim
1330353358Sdim  if (const Function *Fn =
1331353358Sdim          dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
1332341825Sdim    CI->setCallingConv(Fn->getCallingConv());
1333341825Sdim  return CI;
1334341825Sdim}
1335341825Sdim
1336341825SdimValue *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
1337341825Sdim                               const TargetLibraryInfo *TLI) {
1338341825Sdim  if (!TLI->has(LibFunc_fgetc_unlocked))
1339341825Sdim    return nullptr;
1340341825Sdim
1341341825Sdim  Module *M = B.GetInsertBlock()->getModule();
1342341825Sdim  StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked);
1343353358Sdim  FunctionCallee F = M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(),
1344353358Sdim                                            File->getType());
1345341825Sdim  if (File->getType()->isPointerTy())
1346341825Sdim    inferLibFuncAttributes(M, FGetCUnlockedName, *TLI);
1347341825Sdim  CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName);
1348341825Sdim
1349353358Sdim  if (const Function *Fn =
1350353358Sdim          dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
1351341825Sdim    CI->setCallingConv(Fn->getCallingConv());
1352341825Sdim  return CI;
1353341825Sdim}
1354341825Sdim
1355341825SdimValue *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
1356341825Sdim                               IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1357341825Sdim  if (!TLI->has(LibFunc_fgets_unlocked))
1358341825Sdim    return nullptr;
1359341825Sdim
1360341825Sdim  Module *M = B.GetInsertBlock()->getModule();
1361341825Sdim  StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked);
1362353358Sdim  FunctionCallee F =
1363341825Sdim      M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(),
1364341825Sdim                             B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
1365341825Sdim  inferLibFuncAttributes(M, FGetSUnlockedName, *TLI);
1366341825Sdim  CallInst *CI =
1367341825Sdim      B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName);
1368341825Sdim
1369353358Sdim  if (const Function *Fn =
1370353358Sdim          dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
1371341825Sdim    CI->setCallingConv(Fn->getCallingConv());
1372341825Sdim  return CI;
1373341825Sdim}
1374341825Sdim
1375341825SdimValue *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1376341825Sdim                               IRBuilder<> &B, const DataLayout &DL,
1377341825Sdim                               const TargetLibraryInfo *TLI) {
1378341825Sdim  if (!TLI->has(LibFunc_fread_unlocked))
1379341825Sdim    return nullptr;
1380341825Sdim
1381341825Sdim  Module *M = B.GetInsertBlock()->getModule();
1382341825Sdim  LLVMContext &Context = B.GetInsertBlock()->getContext();
1383341825Sdim  StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
1384353358Sdim  FunctionCallee F = M->getOrInsertFunction(
1385341825Sdim      FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1386341825Sdim      DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1387341825Sdim
1388341825Sdim  if (File->getType()->isPointerTy())
1389341825Sdim    inferLibFuncAttributes(M, FReadUnlockedName, *TLI);
1390341825Sdim  CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1391341825Sdim
1392353358Sdim  if (const Function *Fn =
1393353358Sdim          dyn_cast<Function>(F.getCallee()->stripPointerCasts()))
1394341825Sdim    CI->setCallingConv(Fn->getCallingConv());
1395341825Sdim  return CI;
1396341825Sdim}
1397