summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-07-04 00:23:39 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-07-04 00:23:39 +0000
commit651ed5e8fdf05878088b2f7579735083775e43e3 (patch)
tree4ab80da3276fdc4b4abc5d3c51767869d97b625a /llvm/lib/Analysis/InstructionSimplify.cpp
parent4576c115ac8bdca6122ba6b35b5c9dff624973f3 (diff)
downloadbcm5719-llvm-651ed5e8fdf05878088b2f7579735083775e43e3.tar.gz
bcm5719-llvm-651ed5e8fdf05878088b2f7579735083775e43e3.zip
InstSimplify: Fix a bug when INT_MIN is in a sdiv
When INT_MIN is the numerator in a sdiv, we would not properly handle overflow when calculating the bounds of possible values; abs(INT_MIN) is not a meaningful number. Instead, check and handle INT_MIN by reasoning that the largest value is INT_MIN/-2 and the smallest value is INT_MIN. This fixes PR20199. llvm-svn: 212307
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 31263bb7de8..bd42af15da3 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1948,9 +1948,15 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
if (!CI2->isZero())
Upper = NegOne.udiv(CI2->getValue()) + 1;
} else if (match(LHS, m_SDiv(m_ConstantInt(CI2), m_Value()))) {
- // 'sdiv CI2, x' produces [-|CI2|, |CI2|].
- Upper = CI2->getValue().abs() + 1;
- Lower = (-Upper) + 1;
+ if (CI2->isMinSignedValue()) {
+ // 'sdiv INT_MIN, x' produces [INT_MIN, INT_MIN / -2].
+ Lower = CI2->getValue();
+ Upper = Lower.lshr(1) + 1;
+ } else {
+ // 'sdiv CI2, x' produces [-|CI2|, |CI2|].
+ Upper = CI2->getValue().abs() + 1;
+ Lower = (-Upper) + 1;
+ }
} else if (match(LHS, m_SDiv(m_Value(), m_ConstantInt(CI2)))) {
// 'sdiv x, CI2' produces [INT_MIN / CI2, INT_MAX / CI2].
APInt IntMin = APInt::getSignedMinValue(Width);
OpenPOWER on IntegriCloud