Added AssumeSymGT, AssumeSymGE, AssumeSymLT, AssumeSymLE to add some minor improvements to path-sensitivity.  Right now we basically treat 'x > y' and 'x < y' as implying 'x != y', but this restriction will only inevitably apply to our must rudimentary value tracking component (we'll implement more advanced value reasoning later).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54493 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/ValueState.cpp b/lib/Analysis/ValueState.cpp
index 1cf6954..ffc4c28 100644
--- a/lib/Analysis/ValueState.cpp
+++ b/lib/Analysis/ValueState.cpp
@@ -435,50 +435,7 @@
   }
 }
 
-const ValueState* ValueStateManager::AssumeSymNE(const ValueState* St,
-                                            SymbolID sym, const llvm::APSInt& V,
-                                            bool& isFeasible) {
-  
-  // First, determine if sym == X, where X != V.
-  if (const llvm::APSInt* X = St->getSymVal(sym)) {
-    isFeasible = *X != V;
-    return St;
-  }
-  
-  // Second, determine if sym != V.
-  if (St->isNotEqual(sym, V)) {
-    isFeasible = true;
-    return St;
-  }
-  
-  // If we reach here, sym is not a constant and we don't know if it is != V.
-  // Make that assumption.
-  
-  isFeasible = true;
-  return AddNE(St, sym, V);
-}
 
-const ValueState* ValueStateManager::AssumeSymEQ(const ValueState* St, SymbolID sym,
-                                            const llvm::APSInt& V, bool& isFeasible) {
-  
-  // First, determine if sym == X, where X != V.
-  if (const llvm::APSInt* X = St->getSymVal(sym)) {
-    isFeasible = *X == V;
-    return St;
-  }
-  
-  // Second, determine if sym != V.
-  if (St->isNotEqual(sym, V)) {
-    isFeasible = false;
-    return St;
-  }
-  
-  // If we reach here, sym is not a constant and we don't know if it is == V.
-  // Make that assumption.
-  
-  isFeasible = true;
-  return AddEQ(St, sym, V);
-}
 
 const ValueState* ValueStateManager::AssumeSymInt(const ValueState* St,
                                              bool Assumption,
@@ -502,5 +459,116 @@
         return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
       else
         return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
+      
+    case BinaryOperator::GE:
+      if (Assumption)
+        return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
+      else
+        return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
+      
+    case BinaryOperator::LE:
+      if (Assumption)
+        return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
+      else
+        return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);    
   }
 }
+
+//===----------------------------------------------------------------------===//
+// FIXME: This should go into a plug-in constraint engine.
+//===----------------------------------------------------------------------===//
+
+const ValueState*
+ValueStateManager::AssumeSymNE(const ValueState* St, SymbolID sym,
+                               const llvm::APSInt& V, bool& isFeasible) {
+  
+  // First, determine if sym == X, where X != V.
+  if (const llvm::APSInt* X = St->getSymVal(sym)) {
+    isFeasible = *X != V;
+    return St;
+  }
+  
+  // Second, determine if sym != V.
+  if (St->isNotEqual(sym, V)) {
+    isFeasible = true;
+    return St;
+  }
+  
+  // If we reach here, sym is not a constant and we don't know if it is != V.
+  // Make that assumption.
+  
+  isFeasible = true;
+  return AddNE(St, sym, V);
+}
+
+const ValueState*
+ValueStateManager::AssumeSymEQ(const ValueState* St, SymbolID sym,
+                               const llvm::APSInt& V, bool& isFeasible) {
+  
+  // First, determine if sym == X, where X != V.
+  if (const llvm::APSInt* X = St->getSymVal(sym)) {
+    isFeasible = *X == V;
+    return St;
+  }
+  
+  // Second, determine if sym != V.
+  if (St->isNotEqual(sym, V)) {
+    isFeasible = false;
+    return St;
+  }
+  
+  // If we reach here, sym is not a constant and we don't know if it is == V.
+  // Make that assumption.
+  
+  isFeasible = true;
+  return AddEQ(St, sym, V);
+}
+
+const ValueState*
+ValueStateManager::AssumeSymLT(const ValueState* St, SymbolID sym,
+                               const llvm::APSInt& V, bool& isFeasible) {
+  
+  // FIXME: For now have assuming x < y be the same as assuming sym != V;
+  return AssumeSymNE(St, sym, V, isFeasible);
+}
+
+const ValueState*
+ValueStateManager::AssumeSymGT(const ValueState* St, SymbolID sym,
+                               const llvm::APSInt& V, bool& isFeasible) {
+  
+  // FIXME: For now have assuming x > y be the same as assuming sym != V;
+  return AssumeSymNE(St, sym, V, isFeasible);
+}
+
+const ValueState*
+ValueStateManager::AssumeSymGE(const ValueState* St, SymbolID sym,
+                               const llvm::APSInt& V, bool& isFeasible) {
+  
+  // FIXME: Primitive logic for now.  Only reject a path if the value of
+  //  sym is a constant X and !(X >= V).
+  
+  if (const llvm::APSInt* X = St->getSymVal(sym)) {
+    isFeasible = *X >= V;
+    return St;
+  }
+  
+  isFeasible = true;
+  return St;
+}
+
+const ValueState*
+ValueStateManager::AssumeSymLE(const ValueState* St, SymbolID sym,
+                               const llvm::APSInt& V, bool& isFeasible) {
+  
+  // FIXME: Primitive logic for now.  Only reject a path if the value of
+  //  sym is a constant X and !(X <= V).
+    
+  if (const llvm::APSInt* X = St->getSymVal(sym)) {
+    isFeasible = *X <= V;
+    return St;
+  }
+  
+  isFeasible = true;
+  return St;
+}
+