2
0

IntrinsicLowering.cpp 22 KB

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