OSDN Git Service

[ConstantRange] Shl considers full-set shifting to last bit position.
authorMarcello Maggioni <hayarms@gmail.com>
Sun, 7 Apr 2019 06:12:44 +0000 (06:12 +0000)
committerMarcello Maggioni <hayarms@gmail.com>
Sun, 7 Apr 2019 06:12:44 +0000 (06:12 +0000)
if we do SHL of two 16-bit ranges like [0, 30000) with [1,2) we get
"full-set" instead of what I would have expected [0, 60000) which is
still in the 16-bit unsigned range.

This patch changes the SHL algorithm to allow getting a usable range
even in this case.

Differential Revision: https://reviews.llvm.org/D57983

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

lib/IR/ConstantRange.cpp
unittests/IR/ConstantRangeTest.cpp

index eda31f7..f07ec9d 100644 (file)
@@ -1006,8 +1006,12 @@ ConstantRange::shl(const ConstantRange &Other) const {
   APInt max = getUnsignedMax();
   APInt Other_umax = Other.getUnsignedMax();
 
+  // If we are shifting by maximum amount of
+  // zero return return the original range.
+  if (Other_umax.isNullValue())
+    return *this;
   // there's overflow!
-  if (Other_umax.uge(max.countLeadingZeros()))
+  if (Other_umax.ugt(max.countLeadingZeros()))
     return getFull();
 
   // FIXME: implement the other tricky cases
index c9273bc..db298bc 100644 (file)
@@ -704,6 +704,8 @@ TEST_F(ConstantRangeTest, UDiv) {
 }
 
 TEST_F(ConstantRangeTest, Shl) {
+  ConstantRange Some2(APInt(16, 0xfff), APInt(16, 0x8000));
+  ConstantRange WrapNullMax(APInt(16, 0x1), APInt(16, 0x0));
   EXPECT_EQ(Full.shl(Full), Full);
   EXPECT_EQ(Full.shl(Empty), Empty);
   EXPECT_EQ(Full.shl(One), Full);    // TODO: [0, (-1 << 0xa) + 1)
@@ -720,6 +722,10 @@ TEST_F(ConstantRangeTest, Shl) {
   EXPECT_EQ(Some.shl(Some), Full);   // TODO: [0xa << 0xa, 0xfc01)
   EXPECT_EQ(Some.shl(Wrap), Full);   // TODO: [0xa, 0x7ff << 0x5 + 1)
   EXPECT_EQ(Wrap.shl(Wrap), Full);
+  EXPECT_EQ(
+      Some2.shl(ConstantRange(APInt(16, 0x1))),
+      ConstantRange(APInt(16, 0xfff << 0x1), APInt(16, 0x7fff << 0x1) + 1));
+  EXPECT_EQ(One.shl(WrapNullMax), Full);
 }
 
 TEST_F(ConstantRangeTest, Lshr) {