]> granicus.if.org Git - llvm/commitdiff
[ConstantRange] Add isWrappedSet() and isUpperSignWrapped()
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 27 Mar 2019 19:12:09 +0000 (19:12 +0000)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 27 Mar 2019 19:12:09 +0000 (19:12 +0000)
Split off from D59749. This adds isWrappedSet() and
isUpperSignWrapped() set with the same behavior as isSignWrappedSet()
and isUpperWrapped() for the respectively other domain.

The methods isWrappedSet() and isSignWrappedSet() will not consider
ranges of the form [X, Max] == [X, 0) and [X, SignedMax] == [X, SignedMin)
to be wrapping, while isUpperWrapped() and isUpperSignWrapped() will.

Also replace the checks in getUnsignedMin() and friends with method
calls that implement the same logic.

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

include/llvm/IR/ConstantRange.h
lib/IR/ConstantRange.cpp
unittests/IR/ConstantRangeTest.cpp

index 9612890000d97ec72c934efd10d547948a11bf8b..be5e297bf710959f96286b6e336e2c2e416d3180 100644 (file)
@@ -163,6 +163,12 @@ public:
   /// Return true if this set contains no members.
   bool isEmptySet() const;
 
+  /// Return true if this set wraps around the unsigned domain. Special cases:
+  ///  * Empty set: Not wrapped.
+  ///  * Full set: Not wrapped.
+  ///  * [X, 0) == [X, Max]: Not wrapped.
+  bool isWrappedSet() const;
+
   /// Return true if the exclusive upper bound wraps around the unsigned
   /// domain. Special cases:
   ///  * Empty set: Not wrapped.
@@ -176,6 +182,13 @@ public:
   ///  * [X, SignedMin) == [X, SignedMax]: Not wrapped.
   bool isSignWrappedSet() const;
 
+  /// Return true if the (exclusive) upper bound wraps around the signed
+  /// domain. Special cases:
+  ///  * Empty set: Not wrapped.
+  ///  * Full set: Not wrapped.
+  ///  * [X, SignedMin): Wrapped.
+  bool isUpperSignWrapped() const;
+
   /// Return true if the specified value is in the set.
   bool contains(const APInt &Val) const;
 
index 896a870bf9074af515ef03a22ba7ed7b9a041522..eda31f73473ef45e7d9f3d24ec42fbdf784e1169 100644 (file)
@@ -344,6 +344,10 @@ bool ConstantRange::isEmptySet() const {
   return Lower == Upper && Lower.isMinValue();
 }
 
+bool ConstantRange::isWrappedSet() const {
+  return Lower.ugt(Upper) && !Upper.isNullValue();
+}
+
 bool ConstantRange::isUpperWrapped() const {
   return Lower.ugt(Upper);
 }
@@ -352,6 +356,10 @@ bool ConstantRange::isSignWrappedSet() const {
   return Lower.sgt(Upper) && !Upper.isMinSignedValue();
 }
 
