Home | History | Annotate | Download | only in Utils
      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 }
    568