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: {
246 case Intrinsic::allow_runtime_check:
247 case Intrinsic::allow_ubsan_check:
251 case Intrinsic::ctpop:
255 case Intrinsic::bswap:
259 case Intrinsic::ctlz:
263 case Intrinsic::cttz: {
267 NotSrc->
setName(Src->getName() +
".not");
268 Value *SrcM1 = ConstantInt::get(Src->getType(), 1);
275 case Intrinsic::stacksave:
276 case Intrinsic::stackrestore: {
278 errs() <<
"WARNING: this target does not support the llvm.stack"
279 << (Callee->getIntrinsicID() == Intrinsic::stacksave ?
280 "save" :
"restore") <<
" intrinsic.\n";
282 if (Callee->getIntrinsicID() == Intrinsic::stacksave)
287 case Intrinsic::get_dynamic_area_offset:
288 errs() <<
"WARNING: this target does not support the custom llvm.get."
289 "dynamic.area.offset. It is being lowered to a constant 0\n";
294 case Intrinsic::returnaddress:
295 case Intrinsic::frameaddress:
296 errs() <<
"WARNING: this target does not support the llvm."
297 << (Callee->getIntrinsicID() == Intrinsic::returnaddress ?
298 "return" :
"frame") <<
"address intrinsic.\n";
302 case Intrinsic::addressofreturnaddress:
303 errs() <<
"WARNING: this target does not support the "
304 "llvm.addressofreturnaddress intrinsic.\n";
309 case Intrinsic::prefetch:
312 case Intrinsic::pcmarker:
314 case Intrinsic::readcyclecounter: {
315 errs() <<
"WARNING: this target does not support the llvm.readcyclecoun"
316 <<
"ter intrinsic. It is being lowered to a constant 0\n";
320 case Intrinsic::readsteadycounter: {
321 errs() <<
"WARNING: this target does not support the llvm.readsteadycounter"
322 <<
" intrinsic. It is being lowered to a constant 0\n";
327 case Intrinsic::dbg_declare:
328 case Intrinsic::dbg_label:
331 case Intrinsic::eh_typeid_for:
336 case Intrinsic::annotation:
337 case Intrinsic::ptr_annotation:
342 case Intrinsic::assume:
343 case Intrinsic::experimental_noalias_scope_decl:
344 case Intrinsic::var_annotation:
347 case Intrinsic::memcpy: {
358 case Intrinsic::memmove: {
369 case Intrinsic::memset: {
384 case Intrinsic::sqrt: {
388 case Intrinsic::log: {
392 case Intrinsic::log2: {
396 case Intrinsic::log10: {
400 case Intrinsic::exp: {
404 case Intrinsic::exp2: {
408 case Intrinsic::pow: {
412 case Intrinsic::sin: {
416 case Intrinsic::cos: {
420 case Intrinsic::floor: {
424 case Intrinsic::ceil: {
428 case Intrinsic::trunc: {
432 case Intrinsic::round: {
436 case Intrinsic::roundeven: {
440 case Intrinsic::copysign: {
444 case Intrinsic::get_rounding:
449 case Intrinsic::invariant_start:
450 case Intrinsic::lifetime_start:
454 case Intrinsic::invariant_end:
455 case Intrinsic::lifetime_end:
461 "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...
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.
Module.h This file contains the declarations for the Module class.
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)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
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 * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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.