blob: 0bad510324ecee27200372404665ab1250e9f87a [file] [log] [blame]
Chris Lattner3b66ecb2003-12-28 08:19:41 +00001//===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===//
Misha Brukmanedf128a2005-04-21 22:36:52 +00002//
Chris Lattner3b66ecb2003-12-28 08:19:41 +00003// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukmanedf128a2005-04-21 22:36:52 +00007//
Chris Lattner3b66ecb2003-12-28 08:19:41 +00008//===----------------------------------------------------------------------===//
9//
10// This file implements the default intrinsic lowering implementation.
11//
12//===----------------------------------------------------------------------===//
13
Chris Lattner30483732004-06-20 07:49:54 +000014#include "llvm/CodeGen/IntrinsicLowering.h"
Chris Lattnercf899082004-02-14 02:47:17 +000015#include "llvm/Constants.h"
Chris Lattner5fe51cc2004-02-12 17:01:09 +000016#include "llvm/DerivedTypes.h"
Chris Lattner3b66ecb2003-12-28 08:19:41 +000017#include "llvm/Module.h"
Misha Brukman47b14a42004-07-29 17:30:56 +000018#include "llvm/Instructions.h"
Andrew Lenharth691ef2b2005-05-03 17:19:30 +000019#include "llvm/Type.h"
Reid Spencer954da372004-07-04 12:19:56 +000020#include <iostream>
21
Chris Lattner3b66ecb2003-12-28 08:19:41 +000022using namespace llvm;
23
Chris Lattner0979ca72004-05-09 04:29:57 +000024template <class ArgIt>
25static Function *EnsureFunctionExists(Module &M, const char *Name,
26 ArgIt ArgBegin, ArgIt ArgEnd,
27 const Type *RetTy) {
28 if (Function *F = M.getNamedFunction(Name)) return F;
29 // It doesn't already exist in the program, insert a new definition now.
30 std::vector<const Type *> ParamTys;
31 for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
32 ParamTys.push_back(I->getType());
33 return M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false));
34}
35
Chris Lattner588e72d2004-02-15 22:16:39 +000036/// ReplaceCallWith - This function is used when we want to lower an intrinsic
37/// call to a call of an external function. This handles hard cases such as
38/// when there was already a prototype for the external function, and if that
39/// prototype doesn't match the arguments we expect to pass in.
40template <class ArgIt>
41static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI,
42 ArgIt ArgBegin, ArgIt ArgEnd,
43 const Type *RetTy, Function *&FCache) {
44 if (!FCache) {
45 // If we haven't already looked up this function, check to see if the
46 // program already contains a function with this name.
47 Module *M = CI->getParent()->getParent()->getParent();
48 FCache = M->getNamedFunction(NewFn);
49 if (!FCache) {
50 // It doesn't already exist in the program, insert a new definition now.
51 std::vector<const Type *> ParamTys;
52 for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
53 ParamTys.push_back((*I)->getType());
54 FCache = M->getOrInsertFunction(NewFn,
55 FunctionType::get(RetTy, ParamTys, false));
56 }
Chris Lattner0979ca72004-05-09 04:29:57 +000057 }
Chris Lattner588e72d2004-02-15 22:16:39 +000058
59 const FunctionType *FT = FCache->getFunctionType();
60 std::vector<Value*> Operands;
61 unsigned ArgNo = 0;
62 for (ArgIt I = ArgBegin; I != ArgEnd && ArgNo != FT->getNumParams();
63 ++I, ++ArgNo) {
64 Value *Arg = *I;
65 if (Arg->getType() != FT->getParamType(ArgNo))
66 Arg = new CastInst(Arg, FT->getParamType(ArgNo), Arg->getName(), CI);
67 Operands.push_back(Arg);
68 }
69 // Pass nulls into any additional arguments...
70 for (; ArgNo != FT->getNumParams(); ++ArgNo)
71 Operands.push_back(Constant::getNullValue(FT->getParamType(ArgNo)));
72
73 std::string Name = CI->getName(); CI->setName("");
74 if (FT->getReturnType() == Type::VoidTy) Name.clear();
Chris Lattner02348ca2004-06-11 02:54:02 +000075 CallInst *NewCI = new CallInst(FCache, Operands, Name, CI);
76 if (!CI->use_empty()) {
77 Value *V = NewCI;
78 if (CI->getType() != NewCI->getType())
79 V = new CastInst(NewCI, CI->getType(), Name, CI);
80 CI->replaceAllUsesWith(V);
81 }
82 return NewCI;
Chris Lattner588e72d2004-02-15 22:16:39 +000083}
84
Chris Lattner0979ca72004-05-09 04:29:57 +000085void DefaultIntrinsicLowering::AddPrototypes(Module &M) {
86 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
87 if (I->isExternal() && !I->use_empty())
88 switch (I->getIntrinsicID()) {
89 default: break;
90 case Intrinsic::setjmp:
Chris Lattnere4d5c442005-03-15 04:54:21 +000091 EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(), Type::IntTy);
Chris Lattner0979ca72004-05-09 04:29:57 +000092 break;
93 case Intrinsic::longjmp:
Chris Lattnere4d5c442005-03-15 04:54:21 +000094 EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(),Type::VoidTy);
Chris Lattner0979ca72004-05-09 04:29:57 +000095 break;
96 case Intrinsic::siglongjmp:
Chris Lattnere4d5c442005-03-15 04:54:21 +000097 EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(), Type::VoidTy);
Chris Lattner0979ca72004-05-09 04:29:57 +000098 break;
99 case Intrinsic::memcpy:
Chris Lattnere4d5c442005-03-15 04:54:21 +0000100 EnsureFunctionExists(M, "memcpy", I->arg_begin(), --I->arg_end(),
101 I->arg_begin()->getType());
Chris Lattner0979ca72004-05-09 04:29:57 +0000102 break;
103 case Intrinsic::memmove:
Chris Lattnere4d5c442005-03-15 04:54:21 +0000104 EnsureFunctionExists(M, "memmove", I->arg_begin(), --I->arg_end(),
105 I->arg_begin()->getType());
Chris Lattner0979ca72004-05-09 04:29:57 +0000106 break;
107 case Intrinsic::memset:
Chris Lattnere4d5c442005-03-15 04:54:21 +0000108 EnsureFunctionExists(M, "memset", I->arg_begin(), --I->arg_end(),
109 I->arg_begin()->getType());
Chris Lattner0979ca72004-05-09 04:29:57 +0000110 break;
Chris Lattnerbe78ac42004-06-15 21:42:23 +0000111 case Intrinsic::isunordered:
Chris Lattnere4d5c442005-03-15 04:54:21 +0000112 EnsureFunctionExists(M, "isunordered", I->arg_begin(), I->arg_end(), Type::BoolTy);
Chris Lattner02348ca2004-06-11 02:54:02 +0000113 break;
Chris Lattnerb42a9ff2005-04-30 04:07:50 +0000114 case Intrinsic::sqrt:
Alkis Evlogimenosb1beff02005-04-30 07:13:31 +0000115 if(I->arg_begin()->getType() == Type::FloatTy)
Chris Lattnerb42a9ff2005-04-30 04:07:50 +0000116 EnsureFunctionExists(M, "sqrtf", I->arg_begin(), I->arg_end(), Type::FloatTy);
117 else
118 EnsureFunctionExists(M, "sqrt", I->arg_begin(), I->arg_end(), Type::DoubleTy);
119 break;
Chris Lattner0979ca72004-05-09 04:29:57 +0000120 }
Chris Lattner0979ca72004-05-09 04:29:57 +0000121}
Chris Lattner588e72d2004-02-15 22:16:39 +0000122
Chris Lattner3b66ecb2003-12-28 08:19:41 +0000123void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
124 Function *Callee = CI->getCalledFunction();
125 assert(Callee && "Cannot lower an indirect call!");
Misha Brukmanedf128a2005-04-21 22:36:52 +0000126
Chris Lattner3b66ecb2003-12-28 08:19:41 +0000127 switch (Callee->getIntrinsicID()) {
128 case Intrinsic::not_intrinsic:
129 std::cerr << "Cannot lower a call to a non-intrinsic function '"
130 << Callee->getName() << "'!\n";
131 abort();
132 default:
133 std::cerr << "Error: Code generator does not support intrinsic function '"
134 << Callee->getName() << "'!\n";
135 abort();
136
Chris Lattner588e72d2004-02-15 22:16:39 +0000137 // The setjmp/longjmp intrinsics should only exist in the code if it was
138 // never optimized (ie, right out of the CFE), or if it has been hacked on
139 // by the lowerinvoke pass. In both cases, the right thing to do is to
140 // convert the call to an explicit setjmp or longjmp call.
Chris Lattner9b700f72004-02-15 22:24:51 +0000141 case Intrinsic::setjmp: {
142 static Function *SetjmpFCache = 0;
143 Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin()+1, CI->op_end(),
144 Type::IntTy, SetjmpFCache);
Chris Lattner3b66ecb2003-12-28 08:19:41 +0000145 if (CI->getType() != Type::VoidTy)
Chris Lattner9b700f72004-02-15 22:24:51 +0000146 CI->replaceAllUsesWith(V);
Chris Lattner3b66ecb2003-12-28 08:19:41 +0000147 break;
Chris Lattner9b700f72004-02-15 22:24:51 +0000148 }
Misha Brukmanedf128a2005-04-21 22:36:52 +0000149 case Intrinsic::sigsetjmp:
Chris Lattner9b700f72004-02-15 22:24:51 +0000150 if (CI->getType() != Type::VoidTy)
151 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
152 break;
Chris Lattner3b66ecb2003-12-28 08:19:41 +0000153
Chris Lattnerf0a3e6c2004-06-05 01:05:19 +0000154 case Intrinsic::longjmp: {
Chris Lattner9b700f72004-02-15 22:24:51 +0000155 static Function *LongjmpFCache = 0;
156 ReplaceCallWith("longjmp", CI, CI->op_begin()+1, CI->op_end(),
157 Type::VoidTy, LongjmpFCache);
158 break;
Chris Lattnerf0a3e6c2004-06-05 01:05:19 +0000159 }
Chris Lattner9b700f72004-02-15 22:24:51 +0000160
Chris Lattnerf0a3e6c2004-06-05 01:05:19 +0000161 case Intrinsic::siglongjmp: {
Chris Lattner3b66ecb2003-12-28 08:19:41 +0000162 // Insert the call to abort
Chris Lattner588e72d2004-02-15 22:16:39 +0000163 static Function *AbortFCache = 0;
164 ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(), Type::VoidTy,
165 AbortFCache);
Chris Lattner3b66ecb2003-12-28 08:19:41 +0000166 break;
Chris Lattnerf0a3e6c2004-06-05 01:05:19 +0000167 }
Andrew Lenharth691ef2b2005-05-03 17:19:30 +0000168 case Intrinsic::ctpop: {
169 Value *Src = CI->getOperand(1);
170 switch (CI->getOperand(0)->getType()->getTypeID())
171 {
172 case Type::SByteTyID:
173 case Type::UByteTyID:
174 {
175 Value* SA = ConstantUInt::get(Type::UByteTy, 1);
176 Value* MA = ConstantUInt::get(Type::UIntTy, 0x55);
177 Src = BinaryOperator::create(Instruction::Add,
178 BinaryOperator::create(Instruction::And, Src, MA),
179 BinaryOperator::create(Instruction::And,
180 new ShiftInst(Instruction::Shr, Src, SA),
181 MA));
182 SA = ConstantUInt::get(Type::UByteTy, 2);
183 MA = ConstantUInt::get(Type::UIntTy, 0x33);
184 Src = BinaryOperator::create(Instruction::Add,
185 BinaryOperator::create(Instruction::And, Src, MA),
186 BinaryOperator::create(Instruction::And,
187 new ShiftInst(Instruction::Shr, Src, SA),
188 MA));
189 SA = ConstantUInt::get(Type::UByteTy, 4);
190 MA = ConstantUInt::get(Type::UIntTy, 0x0F);
191 Src = BinaryOperator::create(Instruction::Add,
192 BinaryOperator::create(Instruction::And, Src, MA),
193 BinaryOperator::create(Instruction::And,
194 new ShiftInst(Instruction::Shr, Src, SA),
195 MA), "ctpop");
196 }
197 break;
198 case Type::ShortTyID:
199 case Type::UShortTyID:
200 {
201 Value* SA = ConstantUInt::get(Type::UByteTy, 1);
202 Value* MA = ConstantUInt::get(Type::UIntTy, 0x5555);
203 Src = BinaryOperator::create(Instruction::Add,
204 BinaryOperator::create(Instruction::And, Src, MA),
205 BinaryOperator::create(Instruction::And,
206 new ShiftInst(Instruction::Shr, Src, SA),
207 MA));
208 SA = ConstantUInt::get(Type::UByteTy, 2);
209 MA = ConstantUInt::get(Type::UIntTy, 0x3333);
210 Src = BinaryOperator::create(Instruction::Add,
211 BinaryOperator::create(Instruction::And, Src, MA),
212 BinaryOperator::create(Instruction::And,
213 new ShiftInst(Instruction::Shr, Src, SA),
214 MA));
215 SA = ConstantUInt::get(Type::UByteTy, 4);
216 MA = ConstantUInt::get(Type::UIntTy, 0x0F0F);
217 Src = BinaryOperator::create(Instruction::Add,
218 BinaryOperator::create(Instruction::And, Src, MA),
219 BinaryOperator::create(Instruction::And,
220 new ShiftInst(Instruction::Shr, Src, SA),
221 MA));
222 SA = ConstantUInt::get(Type::UByteTy, 8);
223 MA = ConstantUInt::get(Type::UIntTy, 0x00FF);
224 Src = BinaryOperator::create(Instruction::Add,
225 BinaryOperator::create(Instruction::And, Src, MA),
226 BinaryOperator::create(Instruction::And,
227 new ShiftInst(Instruction::Shr, Src, SA),
228 MA), "ctpop");
229
230 }
231 break;
232 case Type::IntTyID:
233 case Type::UIntTyID:
234 {
235 Value* SA = ConstantUInt::get(Type::UByteTy, 1);
236 Value* MA = ConstantUInt::get(Type::UIntTy, 0x55555555);
237 Src = BinaryOperator::create(Instruction::Add,
238 BinaryOperator::create(Instruction::And, Src, MA),
239 BinaryOperator::create(Instruction::And,
240 new ShiftInst(Instruction::Shr, Src, SA),
241 MA));
242 SA = ConstantUInt::get(Type::UByteTy, 2);
243 MA = ConstantUInt::get(Type::UIntTy, 0x33333333);
244 Src = BinaryOperator::create(Instruction::Add,
245 BinaryOperator::create(Instruction::And, Src, MA),
246 BinaryOperator::create(Instruction::And,
247 new ShiftInst(Instruction::Shr, Src, SA),
248 MA));
249 SA = ConstantUInt::get(Type::UByteTy, 4);
250 MA = ConstantUInt::get(Type::UIntTy, 0x0F0F0F0F);
251 Src = BinaryOperator::create(Instruction::Add,
252 BinaryOperator::create(Instruction::And, Src, MA),
253 BinaryOperator::create(Instruction::And,
254 new ShiftInst(Instruction::Shr, Src, SA),
255 MA));
256 SA = ConstantUInt::get(Type::UByteTy, 8);
257 MA = ConstantUInt::get(Type::UIntTy, 0x00FF00FF);
258 Src = BinaryOperator::create(Instruction::Add,
259 BinaryOperator::create(Instruction::And, Src, MA),
260 BinaryOperator::create(Instruction::And,
261 new ShiftInst(Instruction::Shr, Src, SA),
262 MA));
263 SA = ConstantUInt::get(Type::UByteTy, 8);
264 MA = ConstantUInt::get(Type::UIntTy, 0x0000FFFF);
265 Src = BinaryOperator::create(Instruction::Add,
266 BinaryOperator::create(Instruction::And, Src, MA),
267 BinaryOperator::create(Instruction::And,
268 new ShiftInst(Instruction::Shr, Src, SA),
269 MA), "ctpop");
270 }
271 break;
272 case Type::LongTyID:
273 case Type::ULongTyID:
274 {
275 Value* SA = ConstantUInt::get(Type::UByteTy, 1);
276 Value* MA = ConstantUInt::get(Type::ULongTy, 0x5555555555555555ULL);
277 Src = BinaryOperator::create(Instruction::Add,
278 BinaryOperator::create(Instruction::And, Src, MA),
279 BinaryOperator::create(Instruction::And,
280 new ShiftInst(Instruction::Shr, Src, SA),
281 MA));
282 SA = ConstantUInt::get(Type::UByteTy, 2);
283 MA = ConstantUInt::get(Type::ULongTy, 0x3333333333333333ULL);
284 Src = BinaryOperator::create(Instruction::Add,
285 BinaryOperator::create(Instruction::And, Src, MA),
286 BinaryOperator::create(Instruction::And,
287 new ShiftInst(Instruction::Shr, Src, SA),
288 MA));
289 SA = ConstantUInt::get(Type::UByteTy, 4);
290 MA = ConstantUInt::get(Type::ULongTy, 0x0F0F0F0F0F0F0F0FULL);
291 Src = BinaryOperator::create(Instruction::Add,
292 BinaryOperator::create(Instruction::And, Src, MA),
293 BinaryOperator::create(Instruction::And,
294 new ShiftInst(Instruction::Shr, Src, SA),
295 MA));
296 SA = ConstantUInt::get(Type::UByteTy, 8);
297 MA = ConstantUInt::get(Type::ULongTy, 0x00FF00FF00FF00FFULL);
298 Src = BinaryOperator::create(Instruction::Add,
299 BinaryOperator::create(Instruction::And, Src, MA),
300 BinaryOperator::create(Instruction::And,
301 new ShiftInst(Instruction::Shr, Src, SA),
302 MA));
303 SA = ConstantUInt::get(Type::UByteTy, 16);
304 MA = ConstantUInt::get(Type::ULongTy, 0x00000000FFFFFFFFULL);
305 Src = BinaryOperator::create(Instruction::Add,
306 BinaryOperator::create(Instruction::And, Src, MA),
307 BinaryOperator::create(Instruction::And,
308 new ShiftInst(Instruction::Shr, Src, SA),
309 MA), "ctpop");
310 }
311 break;
312 default:
313 abort();
314 }
315
316 CI->replaceAllUsesWith(Src);
317 break;
318 }
319 case Intrinsic::ctlz: {
320 Value *Src = CI->getOperand(1);
321 Value* SA;
322 switch (CI->getOperand(0)->getType()->getTypeID())
323 {
324 case Type::LongTyID:
325 case Type::ULongTyID:
326 SA = ConstantUInt::get(Type::UByteTy, 32);
327 Src = BinaryOperator::create(Instruction::Or, Src, new ShiftInst(Instruction::Shr, Src, SA));
328 case Type::IntTyID:
329 case Type::UIntTyID:
330 SA = ConstantUInt::get(Type::UByteTy, 16);
331 Src = BinaryOperator::create(Instruction::Or, Src, new ShiftInst(Instruction::Shr, Src, SA));
332 case Type::ShortTyID:
333 case Type::UShortTyID:
334 SA = ConstantUInt::get(Type::UByteTy, 8);
335 Src = BinaryOperator::create(Instruction::Or, Src, new ShiftInst(Instruction::Shr, Src, SA));
336 default:
337 SA = ConstantUInt::get(Type::UByteTy, 1);
338 Src = BinaryOperator::create(Instruction::Or, Src, new ShiftInst(Instruction::Shr, Src, SA));
339 SA = ConstantUInt::get(Type::UByteTy, 2);
340 Src = BinaryOperator::create(Instruction::Or, Src, new ShiftInst(Instruction::Shr, Src, SA));
341 SA = ConstantUInt::get(Type::UByteTy, 4);
342 Src = BinaryOperator::create(Instruction::Or, Src, new ShiftInst(Instruction::Shr, Src, SA));
343 };
344 Src = BinaryOperator::createNot(Src);
345
346 Src = new CallInst(new Function(CI->getCalledFunction()->getFunctionType(),
347 CI->getCalledFunction()->getLinkage(),
348 "llvm.ctpop"), Src);
349 CI->replaceAllUsesWith(Src);
350 break;
351 }
352 case Intrinsic::cttz: {
353 Value *Src = CI->getOperand(1);
354 Src = BinaryOperator::create(Instruction::And, BinaryOperator::createNot(Src),
355 BinaryOperator::create(Instruction::Sub, Src,
356 ConstantUInt::get(CI->getOperand(0)->getType(), 1)));
357 Src = new CallInst(new Function(CI->getCalledFunction()->getFunctionType(),
358 CI->getCalledFunction()->getLinkage(),
359 "llvm.ctpop"), Src);
360 CI->replaceAllUsesWith(Src);
361 break;
362 }
Chris Lattner77b13302004-01-05 05:36:30 +0000363
Chris Lattnercf899082004-02-14 02:47:17 +0000364 case Intrinsic::returnaddress:
365 case Intrinsic::frameaddress:
Chris Lattnercc42d2c2004-02-14 04:52:06 +0000366 std::cerr << "WARNING: this target does not support the llvm."
Misha Brukmanedf128a2005-04-21 22:36:52 +0000367 << (Callee->getIntrinsicID() == Intrinsic::returnaddress ?
Chris Lattnercc42d2c2004-02-14 04:52:06 +0000368 "return" : "frame") << "address intrinsic.\n";
Chris Lattnercf899082004-02-14 02:47:17 +0000369 CI->replaceAllUsesWith(ConstantPointerNull::get(
370 cast<PointerType>(CI->getType())));
371 break;
372
Chris Lattner0942b7c2005-02-28 19:27:23 +0000373 case Intrinsic::prefetch:
374 break; // Simply strip out prefetches on unsupported architectures
375
Andrew Lenharth7f4ec3b2005-03-28 20:05:49 +0000376 case Intrinsic::pcmarker:
377 break; // Simply strip out pcmarker on unsupported architectures
378
Chris Lattner77b13302004-01-05 05:36:30 +0000379 case Intrinsic::dbg_stoppoint:
380 case Intrinsic::dbg_region_start:
381 case Intrinsic::dbg_region_end:
Chris Lattnerf907bac2004-01-14 20:41:29 +0000382 case Intrinsic::dbg_declare:
Chris Lattner77b13302004-01-05 05:36:30 +0000383 case Intrinsic::dbg_func_start:
384 if (CI->getType() != Type::VoidTy)
385 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
386 break; // Simply strip out debugging intrinsics
Chris Lattner5fe51cc2004-02-12 17:01:09 +0000387
Chris Lattnerf0a3e6c2004-06-05 01:05:19 +0000388 case Intrinsic::memcpy: {
Chris Lattner5fe51cc2004-02-12 17:01:09 +0000389 // The memcpy intrinsic take an extra alignment argument that the memcpy
390 // libc function does not.
Chris Lattner588e72d2004-02-15 22:16:39 +0000391 static Function *MemcpyFCache = 0;
392 ReplaceCallWith("memcpy", CI, CI->op_begin()+1, CI->op_end()-1,
393 (*(CI->op_begin()+1))->getType(), MemcpyFCache);
Chris Lattner5fe51cc2004-02-12 17:01:09 +0000394 break;
Chris Lattnerf0a3e6c2004-06-05 01:05:19 +0000395 }
396 case Intrinsic::memmove: {
Chris Lattnercf899082004-02-14 02:47:17 +0000397 // The memmove intrinsic take an extra alignment argument that the memmove
Chris Lattner2751e762004-02-12 18:11:20 +0000398 // libc function does not.
Chris Lattner588e72d2004-02-15 22:16:39 +0000399 static Function *MemmoveFCache = 0;
400 ReplaceCallWith("memmove", CI, CI->op_begin()+1, CI->op_end()-1,
401 (*(CI->op_begin()+1))->getType(), MemmoveFCache);
Chris Lattner2751e762004-02-12 18:11:20 +0000402 break;
Chris Lattnerf0a3e6c2004-06-05 01:05:19 +0000403 }
404 case Intrinsic::memset: {
Chris Lattnercf899082004-02-14 02:47:17 +0000405 // The memset intrinsic take an extra alignment argument that the memset
406 // libc function does not.
Chris Lattner588e72d2004-02-15 22:16:39 +0000407 static Function *MemsetFCache = 0;
408 ReplaceCallWith("memset", CI, CI->op_begin()+1, CI->op_end()-1,
409 (*(CI->op_begin()+1))->getType(), MemsetFCache);
Chris Lattnercf899082004-02-14 02:47:17 +0000410 break;
411 }
Alkis Evlogimenos96853722004-06-12 19:19:14 +0000412 case Intrinsic::isunordered: {
Alkis Evlogimenosd0656fc2005-03-01 02:07:58 +0000413 Value *L = CI->getOperand(1);
414 Value *R = CI->getOperand(2);
415
416 Value *LIsNan = new SetCondInst(Instruction::SetNE, L, L, "LIsNan", CI);
417 Value *RIsNan = new SetCondInst(Instruction::SetNE, R, R, "RIsNan", CI);
418 CI->replaceAllUsesWith(
419 BinaryOperator::create(Instruction::Or, LIsNan, RIsNan,
420 "isunordered", CI));
Alkis Evlogimenos96853722004-06-12 19:19:14 +0000421 break;
422 }
Chris Lattnerb42a9ff2005-04-30 04:07:50 +0000423 case Intrinsic::sqrt: {
424 static Function *sqrtFCache = 0;
425 static Function *sqrtfFCache = 0;
426 if(CI->getType() == Type::FloatTy)
427 ReplaceCallWith("sqrtf", CI, CI->op_begin()+1, CI->op_end(),
428 Type::FloatTy, sqrtfFCache);
429 else
430 ReplaceCallWith("sqrt", CI, CI->op_begin()+1, CI->op_end(),
431 Type::DoubleTy, sqrtFCache);
432 break;
433 }
Chris Lattnerf0a3e6c2004-06-05 01:05:19 +0000434 }
Misha Brukmanedf128a2005-04-21 22:36:52 +0000435
Chris Lattner3b66ecb2003-12-28 08:19:41 +0000436 assert(CI->use_empty() &&
437 "Lowering should have eliminated any uses of the intrinsic call!");
438 CI->getParent()->getInstList().erase(CI);
439}