diff options
-rw-r--r-- | llvm/include/llvm/IR/ConstantRange.h | 13 | ||||
-rw-r--r-- | llvm/lib/IR/ConstantRange.cpp | 14 | ||||
-rw-r--r-- | llvm/unittests/IR/ConstantRangeTest.cpp | 33 |
3 files changed, 52 insertions, 8 deletions
diff --git a/llvm/include/llvm/IR/ConstantRange.h b/llvm/include/llvm/IR/ConstantRange.h index 9612890000d..be5e297bf71 100644 --- a/llvm/include/llvm/IR/ConstantRange.h +++ b/llvm/include/llvm/IR/ConstantRange.h @@ -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; diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp index 896a870bf90..eda31f73473 100644 --- a/llvm/lib/IR/ConstantRange.cpp +++ b/llvm/lib/IR/ConstantRange.cpp @@ -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(); } diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp index 0455df5fa5e..2cde17f291c 100644 --- a/llvm/unittests/IR/ConstantRangeTest.cpp +++ b/llvm/unittests/IR/ConstantRangeTest.cpp @@ -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); |