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 14245431Sdim#include "llvm/CodeGen/IntrinsicLowering.h" 15245431Sdim#include "llvm/ADT/SmallVector.h" 16252723Sdim#include "llvm/IR/Constants.h" 17252723Sdim#include "llvm/IR/DataLayout.h" 18252723Sdim#include "llvm/IR/DerivedTypes.h" 19252723Sdim#include "llvm/IR/IRBuilder.h" 20252723Sdim#include "llvm/IR/Module.h" 21252723Sdim#include "llvm/IR/Type.h" 22210299Sed#include "llvm/Support/CallSite.h" 23198090Srdivacky#include "llvm/Support/ErrorHandling.h" 24198090Srdivacky#include "llvm/Support/raw_ostream.h" 25193323Sedusing namespace llvm; 26193323Sed 27193323Sedtemplate <class ArgIt> 28193323Sedstatic void EnsureFunctionExists(Module &M, const char *Name, 29193323Sed ArgIt ArgBegin, ArgIt ArgEnd, 30226890Sdim Type *RetTy) { 31193323Sed // Insert a correctly-typed definition now. 32224145Sdim std::vector<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, 67226890Sdim 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. 72224145Sdim std::vector<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); 80224145Sdim CallInst *NewCI = Builder.CreateCall(FCache, Args); 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 356224145Sdim case Intrinsic::expect: { 357224145Sdim // Just replace __builtin_expect(exp, c) with EXP. 358224145Sdim Value *V = CI->getArgOperand(0); 359224145Sdim CI->replaceAllUsesWith(V); 360224145Sdim break; 361224145Sdim } 362224145Sdim 363193323Sed // The setjmp/longjmp intrinsics should only exist in the code if it was 364193323Sed // never optimized (ie, right out of the CFE), or if it has been hacked on 365193323Sed // by the lowerinvoke pass. In both cases, the right thing to do is to 366193323Sed // convert the call to an explicit setjmp or longjmp call. 367193323Sed case Intrinsic::setjmp: { 368210299Sed Value *V = ReplaceCallWith("setjmp", CI, CS.arg_begin(), CS.arg_end(), 369198090Srdivacky Type::getInt32Ty(Context)); 370202375Srdivacky if (!CI->getType()->isVoidTy()) 371193323Sed CI->replaceAllUsesWith(V); 372193323Sed break; 373193323Sed } 374193323Sed case Intrinsic::sigsetjmp: 375202375Srdivacky if (!CI->getType()->isVoidTy()) 376193323Sed CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 377193323Sed break; 378193323Sed 379193323Sed case Intrinsic::longjmp: { 380210299Sed ReplaceCallWith("longjmp", CI, CS.arg_begin(), CS.arg_end(), 381198090Srdivacky Type::getVoidTy(Context)); 382193323Sed break; 383193323Sed } 384193323Sed 385193323Sed case Intrinsic::siglongjmp: { 386193323Sed // Insert the call to abort 387210299Sed ReplaceCallWith("abort", CI, CS.arg_end(), CS.arg_end(), 388198090Srdivacky Type::getVoidTy(Context)); 389193323Sed break; 390193323Sed } 391193323Sed case Intrinsic::ctpop: 392210299Sed CI->replaceAllUsesWith(LowerCTPOP(Context, CI->getArgOperand(0), CI)); 393193323Sed break; 394193323Sed 395193323Sed case Intrinsic::bswap: 396210299Sed CI->replaceAllUsesWith(LowerBSWAP(Context, CI->getArgOperand(0), CI)); 397193323Sed break; 398193323Sed 399193323Sed case Intrinsic::ctlz: 400210299Sed CI->replaceAllUsesWith(LowerCTLZ(Context, CI->getArgOperand(0), CI)); 401193323Sed break; 402193323Sed 403193323Sed case Intrinsic::cttz: { 404193323Sed // cttz(x) -> ctpop(~X & (X-1)) 405210299Sed Value *Src = CI->getArgOperand(0); 406193323Sed Value *NotSrc = Builder.CreateNot(Src); 407193323Sed NotSrc->setName(Src->getName() + ".not"); 408193323Sed Value *SrcM1 = ConstantInt::get(Src->getType(), 1); 409193323Sed SrcM1 = Builder.CreateSub(Src, SrcM1); 410198090Srdivacky Src = LowerCTPOP(Context, Builder.CreateAnd(NotSrc, SrcM1), CI); 411193323Sed CI->replaceAllUsesWith(Src); 412193323Sed break; 413193323Sed } 414193323Sed 415193323Sed case Intrinsic::stacksave: 416193323Sed case Intrinsic::stackrestore: { 417193323Sed if (!Warned) 418198090Srdivacky errs() << "WARNING: this target does not support the llvm.stack" 419198090Srdivacky << (Callee->getIntrinsicID() == Intrinsic::stacksave ? 420193323Sed "save" : "restore") << " intrinsic.\n"; 421193323Sed Warned = true; 422193323Sed if (Callee->getIntrinsicID() == Intrinsic::stacksave) 423193323Sed CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 424193323Sed break; 425193323Sed } 426193323Sed 427193323Sed case Intrinsic::returnaddress: 428193323Sed case Intrinsic::frameaddress: 429198090Srdivacky errs() << "WARNING: this target does not support the llvm." 430198090Srdivacky << (Callee->getIntrinsicID() == Intrinsic::returnaddress ? 431193323Sed "return" : "frame") << "address intrinsic.\n"; 432193323Sed CI->replaceAllUsesWith(ConstantPointerNull::get( 433193323Sed cast<PointerType>(CI->getType()))); 434193323Sed break; 435193323Sed 436193323Sed case Intrinsic::prefetch: 437193323Sed break; // Simply strip out prefetches on unsupported architectures 438193323Sed 439193323Sed case Intrinsic::pcmarker: 440193323Sed break; // Simply strip out pcmarker on unsupported architectures 441193323Sed case Intrinsic::readcyclecounter: { 442198090Srdivacky errs() << "WARNING: this target does not support the llvm.readcyclecoun" 443198090Srdivacky << "ter intrinsic. It is being lowered to a constant 0\n"; 444198090Srdivacky CI->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context), 0)); 445193323Sed break; 446193323Sed } 447193323Sed 448193323Sed case Intrinsic::dbg_declare: 449193323Sed break; // Simply strip out debugging intrinsics 450193323Sed 451198090Srdivacky case Intrinsic::eh_typeid_for: 452193323Sed // Return something different to eh_selector. 453193323Sed CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 454193323Sed break; 455193323Sed 456252723Sdim case Intrinsic::annotation: 457252723Sdim case Intrinsic::ptr_annotation: 458252723Sdim // Just drop the annotation, but forward the value 459252723Sdim CI->replaceAllUsesWith(CI->getOperand(0)); 460252723Sdim break; 461252723Sdim 462193323Sed case Intrinsic::var_annotation: 463193323Sed break; // Strip out annotate intrinsic 464193323Sed 465193323Sed case Intrinsic::memcpy: { 466245431Sdim Type *IntPtr = TD.getIntPtrType(Context); 467210299Sed Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 468193323Sed /* isSigned */ false); 469193323Sed Value *Ops[3]; 470210299Sed Ops[0] = CI->getArgOperand(0); 471210299Sed Ops[1] = CI->getArgOperand(1); 472193323Sed Ops[2] = Size; 473210299Sed ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 474193323Sed break; 475193323Sed } 476193323Sed case Intrinsic::memmove: { 477245431Sdim Type *IntPtr = TD.getIntPtrType(Context); 478210299Sed Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 479193323Sed /* isSigned */ false); 480193323Sed Value *Ops[3]; 481210299Sed Ops[0] = CI->getArgOperand(0); 482210299Sed Ops[1] = CI->getArgOperand(1); 483193323Sed Ops[2] = Size; 484210299Sed ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 485193323Sed break; 486193323Sed } 487193323Sed case Intrinsic::memset: { 488263509Sdim Value *Op0 = CI->getArgOperand(0); 489263509Sdim Type *IntPtr = TD.getIntPtrType(Op0->getType()); 490210299Sed Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 491193323Sed /* isSigned */ false); 492193323Sed Value *Ops[3]; 493263509Sdim Ops[0] = Op0; 494193323Sed // Extend the amount to i32. 495212904Sdim Ops[1] = Builder.CreateIntCast(CI->getArgOperand(1), 496212904Sdim Type::getInt32Ty(Context), 497193323Sed /* isSigned */ false); 498193323Sed Ops[2] = Size; 499210299Sed ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 500193323Sed break; 501193323Sed } 502193323Sed case Intrinsic::sqrt: { 503195098Sed ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl"); 504193323Sed break; 505193323Sed } 506193323Sed case Intrinsic::log: { 507195098Sed ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl"); 508193323Sed break; 509193323Sed } 510193323Sed case Intrinsic::log2: { 511195098Sed ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l"); 512193323Sed break; 513193323Sed } 514193323Sed case Intrinsic::log10: { 515195098Sed ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l"); 516193323Sed break; 517193323Sed } 518193323Sed case Intrinsic::exp: { 519195098Sed ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl"); 520193323Sed break; 521193323Sed } 522193323Sed case Intrinsic::exp2: { 523195098Sed ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l"); 524193323Sed break; 525193323Sed } 526193323Sed case Intrinsic::pow: { 527195098Sed ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl"); 528193323Sed break; 529193323Sed } 530193323Sed case Intrinsic::flt_rounds: 531193323Sed // Lower to "round to the nearest" 532202375Srdivacky if (!CI->getType()->isVoidTy()) 533193323Sed CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 534193323Sed break; 535199481Srdivacky case Intrinsic::invariant_start: 536199481Srdivacky case Intrinsic::lifetime_start: 537199481Srdivacky // Discard region information. 538199481Srdivacky CI->replaceAllUsesWith(UndefValue::get(CI->getType())); 539199481Srdivacky break; 540199481Srdivacky case Intrinsic::invariant_end: 541199481Srdivacky case Intrinsic::lifetime_end: 542199481Srdivacky // Discard region information. 543199481Srdivacky break; 544193323Sed } 545193323Sed 546193323Sed assert(CI->use_empty() && 547193323Sed "Lowering should have eliminated any uses of the intrinsic call!"); 548193323Sed CI->eraseFromParent(); 549193323Sed} 550218893Sdim 551218893Sdimbool IntrinsicLowering::LowerToByteSwap(CallInst *CI) { 552218893Sdim // Verify this is a simple bswap. 553218893Sdim if (CI->getNumArgOperands() != 1 || 554218893Sdim CI->getType() != CI->getArgOperand(0)->getType() || 555218893Sdim !CI->getType()->isIntegerTy()) 556218893Sdim return false; 557218893Sdim 558224145Sdim IntegerType *Ty = dyn_cast<IntegerType>(CI->getType()); 559218893Sdim if (!Ty) 560218893Sdim return false; 561218893Sdim 562218893Sdim // Okay, we can do this xform, do so now. 563218893Sdim Module *M = CI->getParent()->getParent()->getParent(); 564224145Sdim Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Ty); 565218893Sdim 566218893Sdim Value *Op = CI->getArgOperand(0); 567218893Sdim Op = CallInst::Create(Int, Op, CI->getName(), CI); 568218893Sdim 569218893Sdim CI->replaceAllUsesWith(Op); 570218893Sdim CI->eraseFromParent(); 571218893Sdim return true; 572218893Sdim} 573