1b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
2b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher//
3b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher//                     The LLVM Compiler Infrastructure
4b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher//
5b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher// This file is distributed under the University of Illinois Open Source
6b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher// License. See LICENSE.TXT for details.
7b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher//
8b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher//===----------------------------------------------------------------------===//
9b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher//
10b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher// This file implements some functions that will create standard C libcalls.
11b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher//
12b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher//===----------------------------------------------------------------------===//
13b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
14b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher#include "llvm/Transforms/Utils/BuildLibCalls.h"
15b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher#include "llvm/Type.h"
16b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher#include "llvm/Constants.h"
17b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher#include "llvm/Function.h"
18b5ccb25bc229f096e8bc88d2233cd96af1552eeaBenjamin Kramer#include "llvm/Intrinsics.h"
19b5ccb25bc229f096e8bc88d2233cd96af1552eeaBenjamin Kramer#include "llvm/LLVMContext.h"
20b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher#include "llvm/Module.h"
21b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher#include "llvm/Support/IRBuilder.h"
22b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher#include "llvm/Target/TargetData.h"
239d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman#include "llvm/Target/TargetLibraryInfo.h"
249d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman#include "llvm/LLVMContext.h"
259d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman#include "llvm/Intrinsics.h"
26b5ccb25bc229f096e8bc88d2233cd96af1552eeaBenjamin Kramer#include "llvm/ADT/SmallString.h"
27b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
28b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopherusing namespace llvm;
29b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
30b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
31b6174e3605a184df0e403d6502df1ed57cf34352Eric ChristopherValue *llvm::CastToCStr(Value *V, IRBuilder<> &B) {
32b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr");
33b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
34b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
35b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitStrLen - Emit a call to the strlen function to the builder, for the
36b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// specified pointer.  This always returns an integer value of size intptr_t.
37b6174e3605a184df0e403d6502df1ed57cf34352Eric ChristopherValue *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD) {
38b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
39b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AttributeWithIndex AWI[2];
40b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
41b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
42b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                   Attribute::NoUnwind);
43b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
44b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  LLVMContext &Context = B.GetInsertBlock()->getContext();
45b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Constant *StrLen = M->getOrInsertFunction("strlen", AttrListPtr::get(AWI, 2),
46b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                            TD->getIntPtrType(Context),
47b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                            B.getInt8PtrTy(),
48b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                            NULL);
49b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
50b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
51b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(F->getCallingConv());
52b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
53b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  return CI;
54b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
55b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
56b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitStrChr - Emit a call to the strchr function to the builder, for the
57b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// specified pointer and character.  Ptr is required to be some pointer type,
58b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// and the return value has 'i8*' type.
59b6174e3605a184df0e403d6502df1ed57cf34352Eric ChristopherValue *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
60b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                        const TargetData *TD) {
61b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
62b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AttributeWithIndex AWI =
63b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
64b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
65db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *I8Ptr = B.getInt8PtrTy();
66db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *I32Ty = B.getInt32Ty();
67b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(&AWI, 1),
68b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                            I8Ptr, I8Ptr, I32Ty, NULL);
69b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
70b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               ConstantInt::get(I32Ty, C), "strchr");
71b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
72b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(F->getCallingConv());
73b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  return CI;
74b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
75b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
76386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
77386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin KramerValue *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
78386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer                         IRBuilder<> &B, const TargetData *TD) {
79386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer  Module *M = B.GetInsertBlock()->getParent()->getParent();
80386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer  AttributeWithIndex AWI[3];
81386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
82386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer  AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
83386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer  AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
84386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer                                   Attribute::NoUnwind);
85386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer
86386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer  LLVMContext &Context = B.GetInsertBlock()->getContext();
87386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer  Value *StrNCmp = M->getOrInsertFunction("strncmp", AttrListPtr::get(AWI, 3),
88386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer                                          B.getInt32Ty(),
89386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer                                          B.getInt8PtrTy(),
90386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer                                          B.getInt8PtrTy(),
91386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer                                          TD->getIntPtrType(Context), NULL);
92386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer  CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B),
93386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer                               CastToCStr(Ptr2, B), Len, "strncmp");
94386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer
95386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer  if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
96386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer    CI->setCallingConv(F->getCallingConv());
97386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer
98386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer  return CI;
99386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer}
100386e918438b72620e7c00ee1197bf6940bfe6cf8Benjamin Kramer
101b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
102b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// specified pointer arguments.
103b6174e3605a184df0e403d6502df1ed57cf34352Eric ChristopherValue *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
1047fa30b8e5d2774867787a4e4db17bf27358e5aacBenjamin Kramer                        const TargetData *TD, StringRef Name) {
105b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
106b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AttributeWithIndex AWI[2];
107b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
108b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
109db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *I8Ptr = B.getInt8PtrTy();
1107fa30b8e5d2774867787a4e4db17bf27358e5aacBenjamin Kramer  Value *StrCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI, 2),
111b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         I8Ptr, I8Ptr, I8Ptr, NULL);
112b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
1137fa30b8e5d2774867787a4e4db17bf27358e5aacBenjamin Kramer                               Name);
114b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
115b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(F->getCallingConv());
116b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  return CI;
117b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
118b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
119b0722af7985044696da45d29cc04d4b533f08c03Eric Christopher/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
120bd973762003329c217eec2439071e9f93af3eea5Eric Christopher/// specified pointer arguments.
121bd973762003329c217eec2439071e9f93af3eea5Eric ChristopherValue *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
12271988f1e5bb400d83c622dbec0de2bd7287f078bEric Christopher                         IRBuilder<> &B, const TargetData *TD, StringRef Name) {
123bd973762003329c217eec2439071e9f93af3eea5Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
124bd973762003329c217eec2439071e9f93af3eea5Eric Christopher  AttributeWithIndex AWI[2];
125bd973762003329c217eec2439071e9f93af3eea5Eric Christopher  AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
126bd973762003329c217eec2439071e9f93af3eea5Eric Christopher  AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
127db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *I8Ptr = B.getInt8PtrTy();
12871988f1e5bb400d83c622dbec0de2bd7287f078bEric Christopher  Value *StrNCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI, 2),
12971988f1e5bb400d83c622dbec0de2bd7287f078bEric Christopher                                          I8Ptr, I8Ptr, I8Ptr,
13071988f1e5bb400d83c622dbec0de2bd7287f078bEric Christopher                                          Len->getType(), NULL);
131bd973762003329c217eec2439071e9f93af3eea5Eric Christopher  CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
132bd973762003329c217eec2439071e9f93af3eea5Eric Christopher                               Len, "strncpy");
133bd973762003329c217eec2439071e9f93af3eea5Eric Christopher  if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
134bd973762003329c217eec2439071e9f93af3eea5Eric Christopher    CI->setCallingConv(F->getCallingConv());
135bd973762003329c217eec2439071e9f93af3eea5Eric Christopher  return CI;
136bd973762003329c217eec2439071e9f93af3eea5Eric Christopher}
137bd973762003329c217eec2439071e9f93af3eea5Eric Christopher
1380289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
1390289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
1400289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng/// are pointers.
1410289b419a492c207f2aaaa481c632cdcf33db5f3Evan ChengValue *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
1420289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng                           IRBuilder<> &B, const TargetData *TD) {
1430289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng  Module *M = B.GetInsertBlock()->getParent()->getParent();
1440289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng  AttributeWithIndex AWI;
1450289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng  AWI = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
1460289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng  LLVMContext &Context = B.GetInsertBlock()->getContext();
1470289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng  Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
1480289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng                                         AttrListPtr::get(&AWI, 1),
1490289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng                                         B.getInt8PtrTy(),
1500289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng                                         B.getInt8PtrTy(),
1510289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng                                         B.getInt8PtrTy(),
1520289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng                                         TD->getIntPtrType(Context),
1530289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng                                         TD->getIntPtrType(Context), NULL);
1540289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng  Dst = CastToCStr(Dst, B);
1550289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng  Src = CastToCStr(Src, B);
1560289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng  CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize);
1570289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng  if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
1580289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng    CI->setCallingConv(F->getCallingConv());
1590289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng  return CI;
1600289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng}
1610289b419a492c207f2aaaa481c632cdcf33db5f3Evan Cheng
162b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitMemChr - Emit a call to the memchr function.  This assumes that Ptr is
163b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
164b6174e3605a184df0e403d6502df1ed57cf34352Eric ChristopherValue *llvm::EmitMemChr(Value *Ptr, Value *Val,
165b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                        Value *Len, IRBuilder<> &B, const TargetData *TD) {
166b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
167b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AttributeWithIndex AWI;
168b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
169b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  LLVMContext &Context = B.GetInsertBlock()->getContext();
170b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(&AWI, 1),
171b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         B.getInt8PtrTy(),
172b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         B.getInt8PtrTy(),
173b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         B.getInt32Ty(),
174b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         TD->getIntPtrType(Context),
175b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         NULL);
176b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
177b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
178b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
179b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(F->getCallingConv());
180b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
181b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  return CI;
182b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
183b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
184b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitMemCmp - Emit a call to the memcmp function.
185b6174e3605a184df0e403d6502df1ed57cf34352Eric ChristopherValue *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
186b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                        Value *Len, IRBuilder<> &B, const TargetData *TD) {
187b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
188b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AttributeWithIndex AWI[3];
189b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
190b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
191b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
192b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                   Attribute::NoUnwind);
193b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
194b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  LLVMContext &Context = B.GetInsertBlock()->getContext();
195b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI, 3),
196b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         B.getInt32Ty(),
197b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         B.getInt8PtrTy(),
198b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         B.getInt8PtrTy(),
199b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         TD->getIntPtrType(Context), NULL);
200b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
201b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               Len, "memcmp");
202b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
203b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
204b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(F->getCallingConv());
205b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
206b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  return CI;
207b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
208b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
209b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
210b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// 'floor').  This function is known to take a single of type matching 'Op' and
211b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// returns one value with the same type.  If 'Op' is a long double, 'l' is
212b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
213b5ccb25bc229f096e8bc88d2233cd96af1552eeaBenjamin KramerValue *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
214b5ccb25bc229f096e8bc88d2233cd96af1552eeaBenjamin Kramer                                  const AttrListPtr &Attrs) {
215b5ccb25bc229f096e8bc88d2233cd96af1552eeaBenjamin Kramer  SmallString<20> NameBuffer;
216b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (!Op->getType()->isDoubleTy()) {
217b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    // If we need to add a suffix, copy into NameBuffer.
218b5ccb25bc229f096e8bc88d2233cd96af1552eeaBenjamin Kramer    NameBuffer += Name;
219b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    if (Op->getType()->isFloatTy())
220b5ccb25bc229f096e8bc88d2233cd96af1552eeaBenjamin Kramer      NameBuffer += 'f'; // floorf
221b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    else
222b5ccb25bc229f096e8bc88d2233cd96af1552eeaBenjamin Kramer      NameBuffer += 'l'; // floorl
223b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    Name = NameBuffer;
224b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  }
225b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
226b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
227b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
228b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                         Op->getType(), NULL);
229b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall(Callee, Op, Name);
230b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CI->setAttributes(Attrs);
231b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
232b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(F->getCallingConv());
233b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
234b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  return CI;
235b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
236b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
237b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitPutChar - Emit a call to the putchar function.  This assumes that Char
238b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// is an integer.
239b6174e3605a184df0e403d6502df1ed57cf34352Eric ChristopherValue *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD) {
240b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
241b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
242b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                          B.getInt32Ty(), NULL);
243b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall(PutChar,
244b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                              B.CreateIntCast(Char,
245b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                              B.getInt32Ty(),
246b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                              /*isSigned*/true,
247b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                              "chari"),
248b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                              "putchar");
249b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
250b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
251b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(F->getCallingConv());
252b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  return CI;
253b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
254b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
255b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitPutS - Emit a call to the puts function.  This assumes that Str is
256b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// some pointer.
257b6174e3605a184df0e403d6502df1ed57cf34352Eric Christophervoid llvm::EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD) {
258b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
259b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AttributeWithIndex AWI[2];
260b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
261b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
262b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
263b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI, 2),
264b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                       B.getInt32Ty(),
265b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                       B.getInt8PtrTy(),
266b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                                       NULL);
267b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
268b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
269b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(F->getCallingConv());
270b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
271b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
272b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
273b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitFPutC - Emit a call to the fputc function.  This assumes that Char is
274b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// an integer and File is a pointer to FILE.
275b6174e3605a184df0e403d6502df1ed57cf34352Eric Christophervoid llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
276b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                     const TargetData *TD) {
277b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
278b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AttributeWithIndex AWI[2];
279b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
280b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
281b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Constant *F;
282b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (File->getType()->isPointerTy())
283b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2),
284b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               B.getInt32Ty(),
285b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               B.getInt32Ty(), File->getType(),
286b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               NULL);
287b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  else
288b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    F = M->getOrInsertFunction("fputc",
289b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               B.getInt32Ty(),
290b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               B.getInt32Ty(),
291b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               File->getType(), NULL);
292b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
293b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                         "chari");
294b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
295b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
296b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
297b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(Fn->getCallingConv());
298b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
299b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
300b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitFPutS - Emit a call to the puts function.  Str is required to be a
301b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// pointer and File is a pointer to FILE.
302b6174e3605a184df0e403d6502df1ed57cf34352Eric Christophervoid llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
3039d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman                     const TargetData *TD, const TargetLibraryInfo *TLI) {
304b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
305b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AttributeWithIndex AWI[3];
306b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
307b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
308b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
3099d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman  StringRef FPutsName = TLI->getName(LibFunc::fputs);
310b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Constant *F;
311b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (File->getType()->isPointerTy())
3129d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman    F = M->getOrInsertFunction(FPutsName, AttrListPtr::get(AWI, 3),
313b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               B.getInt32Ty(),
314b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               B.getInt8PtrTy(),
315b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               File->getType(), NULL);
316b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  else
3179d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman    F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
318b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               B.getInt8PtrTy(),
319b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               File->getType(), NULL);
320b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
321b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
322b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
323b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(Fn->getCallingConv());
324b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
325b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
326b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// EmitFWrite - Emit a call to the fwrite function.  This assumes that Ptr is
327b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
328b6174e3605a184df0e403d6502df1ed57cf34352Eric Christophervoid llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
3299d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman                      IRBuilder<> &B, const TargetData *TD,
3309d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman                      const TargetLibraryInfo *TLI) {
331b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Module *M = B.GetInsertBlock()->getParent()->getParent();
332b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AttributeWithIndex AWI[3];
333b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
334b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture);
335b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
336b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  LLVMContext &Context = B.GetInsertBlock()->getContext();
3379d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman  StringRef FWriteName = TLI->getName(LibFunc::fwrite);
338b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  Constant *F;
339b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (File->getType()->isPointerTy())
3409d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman    F = M->getOrInsertFunction(FWriteName, AttrListPtr::get(AWI, 3),
341b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               TD->getIntPtrType(Context),
342b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               B.getInt8PtrTy(),
343b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               TD->getIntPtrType(Context),
344b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               TD->getIntPtrType(Context),
345b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               File->getType(), NULL);
346b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  else
3479d434dbff3eb0501efc3457acec2401afdffef2fEli Friedman    F = M->getOrInsertFunction(FWriteName, TD->getIntPtrType(Context),
348b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               B.getInt8PtrTy(),
349b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               TD->getIntPtrType(Context),
350b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               TD->getIntPtrType(Context),
351b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                               File->getType(), NULL);
352b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
353b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher                        ConstantInt::get(TD->getIntPtrType(Context), 1), File);
354b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher
355b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher  if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
356b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher    CI->setCallingConv(Fn->getCallingConv());
357b6174e3605a184df0e403d6502df1ed57cf34352Eric Christopher}
3580b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer
359a30b181c20710f0b3c511b7119c2d37859e0158dBenjamin KramerSimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
360a30b181c20710f0b3c511b7119c2d37859e0158dBenjamin Kramer
3610b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramerbool SimplifyFortifiedLibCalls::fold(CallInst *CI, const TargetData *TD) {
36267a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher  // We really need TargetData for later.
36367a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher  if (!TD) return false;
36467a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher
3650b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  this->CI = CI;
36667a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher  Function *Callee = CI->getCalledFunction();
36767a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher  StringRef Name = Callee->getName();
368db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FT = Callee->getFunctionType();
36967a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher  LLVMContext &Context = CI->getParent()->getContext();
3701a24bf0cf92fa801fa9399b017485be15621c031Eli Friedman  IRBuilder<> B(CI);
3710b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer
3720b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  if (Name == "__memcpy_chk") {
37367a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher    // Check if this has the right signature.
37467a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
37567a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        !FT->getParamType(0)->isPointerTy() ||
37667a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        !FT->getParamType(1)->isPointerTy() ||
37767a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(2) != TD->getIntPtrType(Context) ||
37867a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(3) != TD->getIntPtrType(Context))
37967a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher      return false;
380f148cb6044b292234109938e0a3802fc2d637e84Gabor Greif
381a6aac4c5bc22bb10c7adb11eee3f82c703af7002Gabor Greif    if (isFoldable(3, 2, false)) {
382def548f9a0efa6e997a68ac2d77cb0ef574b7d43Benjamin Kramer      B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
383def548f9a0efa6e997a68ac2d77cb0ef574b7d43Benjamin Kramer                     CI->getArgOperand(2), 1);
384f148cb6044b292234109938e0a3802fc2d637e84Gabor Greif      replaceCall(CI->getArgOperand(0));
3850b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer      return true;
3860b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    }
3870b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    return false;
3880b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  }
3890b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer
3900b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  // Should be similar to memcpy.
3910b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  if (Name == "__mempcpy_chk") {
3920b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    return false;
3930b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  }
3940b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer
3950b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  if (Name == "__memmove_chk") {
39667a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher    // Check if this has the right signature.
39767a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
39867a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        !FT->getParamType(0)->isPointerTy() ||
39967a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        !FT->getParamType(1)->isPointerTy() ||
40067a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(2) != TD->getIntPtrType(Context) ||
40167a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(3) != TD->getIntPtrType(Context))
40267a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher      return false;
403f148cb6044b292234109938e0a3802fc2d637e84Gabor Greif
404a6aac4c5bc22bb10c7adb11eee3f82c703af7002Gabor Greif    if (isFoldable(3, 2, false)) {
405def548f9a0efa6e997a68ac2d77cb0ef574b7d43Benjamin Kramer      B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
406def548f9a0efa6e997a68ac2d77cb0ef574b7d43Benjamin Kramer                      CI->getArgOperand(2), 1);
407f148cb6044b292234109938e0a3802fc2d637e84Gabor Greif      replaceCall(CI->getArgOperand(0));
4080b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer      return true;
4090b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    }
4100b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    return false;
4110b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  }
4120b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer
4130b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  if (Name == "__memset_chk") {
41467a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher    // Check if this has the right signature.
41567a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
41667a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        !FT->getParamType(0)->isPointerTy() ||
41767a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        !FT->getParamType(1)->isIntegerTy() ||
41867a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(2) != TD->getIntPtrType(Context) ||
41967a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(3) != TD->getIntPtrType(Context))
42067a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher      return false;
421f148cb6044b292234109938e0a3802fc2d637e84Gabor Greif
422a6aac4c5bc22bb10c7adb11eee3f82c703af7002Gabor Greif    if (isFoldable(3, 2, false)) {
423f148cb6044b292234109938e0a3802fc2d637e84Gabor Greif      Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
4240b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer                                   false);
425def548f9a0efa6e997a68ac2d77cb0ef574b7d43Benjamin Kramer      B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
426f1ba6513bf8e6ee9ef6d213ffda1b79b53c2b06aGabor Greif      replaceCall(CI->getArgOperand(0));
4270b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer      return true;
4280b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    }
4290b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    return false;
4300b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  }
4310b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer
4320b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") {
43367a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher    // Check if this has the right signature.
43467a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher    if (FT->getNumParams() != 3 ||
43567a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getReturnType() != FT->getParamType(0) ||
43667a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(0) != FT->getParamType(1) ||
43767a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
43867a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(2) != TD->getIntPtrType(Context))
43967a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher      return 0;
44067a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher
44167a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher
4420b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    // If a) we don't have any length information, or b) we know this will
4430b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our
4440b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    // st[rp]cpy_chk call which may fail at runtime if the size is too long.
4450b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    // TODO: It might be nice to get a maximum length out of the possible
4460b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    // string lengths for varying.
447a6aac4c5bc22bb10c7adb11eee3f82c703af7002Gabor Greif    if (isFoldable(2, 1, true)) {
448f148cb6044b292234109938e0a3802fc2d637e84Gabor Greif      Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD,
4490b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer                              Name.substr(2, 6));
4500b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer      replaceCall(Ret);
4510b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer      return true;
4520b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    }
4530b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    return false;
4540b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  }
4550b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer
45671988f1e5bb400d83c622dbec0de2bd7287f078bEric Christopher  if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") {
45767a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher    // Check if this has the right signature.
45867a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher    if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
45967a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(0) != FT->getParamType(1) ||
46067a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
46167a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        !FT->getParamType(2)->isIntegerTy() ||
46267a71b5306c42f1d56a0d58635432b86206c2a9aEric Christopher        FT->getParamType(3) != TD->getIntPtrType(Context))
4632a7cb9d9ce020068c3cc6c86f8fd2532b148c6f5Eric Christopher      return false;
464f148cb6044b292234109938e0a3802fc2d637e84Gabor Greif
465a6aac4c5bc22bb10c7adb11eee3f82c703af7002Gabor Greif    if (isFoldable(3, 2, false)) {
466f148cb6044b292234109938e0a3802fc2d637e84Gabor Greif      Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
467f148cb6044b292234109938e0a3802fc2d637e84Gabor Greif                               CI->getArgOperand(2), B, TD, Name.substr(2, 7));
4680b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer      replaceCall(Ret);
4690b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer      return true;
4700b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    }
4710b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    return false;
4720b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  }
4730b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer
4740b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  if (Name == "__strcat_chk") {
4750b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    return false;
4760b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  }
4770b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer
4780b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  if (Name == "__strncat_chk") {
4790b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer    return false;
4800b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  }
4810b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer
4820b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer  return false;
4830b6cb507385c8bd10b6a51b5e45a9b99d8d94798Benjamin Kramer}
484