summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2014-10-15 19:25:28 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2014-10-15 19:25:28 +0000
commit90c2f1455ae1e88aa31e68f4e7cdcdf955c945ed (patch)
treeadd8f3ca67de38efd5a3ee5741212f281e41f196 /llvm/lib/Analysis/ScalarEvolution.cpp
parent74cd020fcaa1e5abd31fcbad1c0be0319a3bf790 (diff)
downloadbcm5719-llvm-90c2f1455ae1e88aa31e68f4e7cdcdf955c945ed.tar.gz
bcm5719-llvm-90c2f1455ae1e88aa31e68f4e7cdcdf955c945ed.zip
Teach ScalarEvolution to sharpen range information.
If x is known to have the range [a, b) in a loop predicated by (icmp ne x, a), its range can be sharpened to [a + 1, b). Get ScalarEvolution and hence IndVars to exploit this fact. This change triggers an optimization to widen-loop-comp.ll, so it had to be edited to get it to pass. phabricator: http://reviews.llvm.org/D5639 llvm-svn: 219834
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index b015481b76c..8d1c632008a 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6782,6 +6782,44 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred,
RHS, LHS, FoundLHS, FoundRHS);
}
+ if (FoundPred == ICmpInst::ICMP_NE) {
+ // If we are predicated on something with range [a, b) known not
+ // equal to a, the range can be sharpened to [a + 1, b). Use this
+ // fact.
+ auto CheckRange = [this, Pred, LHS, RHS](const SCEV *C, const SCEV *V) {
+ if (!isa<SCEVConstant>(C)) return false;
+
+ ConstantInt *CI = cast<SCEVConstant>(C)->getValue();
+ APInt Min = ICmpInst::isSigned(Pred) ?
+ getSignedRange(V).getSignedMin() : getUnsignedRange(V).getUnsignedMin();
+
+ if (Min!= CI->getValue()) return false; // nothing to sharpen
+ Min++;
+
+ // We know V >= Min, in the same signedness as in Pred. We can
+ // use this to simplify slt and ult. If the range had a single
+ // value, Min, we now know that FoundValue can never be true;
+ // and any answer is a correct answer.
+
+ switch (Pred) {
+ case ICmpInst::ICMP_SGT:
+ case ICmpInst::ICMP_UGT:
+ return isImpliedCondOperands(Pred, LHS, RHS, V, getConstant(Min));
+
+ default:
+ llvm_unreachable("don't call with predicates other than ICMP_SGT "
+ "and ICMP_UGT");
+ }
+ };
+
+ if ((Pred == ICmpInst::ICMP_SGT) || (Pred == ICmpInst::ICMP_UGT)) {
+ // Inequality is reflexive -- check both the combinations.
+ if (CheckRange(FoundLHS, FoundRHS) || CheckRange(FoundRHS, FoundLHS)) {
+ return true;
+ }
+ }
+ }
+
// Check whether the actual condition is beyond sufficient.
if (FoundPred == ICmpInst::ICMP_EQ)
if (ICmpInst::isTrueWhenEqual(Pred))
OpenPOWER on IntegriCloud