IntrinsicLowering.cpp revision 218893
1193323Sed//===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements the IntrinsicLowering class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#include "llvm/Constants.h" 15193323Sed#include "llvm/DerivedTypes.h" 16193323Sed#include "llvm/Module.h" 17193323Sed#include "llvm/Type.h" 18193323Sed#include "llvm/CodeGen/IntrinsicLowering.h" 19210299Sed#include "llvm/Support/CallSite.h" 20198090Srdivacky#include "llvm/Support/ErrorHandling.h" 21193323Sed#include "llvm/Support/IRBuilder.h" 22198090Srdivacky#include "llvm/Support/raw_ostream.h" 23193323Sed#include "llvm/Target/TargetData.h" 24193323Sed#include "llvm/ADT/SmallVector.h" 25193323Sedusing namespace llvm; 26193323Sed 27193323Sedtemplate <class ArgIt> 28193323Sedstatic void EnsureFunctionExists(Module &M, const char *Name, 29193323Sed ArgIt ArgBegin, ArgIt ArgEnd, 30193323Sed const Type *RetTy) { 31193323Sed // Insert a correctly-typed definition now. 32193323Sed std::vector<const Type *> ParamTys; 33193323Sed for (ArgIt I = ArgBegin; I != ArgEnd; ++I) 34193323Sed ParamTys.push_back(I->getType()); 35193323Sed M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); 36193323Sed} 37193323Sed 38193323Sedstatic void EnsureFPIntrinsicsExist(Module &M, Function *Fn, 39193323Sed const char *FName, 40193323Sed const char *DName, const char *LDName) { 41193323Sed // Insert definitions for all the floating point types. 42193323Sed switch((int)Fn->arg_begin()->getType()->getTypeID()) { 43193323Sed case Type::FloatTyID: 44193323Sed EnsureFunctionExists(M, FName, Fn->arg_begin(), Fn->arg_end(), 45198090Srdivacky Type::getFloatTy(M.getContext())); 46193323Sed break; 47193323Sed case Type::DoubleTyID: 48193323Sed EnsureFunctionExists(M, DName, Fn->arg_begin(), Fn->arg_end(), 49198090Srdivacky Type::getDoubleTy(M.getContext())); 50193323Sed break; 51193323Sed case Type::X86_FP80TyID: 52193323Sed case Type::FP128TyID: 53193323Sed case Type::PPC_FP128TyID: 54193323Sed EnsureFunctionExists(M, LDName, Fn->arg_begin(), Fn->arg_end(), 55193323Sed Fn->arg_begin()->getType()); 56193323Sed break; 57193323Sed } 58193323Sed} 59193323Sed 60193323Sed/// ReplaceCallWith - This function is used when we want to lower an intrinsic 61193323Sed/// call to a call of an external function. This handles hard cases such as 62193323Sed/// when there was already a prototype for the external function, and if that 63193323Sed/// prototype doesn't match the arguments we expect to pass in. 64193323Sedtemplate <class ArgIt> 65193323Sedstatic CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, 66193323Sed ArgIt ArgBegin, ArgIt ArgEnd, 67195098Sed const Type *RetTy) { 68195098Sed // If we haven't already looked up this function, check to see if the 69195098Sed // program already contains a function with this name. 70195098Sed Module *M = CI->getParent()->getParent()->getParent(); 71195098Sed // Get or insert the definition now. 72195098Sed std::vector<const Type *> ParamTys; 73195098Sed for (ArgIt I = ArgBegin; I != ArgEnd; ++I) 74195098Sed ParamTys.push_back((*I)->getType()); 75195098Sed Constant* FCache = M->getOrInsertFunction(NewFn, 76195098Sed FunctionType::get(RetTy, ParamTys, false)); 77193323Sed 78193323Sed IRBuilder<> Builder(CI->getParent(), CI); 79193323Sed SmallVector<Value *, 8> Args(ArgBegin, ArgEnd); 80193323Sed CallInst *NewCI = Builder.CreateCall(FCache, Args.begin(), Args.end()); 81193323Sed NewCI->setName(CI->getName()); 82193323Sed if (!CI->use_empty()) 83193323Sed CI->replaceAllUsesWith(NewCI); 84193323Sed return NewCI; 85193323Sed} 86193323Sed 87208599Srdivacky// VisualStudio defines setjmp as _setjmp 88218893Sdim#if defined(_MSC_VER) && defined(setjmp) && \ 89218893Sdim !defined(setjmp_undefined_for_msvc) 90218893Sdim# pragma push_macro("setjmp") 91218893Sdim# undef setjmp 92218893Sdim# define setjmp_undefined_for_msvc 93208599Srdivacky#endif 94208599Srdivacky 95193323Sedvoid IntrinsicLowering::AddPrototypes(Module &M) { 96198090Srdivacky LLVMContext &Context = M.getContext(); 97193323Sed for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 98193323Sed if (I->isDeclaration() && !I->use_empty()) 99193323Sed switch (I->getIntrinsicID()) { 100193323Sed default: break; 101193323Sed case Intrinsic::setjmp: 102193323Sed EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(), 103198090Srdivacky Type::getInt32Ty(M.getContext())); 104193323Sed break; 105193323Sed case Intrinsic::longjmp: 106193323Sed EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(), 107198090Srdivacky Type::getVoidTy(M.getContext())); 108193323Sed break; 109193323Sed case Intrinsic::siglongjmp: 110193323Sed EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(), 111198090Srdivacky Type::getVoidTy(M.getContext())); 112193323Sed break; 113193323Sed case Intrinsic::memcpy: 114198090Srdivacky M.getOrInsertFunction("memcpy", 115198090Srdivacky Type::getInt8PtrTy(Context), 116198090Srdivacky Type::getInt8PtrTy(Context), 117198090Srdivacky Type::getInt8PtrTy(Context), 118198090Srdivacky TD.getIntPtrType(Context), (Type *)0); 119193323Sed break; 120193323Sed case Intrinsic::memmove: 121198090Srdivacky M.getOrInsertFunction("memmove", 122198090Srdivacky Type::getInt8PtrTy(Context), 123198090Srdivacky Type::getInt8PtrTy(Context), 124198090Srdivacky Type::getInt8PtrTy(Context), 125198090Srdivacky TD.getIntPtrType(Context), (Type *)0); 126193323Sed break; 127193323Sed case Intrinsic::memset: 128198090Srdivacky M.getOrInsertFunction("memset", 129198090Srdivacky Type::getInt8PtrTy(Context), 130198090Srdivacky Type::getInt8PtrTy(Context), 131198090Srdivacky Type::getInt32Ty(M.getContext()), 132198090Srdivacky TD.getIntPtrType(Context), (Type *)0); 133193323Sed break; 134193323Sed case Intrinsic::sqrt: 135193323Sed EnsureFPIntrinsicsExist(M, I, "sqrtf", "sqrt", "sqrtl"); 136193323Sed break; 137193323Sed case Intrinsic::sin: 138193323Sed EnsureFPIntrinsicsExist(M, I, "sinf", "sin", "sinl"); 139193323Sed break; 140193323Sed case Intrinsic::cos: 141193323Sed EnsureFPIntrinsicsExist(M, I, "cosf", "cos", "cosl"); 142193323Sed break; 143193323Sed case Intrinsic::pow: 144193323Sed EnsureFPIntrinsicsExist(M, I, "powf", "pow", "powl"); 145193323Sed break; 146193323Sed case Intrinsic::log: 147193323Sed EnsureFPIntrinsicsExist(M, I, "logf", "log", "logl"); 148193323Sed break; 149193323Sed case Intrinsic::log2: 150193323Sed EnsureFPIntrinsicsExist(M, I, "log2f", "log2", "log2l"); 151193323Sed break; 152193323Sed case Intrinsic::log10: 153193323Sed EnsureFPIntrinsicsExist(M, I, "log10f", "log10", "log10l"); 154193323Sed break; 155193323Sed case Intrinsic::exp: 156193323Sed EnsureFPIntrinsicsExist(M, I, "expf", "exp", "expl"); 157193323Sed break; 158193323Sed case Intrinsic::exp2: 159193323Sed EnsureFPIntrinsicsExist(M, I, "exp2f", "exp2", "exp2l"); 160193323Sed break; 161193323Sed } 162193323Sed} 163193323Sed 164193323Sed/// LowerBSWAP - Emit the code to lower bswap of V before the specified 165193323Sed/// instruction IP. 166198090Srdivackystatic Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) { 167203954Srdivacky assert(V->getType()->isIntegerTy() && "Can't bswap a non-integer type!"); 168193323Sed 169193323Sed unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 170193323Sed 171193323Sed IRBuilder<> Builder(IP->getParent(), IP); 172193323Sed 173193323Sed switch(BitSize) { 174198090Srdivacky default: llvm_unreachable("Unhandled type size of value to byteswap!"); 175193323Sed case 16: { 176193323Sed Value *Tmp1 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 177193323Sed "bswap.2"); 178193323Sed Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 179193323Sed "bswap.1"); 180193323Sed V = Builder.CreateOr(Tmp1, Tmp2, "bswap.i16"); 181193323Sed break; 182193323Sed } 183193323Sed case 32: { 184193323Sed Value *Tmp4 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), 185193323Sed "bswap.4"); 186193323Sed Value *Tmp3 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 187193323Sed "bswap.3"); 188193323Sed Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 189193323Sed "bswap.2"); 190198090Srdivacky Value *Tmp1 = Builder.CreateLShr(V,ConstantInt::get(V->getType(), 24), 191193323Sed "bswap.1"); 192198090Srdivacky Tmp3 = Builder.CreateAnd(Tmp3, 193198090Srdivacky ConstantInt::get(Type::getInt32Ty(Context), 0xFF0000), 194193323Sed "bswap.and3"); 195198090Srdivacky Tmp2 = Builder.CreateAnd(Tmp2, 196198090Srdivacky ConstantInt::get(Type::getInt32Ty(Context), 0xFF00), 197193323Sed "bswap.and2"); 198193323Sed Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or1"); 199193323Sed Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or2"); 200193323Sed V = Builder.CreateOr(Tmp4, Tmp2, "bswap.i32"); 201193323Sed break; 202193323Sed } 203193323Sed case 64: { 204193323Sed Value *Tmp8 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 56), 205193323Sed "bswap.8"); 206193323Sed Value *Tmp7 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 40), 207193323Sed "bswap.7"); 208193323Sed Value *Tmp6 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), 209193323Sed "bswap.6"); 210193323Sed Value *Tmp5 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 211193323Sed "bswap.5"); 212193323Sed Value* Tmp4 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 213193323Sed "bswap.4"); 214198090Srdivacky Value* Tmp3 = Builder.CreateLShr(V, 215198090Srdivacky ConstantInt::get(V->getType(), 24), 216193323Sed "bswap.3"); 217198090Srdivacky Value* Tmp2 = Builder.CreateLShr(V, 218198090Srdivacky ConstantInt::get(V->getType(), 40), 219193323Sed "bswap.2"); 220198090Srdivacky Value* Tmp1 = Builder.CreateLShr(V, 221198090Srdivacky ConstantInt::get(V->getType(), 56), 222193323Sed "bswap.1"); 223193323Sed Tmp7 = Builder.CreateAnd(Tmp7, 224198090Srdivacky ConstantInt::get(Type::getInt64Ty(Context), 225193323Sed 0xFF000000000000ULL), 226193323Sed "bswap.and7"); 227193323Sed Tmp6 = Builder.CreateAnd(Tmp6, 228198090Srdivacky ConstantInt::get(Type::getInt64Ty(Context), 229193323Sed 0xFF0000000000ULL), 230193323Sed "bswap.and6"); 231193323Sed Tmp5 = Builder.CreateAnd(Tmp5, 232198090Srdivacky ConstantInt::get(Type::getInt64Ty(Context), 233198090Srdivacky 0xFF00000000ULL), 234193323Sed "bswap.and5"); 235193323Sed Tmp4 = Builder.CreateAnd(Tmp4, 236198090Srdivacky ConstantInt::get(Type::getInt64Ty(Context), 237198090Srdivacky 0xFF000000ULL), 238193323Sed "bswap.and4"); 239193323Sed Tmp3 = Builder.CreateAnd(Tmp3, 240198090Srdivacky ConstantInt::get(Type::getInt64Ty(Context), 241198090Srdivacky 0xFF0000ULL), 242193323Sed "bswap.and3"); 243193323Sed Tmp2 = Builder.CreateAnd(Tmp2, 244198090Srdivacky ConstantInt::get(Type::getInt64Ty(Context), 245198090Srdivacky 0xFF00ULL), 246193323Sed "bswap.and2"); 247193323Sed Tmp8 = Builder.CreateOr(Tmp8, Tmp7, "bswap.or1"); 248193323Sed Tmp6 = Builder.CreateOr(Tmp6, Tmp5, "bswap.or2"); 249193323Sed Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or3"); 250193323Sed Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or4"); 251193323Sed Tmp8 = Builder.CreateOr(Tmp8, Tmp6, "bswap.or5"); 252193323Sed Tmp4 = Builder.CreateOr(Tmp4, Tmp2, "bswap.or6"); 253193323Sed V = Builder.CreateOr(Tmp8, Tmp4, "bswap.i64"); 254193323Sed break; 255193323Sed } 256193323Sed } 257193323Sed return V; 258193323Sed} 259193323Sed 260193323Sed/// LowerCTPOP - Emit the code to lower ctpop of V before the specified 261193323Sed/// instruction IP. 262198090Srdivackystatic Value *LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP) { 263203954Srdivacky assert(V->getType()->isIntegerTy() && "Can't ctpop a non-integer type!"); 264193323Sed 265193323Sed static const uint64_t MaskValues[6] = { 266193323Sed 0x5555555555555555ULL, 0x3333333333333333ULL, 267193323Sed 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL, 268193323Sed 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL 269193323Sed }; 270193323Sed 271193323Sed IRBuilder<> Builder(IP->getParent(), IP); 272193323Sed 273193323Sed unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 274193323Sed unsigned WordSize = (BitSize + 63) / 64; 275193323Sed Value *Count = ConstantInt::get(V->getType(), 0); 276193323Sed 277193323Sed for (unsigned n = 0; n < WordSize; ++n) { 278193323Sed Value *PartValue = V; 279193323Sed for (unsigned i = 1, ct = 0; i < (BitSize>64 ? 64 : BitSize); 280193323Sed i <<= 1, ++ct) { 281193323Sed Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]); 282193323Sed Value *LHS = Builder.CreateAnd(PartValue, MaskCst, "cppop.and1"); 283193323Sed Value *VShift = Builder.CreateLShr(PartValue, 284198090Srdivacky ConstantInt::get(V->getType(), i), 285193323Sed "ctpop.sh"); 286193323Sed Value *RHS = Builder.CreateAnd(VShift, MaskCst, "cppop.and2"); 287193323Sed PartValue = Builder.CreateAdd(LHS, RHS, "ctpop.step"); 288193323Sed } 289193323Sed Count = Builder.CreateAdd(PartValue, Count, "ctpop.part"); 290193323Sed if (BitSize > 64) { 291193323Sed V = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 64), 292193323Sed "ctpop.part.sh"); 293193323Sed BitSize -= 64; 294193323Sed } 295193323Sed } 296193323Sed 297193323Sed return Count; 298193323Sed} 299193323Sed 300193323Sed/// LowerCTLZ - Emit the code to lower ctlz of V before the specified 301193323Sed/// instruction IP. 302198090Srdivackystatic Value *LowerCTLZ(LLVMContext &Context, Value *V, Instruction *IP) { 303193323Sed 304193323Sed IRBuilder<> Builder(IP->getParent(), IP); 305193323Sed 306193323Sed unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 307193323Sed for (unsigned i = 1; i < BitSize; i <<= 1) { 308193323Sed Value *ShVal = ConstantInt::get(V->getType(), i); 309193323Sed ShVal = Builder.CreateLShr(V, ShVal, "ctlz.sh"); 310193323Sed V = Builder.CreateOr(V, ShVal, "ctlz.step"); 311193323Sed } 312193323Sed 313193323Sed V = Builder.CreateNot(V); 314198090Srdivacky return LowerCTPOP(Context, V, IP); 315193323Sed} 316193323Sed 317195098Sedstatic void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, 318195098Sed const char *Dname, 319193323Sed const char *LDname) { 320210299Sed CallSite CS(CI); 321210299Sed switch (CI->getArgOperand(0)->getType()->getTypeID()) { 322198090Srdivacky default: llvm_unreachable("Invalid type in intrinsic"); 323193323Sed case Type::FloatTyID: 324210299Sed ReplaceCallWith(Fname, CI, CS.arg_begin(), CS.arg_end(), 325198090Srdivacky Type::getFloatTy(CI->getContext())); 326193323Sed break; 327193323Sed case Type::DoubleTyID: 328210299Sed ReplaceCallWith(Dname, CI, CS.arg_begin(), CS.arg_end(), 329198090Srdivacky Type::getDoubleTy(CI->getContext())); 330193323Sed break; 331193323Sed case Type::X86_FP80TyID: 332193323Sed case Type::FP128TyID: 333193323Sed case Type::PPC_FP128TyID: 334210299Sed ReplaceCallWith(LDname, CI, CS.arg_begin(), CS.arg_end(), 335210299Sed CI->getArgOperand(0)->getType()); 336193323Sed break; 337193323Sed } 338193323Sed} 339193323Sed 340193323Sedvoid IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { 341193323Sed IRBuilder<> Builder(CI->getParent(), CI); 342198090Srdivacky LLVMContext &Context = CI->getContext(); 343193323Sed 344207618Srdivacky const Function *Callee = CI->getCalledFunction(); 345193323Sed assert(Callee && "Cannot lower an indirect call!"); 346193323Sed 347210299Sed CallSite CS(CI); 348193323Sed switch (Callee->getIntrinsicID()) { 349193323Sed case Intrinsic::not_intrinsic: 350207618Srdivacky report_fatal_error("Cannot lower a call to a non-intrinsic function '"+ 351198090Srdivacky Callee->getName() + "'!"); 352193323Sed default: 353207618Srdivacky report_fatal_error("Code generator does not support intrinsic function '"+ 354198090Srdivacky Callee->getName()+"'!"); 355193323Sed 356193323Sed // The setjmp/longjmp intrinsics should only exist in the code if it was 357193323Sed // never optimized (ie, right out of the CFE), or if it has been hacked on 358193323Sed // by the lowerinvoke pass. In both cases, the right thing to do is to 359193323Sed // convert the call to an explicit setjmp or longjmp call. 360193323Sed case Intrinsic::setjmp: { 361210299Sed Value *V = ReplaceCallWith("setjmp", CI, CS.arg_begin(), CS.arg_end(), 362198090Srdivacky Type::getInt32Ty(Context)); 363202375Srdivacky if (!CI->getType()->isVoidTy()) 364193323Sed CI->replaceAllUsesWith(V); 365193323Sed break; 366193323Sed } 367193323Sed case Intrinsic::sigsetjmp: 368202375Srdivacky if (!CI->getType()->isVoidTy()) 369193323Sed CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 370193323Sed break; 371193323Sed 372193323Sed case Intrinsic::longjmp: { 373210299Sed ReplaceCallWith("longjmp", CI, CS.arg_begin(), CS.arg_end(), 374198090Srdivacky Type::getVoidTy(Context)); 375193323Sed break; 376193323Sed } 377193323Sed 378193323Sed case Intrinsic::siglongjmp: { 379193323Sed // Insert the call to abort 380210299Sed ReplaceCallWith("abort", CI, CS.arg_end(), CS.arg_end(), 381198090Srdivacky Type::getVoidTy(Context)); 382193323Sed break; 383193323Sed } 384193323Sed case Intrinsic::ctpop: 385210299Sed CI->replaceAllUsesWith(LowerCTPOP(Context, CI->getArgOperand(0), CI)); 386193323Sed break; 387193323Sed 388193323Sed case Intrinsic::bswap: 389210299Sed CI->replaceAllUsesWith(LowerBSWAP(Context, CI->getArgOperand(0), CI)); 390193323Sed break; 391193323Sed 392193323Sed case Intrinsic::ctlz: 393210299Sed CI->replaceAllUsesWith(LowerCTLZ(Context, CI->getArgOperand(0), CI)); 394193323Sed break; 395193323Sed 396193323Sed case Intrinsic::cttz: { 397193323Sed // cttz(x) -> ctpop(~X & (X-1)) 398210299Sed Value *Src = CI->getArgOperand(0); 399193323Sed Value *NotSrc = Builder.CreateNot(Src); 400193323Sed NotSrc->setName(Src->getName() + ".not"); 401193323Sed Value *SrcM1 = ConstantInt::get(Src->getType(), 1); 402193323Sed SrcM1 = Builder.CreateSub(Src, SrcM1); 403198090Srdivacky Src = LowerCTPOP(Context, Builder.CreateAnd(NotSrc, SrcM1), CI); 404193323Sed CI->replaceAllUsesWith(Src); 405193323Sed break; 406193323Sed } 407193323Sed 408193323Sed case Intrinsic::stacksave: 409193323Sed case Intrinsic::stackrestore: { 410193323Sed if (!Warned) 411198090Srdivacky errs() << "WARNING: this target does not support the llvm.stack" 412198090Srdivacky << (Callee->getIntrinsicID() == Intrinsic::stacksave ? 413193323Sed "save" : "restore") << " intrinsic.\n"; 414193323Sed Warned = true; 415193323Sed if (Callee->getIntrinsicID() == Intrinsic::stacksave) 416193323Sed CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 417193323Sed break; 418193323Sed } 419193323Sed 420193323Sed case Intrinsic::returnaddress: 421193323Sed case Intrinsic::frameaddress: 422198090Srdivacky errs() << "WARNING: this target does not support the llvm." 423198090Srdivacky << (Callee->getIntrinsicID() == Intrinsic::returnaddress ? 424193323Sed "return" : "frame") << "address intrinsic.\n"; 425193323Sed CI->replaceAllUsesWith(ConstantPointerNull::get( 426193323Sed cast<PointerType>(CI->getType()))); 427193323Sed break; 428193323Sed 429193323Sed case Intrinsic::prefetch: 430193323Sed break; // Simply strip out prefetches on unsupported architectures 431193323Sed 432193323Sed case Intrinsic::pcmarker: 433193323Sed break; // Simply strip out pcmarker on unsupported architectures 434193323Sed case Intrinsic::readcyclecounter: { 435198090Srdivacky errs() << "WARNING: this target does not support the llvm.readcyclecoun" 436198090Srdivacky << "ter intrinsic. It is being lowered to a constant 0\n"; 437198090Srdivacky CI->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context), 0)); 438193323Sed break; 439193323Sed } 440193323Sed 441193323Sed case Intrinsic::dbg_declare: 442193323Sed break; // Simply strip out debugging intrinsics 443193323Sed 444193323Sed case Intrinsic::eh_exception: 445198090Srdivacky case Intrinsic::eh_selector: 446193323Sed CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 447193323Sed break; 448193323Sed 449198090Srdivacky case Intrinsic::eh_typeid_for: 450193323Sed // Return something different to eh_selector. 451193323Sed CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 452193323Sed break; 453193323Sed 454193323Sed case Intrinsic::var_annotation: 455193323Sed break; // Strip out annotate intrinsic 456193323Sed 457193323Sed case Intrinsic::memcpy: { 458198090Srdivacky const IntegerType *IntPtr = TD.getIntPtrType(Context); 459210299Sed Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 460193323Sed /* isSigned */ false); 461193323Sed Value *Ops[3]; 462210299Sed Ops[0] = CI->getArgOperand(0); 463210299Sed Ops[1] = CI->getArgOperand(1); 464193323Sed Ops[2] = Size; 465210299Sed ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 466193323Sed break; 467193323Sed } 468193323Sed case Intrinsic::memmove: { 469198090Srdivacky const IntegerType *IntPtr = TD.getIntPtrType(Context); 470210299Sed Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 471193323Sed /* isSigned */ false); 472193323Sed Value *Ops[3]; 473210299Sed Ops[0] = CI->getArgOperand(0); 474210299Sed Ops[1] = CI->getArgOperand(1); 475193323Sed Ops[2] = Size; 476210299Sed ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 477193323Sed break; 478193323Sed } 479193323Sed case Intrinsic::memset: { 480198090Srdivacky const IntegerType *IntPtr = TD.getIntPtrType(Context); 481210299Sed Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 482193323Sed /* isSigned */ false); 483193323Sed Value *Ops[3]; 484210299Sed Ops[0] = CI->getArgOperand(0); 485193323Sed // Extend the amount to i32. 486212904Sdim Ops[1] = Builder.CreateIntCast(CI->getArgOperand(1), 487212904Sdim Type::getInt32Ty(Context), 488193323Sed /* isSigned */ false); 489193323Sed Ops[2] = Size; 490210299Sed ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 491193323Sed break; 492193323Sed } 493193323Sed case Intrinsic::sqrt: { 494195098Sed ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl"); 495193323Sed break; 496193323Sed } 497193323Sed case Intrinsic::log: { 498195098Sed ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl"); 499193323Sed break; 500193323Sed } 501193323Sed case Intrinsic::log2: { 502195098Sed ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l"); 503193323Sed break; 504193323Sed } 505193323Sed case Intrinsic::log10: { 506195098Sed ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l"); 507193323Sed break; 508193323Sed } 509193323Sed case Intrinsic::exp: { 510195098Sed ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl"); 511193323Sed break; 512193323Sed } 513193323Sed case Intrinsic::exp2: { 514195098Sed ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l"); 515193323Sed break; 516193323Sed } 517193323Sed case Intrinsic::pow: { 518195098Sed ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl"); 519193323Sed break; 520193323Sed } 521193323Sed case Intrinsic::flt_rounds: 522193323Sed // Lower to "round to the nearest" 523202375Srdivacky if (!CI->getType()->isVoidTy()) 524193323Sed CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 525193323Sed break; 526199481Srdivacky case Intrinsic::invariant_start: 527199481Srdivacky case Intrinsic::lifetime_start: 528199481Srdivacky // Discard region information. 529199481Srdivacky CI->replaceAllUsesWith(UndefValue::get(CI->getType())); 530199481Srdivacky break; 531199481Srdivacky case Intrinsic::invariant_end: 532199481Srdivacky case Intrinsic::lifetime_end: 533199481Srdivacky // Discard region information. 534199481Srdivacky break; 535193323Sed } 536193323Sed 537193323Sed assert(CI->use_empty() && 538193323Sed "Lowering should have eliminated any uses of the intrinsic call!"); 539193323Sed CI->eraseFromParent(); 540193323Sed} 541218893Sdim 542218893Sdimbool IntrinsicLowering::LowerToByteSwap(CallInst *CI) { 543218893Sdim // Verify this is a simple bswap. 544218893Sdim if (CI->getNumArgOperands() != 1 || 545218893Sdim CI->getType() != CI->getArgOperand(0)->getType() || 546218893Sdim !CI->getType()->isIntegerTy()) 547218893Sdim return false; 548218893Sdim 549218893Sdim const IntegerType *Ty = dyn_cast<IntegerType>(CI->getType()); 550218893Sdim if (!Ty) 551218893Sdim return false; 552218893Sdim 553218893Sdim // Okay, we can do this xform, do so now. 554218893Sdim const Type *Tys[] = { Ty }; 555218893Sdim Module *M = CI->getParent()->getParent()->getParent(); 556218893Sdim Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 1); 557218893Sdim 558218893Sdim Value *Op = CI->getArgOperand(0); 559218893Sdim Op = CallInst::Create(Int, Op, CI->getName(), CI); 560218893Sdim 561218893Sdim CI->replaceAllUsesWith(Op); 562218893Sdim CI->eraseFromParent(); 563218893Sdim return true; 564218893Sdim} 565