summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-06-25 22:50:26 +0000
committerSanjay Patel <spatel@rotateright.com>2018-06-25 22:50:26 +0000
commit38a86d3136f61eb1884ce6e5fa5681508347348f (patch)
treeb8e9cc51825257bfe10ddbfbbc547376835a2437 /llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
parent0c90400bf24a7b14bb087558c8f0dc79c34e0ecc (diff)
downloadbcm5719-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.cpp50
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;
OpenPOWER on IntegriCloud