13b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner//===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// 2edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman// 33b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner// The LLVM Compiler Infrastructure 43b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman// 83b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner//===----------------------------------------------------------------------===// 93b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner// 10b71fd7897f6b4500cdbe602c5a9907316750cf5aChris Lattner// This file implements the IntrinsicLowering class. 113b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner// 123b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner//===----------------------------------------------------------------------===// 133b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner 1406cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/CodeGen/IntrinsicLowering.h" 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallVector.h" 160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h" 200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h" 229e38531d9561630520732146c32977443c73c243Gabor Greif#include "llvm/Support/CallSite.h" 237d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin#include "llvm/Support/ErrorHandling.h" 2445cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner#include "llvm/Support/raw_ostream.h" 253b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattnerusing namespace llvm; 263b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner 270979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattnertemplate <class ArgIt> 28b76efb71d41dc1ae33e47d5d9ef79df25cde0b5dChris Lattnerstatic void EnsureFunctionExists(Module &M, const char *Name, 29b76efb71d41dc1ae33e47d5d9ef79df25cde0b5dChris Lattner ArgIt ArgBegin, ArgIt ArgEnd, 30db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *RetTy) { 31b76efb71d41dc1ae33e47d5d9ef79df25cde0b5dChris Lattner // Insert a correctly-typed definition now. 325fdd6c8793462549e3593890ec61573da06e3346Jay Foad std::vector<Type *> ParamTys; 330979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner for (ArgIt I = ArgBegin; I != ArgEnd; ++I) 340979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner ParamTys.push_back(I->getType()); 35b76efb71d41dc1ae33e47d5d9ef79df25cde0b5dChris Lattner M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); 360979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner} 370979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner 38556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattnerstatic void EnsureFPIntrinsicsExist(Module &M, Function *Fn, 39556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattner const char *FName, 40556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattner const char *DName, const char *LDName) { 41c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen // Insert definitions for all the floating point types. 42556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattner switch((int)Fn->arg_begin()->getType()->getTypeID()) { 43c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen case Type::FloatTyID: 44556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattner EnsureFunctionExists(M, FName, Fn->arg_begin(), Fn->arg_end(), 451d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getFloatTy(M.getContext())); 46556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattner break; 47c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen case Type::DoubleTyID: 48556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattner EnsureFunctionExists(M, DName, Fn->arg_begin(), Fn->arg_end(), 491d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getDoubleTy(M.getContext())); 50556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattner break; 51c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen case Type::X86_FP80TyID: 52c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen case Type::FP128TyID: 53c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen case Type::PPC_FP128TyID: 54556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattner EnsureFunctionExists(M, LDName, Fn->arg_begin(), Fn->arg_end(), 55556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattner Fn->arg_begin()->getType()); 56556b4a6385d34b77e58ff5a3ce51ddae5ae6112cChris Lattner break; 57c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen } 58c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen} 59c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen 60588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner/// ReplaceCallWith - This function is used when we want to lower an intrinsic 61588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner/// call to a call of an external function. This handles hard cases such as 62588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner/// when there was already a prototype for the external function, and if that 63588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner/// prototype doesn't match the arguments we expect to pass in. 64588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattnertemplate <class ArgIt> 65588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattnerstatic CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, 66b76efb71d41dc1ae33e47d5d9ef79df25cde0b5dChris Lattner ArgIt ArgBegin, ArgIt ArgEnd, 67db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *RetTy) { 68b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson // If we haven't already looked up this function, check to see if the 69b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson // program already contains a function with this name. 70b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson Module *M = CI->getParent()->getParent()->getParent(); 71b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson // Get or insert the definition now. 725fdd6c8793462549e3593890ec61573da06e3346Jay Foad std::vector<Type *> ParamTys; 73b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson for (ArgIt I = ArgBegin; I != ArgEnd; ++I) 74b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson ParamTys.push_back((*I)->getType()); 75b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson Constant* FCache = M->getOrInsertFunction(NewFn, 76b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson FunctionType::get(RetTy, ParamTys, false)); 77588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner 78e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad IRBuilder<> Builder(CI->getParent(), CI); 7952eec548206d0b135b55ba52dd0e82e978f15ae5David Greene SmallVector<Value *, 8> Args(ArgBegin, ArgEnd); 80a3efbb15ddd5aa9006564cd79086723640084878Jay Foad CallInst *NewCI = Builder.CreateCall(FCache, Args); 81e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad NewCI->setName(CI->getName()); 82b76efb71d41dc1ae33e47d5d9ef79df25cde0b5dChris Lattner if (!CI->use_empty()) 83b76efb71d41dc1ae33e47d5d9ef79df25cde0b5dChris Lattner CI->replaceAllUsesWith(NewCI); 8402348caffc6a0ca6e00960767152b6b7422ab450Chris Lattner return NewCI; 85588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner} 86588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner 877d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor// VisualStudio defines setjmp as _setjmp 881f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer#if defined(_MSC_VER) && defined(setjmp) && \ 891f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer !defined(setjmp_undefined_for_msvc) 901f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer# pragma push_macro("setjmp") 911f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer# undef setjmp 921f4096054367cab3acab3a74c719ef6d3090606aMichael J. Spencer# define setjmp_undefined_for_msvc 937d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor#endif 947d9663c70b3300070298d716dba6e6f6ce2d1e3eDouglas Gregor 95b71fd7897f6b4500cdbe602c5a9907316750cf5aChris Lattnervoid IntrinsicLowering::AddPrototypes(Module &M) { 961d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson LLVMContext &Context = M.getContext(); 970979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 985cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer if (I->isDeclaration() && !I->use_empty()) 990979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner switch (I->getIntrinsicID()) { 1000979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner default: break; 1010979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner case Intrinsic::setjmp: 1021f243e9f43e3552c28331c2e17b7c19bdfc889f6Chris Lattner EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(), 1031d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getInt32Ty(M.getContext())); 1040979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner break; 1050979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner case Intrinsic::longjmp: 1061f243e9f43e3552c28331c2e17b7c19bdfc889f6Chris Lattner EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(), 1071d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getVoidTy(M.getContext())); 1080979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner break; 1090979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner case Intrinsic::siglongjmp: 1101f243e9f43e3552c28331c2e17b7c19bdfc889f6Chris Lattner EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(), 1111d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getVoidTy(M.getContext())); 1120979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner break; 113824b958e6fb1236e92e4d07f3acf18fca107cdc0Chris Lattner case Intrinsic::memcpy: 1141d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson M.getOrInsertFunction("memcpy", 115ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getInt8PtrTy(Context), 116ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getInt8PtrTy(Context), 117ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getInt8PtrTy(Context), 118ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth TD.getIntPtrType(Context), (Type *)0); 1190979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner break; 120824b958e6fb1236e92e4d07f3acf18fca107cdc0Chris Lattner case Intrinsic::memmove: 1211d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson M.getOrInsertFunction("memmove", 122ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getInt8PtrTy(Context), 123ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getInt8PtrTy(Context), 124ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getInt8PtrTy(Context), 125ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth TD.getIntPtrType(Context), (Type *)0); 1260979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner break; 127824b958e6fb1236e92e4d07f3acf18fca107cdc0Chris Lattner case Intrinsic::memset: 1281d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson M.getOrInsertFunction("memset", 129ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getInt8PtrTy(Context), 130ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getInt8PtrTy(Context), 1311d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getInt32Ty(M.getContext()), 132ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth TD.getIntPtrType(Context), (Type *)0); 1330979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner break; 1349ab7fb3ba47442d521a5bed09a27a5e8e7a786edDale Johannesen case Intrinsic::sqrt: 135c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen EnsureFPIntrinsicsExist(M, I, "sqrtf", "sqrt", "sqrtl"); 136b42a9ffbe9f5dc7dc0e54c6425dff10e926e1f3dChris Lattner break; 137c4c966012901691fff21eed02d72a3de44dd47f1Dan Gohman case Intrinsic::sin: 138c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen EnsureFPIntrinsicsExist(M, I, "sinf", "sin", "sinl"); 139c4c966012901691fff21eed02d72a3de44dd47f1Dan Gohman break; 140c4c966012901691fff21eed02d72a3de44dd47f1Dan Gohman case Intrinsic::cos: 141c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen EnsureFPIntrinsicsExist(M, I, "cosf", "cos", "cosl"); 142c4c966012901691fff21eed02d72a3de44dd47f1Dan Gohman break; 143c4c966012901691fff21eed02d72a3de44dd47f1Dan Gohman case Intrinsic::pow: 144c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen EnsureFPIntrinsicsExist(M, I, "powf", "pow", "powl"); 145c4c966012901691fff21eed02d72a3de44dd47f1Dan Gohman break; 1467794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::log: 147c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen EnsureFPIntrinsicsExist(M, I, "logf", "log", "logl"); 1487794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 1497794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::log2: 150c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen EnsureFPIntrinsicsExist(M, I, "log2f", "log2", "log2l"); 1517794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 1527794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::log10: 153c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen EnsureFPIntrinsicsExist(M, I, "log10f", "log10", "log10l"); 1547794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 1557794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::exp: 156c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen EnsureFPIntrinsicsExist(M, I, "expf", "exp", "expl"); 1577794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 1587794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::exp2: 159c4342eab9bb999050dd94be929093c6e36a49c67Dale Johannesen EnsureFPIntrinsicsExist(M, I, "exp2f", "exp2", "exp2l"); 1607794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 1610979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner } 1620979ca7e3e8ff1bb3f38f7b93a02db2e1704333cChris Lattner} 163588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner 164e598181889d8ab43c3924799fd310e68571186f1Nate Begeman/// LowerBSWAP - Emit the code to lower bswap of V before the specified 165e598181889d8ab43c3924799fd310e68571186f1Nate Begeman/// instruction IP. 1669adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Andersonstatic Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) { 167b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands assert(V->getType()->isIntegerTy() && "Can't bswap a non-integer type!"); 168e598181889d8ab43c3924799fd310e68571186f1Nate Begeman 169e598181889d8ab43c3924799fd310e68571186f1Nate Begeman unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 170e598181889d8ab43c3924799fd310e68571186f1Nate Begeman 171e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad IRBuilder<> Builder(IP->getParent(), IP); 172e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad 173e598181889d8ab43c3924799fd310e68571186f1Nate Begeman switch(BitSize) { 174c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unhandled type size of value to byteswap!"); 175e598181889d8ab43c3924799fd310e68571186f1Nate Begeman case 16: { 176eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Tmp1 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 177e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.2"); 178eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 179e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.1"); 180e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad V = Builder.CreateOr(Tmp1, Tmp2, "bswap.i16"); 181e598181889d8ab43c3924799fd310e68571186f1Nate Begeman break; 182e598181889d8ab43c3924799fd310e68571186f1Nate Begeman } 183e598181889d8ab43c3924799fd310e68571186f1Nate Begeman case 32: { 184eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Tmp4 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), 185e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.4"); 186eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Tmp3 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 187e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.3"); 188eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 189e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.2"); 190eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Tmp1 = Builder.CreateLShr(V,ConstantInt::get(V->getType(), 24), 191e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.1"); 1929adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson Tmp3 = Builder.CreateAnd(Tmp3, 1931d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ConstantInt::get(Type::getInt32Ty(Context), 0xFF0000), 194e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.and3"); 1959adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson Tmp2 = Builder.CreateAnd(Tmp2, 1961d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ConstantInt::get(Type::getInt32Ty(Context), 0xFF00), 197e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.and2"); 198e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or1"); 199e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or2"); 200e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad V = Builder.CreateOr(Tmp4, Tmp2, "bswap.i32"); 201e598181889d8ab43c3924799fd310e68571186f1Nate Begeman break; 202e598181889d8ab43c3924799fd310e68571186f1Nate Begeman } 203e598181889d8ab43c3924799fd310e68571186f1Nate Begeman case 64: { 204eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Tmp8 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 56), 205e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.8"); 206eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Tmp7 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 40), 207e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.7"); 208eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Tmp6 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), 209e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.6"); 210eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Tmp5 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 211e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.5"); 212eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value* Tmp4 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 213e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.4"); 2149adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson Value* Tmp3 = Builder.CreateLShr(V, 215eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson ConstantInt::get(V->getType(), 24), 216e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.3"); 2179adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson Value* Tmp2 = Builder.CreateLShr(V, 218eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson ConstantInt::get(V->getType(), 40), 219e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.2"); 2209adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson Value* Tmp1 = Builder.CreateLShr(V, 221eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson ConstantInt::get(V->getType(), 56), 222e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.1"); 223e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp7 = Builder.CreateAnd(Tmp7, 2241d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ConstantInt::get(Type::getInt64Ty(Context), 225e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad 0xFF000000000000ULL), 226e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.and7"); 227e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp6 = Builder.CreateAnd(Tmp6, 2281d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ConstantInt::get(Type::getInt64Ty(Context), 229e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad 0xFF0000000000ULL), 230e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.and6"); 231e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp5 = Builder.CreateAnd(Tmp5, 2321d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ConstantInt::get(Type::getInt64Ty(Context), 2331d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson 0xFF00000000ULL), 234e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.and5"); 235e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp4 = Builder.CreateAnd(Tmp4, 2361d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ConstantInt::get(Type::getInt64Ty(Context), 2371d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson 0xFF000000ULL), 238e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.and4"); 239e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp3 = Builder.CreateAnd(Tmp3, 2401d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ConstantInt::get(Type::getInt64Ty(Context), 2411d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson 0xFF0000ULL), 242e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.and3"); 243e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp2 = Builder.CreateAnd(Tmp2, 2441d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ConstantInt::get(Type::getInt64Ty(Context), 2451d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson 0xFF00ULL), 246e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "bswap.and2"); 247e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp8 = Builder.CreateOr(Tmp8, Tmp7, "bswap.or1"); 248e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp6 = Builder.CreateOr(Tmp6, Tmp5, "bswap.or2"); 249e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or3"); 250e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or4"); 251e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp8 = Builder.CreateOr(Tmp8, Tmp6, "bswap.or5"); 252e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Tmp4 = Builder.CreateOr(Tmp4, Tmp2, "bswap.or6"); 253e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad V = Builder.CreateOr(Tmp8, Tmp4, "bswap.i64"); 254e598181889d8ab43c3924799fd310e68571186f1Nate Begeman break; 255e598181889d8ab43c3924799fd310e68571186f1Nate Begeman } 256e598181889d8ab43c3924799fd310e68571186f1Nate Begeman } 257e598181889d8ab43c3924799fd310e68571186f1Nate Begeman return V; 258e598181889d8ab43c3924799fd310e68571186f1Nate Begeman} 259e598181889d8ab43c3924799fd310e68571186f1Nate Begeman 26086f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner/// LowerCTPOP - Emit the code to lower ctpop of V before the specified 261e598181889d8ab43c3924799fd310e68571186f1Nate Begeman/// instruction IP. 2629adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Andersonstatic Value *LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP) { 263b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands assert(V->getType()->isIntegerTy() && "Can't ctpop a non-integer type!"); 26486f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner 26586f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner static const uint64_t MaskValues[6] = { 26686f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner 0x5555555555555555ULL, 0x3333333333333333ULL, 26786f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL, 26886f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL 26986f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner }; 27086f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner 271e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad IRBuilder<> Builder(IP->getParent(), IP); 272e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad 27398cf45bbf6b6efc1b90d4744082149e9b5f3e17aChris Lattner unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 27402031c0ff8ad48acdb8c4a4058c4fafe600423e1Zhou Sheng unsigned WordSize = (BitSize + 63) / 64; 275eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *Count = ConstantInt::get(V->getType(), 0); 2763822ff5c71478c7c90a50ca57045fb676fcb5005Reid Spencer 27702031c0ff8ad48acdb8c4a4058c4fafe600423e1Zhou Sheng for (unsigned n = 0; n < WordSize; ++n) { 27802031c0ff8ad48acdb8c4a4058c4fafe600423e1Zhou Sheng Value *PartValue = V; 27902031c0ff8ad48acdb8c4a4058c4fafe600423e1Zhou Sheng for (unsigned i = 1, ct = 0; i < (BitSize>64 ? 64 : BitSize); 28002031c0ff8ad48acdb8c4a4058c4fafe600423e1Zhou Sheng i <<= 1, ++ct) { 281eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]); 282e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Value *LHS = Builder.CreateAnd(PartValue, MaskCst, "cppop.and1"); 283e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Value *VShift = Builder.CreateLShr(PartValue, 284eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson ConstantInt::get(V->getType(), i), 285e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "ctpop.sh"); 286e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Value *RHS = Builder.CreateAnd(VShift, MaskCst, "cppop.and2"); 287e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad PartValue = Builder.CreateAdd(LHS, RHS, "ctpop.step"); 28802031c0ff8ad48acdb8c4a4058c4fafe600423e1Zhou Sheng } 289e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Count = Builder.CreateAdd(PartValue, Count, "ctpop.part"); 29002031c0ff8ad48acdb8c4a4058c4fafe600423e1Zhou Sheng if (BitSize > 64) { 291eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson V = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 64), 292e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad "ctpop.part.sh"); 29302031c0ff8ad48acdb8c4a4058c4fafe600423e1Zhou Sheng BitSize -= 64; 29402031c0ff8ad48acdb8c4a4058c4fafe600423e1Zhou Sheng } 29586f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner } 29686f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner 297914ce4508d46bdc5db0eec1aff8051ccd94c3d5fChris Lattner return Count; 29886f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner} 29986f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner 30098cf45bbf6b6efc1b90d4744082149e9b5f3e17aChris Lattner/// LowerCTLZ - Emit the code to lower ctlz of V before the specified 301e598181889d8ab43c3924799fd310e68571186f1Nate Begeman/// instruction IP. 3029adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Andersonstatic Value *LowerCTLZ(LLVMContext &Context, Value *V, Instruction *IP) { 30398cf45bbf6b6efc1b90d4744082149e9b5f3e17aChris Lattner 304e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad IRBuilder<> Builder(IP->getParent(), IP); 305e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad 30698cf45bbf6b6efc1b90d4744082149e9b5f3e17aChris Lattner unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 30702031c0ff8ad48acdb8c4a4058c4fafe600423e1Zhou Sheng for (unsigned i = 1; i < BitSize; i <<= 1) { 308eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *ShVal = ConstantInt::get(V->getType(), i); 309e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad ShVal = Builder.CreateLShr(V, ShVal, "ctlz.sh"); 310e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad V = Builder.CreateOr(V, ShVal, "ctlz.step"); 31198cf45bbf6b6efc1b90d4744082149e9b5f3e17aChris Lattner } 31298cf45bbf6b6efc1b90d4744082149e9b5f3e17aChris Lattner 313e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad V = Builder.CreateNot(V); 3149adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson return LowerCTPOP(Context, V, IP); 31598cf45bbf6b6efc1b90d4744082149e9b5f3e17aChris Lattner} 31698cf45bbf6b6efc1b90d4744082149e9b5f3e17aChris Lattner 317b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Andersonstatic void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, 318b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson const char *Dname, 319f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen const char *LDname) { 3209e38531d9561630520732146c32977443c73c243Gabor Greif CallSite CS(CI); 3219e38531d9561630520732146c32977443c73c243Gabor Greif switch (CI->getArgOperand(0)->getType()->getTypeID()) { 322c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Invalid type in intrinsic"); 323f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen case Type::FloatTyID: 3249e38531d9561630520732146c32977443c73c243Gabor Greif ReplaceCallWith(Fname, CI, CS.arg_begin(), CS.arg_end(), 3251d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getFloatTy(CI->getContext())); 326f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen break; 327f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen case Type::DoubleTyID: 3289e38531d9561630520732146c32977443c73c243Gabor Greif ReplaceCallWith(Dname, CI, CS.arg_begin(), CS.arg_end(), 3291d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getDoubleTy(CI->getContext())); 330f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen break; 331f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen case Type::X86_FP80TyID: 332f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen case Type::FP128TyID: 333f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen case Type::PPC_FP128TyID: 3349e38531d9561630520732146c32977443c73c243Gabor Greif ReplaceCallWith(LDname, CI, CS.arg_begin(), CS.arg_end(), 3359e38531d9561630520732146c32977443c73c243Gabor Greif CI->getArgOperand(0)->getType()); 336f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen break; 337f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen } 338f74185b80e07d58208b24f0314d94853d48ec9bdDale Johannesen} 339addd11d98ee3a3013c66d3fd25ee2cfb09b3c7bdReid Spencer 340b71fd7897f6b4500cdbe602c5a9907316750cf5aChris Lattnervoid IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { 341e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad IRBuilder<> Builder(CI->getParent(), CI); 342e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson LLVMContext &Context = CI->getContext(); 343e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad 34446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Function *Callee = CI->getCalledFunction(); 3453b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner assert(Callee && "Cannot lower an indirect call!"); 346edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 3479e38531d9561630520732146c32977443c73c243Gabor Greif CallSite CS(CI); 3483b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner switch (Callee->getIntrinsicID()) { 3493b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner case Intrinsic::not_intrinsic: 35075361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("Cannot lower a call to a non-intrinsic function '"+ 3517d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin Callee->getName() + "'!"); 3523b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner default: 35375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("Code generator does not support intrinsic function '"+ 3547d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin Callee->getName()+"'!"); 3553b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner 3569da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak case Intrinsic::expect: { 3579da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak // Just replace __builtin_expect(exp, c) with EXP. 3589da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak Value *V = CI->getArgOperand(0); 3599da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak CI->replaceAllUsesWith(V); 3609da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak break; 3619da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak } 3629da9934e27dfb48de77b80a3e20ed2d869b52024Jakub Staszak 363588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner // The setjmp/longjmp intrinsics should only exist in the code if it was 364588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner // never optimized (ie, right out of the CFE), or if it has been hacked on 365588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner // by the lowerinvoke pass. In both cases, the right thing to do is to 366588e72db75649e8f9f79d73c24156c9611aeacf3Chris Lattner // convert the call to an explicit setjmp or longjmp call. 3679b700f7951b07cb7be885c7560066c73733ef101Chris Lattner case Intrinsic::setjmp: { 3689e38531d9561630520732146c32977443c73c243Gabor Greif Value *V = ReplaceCallWith("setjmp", CI, CS.arg_begin(), CS.arg_end(), 3691d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getInt32Ty(Context)); 370f012705c7e4ca8cf90b6b734ce1d5355daca5ba5Benjamin Kramer if (!CI->getType()->isVoidTy()) 3719b700f7951b07cb7be885c7560066c73733ef101Chris Lattner CI->replaceAllUsesWith(V); 3723b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner break; 3739b700f7951b07cb7be885c7560066c73733ef101Chris Lattner } 374edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman case Intrinsic::sigsetjmp: 375f012705c7e4ca8cf90b6b734ce1d5355daca5ba5Benjamin Kramer if (!CI->getType()->isVoidTy()) 376a7235ea7245028a0723e8ab7fd011386b3900777Owen Anderson CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 3779b700f7951b07cb7be885c7560066c73733ef101Chris Lattner break; 3783b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner 379f0a3e6c21cc24ebbec701bd8f6b1253b49498457Chris Lattner case Intrinsic::longjmp: { 3809e38531d9561630520732146c32977443c73c243Gabor Greif ReplaceCallWith("longjmp", CI, CS.arg_begin(), CS.arg_end(), 3811d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getVoidTy(Context)); 3829b700f7951b07cb7be885c7560066c73733ef101Chris Lattner break; 383f0a3e6c21cc24ebbec701bd8f6b1253b49498457Chris Lattner } 3849b700f7951b07cb7be885c7560066c73733ef101Chris Lattner 385f0a3e6c21cc24ebbec701bd8f6b1253b49498457Chris Lattner case Intrinsic::siglongjmp: { 3863b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner // Insert the call to abort 387d0fcab915441c0748667ef981ef85989abd28b11Gabor Greif ReplaceCallWith("abort", CI, CS.arg_end(), CS.arg_end(), 3881d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Type::getVoidTy(Context)); 3893b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner break; 390f0a3e6c21cc24ebbec701bd8f6b1253b49498457Chris Lattner } 391e9391fd9b52e93717b365bdd05c471101323a4dfReid Spencer case Intrinsic::ctpop: 3929e38531d9561630520732146c32977443c73c243Gabor Greif CI->replaceAllUsesWith(LowerCTPOP(Context, CI->getArgOperand(0), CI)); 3930b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer break; 3940b118206bf3411722707f2e5cab8fd2eedcd50d6Reid Spencer 395e9391fd9b52e93717b365bdd05c471101323a4dfReid Spencer case Intrinsic::bswap: 3969e38531d9561630520732146c32977443c73c243Gabor Greif CI->replaceAllUsesWith(LowerBSWAP(Context, CI->getArgOperand(0), CI)); 397e598181889d8ab43c3924799fd310e68571186f1Nate Begeman break; 398e598181889d8ab43c3924799fd310e68571186f1Nate Begeman 399e9391fd9b52e93717b365bdd05c471101323a4dfReid Spencer case Intrinsic::ctlz: 4009e38531d9561630520732146c32977443c73c243Gabor Greif CI->replaceAllUsesWith(LowerCTLZ(Context, CI->getArgOperand(0), CI)); 401691ef2ba066dda14ae4ac0ad645054fbc967785aAndrew Lenharth break; 402e598181889d8ab43c3924799fd310e68571186f1Nate Begeman 403e9391fd9b52e93717b365bdd05c471101323a4dfReid Spencer case Intrinsic::cttz: { 404a801172e504b45b2266486ec68adb64f7fcf8e17Chris Lattner // cttz(x) -> ctpop(~X & (X-1)) 4059e38531d9561630520732146c32977443c73c243Gabor Greif Value *Src = CI->getArgOperand(0); 406e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad Value *NotSrc = Builder.CreateNot(Src); 407e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad NotSrc->setName(Src->getName() + ".not"); 408eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson Value *SrcM1 = ConstantInt::get(Src->getType(), 1); 409e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad SrcM1 = Builder.CreateSub(Src, SrcM1); 410e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson Src = LowerCTPOP(Context, Builder.CreateAnd(NotSrc, SrcM1), CI); 411691ef2ba066dda14ae4ac0ad645054fbc967785aAndrew Lenharth CI->replaceAllUsesWith(Src); 412691ef2ba066dda14ae4ac0ad645054fbc967785aAndrew Lenharth break; 413691ef2ba066dda14ae4ac0ad645054fbc967785aAndrew Lenharth } 41477b1330ece6ea40b3b7700fe13e2ca64bd494203Chris Lattner 4150c067bc11d5274973c21f83b6c6403a9928265d8Chris Lattner case Intrinsic::stacksave: 41658446916b71c4ff79962081ea7c4df078c388b0eBob Wilson case Intrinsic::stackrestore: { 4170c067bc11d5274973c21f83b6c6403a9928265d8Chris Lattner if (!Warned) 41858446916b71c4ff79962081ea7c4df078c388b0eBob Wilson errs() << "WARNING: this target does not support the llvm.stack" 41958446916b71c4ff79962081ea7c4df078c388b0eBob Wilson << (Callee->getIntrinsicID() == Intrinsic::stacksave ? 42058446916b71c4ff79962081ea7c4df078c388b0eBob Wilson "save" : "restore") << " intrinsic.\n"; 4210c067bc11d5274973c21f83b6c6403a9928265d8Chris Lattner Warned = true; 42258446916b71c4ff79962081ea7c4df078c388b0eBob Wilson if (Callee->getIntrinsicID() == Intrinsic::stacksave) 42358446916b71c4ff79962081ea7c4df078c388b0eBob Wilson CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 4240c067bc11d5274973c21f83b6c6403a9928265d8Chris Lattner break; 42558446916b71c4ff79962081ea7c4df078c388b0eBob Wilson } 4260c067bc11d5274973c21f83b6c6403a9928265d8Chris Lattner 427cf8990838143fcfa91dd6276af523ac6c23517c2Chris Lattner case Intrinsic::returnaddress: 428cf8990838143fcfa91dd6276af523ac6c23517c2Chris Lattner case Intrinsic::frameaddress: 42958446916b71c4ff79962081ea7c4df078c388b0eBob Wilson errs() << "WARNING: this target does not support the llvm." 43058446916b71c4ff79962081ea7c4df078c388b0eBob Wilson << (Callee->getIntrinsicID() == Intrinsic::returnaddress ? 43158446916b71c4ff79962081ea7c4df078c388b0eBob Wilson "return" : "frame") << "address intrinsic.\n"; 432cf8990838143fcfa91dd6276af523ac6c23517c2Chris Lattner CI->replaceAllUsesWith(ConstantPointerNull::get( 433cf8990838143fcfa91dd6276af523ac6c23517c2Chris Lattner cast<PointerType>(CI->getType()))); 434cf8990838143fcfa91dd6276af523ac6c23517c2Chris Lattner break; 435cf8990838143fcfa91dd6276af523ac6c23517c2Chris Lattner 4360942b7caf1b5fde959301042129d25f1e7b86b28Chris Lattner case Intrinsic::prefetch: 4370942b7caf1b5fde959301042129d25f1e7b86b28Chris Lattner break; // Simply strip out prefetches on unsupported architectures 4380942b7caf1b5fde959301042129d25f1e7b86b28Chris Lattner 4397f4ec3b2e3157e6a0798f3e95a3961bfa6ef66b6Andrew Lenharth case Intrinsic::pcmarker: 4407f4ec3b2e3157e6a0798f3e95a3961bfa6ef66b6Andrew Lenharth break; // Simply strip out pcmarker on unsupported architectures 44158446916b71c4ff79962081ea7c4df078c388b0eBob Wilson case Intrinsic::readcyclecounter: { 44258446916b71c4ff79962081ea7c4df078c388b0eBob Wilson errs() << "WARNING: this target does not support the llvm.readcyclecoun" 44358446916b71c4ff79962081ea7c4df078c388b0eBob Wilson << "ter intrinsic. It is being lowered to a constant 0\n"; 4441d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson CI->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context), 0)); 44551b8d54922350b7e1c2cd5a5183ef2c5f5d1b1d5Andrew Lenharth break; 44658446916b71c4ff79962081ea7c4df078c388b0eBob Wilson } 4477f4ec3b2e3157e6a0798f3e95a3961bfa6ef66b6Andrew Lenharth 44843970fec322d9e0153ca513de41d80af1c79bddeJim Laskey case Intrinsic::dbg_declare: 449f664e41b201bad27ed3661bf50cd71f54242c114Duncan Sands break; // Simply strip out debugging intrinsics 450f664e41b201bad27ed3661bf50cd71f54242c114Duncan Sands 451b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands case Intrinsic::eh_typeid_for: 452f664e41b201bad27ed3661bf50cd71f54242c114Duncan Sands // Return something different to eh_selector. 453eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 454f664e41b201bad27ed3661bf50cd71f54242c114Duncan Sands break; 4555fe51cc2c46afca64638597cdef3bdafa6cd0a8cChris Lattner 456c2b7f5fa511420b99dd8238ab4ba769a6a6015a5Justin Holewinski case Intrinsic::annotation: 457c2b7f5fa511420b99dd8238ab4ba769a6a6015a5Justin Holewinski case Intrinsic::ptr_annotation: 458c2b7f5fa511420b99dd8238ab4ba769a6a6015a5Justin Holewinski // Just drop the annotation, but forward the value 459c2b7f5fa511420b99dd8238ab4ba769a6a6015a5Justin Holewinski CI->replaceAllUsesWith(CI->getOperand(0)); 460c2b7f5fa511420b99dd8238ab4ba769a6a6015a5Justin Holewinski break; 461c2b7f5fa511420b99dd8238ab4ba769a6a6015a5Justin Holewinski 46224e5aada7d112447c41c12008f7daf1fc15a24bcTanya Lattner case Intrinsic::var_annotation: 46324e5aada7d112447c41c12008f7daf1fc15a24bcTanya Lattner break; // Strip out annotate intrinsic 46424e5aada7d112447c41c12008f7daf1fc15a24bcTanya Lattner 465824b958e6fb1236e92e4d07f3acf18fca107cdc0Chris Lattner case Intrinsic::memcpy: { 466ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth Type *IntPtr = TD.getIntPtrType(Context); 4679e38531d9561630520732146c32977443c73c243Gabor Greif Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 468e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad /* isSigned */ false); 469c67da0cf13e2d671061449e8da4ffe102e5fc848Chris Lattner Value *Ops[3]; 4709e38531d9561630520732146c32977443c73c243Gabor Greif Ops[0] = CI->getArgOperand(0); 4719e38531d9561630520732146c32977443c73c243Gabor Greif Ops[1] = CI->getArgOperand(1); 472c67da0cf13e2d671061449e8da4ffe102e5fc848Chris Lattner Ops[2] = Size; 4739e38531d9561630520732146c32977443c73c243Gabor Greif ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 4745fe51cc2c46afca64638597cdef3bdafa6cd0a8cChris Lattner break; 475f0a3e6c21cc24ebbec701bd8f6b1253b49498457Chris Lattner } 476824b958e6fb1236e92e4d07f3acf18fca107cdc0Chris Lattner case Intrinsic::memmove: { 477ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth Type *IntPtr = TD.getIntPtrType(Context); 4789e38531d9561630520732146c32977443c73c243Gabor Greif Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 479e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad /* isSigned */ false); 480c67da0cf13e2d671061449e8da4ffe102e5fc848Chris Lattner Value *Ops[3]; 4819e38531d9561630520732146c32977443c73c243Gabor Greif Ops[0] = CI->getArgOperand(0); 4829e38531d9561630520732146c32977443c73c243Gabor Greif Ops[1] = CI->getArgOperand(1); 483c67da0cf13e2d671061449e8da4ffe102e5fc848Chris Lattner Ops[2] = Size; 4849e38531d9561630520732146c32977443c73c243Gabor Greif ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 485c67da0cf13e2d671061449e8da4ffe102e5fc848Chris Lattner break; 4863da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer } 487824b958e6fb1236e92e4d07f3acf18fca107cdc0Chris Lattner case Intrinsic::memset: { 488ece6c6bb6329748b92403c06ac87f45c43485911Chandler Carruth Type *IntPtr = TD.getIntPtrType(Context); 4899e38531d9561630520732146c32977443c73c243Gabor Greif Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 490e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad /* isSigned */ false); 491c67da0cf13e2d671061449e8da4ffe102e5fc848Chris Lattner Value *Ops[3]; 4929e38531d9561630520732146c32977443c73c243Gabor Greif Ops[0] = CI->getArgOperand(0); 493c67da0cf13e2d671061449e8da4ffe102e5fc848Chris Lattner // Extend the amount to i32. 494a399781289092fcdceb58b21174229f4373c4191Gabor Greif Ops[1] = Builder.CreateIntCast(CI->getArgOperand(1), 495a399781289092fcdceb58b21174229f4373c4191Gabor Greif Type::getInt32Ty(Context), 496e1e201416ae8ab40d31d223c5d560ee0f635e05aJay Foad /* isSigned */ false); 497c67da0cf13e2d671061449e8da4ffe102e5fc848Chris Lattner Ops[2] = Size; 4989e38531d9561630520732146c32977443c73c243Gabor Greif ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 499cf8990838143fcfa91dd6276af523ac6c23517c2Chris Lattner break; 500cf8990838143fcfa91dd6276af523ac6c23517c2Chris Lattner } 5019ab7fb3ba47442d521a5bed09a27a5e8e7a786edDale Johannesen case Intrinsic::sqrt: { 502b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl"); 5034292d1c02a6f10eca22aa6e27d57ea8bf15b3140Dale Johannesen break; 5044292d1c02a6f10eca22aa6e27d57ea8bf15b3140Dale Johannesen } 5057794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::log: { 506b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl"); 5077794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 5087794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen } 5097794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::log2: { 510b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l"); 5117794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 5127794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen } 5137794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::log10: { 514b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l"); 5157794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 5167794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen } 5177794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::exp: { 518b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl"); 5197794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 5207794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen } 5217794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::exp2: { 522b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l"); 5237794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 5247794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen } 5257794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case Intrinsic::pow: { 526b41b5e0b2d865f9dcb8cc868b28929daf3a11207Owen Anderson ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl"); 5277794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 5287794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen } 529917c2a6ff2cfcd1263a5dd80c54336754c553aceAnton Korobeynikov case Intrinsic::flt_rounds: 530917c2a6ff2cfcd1263a5dd80c54336754c553aceAnton Korobeynikov // Lower to "round to the nearest" 531f012705c7e4ca8cf90b6b734ce1d5355daca5ba5Benjamin Kramer if (!CI->getType()->isVoidTy()) 532eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 533917c2a6ff2cfcd1263a5dd80c54336754c553aceAnton Korobeynikov break; 534f07c9497b2ad030457c9314db5bfb8b0b204a0daDuncan Sands case Intrinsic::invariant_start: 535f07c9497b2ad030457c9314db5bfb8b0b204a0daDuncan Sands case Intrinsic::lifetime_start: 536f07c9497b2ad030457c9314db5bfb8b0b204a0daDuncan Sands // Discard region information. 537f07c9497b2ad030457c9314db5bfb8b0b204a0daDuncan Sands CI->replaceAllUsesWith(UndefValue::get(CI->getType())); 538f07c9497b2ad030457c9314db5bfb8b0b204a0daDuncan Sands break; 539f07c9497b2ad030457c9314db5bfb8b0b204a0daDuncan Sands case Intrinsic::invariant_end: 540f07c9497b2ad030457c9314db5bfb8b0b204a0daDuncan Sands case Intrinsic::lifetime_end: 541f07c9497b2ad030457c9314db5bfb8b0b204a0daDuncan Sands // Discard region information. 542f07c9497b2ad030457c9314db5bfb8b0b204a0daDuncan Sands break; 543f0a3e6c21cc24ebbec701bd8f6b1253b49498457Chris Lattner } 544edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 5453b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner assert(CI->use_empty() && 5463b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner "Lowering should have eliminated any uses of the intrinsic call!"); 54786f3e0c24e8834e6ad5ac61f2459fb335549bc24Chris Lattner CI->eraseFromParent(); 5483b66ecb05fedbfe0a70b39d73b1ea5998bc8c31bChris Lattner} 54955d42003368c57d3a41c5f464d39b8440050d558Evan Cheng 55055d42003368c57d3a41c5f464d39b8440050d558Evan Chengbool IntrinsicLowering::LowerToByteSwap(CallInst *CI) { 55155d42003368c57d3a41c5f464d39b8440050d558Evan Cheng // Verify this is a simple bswap. 55255d42003368c57d3a41c5f464d39b8440050d558Evan Cheng if (CI->getNumArgOperands() != 1 || 55355d42003368c57d3a41c5f464d39b8440050d558Evan Cheng CI->getType() != CI->getArgOperand(0)->getType() || 55455d42003368c57d3a41c5f464d39b8440050d558Evan Cheng !CI->getType()->isIntegerTy()) 55555d42003368c57d3a41c5f464d39b8440050d558Evan Cheng return false; 55655d42003368c57d3a41c5f464d39b8440050d558Evan Cheng 5575fdd6c8793462549e3593890ec61573da06e3346Jay Foad IntegerType *Ty = dyn_cast<IntegerType>(CI->getType()); 55855d42003368c57d3a41c5f464d39b8440050d558Evan Cheng if (!Ty) 55955d42003368c57d3a41c5f464d39b8440050d558Evan Cheng return false; 56055d42003368c57d3a41c5f464d39b8440050d558Evan Cheng 56155d42003368c57d3a41c5f464d39b8440050d558Evan Cheng // Okay, we can do this xform, do so now. 56255d42003368c57d3a41c5f464d39b8440050d558Evan Cheng Module *M = CI->getParent()->getParent()->getParent(); 563eb9a85f09e18b3fe88499710404b38d3a9128f62Benjamin Kramer Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Ty); 56455d42003368c57d3a41c5f464d39b8440050d558Evan Cheng 56555d42003368c57d3a41c5f464d39b8440050d558Evan Cheng Value *Op = CI->getArgOperand(0); 56655d42003368c57d3a41c5f464d39b8440050d558Evan Cheng Op = CallInst::Create(Int, Op, CI->getName(), CI); 56755d42003368c57d3a41c5f464d39b8440050d558Evan Cheng 56855d42003368c57d3a41c5f464d39b8440050d558Evan Cheng CI->replaceAllUsesWith(Op); 56955d42003368c57d3a41c5f464d39b8440050d558Evan Cheng CI->eraseFromParent(); 57055d42003368c57d3a41c5f464d39b8440050d558Evan Cheng return true; 57155d42003368c57d3a41c5f464d39b8440050d558Evan Cheng} 572