[llvm] r262080 - [ConstantRange] Add umin/smin operators

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 26 14:08:18 PST 2016


Author: reames
Date: Fri Feb 26 16:08:18 2016
New Revision: 262080

URL: http://llvm.org/viewvc/llvm-project?rev=262080&view=rev
Log:
[ConstantRange] Add umin/smin operators

This was split off from http://reviews.llvm.org/D17184.

Reviewed by: Sanjoy


Modified:
    llvm/trunk/include/llvm/IR/ConstantRange.h
    llvm/trunk/lib/IR/ConstantRange.cpp
    llvm/trunk/unittests/IR/ConstantRangeTest.cpp

Modified: llvm/trunk/include/llvm/IR/ConstantRange.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ConstantRange.h?rev=262080&r1=262079&r2=262080&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/ConstantRange.h (original)
+++ llvm/trunk/include/llvm/IR/ConstantRange.h Fri Feb 26 16:08:18 2016
@@ -254,6 +254,14 @@ public:
   ConstantRange umax(const ConstantRange &Other) const;
 
   /// Return a new range representing the possible values resulting
+  /// from a signed minimum of a value in this range and a value in \p Other.
+  ConstantRange smin(const ConstantRange &Other) const;
+
+  /// Return a new range representing the possible values resulting
+  /// from an unsigned minimum of a value in this range and a value in \p Other.
+  ConstantRange umin(const ConstantRange &Other) const;
+
+  /// Return a new range representing the possible values resulting
   /// from an unsigned division of a value in this range and a value in
   /// \p Other.
   ConstantRange udiv(const ConstantRange &Other) const;

Modified: llvm/trunk/lib/IR/ConstantRange.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantRange.cpp?rev=262080&r1=262079&r2=262080&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantRange.cpp (original)
+++ llvm/trunk/lib/IR/ConstantRange.cpp Fri Feb 26 16:08:18 2016
@@ -714,6 +714,32 @@ ConstantRange::umax(const ConstantRange
 }
 
 ConstantRange
+ConstantRange::smin(const ConstantRange &Other) const {
+  // X smin Y is: range(smin(X_smin, Y_smin),
+  //                    smin(X_smax, Y_smax))
+  if (isEmptySet() || Other.isEmptySet())
+    return ConstantRange(getBitWidth(), /*isFullSet=*/false);
+  APInt NewL = APIntOps::smin(getSignedMin(), Other.getSignedMin());
+  APInt NewU = APIntOps::smin(getSignedMax(), Other.getSignedMax()) + 1;
+  if (NewU == NewL)
+    return ConstantRange(getBitWidth(), /*isFullSet=*/true);
+  return ConstantRange(NewL, NewU);
+}
+
+ConstantRange
+ConstantRange::umin(const ConstantRange &Other) const {
+  // X umin Y is: range(umin(X_umin, Y_umin),
+  //                    umin(X_umax, Y_umax))
+  if (isEmptySet() || Other.isEmptySet())
+    return ConstantRange(getBitWidth(), /*isFullSet=*/false);
+  APInt NewL = APIntOps::umin(getUnsignedMin(), Other.getUnsignedMin());
+  APInt NewU = APIntOps::umin(getUnsignedMax(), Other.getUnsignedMax()) + 1;
+  if (NewU == NewL)
+    return ConstantRange(getBitWidth(), /*isFullSet=*/true);
+  return ConstantRange(NewL, NewU);
+}
+
+ConstantRange
 ConstantRange::udiv(const ConstantRange &RHS) const {
   if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax() == 0)
     return ConstantRange(getBitWidth(), /*isFullSet=*/false);

Modified: llvm/trunk/unittests/IR/ConstantRangeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/ConstantRangeTest.cpp?rev=262080&r1=262079&r2=262080&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/ConstantRangeTest.cpp (original)
+++ llvm/trunk/unittests/IR/ConstantRangeTest.cpp Fri Feb 26 16:08:18 2016
@@ -450,6 +450,45 @@ TEST_F(ConstantRangeTest, SMax) {
   EXPECT_EQ(One.smax(One), One);
 }
 
+TEST_F(ConstantRangeTest, UMin) {
+  EXPECT_EQ(Full.umin(Full), Full);
+  EXPECT_EQ(Full.umin(Empty), Empty);
+  EXPECT_EQ(Full.umin(Some), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
+  EXPECT_EQ(Full.umin(Wrap), Full);
+  EXPECT_EQ(Empty.umin(Empty), Empty);
+  EXPECT_EQ(Empty.umin(Some), Empty);
+  EXPECT_EQ(Empty.umin(Wrap), Empty);
+  EXPECT_EQ(Empty.umin(One), Empty);
+  EXPECT_EQ(Some.umin(Some), Some);
+  EXPECT_EQ(Some.umin(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
+  EXPECT_EQ(Some.umin(One), One);
+  // TODO: ConstantRange is currently over-conservative here.
+  EXPECT_EQ(Wrap.umin(Wrap), Full);
+  EXPECT_EQ(Wrap.umin(One), ConstantRange(APInt(16, 0), APInt(16, 0xb)));
+  EXPECT_EQ(One.umin(One), One);
+}
+
+TEST_F(ConstantRangeTest, SMin) {
+  EXPECT_EQ(Full.smin(Full), Full);
+  EXPECT_EQ(Full.smin(Empty), Empty);
+  EXPECT_EQ(Full.smin(Some), ConstantRange(APInt(16, (uint64_t)INT16_MIN),
+                                           APInt(16, 0xaaa)));
+  EXPECT_EQ(Full.smin(Wrap), Full);
+  EXPECT_EQ(Empty.smin(Empty), Empty);
+  EXPECT_EQ(Empty.smin(Some), Empty);
+  EXPECT_EQ(Empty.smin(Wrap), Empty);
+  EXPECT_EQ(Empty.smin(One), Empty);
+  EXPECT_EQ(Some.smin(Some), Some);
+  EXPECT_EQ(Some.smin(Wrap), ConstantRange(APInt(16, (uint64_t)INT16_MIN),
+                                           APInt(16, 0xaaa)));
+  EXPECT_EQ(Some.smin(One), One);
+  // TODO: ConstantRange is currently over-conservative here.
+  EXPECT_EQ(Wrap.smin(Wrap), Full);
+  EXPECT_EQ(Wrap.smin(One), ConstantRange(APInt(16, (uint64_t)INT16_MIN),
+                                          APInt(16, 0xb)));
+  EXPECT_EQ(One.smin(One), One);
+}
+
 TEST_F(ConstantRangeTest, UDiv) {
   EXPECT_EQ(Full.udiv(Full), Full);
   EXPECT_EQ(Full.udiv(Empty), Empty);




More information about the llvm-commits mailing list