[PATCH] D32508: [ValueTracking] Begin adding some useful methods to the proposed KnownBits struct

Craig Topper via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 25 15:26:14 PDT 2017


craig.topper created this revision.

This patch adds some plausible methods to the KnownBits struct from https://reviews.llvm.org/D32376.

I'm not married to the names for hasConflict, isValid, isComplete, and getValue.

hasConflict and isValid are opposites of each other, but I've added both because isValid is going to be primarily used in asserts that verify no conflicts.  hasConflict will be used in a couple places in places where we explicitly check for conflicts today like in the assume handling code.

I've intentionally avoided calling isComplete something like allBitsKnown because the struct itself is usually a variable called Known so it would read repetitively.


https://reviews.llvm.org/D32508

Files:
  include/llvm/Support/KnownBits.h


Index: include/llvm/Support/KnownBits.h
===================================================================
--- include/llvm/Support/KnownBits.h
+++ include/llvm/Support/KnownBits.h
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file contains a class for reprsenting known zeros and ones used by
+// This file contains a class for representing known zeros and ones used by
 // computeKnownBits.
 //
 //===----------------------------------------------------------------------===//
@@ -19,7 +19,7 @@
 
 namespace llvm {
 
-// For now this is a simple wrapper around two APInts.
+// Struct for managing the known zeros and ones of a value.
 struct KnownBits {
   APInt Zero;
   APInt One;
@@ -36,6 +36,56 @@
            "Zero and One should have the same width!");
     return Zero.getBitWidth();
   }
+
+  /// Returns true if there is conflicting information.
+  bool hasConflict() const { return Zero.intersects(One); }
+
+  /// Returns true if there is no conflicting information.
+  bool isValid() const {
+    assert(Zero.getBitWidth() == One.getBitWidth() &&
+           "Zero and One should have the same width!");
+    return !hasConflict();
+  }
+
+  /// Returns true if we know the value of all bits.
+  bool isComplete() const {
+    assert(isValid() && "KnownBits conflict!");
+    return Zero.countPopulation() + One.countPopulation() == getBitWidth();
+  }
+
+  /// Returns the value when all bits have a known value. This just returns One
+  /// with a protective assertion.
+  const APInt &getValue() const {
+    assert(isComplete() && "Can only get value when all bits are known");
+    return One;
+  }
+
+  /// Returns true if this value is known to be negative.
+  bool isNegative() const { return One.isSignBitSet(); }
+
+  /// Returns true if this value is known to be non-negative.
+  bool isNonNegative() const { return Zero.isSignBitSet(); }
+
+  /// Truncate the underlying known Zero and One bits. This is equivalent
+  /// to truncating the value we're tracking.
+  void trunc(unsigned BitWidth) {
+    Zero = Zero.trunc(BitWidth);
+    One  = One.trunc(BitWidth);
+  }
+
+  /// Zero extends the underlying known Zero and One bits. This is equivalent
+  /// to zero extending the value we're tracking.
+  void zext(unsigned BitWidth) {
+    Zero = Zero.zext(BitWidth);
+    One  = One.zext(BitWidth);
+  }
+
+  /// Sign extends the underlying known Zero and One bits. This is equivalent
+  /// to sign extending the value we're tracking. 
+  void sext(unsigned BitWidth) {
+    Zero = Zero.sext(BitWidth);
+    One  = One.sext(BitWidth);
+  }
 };
 
 } // end namespace llvm


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32508.96640.patch
Type: text/x-patch
Size: 2669 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170425/6a6860f9/attachment.bin>


More information about the llvm-commits mailing list