File: | lib/CodeGen/IntrinsicLowering.cpp |
Location: | line 74, column 24 |
Description: | Called C++ object pointer is null |
1 | //===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// | |||
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 the IntrinsicLowering class. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "llvm/CodeGen/IntrinsicLowering.h" | |||
15 | #include "llvm/ADT/SmallVector.h" | |||
16 | #include "llvm/IR/CallSite.h" | |||
17 | #include "llvm/IR/Constants.h" | |||
18 | #include "llvm/IR/DataLayout.h" | |||
19 | #include "llvm/IR/DerivedTypes.h" | |||
20 | #include "llvm/IR/IRBuilder.h" | |||
21 | #include "llvm/IR/Module.h" | |||
22 | #include "llvm/IR/Type.h" | |||
23 | #include "llvm/Support/ErrorHandling.h" | |||
24 | #include "llvm/Support/raw_ostream.h" | |||
25 | using namespace llvm; | |||
26 | ||||
27 | template <class ArgIt> | |||
28 | static void EnsureFunctionExists(Module &M, const char *Name, | |||
29 | ArgIt ArgBegin, ArgIt ArgEnd, | |||
30 | Type *RetTy) { | |||
31 | // Insert a correctly-typed definition now. | |||
32 | std::vector<Type *> ParamTys; | |||
33 | for (ArgIt I = ArgBegin; I != ArgEnd; ++I) | |||
34 | ParamTys.push_back(I->getType()); | |||
35 | M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); | |||
36 | } | |||
37 | ||||
38 | static void EnsureFPIntrinsicsExist(Module &M, Function *Fn, | |||
39 | const char *FName, | |||
40 | const char *DName, const char *LDName) { | |||
41 | // Insert definitions for all the floating point types. | |||
42 | switch((int)Fn->arg_begin()->getType()->getTypeID()) { | |||
43 | case Type::FloatTyID: | |||
44 | EnsureFunctionExists(M, FName, Fn->arg_begin(), Fn->arg_end(), | |||
45 | Type::getFloatTy(M.getContext())); | |||
46 | break; | |||
47 | case Type::DoubleTyID: | |||
48 | EnsureFunctionExists(M, DName, Fn->arg_begin(), Fn->arg_end(), | |||
49 | Type::getDoubleTy(M.getContext())); | |||
50 | break; | |||
51 | case Type::X86_FP80TyID: | |||
52 | case Type::FP128TyID: | |||
53 | case Type::PPC_FP128TyID: | |||
54 | EnsureFunctionExists(M, LDName, Fn->arg_begin(), Fn->arg_end(), | |||
55 | Fn->arg_begin()->getType()); | |||
56 | break; | |||
57 | } | |||
58 | } | |||
59 | ||||
60 | /// ReplaceCallWith - This function is used when we want to lower an intrinsic | |||
61 | /// call to a call of an external function. This handles hard cases such as | |||
62 | /// when there was already a prototype for the external function, and if that | |||
63 | /// prototype doesn't match the arguments we expect to pass in. | |||
64 | template <class ArgIt> | |||
65 | static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, | |||
66 | ArgIt ArgBegin, ArgIt ArgEnd, | |||
67 | Type *RetTy) { | |||
68 | // If we haven't already looked up this function, check to see if the | |||
69 | // program already contains a function with this name. | |||
70 | Module *M = CI->getParent()->getParent()->getParent(); | |||
71 | // Get or insert the definition now. | |||
72 | std::vector<Type *> ParamTys; | |||
73 | for (ArgIt I = ArgBegin; I != ArgEnd; ++I) | |||
74 | ParamTys.push_back((*I)->getType()); | |||
| ||||
75 | Constant* FCache = M->getOrInsertFunction(NewFn, | |||
76 | FunctionType::get(RetTy, ParamTys, false)); | |||
77 | ||||
78 | IRBuilder<> Builder(CI->getParent(), CI); | |||
79 | SmallVector<Value *, 8> Args(ArgBegin, ArgEnd); | |||
80 | CallInst *NewCI = Builder.CreateCall(FCache, Args); | |||
81 | NewCI->setName(CI->getName()); | |||
82 | if (!CI->use_empty()) | |||
83 | CI->replaceAllUsesWith(NewCI); | |||
84 | return NewCI; | |||
85 | } | |||
86 | ||||
87 | // VisualStudio defines setjmp as _setjmp | |||
88 | #if defined(_MSC_VER) && defined(setjmp) && \ | |||
89 | !defined(setjmp_undefined_for_msvc) | |||
90 | # pragma push_macro("setjmp") | |||
91 | # undef setjmp | |||
92 | # define setjmp_undefined_for_msvc | |||
93 | #endif | |||
94 | ||||
95 | void IntrinsicLowering::AddPrototypes(Module &M) { | |||
96 | LLVMContext &Context = M.getContext(); | |||
97 | for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) | |||
98 | if (I->isDeclaration() && !I->use_empty()) | |||
99 | switch (I->getIntrinsicID()) { | |||
100 | default: break; | |||
101 | case Intrinsic::setjmp: | |||
102 | EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(), | |||
103 | Type::getInt32Ty(M.getContext())); | |||
104 | break; | |||
105 | case Intrinsic::longjmp: | |||
106 | EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(), | |||
107 | Type::getVoidTy(M.getContext())); | |||
108 | break; | |||
109 | case Intrinsic::siglongjmp: | |||
110 | EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(), | |||
111 | Type::getVoidTy(M.getContext())); | |||
112 | break; | |||
113 | case Intrinsic::memcpy: | |||
114 | M.getOrInsertFunction("memcpy", | |||
115 | Type::getInt8PtrTy(Context), | |||
116 | Type::getInt8PtrTy(Context), | |||
117 | Type::getInt8PtrTy(Context), | |||
118 | DL.getIntPtrType(Context), nullptr); | |||
119 | break; | |||
120 | case Intrinsic::memmove: | |||
121 | M.getOrInsertFunction("memmove", | |||
122 | Type::getInt8PtrTy(Context), | |||
123 | Type::getInt8PtrTy(Context), | |||
124 | Type::getInt8PtrTy(Context), | |||
125 | DL.getIntPtrType(Context), nullptr); | |||
126 | break; | |||
127 | case Intrinsic::memset: | |||
128 | M.getOrInsertFunction("memset", | |||
129 | Type::getInt8PtrTy(Context), | |||
130 | Type::getInt8PtrTy(Context), | |||
131 | Type::getInt32Ty(M.getContext()), | |||
132 | DL.getIntPtrType(Context), nullptr); | |||
133 | break; | |||
134 | case Intrinsic::sqrt: | |||
135 | EnsureFPIntrinsicsExist(M, I, "sqrtf", "sqrt", "sqrtl"); | |||
136 | break; | |||
137 | case Intrinsic::sin: | |||
138 | EnsureFPIntrinsicsExist(M, I, "sinf", "sin", "sinl"); | |||
139 | break; | |||
140 | case Intrinsic::cos: | |||
141 | EnsureFPIntrinsicsExist(M, I, "cosf", "cos", "cosl"); | |||
142 | break; | |||
143 | case Intrinsic::pow: | |||
144 | EnsureFPIntrinsicsExist(M, I, "powf", "pow", "powl"); | |||
145 | break; | |||
146 | case Intrinsic::log: | |||
147 | EnsureFPIntrinsicsExist(M, I, "logf", "log", "logl"); | |||
148 | break; | |||
149 | case Intrinsic::log2: | |||
150 | EnsureFPIntrinsicsExist(M, I, "log2f", "log2", "log2l"); | |||
151 | break; | |||
152 | case Intrinsic::log10: | |||
153 | EnsureFPIntrinsicsExist(M, I, "log10f", "log10", "log10l"); | |||
154 | break; | |||
155 | case Intrinsic::exp: | |||
156 | EnsureFPIntrinsicsExist(M, I, "expf", "exp", "expl"); | |||
157 | break; | |||
158 | case Intrinsic::exp2: | |||
159 | EnsureFPIntrinsicsExist(M, I, "exp2f", "exp2", "exp2l"); | |||
160 | break; | |||
161 | } | |||
162 | } | |||
163 | ||||
164 | /// LowerBSWAP - Emit the code to lower bswap of V before the specified | |||
165 | /// instruction IP. | |||
166 | static Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) { | |||
167 | assert(V->getType()->isIntegerTy() && "Can't bswap a non-integer type!")((V->getType()->isIntegerTy() && "Can't bswap a non-integer type!" ) ? static_cast<void> (0) : __assert_fail ("V->getType()->isIntegerTy() && \"Can't bswap a non-integer type!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn223349/lib/CodeGen/IntrinsicLowering.cpp" , 167, __PRETTY_FUNCTION__)); | |||
168 | ||||
169 | unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); | |||
170 | ||||
171 | IRBuilder<> Builder(IP->getParent(), IP); | |||
172 | ||||
173 | switch(BitSize) { | |||
174 | default: llvm_unreachable("Unhandled type size of value to byteswap!")::llvm::llvm_unreachable_internal("Unhandled type size of value to byteswap!" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn223349/lib/CodeGen/IntrinsicLowering.cpp" , 174); | |||
175 | case 16: { | |||
176 | Value *Tmp1 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), | |||
177 | "bswap.2"); | |||
178 | Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), | |||
179 | "bswap.1"); | |||
180 | V = Builder.CreateOr(Tmp1, Tmp2, "bswap.i16"); | |||
181 | break; | |||
182 | } | |||
183 | case 32: { | |||
184 | Value *Tmp4 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), | |||
185 | "bswap.4"); | |||
186 | Value *Tmp3 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), | |||
187 | "bswap.3"); | |||
188 | Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), | |||
189 | "bswap.2"); | |||
190 | Value *Tmp1 = Builder.CreateLShr(V,ConstantInt::get(V->getType(), 24), | |||
191 | "bswap.1"); | |||
192 | Tmp3 = Builder.CreateAnd(Tmp3, | |||
193 | ConstantInt::get(Type::getInt32Ty(Context), 0xFF0000), | |||
194 | "bswap.and3"); | |||
195 | Tmp2 = Builder.CreateAnd(Tmp2, | |||
196 | ConstantInt::get(Type::getInt32Ty(Context), 0xFF00), | |||
197 | "bswap.and2"); | |||
198 | Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or1"); | |||
199 | Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or2"); | |||
200 | V = Builder.CreateOr(Tmp4, Tmp2, "bswap.i32"); | |||
201 | break; | |||
202 | } | |||
203 | case 64: { | |||
204 | Value *Tmp8 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 56), | |||
205 | "bswap.8"); | |||
206 | Value *Tmp7 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 40), | |||
207 | "bswap.7"); | |||
208 | Value *Tmp6 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), | |||
209 | "bswap.6"); | |||
210 | Value *Tmp5 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), | |||
211 | "bswap.5"); | |||
212 | Value* Tmp4 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), | |||
213 | "bswap.4"); | |||
214 | Value* Tmp3 = Builder.CreateLShr(V, | |||
215 | ConstantInt::get(V->getType(), 24), | |||
216 | "bswap.3"); | |||
217 | Value* Tmp2 = Builder.CreateLShr(V, | |||
218 | ConstantInt::get(V->getType(), 40), | |||
219 | "bswap.2"); | |||
220 | Value* Tmp1 = Builder.CreateLShr(V, | |||
221 | ConstantInt::get(V->getType(), 56), | |||
222 | "bswap.1"); | |||
223 | Tmp7 = Builder.CreateAnd(Tmp7, | |||
224 | ConstantInt::get(Type::getInt64Ty(Context), | |||
225 | 0xFF000000000000ULL), | |||
226 | "bswap.and7"); | |||
227 | Tmp6 = Builder.CreateAnd(Tmp6, | |||
228 | ConstantInt::get(Type::getInt64Ty(Context), | |||
229 | 0xFF0000000000ULL), | |||
230 | "bswap.and6"); | |||
231 | Tmp5 = Builder.CreateAnd(Tmp5, | |||
232 | ConstantInt::get(Type::getInt64Ty(Context), | |||
233 | 0xFF00000000ULL), | |||
234 | "bswap.and5"); | |||
235 | Tmp4 = Builder.CreateAnd(Tmp4, | |||
236 | ConstantInt::get(Type::getInt64Ty(Context), | |||
237 | 0xFF000000ULL), | |||
238 | "bswap.and4"); | |||
239 | Tmp3 = Builder.CreateAnd(Tmp3, | |||
240 | ConstantInt::get(Type::getInt64Ty(Context), | |||
241 | 0xFF0000ULL), | |||
242 | "bswap.and3"); | |||
243 | Tmp2 = Builder.CreateAnd(Tmp2, | |||
244 | ConstantInt::get(Type::getInt64Ty(Context), | |||
245 | 0xFF00ULL), | |||
246 | "bswap.and2"); | |||
247 | Tmp8 = Builder.CreateOr(Tmp8, Tmp7, "bswap.or1"); | |||
248 | Tmp6 = Builder.CreateOr(Tmp6, Tmp5, "bswap.or2"); | |||
249 | Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or3"); | |||
250 | Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or4"); | |||
251 | Tmp8 = Builder.CreateOr(Tmp8, Tmp6, "bswap.or5"); | |||
252 | Tmp4 = Builder.CreateOr(Tmp4, Tmp2, "bswap.or6"); | |||
253 | V = Builder.CreateOr(Tmp8, Tmp4, "bswap.i64"); | |||
254 | break; | |||
255 | } | |||
256 | } | |||
257 | return V; | |||
258 | } | |||
259 | ||||
260 | /// LowerCTPOP - Emit the code to lower ctpop of V before the specified | |||
261 | /// instruction IP. | |||
262 | static Value *LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP) { | |||
263 | assert(V->getType()->isIntegerTy() && "Can't ctpop a non-integer type!")((V->getType()->isIntegerTy() && "Can't ctpop a non-integer type!" ) ? static_cast<void> (0) : __assert_fail ("V->getType()->isIntegerTy() && \"Can't ctpop a non-integer type!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn223349/lib/CodeGen/IntrinsicLowering.cpp" , 263, __PRETTY_FUNCTION__)); | |||
264 | ||||
265 | static const uint64_t MaskValues[6] = { | |||
266 | 0x5555555555555555ULL, 0x3333333333333333ULL, | |||
267 | 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL, | |||
268 | 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL | |||
269 | }; | |||
270 | ||||
271 | IRBuilder<> Builder(IP->getParent(), IP); | |||
272 | ||||
273 | unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); | |||
274 | unsigned WordSize = (BitSize + 63) / 64; | |||
275 | Value *Count = ConstantInt::get(V->getType(), 0); | |||
276 | ||||
277 | for (unsigned n = 0; n < WordSize; ++n) { | |||
278 | Value *PartValue = V; | |||
279 | for (unsigned i = 1, ct = 0; i < (BitSize>64 ? 64 : BitSize); | |||
280 | i <<= 1, ++ct) { | |||
281 | Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]); | |||
282 | Value *LHS = Builder.CreateAnd(PartValue, MaskCst, "cppop.and1"); | |||
283 | Value *VShift = Builder.CreateLShr(PartValue, | |||
284 | ConstantInt::get(V->getType(), i), | |||
285 | "ctpop.sh"); | |||
286 | Value *RHS = Builder.CreateAnd(VShift, MaskCst, "cppop.and2"); | |||
287 | PartValue = Builder.CreateAdd(LHS, RHS, "ctpop.step"); | |||
288 | } | |||
289 | Count = Builder.CreateAdd(PartValue, Count, "ctpop.part"); | |||
290 | if (BitSize > 64) { | |||
291 | V = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 64), | |||
292 | "ctpop.part.sh"); | |||
293 | BitSize -= 64; | |||
294 | } | |||
295 | } | |||
296 | ||||
297 | return Count; | |||
298 | } | |||
299 | ||||
300 | /// LowerCTLZ - Emit the code to lower ctlz of V before the specified | |||
301 | /// instruction IP. | |||
302 | static Value *LowerCTLZ(LLVMContext &Context, Value *V, Instruction *IP) { | |||
303 | ||||
304 | IRBuilder<> Builder(IP->getParent(), IP); | |||
305 | ||||
306 | unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); | |||
307 | for (unsigned i = 1; i < BitSize; i <<= 1) { | |||
308 | Value *ShVal = ConstantInt::get(V->getType(), i); | |||
309 | ShVal = Builder.CreateLShr(V, ShVal, "ctlz.sh"); | |||
310 | V = Builder.CreateOr(V, ShVal, "ctlz.step"); | |||
311 | } | |||
312 | ||||
313 | V = Builder.CreateNot(V); | |||
314 | return LowerCTPOP(Context, V, IP); | |||
315 | } | |||
316 | ||||
317 | static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, | |||
318 | const char *Dname, | |||
319 | const char *LDname) { | |||
320 | CallSite CS(CI); | |||
321 | switch (CI->getArgOperand(0)->getType()->getTypeID()) { | |||
322 | default: llvm_unreachable("Invalid type in intrinsic")::llvm::llvm_unreachable_internal("Invalid type in intrinsic" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn223349/lib/CodeGen/IntrinsicLowering.cpp" , 322); | |||
323 | case Type::FloatTyID: | |||
324 | ReplaceCallWith(Fname, CI, CS.arg_begin(), CS.arg_end(), | |||
325 | Type::getFloatTy(CI->getContext())); | |||
326 | break; | |||
327 | case Type::DoubleTyID: | |||
328 | ReplaceCallWith(Dname, CI, CS.arg_begin(), CS.arg_end(), | |||
329 | Type::getDoubleTy(CI->getContext())); | |||
330 | break; | |||
331 | case Type::X86_FP80TyID: | |||
332 | case Type::FP128TyID: | |||
333 | case Type::PPC_FP128TyID: | |||
334 | ReplaceCallWith(LDname, CI, CS.arg_begin(), CS.arg_end(), | |||
335 | CI->getArgOperand(0)->getType()); | |||
336 | break; | |||
337 | } | |||
338 | } | |||
339 | ||||
340 | void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { | |||
341 | IRBuilder<> Builder(CI->getParent(), CI); | |||
342 | LLVMContext &Context = CI->getContext(); | |||
343 | ||||
344 | const Function *Callee = CI->getCalledFunction(); | |||
345 | assert(Callee && "Cannot lower an indirect call!")((Callee && "Cannot lower an indirect call!") ? static_cast <void> (0) : __assert_fail ("Callee && \"Cannot lower an indirect call!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn223349/lib/CodeGen/IntrinsicLowering.cpp" , 345, __PRETTY_FUNCTION__)); | |||
346 | ||||
347 | CallSite CS(CI); | |||
348 | switch (Callee->getIntrinsicID()) { | |||
| ||||
349 | case Intrinsic::not_intrinsic: | |||
350 | report_fatal_error("Cannot lower a call to a non-intrinsic function '"+ | |||
351 | Callee->getName() + "'!"); | |||
352 | default: | |||
353 | report_fatal_error("Code generator does not support intrinsic function '"+ | |||
354 | Callee->getName()+"'!"); | |||
355 | ||||
356 | case Intrinsic::expect: { | |||
357 | // Just replace __builtin_expect(exp, c) with EXP. | |||
358 | Value *V = CI->getArgOperand(0); | |||
359 | CI->replaceAllUsesWith(V); | |||
360 | break; | |||
361 | } | |||
362 | ||||
363 | // The setjmp/longjmp intrinsics should only exist in the code if it was | |||
364 | // never optimized (ie, right out of the CFE), or if it has been hacked on | |||
365 | // by the lowerinvoke pass. In both cases, the right thing to do is to | |||
366 | // convert the call to an explicit setjmp or longjmp call. | |||
367 | case Intrinsic::setjmp: { | |||
368 | Value *V = ReplaceCallWith("setjmp", CI, CS.arg_begin(), CS.arg_end(), | |||
369 | Type::getInt32Ty(Context)); | |||
370 | if (!CI->getType()->isVoidTy()) | |||
371 | CI->replaceAllUsesWith(V); | |||
372 | break; | |||
373 | } | |||
374 | case Intrinsic::sigsetjmp: | |||
375 | if (!CI->getType()->isVoidTy()) | |||
376 | CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); | |||
377 | break; | |||
378 | ||||
379 | case Intrinsic::longjmp: { | |||
380 | ReplaceCallWith("longjmp", CI, CS.arg_begin(), CS.arg_end(), | |||
381 | Type::getVoidTy(Context)); | |||
382 | break; | |||
383 | } | |||
384 | ||||
385 | case Intrinsic::siglongjmp: { | |||
386 | // Insert the call to abort | |||
387 | ReplaceCallWith("abort", CI, CS.arg_end(), CS.arg_end(), | |||
388 | Type::getVoidTy(Context)); | |||
389 | break; | |||
390 | } | |||
391 | case Intrinsic::ctpop: | |||
392 | CI->replaceAllUsesWith(LowerCTPOP(Context, CI->getArgOperand(0), CI)); | |||
393 | break; | |||
394 | ||||
395 | case Intrinsic::bswap: | |||
396 | CI->replaceAllUsesWith(LowerBSWAP(Context, CI->getArgOperand(0), CI)); | |||
397 | break; | |||
398 | ||||
399 | case Intrinsic::ctlz: | |||
400 | CI->replaceAllUsesWith(LowerCTLZ(Context, CI->getArgOperand(0), CI)); | |||
401 | break; | |||
402 | ||||
403 | case Intrinsic::cttz: { | |||
404 | // cttz(x) -> ctpop(~X & (X-1)) | |||
405 | Value *Src = CI->getArgOperand(0); | |||
406 | Value *NotSrc = Builder.CreateNot(Src); | |||
407 | NotSrc->setName(Src->getName() + ".not"); | |||
408 | Value *SrcM1 = ConstantInt::get(Src->getType(), 1); | |||
409 | SrcM1 = Builder.CreateSub(Src, SrcM1); | |||
410 | Src = LowerCTPOP(Context, Builder.CreateAnd(NotSrc, SrcM1), CI); | |||
411 | CI->replaceAllUsesWith(Src); | |||
412 | break; | |||
413 | } | |||
414 | ||||
415 | case Intrinsic::stacksave: | |||
416 | case Intrinsic::stackrestore: { | |||
417 | if (!Warned) | |||
418 | errs() << "WARNING: this target does not support the llvm.stack" | |||
419 | << (Callee->getIntrinsicID() == Intrinsic::stacksave ? | |||
420 | "save" : "restore") << " intrinsic.\n"; | |||
421 | Warned = true; | |||
422 | if (Callee->getIntrinsicID() == Intrinsic::stacksave) | |||
423 | CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); | |||
424 | break; | |||
425 | } | |||
426 | ||||
427 | case Intrinsic::returnaddress: | |||
428 | case Intrinsic::frameaddress: | |||
429 | errs() << "WARNING: this target does not support the llvm." | |||
430 | << (Callee->getIntrinsicID() == Intrinsic::returnaddress ? | |||
431 | "return" : "frame") << "address intrinsic.\n"; | |||
432 | CI->replaceAllUsesWith(ConstantPointerNull::get( | |||
433 | cast<PointerType>(CI->getType()))); | |||
434 | break; | |||
435 | ||||
436 | case Intrinsic::prefetch: | |||
437 | break; // Simply strip out prefetches on unsupported architectures | |||
438 | ||||
439 | case Intrinsic::pcmarker: | |||
440 | break; // Simply strip out pcmarker on unsupported architectures | |||
441 | case Intrinsic::readcyclecounter: { | |||
442 | errs() << "WARNING: this target does not support the llvm.readcyclecoun" | |||
443 | << "ter intrinsic. It is being lowered to a constant 0\n"; | |||
444 | CI->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context), 0)); | |||
445 | break; | |||
446 | } | |||
447 | ||||
448 | case Intrinsic::dbg_declare: | |||
449 | break; // Simply strip out debugging intrinsics | |||
450 | ||||
451 | case Intrinsic::eh_typeid_for: | |||
452 | // Return something different to eh_selector. | |||
453 | CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); | |||
454 | break; | |||
455 | ||||
456 | case Intrinsic::annotation: | |||
457 | case Intrinsic::ptr_annotation: | |||
458 | // Just drop the annotation, but forward the value | |||
459 | CI->replaceAllUsesWith(CI->getOperand(0)); | |||
460 | break; | |||
461 | ||||
462 | case Intrinsic::assume: | |||
463 | case Intrinsic::var_annotation: | |||
464 | break; // Strip out these intrinsics | |||
465 | ||||
466 | case Intrinsic::memcpy: { | |||
467 | Type *IntPtr = DL.getIntPtrType(Context); | |||
468 | Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, | |||
469 | /* isSigned */ false); | |||
470 | Value *Ops[3]; | |||
471 | Ops[0] = CI->getArgOperand(0); | |||
472 | Ops[1] = CI->getArgOperand(1); | |||
473 | Ops[2] = Size; | |||
474 | ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); | |||
475 | break; | |||
476 | } | |||
477 | case Intrinsic::memmove: { | |||
478 | Type *IntPtr = DL.getIntPtrType(Context); | |||
479 | Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, | |||
480 | /* isSigned */ false); | |||
481 | Value *Ops[3]; | |||
482 | Ops[0] = CI->getArgOperand(0); | |||
483 | Ops[1] = CI->getArgOperand(1); | |||
484 | Ops[2] = Size; | |||
485 | ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); | |||
486 | break; | |||
487 | } | |||
488 | case Intrinsic::memset: { | |||
489 | Value *Op0 = CI->getArgOperand(0); | |||
490 | Type *IntPtr = DL.getIntPtrType(Op0->getType()); | |||
491 | Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, | |||
492 | /* isSigned */ false); | |||
493 | Value *Ops[3]; | |||
494 | Ops[0] = Op0; | |||
495 | // Extend the amount to i32. | |||
496 | Ops[1] = Builder.CreateIntCast(CI->getArgOperand(1), | |||
497 | Type::getInt32Ty(Context), | |||
498 | /* isSigned */ false); | |||
499 | Ops[2] = Size; | |||
500 | ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); | |||
501 | break; | |||
502 | } | |||
503 | case Intrinsic::sqrt: { | |||
504 | ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl"); | |||
505 | break; | |||
506 | } | |||
507 | case Intrinsic::log: { | |||
508 | ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl"); | |||
509 | break; | |||
510 | } | |||
511 | case Intrinsic::log2: { | |||
512 | ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l"); | |||
513 | break; | |||
514 | } | |||
515 | case Intrinsic::log10: { | |||
516 | ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l"); | |||
517 | break; | |||
518 | } | |||
519 | case Intrinsic::exp: { | |||
520 | ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl"); | |||
521 | break; | |||
522 | } | |||
523 | case Intrinsic::exp2: { | |||
524 | ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l"); | |||
525 | break; | |||
526 | } | |||
527 | case Intrinsic::pow: { | |||
528 | ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl"); | |||
529 | break; | |||
530 | } | |||
531 | case Intrinsic::sin: { | |||
532 | ReplaceFPIntrinsicWithCall(CI, "sinf", "sin", "sinl"); | |||
533 | break; | |||
534 | } | |||
535 | case Intrinsic::cos: { | |||
536 | ReplaceFPIntrinsicWithCall(CI, "cosf", "cos", "cosl"); | |||
537 | break; | |||
538 | } | |||
539 | case Intrinsic::floor: { | |||
540 | ReplaceFPIntrinsicWithCall(CI, "floorf", "floor", "floorl"); | |||
541 | break; | |||
542 | } | |||
543 | case Intrinsic::ceil: { | |||
544 | ReplaceFPIntrinsicWithCall(CI, "ceilf", "ceil", "ceill"); | |||
545 | break; | |||
546 | } | |||
547 | case Intrinsic::trunc: { | |||
548 | ReplaceFPIntrinsicWithCall(CI, "truncf", "trunc", "truncl"); | |||
549 | break; | |||
550 | } | |||
551 | case Intrinsic::round: { | |||
552 | ReplaceFPIntrinsicWithCall(CI, "roundf", "round", "roundl"); | |||
553 | break; | |||
554 | } | |||
555 | case Intrinsic::copysign: { | |||
556 | ReplaceFPIntrinsicWithCall(CI, "copysignf", "copysign", "copysignl"); | |||
557 | break; | |||
558 | } | |||
559 | case Intrinsic::flt_rounds: | |||
560 | // Lower to "round to the nearest" | |||
561 | if (!CI->getType()->isVoidTy()) | |||
562 | CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); | |||
563 | break; | |||
564 | case Intrinsic::invariant_start: | |||
565 | case Intrinsic::lifetime_start: | |||
566 | // Discard region information. | |||
567 | CI->replaceAllUsesWith(UndefValue::get(CI->getType())); | |||
568 | break; | |||
569 | case Intrinsic::invariant_end: | |||
570 | case Intrinsic::lifetime_end: | |||
571 | // Discard region information. | |||
572 | break; | |||
573 | } | |||
574 | ||||
575 | assert(CI->use_empty() &&((CI->use_empty() && "Lowering should have eliminated any uses of the intrinsic call!" ) ? static_cast<void> (0) : __assert_fail ("CI->use_empty() && \"Lowering should have eliminated any uses of the intrinsic call!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn223349/lib/CodeGen/IntrinsicLowering.cpp" , 576, __PRETTY_FUNCTION__)) | |||
576 | "Lowering should have eliminated any uses of the intrinsic call!")((CI->use_empty() && "Lowering should have eliminated any uses of the intrinsic call!" ) ? static_cast<void> (0) : __assert_fail ("CI->use_empty() && \"Lowering should have eliminated any uses of the intrinsic call!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn223349/lib/CodeGen/IntrinsicLowering.cpp" , 576, __PRETTY_FUNCTION__)); | |||
577 | CI->eraseFromParent(); | |||
578 | } | |||
579 | ||||
580 | bool IntrinsicLowering::LowerToByteSwap(CallInst *CI) { | |||
581 | // Verify this is a simple bswap. | |||
582 | if (CI->getNumArgOperands() != 1 || | |||
583 | CI->getType() != CI->getArgOperand(0)->getType() || | |||
584 | !CI->getType()->isIntegerTy()) | |||
585 | return false; | |||
586 | ||||
587 | IntegerType *Ty = dyn_cast<IntegerType>(CI->getType()); | |||
588 | if (!Ty) | |||
589 | return false; | |||
590 | ||||
591 | // Okay, we can do this xform, do so now. | |||
592 | Module *M = CI->getParent()->getParent()->getParent(); | |||
593 | Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Ty); | |||
594 | ||||
595 | Value *Op = CI->getArgOperand(0); | |||
596 | Op = CallInst::Create(Int, Op, CI->getName(), CI); | |||
597 | ||||
598 | CI->replaceAllUsesWith(Op); | |||
599 | CI->eraseFromParent(); | |||
600 | return true; | |||
601 | } |