blob: c9681ae8b3e0572108c078e38a7375c5f8bee44c [file] [log] [blame]
Eric Christopherb6174e32010-03-05 22:25:30 +00001//===- 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"
Eric Christopherb6174e32010-03-05 22:25:30 +000015#include "llvm/Constants.h"
16#include "llvm/Function.h"
Chandler Carruth06cb8ed2012-06-29 12:38:19 +000017#include "llvm/IRBuilder.h"
Benjamin Kramerb5ccb252011-11-15 19:12:09 +000018#include "llvm/Intrinsics.h"
Chandler Carruth06cb8ed2012-06-29 12:38:19 +000019#include "llvm/Intrinsics.h"
20#include "llvm/LLVMContext.h"
Benjamin Kramerb5ccb252011-11-15 19:12:09 +000021#include "llvm/LLVMContext.h"
Eric Christopherb6174e32010-03-05 22:25:30 +000022#include "llvm/Module.h"
Chandler Carruth06cb8ed2012-06-29 12:38:19 +000023#include "llvm/Type.h"
24#include "llvm/ADT/SmallString.h"
Eric Christopherb6174e32010-03-05 22:25:30 +000025#include "llvm/Target/TargetData.h"
Eli Friedman9d434db2011-11-17 01:27:36 +000026#include "llvm/Target/TargetLibraryInfo.h"
Eric Christopherb6174e32010-03-05 22:25:30 +000027
28using namespace llvm;
29
30/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
31Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) {
32 return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr");
33}
34
35/// EmitStrLen - Emit a call to the strlen function to the builder, for the
36/// specified pointer. This always returns an integer value of size intptr_t.
Nuno Lopes51004df2012-07-25 16:46:31 +000037Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD,
38 const TargetLibraryInfo *TLI) {
39 if (!TLI->has(LibFunc::strlen))
40 return 0;
41
Eric Christopherb6174e32010-03-05 22:25:30 +000042 Module *M = B.GetInsertBlock()->getParent()->getParent();
43 AttributeWithIndex AWI[2];
44 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
45 AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
46 Attribute::NoUnwind);
47
48 LLVMContext &Context = B.GetInsertBlock()->getContext();
Chris Lattnerd509d0b2012-05-28 01:47:44 +000049 Constant *StrLen = M->getOrInsertFunction("strlen", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +000050 TD->getIntPtrType(Context),
51 B.getInt8PtrTy(),
52 NULL);
53 CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
54 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
55 CI->setCallingConv(F->getCallingConv());
56
57 return CI;
58}
59
60/// EmitStrChr - Emit a call to the strchr function to the builder, for the
61/// specified pointer and character. Ptr is required to be some pointer type,
62/// and the return value has 'i8*' type.
63Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Nuno Lopes51004df2012-07-25 16:46:31 +000064 const TargetData *TD, const TargetLibraryInfo *TLI) {
65 if (!TLI->has(LibFunc::strchr))
66 return 0;
67
Eric Christopherb6174e32010-03-05 22:25:30 +000068 Module *M = B.GetInsertBlock()->getParent()->getParent();
69 AttributeWithIndex AWI =
70 AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
71
Chris Lattnerdb125cf2011-07-18 04:54:35 +000072 Type *I8Ptr = B.getInt8PtrTy();
73 Type *I32Ty = B.getInt32Ty();
Chris Lattnerd509d0b2012-05-28 01:47:44 +000074 Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +000075 I8Ptr, I8Ptr, I32Ty, NULL);
76 CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
77 ConstantInt::get(I32Ty, C), "strchr");
78 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
79 CI->setCallingConv(F->getCallingConv());
80 return CI;
81}
82
Benjamin Kramer386e9182010-06-15 21:34:25 +000083/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
84Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
Nuno Lopes51004df2012-07-25 16:46:31 +000085 IRBuilder<> &B, const TargetData *TD,
86 const TargetLibraryInfo *TLI) {
87 if (!TLI->has(LibFunc::strncmp))
88 return 0;
89
Benjamin Kramer386e9182010-06-15 21:34:25 +000090 Module *M = B.GetInsertBlock()->getParent()->getParent();
91 AttributeWithIndex AWI[3];
92 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
93 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
94 AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
95 Attribute::NoUnwind);
96
97 LLVMContext &Context = B.GetInsertBlock()->getContext();
Chris Lattnerd509d0b2012-05-28 01:47:44 +000098 Value *StrNCmp = M->getOrInsertFunction("strncmp", AttrListPtr::get(AWI),
Benjamin Kramer386e9182010-06-15 21:34:25 +000099 B.getInt32Ty(),
100 B.getInt8PtrTy(),
101 B.getInt8PtrTy(),
102 TD->getIntPtrType(Context), NULL);
103 CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B),
104 CastToCStr(Ptr2, B), Len, "strncmp");
105
106 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
107 CI->setCallingConv(F->getCallingConv());
108
109 return CI;
110}
111
Eric Christopherb6174e32010-03-05 22:25:30 +0000112/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
113/// specified pointer arguments.
114Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Nuno Lopes51004df2012-07-25 16:46:31 +0000115 const TargetData *TD, const TargetLibraryInfo *TLI,
116 StringRef Name) {
117 if (!TLI->has(LibFunc::strcpy))
118 return 0;
119
Eric Christopherb6174e32010-03-05 22:25:30 +0000120 Module *M = B.GetInsertBlock()->getParent()->getParent();
121 AttributeWithIndex AWI[2];
122 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
123 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
Chris Lattnerdb125cf2011-07-18 04:54:35 +0000124 Type *I8Ptr = B.getInt8PtrTy();
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000125 Value *StrCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000126 I8Ptr, I8Ptr, I8Ptr, NULL);
127 CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
Benjamin Kramer7fa30b82010-03-11 20:45:13 +0000128 Name);
Eric Christopherb6174e32010-03-05 22:25:30 +0000129 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
130 CI->setCallingConv(F->getCallingConv());
131 return CI;
132}
133
Eric Christopherb0722af2010-03-11 17:45:38 +0000134/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
Eric Christopherbd973762010-03-11 01:25:07 +0000135/// specified pointer arguments.
136Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
Nuno Lopes51004df2012-07-25 16:46:31 +0000137 IRBuilder<> &B, const TargetData *TD,
138 const TargetLibraryInfo *TLI, StringRef Name) {
139 if (!TLI->has(LibFunc::strncpy))
140 return 0;
141
Eric Christopherbd973762010-03-11 01:25:07 +0000142 Module *M = B.GetInsertBlock()->getParent()->getParent();
143 AttributeWithIndex AWI[2];
144 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
145 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
Chris Lattnerdb125cf2011-07-18 04:54:35 +0000146 Type *I8Ptr = B.getInt8PtrTy();
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000147 Value *StrNCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI),
Eric Christopher71988f12010-04-07 23:00:07 +0000148 I8Ptr, I8Ptr, I8Ptr,
149 Len->getType(), NULL);
Eric Christopherbd973762010-03-11 01:25:07 +0000150 CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
151 Len, "strncpy");
152 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
153 CI->setCallingConv(F->getCallingConv());
154 return CI;
155}
156
Evan Cheng0289b412010-03-23 15:48:04 +0000157/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
158/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
159/// are pointers.
160Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Nuno Lopes51004df2012-07-25 16:46:31 +0000161 IRBuilder<> &B, const TargetData *TD,
162 const TargetLibraryInfo *TLI) {
163 if (!TLI->has(LibFunc::memcpy_chk))
164 return 0;
165
Evan Cheng0289b412010-03-23 15:48:04 +0000166 Module *M = B.GetInsertBlock()->getParent()->getParent();
167 AttributeWithIndex AWI;
168 AWI = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
169 LLVMContext &Context = B.GetInsertBlock()->getContext();
170 Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000171 AttrListPtr::get(AWI),
Evan Cheng0289b412010-03-23 15:48:04 +0000172 B.getInt8PtrTy(),
173 B.getInt8PtrTy(),
174 B.getInt8PtrTy(),
175 TD->getIntPtrType(Context),
176 TD->getIntPtrType(Context), NULL);
177 Dst = CastToCStr(Dst, B);
178 Src = CastToCStr(Src, B);
179 CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize);
180 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
181 CI->setCallingConv(F->getCallingConv());
182 return CI;
183}
184
Eric Christopherb6174e32010-03-05 22:25:30 +0000185/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
186/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
187Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
Nuno Lopes51004df2012-07-25 16:46:31 +0000188 Value *Len, IRBuilder<> &B, const TargetData *TD,
189 const TargetLibraryInfo *TLI) {
190 if (!TLI->has(LibFunc::memchr))
191 return 0;
192
Eric Christopherb6174e32010-03-05 22:25:30 +0000193 Module *M = B.GetInsertBlock()->getParent()->getParent();
194 AttributeWithIndex AWI;
195 AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
196 LLVMContext &Context = B.GetInsertBlock()->getContext();
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000197 Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000198 B.getInt8PtrTy(),
199 B.getInt8PtrTy(),
200 B.getInt32Ty(),
201 TD->getIntPtrType(Context),
202 NULL);
203 CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
204
205 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
206 CI->setCallingConv(F->getCallingConv());
207
208 return CI;
209}
210
211/// EmitMemCmp - Emit a call to the memcmp function.
212Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
Nuno Lopes51004df2012-07-25 16:46:31 +0000213 Value *Len, IRBuilder<> &B, const TargetData *TD,
214 const TargetLibraryInfo *TLI) {
215 if (!TLI->has(LibFunc::memcmp))
216 return 0;
217
Eric Christopherb6174e32010-03-05 22:25:30 +0000218 Module *M = B.GetInsertBlock()->getParent()->getParent();
219 AttributeWithIndex AWI[3];
220 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
221 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
222 AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
223 Attribute::NoUnwind);
224
225 LLVMContext &Context = B.GetInsertBlock()->getContext();
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000226 Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000227 B.getInt32Ty(),
228 B.getInt8PtrTy(),
229 B.getInt8PtrTy(),
230 TD->getIntPtrType(Context), NULL);
231 CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
232 Len, "memcmp");
233
234 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
235 CI->setCallingConv(F->getCallingConv());
236
237 return CI;
238}
239
Eric Christopherb6174e32010-03-05 22:25:30 +0000240/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
241/// 'floor'). This function is known to take a single of type matching 'Op' and
242/// returns one value with the same type. If 'Op' is a long double, 'l' is
243/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000244Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
245 const AttrListPtr &Attrs) {
246 SmallString<20> NameBuffer;
Eric Christopherb6174e32010-03-05 22:25:30 +0000247 if (!Op->getType()->isDoubleTy()) {
248 // If we need to add a suffix, copy into NameBuffer.
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000249 NameBuffer += Name;
Eric Christopherb6174e32010-03-05 22:25:30 +0000250 if (Op->getType()->isFloatTy())
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000251 NameBuffer += 'f'; // floorf
Eric Christopherb6174e32010-03-05 22:25:30 +0000252 else
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000253 NameBuffer += 'l'; // floorl
Eric Christopherb6174e32010-03-05 22:25:30 +0000254 Name = NameBuffer;
255 }
256
257 Module *M = B.GetInsertBlock()->getParent()->getParent();
258 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
259 Op->getType(), NULL);
260 CallInst *CI = B.CreateCall(Callee, Op, Name);
261 CI->setAttributes(Attrs);
262 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
263 CI->setCallingConv(F->getCallingConv());
264
265 return CI;
266}
267
268/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
269/// is an integer.
Nuno Lopes51004df2012-07-25 16:46:31 +0000270Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD,
271 const TargetLibraryInfo *TLI) {
272 if (!TLI->has(LibFunc::putchar))
273 return 0;
274
Eric Christopherb6174e32010-03-05 22:25:30 +0000275 Module *M = B.GetInsertBlock()->getParent()->getParent();
276 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
277 B.getInt32Ty(), NULL);
278 CallInst *CI = B.CreateCall(PutChar,
279 B.CreateIntCast(Char,
280 B.getInt32Ty(),
281 /*isSigned*/true,
282 "chari"),
283 "putchar");
284
285 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
286 CI->setCallingConv(F->getCallingConv());
287 return CI;
288}
289
290/// EmitPutS - Emit a call to the puts function. This assumes that Str is
291/// some pointer.
Nuno Lopes51004df2012-07-25 16:46:31 +0000292Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD,
293 const TargetLibraryInfo *TLI) {
294 if (!TLI->has(LibFunc::puts))
295 return 0;
296
Eric Christopherb6174e32010-03-05 22:25:30 +0000297 Module *M = B.GetInsertBlock()->getParent()->getParent();
298 AttributeWithIndex AWI[2];
299 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
300 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
301
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000302 Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000303 B.getInt32Ty(),
304 B.getInt8PtrTy(),
305 NULL);
306 CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
307 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
308 CI->setCallingConv(F->getCallingConv());
Nuno Lopes51004df2012-07-25 16:46:31 +0000309 return CI;
Eric Christopherb6174e32010-03-05 22:25:30 +0000310}
311
312/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
313/// an integer and File is a pointer to FILE.
Nuno Lopes51004df2012-07-25 16:46:31 +0000314Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
315 const TargetData *TD, const TargetLibraryInfo *TLI) {
316 if (!TLI->has(LibFunc::fputc))
317 return 0;
318
Eric Christopherb6174e32010-03-05 22:25:30 +0000319 Module *M = B.GetInsertBlock()->getParent()->getParent();
320 AttributeWithIndex AWI[2];
321 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
322 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
323 Constant *F;
324 if (File->getType()->isPointerTy())
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000325 F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000326 B.getInt32Ty(),
327 B.getInt32Ty(), File->getType(),
328 NULL);
329 else
330 F = M->getOrInsertFunction("fputc",
331 B.getInt32Ty(),
332 B.getInt32Ty(),
333 File->getType(), NULL);
334 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
335 "chari");
336 CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
337
338 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
339 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes51004df2012-07-25 16:46:31 +0000340 return CI;
Eric Christopherb6174e32010-03-05 22:25:30 +0000341}
342
343/// EmitFPutS - Emit a call to the puts function. Str is required to be a
344/// pointer and File is a pointer to FILE.
Nuno Lopes51004df2012-07-25 16:46:31 +0000345Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
346 const TargetData *TD, const TargetLibraryInfo *TLI) {
347 if (!TLI->has(LibFunc::fputs))
348 return 0;
349
Eric Christopherb6174e32010-03-05 22:25:30 +0000350 Module *M = B.GetInsertBlock()->getParent()->getParent();
351 AttributeWithIndex AWI[3];
352 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
353 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
354 AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
Eli Friedman9d434db2011-11-17 01:27:36 +0000355 StringRef FPutsName = TLI->getName(LibFunc::fputs);
Eric Christopherb6174e32010-03-05 22:25:30 +0000356 Constant *F;
357 if (File->getType()->isPointerTy())
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000358 F = M->getOrInsertFunction(FPutsName, AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000359 B.getInt32Ty(),
360 B.getInt8PtrTy(),
361 File->getType(), NULL);
362 else
Eli Friedman9d434db2011-11-17 01:27:36 +0000363 F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
Eric Christopherb6174e32010-03-05 22:25:30 +0000364 B.getInt8PtrTy(),
365 File->getType(), NULL);
366 CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
367
368 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
369 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes51004df2012-07-25 16:46:31 +0000370 return CI;
Eric Christopherb6174e32010-03-05 22:25:30 +0000371}
372
373/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
374/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
Nuno Lopes51004df2012-07-25 16:46:31 +0000375Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
376 IRBuilder<> &B, const TargetData *TD,
377 const TargetLibraryInfo *TLI) {
378 if (!TLI->has(LibFunc::fwrite))
379 return 0;
380
Eric Christopherb6174e32010-03-05 22:25:30 +0000381 Module *M = B.GetInsertBlock()->getParent()->getParent();
382 AttributeWithIndex AWI[3];
383 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
384 AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture);
385 AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
386 LLVMContext &Context = B.GetInsertBlock()->getContext();
Eli Friedman9d434db2011-11-17 01:27:36 +0000387 StringRef FWriteName = TLI->getName(LibFunc::fwrite);
Eric Christopherb6174e32010-03-05 22:25:30 +0000388 Constant *F;
389 if (File->getType()->isPointerTy())
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000390 F = M->getOrInsertFunction(FWriteName, AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000391 TD->getIntPtrType(Context),
392 B.getInt8PtrTy(),
393 TD->getIntPtrType(Context),
394 TD->getIntPtrType(Context),
395 File->getType(), NULL);
396 else
Eli Friedman9d434db2011-11-17 01:27:36 +0000397 F = M->getOrInsertFunction(FWriteName, TD->getIntPtrType(Context),
Eric Christopherb6174e32010-03-05 22:25:30 +0000398 B.getInt8PtrTy(),
399 TD->getIntPtrType(Context),
400 TD->getIntPtrType(Context),
401 File->getType(), NULL);
402 CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
403 ConstantInt::get(TD->getIntPtrType(Context), 1), File);
404
405 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
406 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes51004df2012-07-25 16:46:31 +0000407 return CI;
Eric Christopherb6174e32010-03-05 22:25:30 +0000408}
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000409
Benjamin Kramera30b1812010-03-12 20:41:29 +0000410SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
411
Nuno Lopes51004df2012-07-25 16:46:31 +0000412bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const TargetData *TD,
413 const TargetLibraryInfo *TLI) {
Eric Christopher67a71b52010-04-12 04:48:00 +0000414 // We really need TargetData for later.
415 if (!TD) return false;
416
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000417 this->CI = CI;
Eric Christopher67a71b52010-04-12 04:48:00 +0000418 Function *Callee = CI->getCalledFunction();
419 StringRef Name = Callee->getName();
Chris Lattnerdb125cf2011-07-18 04:54:35 +0000420 FunctionType *FT = Callee->getFunctionType();
Eric Christopher67a71b52010-04-12 04:48:00 +0000421 LLVMContext &Context = CI->getParent()->getContext();
Eli Friedman1a24bf02011-05-27 01:00:36 +0000422 IRBuilder<> B(CI);
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000423
424 if (Name == "__memcpy_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000425 // Check if this has the right signature.
426 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
427 !FT->getParamType(0)->isPointerTy() ||
428 !FT->getParamType(1)->isPointerTy() ||
429 FT->getParamType(2) != TD->getIntPtrType(Context) ||
430 FT->getParamType(3) != TD->getIntPtrType(Context))
431 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000432
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000433 if (isFoldable(3, 2, false)) {
Benjamin Kramerdef548f2010-12-27 00:25:32 +0000434 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
435 CI->getArgOperand(2), 1);
Gabor Greiff148cb62010-06-28 12:29:20 +0000436 replaceCall(CI->getArgOperand(0));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000437 return true;
438 }
439 return false;
440 }
441
442 // Should be similar to memcpy.
443 if (Name == "__mempcpy_chk") {
444 return false;
445 }
446
447 if (Name == "__memmove_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000448 // Check if this has the right signature.
449 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
450 !FT->getParamType(0)->isPointerTy() ||
451 !FT->getParamType(1)->isPointerTy() ||
452 FT->getParamType(2) != TD->getIntPtrType(Context) ||
453 FT->getParamType(3) != TD->getIntPtrType(Context))
454 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000455
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000456 if (isFoldable(3, 2, false)) {
Benjamin Kramerdef548f2010-12-27 00:25:32 +0000457 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
458 CI->getArgOperand(2), 1);
Gabor Greiff148cb62010-06-28 12:29:20 +0000459 replaceCall(CI->getArgOperand(0));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000460 return true;
461 }
462 return false;
463 }
464
465 if (Name == "__memset_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000466 // Check if this has the right signature.
467 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
468 !FT->getParamType(0)->isPointerTy() ||
469 !FT->getParamType(1)->isIntegerTy() ||
470 FT->getParamType(2) != TD->getIntPtrType(Context) ||
471 FT->getParamType(3) != TD->getIntPtrType(Context))
472 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000473
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000474 if (isFoldable(3, 2, false)) {
Gabor Greiff148cb62010-06-28 12:29:20 +0000475 Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000476 false);
Benjamin Kramerdef548f2010-12-27 00:25:32 +0000477 B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
Gabor Greiff1ba6512010-06-25 07:58:41 +0000478 replaceCall(CI->getArgOperand(0));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000479 return true;
480 }
481 return false;
482 }
483
484 if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000485 // Check if this has the right signature.
486 if (FT->getNumParams() != 3 ||
487 FT->getReturnType() != FT->getParamType(0) ||
488 FT->getParamType(0) != FT->getParamType(1) ||
489 FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
490 FT->getParamType(2) != TD->getIntPtrType(Context))
491 return 0;
492
493
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000494 // If a) we don't have any length information, or b) we know this will
495 // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our
496 // st[rp]cpy_chk call which may fail at runtime if the size is too long.
497 // TODO: It might be nice to get a maximum length out of the possible
498 // string lengths for varying.
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000499 if (isFoldable(2, 1, true)) {
Gabor Greiff148cb62010-06-28 12:29:20 +0000500 Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000501 TLI, Name.substr(2, 6));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000502 replaceCall(Ret);
503 return true;
504 }
505 return false;
506 }
507
Eric Christopher71988f12010-04-07 23:00:07 +0000508 if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000509 // Check if this has the right signature.
510 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
511 FT->getParamType(0) != FT->getParamType(1) ||
512 FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
513 !FT->getParamType(2)->isIntegerTy() ||
514 FT->getParamType(3) != TD->getIntPtrType(Context))
Eric Christopher2a7cb9d2010-04-13 16:41:29 +0000515 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000516
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000517 if (isFoldable(3, 2, false)) {
Gabor Greiff148cb62010-06-28 12:29:20 +0000518 Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
Nuno Lopes51004df2012-07-25 16:46:31 +0000519 CI->getArgOperand(2), B, TD, TLI,
520 Name.substr(2, 7));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000521 replaceCall(Ret);
522 return true;
523 }
524 return false;
525 }
526
527 if (Name == "__strcat_chk") {
528 return false;
529 }
530
531 if (Name == "__strncat_chk") {
532 return false;
533 }
534
535 return false;
536}