blob: ad01f0b6fadfdf79669354e0eaf02081a32a3307 [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"
Micah Villmow3574eca2012-10-08 16:38:25 +000025#include "llvm/DataLayout.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.
Micah Villmow3574eca2012-10-08 16:38:25 +000037Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
Nuno Lopes51004df2012-07-25 16:46:31 +000038 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
Nuno Lopesa5368352012-07-25 17:18:59 +000060/// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
61/// specified pointer. Ptr is required to be some pointer type, MaxLen must
62/// be of size_t type, and the return value has 'intptr_t' type.
63Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
Micah Villmow3574eca2012-10-08 16:38:25 +000064 const DataLayout *TD, const TargetLibraryInfo *TLI) {
Nuno Lopesa5368352012-07-25 17:18:59 +000065 if (!TLI->has(LibFunc::strnlen))
66 return 0;
67
68 Module *M = B.GetInsertBlock()->getParent()->getParent();
69 AttributeWithIndex AWI[2];
70 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
71 AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
72 Attribute::NoUnwind);
73
74 LLVMContext &Context = B.GetInsertBlock()->getContext();
75 Constant *StrNLen = M->getOrInsertFunction("strnlen", AttrListPtr::get(AWI),
76 TD->getIntPtrType(Context),
77 B.getInt8PtrTy(),
78 TD->getIntPtrType(Context),
79 NULL);
80 CallInst *CI = B.CreateCall2(StrNLen, CastToCStr(Ptr, B), MaxLen, "strnlen");
81 if (const Function *F = dyn_cast<Function>(StrNLen->stripPointerCasts()))
82 CI->setCallingConv(F->getCallingConv());
83
84 return CI;
85}
86
Eric Christopherb6174e32010-03-05 22:25:30 +000087/// EmitStrChr - Emit a call to the strchr function to the builder, for the
88/// specified pointer and character. Ptr is required to be some pointer type,
89/// and the return value has 'i8*' type.
90Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Micah Villmow3574eca2012-10-08 16:38:25 +000091 const DataLayout *TD, const TargetLibraryInfo *TLI) {
Nuno Lopes51004df2012-07-25 16:46:31 +000092 if (!TLI->has(LibFunc::strchr))
93 return 0;
94
Eric Christopherb6174e32010-03-05 22:25:30 +000095 Module *M = B.GetInsertBlock()->getParent()->getParent();
96 AttributeWithIndex AWI =
97 AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
98
Chris Lattnerdb125cf2011-07-18 04:54:35 +000099 Type *I8Ptr = B.getInt8PtrTy();
100 Type *I32Ty = B.getInt32Ty();
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000101 Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000102 I8Ptr, I8Ptr, I32Ty, NULL);
103 CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
104 ConstantInt::get(I32Ty, C), "strchr");
105 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
106 CI->setCallingConv(F->getCallingConv());
107 return CI;
108}
109
Benjamin Kramer386e9182010-06-15 21:34:25 +0000110/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
111Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
Micah Villmow3574eca2012-10-08 16:38:25 +0000112 IRBuilder<> &B, const DataLayout *TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000113 const TargetLibraryInfo *TLI) {
114 if (!TLI->has(LibFunc::strncmp))
115 return 0;
116
Benjamin Kramer386e9182010-06-15 21:34:25 +0000117 Module *M = B.GetInsertBlock()->getParent()->getParent();
118 AttributeWithIndex AWI[3];
119 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
120 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
121 AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
122 Attribute::NoUnwind);
123
124 LLVMContext &Context = B.GetInsertBlock()->getContext();
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000125 Value *StrNCmp = M->getOrInsertFunction("strncmp", AttrListPtr::get(AWI),
Benjamin Kramer386e9182010-06-15 21:34:25 +0000126 B.getInt32Ty(),
127 B.getInt8PtrTy(),
128 B.getInt8PtrTy(),
129 TD->getIntPtrType(Context), NULL);
130 CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B),
131 CastToCStr(Ptr2, B), Len, "strncmp");
132
133 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
134 CI->setCallingConv(F->getCallingConv());
135
136 return CI;
137}
138
Eric Christopherb6174e32010-03-05 22:25:30 +0000139/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
140/// specified pointer arguments.
141Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Micah Villmow3574eca2012-10-08 16:38:25 +0000142 const DataLayout *TD, const TargetLibraryInfo *TLI,
Nuno Lopes51004df2012-07-25 16:46:31 +0000143 StringRef Name) {
144 if (!TLI->has(LibFunc::strcpy))
145 return 0;
146
Eric Christopherb6174e32010-03-05 22:25:30 +0000147 Module *M = B.GetInsertBlock()->getParent()->getParent();
148 AttributeWithIndex AWI[2];
149 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
150 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
Chris Lattnerdb125cf2011-07-18 04:54:35 +0000151 Type *I8Ptr = B.getInt8PtrTy();
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000152 Value *StrCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000153 I8Ptr, I8Ptr, I8Ptr, NULL);
154 CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
Benjamin Kramer7fa30b82010-03-11 20:45:13 +0000155 Name);
Eric Christopherb6174e32010-03-05 22:25:30 +0000156 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
157 CI->setCallingConv(F->getCallingConv());
158 return CI;
159}
160
Eric Christopherb0722af2010-03-11 17:45:38 +0000161/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
Eric Christopherbd973762010-03-11 01:25:07 +0000162/// specified pointer arguments.
163Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
Micah Villmow3574eca2012-10-08 16:38:25 +0000164 IRBuilder<> &B, const DataLayout *TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000165 const TargetLibraryInfo *TLI, StringRef Name) {
166 if (!TLI->has(LibFunc::strncpy))
167 return 0;
168
Eric Christopherbd973762010-03-11 01:25:07 +0000169 Module *M = B.GetInsertBlock()->getParent()->getParent();
170 AttributeWithIndex AWI[2];
171 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
172 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
Chris Lattnerdb125cf2011-07-18 04:54:35 +0000173 Type *I8Ptr = B.getInt8PtrTy();
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000174 Value *StrNCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI),
Eric Christopher71988f12010-04-07 23:00:07 +0000175 I8Ptr, I8Ptr, I8Ptr,
176 Len->getType(), NULL);
Eric Christopherbd973762010-03-11 01:25:07 +0000177 CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
178 Len, "strncpy");
179 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
180 CI->setCallingConv(F->getCallingConv());
181 return CI;
182}
183
Evan Cheng0289b412010-03-23 15:48:04 +0000184/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
185/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
186/// are pointers.
187Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Micah Villmow3574eca2012-10-08 16:38:25 +0000188 IRBuilder<> &B, const DataLayout *TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000189 const TargetLibraryInfo *TLI) {
190 if (!TLI->has(LibFunc::memcpy_chk))
191 return 0;
192
Evan Cheng0289b412010-03-23 15:48:04 +0000193 Module *M = B.GetInsertBlock()->getParent()->getParent();
194 AttributeWithIndex AWI;
195 AWI = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
196 LLVMContext &Context = B.GetInsertBlock()->getContext();
197 Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000198 AttrListPtr::get(AWI),
Evan Cheng0289b412010-03-23 15:48:04 +0000199 B.getInt8PtrTy(),
200 B.getInt8PtrTy(),
201 B.getInt8PtrTy(),
202 TD->getIntPtrType(Context),
203 TD->getIntPtrType(Context), NULL);
204 Dst = CastToCStr(Dst, B);
205 Src = CastToCStr(Src, B);
206 CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize);
207 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
208 CI->setCallingConv(F->getCallingConv());
209 return CI;
210}
211
Eric Christopherb6174e32010-03-05 22:25:30 +0000212/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
213/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
214Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
Micah Villmow3574eca2012-10-08 16:38:25 +0000215 Value *Len, IRBuilder<> &B, const DataLayout *TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000216 const TargetLibraryInfo *TLI) {
217 if (!TLI->has(LibFunc::memchr))
218 return 0;
219
Eric Christopherb6174e32010-03-05 22:25:30 +0000220 Module *M = B.GetInsertBlock()->getParent()->getParent();
221 AttributeWithIndex AWI;
222 AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
223 LLVMContext &Context = B.GetInsertBlock()->getContext();
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000224 Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000225 B.getInt8PtrTy(),
226 B.getInt8PtrTy(),
227 B.getInt32Ty(),
228 TD->getIntPtrType(Context),
229 NULL);
230 CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
231
232 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
233 CI->setCallingConv(F->getCallingConv());
234
235 return CI;
236}
237
238/// EmitMemCmp - Emit a call to the memcmp function.
239Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
Micah Villmow3574eca2012-10-08 16:38:25 +0000240 Value *Len, IRBuilder<> &B, const DataLayout *TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000241 const TargetLibraryInfo *TLI) {
242 if (!TLI->has(LibFunc::memcmp))
243 return 0;
244
Eric Christopherb6174e32010-03-05 22:25:30 +0000245 Module *M = B.GetInsertBlock()->getParent()->getParent();
246 AttributeWithIndex AWI[3];
247 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
248 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
249 AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
250 Attribute::NoUnwind);
251
252 LLVMContext &Context = B.GetInsertBlock()->getContext();
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000253 Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000254 B.getInt32Ty(),
255 B.getInt8PtrTy(),
256 B.getInt8PtrTy(),
257 TD->getIntPtrType(Context), NULL);
258 CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
259 Len, "memcmp");
260
261 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
262 CI->setCallingConv(F->getCallingConv());
263
264 return CI;
265}
266
Eric Christopherb6174e32010-03-05 22:25:30 +0000267/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
268/// 'floor'). This function is known to take a single of type matching 'Op' and
269/// returns one value with the same type. If 'Op' is a long double, 'l' is
270/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000271Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
272 const AttrListPtr &Attrs) {
273 SmallString<20> NameBuffer;
Eric Christopherb6174e32010-03-05 22:25:30 +0000274 if (!Op->getType()->isDoubleTy()) {
275 // If we need to add a suffix, copy into NameBuffer.
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000276 NameBuffer += Name;
Eric Christopherb6174e32010-03-05 22:25:30 +0000277 if (Op->getType()->isFloatTy())
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000278 NameBuffer += 'f'; // floorf
Eric Christopherb6174e32010-03-05 22:25:30 +0000279 else
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000280 NameBuffer += 'l'; // floorl
Eric Christopherb6174e32010-03-05 22:25:30 +0000281 Name = NameBuffer;
282 }
283
284 Module *M = B.GetInsertBlock()->getParent()->getParent();
285 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
286 Op->getType(), NULL);
287 CallInst *CI = B.CreateCall(Callee, Op, Name);
288 CI->setAttributes(Attrs);
289 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
290 CI->setCallingConv(F->getCallingConv());
291
292 return CI;
293}
294
295/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
296/// is an integer.
Micah Villmow3574eca2012-10-08 16:38:25 +0000297Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000298 const TargetLibraryInfo *TLI) {
299 if (!TLI->has(LibFunc::putchar))
300 return 0;
301
Eric Christopherb6174e32010-03-05 22:25:30 +0000302 Module *M = B.GetInsertBlock()->getParent()->getParent();
303 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
304 B.getInt32Ty(), NULL);
305 CallInst *CI = B.CreateCall(PutChar,
306 B.CreateIntCast(Char,
307 B.getInt32Ty(),
308 /*isSigned*/true,
309 "chari"),
310 "putchar");
311
312 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
313 CI->setCallingConv(F->getCallingConv());
314 return CI;
315}
316
317/// EmitPutS - Emit a call to the puts function. This assumes that Str is
318/// some pointer.
Micah Villmow3574eca2012-10-08 16:38:25 +0000319Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000320 const TargetLibraryInfo *TLI) {
321 if (!TLI->has(LibFunc::puts))
322 return 0;
323
Eric Christopherb6174e32010-03-05 22:25:30 +0000324 Module *M = B.GetInsertBlock()->getParent()->getParent();
325 AttributeWithIndex AWI[2];
326 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
327 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
328
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000329 Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000330 B.getInt32Ty(),
331 B.getInt8PtrTy(),
332 NULL);
333 CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
334 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
335 CI->setCallingConv(F->getCallingConv());
Nuno Lopes51004df2012-07-25 16:46:31 +0000336 return CI;
Eric Christopherb6174e32010-03-05 22:25:30 +0000337}
338
339/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
340/// an integer and File is a pointer to FILE.
Nuno Lopes51004df2012-07-25 16:46:31 +0000341Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Micah Villmow3574eca2012-10-08 16:38:25 +0000342 const DataLayout *TD, const TargetLibraryInfo *TLI) {
Nuno Lopes51004df2012-07-25 16:46:31 +0000343 if (!TLI->has(LibFunc::fputc))
344 return 0;
345
Eric Christopherb6174e32010-03-05 22:25:30 +0000346 Module *M = B.GetInsertBlock()->getParent()->getParent();
347 AttributeWithIndex AWI[2];
348 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
349 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
350 Constant *F;
351 if (File->getType()->isPointerTy())
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000352 F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000353 B.getInt32Ty(),
354 B.getInt32Ty(), File->getType(),
355 NULL);
356 else
357 F = M->getOrInsertFunction("fputc",
358 B.getInt32Ty(),
359 B.getInt32Ty(),
360 File->getType(), NULL);
361 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
362 "chari");
363 CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
364
365 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
366 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes51004df2012-07-25 16:46:31 +0000367 return CI;
Eric Christopherb6174e32010-03-05 22:25:30 +0000368}
369
370/// EmitFPutS - Emit a call to the puts function. Str is required to be a
371/// pointer and File is a pointer to FILE.
Nuno Lopes51004df2012-07-25 16:46:31 +0000372Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Micah Villmow3574eca2012-10-08 16:38:25 +0000373 const DataLayout *TD, const TargetLibraryInfo *TLI) {
Nuno Lopes51004df2012-07-25 16:46:31 +0000374 if (!TLI->has(LibFunc::fputs))
375 return 0;
376
Eric Christopherb6174e32010-03-05 22:25:30 +0000377 Module *M = B.GetInsertBlock()->getParent()->getParent();
378 AttributeWithIndex AWI[3];
379 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
380 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
381 AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
Eli Friedman9d434db2011-11-17 01:27:36 +0000382 StringRef FPutsName = TLI->getName(LibFunc::fputs);
Eric Christopherb6174e32010-03-05 22:25:30 +0000383 Constant *F;
384 if (File->getType()->isPointerTy())
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000385 F = M->getOrInsertFunction(FPutsName, AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000386 B.getInt32Ty(),
387 B.getInt8PtrTy(),
388 File->getType(), NULL);
389 else
Eli Friedman9d434db2011-11-17 01:27:36 +0000390 F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(),
Eric Christopherb6174e32010-03-05 22:25:30 +0000391 B.getInt8PtrTy(),
392 File->getType(), NULL);
393 CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
394
395 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
396 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes51004df2012-07-25 16:46:31 +0000397 return CI;
Eric Christopherb6174e32010-03-05 22:25:30 +0000398}
399
400/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
401/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
Nuno Lopes51004df2012-07-25 16:46:31 +0000402Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
Micah Villmow3574eca2012-10-08 16:38:25 +0000403 IRBuilder<> &B, const DataLayout *TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000404 const TargetLibraryInfo *TLI) {
405 if (!TLI->has(LibFunc::fwrite))
406 return 0;
407
Eric Christopherb6174e32010-03-05 22:25:30 +0000408 Module *M = B.GetInsertBlock()->getParent()->getParent();
409 AttributeWithIndex AWI[3];
410 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
411 AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture);
412 AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
413 LLVMContext &Context = B.GetInsertBlock()->getContext();
Eli Friedman9d434db2011-11-17 01:27:36 +0000414 StringRef FWriteName = TLI->getName(LibFunc::fwrite);
Eric Christopherb6174e32010-03-05 22:25:30 +0000415 Constant *F;
416 if (File->getType()->isPointerTy())
Chris Lattnerd509d0b2012-05-28 01:47:44 +0000417 F = M->getOrInsertFunction(FWriteName, AttrListPtr::get(AWI),
Eric Christopherb6174e32010-03-05 22:25:30 +0000418 TD->getIntPtrType(Context),
419 B.getInt8PtrTy(),
420 TD->getIntPtrType(Context),
421 TD->getIntPtrType(Context),
422 File->getType(), NULL);
423 else
Eli Friedman9d434db2011-11-17 01:27:36 +0000424 F = M->getOrInsertFunction(FWriteName, TD->getIntPtrType(Context),
Eric Christopherb6174e32010-03-05 22:25:30 +0000425 B.getInt8PtrTy(),
426 TD->getIntPtrType(Context),
427 TD->getIntPtrType(Context),
428 File->getType(), NULL);
429 CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
430 ConstantInt::get(TD->getIntPtrType(Context), 1), File);
431
432 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
433 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes51004df2012-07-25 16:46:31 +0000434 return CI;
Eric Christopherb6174e32010-03-05 22:25:30 +0000435}
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000436
Benjamin Kramera30b1812010-03-12 20:41:29 +0000437SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
438
Micah Villmow3574eca2012-10-08 16:38:25 +0000439bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const DataLayout *TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000440 const TargetLibraryInfo *TLI) {
Micah Villmow3574eca2012-10-08 16:38:25 +0000441 // We really need DataLayout for later.
Eric Christopher67a71b52010-04-12 04:48:00 +0000442 if (!TD) return false;
443
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000444 this->CI = CI;
Eric Christopher67a71b52010-04-12 04:48:00 +0000445 Function *Callee = CI->getCalledFunction();
446 StringRef Name = Callee->getName();
Chris Lattnerdb125cf2011-07-18 04:54:35 +0000447 FunctionType *FT = Callee->getFunctionType();
Eric Christopher67a71b52010-04-12 04:48:00 +0000448 LLVMContext &Context = CI->getParent()->getContext();
Eli Friedman1a24bf02011-05-27 01:00:36 +0000449 IRBuilder<> B(CI);
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000450
451 if (Name == "__memcpy_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000452 // Check if this has the right signature.
453 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
454 !FT->getParamType(0)->isPointerTy() ||
455 !FT->getParamType(1)->isPointerTy() ||
456 FT->getParamType(2) != TD->getIntPtrType(Context) ||
457 FT->getParamType(3) != TD->getIntPtrType(Context))
458 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000459
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000460 if (isFoldable(3, 2, false)) {
Benjamin Kramerdef548f2010-12-27 00:25:32 +0000461 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
462 CI->getArgOperand(2), 1);
Gabor Greiff148cb62010-06-28 12:29:20 +0000463 replaceCall(CI->getArgOperand(0));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000464 return true;
465 }
466 return false;
467 }
468
469 // Should be similar to memcpy.
470 if (Name == "__mempcpy_chk") {
471 return false;
472 }
473
474 if (Name == "__memmove_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000475 // Check if this has the right signature.
476 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
477 !FT->getParamType(0)->isPointerTy() ||
478 !FT->getParamType(1)->isPointerTy() ||
479 FT->getParamType(2) != TD->getIntPtrType(Context) ||
480 FT->getParamType(3) != TD->getIntPtrType(Context))
481 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000482
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000483 if (isFoldable(3, 2, false)) {
Benjamin Kramerdef548f2010-12-27 00:25:32 +0000484 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
485 CI->getArgOperand(2), 1);
Gabor Greiff148cb62010-06-28 12:29:20 +0000486 replaceCall(CI->getArgOperand(0));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000487 return true;
488 }
489 return false;
490 }
491
492 if (Name == "__memset_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000493 // Check if this has the right signature.
494 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
495 !FT->getParamType(0)->isPointerTy() ||
496 !FT->getParamType(1)->isIntegerTy() ||
497 FT->getParamType(2) != TD->getIntPtrType(Context) ||
498 FT->getParamType(3) != TD->getIntPtrType(Context))
499 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000500
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000501 if (isFoldable(3, 2, false)) {
Gabor Greiff148cb62010-06-28 12:29:20 +0000502 Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000503 false);
Benjamin Kramerdef548f2010-12-27 00:25:32 +0000504 B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
Gabor Greiff1ba6512010-06-25 07:58:41 +0000505 replaceCall(CI->getArgOperand(0));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000506 return true;
507 }
508 return false;
509 }
510
511 if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000512 // Check if this has the right signature.
513 if (FT->getNumParams() != 3 ||
514 FT->getReturnType() != FT->getParamType(0) ||
515 FT->getParamType(0) != FT->getParamType(1) ||
516 FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
517 FT->getParamType(2) != TD->getIntPtrType(Context))
518 return 0;
519
520
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000521 // If a) we don't have any length information, or b) we know this will
522 // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our
523 // st[rp]cpy_chk call which may fail at runtime if the size is too long.
524 // TODO: It might be nice to get a maximum length out of the possible
525 // string lengths for varying.
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000526 if (isFoldable(2, 1, true)) {
Gabor Greiff148cb62010-06-28 12:29:20 +0000527 Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD,
Nuno Lopes51004df2012-07-25 16:46:31 +0000528 TLI, Name.substr(2, 6));
Nuno Lopes28ad8632012-08-01 16:58:51 +0000529 if (!Ret)
Nuno Lopes918067d2012-08-01 17:13:28 +0000530 return false;
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000531 replaceCall(Ret);
532 return true;
533 }
534 return false;
535 }
536
Eric Christopher71988f12010-04-07 23:00:07 +0000537 if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000538 // Check if this has the right signature.
539 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
540 FT->getParamType(0) != FT->getParamType(1) ||
541 FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
542 !FT->getParamType(2)->isIntegerTy() ||
543 FT->getParamType(3) != TD->getIntPtrType(Context))
Eric Christopher2a7cb9d2010-04-13 16:41:29 +0000544 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000545
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000546 if (isFoldable(3, 2, false)) {
Gabor Greiff148cb62010-06-28 12:29:20 +0000547 Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
Nuno Lopes51004df2012-07-25 16:46:31 +0000548 CI->getArgOperand(2), B, TD, TLI,
549 Name.substr(2, 7));
Nuno Lopes28ad8632012-08-01 16:58:51 +0000550 if (!Ret)
Nuno Lopes918067d2012-08-01 17:13:28 +0000551 return false;
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000552 replaceCall(Ret);
553 return true;
554 }
555 return false;
556 }
557
558 if (Name == "__strcat_chk") {
559 return false;
560 }
561
562 if (Name == "__strncat_chk") {
563 return false;
564 }
565
566 return false;
567}