blob: fc741106dd6736944e5e10248bfa533ed0c93f24 [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"
15#include "llvm/Type.h"
16#include "llvm/Constants.h"
17#include "llvm/Function.h"
Benjamin Kramerb5ccb252011-11-15 19:12:09 +000018#include "llvm/Intrinsics.h"
19#include "llvm/LLVMContext.h"
Eric Christopherb6174e32010-03-05 22:25:30 +000020#include "llvm/Module.h"
21#include "llvm/Support/IRBuilder.h"
22#include "llvm/Target/TargetData.h"
Benjamin Kramerb5ccb252011-11-15 19:12:09 +000023#include "llvm/ADT/SmallString.h"
Eric Christopherb6174e32010-03-05 22:25:30 +000024
25using namespace llvm;
26
27/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
28Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) {
29 return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr");
30}
31
32/// EmitStrLen - Emit a call to the strlen function to the builder, for the
33/// specified pointer. This always returns an integer value of size intptr_t.
34Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD) {
35 Module *M = B.GetInsertBlock()->getParent()->getParent();
36 AttributeWithIndex AWI[2];
37 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
38 AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
39 Attribute::NoUnwind);
40
41 LLVMContext &Context = B.GetInsertBlock()->getContext();
42 Constant *StrLen = M->getOrInsertFunction("strlen", AttrListPtr::get(AWI, 2),
43 TD->getIntPtrType(Context),
44 B.getInt8PtrTy(),
45 NULL);
46 CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
47 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
48 CI->setCallingConv(F->getCallingConv());
49
50 return CI;
51}
52
53/// EmitStrChr - Emit a call to the strchr function to the builder, for the
54/// specified pointer and character. Ptr is required to be some pointer type,
55/// and the return value has 'i8*' type.
56Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
57 const TargetData *TD) {
58 Module *M = B.GetInsertBlock()->getParent()->getParent();
59 AttributeWithIndex AWI =
60 AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
61
Chris Lattnerdb125cf2011-07-18 04:54:35 +000062 Type *I8Ptr = B.getInt8PtrTy();
63 Type *I32Ty = B.getInt32Ty();
Eric Christopherb6174e32010-03-05 22:25:30 +000064 Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(&AWI, 1),
65 I8Ptr, I8Ptr, I32Ty, NULL);
66 CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
67 ConstantInt::get(I32Ty, C), "strchr");
68 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
69 CI->setCallingConv(F->getCallingConv());
70 return CI;
71}
72
Benjamin Kramer386e9182010-06-15 21:34:25 +000073/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
74Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
75 IRBuilder<> &B, const TargetData *TD) {
76 Module *M = B.GetInsertBlock()->getParent()->getParent();
77 AttributeWithIndex AWI[3];
78 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
79 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
80 AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
81 Attribute::NoUnwind);
82
83 LLVMContext &Context = B.GetInsertBlock()->getContext();
84 Value *StrNCmp = M->getOrInsertFunction("strncmp", AttrListPtr::get(AWI, 3),
85 B.getInt32Ty(),
86 B.getInt8PtrTy(),
87 B.getInt8PtrTy(),
88 TD->getIntPtrType(Context), NULL);
89 CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B),
90 CastToCStr(Ptr2, B), Len, "strncmp");
91
92 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
93 CI->setCallingConv(F->getCallingConv());
94
95 return CI;
96}
97
Eric Christopherb6174e32010-03-05 22:25:30 +000098/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
99/// specified pointer arguments.
100Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Benjamin Kramer7fa30b82010-03-11 20:45:13 +0000101 const TargetData *TD, StringRef Name) {
Eric Christopherb6174e32010-03-05 22:25:30 +0000102 Module *M = B.GetInsertBlock()->getParent()->getParent();
103 AttributeWithIndex AWI[2];
104 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
105 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
Chris Lattnerdb125cf2011-07-18 04:54:35 +0000106 Type *I8Ptr = B.getInt8PtrTy();
Benjamin Kramer7fa30b82010-03-11 20:45:13 +0000107 Value *StrCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI, 2),
Eric Christopherb6174e32010-03-05 22:25:30 +0000108 I8Ptr, I8Ptr, I8Ptr, NULL);
109 CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
Benjamin Kramer7fa30b82010-03-11 20:45:13 +0000110 Name);
Eric Christopherb6174e32010-03-05 22:25:30 +0000111 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
112 CI->setCallingConv(F->getCallingConv());
113 return CI;
114}
115
Eric Christopherb0722af2010-03-11 17:45:38 +0000116/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
Eric Christopherbd973762010-03-11 01:25:07 +0000117/// specified pointer arguments.
118Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
Eric Christopher71988f12010-04-07 23:00:07 +0000119 IRBuilder<> &B, const TargetData *TD, StringRef Name) {
Eric Christopherbd973762010-03-11 01:25:07 +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();
Eric Christopher71988f12010-04-07 23:00:07 +0000125 Value *StrNCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI, 2),
126 I8Ptr, I8Ptr, I8Ptr,
127 Len->getType(), NULL);
Eric Christopherbd973762010-03-11 01:25:07 +0000128 CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
129 Len, "strncpy");
130 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
131 CI->setCallingConv(F->getCallingConv());
132 return CI;
133}
134
Evan Cheng0289b412010-03-23 15:48:04 +0000135/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
136/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
137/// are pointers.
138Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
139 IRBuilder<> &B, const TargetData *TD) {
140 Module *M = B.GetInsertBlock()->getParent()->getParent();
141 AttributeWithIndex AWI;
142 AWI = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
143 LLVMContext &Context = B.GetInsertBlock()->getContext();
144 Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
145 AttrListPtr::get(&AWI, 1),
146 B.getInt8PtrTy(),
147 B.getInt8PtrTy(),
148 B.getInt8PtrTy(),
149 TD->getIntPtrType(Context),
150 TD->getIntPtrType(Context), NULL);
151 Dst = CastToCStr(Dst, B);
152 Src = CastToCStr(Src, B);
153 CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize);
154 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
155 CI->setCallingConv(F->getCallingConv());
156 return CI;
157}
158
Eric Christopherb6174e32010-03-05 22:25:30 +0000159/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
160/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
161Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
162 Value *Len, IRBuilder<> &B, const TargetData *TD) {
163 Module *M = B.GetInsertBlock()->getParent()->getParent();
164 AttributeWithIndex AWI;
165 AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
166 LLVMContext &Context = B.GetInsertBlock()->getContext();
167 Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(&AWI, 1),
168 B.getInt8PtrTy(),
169 B.getInt8PtrTy(),
170 B.getInt32Ty(),
171 TD->getIntPtrType(Context),
172 NULL);
173 CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
174
175 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
176 CI->setCallingConv(F->getCallingConv());
177
178 return CI;
179}
180
181/// EmitMemCmp - Emit a call to the memcmp function.
182Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
183 Value *Len, IRBuilder<> &B, const TargetData *TD) {
184 Module *M = B.GetInsertBlock()->getParent()->getParent();
185 AttributeWithIndex AWI[3];
186 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
187 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
188 AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
189 Attribute::NoUnwind);
190
191 LLVMContext &Context = B.GetInsertBlock()->getContext();
192 Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI, 3),
193 B.getInt32Ty(),
194 B.getInt8PtrTy(),
195 B.getInt8PtrTy(),
196 TD->getIntPtrType(Context), NULL);
197 CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
198 Len, "memcmp");
199
200 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
201 CI->setCallingConv(F->getCallingConv());
202
203 return CI;
204}
205
Eric Christopherb6174e32010-03-05 22:25:30 +0000206/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
207/// 'floor'). This function is known to take a single of type matching 'Op' and
208/// returns one value with the same type. If 'Op' is a long double, 'l' is
209/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000210Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
211 const AttrListPtr &Attrs) {
212 SmallString<20> NameBuffer;
Eric Christopherb6174e32010-03-05 22:25:30 +0000213 if (!Op->getType()->isDoubleTy()) {
214 // If we need to add a suffix, copy into NameBuffer.
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000215 NameBuffer += Name;
Eric Christopherb6174e32010-03-05 22:25:30 +0000216 if (Op->getType()->isFloatTy())
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000217 NameBuffer += 'f'; // floorf
Eric Christopherb6174e32010-03-05 22:25:30 +0000218 else
Benjamin Kramerb5ccb252011-11-15 19:12:09 +0000219 NameBuffer += 'l'; // floorl
Eric Christopherb6174e32010-03-05 22:25:30 +0000220 Name = NameBuffer;
221 }
222
223 Module *M = B.GetInsertBlock()->getParent()->getParent();
224 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
225 Op->getType(), NULL);
226 CallInst *CI = B.CreateCall(Callee, Op, Name);
227 CI->setAttributes(Attrs);
228 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
229 CI->setCallingConv(F->getCallingConv());
230
231 return CI;
232}
233
234/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
235/// is an integer.
236Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD) {
237 Module *M = B.GetInsertBlock()->getParent()->getParent();
238 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
239 B.getInt32Ty(), NULL);
240 CallInst *CI = B.CreateCall(PutChar,
241 B.CreateIntCast(Char,
242 B.getInt32Ty(),
243 /*isSigned*/true,
244 "chari"),
245 "putchar");
246
247 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
248 CI->setCallingConv(F->getCallingConv());
249 return CI;
250}
251
252/// EmitPutS - Emit a call to the puts function. This assumes that Str is
253/// some pointer.
254void llvm::EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD) {
255 Module *M = B.GetInsertBlock()->getParent()->getParent();
256 AttributeWithIndex AWI[2];
257 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
258 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
259
260 Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI, 2),
261 B.getInt32Ty(),
262 B.getInt8PtrTy(),
263 NULL);
264 CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
265 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
266 CI->setCallingConv(F->getCallingConv());
267
268}
269
270/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
271/// an integer and File is a pointer to FILE.
272void llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
273 const TargetData *TD) {
274 Module *M = B.GetInsertBlock()->getParent()->getParent();
275 AttributeWithIndex AWI[2];
276 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
277 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
278 Constant *F;
279 if (File->getType()->isPointerTy())
280 F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2),
281 B.getInt32Ty(),
282 B.getInt32Ty(), File->getType(),
283 NULL);
284 else
285 F = M->getOrInsertFunction("fputc",
286 B.getInt32Ty(),
287 B.getInt32Ty(),
288 File->getType(), NULL);
289 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
290 "chari");
291 CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
292
293 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
294 CI->setCallingConv(Fn->getCallingConv());
295}
296
297/// EmitFPutS - Emit a call to the puts function. Str is required to be a
298/// pointer and File is a pointer to FILE.
299void llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
300 const TargetData *TD) {
301 Module *M = B.GetInsertBlock()->getParent()->getParent();
302 AttributeWithIndex AWI[3];
303 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
304 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
305 AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
306 Constant *F;
307 if (File->getType()->isPointerTy())
308 F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 3),
309 B.getInt32Ty(),
310 B.getInt8PtrTy(),
311 File->getType(), NULL);
312 else
313 F = M->getOrInsertFunction("fputs", B.getInt32Ty(),
314 B.getInt8PtrTy(),
315 File->getType(), NULL);
316 CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
317
318 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
319 CI->setCallingConv(Fn->getCallingConv());
320}
321
322/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
323/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
324void llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
325 IRBuilder<> &B, const TargetData *TD) {
326 Module *M = B.GetInsertBlock()->getParent()->getParent();
327 AttributeWithIndex AWI[3];
328 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
329 AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture);
330 AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
331 LLVMContext &Context = B.GetInsertBlock()->getContext();
332 Constant *F;
333 if (File->getType()->isPointerTy())
334 F = M->getOrInsertFunction("fwrite", AttrListPtr::get(AWI, 3),
335 TD->getIntPtrType(Context),
336 B.getInt8PtrTy(),
337 TD->getIntPtrType(Context),
338 TD->getIntPtrType(Context),
339 File->getType(), NULL);
340 else
341 F = M->getOrInsertFunction("fwrite", TD->getIntPtrType(Context),
342 B.getInt8PtrTy(),
343 TD->getIntPtrType(Context),
344 TD->getIntPtrType(Context),
345 File->getType(), NULL);
346 CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
347 ConstantInt::get(TD->getIntPtrType(Context), 1), File);
348
349 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
350 CI->setCallingConv(Fn->getCallingConv());
351}
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000352
Benjamin Kramera30b1812010-03-12 20:41:29 +0000353SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
354
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000355bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const TargetData *TD) {
Eric Christopher67a71b52010-04-12 04:48:00 +0000356 // We really need TargetData for later.
357 if (!TD) return false;
358
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000359 this->CI = CI;
Eric Christopher67a71b52010-04-12 04:48:00 +0000360 Function *Callee = CI->getCalledFunction();
361 StringRef Name = Callee->getName();
Chris Lattnerdb125cf2011-07-18 04:54:35 +0000362 FunctionType *FT = Callee->getFunctionType();
Eric Christopher67a71b52010-04-12 04:48:00 +0000363 LLVMContext &Context = CI->getParent()->getContext();
Eli Friedman1a24bf02011-05-27 01:00:36 +0000364 IRBuilder<> B(CI);
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000365
366 if (Name == "__memcpy_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000367 // Check if this has the right signature.
368 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
369 !FT->getParamType(0)->isPointerTy() ||
370 !FT->getParamType(1)->isPointerTy() ||
371 FT->getParamType(2) != TD->getIntPtrType(Context) ||
372 FT->getParamType(3) != TD->getIntPtrType(Context))
373 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000374
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000375 if (isFoldable(3, 2, false)) {
Benjamin Kramerdef548f2010-12-27 00:25:32 +0000376 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
377 CI->getArgOperand(2), 1);
Gabor Greiff148cb62010-06-28 12:29:20 +0000378 replaceCall(CI->getArgOperand(0));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000379 return true;
380 }
381 return false;
382 }
383
384 // Should be similar to memcpy.
385 if (Name == "__mempcpy_chk") {
386 return false;
387 }
388
389 if (Name == "__memmove_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000390 // Check if this has the right signature.
391 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
392 !FT->getParamType(0)->isPointerTy() ||
393 !FT->getParamType(1)->isPointerTy() ||
394 FT->getParamType(2) != TD->getIntPtrType(Context) ||
395 FT->getParamType(3) != TD->getIntPtrType(Context))
396 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000397
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000398 if (isFoldable(3, 2, false)) {
Benjamin Kramerdef548f2010-12-27 00:25:32 +0000399 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
400 CI->getArgOperand(2), 1);
Gabor Greiff148cb62010-06-28 12:29:20 +0000401 replaceCall(CI->getArgOperand(0));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000402 return true;
403 }
404 return false;
405 }
406
407 if (Name == "__memset_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000408 // Check if this has the right signature.
409 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
410 !FT->getParamType(0)->isPointerTy() ||
411 !FT->getParamType(1)->isIntegerTy() ||
412 FT->getParamType(2) != TD->getIntPtrType(Context) ||
413 FT->getParamType(3) != TD->getIntPtrType(Context))
414 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000415
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000416 if (isFoldable(3, 2, false)) {
Gabor Greiff148cb62010-06-28 12:29:20 +0000417 Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000418 false);
Benjamin Kramerdef548f2010-12-27 00:25:32 +0000419 B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
Gabor Greiff1ba6512010-06-25 07:58:41 +0000420 replaceCall(CI->getArgOperand(0));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000421 return true;
422 }
423 return false;
424 }
425
426 if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000427 // Check if this has the right signature.
428 if (FT->getNumParams() != 3 ||
429 FT->getReturnType() != FT->getParamType(0) ||
430 FT->getParamType(0) != FT->getParamType(1) ||
431 FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
432 FT->getParamType(2) != TD->getIntPtrType(Context))
433 return 0;
434
435
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000436 // If a) we don't have any length information, or b) we know this will
437 // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our
438 // st[rp]cpy_chk call which may fail at runtime if the size is too long.
439 // TODO: It might be nice to get a maximum length out of the possible
440 // string lengths for varying.
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000441 if (isFoldable(2, 1, true)) {
Gabor Greiff148cb62010-06-28 12:29:20 +0000442 Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD,
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000443 Name.substr(2, 6));
444 replaceCall(Ret);
445 return true;
446 }
447 return false;
448 }
449
Eric Christopher71988f12010-04-07 23:00:07 +0000450 if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") {
Eric Christopher67a71b52010-04-12 04:48:00 +0000451 // Check if this has the right signature.
452 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
453 FT->getParamType(0) != FT->getParamType(1) ||
454 FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
455 !FT->getParamType(2)->isIntegerTy() ||
456 FT->getParamType(3) != TD->getIntPtrType(Context))
Eric Christopher2a7cb9d2010-04-13 16:41:29 +0000457 return false;
Gabor Greiff148cb62010-06-28 12:29:20 +0000458
Gabor Greifa6aac4c2010-07-16 09:38:02 +0000459 if (isFoldable(3, 2, false)) {
Gabor Greiff148cb62010-06-28 12:29:20 +0000460 Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
461 CI->getArgOperand(2), B, TD, Name.substr(2, 7));
Benjamin Kramer0b6cb502010-03-12 09:27:41 +0000462 replaceCall(Ret);
463 return true;
464 }
465 return false;
466 }
467
468 if (Name == "__strcat_chk") {
469 return false;
470 }
471
472 if (Name == "__strncat_chk") {
473 return false;
474 }
475
476 return false;
477}