[llvm-commits] [llvm] r76360 - in /llvm/trunk: lib/Support/ConstantRange.cpp unittests/Support/ConstantRangeTest.cpp

Nick Lewycky nicholas at mxc.ca
Sat Jul 18 20:44:39 PDT 2009


Author: nicholas
Date: Sat Jul 18 22:44:35 2009
New Revision: 76360

URL: http://llvm.org/viewvc/llvm-project?rev=76360&view=rev
Log:
Fix ConstantRange::unionWith. Also make it work a little hard in some cases to
return the smallest union of two ranges instead of just any range that happens
to contain the union.

Modified:
    llvm/trunk/lib/Support/ConstantRange.cpp
    llvm/trunk/unittests/Support/ConstantRangeTest.cpp

Modified: llvm/trunk/lib/Support/ConstantRange.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ConstantRange.cpp?rev=76360&r1=76359&r2=76360&view=diff

==============================================================================
--- llvm/trunk/lib/Support/ConstantRange.cpp (original)
+++ llvm/trunk/lib/Support/ConstantRange.cpp Sat Jul 18 22:44:35 2009
@@ -371,69 +371,74 @@
 
   if (!isWrappedSet() && CR.isWrappedSet()) return CR.unionWith(*this);
 
-  APInt L = Lower, U = Upper;
-
   if (!isWrappedSet() && !CR.isWrappedSet()) {
+    if (CR.Upper.ult(Lower) || Upper.ult(CR.Lower)) {
+      // If the two ranges are disjoint, find the smaller gap and bridge it.
+      APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper;
+      if (d1.ult(d2))
+        return ConstantRange(Lower, CR.Upper);
+      else
+        return ConstantRange(CR.Lower, Upper);
+    }
+
+    APInt L = Lower, U = Upper;
     if (CR.Lower.ult(L))
       L = CR.Lower;
-
-    if (CR.Upper.ugt(U))
+    if ((CR.Upper - 1).ugt(U - 1))
       U = CR.Upper;
+
+    if (L == 0 && U == 0)
+      return ConstantRange(getBitWidth());
+
+    return ConstantRange(L, U);
   }
 
-  if (isWrappedSet() && !CR.isWrappedSet()) {
-    if ((CR.Lower.ult(Upper) && CR.Upper.ult(Upper)) ||
-        (CR.Lower.ugt(Lower) && CR.Upper.ugt(Lower))) {
+  if (!CR.isWrappedSet()) {
+    // ------U   L-----  and  ------U   L----- : this
+    //   L--U                            L--U  : CR
+    if (CR.Upper.ule(Upper) || CR.Lower.uge(Lower))
       return *this;
-    }
 
-    if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper)) {
+    // ------U   L----- : this
+    //    L---------U   : CR
+    if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper))
       return ConstantRange(getBitWidth());
-    }
 
-    if (CR.Lower.ule(Upper) && CR.Upper.ule(Lower)) {
-      APInt d1 = CR.Upper - Upper, d2 = Lower - CR.Upper;
-      if (d1.ult(d2)) {
-        U = CR.Upper;
-      } else {
-        L = CR.Upper;
-      }
-    }
-
-    if (Upper.ult(CR.Lower) && CR.Upper.ult(Lower)) {
+    // ----U       L---- : this
+    //       L---U       : CR
+    //    <d1>  <d2>
+    if (Upper.ule(CR.Lower) && CR.Upper.ule(Lower)) {
       APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper;
-      if (d1.ult(d2)) {
-        U = CR.Lower + 1;
-      } else {
-        L = CR.Upper - 1;
-      }
+      if (d1.ult(d2))
+        return ConstantRange(Lower, CR.Upper);
+      else
+        return ConstantRange(CR.Lower, Upper);
     }
 
-    if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper)) {
-      APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Lower;
-
-      if (d1.ult(d2)) {
-        U = CR.Lower + 1;
-      } else {
-        L = CR.Lower;
-      }
-    }
+    // ----U     L----- : this
+    //        L----U    : CR
+    if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper))
+      return ConstantRange(CR.Lower, Upper);
+
+    // ------U    L---- : this
+    //    L-----U       : CR
+    if (CR.Lower.ult(Upper) && CR.Upper.ult(Lower))
+      return ConstantRange(Lower, CR.Upper);
   }
 
-  if (isWrappedSet() && CR.isWrappedSet()) {
-    if (Lower.ult(CR.Upper) || CR.Lower.ult(Upper))
-      return ConstantRange(getBitWidth());
+  assert(isWrappedSet() && CR.isWrappedSet() &&
+         "ConstantRange::unionWith missed wrapped union unwrapped case");
 
-    if (CR.Upper.ugt(U)) {
-      U = CR.Upper;
-    }
+  // ------U    L----  and  ------U    L---- : this
+  // -U  L-----------  and  ------------U  L : CR
+  if (CR.Lower.ule(Upper) || Lower.ule(CR.Upper))
+    return ConstantRange(getBitWidth());
 
-    if (CR.Lower.ult(L)) {
-      L = CR.Lower;
-    }
-
-    if (L == U) return ConstantRange(getBitWidth());
-  }
+  APInt L = Lower, U = Upper;
+  if (CR.Upper.ugt(U))
+    U = CR.Upper;
+  if (CR.Lower.ult(L))
+    L = CR.Lower;
 
   return ConstantRange(L, U);
 }

Modified: llvm/trunk/unittests/Support/ConstantRangeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ConstantRangeTest.cpp?rev=76360&r1=76359&r2=76360&view=diff

==============================================================================
--- llvm/trunk/unittests/Support/ConstantRangeTest.cpp (original)
+++ llvm/trunk/unittests/Support/ConstantRangeTest.cpp Sat Jul 18 22:44:35 2009
@@ -219,6 +219,17 @@
   EXPECT_TRUE(Empty.unionWith(Empty).isEmptySet());
   EXPECT_TRUE(Full.unionWith(Full).isFullSet());
   EXPECT_TRUE(Some.unionWith(Wrap).isFullSet());
+
+  // PR4545
+  EXPECT_EQ(ConstantRange(APInt(16, 14), APInt(16, 1)).unionWith(
+            ConstantRange(APInt(16, 0), APInt(16, 8))),
+            ConstantRange(APInt(16, 14), APInt(16, 8)));
+  EXPECT_EQ(ConstantRange(APInt(16, 6), APInt(16, 4)).unionWith(
+            ConstantRange(APInt(16, 4), APInt(16, 0))),
+            ConstantRange(16));
+  EXPECT_EQ(ConstantRange(APInt(16, 1), APInt(16, 0)).unionWith(
+            ConstantRange(APInt(16, 2), APInt(16, 1))),
+            ConstantRange(16));
 }
 
 TEST_F(ConstantRangeTest, SubtractAPInt) {





More information about the llvm-commits mailing list