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