Now that we're using ConstantRange to represent potential values, make use of that...
authorOwen Anderson <resistor@mac.com>
Tue, 10 Aug 2010 23:20:01 +0000 (23:20 +0000)
committerOwen Anderson <resistor@mac.com>
Tue, 10 Aug 2010 23:20:01 +0000 (23:20 +0000)
create constraints from comparisons other than eq/neq.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110742 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/LazyValueInfo.cpp

index 7ec35cdcc5bdb11c805d47dd8125b00e26f6eb1f..48778232002e991bf66f1002011b87fae90c9623 100644 (file)
@@ -91,6 +91,11 @@ public:
       Res.markNotConstant(C);
     return Res;
   }
+  static LVILatticeVal getRange(ConstantRange CR) {
+    LVILatticeVal Res;
+    Res.markConstantRange(CR);
+    return Res;
+  }
   
   bool isUndefined() const     { return Tag == undefined; }
   bool isConstant() const      { return Tag == constant; }
@@ -507,13 +512,35 @@ LVILatticeVal LVIQuery::getEdgeValue(BasicBlock *BBFrom, BasicBlock *BBTo) {
       // If the condition of the branch is an equality comparison, we may be
       // able to infer the value.
       if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition()))
-        if (ICI->isEquality() && ICI->getOperand(0) == Val &&
-            isa<Constant>(ICI->getOperand(1))) {
-          // We know that V has the RHS constant if this is a true SETEQ or
-          // false SETNE. 
-          if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ))
-            return LVILatticeVal::get(cast<Constant>(ICI->getOperand(1)));
-          return LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1)));
+        if (ICI->getOperand(0) == Val && isa<Constant>(ICI->getOperand(1))) {
+          if (ICI->isEquality()) {
+            // We know that V has the RHS constant if this is a true SETEQ or
+            // false SETNE. 
+            if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ))
+              return LVILatticeVal::get(cast<Constant>(ICI->getOperand(1)));
+            return LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1)));
+          } else if (ConstantInt *CI =
+                                   dyn_cast<ConstantInt>(ICI->getOperand(1))) {
+            
+            // Calculate the range of values that would satisfy the comparison.
+            ConstantRange CmpRange(CI->getValue(), CI->getValue()+1);
+            ConstantRange TrueValues =
+              ConstantRange::makeICmpRegion(ICI->getPredicate(), CmpRange);
+            
+            // If we're interested in the false dest, invert the condition.
+            if (!isTrueDest) TrueValues = TrueValues.inverse();
+            
+            // Figure out the possible values of the query BEFORE this branch.  
+            LVILatticeVal InBlock = getBlockValue(BBFrom);
+            if (!InBlock.isConstantRange()) return InBlock;
+            
+            // Find all potential values that satisfy both the input and output
+            // conditions.
+            ConstantRange PossibleValues =
+              TrueValues.intersectWith(InBlock.getConstantRange());
+            
+            return LVILatticeVal::getRange(PossibleValues);
+          }
         }
     }
   }
@@ -730,7 +757,7 @@ LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
     ConstantRange TrueValues = ConstantRange::makeICmpRegion(Pred, RHS);
     if (CR.intersectWith(TrueValues).isEmptySet())
       return False;
-    else if (CR.intersectWith(TrueValues) == CR)
+    else if (TrueValues.contains(CR))
       return True;
     
     return Unknown;