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