summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/LazyValueInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp52
1 files changed, 33 insertions, 19 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 2728687a31c..e6c375a8d8c 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1197,30 +1197,44 @@ bool getValueFromCondition(Value *Val, Value *Cond, LVILatticeVal &Result,
Result = LVILatticeVal::getNot(cast<Constant>(RHS));
return true;
}
+ }
- // Recognize the range checking idiom that InstCombine produces.
- // (X+C1) u< C2 --> [-C1, C2-C1)
- ConstantInt *Offset = nullptr;
- if (Predicate == ICmpInst::ICMP_ULT)
- match(LHS, m_Add(m_Specific(Val), m_ConstantInt(Offset)));
+ // Use ConstantRange::makeAllowedICmpRegion in order to determine the possible
+ // range of Val guaranteed by the condition. Recognize comparisons in the from
+ // of:
+ // icmp <pred> Val, ...
+ // icmp ult (add Val, Offset), ...
+ // The latter is the range checking idiom that InstCombine produces. Subtract
+ // the offset from the allowed range for RHS in this case.
+
+ // Val or (add Val, Offset) can be on either hand of the comparison
+ if (LHS != Val && !match(LHS, m_Add(m_Specific(Val), m_ConstantInt()))) {
+ std::swap(LHS, RHS);
+ Predicate = CmpInst::getSwappedPredicate(Predicate);
+ }
- ConstantInt *CI = dyn_cast<ConstantInt>(RHS);
- if (CI && (LHS == Val || Offset)) {
- // Calculate the range of values that are allowed by the comparison
- ConstantRange CmpRange(CI->getValue());
+ ConstantInt *Offset = nullptr;
+ if (Predicate == ICmpInst::ICMP_ULT)
+ match(LHS, m_Add(m_Specific(Val), m_ConstantInt(Offset)));
- // If we're interested in the false dest, invert the condition
- CmpInst::Predicate Pred =
- isTrueDest ? Predicate : CmpInst::getInversePredicate(Predicate);
- ConstantRange TrueValues =
- ConstantRange::makeAllowedICmpRegion(Pred, CmpRange);
+ if (LHS == Val || Offset) {
+ // Calculate the range of values that are allowed by the comparison
+ ConstantRange RHSRange(RHS->getType()->getIntegerBitWidth(),
+ /*isFullSet=*/true);
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
+ RHSRange = ConstantRange(CI->getValue());
- if (Offset) // Apply the offset from above.
- TrueValues = TrueValues.subtract(Offset->getValue());
+ // If we're interested in the false dest, invert the condition
+ CmpInst::Predicate Pred =
+ isTrueDest ? Predicate : CmpInst::getInversePredicate(Predicate);
+ ConstantRange TrueValues =
+ ConstantRange::makeAllowedICmpRegion(Pred, RHSRange);
- Result = LVILatticeVal::getRange(std::move(TrueValues));
- return true;
- }
+ if (Offset) // Apply the offset from above.
+ TrueValues = TrueValues.subtract(Offset->getValue());
+
+ Result = LVILatticeVal::getRange(std::move(TrueValues));
+ return true;
}
return false;
OpenPOWER on IntegriCloud