31 ArgIt ArgBegin, ArgIt ArgEnd,
37 std::vector<Type *> ParamTys;
38 for (ArgIt
I = ArgBegin;
I != ArgEnd; ++
I)
39 ParamTys.push_back((*I)->getType());
41 M->getOrInsertFunction(NewFn, FunctionType::get(
RetTy, ParamTys,
false));
54 assert(V->getType()->isIntOrIntVectorTy() &&
"Can't bswap a non-integer type!");
56 unsigned BitSize = V->getType()->getScalarSizeInBits();
63 Value *Tmp1 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 8),
67 V = Builder.
CreateOr(Tmp1, Tmp2,
"bswap.i16");
71 Value *Tmp4 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 24),
73 Value *Tmp3 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 8),
80 ConstantInt::get(V->getType(), 0xFF0000),
83 ConstantInt::get(V->getType(), 0xFF00),
85 Tmp4 = Builder.
CreateOr(Tmp4, Tmp3,
"bswap.or1");
86 Tmp2 = Builder.
CreateOr(Tmp2, Tmp1,
"bswap.or2");
87 V = Builder.
CreateOr(Tmp4, Tmp2,
"bswap.i32");
91 Value *Tmp8 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 56),
93 Value *Tmp7 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 40),
95 Value *Tmp6 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 24),
97 Value *Tmp5 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 8),
102 ConstantInt::get(V->getType(), 24),
105 ConstantInt::get(V->getType(), 40),
108 ConstantInt::get(V->getType(), 56),
111 ConstantInt::get(V->getType(),
112 0xFF000000000000ULL),
115 ConstantInt::get(V->getType(),
119 ConstantInt::get(V->getType(),
123 ConstantInt::get(V->getType(),
127 ConstantInt::get(V->getType(),
131 ConstantInt::get(V->getType(),
134 Tmp8 = Builder.
CreateOr(Tmp8, Tmp7,
"bswap.or1");
135 Tmp6 = Builder.
CreateOr(Tmp6, Tmp5,
"bswap.or2");
136 Tmp4 = Builder.
CreateOr(Tmp4, Tmp3,
"bswap.or3");
137 Tmp2 = Builder.
CreateOr(Tmp2, Tmp1,
"bswap.or4");
138 Tmp8 = Builder.
CreateOr(Tmp8, Tmp6,
"bswap.or5");
139 Tmp4 = Builder.
CreateOr(Tmp4, Tmp2,
"bswap.or6");
140 V = Builder.
CreateOr(Tmp8, Tmp4,
"bswap.i64");
149 assert(V->getType()->isIntegerTy() &&
"Can't ctpop a non-integer type!");
151 static const uint64_t MaskValues[6] = {
152 0x5555555555555555ULL, 0x3333333333333333ULL,
153 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL,
154 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL
159 unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
160 unsigned WordSize = (BitSize + 63) / 64;
161 Value *Count = ConstantInt::get(V->getType(), 0);
163 for (
unsigned n = 0; n < WordSize; ++n) {
164 Value *PartValue = V;
165 for (
unsigned i = 1, ct = 0; i < (BitSize>64 ? 64 : BitSize);
167 Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]);
170 ConstantInt::get(V->getType(), i),
175 Count = Builder.
CreateAdd(PartValue, Count,
"ctpop.part");
177 V = Builder.
CreateLShr(V, ConstantInt::get(V->getType(), 64),
191 unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
192 for (
unsigned i = 1; i < BitSize; i <<= 1) {
193 Value *ShVal = ConstantInt::get(V->getType(), i);
194 ShVal = Builder.
CreateLShr(V, ShVal,
"ctlz.sh");
195 V = Builder.
CreateOr(V, ShVal,
"ctlz.step");
204 const char *LDname) {
229 assert(Callee &&
"Cannot lower an indirect call!");
231 switch (Callee->getIntrinsicID()) {
234 Callee->getName() +
"'!");
237 Callee->getName()+
"'!");
239 case Intrinsic::expect:
240 case Intrinsic::expect_with_probability: {
248 case Intrinsic::allow_runtime_check:
249 case Intrinsic::allow_ubsan_check:
253 case Intrinsic::ctpop:
257 case Intrinsic::bswap:
261 case Intrinsic::ctlz:
265 case Intrinsic::cttz: {
269 NotSrc->
setName(Src->getName() +
".not");
270 Value *SrcM1 = ConstantInt::get(Src->getType(), 1);
277 case Intrinsic::stacksave:
278 case Intrinsic::stackrestore: {
280 errs() <<
"WARNING: this target does not support the llvm.stack"
281 << (Callee->getIntrinsicID() == Intrinsic::stacksave ?
282 "save" :
"restore") <<
" intrinsic.\n";
284 if (Callee->getIntrinsicID() == Intrinsic::stacksave)
289 case Intrinsic::get_dynamic_area_offset:
290 errs() <<
"WARNING: this target does not support the custom llvm.get."
291 "dynamic.area.offset. It is being lowered to a constant 0\n";
296 case Intrinsic::returnaddress:
297 case Intrinsic::frameaddress:
298 errs() <<
"WARNING: this target does not support the llvm."
299 << (Callee->getIntrinsicID() == Intrinsic::returnaddress ?
300 "return" :
"frame") <<
"address intrinsic.\n";
304 case Intrinsic::addressofreturnaddress:
305 errs() <<
"WARNING: this target does not support the "
306 "llvm.addressofreturnaddress intrinsic.\n";
311 case Intrinsic::prefetch:
314 case Intrinsic::pcmarker:
316 case Intrinsic::readcyclecounter: {
317 errs() <<
"WARNING: this target does not support the llvm.readcyclecoun"
318 <<
"ter intrinsic. It is being lowered to a constant 0\n";
322 case Intrinsic::readsteadycounter: {
323 errs() <<
"WARNING: this target does not support the llvm.readsteadycounter"
324 <<
" intrinsic. It is being lowered to a constant 0\n";
329 case Intrinsic::dbg_declare:
330 case Intrinsic::dbg_label:
333 case Intrinsic::eh_typeid_for:
338 case Intrinsic::annotation:
339 case Intrinsic::ptr_annotation:
344 case Intrinsic::assume:
345 case Intrinsic::experimental_noalias_scope_decl:
346 case Intrinsic::var_annotation:
349 case Intrinsic::memcpy: {
360 case Intrinsic::memmove: {
371 case Intrinsic::memset: {
386 case Intrinsic::sqrt: {
390 case Intrinsic::log: {
394 case Intrinsic::log2: {
398 case Intrinsic::log10: {
402 case Intrinsic::exp: {
406 case Intrinsic::exp2: {
410 case Intrinsic::pow: {
414 case Intrinsic::sin: {
418 case Intrinsic::cos: {
422 case Intrinsic::floor: {
426 case Intrinsic::ceil: {
430 case Intrinsic::trunc: {
434 case Intrinsic::round: {
438 case Intrinsic::roundeven: {
442 case Intrinsic::copysign: {
446 case Intrinsic::get_rounding:
451 case Intrinsic::invariant_start:
452 case Intrinsic::lifetime_start:
456 case Intrinsic::invariant_end:
457 case Intrinsic::lifetime_end:
463 "Lowering should have eliminated any uses of the intrinsic call!");
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
static Value * LowerCTLZ(LLVMContext &Context, Value *V, Instruction *IP)
Emit the code to lower ctlz of V before the specified instruction IP.
static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, const char *Dname, const char *LDname)
static CallInst * ReplaceCallWith(const char *NewFn, CallInst *CI, ArgIt ArgBegin, ArgIt ArgEnd, Type *RetTy)
This function is used when we want to lower an intrinsic call to a call of an external function.
static Value * LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP)
Emit the code to lower ctpop of V before the specified instruction IP.
static Value * LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP)
Emit the code to lower bswap of V before the specified instruction IP.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Value * getArgOperand(unsigned i) const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static ConstantInt * getTrue(LLVMContext &Context)
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Class to represent integer types.
void LowerIntrinsicCall(CallInst *CI)
Replace a call to the specified intrinsic function.
static bool LowerToByteSwap(CallInst *CI)
Try to replace a call instruction with a call to a bswap intrinsic.
This is an important class for using LLVM in a threaded context.
A Module instance is used to store all the information related to an LLVM module.
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
static Type * getDoubleTy(LLVMContext &C)
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ X86_FP80TyID
80-bit floating point type (X87)
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
@ FP128TyID
128-bit floating point type (112-bit significand)
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
static Type * getFloatTy(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
bool isVoidTy() const
Return true if this is 'void'.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void setName(const Twine &Name)
Change the name of the value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
This is an optimization pass for GlobalISel generic memory operations.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.