Add completely hokey binary-and and binary-or operations to ConstantRange and
authorNick Lewycky <nicholas@mxc.ca>
Tue, 7 Sep 2010 05:39:02 +0000 (05:39 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Tue, 7 Sep 2010 05:39:02 +0000 (05:39 +0000)
teach LazyValueInfo to use them.

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

include/llvm/Support/ConstantRange.h
lib/Analysis/LazyValueInfo.cpp
lib/Support/ConstantRange.cpp

index 2af2cf61eaeac298ec00d82f88df464df0abb7e3..792b4107b143788316a051df2a625c21b76c352b 100644 (file)
@@ -224,6 +224,14 @@ public:
   /// \p Other.
   ConstantRange udiv(const ConstantRange &Other) const;
 
+  /// binaryAnd - return a new range representing the possible values resulting
+  /// from a binary-and of a value in this range by a value in \p Other.
+  ConstantRange binaryAnd(const ConstantRange &Other) const;
+
+  /// binaryOr - return a new range representing the possible values resulting
+  /// from a binary-or of a value in this range by a value in \p Other.
+  ConstantRange binaryOr(const ConstantRange &Other) const;
+
   /// shl - Return a new range representing the possible values resulting
   /// from a left shift of a value in this range by a value in \p Other.
   /// TODO: This isn't fully implemented yet.
index 9c3878b7759ffc5017e744f985c15d22001f0511..2c25f80dbeacb1ef1646f0dc52d32357f7332993 100644 (file)
@@ -602,6 +602,12 @@ LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) {
   case Instruction::BitCast:
     Result.markConstantRange(LHSRange);
     break;
+  case Instruction::And:
+    Result.markConstantRange(LHSRange.binaryAnd(RHSRange));
+    break;
+  case Instruction::Or:
+    Result.markConstantRange(LHSRange.binaryOr(RHSRange));
+    break;
   
   // Unhandled instructions are overdefined.
   default:
index defb8189b6285b9d4000acf7329df028e18fe28c..c89ec9a2aacd9f2ff285fb4f9f8a694084b5178f 100644 (file)
@@ -607,6 +607,32 @@ ConstantRange::udiv(const ConstantRange &RHS) const {
   return ConstantRange(Lower, Upper);
 }
 
+ConstantRange
+ConstantRange::binaryAnd(const ConstantRange &Other) const {
+  if (isEmptySet() || Other.isEmptySet())
+    return ConstantRange(getBitWidth(), /*isFullSet=*/false);
+
+  // TODO: replace this with something less conservative
+
+  APInt umin = APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax());
+  if (umin.isAllOnesValue())
+    return ConstantRange(getBitWidth(), /*isFullSet=*/true);
+  return ConstantRange(APInt::getNullValue(getBitWidth()), umin + 1);
+}
+
+ConstantRange
+ConstantRange::binaryOr(const ConstantRange &Other) const {
+  if (isEmptySet() || Other.isEmptySet())
+    return ConstantRange(getBitWidth(), /*isFullSet=*/false);
+
+  // TODO: replace this with something less conservative
+
+  APInt umax = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin());
+  if (umax.isMinValue())
+    return ConstantRange(getBitWidth(), /*isFullSet=*/true);
+  return ConstantRange(umax, APInt::getNullValue(getBitWidth()));
+}
+
 ConstantRange
 ConstantRange::shl(const ConstantRange &Other) const {
   if (isEmptySet() || Other.isEmptySet())