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,
252 Value *RetDividend = Builder.CreateICmpEQ(SR, MSB);
255 Value *RetVal = Builder.CreateSelect(Ret0, Zero, Dividend);
258 Value *EarlyRet = Builder.CreateLogicalOr(Ret0, RetDividend);
266 Value *ConBrSpecialCases = Builder.CreateCondBr(EarlyRet, End, BB1);
269 LLVMContext::MD_prof,
278 Builder.SetInsertPoint(BB1);
279 Value *SR_1 = Builder.CreateAdd(SR, One);
280 Value *Tmp2 = Builder.CreateSub(MSB, SR);
281 Value *Q = Builder.CreateShl(Dividend, Tmp2);
286 Value *SkipLoop = Builder.CreateICmpEQ(SR_1, Zero);
287 Value *ConBrBB1 = Builder.CreateCondBr(SkipLoop, LoopExit, Preheader);
290 LLVMContext::MD_prof,
297 Builder.SetInsertPoint(Preheader);
298 Value *Tmp3 = Builder.CreateLShr(Dividend, SR_1);
299 Value *Tmp4 = Builder.CreateAdd(Divisor, NegOne);
300 Builder.CreateBr(DoWhile);
320 Builder.SetInsertPoint(DoWhile);
321 PHINode *Carry_1 = Builder.CreatePHI(DivTy, 2);
322 PHINode *SR_3 = Builder.CreatePHI(DivTy, 2);
323 PHINode *R_1 = Builder.CreatePHI(DivTy, 2);
324 PHINode *Q_2 = Builder.CreatePHI(DivTy, 2);
325 Value *Tmp5 = Builder.CreateShl(R_1, One);
326 Value *Tmp6 = Builder.CreateLShr(Q_2, MSB);
327 Value *Tmp7 = Builder.CreateOr(Tmp5, Tmp6);
328 Value *Tmp8 = Builder.CreateShl(Q_2, One);
329 Value *Q_1 = Builder.CreateOr(Carry_1, Tmp8);
330 Value *Tmp9 = Builder.CreateSub(Tmp4, Tmp7);
331 Value *Tmp10 = Builder.CreateAShr(Tmp9, MSB);
332 Value *Carry = Builder.CreateAnd(Tmp10, One);
333 Value *Tmp11 = Builder.CreateAnd(Tmp10, Divisor);
334 Value *R = Builder.CreateSub(Tmp7, Tmp11);
335 Value *SR_2 = Builder.CreateAdd(SR_3, NegOne);
336 Value *Tmp12 = Builder.CreateICmpEQ(SR_2, Zero);
340 Value *ConBrDoWhile = Builder.CreateCondBr(Tmp12, LoopExit, DoWhile);
343 LLVMContext::MD_prof,
352 Builder.SetInsertPoint(LoopExit);
353 PHINode *Carry_2 = Builder.CreatePHI(DivTy, 2);
354 PHINode *Q_3 = Builder.CreatePHI(DivTy, 2);
355 Value *Tmp13 = Builder.CreateShl(Q_3, One);
356 Value *Q_4 = Builder.CreateOr(Carry_2, Tmp13);
357 Builder.CreateBr(End);
362 Builder.SetInsertPoint(End, End->
begin());
363 PHINode *Q_5 = Builder.CreatePHI(DivTy, 2);
399 Rem->
getOpcode() == Instruction::URem) &&
400 "Trying to expand remainder from a non-remainder function");
407 if (Rem->
getOpcode() == Instruction::SRem) {
412 bool IsInsertPoint = Rem->
getIterator() == Builder.GetInsertPoint();
436 assert(UDiv->getOpcode() == Instruction::UDiv &&
"Non-udiv in expansion?");
451 Div->
getOpcode() == Instruction::UDiv) &&
452 "Trying to expand division from a non-division function");
459 if (Div->
getOpcode() == Instruction::SDiv) {
465 bool IsInsertPoint = Div->
getIterator() == Builder.GetInsertPoint();
500 Rem->
getOpcode() == Instruction::URem) &&
501 "Trying to expand remainder from a non-remainder function");
508 assert(RemTyBitWidth <= 32 &&
509 "Div of bitwidth greater than 32 not supported");
511 if (RemTyBitWidth == 32)
524 if (Rem->
getOpcode() == Instruction::SRem) {
525 ExtDividend = Builder.CreateSExt(Rem->
getOperand(0), Int32Ty);
526 ExtDivisor = Builder.CreateSExt(Rem->
getOperand(1), Int32Ty);
527 ExtRem = Builder.CreateSRem(ExtDividend, ExtDivisor);
529 ExtDividend = Builder.CreateZExt(Rem->
getOperand(0), Int32Ty);
530 ExtDivisor = Builder.CreateZExt(Rem->
getOperand(1), Int32Ty);
531 ExtRem = Builder.CreateURem(ExtDividend, ExtDivisor);
533 Trunc = Builder.CreateTrunc(ExtRem, RemTy);
549 Rem->
getOpcode() == Instruction::URem) &&
550 "Trying to expand remainder from a non-remainder function");
557 if (RemTyBitWidth >= 64)
570 if (Rem->
getOpcode() == Instruction::SRem) {
571 ExtDividend = Builder.CreateSExt(Rem->
getOperand(0), Int64Ty);
572 ExtDivisor = Builder.CreateSExt(Rem->
getOperand(1), Int64Ty);
573 ExtRem = Builder.CreateSRem(ExtDividend, ExtDivisor);
575 ExtDividend = Builder.CreateZExt(Rem->
getOperand(0), Int64Ty);
576 ExtDivisor = Builder.CreateZExt(Rem->
getOperand(1), Int64Ty);
577 ExtRem = Builder.CreateURem(ExtDividend, ExtDivisor);
579 Trunc = Builder.CreateTrunc(ExtRem, RemTy);
596 Div->
getOpcode() == Instruction::UDiv) &&
597 "Trying to expand division from a non-division function");
604 assert(DivTyBitWidth <= 32 &&
"Div of bitwidth greater than 32 not supported");
606 if (DivTyBitWidth == 32)
619 if (Div->
getOpcode() == Instruction::SDiv) {
620 ExtDividend = Builder.CreateSExt(Div->
getOperand(0), Int32Ty);
621 ExtDivisor = Builder.CreateSExt(Div->
getOperand(1), Int32Ty);
622 ExtDiv = Builder.CreateSDiv(ExtDividend, ExtDivisor);
624 ExtDividend = Builder.CreateZExt(Div->
getOperand(0), Int32Ty);
625 ExtDivisor = Builder.CreateZExt(Div->
getOperand(1), Int32Ty);
626 ExtDiv = Builder.CreateUDiv(ExtDividend, ExtDivisor);
628 Trunc = Builder.CreateTrunc(ExtDiv, DivTy);
644 Div->
getOpcode() == Instruction::UDiv) &&
645 "Trying to expand division from a non-division function");
652 if (DivTyBitWidth >= 64)
665 if (Div->
getOpcode() == Instruction::SDiv) {
666 ExtDividend = Builder.CreateSExt(Div->
getOperand(0), Int64Ty);
667 ExtDivisor = Builder.CreateSExt(Div->
getOperand(1), Int64Ty);
668 ExtDiv = Builder.CreateSDiv(ExtDividend, ExtDivisor);
670 ExtDividend = Builder.CreateZExt(Div->
getOperand(0), Int64Ty);
671 ExtDivisor = Builder.CreateZExt(Div->
getOperand(1), Int64Ty);
672 ExtDiv = Builder.CreateUDiv(ExtDividend, ExtDivisor);
674 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.
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
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.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
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.
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.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
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 setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
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.
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 * > OverloadTys={})
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.
LLVM_ABI bool expandRemainderUpTo64Bits(BinaryOperator *Rem)
Generate code to calculate the remainder of two integers, replacing Rem with the generated code.
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.