Rename the 'Attributes' class to 'Attribute'. It's going to represent a single attrib...
[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/ADT/SmallString.h"
16 #include "llvm/Constants.h"
17 #include "llvm/DataLayout.h"
18 #include "llvm/Function.h"
19 #include "llvm/IRBuilder.h"
20 #include "llvm/Intrinsics.h"
21 #include "llvm/Intrinsics.h"
22 #include "llvm/LLVMContext.h"
23 #include "llvm/LLVMContext.h"
24 #include "llvm/Module.h"
25 #include "llvm/Target/TargetLibraryInfo.h"
26 #include "llvm/Type.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, Attribute::NoCapture);
45   Attribute::AttrVal AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
46   AWI[1] = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
47                                    ArrayRef<Attribute::AttrVal>(AVs, 2));
48
49   LLVMContext &Context = B.GetInsertBlock()->getContext();
50   Constant *StrLen = M->getOrInsertFunction("strlen",
51                                             AttributeSet::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.
66 Value *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, Attribute::NoCapture);
74   Attribute::AttrVal AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
75   AWI[1] = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
76                                    ArrayRef<Attribute::AttrVal>(AVs, 2));
77
78   LLVMContext &Context = B.GetInsertBlock()->getContext();
79   Constant *StrNLen = M->getOrInsertFunction("strnlen",
80                                              AttributeSet::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.
96 Value *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   Attribute::AttrVal AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
103   AttributeWithIndex AWI =
104     AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
105                             ArrayRef<Attribute::AttrVal>(AVs, 2));
106
107   Type *I8Ptr = B.getInt8PtrTy();
108   Type *I32Ty = B.getInt32Ty();
109   Constant *StrChr = M->getOrInsertFunction("strchr",
110                                             AttributeSet::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.
121 Value *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, Attribute::NoCapture);
130   AWI[1] = AttributeWithIndex::get(M->getContext(), 2, Attribute::NoCapture);
131   Attribute::AttrVal AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
132   AWI[2] = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
133                                    ArrayRef<Attribute::AttrVal>(AVs, 2));
134
135   LLVMContext &Context = B.GetInsertBlock()->getContext();
136   Value *StrNCmp = M->getOrInsertFunction("strncmp",
137                                           AttributeSet::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.
154 Value *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, Attribute::NoCapture);
163   AWI[1] = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
164                                    Attribute::NoUnwind);
165   Type *I8Ptr = B.getInt8PtrTy();
166   Value *StrCpy = M->getOrInsertFunction(Name,
167                                          AttributeSet::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.
178 Value *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, Attribute::NoCapture);
187   AWI[1] = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
188                                    Attribute::NoUnwind);
189   Type *I8Ptr = B.getInt8PtrTy();
190   Value *StrNCpy = M->getOrInsertFunction(Name,
191                                           AttributeSet::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.
205 Value *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(), AttributeSet::FunctionIndex,
214                                 Attribute::NoUnwind);
215   LLVMContext &Context = B.GetInsertBlock()->getContext();
216   Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
217                                          AttributeSet::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.
233 Value *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   Attribute::AttrVal AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
242   AWI = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
243                                 ArrayRef<Attribute::AttrVal>(AVs, 2));
244   LLVMContext &Context = B.GetInsertBlock()->getContext();
245   Value *MemChr = M->getOrInsertFunction("memchr",
246                                          AttributeSet::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.
261 Value *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, Attribute::NoCapture);
270   AWI[1] = AttributeWithIndex::get(M->getContext(), 2, Attribute::NoCapture);
271   Attribute::AttrVal AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
272   AWI[2] = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
273                                    ArrayRef<Attribute::AttrVal>(AVs, 2));
274
275   LLVMContext &Context = B.GetInsertBlock()->getContext();
276   Value *MemCmp = M->getOrInsertFunction("memcmp",
277                                          AttributeSet::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.
295 Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
296                                   const AttributeSet &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.
321 Value *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.
343 Value *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, Attribute::NoCapture);
351   AWI[1] = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
352                                    Attribute::NoUnwind);
353
354   Value *PutS = M->getOrInsertFunction("puts",
355                                        AttributeSet::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.
367 Value *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, Attribute::NoCapture);
375   AWI[1] = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
376                                    Attribute::NoUnwind);
377   Constant *F;
378   if (File->getType()->isPointerTy())
379     F = M->getOrInsertFunction("fputc",
380                                AttributeSet::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.
400 Value *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, Attribute::NoCapture);
408   AWI[1] = AttributeWithIndex::get(M->getContext(), 2, Attribute::NoCapture);
409   AWI[2] = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
410                                    Attribute::NoUnwind);
411   StringRef FPutsName = TLI->getName(LibFunc::fputs);
412   Constant *F;
413   if (File->getType()->isPointerTy())
414     F = M->getOrInsertFunction(FPutsName,
415                                AttributeSet::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.
432 Value *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, Attribute::NoCapture);
441   AWI[1] = AttributeWithIndex::get(M->getContext(), 4, Attribute::NoCapture);
442   AWI[2] = AttributeWithIndex::get(M->getContext(), AttributeSet::FunctionIndex,
443                                    Attribute::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                                AttributeSet::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
469 SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
470
471 bool 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 }