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.
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.
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.