diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-06-25 22:50:26 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-06-25 22:50:26 +0000 |
commit | 38a86d3136f61eb1884ce6e5fa5681508347348f (patch) | |
tree | b8e9cc51825257bfe10ddbfbbc547376835a2437 /llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | |
parent | 0c90400bf24a7b14bb087558c8f0dc79c34e0ecc (diff) | |
download | bcm5719-llvm-38a86d3136f61eb1884ce6e5fa5681508347348f.tar.gz bcm5719-llvm-38a86d3136f61eb1884ce6e5fa5681508347348f.zip |
[InstCombine] cleanup udiv folds; NFCI
This removes a "UDivFoldAction" in favor of a simple constant
matcher. In theory, the existing code could do more matching,
but I don't see any evidence or need for it. I've left a TODO
about using ValueTracking in case we see any regressions.
llvm-svn: 335545
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 50 |
1 files changed, 20 insertions, 30 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 326f499ed9f..bb714d00d69 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -826,14 +826,6 @@ static Instruction *foldUDivPow2Cst(Value *Op0, Value *Op1, return LShr; } -// X udiv C, where C >= signbit -static Instruction *foldUDivNegCst(Value *Op0, Value *Op1, - const BinaryOperator &I, InstCombiner &IC) { - Value *ICI = IC.Builder.CreateICmpULT(Op0, cast<Constant>(Op1)); - return SelectInst::Create(ICI, Constant::getNullValue(I.getType()), - ConstantInt::get(I.getType(), 1)); -} - // X udiv (C1 << N), where C1 is "1<<C2" --> X >> (N+C2) // X udiv (zext (C1 << N)), where C1 is "1<<C2" --> X >> (N+C2) static Instruction *foldUDivShl(Value *Op0, Value *Op1, const BinaryOperator &I, @@ -872,12 +864,6 @@ static size_t visitUDivOperand(Value *Op0, Value *Op1, const BinaryOperator &I, return Actions.size(); } - // X udiv C, where C >= signbit - if (match(Op1, m_Negative())) { - Actions.push_back(UDivFoldAction(foldUDivNegCst, Op1)); - return Actions.size(); - } - // X udiv (C1 << N), where C1 is "1<<C2" --> X >> (N+C2) if (match(Op1, m_Shl(m_Power2(), m_Value())) || match(Op1, m_ZExt(m_Shl(m_Power2(), m_Value())))) { @@ -949,26 +935,30 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) { if (Instruction *Common = commonIDivTransforms(I)) return Common; - // (x lshr C1) udiv C2 --> x udiv (C2 << C1) Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - { - Value *X; - const APInt *C1, *C2; - if (match(Op0, m_LShr(m_Value(X), m_APInt(C1))) && - match(Op1, m_APInt(C2))) { - bool Overflow; - APInt C2ShlC1 = C2->ushl_ov(*C1, Overflow); - if (!Overflow) { - bool IsExact = I.isExact() && match(Op0, m_Exact(m_Value())); - BinaryOperator *BO = BinaryOperator::CreateUDiv( - X, ConstantInt::get(X->getType(), C2ShlC1)); - if (IsExact) - BO->setIsExact(); - return BO; - } + Value *X; + const APInt *C1, *C2; + if (match(Op0, m_LShr(m_Value(X), m_APInt(C1))) && match(Op1, m_APInt(C2))) { + // (X lshr C1) udiv C2 --> X udiv (C2 << C1) + bool Overflow; + APInt C2ShlC1 = C2->ushl_ov(*C1, Overflow); + if (!Overflow) { + bool IsExact = I.isExact() && match(Op0, m_Exact(m_Value())); + BinaryOperator *BO = BinaryOperator::CreateUDiv( + X, ConstantInt::get(X->getType(), C2ShlC1)); + if (IsExact) + BO->setIsExact(); + return BO; } } + // Op0 / C where C is large (negative) --> zext (Op0 >= C) + // TODO: Could use isKnownNegative() to handle non-constant values. + if (match(Op1, m_Negative())) { + Value *Cmp = Builder.CreateICmpUGE(Op0, Op1); + return CastInst::CreateZExtOrBitCast(Cmp, I.getType()); + } + if (Instruction *NarrowDiv = narrowUDivURem(I, Builder)) return NarrowDiv; |