+bool ConstantRange::isUpperSignWrapped() const {
+  return Lower.sgt(Upper);
+}
+
 APInt ConstantRange::getSetSize() const {
   if (isFullSet())
     return APInt::getOneBitSet(getBitWidth()+1, getBitWidth());
@@ -388,19 +396,19 @@ APInt ConstantRange::getUnsignedMax() const {
 }
 
 APInt ConstantRange::getUnsignedMin() const {
-  if (isFullSet() || (isUpperWrapped() && !getUpper().isNullValue()))
+  if (isFullSet() || isWrappedSet())
     return APInt::getMinValue(getBitWidth());
   return getLower();
 }
 
 APInt ConstantRange::getSignedMax() const {
-  if (isFullSet() || Lower.sgt(Upper))
+  if (isFullSet() || isUpperSignWrapped())
     return APInt::getSignedMaxValue(getBitWidth());
   return getUpper() - 1;
 }
 
 APInt ConstantRange::getSignedMin() const {
-  if (isFullSet() || (Lower.sgt(Upper) && !getUpper().isMinSignedValue()))
+  if (isFullSet() || isSignWrappedSet())
     return APInt::getSignedMinValue(getBitWidth());
   return getLower();
 }
index 0455df5fa5e3cf8ae2e2c232b36a95c0b76c1f63..2cde17f291cb45fc98a805cd4791c5e1929e280c 100644 (file)
@@ -35,7 +35,7 @@ TEST_F(ConstantRangeTest, Basics) {
   EXPECT_TRUE(Full.isFullSet());
   EXPECT_FALSE(Full.isEmptySet());
   EXPECT_TRUE(Full.inverse().isEmptySet());
-  EXPECT_FALSE(Full.isUpperWrapped());
+  EXPECT_FALSE(Full.isWrappedSet());
   EXPECT_TRUE(Full.contains(APInt(16, 0x0)));
   EXPECT_TRUE(Full.contains(APInt(16, 0x9)));
   EXPECT_TRUE(Full.contains(APInt(16, 0xa)));
@@ -45,7 +45,7 @@ TEST_F(ConstantRangeTest, Basics) {
   EXPECT_FALSE(Empty.isFullSet());
   EXPECT_TRUE(Empty.isEmptySet());
   EXPECT_TRUE(Empty.inverse().isFullSet());
-  EXPECT_FALSE(Empty.isUpperWrapped());
+  EXPECT_FALSE(Empty.isWrappedSet());
   EXPECT_FALSE(Empty.contains(APInt(16, 0x0)));
   EXPECT_FALSE(Empty.contains(APInt(16, 0x9)));
   EXPECT_FALSE(Empty.contains(APInt(16, 0xa)));
@@ -54,7 +54,7 @@ TEST_F(ConstantRangeTest, Basics) {
 
   EXPECT_FALSE(One.isFullSet());
   EXPECT_FALSE(One.isEmptySet());
-  EXPECT_FALSE(One.isUpperWrapped());
+  EXPECT_FALSE(One.isWrappedSet());
   EXPECT_FALSE(One.contains(APInt(16, 0x0)));
   EXPECT_FALSE(One.contains(APInt(16, 0x9)));
   EXPECT_TRUE(One.contains(APInt(16, 0xa)));
@@ -64,7 +64,7 @@ TEST_F(ConstantRangeTest, Basics) {
 
   EXPECT_FALSE(Some.isFullSet());
   EXPECT_FALSE(Some.isEmptySet());
-  EXPECT_FALSE(Some.isUpperWrapped());
+  EXPECT_FALSE(Some.isWrappedSet());
   EXPECT_FALSE(Some.contains(APInt(16, 0x0)));
   EXPECT_FALSE(Some.contains(APInt(16, 0x9)));
   EXPECT_TRUE(Some.contains(APInt(16, 0xa)));
@@ -73,7 +73,7 @@ TEST_F(ConstantRangeTest, Basics) {
 
   EXPECT_FALSE(Wrap.isFullSet());
   EXPECT_FALSE(Wrap.isEmptySet());
-  EXPECT_TRUE(Wrap.isUpperWrapped());
+  EXPECT_TRUE(Wrap.isWrappedSet());
   EXPECT_TRUE(Wrap.contains(APInt(16, 0x0)));
   EXPECT_TRUE(Wrap.contains(APInt(16, 0x9)));
   EXPECT_FALSE(Wrap.contains(APInt(16, 0xa)));
@@ -176,6 +176,29 @@ TEST_F(ConstantRangeTest, SignWrapped) {
   EXPECT_FALSE(ConstantRange(APInt(8, 250), APInt(8, 251)).isSignWrappedSet());
 }
 
+TEST_F(ConstantRangeTest, UpperWrapped) {
+  // The behavior here is the same as for isWrappedSet() / isSignWrappedSet().
+  EXPECT_FALSE(Full.isUpperWrapped());
+  EXPECT_FALSE(Empty.isUpperWrapped());
+  EXPECT_FALSE(One.isUpperWrapped());
+  EXPECT_FALSE(Some.isUpperWrapped());
+  EXPECT_TRUE(Wrap.isUpperWrapped());
+  EXPECT_FALSE(Full.isUpperSignWrapped());
+  EXPECT_FALSE(Empty.isUpperSignWrapped());
+  EXPECT_FALSE(One.isUpperSignWrapped());
+  EXPECT_FALSE(Some.isUpperSignWrapped());
+  EXPECT_TRUE(Wrap.isUpperSignWrapped());
+
+  // The behavior differs if Upper is the Min/SignedMin value.
+  ConstantRange CR1(APInt(8, 42), APInt::getMinValue(8));
+  EXPECT_FALSE(CR1.isWrappedSet());
+  EXPECT_TRUE(CR1.isUpperWrapped());
+
+  ConstantRange CR2(APInt(8, 42), APInt::getSignedMinValue(8));
+  EXPECT_FALSE(CR2.isSignWrappedSet());
+  EXPECT_TRUE(CR2.isUpperSignWrapped());
+}
+
 TEST_F(ConstantRangeTest, Trunc) {
   ConstantRange TFull = Full.truncate(10);
   ConstantRange TEmpty = Empty.truncate(10);