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