BuildLibCalls.cpp revision 243830
1//===- 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"
15#include "llvm/Constants.h"
16#include "llvm/Function.h"
17#include "llvm/IRBuilder.h"
18#include "llvm/Intrinsics.h"
19#include "llvm/Intrinsics.h"
20#include "llvm/LLVMContext.h"
21#include "llvm/LLVMContext.h"
22#include "llvm/Module.h"
23#include "llvm/Type.h"
24#include "llvm/ADT/SmallString.h"
25#include "llvm/DataLayout.h"
26#include "llvm/Target/TargetLibraryInfo.h"
27
28using namespace llvm;
29
30/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
31Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) {
32  return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr");
33}
34
35/// EmitStrLen - Emit a call to the strlen function to the builder, for the
36/// specified pointer.  This always returns an integer value of size intptr_t.
37Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
38                        const TargetLibraryInfo *TLI) {
39  if (!TLI->has(LibFunc::strlen))
40    return 0;
41
42  Module *M = B.GetInsertBlock()->getParent()->getParent();
43  AttributeWithIndex AWI[2];
44  AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture);
45  Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind };
46  AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
47                                   ArrayRef<Attributes::AttrVal>(AVs, 2));
48
49  LLVMContext &Context = B.GetInsertBlock()->getContext();
50  Constant *StrLen = M->getOrInsertFunction("strlen",
51                                            AttrListPtr::get(M->getContext(),
52                                                             AWI),
53                                            TD->getIntPtrType(Context),
54                                            B.getInt8PtrTy(),
55                                            NULL);
56  CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
57  if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
58    CI->setCallingConv(F->getCallingConv());
59
60  return CI;
61}
62
63/// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
64/// specified pointer.  Ptr is required to be some pointer type, MaxLen must
65/// be of size_t type, and the return value has 'intptr_t' type.
66Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
67                         const DataLayout *TD, const TargetLibraryInfo *TLI) {
68  if (!TLI->has(LibFunc::strnlen))
69    return 0;
70
71  Module *M = B.GetInsertBlock()->getParent()->getParent();
72  AttributeWithIndex AWI[2];
73  AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture);
74  Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind };
75  AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
76                                   ArrayRef<Attributes::AttrVal>(AVs, 2));
77
78  LLVMContext &Context = B.GetInsertBlock()->getContext();
79  Constant *StrNLen = M->getOrInsertFunction("strnlen",
80                                             AttrListPtr::get(M->getContext(),
81                                                              AWI),
82                                             TD->getIntPtrType(Context),
83                                             B.getInt8PtrTy(),
84                                             TD->getIntPtrType(Context),
85                                             NULL);
86  CallInst *CI = B.CreateCall2(StrNLen, CastToCStr(Ptr, B), MaxLen, "strnlen");
87  if (const Function *F = dyn_cast<Function>(StrNLen->stripPointerCasts()))
88    CI->setCallingConv(F->getCallingConv());
89
90  return CI;
91}
92
93/// EmitStrChr - Emit a call to the strchr function to the builder, for the
94/// specified pointer and character.  Ptr is required to be some pointer type,
95/// and the return value has 'i8*' type.
96Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
97                        const DataLayout *TD, const TargetLibraryInfo *TLI) {
98  if (!TLI->has(LibFunc::strchr))
99    return 0;
100
101  Module *M = B.GetInsertBlock()->getParent()->getParent();
102  Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind };
103  AttributeWithIndex AWI =
104    AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
105                            ArrayRef<Attributes::AttrVal>(AVs, 2));
106
107  Type *I8Ptr = B.getInt8PtrTy();
108  Type *I32Ty = B.getInt32Ty();
109  Constant *StrChr = M->getOrInsertFunction("strchr",
110                                            AttrListPtr::get(M->getContext(),
111                                                             AWI),
112                                            I8Ptr, I8Ptr, I32Ty, NULL);
113  CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
114                               ConstantInt::get(I32Ty, C), "strchr");
115  if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
116    CI->setCallingConv(F->getCallingConv());
117  return CI;
118}
119
120/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
121Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
122                         IRBuilder<> &B, const DataLayout *TD,
123                         const TargetLibraryInfo *TLI) {
124  if (!TLI->has(LibFunc::strncmp))
125    return 0;
126
127  Module *M = B.GetInsertBlock()->getParent()->getParent();
128  AttributeWithIndex AWI[3];
129  AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture);
130  AWI[1] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture);
131  Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind };
132  AWI[2] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
133                                   ArrayRef<Attributes::AttrVal>(AVs, 2));
134
135  LLVMContext &Context = B.GetInsertBlock()->getContext();
136  Value *StrNCmp = M->getOrInsertFunction("strncmp",
137                                          AttrListPtr::get(M->getContext(),
138                                                           AWI),
139                                          B.getInt32Ty(),
140                                          B.getInt8PtrTy(),
141                                          B.getInt8PtrTy(),
142                                          TD->getIntPtrType(Context), NULL);
143  CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B),
144                               CastToCStr(Ptr2, B), Len, "strncmp");
145
146  if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
147    CI->setCallingConv(F->getCallingConv());
148
149  return CI;
150}
151
152/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
153/// specified pointer arguments.
154Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
155                        const DataLayout *TD, const TargetLibraryInfo *TLI,
156                        StringRef Name) {
157  if (!TLI->has(LibFunc::strcpy))
158    return 0;
159
160  Module *M = B.GetInsertBlock()->getParent()->getParent();
161  AttributeWithIndex AWI[2];
162  AWI[0] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture);
163  AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
164                                   Attributes::NoUnwind);
165  Type *I8Ptr = B.getInt8PtrTy();
166  Value *StrCpy = M->getOrInsertFunction(Name,
167                                         AttrListPtr::get(M->getContext(), AWI),
168                                         I8Ptr, I8Ptr, I8Ptr, NULL);
169  CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
170                               Name);
171  if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
172    CI->setCallingConv(F->getCallingConv());
173  return CI;
174}
175
176/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
177/// specified pointer arguments.
178Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
179                         IRBuilder<> &B, const DataLayout *TD,
180                         const TargetLibraryInfo *TLI, StringRef Name) {
181  if (!TLI->has(LibFunc::strncpy))
182    return 0;
183
184  Module *M = B.GetInsertBlock()->getParent()->getParent();
185  AttributeWithIndex AWI[2];
186  AWI[0] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture);
187  AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
188                                   Attributes::NoUnwind);
189  Type *I8Ptr = B.getInt8PtrTy();
190  Value *StrNCpy = M->getOrInsertFunction(Name,
191                                          AttrListPtr::get(M->getContext(),
192                                                           AWI),
193                                          I8Ptr, I8Ptr, I8Ptr,
194                                          Len->getType(), NULL);
195  CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
196                               Len, "strncpy");
197  if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
198    CI->setCallingConv(F->getCallingConv());
199  return CI;
200}
201
202/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
203/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
204/// are pointers.
205Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
206                           IRBuilder<> &B, const DataLayout *TD,
207                           const TargetLibraryInfo *TLI) {
208  if (!TLI->has(LibFunc::memcpy_chk))
209    return 0;
210
211  Module *M = B.GetInsertBlock()->getParent()->getParent();
212  AttributeWithIndex AWI;
213  AWI = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
214                                Attributes::NoUnwind);
215  LLVMContext &Context = B.GetInsertBlock()->getContext();
216  Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
217                                         AttrListPtr::get(M->getContext(), AWI),
218                                         B.getInt8PtrTy(),
219                                         B.getInt8PtrTy(),
220                                         B.getInt8PtrTy(),
221                                         TD->getIntPtrType(Context),
222                                         TD->getIntPtrType(Context), NULL);
223  Dst = CastToCStr(Dst, B);
224  Src = CastToCStr(Src, B);
225  CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize);
226  if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
227    CI->setCallingConv(F->getCallingConv());
228  return CI;
229}
230
231/// EmitMemChr - Emit a call to the memchr function.  This assumes that Ptr is
232/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
233Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
234                        Value *Len, IRBuilder<> &B, const DataLayout *TD,
235                        const TargetLibraryInfo *TLI) {
236  if (!TLI->has(LibFunc::memchr))
237    return 0;
238
239  Module *M = B.GetInsertBlock()->getParent()->getParent();
240  AttributeWithIndex AWI;
241  Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind };
242  AWI = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
243                                ArrayRef<Attributes::AttrVal>(AVs, 2));
244  LLVMContext &Context = B.GetInsertBlock()->getContext();
245  Value *MemChr = M->getOrInsertFunction("memchr",
246                                         AttrListPtr::get(M->getContext(), AWI),
247                                         B.getInt8PtrTy(),
248                                         B.getInt8PtrTy(),
249                                         B.getInt32Ty(),
250                                         TD->getIntPtrType(Context),
251                                         NULL);
252  CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
253
254  if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
255    CI->setCallingConv(F->getCallingConv());
256
257  return CI;
258}
259
260/// EmitMemCmp - Emit a call to the memcmp function.
261Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
262                        Value *Len, IRBuilder<> &B, const DataLayout *TD,
263                        const TargetLibraryInfo *TLI) {
264  if (!TLI->has(LibFunc::memcmp))
265    return 0;
266
267  Module *M = B.GetInsertBlock()->getParent()->getParent();
268  AttributeWithIndex AWI[3];
269  AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture);
270  AWI[1] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture);
271  Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind };
272  AWI[2] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
273                                   ArrayRef<Attributes::AttrVal>(AVs, 2));
274
275  LLVMContext &Context = B.GetInsertBlock()->getContext();
276  Value *MemCmp = M->getOrInsertFunction("memcmp",
277                                         AttrListPtr::get(M->getContext(), AWI),
278                                         B.getInt32Ty(),
279                                         B.getInt8PtrTy(),
280                                         B.getInt8PtrTy(),
281                                         TD->getIntPtrType(Context), NULL);
282  CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
283                               Len, "memcmp");
284
285  if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
286    CI->setCallingConv(F->getCallingConv());
287
288  return CI;
289}
290
291/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
292/// 'floor').  This function is known to take a single of type matching 'Op' and
293/// returns one value with the same type.  If 'Op' is a long double, 'l' is
294/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
295Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
296                                  const AttrListPtr &Attrs) {
297  SmallString<20> NameBuffer;
298  if (!Op->getType()->isDoubleTy()) {
299    // If we need to add a suffix, copy into NameBuffer.
300    NameBuffer += Name;
301    if (Op->getType()->isFloatTy())
302      NameBuffer += 'f'; // floorf
303    else
304      NameBuffer += 'l'; // floorl
305    Name = NameBuffer;
306  }
307
308  Module *M = B.GetInsertBlock()->getParent()->getParent();
309  Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
310                                         Op->getType(), NULL);
311  CallInst *CI = B.CreateCall(Callee, Op, Name);
312  CI->setAttributes(Attrs);
313  if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
314    CI->setCallingConv(F->getCallingConv());
315
316  return CI;
317}
318
319/// EmitPutChar - Emit a call to the putchar function.  This assumes that Char
320/// is an integer.
321Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
322                         const TargetLibraryInfo *TLI) {
323  if (!TLI->has(LibFunc::putchar))
324    return 0;
325
326  Module *M = B.GetInsertBlock()->getParent()->getParent();
327  Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
328                                          B.getInt32Ty(), NULL);
329  CallInst *CI = B.CreateCall(PutChar,
330                              B.CreateIntCast(Char,
331                              B.getInt32Ty(),
332                              /*isSigned*/true,
333                              "chari"),
334                              "putchar");
335
336  if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
337    CI->setCallingConv(F->getCallingConv());
338  return CI;
339}
340
341/// EmitPutS - Emit a call to the puts function.  This assumes that Str is
342/// some pointer.
343Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
344                      const TargetLibraryInfo *TLI) {
345  if (!TLI->has(LibFunc::puts))
346    return 0;
347
348  Module *M = B.GetInsertBlock()->getParent()->getParent();
349  AttributeWithIndex AWI[2];
350  AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture);
351  AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
352                                   Attributes::NoUnwind);
353
354  Value *PutS = M->getOrInsertFunction("puts",
355                                       AttrListPtr::get(M->getContext(), AWI),
356                                       B.getInt32Ty(),
357                                       B.getInt8PtrTy(),
358                                       NULL);
359  CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
360  if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
361    CI->setCallingConv(F->getCallingConv());
362  return CI;
363}
364
365/// EmitFPutC - Emit a call to the fputc function.  This assumes that Char is
366/// an integer and File is a pointer to FILE.
367Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
368                       const DataLayout *TD, const TargetLibraryInfo *TLI) {
369  if (!TLI->has(LibFunc::fputc))
370    return 0;
371
372  Module *M = B.GetInsertBlock()->getParent()->getParent();
373  AttributeWithIndex AWI[2];
374  AWI[0] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture);
375  AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
376                                   Attributes::NoUnwind);
377  Constant *F;
378  if (File->getType()->isPointerTy())
379    F = M->getOrInsertFunction("fputc",
380                               AttrListPtr::get(M->getContext(), AWI),
381                               B.getInt32Ty(),
382                               B.getInt32Ty(), File->getType(),
383                               NULL);
384  else
385    F = M->getOrInsertFunction("fputc",
386                               B.getInt32Ty(),
387                               B.getInt32Ty(),
388                               File->getType(), NULL);
389  Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
390                         "chari");
391  CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
392
393  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
394    CI->setCallingConv(Fn->getCallingConv());
395  return CI;
396}
397
398/// EmitFPutS - Emit a call to the puts function.  Str is required to be a
399/// pointer and File is a pointer to FILE.
400Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
401                       const DataLayout *TD, const TargetLibraryInfo *TLI) {
402  if (!TLI->has(LibFunc::fputs))
403    return 0;
404
405  Module *M = B.GetInsertBlock()->getParent()->getParent();
406  AttributeWithIndex AWI[3];
407  AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture);
408  AWI[1] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture);
409  AWI[2] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
410                                   Attributes::NoUnwind);
411  StringRef FPutsName = TLI->getName(LibFunc::fputs);
412  Constant *F;
413  if (File->getType()->isPointerTy())
414    F = M->getOrInsertFunction(FPutsName,
415                               AttrListPtr::get(M->getContext(), AWI),
416                               B.getInt32Ty(),
417                               B.getInt8PtrTy(),
418                               File->getType(), NULL);
419  else
420    F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
421                               B.getInt8PtrTy(),
422                               File->getType(), NULL);
423  CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
424
425  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
426    CI->setCallingConv(Fn->getCallingConv());
427  return CI;
428}
429
430/// EmitFWrite - Emit a call to the fwrite function.  This assumes that Ptr is
431/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
432Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
433                        IRBuilder<> &B, const DataLayout *TD,
434                        const TargetLibraryInfo *TLI) {
435  if (!TLI->has(LibFunc::fwrite))
436    return 0;
437
438  Module *M = B.GetInsertBlock()->getParent()->getParent();
439  AttributeWithIndex AWI[3];
440  AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture);
441  AWI[1] = AttributeWithIndex::get(M->getContext(), 4, Attributes::NoCapture);
442  AWI[2] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
443                                   Attributes::NoUnwind);
444  LLVMContext &Context = B.GetInsertBlock()->getContext();
445  StringRef FWriteName = TLI->getName(LibFunc::fwrite);
446  Constant *F;
447  if (File->getType()->isPointerTy())
448    F = M->getOrInsertFunction(FWriteName,
449                               AttrListPtr::get(M->getContext(), AWI),
450                               TD->getIntPtrType(Context),
451                               B.getInt8PtrTy(),
452                               TD->getIntPtrType(Context),
453                               TD->getIntPtrType(Context),
454                               File->getType(), NULL);
455  else
456    F = M->getOrInsertFunction(FWriteName, TD->getIntPtrType(Context),
457                               B.getInt8PtrTy(),
458                               TD->getIntPtrType(Context),
459                               TD->getIntPtrType(Context),
460                               File->getType(), NULL);
461  CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
462                        ConstantInt::get(TD->getIntPtrType(Context), 1), File);
463
464  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
465    CI->setCallingConv(Fn->getCallingConv());
466  return CI;
467}
468
469SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
470
471bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const DataLayout *TD,
472                                     const TargetLibraryInfo *TLI) {
473  // We really need DataLayout for later.
474  if (!TD) return false;
475
476  this->CI = CI;
477  Function *Callee = CI->getCalledFunction();
478  StringRef Name = Callee->getName();
479  FunctionType *FT = Callee->getFunctionType();
480  LLVMContext &Context = CI->getParent()->getContext();
481  IRBuilder<> B(CI);
482
483  if (Name == "__memcpy_chk") {
484    // Check if this has the right signature.
485    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
486        !FT->getParamType(0)->isPointerTy() ||
487        !FT->getParamType(1)->isPointerTy() ||
488        FT->getParamType(2) != TD->getIntPtrType(Context) ||
489        FT->getParamType(3) != TD->getIntPtrType(Context))
490      return false;
491
492    if (isFoldable(3, 2, false)) {
493      B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
494                     CI->getArgOperand(2), 1);
495      replaceCall(CI->getArgOperand(0));
496      return true;
497    }
498    return false;
499  }
500
501  // Should be similar to memcpy.
502  if (Name == "__mempcpy_chk") {
503    return false;
504  }
505
506  if (Name == "__memmove_chk") {
507    // Check if this has the right signature.
508    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
509        !FT->getParamType(0)->isPointerTy() ||
510        !FT->getParamType(1)->isPointerTy() ||
511        FT->getParamType(2) != TD->getIntPtrType(Context) ||
512        FT->getParamType(3) != TD->getIntPtrType(Context))
513      return false;
514
515    if (isFoldable(3, 2, false)) {
516      B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
517                      CI->getArgOperand(2), 1);
518      replaceCall(CI->getArgOperand(0));
519      return true;
520    }
521    return false;
522  }
523
524  if (Name == "__memset_chk") {
525    // Check if this has the right signature.
526    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
527        !FT->getParamType(0)->isPointerTy() ||
528        !FT->getParamType(1)->isIntegerTy() ||
529        FT->getParamType(2) != TD->getIntPtrType(Context) ||
530        FT->getParamType(3) != TD->getIntPtrType(Context))
531      return false;
532
533    if (isFoldable(3, 2, false)) {
534      Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
535                                   false);
536      B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
537      replaceCall(CI->getArgOperand(0));
538      return true;
539    }
540    return false;
541  }
542
543  if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") {
544    // Check if this has the right signature.
545    if (FT->getNumParams() != 3 ||
546        FT->getReturnType() != FT->getParamType(0) ||
547        FT->getParamType(0) != FT->getParamType(1) ||
548        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
549        FT->getParamType(2) != TD->getIntPtrType(Context))
550      return 0;
551
552
553    // If a) we don't have any length information, or b) we know this will
554    // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our
555    // st[rp]cpy_chk call which may fail at runtime if the size is too long.
556    // TODO: It might be nice to get a maximum length out of the possible
557    // string lengths for varying.
558    if (isFoldable(2, 1, true)) {
559      Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD,
560                              TLI, Name.substr(2, 6));
561      if (!Ret)
562        return false;
563      replaceCall(Ret);
564      return true;
565    }
566    return false;
567  }
568
569  if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") {
570    // Check if this has the right signature.
571    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
572        FT->getParamType(0) != FT->getParamType(1) ||
573        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
574        !FT->getParamType(2)->isIntegerTy() ||
575        FT->getParamType(3) != TD->getIntPtrType(Context))
576      return false;
577
578    if (isFoldable(3, 2, false)) {
579      Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
580                               CI->getArgOperand(2), B, TD, TLI,
581                               Name.substr(2, 7));
582      if (!Ret)
583        return false;
584      replaceCall(Ret);
585      return true;
586    }
587    return false;
588  }
589
590  if (Name == "__strcat_chk") {
591    return false;
592  }
593
594  if (Name == "__strncat_chk") {
595    return false;
596  }
597
598  return false;
599}
600