LLVM API Documentation
00001 //===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the IntrinsicLowering class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/CodeGen/IntrinsicLowering.h" 00015 #include "llvm/ADT/SmallVector.h" 00016 #include "llvm/IR/CallSite.h" 00017 #include "llvm/IR/Constants.h" 00018 #include "llvm/IR/DataLayout.h" 00019 #include "llvm/IR/DerivedTypes.h" 00020 #include "llvm/IR/IRBuilder.h" 00021 #include "llvm/IR/Module.h" 00022 #include "llvm/IR/Type.h" 00023 #include "llvm/Support/ErrorHandling.h" 00024 #include "llvm/Support/raw_ostream.h" 00025 using namespace llvm; 00026 00027 template <class ArgIt> 00028 static void EnsureFunctionExists(Module &M, const char *Name, 00029 ArgIt ArgBegin, ArgIt ArgEnd, 00030 Type *RetTy) { 00031 // Insert a correctly-typed definition now. 00032 std::vector<Type *> ParamTys; 00033 for (ArgIt I = ArgBegin; I != ArgEnd; ++I) 00034 ParamTys.push_back(I->getType()); 00035 M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); 00036 } 00037 00038 static void EnsureFPIntrinsicsExist(Module &M, Function *Fn, 00039 const char *FName, 00040 const char *DName, const char *LDName) { 00041 // Insert definitions for all the floating point types. 00042 switch((int)Fn->arg_begin()->getType()->getTypeID()) { 00043 case Type::FloatTyID: 00044 EnsureFunctionExists(M, FName, Fn->arg_begin(), Fn->arg_end(), 00045 Type::getFloatTy(M.getContext())); 00046 break; 00047 case Type::DoubleTyID: 00048 EnsureFunctionExists(M, DName, Fn->arg_begin(), Fn->arg_end(), 00049 Type::getDoubleTy(M.getContext())); 00050 break; 00051 case Type::X86_FP80TyID: 00052 case Type::FP128TyID: 00053 case Type::PPC_FP128TyID: 00054 EnsureFunctionExists(M, LDName, Fn->arg_begin(), Fn->arg_end(), 00055 Fn->arg_begin()->getType()); 00056 break; 00057 } 00058 } 00059 00060 /// ReplaceCallWith - This function is used when we want to lower an intrinsic 00061 /// call to a call of an external function. This handles hard cases such as 00062 /// when there was already a prototype for the external function, and if that 00063 /// prototype doesn't match the arguments we expect to pass in. 00064 template <class ArgIt> 00065 static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, 00066 ArgIt ArgBegin, ArgIt ArgEnd, 00067 Type *RetTy) { 00068 // If we haven't already looked up this function, check to see if the 00069 // program already contains a function with this name. 00070 Module *M = CI->getParent()->getParent()->getParent(); 00071 // Get or insert the definition now. 00072 std::vector<Type *> ParamTys; 00073 for (ArgIt I = ArgBegin; I != ArgEnd; ++I) 00074 ParamTys.push_back((*I)->getType()); 00075 Constant* FCache = M->getOrInsertFunction(NewFn, 00076 FunctionType::get(RetTy, ParamTys, false)); 00077 00078 IRBuilder<> Builder(CI->getParent(), CI); 00079 SmallVector<Value *, 8> Args(ArgBegin, ArgEnd); 00080 CallInst *NewCI = Builder.CreateCall(FCache, Args); 00081 NewCI->setName(CI->getName()); 00082 if (!CI->use_empty()) 00083 CI->replaceAllUsesWith(NewCI); 00084 return NewCI; 00085 } 00086 00087 // VisualStudio defines setjmp as _setjmp 00088 #if defined(_MSC_VER) && defined(setjmp) && \ 00089 !defined(setjmp_undefined_for_msvc) 00090 # pragma push_macro("setjmp") 00091 # undef setjmp 00092 # define setjmp_undefined_for_msvc 00093 #endif 00094 00095 void IntrinsicLowering::AddPrototypes(Module &M) { 00096 LLVMContext &Context = M.getContext(); 00097 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 00098 if (I->isDeclaration() && !I->use_empty()) 00099 switch (I->getIntrinsicID()) { 00100 default: break; 00101 case Intrinsic::setjmp: 00102 EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(), 00103 Type::getInt32Ty(M.getContext())); 00104 break; 00105 case Intrinsic::longjmp: 00106 EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(), 00107 Type::getVoidTy(M.getContext())); 00108 break; 00109 case Intrinsic::siglongjmp: 00110 EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(), 00111 Type::getVoidTy(M.getContext())); 00112 break; 00113 case Intrinsic::memcpy: 00114 M.getOrInsertFunction("memcpy", 00115 Type::getInt8PtrTy(Context), 00116 Type::getInt8PtrTy(Context), 00117 Type::getInt8PtrTy(Context), 00118 DL.getIntPtrType(Context), nullptr); 00119 break; 00120 case Intrinsic::memmove: 00121 M.getOrInsertFunction("memmove", 00122 Type::getInt8PtrTy(Context), 00123 Type::getInt8PtrTy(Context), 00124 Type::getInt8PtrTy(Context), 00125 DL.getIntPtrType(Context), nullptr); 00126 break; 00127 case Intrinsic::memset: 00128 M.getOrInsertFunction("memset", 00129 Type::getInt8PtrTy(Context), 00130 Type::getInt8PtrTy(Context), 00131 Type::getInt32Ty(M.getContext()), 00132 DL.getIntPtrType(Context), nullptr); 00133 break; 00134 case Intrinsic::sqrt: 00135 EnsureFPIntrinsicsExist(M, I, "sqrtf", "sqrt", "sqrtl"); 00136 break; 00137 case Intrinsic::sin: 00138 EnsureFPIntrinsicsExist(M, I, "sinf", "sin", "sinl"); 00139 break; 00140 case Intrinsic::cos: 00141 EnsureFPIntrinsicsExist(M, I, "cosf", "cos", "cosl"); 00142 break; 00143 case Intrinsic::pow: 00144 EnsureFPIntrinsicsExist(M, I, "powf", "pow", "powl"); 00145 break; 00146 case Intrinsic::log: 00147 EnsureFPIntrinsicsExist(M, I, "logf", "log", "logl"); 00148 break; 00149 case Intrinsic::log2: 00150 EnsureFPIntrinsicsExist(M, I, "log2f", "log2", "log2l"); 00151 break; 00152 case Intrinsic::log10: 00153 EnsureFPIntrinsicsExist(M, I, "log10f", "log10", "log10l"); 00154 break; 00155 case Intrinsic::exp: 00156 EnsureFPIntrinsicsExist(M, I, "expf", "exp", "expl"); 00157 break; 00158 case Intrinsic::exp2: 00159 EnsureFPIntrinsicsExist(M, I, "exp2f", "exp2", "exp2l"); 00160 break; 00161 } 00162 } 00163 00164 /// LowerBSWAP - Emit the code to lower bswap of V before the specified 00165 /// instruction IP. 00166 static Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) { 00167 assert(V->getType()->isIntegerTy() && "Can't bswap a non-integer type!"); 00168 00169 unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 00170 00171 IRBuilder<> Builder(IP->getParent(), IP); 00172 00173 switch(BitSize) { 00174 default: llvm_unreachable("Unhandled type size of value to byteswap!"); 00175 case 16: { 00176 Value *Tmp1 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 00177 "bswap.2"); 00178 Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 00179 "bswap.1"); 00180 V = Builder.CreateOr(Tmp1, Tmp2, "bswap.i16"); 00181 break; 00182 } 00183 case 32: { 00184 Value *Tmp4 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), 00185 "bswap.4"); 00186 Value *Tmp3 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 00187 "bswap.3"); 00188 Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 00189 "bswap.2"); 00190 Value *Tmp1 = Builder.CreateLShr(V,ConstantInt::get(V->getType(), 24), 00191 "bswap.1"); 00192 Tmp3 = Builder.CreateAnd(Tmp3, 00193 ConstantInt::get(Type::getInt32Ty(Context), 0xFF0000), 00194 "bswap.and3"); 00195 Tmp2 = Builder.CreateAnd(Tmp2, 00196 ConstantInt::get(Type::getInt32Ty(Context), 0xFF00), 00197 "bswap.and2"); 00198 Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or1"); 00199 Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or2"); 00200 V = Builder.CreateOr(Tmp4, Tmp2, "bswap.i32"); 00201 break; 00202 } 00203 case 64: { 00204 Value *Tmp8 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 56), 00205 "bswap.8"); 00206 Value *Tmp7 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 40), 00207 "bswap.7"); 00208 Value *Tmp6 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), 00209 "bswap.6"); 00210 Value *Tmp5 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 00211 "bswap.5"); 00212 Value* Tmp4 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 00213 "bswap.4"); 00214 Value* Tmp3 = Builder.CreateLShr(V, 00215 ConstantInt::get(V->getType(), 24), 00216 "bswap.3"); 00217 Value* Tmp2 = Builder.CreateLShr(V, 00218 ConstantInt::get(V->getType(), 40), 00219 "bswap.2"); 00220 Value* Tmp1 = Builder.CreateLShr(V, 00221 ConstantInt::get(V->getType(), 56), 00222 "bswap.1"); 00223 Tmp7 = Builder.CreateAnd(Tmp7, 00224 ConstantInt::get(Type::getInt64Ty(Context), 00225 0xFF000000000000ULL), 00226 "bswap.and7"); 00227 Tmp6 = Builder.CreateAnd(Tmp6, 00228 ConstantInt::get(Type::getInt64Ty(Context), 00229 0xFF0000000000ULL), 00230 "bswap.and6"); 00231 Tmp5 = Builder.CreateAnd(Tmp5, 00232 ConstantInt::get(Type::getInt64Ty(Context), 00233 0xFF00000000ULL), 00234 "bswap.and5"); 00235 Tmp4 = Builder.CreateAnd(Tmp4, 00236 ConstantInt::get(Type::getInt64Ty(Context), 00237 0xFF000000ULL), 00238 "bswap.and4"); 00239 Tmp3 = Builder.CreateAnd(Tmp3, 00240 ConstantInt::get(Type::getInt64Ty(Context), 00241 0xFF0000ULL), 00242 "bswap.and3"); 00243 Tmp2 = Builder.CreateAnd(Tmp2, 00244 ConstantInt::get(Type::getInt64Ty(Context), 00245 0xFF00ULL), 00246 "bswap.and2"); 00247 Tmp8 = Builder.CreateOr(Tmp8, Tmp7, "bswap.or1"); 00248 Tmp6 = Builder.CreateOr(Tmp6, Tmp5, "bswap.or2"); 00249 Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or3"); 00250 Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or4"); 00251 Tmp8 = Builder.CreateOr(Tmp8, Tmp6, "bswap.or5"); 00252 Tmp4 = Builder.CreateOr(Tmp4, Tmp2, "bswap.or6"); 00253 V = Builder.CreateOr(Tmp8, Tmp4, "bswap.i64"); 00254 break; 00255 } 00256 } 00257 return V; 00258 } 00259 00260 /// LowerCTPOP - Emit the code to lower ctpop of V before the specified 00261 /// instruction IP. 00262 static Value *LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP) { 00263 assert(V->getType()->isIntegerTy() && "Can't ctpop a non-integer type!"); 00264 00265 static const uint64_t MaskValues[6] = { 00266 0x5555555555555555ULL, 0x3333333333333333ULL, 00267 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL, 00268 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL 00269 }; 00270 00271 IRBuilder<> Builder(IP->getParent(), IP); 00272 00273 unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 00274 unsigned WordSize = (BitSize + 63) / 64; 00275 Value *Count = ConstantInt::get(V->getType(), 0); 00276 00277 for (unsigned n = 0; n < WordSize; ++n) { 00278 Value *PartValue = V; 00279 for (unsigned i = 1, ct = 0; i < (BitSize>64 ? 64 : BitSize); 00280 i <<= 1, ++ct) { 00281 Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]); 00282 Value *LHS = Builder.CreateAnd(PartValue, MaskCst, "cppop.and1"); 00283 Value *VShift = Builder.CreateLShr(PartValue, 00284 ConstantInt::get(V->getType(), i), 00285 "ctpop.sh"); 00286 Value *RHS = Builder.CreateAnd(VShift, MaskCst, "cppop.and2"); 00287 PartValue = Builder.CreateAdd(LHS, RHS, "ctpop.step"); 00288 } 00289 Count = Builder.CreateAdd(PartValue, Count, "ctpop.part"); 00290 if (BitSize > 64) { 00291 V = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 64), 00292 "ctpop.part.sh"); 00293 BitSize -= 64; 00294 } 00295 } 00296 00297 return Count; 00298 } 00299 00300 /// LowerCTLZ - Emit the code to lower ctlz of V before the specified 00301 /// instruction IP. 00302 static Value *LowerCTLZ(LLVMContext &Context, Value *V, Instruction *IP) { 00303 00304 IRBuilder<> Builder(IP->getParent(), IP); 00305 00306 unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 00307 for (unsigned i = 1; i < BitSize; i <<= 1) { 00308 Value *ShVal = ConstantInt::get(V->getType(), i); 00309 ShVal = Builder.CreateLShr(V, ShVal, "ctlz.sh"); 00310 V = Builder.CreateOr(V, ShVal, "ctlz.step"); 00311 } 00312 00313 V = Builder.CreateNot(V); 00314 return LowerCTPOP(Context, V, IP); 00315 } 00316 00317 static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, 00318 const char *Dname, 00319 const char *LDname) { 00320 CallSite CS(CI); 00321 switch (CI->getArgOperand(0)->getType()->getTypeID()) { 00322 default: llvm_unreachable("Invalid type in intrinsic"); 00323 case Type::FloatTyID: 00324 ReplaceCallWith(Fname, CI, CS.arg_begin(), CS.arg_end(), 00325 Type::getFloatTy(CI->getContext())); 00326 break; 00327 case Type::DoubleTyID: 00328 ReplaceCallWith(Dname, CI, CS.arg_begin(), CS.arg_end(), 00329 Type::getDoubleTy(CI->getContext())); 00330 break; 00331 case Type::X86_FP80TyID: 00332 case Type::FP128TyID: 00333 case Type::PPC_FP128TyID: 00334 ReplaceCallWith(LDname, CI, CS.arg_begin(), CS.arg_end(), 00335 CI->getArgOperand(0)->getType()); 00336 break; 00337 } 00338 } 00339 00340 void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { 00341 IRBuilder<> Builder(CI->getParent(), CI); 00342 LLVMContext &Context = CI->getContext(); 00343 00344 const Function *Callee = CI->getCalledFunction(); 00345 assert(Callee && "Cannot lower an indirect call!"); 00346 00347 CallSite CS(CI); 00348 switch (Callee->getIntrinsicID()) { 00349 case Intrinsic::not_intrinsic: 00350 report_fatal_error("Cannot lower a call to a non-intrinsic function '"+ 00351 Callee->getName() + "'!"); 00352 default: 00353 report_fatal_error("Code generator does not support intrinsic function '"+ 00354 Callee->getName()+"'!"); 00355 00356 case Intrinsic::expect: { 00357 // Just replace __builtin_expect(exp, c) with EXP. 00358 Value *V = CI->getArgOperand(0); 00359 CI->replaceAllUsesWith(V); 00360 break; 00361 } 00362 00363 // The setjmp/longjmp intrinsics should only exist in the code if it was 00364 // never optimized (ie, right out of the CFE), or if it has been hacked on 00365 // by the lowerinvoke pass. In both cases, the right thing to do is to 00366 // convert the call to an explicit setjmp or longjmp call. 00367 case Intrinsic::setjmp: { 00368 Value *V = ReplaceCallWith("setjmp", CI, CS.arg_begin(), CS.arg_end(), 00369 Type::getInt32Ty(Context)); 00370 if (!CI->getType()->isVoidTy()) 00371 CI->replaceAllUsesWith(V); 00372 break; 00373 } 00374 case Intrinsic::sigsetjmp: 00375 if (!CI->getType()->isVoidTy()) 00376 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 00377 break; 00378 00379 case Intrinsic::longjmp: { 00380 ReplaceCallWith("longjmp", CI, CS.arg_begin(), CS.arg_end(), 00381 Type::getVoidTy(Context)); 00382 break; 00383 } 00384 00385 case Intrinsic::siglongjmp: { 00386 // Insert the call to abort 00387 ReplaceCallWith("abort", CI, CS.arg_end(), CS.arg_end(), 00388 Type::getVoidTy(Context)); 00389 break; 00390 } 00391 case Intrinsic::ctpop: 00392 CI->replaceAllUsesWith(LowerCTPOP(Context, CI->getArgOperand(0), CI)); 00393 break; 00394 00395 case Intrinsic::bswap: 00396 CI->replaceAllUsesWith(LowerBSWAP(Context, CI->getArgOperand(0), CI)); 00397 break; 00398 00399 case Intrinsic::ctlz: 00400 CI->replaceAllUsesWith(LowerCTLZ(Context, CI->getArgOperand(0), CI)); 00401 break; 00402 00403 case Intrinsic::cttz: { 00404 // cttz(x) -> ctpop(~X & (X-1)) 00405 Value *Src = CI->getArgOperand(0); 00406 Value *NotSrc = Builder.CreateNot(Src); 00407 NotSrc->setName(Src->getName() + ".not"); 00408 Value *SrcM1 = ConstantInt::get(Src->getType(), 1); 00409 SrcM1 = Builder.CreateSub(Src, SrcM1); 00410 Src = LowerCTPOP(Context, Builder.CreateAnd(NotSrc, SrcM1), CI); 00411 CI->replaceAllUsesWith(Src); 00412 break; 00413 } 00414 00415 case Intrinsic::stacksave: 00416 case Intrinsic::stackrestore: { 00417 if (!Warned) 00418 errs() << "WARNING: this target does not support the llvm.stack" 00419 << (Callee->getIntrinsicID() == Intrinsic::stacksave ? 00420 "save" : "restore") << " intrinsic.\n"; 00421 Warned = true; 00422 if (Callee->getIntrinsicID() == Intrinsic::stacksave) 00423 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 00424 break; 00425 } 00426 00427 case Intrinsic::returnaddress: 00428 case Intrinsic::frameaddress: 00429 errs() << "WARNING: this target does not support the llvm." 00430 << (Callee->getIntrinsicID() == Intrinsic::returnaddress ? 00431 "return" : "frame") << "address intrinsic.\n"; 00432 CI->replaceAllUsesWith(ConstantPointerNull::get( 00433 cast<PointerType>(CI->getType()))); 00434 break; 00435 00436 case Intrinsic::prefetch: 00437 break; // Simply strip out prefetches on unsupported architectures 00438 00439 case Intrinsic::pcmarker: 00440 break; // Simply strip out pcmarker on unsupported architectures 00441 case Intrinsic::readcyclecounter: { 00442 errs() << "WARNING: this target does not support the llvm.readcyclecoun" 00443 << "ter intrinsic. It is being lowered to a constant 0\n"; 00444 CI->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context), 0)); 00445 break; 00446 } 00447 00448 case Intrinsic::dbg_declare: 00449 break; // Simply strip out debugging intrinsics 00450 00451 case Intrinsic::eh_typeid_for: 00452 // Return something different to eh_selector. 00453 CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 00454 break; 00455 00456 case Intrinsic::annotation: 00457 case Intrinsic::ptr_annotation: 00458 // Just drop the annotation, but forward the value 00459 CI->replaceAllUsesWith(CI->getOperand(0)); 00460 break; 00461 00462 case Intrinsic::assume: 00463 case Intrinsic::var_annotation: 00464 break; // Strip out these intrinsics 00465 00466 case Intrinsic::memcpy: { 00467 Type *IntPtr = DL.getIntPtrType(Context); 00468 Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 00469 /* isSigned */ false); 00470 Value *Ops[3]; 00471 Ops[0] = CI->getArgOperand(0); 00472 Ops[1] = CI->getArgOperand(1); 00473 Ops[2] = Size; 00474 ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 00475 break; 00476 } 00477 case Intrinsic::memmove: { 00478 Type *IntPtr = DL.getIntPtrType(Context); 00479 Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 00480 /* isSigned */ false); 00481 Value *Ops[3]; 00482 Ops[0] = CI->getArgOperand(0); 00483 Ops[1] = CI->getArgOperand(1); 00484 Ops[2] = Size; 00485 ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 00486 break; 00487 } 00488 case Intrinsic::memset: { 00489 Value *Op0 = CI->getArgOperand(0); 00490 Type *IntPtr = DL.getIntPtrType(Op0->getType()); 00491 Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 00492 /* isSigned */ false); 00493 Value *Ops[3]; 00494 Ops[0] = Op0; 00495 // Extend the amount to i32. 00496 Ops[1] = Builder.CreateIntCast(CI->getArgOperand(1), 00497 Type::getInt32Ty(Context), 00498 /* isSigned */ false); 00499 Ops[2] = Size; 00500 ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 00501 break; 00502 } 00503 case Intrinsic::sqrt: { 00504 ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl"); 00505 break; 00506 } 00507 case Intrinsic::log: { 00508 ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl"); 00509 break; 00510 } 00511 case Intrinsic::log2: { 00512 ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l"); 00513 break; 00514 } 00515 case Intrinsic::log10: { 00516 ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l"); 00517 break; 00518 } 00519 case Intrinsic::exp: { 00520 ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl"); 00521 break; 00522 } 00523 case Intrinsic::exp2: { 00524 ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l"); 00525 break; 00526 } 00527 case Intrinsic::pow: { 00528 ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl"); 00529 break; 00530 } 00531 case Intrinsic::sin: { 00532 ReplaceFPIntrinsicWithCall(CI, "sinf", "sin", "sinl"); 00533 break; 00534 } 00535 case Intrinsic::cos: { 00536 ReplaceFPIntrinsicWithCall(CI, "cosf", "cos", "cosl"); 00537 break; 00538 } 00539 case Intrinsic::floor: { 00540 ReplaceFPIntrinsicWithCall(CI, "floorf", "floor", "floorl"); 00541 break; 00542 } 00543 case Intrinsic::ceil: { 00544 ReplaceFPIntrinsicWithCall(CI, "ceilf", "ceil", "ceill"); 00545 break; 00546 } 00547 case Intrinsic::trunc: { 00548 ReplaceFPIntrinsicWithCall(CI, "truncf", "trunc", "truncl"); 00549 break; 00550 } 00551 case Intrinsic::round: { 00552 ReplaceFPIntrinsicWithCall(CI, "roundf", "round", "roundl"); 00553 break; 00554 } 00555 case Intrinsic::copysign: { 00556 ReplaceFPIntrinsicWithCall(CI, "copysignf", "copysign", "copysignl"); 00557 break; 00558 } 00559 case Intrinsic::flt_rounds: 00560 // Lower to "round to the nearest" 00561 if (!CI->getType()->isVoidTy()) 00562 CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 00563 break; 00564 case Intrinsic::invariant_start: 00565 case Intrinsic::lifetime_start: 00566 // Discard region information. 00567 CI->replaceAllUsesWith(UndefValue::get(CI->getType())); 00568 break; 00569 case Intrinsic::invariant_end: 00570 case Intrinsic::lifetime_end: 00571 // Discard region information. 00572 break; 00573 } 00574 00575 assert(CI->use_empty() && 00576 "Lowering should have eliminated any uses of the intrinsic call!"); 00577 CI->eraseFromParent(); 00578 } 00579 00580 bool IntrinsicLowering::LowerToByteSwap(CallInst *CI) { 00581 // Verify this is a simple bswap. 00582 if (CI->getNumArgOperands() != 1 || 00583 CI->getType() != CI->getArgOperand(0)->getType() || 00584 !CI->getType()->isIntegerTy()) 00585 return false; 00586 00587 IntegerType *Ty = dyn_cast<IntegerType>(CI->getType()); 00588 if (!Ty) 00589 return false; 00590 00591 // Okay, we can do this xform, do so now. 00592 Module *M = CI->getParent()->getParent()->getParent(); 00593 Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Ty); 00594 00595 Value *Op = CI->getArgOperand(0); 00596 Op = CallInst::Create(Int, Op, CI->getName(), CI); 00597 00598 CI->replaceAllUsesWith(Op); 00599 CI->eraseFromParent(); 00600 return true; 00601 }