30#define DEBUG_TYPE "integer-division"
55 Dividend = Builder.CreateFreeze(Dividend);
56 Divisor = Builder.CreateFreeze(Divisor);
57 Value *DividendSign = Builder.CreateAShr(Dividend, Shift);
58 Value *DivisorSign = Builder.CreateAShr(Divisor, Shift);
59 Value *DvdXor = Builder.CreateXor(Dividend, DividendSign);
60 Value *DvsXor = Builder.CreateXor(Divisor, DivisorSign);
61 Value *UDividend = Builder.CreateSub(DvdXor, DividendSign);
62 Value *UDivisor = Builder.CreateSub(DvsXor, DivisorSign);
63 Value *URem = Builder.CreateURem(UDividend, UDivisor);
64 Value *Xored = Builder.CreateXor(URem, DividendSign);
65 Value *SRem = Builder.CreateSub(Xored, DividendSign);
68 Builder.SetInsertPoint(URemInst);
88 Dividend = Builder.CreateFreeze(Dividend);
89 Divisor = Builder.CreateFreeze(Divisor);
90 Value *Quotient = Builder.CreateUDiv(Dividend, Divisor);
91 Value *Product = Builder.CreateMul(Divisor, Quotient);
92 Value *Remainder = Builder.CreateSub(Dividend, Product);
95 Builder.SetInsertPoint(UDiv);
125 Dividend = Builder.CreateFreeze(Dividend);
126 Divisor = Builder.CreateFreeze(Divisor);
127 Value *Tmp = Builder.CreateAShr(Dividend, Shift);
128 Value *Tmp1 = Builder.CreateAShr(Divisor, Shift);
129 Value *Tmp2 = Builder.CreateXor(Tmp, Dividend);
130 Value *U_Dvnd = Builder.CreateSub(Tmp2, Tmp);
131 Value *Tmp3 = Builder.CreateXor(Tmp1, Divisor);
132 Value *U_Dvsr = Builder.CreateSub(Tmp3, Tmp1);
133 Value *Q_Sgn = Builder.CreateXor(Tmp1, Tmp);
134 Value *Q_Mag = Builder.CreateUDiv(U_Dvnd, U_Dvsr);
135 Value *Tmp4 = Builder.CreateXor(Q_Mag, Q_Sgn);
136 Value *Q = Builder.CreateSub(Tmp4, Q_Sgn);
139 Builder.SetInsertPoint(UDiv);
201 BasicBlock *SpecialCases = Builder.GetInsertBlock();
206 "udiv-loop-exit",
F, End);
208 "udiv-do-while",
F, End);
210 "udiv-preheader",
F, End);
234 Builder.SetInsertPoint(SpecialCases);
235 Divisor = Builder.CreateFreeze(Divisor);
236 Dividend = Builder.CreateFreeze(Dividend);
237 Value *Ret0_1 = Builder.CreateICmpEQ(Divisor, Zero);
238 Value *Ret0_2 = Builder.CreateICmpEQ(Dividend, Zero);
239 Value *Ret0_3 = Builder.CreateOr(Ret0_1, Ret0_2);
240 Value *Tmp0 = Builder.CreateCall(CTLZ, {Divisor, True});
241 Value *Tmp1 = Builder.CreateCall(CTLZ, {Dividend, True});
242 Value *SR = Builder.CreateSub(Tmp0, Tmp1);
243 Value *Ret0_4 = Builder.CreateICmpUGT(SR, MSB);
247 Value *Ret0 = Builder.CreateLogicalOr(Ret0_3, Ret0_4);
250 LLVMContext::MD_prof,
253 Value *RetDividend = Builder.CreateICmpEQ(SR, MSB);
256 Value *RetVal = Builder.CreateSelect(Ret0, Zero, Dividend);
260 Value *EarlyRet = Builder.CreateLogicalOr(Ret0, RetDividend);
269 Value *ConBrSpecialCases = Builder.CreateCondBr(EarlyRet, End, BB1);
272 LLVMContext::MD_prof,
282 Builder.SetInsertPoint(BB1);
283 Value *SR_1 = Builder.CreateAdd(SR, One);
284 Value *Tmp2 = Builder.CreateSub(MSB, SR);
285 Value *Q = Builder.CreateShl(Dividend, Tmp2);
290 Value *SkipLoop = Builder.CreateICmpEQ(SR_1, Zero);
291 Value *ConBrBB1 = Builder.CreateCondBr(SkipLoop, LoopExit, Preheader);
294 LLVMContext::MD_prof,
302 Builder.SetInsertPoint(Preheader);
303 Value *Tmp3 = Builder.CreateLShr(Dividend, SR_1);
304 Value *Tmp4 = Builder.CreateAdd(Divisor, NegOne);
305 Builder.CreateBr(DoWhile);
325 Builder.SetInsertPoint(DoWhile);
326 PHINode *Carry_1 = Builder.CreatePHI(DivTy, 2);
327 PHINode *SR_3 = Builder.CreatePHI(DivTy, 2);
328 PHINode *R_1 = Builder.CreatePHI(DivTy, 2);
329 PHINode *Q_2 = Builder.CreatePHI(DivTy, 2);
330 Value *Tmp5 = Builder.CreateShl(R_1, One);
331 Value *Tmp6 = Builder.CreateLShr(Q_2, MSB);
332 Value *Tmp7 = Builder.CreateOr(Tmp5, Tmp6);
333 Value *Tmp8 = Builder.CreateShl(Q_2, One);
334 Value *Q_1 = Builder.CreateOr(Carry_1, Tmp8);
335 Value *Tmp9 = Builder.CreateSub(Tmp4, Tmp7);
336 Value *Tmp10 = Builder.CreateAShr(Tmp9, MSB);
337 Value *Carry = Builder.CreateAnd(Tmp10, One);
338 Value *Tmp11 = Builder.CreateAnd(Tmp10, Divisor);
339 Value *R = Builder.CreateSub(Tmp7, Tmp11);
340 Value *SR_2 = Builder.CreateAdd(SR_3, NegOne);
341 Value *Tmp12 = Builder.CreateICmpEQ(SR_2, Zero);
345 Value *ConBrDoWhile = Builder.CreateCondBr(Tmp12, LoopExit, DoWhile);
348 LLVMContext::MD_prof,
358 Builder.SetInsertPoint(LoopExit);
359 PHINode *Carry_2 = Builder.CreatePHI(DivTy, 2);
360 PHINode *Q_3 = Builder.CreatePHI(DivTy, 2);
361 Value *Tmp13 = Builder.CreateShl(Q_3, One);
362 Value *Q_4 = Builder.CreateOr(Carry_2, Tmp13);
363 Builder.CreateBr(End);
368 Builder.SetInsertPoint(End, End->
begin());
369 PHINode *Q_5 = Builder.CreatePHI(DivTy, 2);
405 Rem->
getOpcode() == Instruction::URem) &&
406 "Trying to expand remainder from a non-remainder function");
413 if (Rem->
getOpcode() == Instruction::SRem) {
418 bool IsInsertPoint = Rem->
getIterator() == Builder.GetInsertPoint();
442 assert(UDiv->getOpcode() == Instruction::UDiv &&
"Non-udiv in expansion?");
457 Div->
getOpcode() == Instruction::UDiv) &&
458 "Trying to expand division from a non-division function");
465 if (Div->
getOpcode() == Instruction::SDiv) {
471 bool IsInsertPoint = Div->
getIterator() == Builder.GetInsertPoint();
506 Rem->
getOpcode() == Instruction::URem) &&
507 "Trying to expand remainder from a non-remainder function");
514 assert(RemTyBitWidth <= 32 &&
515 "Div of bitwidth greater than 32 not supported");
517 if (RemTyBitWidth == 32)
530 if (Rem->
getOpcode() == Instruction::SRem) {
533 ExtRem = Builder.CreateSRem(ExtDividend, ExtDivisor);
537 ExtRem = Builder.CreateURem(ExtDividend, ExtDivisor);
539 Trunc = Builder.CreateTrunc(ExtRem, RemTy);
555 Rem->
getOpcode() == Instruction::URem) &&
556 "Trying to expand remainder from a non-remainder function");
563 if (RemTyBitWidth >= 64)
576 if (Rem->
getOpcode() == Instruction::SRem) {
577 ExtDividend = Builder.CreateSExt(Rem->
getOperand(0), Int64Ty);
578 ExtDivisor = Builder.CreateSExt(Rem->
getOperand(1), Int64Ty);
579 ExtRem = Builder.CreateSRem(ExtDividend, ExtDivisor);
581 ExtDividend = Builder.CreateZExt(Rem->
getOperand(0), Int64Ty);
582 ExtDivisor = Builder.CreateZExt(Rem->
getOperand(1), Int64Ty);
583 ExtRem = Builder.CreateURem(ExtDividend, ExtDivisor);
585 Trunc = Builder.CreateTrunc(ExtRem, RemTy);
602 Div->
getOpcode() == Instruction::UDiv) &&
603 "Trying to expand division from a non-division function");
610 assert(DivTyBitWidth <= 32 &&
"Div of bitwidth greater than 32 not supported");
612 if (DivTyBitWidth == 32)
625 if (Div->
getOpcode() == Instruction::SDiv) {
628 ExtDiv = Builder.CreateSDiv(ExtDividend, ExtDivisor);
632 ExtDiv = Builder.CreateUDiv(ExtDividend, ExtDivisor);
634 Trunc = Builder.CreateTrunc(ExtDiv, DivTy);
650 Div->
getOpcode() == Instruction::UDiv) &&
651 "Trying to expand division from a non-division function");
658 if (DivTyBitWidth >= 64)
671 if (Div->
getOpcode() == Instruction::SDiv) {
672 ExtDividend = Builder.CreateSExt(Div->
getOperand(0), Int64Ty);
673 ExtDivisor = Builder.CreateSExt(Div->
getOperand(1), Int64Ty);
674 ExtDiv = Builder.CreateSDiv(ExtDividend, ExtDivisor);
676 ExtDividend = Builder.CreateZExt(Div->
getOperand(0), Int64Ty);
677 ExtDivisor = Builder.CreateZExt(Div->
getOperand(1), Int64Ty);
678 ExtDiv = Builder.CreateUDiv(ExtDividend, ExtDivisor);
680 Trunc = Builder.CreateTrunc(ExtDiv, DivTy);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Value * generateSignedDivisionCode(Value *Dividend, Value *Divisor, IRBuilder<> &Builder)
Generate code to divide two signed integers.
static Value * generateUnsignedRemainderCode(Value *Dividend, Value *Divisor, IRBuilder<> &Builder)
Generate code to compute the remainder of two unsigned integers.
static Value * generateSignedRemainderCode(Value *Dividend, Value *Divisor, IRBuilder<> &Builder)
Generate code to compute the remainder of two signed integers.
static Value * generateUnsignedDivisionCode(Value *Dividend, Value *Divisor, IRBuilder<> &Builder)
Generates code to divide two unsigned scalar 32-bit or 64-bit integers.
This file contains the declarations for profiling metadata utility functions.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Function * getParent() const
Return the enclosing method, or null if none.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
BinaryOps getOpcode() const
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
Class to represent integer types.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
void dropAllReferences()
Drop all references to operands.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI 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.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
self_iterator getIterator()
LLVM_ABI 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.
LLVM_ABI bool expandDivision(BinaryOperator *Div)
Generate code to divide two integers, replacing Div with the generated code.
LLVM_ABI bool expandRemainderUpTo32Bits(BinaryOperator *Rem)
Generate code to calculate the remainder of two integers, replacing Rem with the generated code.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
LLVM_ABI bool expandRemainderUpTo64Bits(BinaryOperator *Rem)
Generate code to calculate the remainder of two integers, replacing Rem with the generated code.
LLVM_ABI void applyProfMetadataIfEnabled(Value *V, llvm::function_ref< void(Instruction *)> setMetadataCallback)
LLVM_ABI bool expandDivisionUpTo64Bits(BinaryOperator *Div)
Generate code to divide two integers, replacing Div with the generated code.
LLVM_ABI bool expandDivisionUpTo32Bits(BinaryOperator *Div)
Generate code to divide two integers, replacing Div with the generated code.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool expandRemainder(BinaryOperator *Rem)
Generate code to calculate the remainder of two integers, replacing Rem with the generated code.