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