summaryrefslogtreecommitdiff
path: root/lib/Analysis
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-05-16 17:14:03 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-05-16 17:14:03 +0000
commit3258443195f7574206dd90f7a67959a252737c51 (patch)
tree46d2a9338d1adb9c74caa9b7523f1ee1d5800d25 /lib/Analysis
parent7a2ed26563512149ea03e56d8ecd92c884c32f8f (diff)
downloadllvm-3258443195f7574206dd90f7a67959a252737c51.tar.gz
llvm-3258443195f7574206dd90f7a67959a252737c51.tar.bz2
llvm-3258443195f7574206dd90f7a67959a252737c51.tar.xz
InstSimplify: Improve handling of ashr/lshr
Summary: Analyze the range of values produced by ashr/lshr cst, %V when it is being used in an icmp. Reviewers: nicholas Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D3774 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209000 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/InstructionSimplify.cpp22
1 files changed, 21 insertions, 1 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 4cad81b139..3684fda854 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -2001,7 +2001,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
// Many binary operators with constant RHS have easy to compute constant
// range. Use them to check whether the comparison is a tautology.
- uint32_t Width = CI->getBitWidth();
+ unsigned Width = CI->getBitWidth();
APInt Lower = APInt(Width, 0);
APInt Upper = APInt(Width, 0);
ConstantInt *CI2;
@@ -2038,6 +2038,13 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
APInt NegOne = APInt::getAllOnesValue(Width);
if (CI2->getValue().ult(Width))
Upper = NegOne.lshr(CI2->getValue()) + 1;
+ } else if (match(LHS, m_LShr(m_ConstantInt(CI2), m_Value()))) {
+ // 'lshr CI2, x' produces [CI2 >> (Width-1), CI2].
+ unsigned ShiftAmount = Width - 1;
+ if (!CI2->isZero() && cast<BinaryOperator>(LHS)->isExact())
+ ShiftAmount = CI2->getValue().countTrailingZeros();
+ Lower = CI2->getValue().lshr(ShiftAmount);
+ Upper = CI2->getValue() + 1;
} else if (match(LHS, m_AShr(m_Value(), m_ConstantInt(CI2)))) {
// 'ashr x, CI2' produces [INT_MIN >> CI2, INT_MAX >> CI2].
APInt IntMin = APInt::getSignedMinValue(Width);
@@ -2046,6 +2053,19 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
Lower = IntMin.ashr(CI2->getValue());
Upper = IntMax.ashr(CI2->getValue()) + 1;
}
+ } else if (match(LHS, m_AShr(m_ConstantInt(CI2), m_Value()))) {
+ unsigned ShiftAmount = Width - 1;
+ if (!CI2->isZero() && cast<BinaryOperator>(LHS)->isExact())
+ ShiftAmount = CI2->getValue().countTrailingZeros();
+ if (CI2->isNegative()) {
+ // 'ashr CI2, x' produces [CI2, CI2 >> (Width-1)]
+ Lower = CI2->getValue();
+ Upper = CI2->getValue().ashr(ShiftAmount) + 1;
+ } else {
+ // 'ashr CI2, x' produces [CI2 >> (Width-1), CI2]
+ Lower = CI2->getValue().ashr(ShiftAmount);
+ Upper = CI2->getValue() + 1;
+ }
} else if (match(LHS, m_Or(m_Value(), m_ConstantInt(CI2)))) {
// 'or x, CI2' produces [CI2, UINT_MAX].
Lower = CI2->getValue();