For functions with ARM target specific calling convention, when simplify-libcall
[oota-llvm.git] / lib / Transforms / Utils / BuildLibCalls.cpp
1 //===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements some functions that will create standard C libcalls.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Transforms/Utils/BuildLibCalls.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/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   return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr");
31 }
32
33 /// EmitStrLen - Emit a call to the strlen function to the builder, for the
34 /// specified pointer.  This always returns an integer value of size intptr_t.
35 Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
36                         const TargetLibraryInfo *TLI) {
37   if (!TLI->has(LibFunc::strlen))
38     return 0;
39
40   Function *CallerF = B.GetInsertBlock()->getParent();
41   Module *M = CallerF->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 (Function *F = dyn_cast<Function>(StrLen->stripPointerCasts())) {
57     CallingConv::ID CC = F->getCallingConv();
58     CallingConv::ID CallerCC = CallerF->getCallingConv();
59     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
60       // If caller is using ARM target specific CC such as AAPCS-VFP,
61       // make sure the call uses it or it would introduce a calling
62       // convention mismatch.
63       CI->setCallingConv(CallerCC);
64       F->setCallingConv(CallerCC);
65     } else
66       CI->setCallingConv(CC);
67   }
68
69   return CI;
70 }
71
72 /// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
73 /// specified pointer.  Ptr is required to be some pointer type, MaxLen must
74 /// be of size_t type, and the return value has 'intptr_t' type.
75 Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
76                          const DataLayout *TD, const TargetLibraryInfo *TLI) {
77   if (!TLI->has(LibFunc::strnlen))
78     return 0;
79
80   Function *CallerF = B.GetInsertBlock()->getParent();
81   Module *M = CallerF->getParent();
82   AttributeSet AS[2];
83   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
84   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
85   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
86                             ArrayRef<Attribute::AttrKind>(AVs, 2));
87
88   LLVMContext &Context = B.GetInsertBlock()->getContext();
89   Constant *StrNLen = M->getOrInsertFunction("strnlen",
90                                              AttributeSet::get(M->getContext(),
91                                                               AS),
92                                              TD->getIntPtrType(Context),
93                                              B.getInt8PtrTy(),
94                                              TD->getIntPtrType(Context),
95                                              NULL);
96   CallInst *CI = B.CreateCall2(StrNLen, CastToCStr(Ptr, B), MaxLen, "strnlen");
97   if (Function *F = dyn_cast<Function>(StrNLen->stripPointerCasts())) {
98     CallingConv::ID CC = F->getCallingConv();
99     CallingConv::ID CallerCC = CallerF->getCallingConv();
100     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
101       // If caller is using ARM target specific CC such as AAPCS-VFP,
102       // make sure the call uses it or it would introduce a calling
103       // convention mismatch.
104       CI->setCallingConv(CallerCC);
105       F->setCallingConv(CallerCC);
106     } else
107       CI->setCallingConv(CC);
108   }
109
110   return CI;
111 }
112
113 /// EmitStrChr - Emit a call to the strchr function to the builder, for the
114 /// specified pointer and character.  Ptr is required to be some pointer type,
115 /// and the return value has 'i8*' type.
116 Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
117                         const DataLayout *TD, const TargetLibraryInfo *TLI) {
118   if (!TLI->has(LibFunc::strchr))
119     return 0;
120
121   Function *CallerF = B.GetInsertBlock()->getParent();
122   Module *M = CallerF->getParent();
123   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
124   AttributeSet AS =
125     AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
126                       ArrayRef<Attribute::AttrKind>(AVs, 2));
127
128   Type *I8Ptr = B.getInt8PtrTy();
129   Type *I32Ty = B.getInt32Ty();
130   Constant *StrChr = M->getOrInsertFunction("strchr",
131                                             AttributeSet::get(M->getContext(),
132                                                              AS),
133                                             I8Ptr, I8Ptr, I32Ty, NULL);
134   CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
135                                ConstantInt::get(I32Ty, C), "strchr");
136   if (Function *F = dyn_cast<Function>(StrChr->stripPointerCasts())) {
137     CallingConv::ID CC = F->getCallingConv();
138     CallingConv::ID CallerCC = CallerF->getCallingConv();
139     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
140       // If caller is using ARM target specific CC such as AAPCS-VFP,
141       // make sure the call uses it or it would introduce a calling
142       // convention mismatch.
143       CI->setCallingConv(CallerCC);
144       F->setCallingConv(CallerCC);
145     } else
146       CI->setCallingConv(CC);
147   }
148
149   return CI;
150 }
151
152 /// EmitStrNCmp - Emit a call to the strncmp function to the builder.
153 Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
154                          IRBuilder<> &B, const DataLayout *TD,
155                          const TargetLibraryInfo *TLI) {
156   if (!TLI->has(LibFunc::strncmp))
157     return 0;
158
159   Function *CallerF = B.GetInsertBlock()->getParent();
160   Module *M = CallerF->getParent();
161   AttributeSet AS[3];
162   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
163   AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
164   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
165   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
166                             ArrayRef<Attribute::AttrKind>(AVs, 2));
167
168   LLVMContext &Context = B.GetInsertBlock()->getContext();
169   Value *StrNCmp = M->getOrInsertFunction("strncmp",
170                                           AttributeSet::get(M->getContext(),
171                                                            AS),
172                                           B.getInt32Ty(),
173                                           B.getInt8PtrTy(),
174                                           B.getInt8PtrTy(),
175                                           TD->getIntPtrType(Context), NULL);
176   CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B),
177                                CastToCStr(Ptr2, B), Len, "strncmp");
178
179   if (Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts())) {
180     CallingConv::ID CC = F->getCallingConv();
181     CallingConv::ID CallerCC = CallerF->getCallingConv();
182     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
183       // If caller is using ARM target specific CC such as AAPCS-VFP,
184       // make sure the call uses it or it would introduce a calling
185       // convention mismatch.
186       CI->setCallingConv(CallerCC);
187       F->setCallingConv(CallerCC);
188     } else
189       CI->setCallingConv(CC);
190   }
191
192   return CI;
193 }
194
195 /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
196 /// specified pointer arguments.
197 Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
198                         const DataLayout *TD, const TargetLibraryInfo *TLI,
199                         StringRef Name) {
200   if (!TLI->has(LibFunc::strcpy))
201     return 0;
202
203   Function *CallerF = B.GetInsertBlock()->getParent();
204   Module *M = CallerF->getParent();
205   AttributeSet AS[2];
206   AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
207   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
208                             Attribute::NoUnwind);
209   Type *I8Ptr = B.getInt8PtrTy();
210   Value *StrCpy = M->getOrInsertFunction(Name,
211                                          AttributeSet::get(M->getContext(), AS),
212                                          I8Ptr, I8Ptr, I8Ptr, NULL);
213   CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
214                                Name);
215   if (Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts())) {
216     CallingConv::ID CC = F->getCallingConv();
217     CallingConv::ID CallerCC = CallerF->getCallingConv();
218     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
219       // If caller is using ARM target specific CC such as AAPCS-VFP,
220       // make sure the call uses it or it would introduce a calling
221       // convention mismatch.
222       CI->setCallingConv(CallerCC);
223       F->setCallingConv(CallerCC);
224     } else
225       CI->setCallingConv(CC);
226   }
227
228   return CI;
229 }
230
231 /// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
232 /// specified pointer arguments.
233 Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
234                          IRBuilder<> &B, const DataLayout *TD,
235                          const TargetLibraryInfo *TLI, StringRef Name) {
236   if (!TLI->has(LibFunc::strncpy))
237     return 0;
238
239   Function *CallerF = B.GetInsertBlock()->getParent();
240   Module *M = CallerF->getParent();
241   AttributeSet AS[2];
242   AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
243   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
244                             Attribute::NoUnwind);
245   Type *I8Ptr = B.getInt8PtrTy();
246   Value *StrNCpy = M->getOrInsertFunction(Name,
247                                           AttributeSet::get(M->getContext(),
248                                                             AS),
249                                           I8Ptr, I8Ptr, I8Ptr,
250                                           Len->getType(), NULL);
251   CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
252                                Len, "strncpy");
253   if (Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts())) {
254     CallingConv::ID CC = F->getCallingConv();
255     CallingConv::ID CallerCC = CallerF->getCallingConv();
256     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
257       // If caller is using ARM target specific CC such as AAPCS-VFP,
258       // make sure the call uses it or it would introduce a calling
259       // convention mismatch.
260       CI->setCallingConv(CallerCC);
261       F->setCallingConv(CallerCC);
262     } else
263       CI->setCallingConv(CC);
264   }
265
266   return CI;
267 }
268
269 /// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
270 /// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
271 /// are pointers.
272 Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
273                            IRBuilder<> &B, const DataLayout *TD,
274                            const TargetLibraryInfo *TLI) {
275   if (!TLI->has(LibFunc::memcpy_chk))
276     return 0;
277
278   Function *CallerF = B.GetInsertBlock()->getParent();
279   Module *M = CallerF->getParent();
280   AttributeSet AS;
281   AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
282                          Attribute::NoUnwind);
283   LLVMContext &Context = B.GetInsertBlock()->getContext();
284   Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
285                                          AttributeSet::get(M->getContext(), AS),
286                                          B.getInt8PtrTy(),
287                                          B.getInt8PtrTy(),
288                                          B.getInt8PtrTy(),
289                                          TD->getIntPtrType(Context),
290                                          TD->getIntPtrType(Context), NULL);
291   Dst = CastToCStr(Dst, B);
292   Src = CastToCStr(Src, B);
293   CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize);
294   if (Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts())) {
295     CallingConv::ID CC = F->getCallingConv();
296     CallingConv::ID CallerCC = CallerF->getCallingConv();
297     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
298       // If caller is using ARM target specific CC such as AAPCS-VFP,
299       // make sure the call uses it or it would introduce a calling
300       // convention mismatch.
301       CI->setCallingConv(CallerCC);
302       F->setCallingConv(CallerCC);
303     } else
304       CI->setCallingConv(CC);
305   }
306
307   return CI;
308 }
309
310 /// EmitMemChr - Emit a call to the memchr function.  This assumes that Ptr is
311 /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
312 Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
313                         Value *Len, IRBuilder<> &B, const DataLayout *TD,
314                         const TargetLibraryInfo *TLI) {
315   if (!TLI->has(LibFunc::memchr))
316     return 0;
317
318   Function *CallerF = B.GetInsertBlock()->getParent();
319   Module *M = CallerF->getParent();
320   AttributeSet AS;
321   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
322   AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
323                          ArrayRef<Attribute::AttrKind>(AVs, 2));
324   LLVMContext &Context = B.GetInsertBlock()->getContext();
325   Value *MemChr = M->getOrInsertFunction("memchr",
326                                          AttributeSet::get(M->getContext(), AS),
327                                          B.getInt8PtrTy(),
328                                          B.getInt8PtrTy(),
329                                          B.getInt32Ty(),
330                                          TD->getIntPtrType(Context),
331                                          NULL);
332   CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
333
334   if (Function *F = dyn_cast<Function>(MemChr->stripPointerCasts())) {
335     CallingConv::ID CC = F->getCallingConv();
336     CallingConv::ID CallerCC = CallerF->getCallingConv();
337     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
338       // If caller is using ARM target specific CC such as AAPCS-VFP,
339       // make sure the call uses it or it would introduce a calling
340       // convention mismatch.
341       CI->setCallingConv(CallerCC);
342       F->setCallingConv(CallerCC);
343     } else
344       CI->setCallingConv(CC);
345   }
346
347   return CI;
348 }
349
350 /// EmitMemCmp - Emit a call to the memcmp function.
351 Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
352                         Value *Len, IRBuilder<> &B, const DataLayout *TD,
353                         const TargetLibraryInfo *TLI) {
354   if (!TLI->has(LibFunc::memcmp))
355     return 0;
356
357   Function *CallerF = B.GetInsertBlock()->getParent();
358   Module *M = CallerF->getParent();
359   AttributeSet AS[3];
360   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
361   AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
362   Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
363   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
364                             ArrayRef<Attribute::AttrKind>(AVs, 2));
365
366   LLVMContext &Context = B.GetInsertBlock()->getContext();
367   Value *MemCmp = M->getOrInsertFunction("memcmp",
368                                          AttributeSet::get(M->getContext(), AS),
369                                          B.getInt32Ty(),
370                                          B.getInt8PtrTy(),
371                                          B.getInt8PtrTy(),
372                                          TD->getIntPtrType(Context), NULL);
373   CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
374                                Len, "memcmp");
375
376   if (Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts())) {
377     CallingConv::ID CC = F->getCallingConv();
378     CallingConv::ID CallerCC = CallerF->getCallingConv();
379     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
380       // If caller is using ARM target specific CC such as AAPCS-VFP,
381       // make sure the call uses it or it would introduce a calling
382       // convention mismatch.
383       CI->setCallingConv(CallerCC);
384       F->setCallingConv(CallerCC);
385     } else
386       CI->setCallingConv(CC);
387   }
388
389   return CI;
390 }
391
392 /// Append a suffix to the function name according to the type of 'Op'.
393 static void AppendTypeSuffix(Value *Op, StringRef &Name, SmallString<20> &NameBuffer) {
394   if (!Op->getType()->isDoubleTy()) {
395       NameBuffer += Name;
396
397     if (Op->getType()->isFloatTy())
398       NameBuffer += 'f';
399     else
400       NameBuffer += 'l';
401
402     Name = NameBuffer;
403   }  
404   return;
405 }
406
407 /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
408 /// 'floor').  This function is known to take a single of type matching 'Op' and
409 /// returns one value with the same type.  If 'Op' is a long double, 'l' is
410 /// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
411 Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
412                                   const AttributeSet &Attrs) {
413   SmallString<20> NameBuffer;
414   AppendTypeSuffix(Op, Name, NameBuffer);   
415
416   Function *CallerF = B.GetInsertBlock()->getParent();
417   Module *M = CallerF->getParent();
418   Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
419                                          Op->getType(), NULL);
420   CallInst *CI = B.CreateCall(Callee, Op, Name);
421   CI->setAttributes(Attrs);
422   if (Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) {
423     CallingConv::ID CC = F->getCallingConv();
424     CallingConv::ID CallerCC = CallerF->getCallingConv();
425     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
426       // If caller is using ARM target specific CC such as AAPCS-VFP,
427       // make sure the call uses it or it would introduce a calling
428       // convention mismatch.
429       CI->setCallingConv(CallerCC);
430       F->setCallingConv(CallerCC);
431     } else
432       CI->setCallingConv(CC);
433   }
434
435   return CI;
436 }
437
438 /// EmitBinaryFloatFnCall - Emit a call to the binary function named 'Name'
439 /// (e.g. 'fmin').  This function is known to take type matching 'Op1' and 'Op2'
440 /// and return one value with the same type.  If 'Op1/Op2' are long double, 'l'
441 /// is added as the suffix of name, if 'Op1/Op2' is a float, we add a 'f'
442 /// suffix.
443 Value *llvm::EmitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
444                                   IRBuilder<> &B, const AttributeSet &Attrs) {
445   SmallString<20> NameBuffer;
446   AppendTypeSuffix(Op1, Name, NameBuffer);   
447
448   Function *CallerF = B.GetInsertBlock()->getParent();
449   Module *M = CallerF->getParent();
450   Value *Callee = M->getOrInsertFunction(Name, Op1->getType(),
451                                          Op1->getType(), Op2->getType(), NULL);
452   CallInst *CI = B.CreateCall2(Callee, Op1, Op2, Name);
453   CI->setAttributes(Attrs);
454   if (Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) {
455     CallingConv::ID CC = F->getCallingConv();
456     CallingConv::ID CallerCC = CallerF->getCallingConv();
457     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
458       // If caller is using ARM target specific CC such as AAPCS-VFP,
459       // make sure the call uses it or it would introduce a calling
460       // convention mismatch.
461       CI->setCallingConv(CallerCC);
462       F->setCallingConv(CallerCC);
463     } else
464       CI->setCallingConv(CC);
465   }
466
467   return CI;
468 }
469
470 /// EmitPutChar - Emit a call to the putchar function.  This assumes that Char
471 /// is an integer.
472 Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
473                          const TargetLibraryInfo *TLI) {
474   if (!TLI->has(LibFunc::putchar))
475     return 0;
476
477   Function *CallerF = B.GetInsertBlock()->getParent();
478   Module *M = CallerF->getParent();
479   Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
480                                           B.getInt32Ty(), NULL);
481   CallInst *CI = B.CreateCall(PutChar,
482                               B.CreateIntCast(Char,
483                               B.getInt32Ty(),
484                               /*isSigned*/true,
485                               "chari"),
486                               "putchar");
487
488   if (Function *F = dyn_cast<Function>(PutChar->stripPointerCasts())) {
489     CallingConv::ID CC = F->getCallingConv();
490     CallingConv::ID CallerCC = CallerF->getCallingConv();
491     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
492       // If caller is using ARM target specific CC such as AAPCS-VFP,
493       // make sure the call uses it or it would introduce a calling
494       // convention mismatch.
495       CI->setCallingConv(CallerCC);
496       F->setCallingConv(CallerCC);
497     } else
498       CI->setCallingConv(CC);
499   }
500
501   return CI;
502 }
503
504 /// EmitPutS - Emit a call to the puts function.  This assumes that Str is
505 /// some pointer.
506 Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
507                       const TargetLibraryInfo *TLI) {
508   if (!TLI->has(LibFunc::puts))
509     return 0;
510
511   Function *CallerF = B.GetInsertBlock()->getParent();
512   Module *M = CallerF->getParent();
513   AttributeSet AS[2];
514   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
515   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
516                             Attribute::NoUnwind);
517
518   Value *PutS = M->getOrInsertFunction("puts",
519                                        AttributeSet::get(M->getContext(), AS),
520                                        B.getInt32Ty(),
521                                        B.getInt8PtrTy(),
522                                        NULL);
523   CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
524   if (Function *F = dyn_cast<Function>(PutS->stripPointerCasts())) {
525     CallingConv::ID CC = F->getCallingConv();
526     CallingConv::ID CallerCC = CallerF->getCallingConv();
527     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
528       // If caller is using ARM target specific CC such as AAPCS-VFP,
529       // make sure the call uses it or it would introduce a calling
530       // convention mismatch.
531       CI->setCallingConv(CallerCC);
532       F->setCallingConv(CallerCC);
533     } else
534       CI->setCallingConv(CC);
535   }
536
537   return CI;
538 }
539
540 /// EmitFPutC - Emit a call to the fputc function.  This assumes that Char is
541 /// an integer and File is a pointer to FILE.
542 Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
543                        const DataLayout *TD, const TargetLibraryInfo *TLI) {
544   if (!TLI->has(LibFunc::fputc))
545     return 0;
546
547   Function *CallerF = B.GetInsertBlock()->getParent();
548   Module *M = CallerF->getParent();
549   AttributeSet AS[2];
550   AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
551   AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
552                             Attribute::NoUnwind);
553   Constant *F;
554   if (File->getType()->isPointerTy())
555     F = M->getOrInsertFunction("fputc",
556                                AttributeSet::get(M->getContext(), AS),
557                                B.getInt32Ty(),
558                                B.getInt32Ty(), File->getType(),
559                                NULL);
560   else
561     F = M->getOrInsertFunction("fputc",
562                                B.getInt32Ty(),
563                                B.getInt32Ty(),
564                                File->getType(), NULL);
565   Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
566                          "chari");
567   CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
568
569   if (Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) {
570     CallingConv::ID CC = Fn->getCallingConv();
571     CallingConv::ID CallerCC = CallerF->getCallingConv();
572     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
573       // If caller is using ARM target specific CC such as AAPCS-VFP,
574       // make sure the call uses it or it would introduce a calling
575       // convention mismatch.
576       CI->setCallingConv(CallerCC);
577       Fn->setCallingConv(CallerCC);
578     } else
579       CI->setCallingConv(CC);
580   }
581
582   return CI;
583 }
584
585 /// EmitFPutS - Emit a call to the puts function.  Str is required to be a
586 /// pointer and File is a pointer to FILE.
587 Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
588                        const DataLayout *TD, const TargetLibraryInfo *TLI) {
589   if (!TLI->has(LibFunc::fputs))
590     return 0;
591
592   Function *CallerF = B.GetInsertBlock()->getParent();
593   Module *M = CallerF->getParent();
594   AttributeSet AS[3];
595   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
596   AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
597   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
598                             Attribute::NoUnwind);
599   StringRef FPutsName = TLI->getName(LibFunc::fputs);
600   Constant *F;
601   if (File->getType()->isPointerTy())
602     F = M->getOrInsertFunction(FPutsName,
603                                AttributeSet::get(M->getContext(), AS),
604                                B.getInt32Ty(),
605                                B.getInt8PtrTy(),
606                                File->getType(), NULL);
607   else
608     F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
609                                B.getInt8PtrTy(),
610                                File->getType(), NULL);
611   CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
612
613   if (Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) {
614     CallingConv::ID CC = Fn->getCallingConv();
615     CallingConv::ID CallerCC = CallerF->getCallingConv();
616     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
617       // If caller is using ARM target specific CC such as AAPCS-VFP,
618       // make sure the call uses it or it would introduce a calling
619       // convention mismatch.
620       CI->setCallingConv(CallerCC);
621       Fn->setCallingConv(CallerCC);
622     } else
623       CI->setCallingConv(CC);
624   }
625
626   return CI;
627 }
628
629 /// EmitFWrite - Emit a call to the fwrite function.  This assumes that Ptr is
630 /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
631 Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
632                         IRBuilder<> &B, const DataLayout *TD,
633                         const TargetLibraryInfo *TLI) {
634   if (!TLI->has(LibFunc::fwrite))
635     return 0;
636
637   Function *CallerF = B.GetInsertBlock()->getParent();
638   Module *M = CallerF->getParent();
639   AttributeSet AS[3];
640   AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
641   AS[1] = AttributeSet::get(M->getContext(), 4, Attribute::NoCapture);
642   AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
643                             Attribute::NoUnwind);
644   LLVMContext &Context = B.GetInsertBlock()->getContext();
645   StringRef FWriteName = TLI->getName(LibFunc::fwrite);
646   Constant *F;
647   if (File->getType()->isPointerTy())
648     F = M->getOrInsertFunction(FWriteName,
649                                AttributeSet::get(M->getContext(), AS),
650                                TD->getIntPtrType(Context),
651                                B.getInt8PtrTy(),
652                                TD->getIntPtrType(Context),
653                                TD->getIntPtrType(Context),
654                                File->getType(), NULL);
655   else
656     F = M->getOrInsertFunction(FWriteName, TD->getIntPtrType(Context),
657                                B.getInt8PtrTy(),
658                                TD->getIntPtrType(Context),
659                                TD->getIntPtrType(Context),
660                                File->getType(), NULL);
661   CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
662                         ConstantInt::get(TD->getIntPtrType(Context), 1), File);
663
664   if (Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) {
665     CallingConv::ID CC = Fn->getCallingConv();
666     CallingConv::ID CallerCC = CallerF->getCallingConv();
667     if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
668       // If caller is using ARM target specific CC such as AAPCS-VFP,
669       // make sure the call uses it or it would introduce a calling
670       // convention mismatch.
671       CI->setCallingConv(CallerCC);
672       Fn->setCallingConv(CallerCC);
673     } else
674       CI->setCallingConv(CC);
675   }
676
677   return CI;
678 }
679
680 SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
681
682 bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const DataLayout *TD,
683                                      const TargetLibraryInfo *TLI) {
684   // We really need DataLayout for later.
685   if (!TD) return false;
686   
687   this->CI = CI;
688   Function *Callee = CI->getCalledFunction();
689   StringRef Name = Callee->getName();
690   FunctionType *FT = Callee->getFunctionType();
691   LLVMContext &Context = CI->getParent()->getContext();
692   IRBuilder<> B(CI);
693
694   if (Name == "__memcpy_chk") {
695     // Check if this has the right signature.
696     if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
697         !FT->getParamType(0)->isPointerTy() ||
698         !FT->getParamType(1)->isPointerTy() ||
699         FT->getParamType(2) != TD->getIntPtrType(Context) ||
700         FT->getParamType(3) != TD->getIntPtrType(Context))
701       return false;
702
703     if (isFoldable(3, 2, false)) {
704       B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
705                      CI->getArgOperand(2), 1);
706       replaceCall(CI->getArgOperand(0));
707       return true;
708     }
709     return false;
710   }
711
712   // Should be similar to memcpy.
713   if (Name == "__mempcpy_chk") {
714     return false;
715   }
716
717   if (Name == "__memmove_chk") {
718     // Check if this has the right signature.
719     if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
720         !FT->getParamType(0)->isPointerTy() ||
721         !FT->getParamType(1)->isPointerTy() ||
722         FT->getParamType(2) != TD->getIntPtrType(Context) ||
723         FT->getParamType(3) != TD->getIntPtrType(Context))
724       return false;
725
726     if (isFoldable(3, 2, false)) {
727       B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
728                       CI->getArgOperand(2), 1);
729       replaceCall(CI->getArgOperand(0));
730       return true;
731     }
732     return false;
733   }
734
735   if (Name == "__memset_chk") {
736     // Check if this has the right signature.
737     if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
738         !FT->getParamType(0)->isPointerTy() ||
739         !FT->getParamType(1)->isIntegerTy() ||
740         FT->getParamType(2) != TD->getIntPtrType(Context) ||
741         FT->getParamType(3) != TD->getIntPtrType(Context))
742       return false;
743
744     if (isFoldable(3, 2, false)) {
745       Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
746                                    false);
747       B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
748       replaceCall(CI->getArgOperand(0));
749       return true;
750     }
751     return false;
752   }
753
754   if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") {
755     // Check if this has the right signature.
756     if (FT->getNumParams() != 3 ||
757         FT->getReturnType() != FT->getParamType(0) ||
758         FT->getParamType(0) != FT->getParamType(1) ||
759         FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
760         FT->getParamType(2) != TD->getIntPtrType(Context))
761       return 0;
762     
763     
764     // If a) we don't have any length information, or b) we know this will
765     // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our
766     // st[rp]cpy_chk call which may fail at runtime if the size is too long.
767     // TODO: It might be nice to get a maximum length out of the possible
768     // string lengths for varying.
769     if (isFoldable(2, 1, true)) {
770       Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD,
771                               TLI, Name.substr(2, 6));
772       if (!Ret)
773         return false;
774       replaceCall(Ret);
775       return true;
776     }
777     return false;
778   }
779
780   if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") {
781     // Check if this has the right signature.
782     if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
783         FT->getParamType(0) != FT->getParamType(1) ||
784         FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
785         !FT->getParamType(2)->isIntegerTy() ||
786         FT->getParamType(3) != TD->getIntPtrType(Context))
787       return false;
788
789     if (isFoldable(3, 2, false)) {
790       Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
791                                CI->getArgOperand(2), B, TD, TLI,
792                                Name.substr(2, 7));
793       if (!Ret)
794         return false;
795       replaceCall(Ret);
796       return true;
797     }
798     return false;
799   }
800
801   if (Name == "__strcat_chk") {
802     return false;
803   }
804
805   if (Name == "__strncat_chk") {
806     return false;
807   }
808
809   return false;
810 }