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