[llvm] r270018 - [ConstantRange] Add an getEquivalentICmp helper

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Wed May 18 20:53:09 PDT 2016


Author: sanjoy
Date: Wed May 18 22:53:06 2016
New Revision: 270018

URL: http://llvm.org/viewvc/llvm-project?rev=270018&view=rev
Log:
[ConstantRange] Add an getEquivalentICmp helper

Currently only its unit test uses it, but this will be used in a later
change to simplify some logic in the GuardWidening pass.

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=270018&r1=270017&r2=270018&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/ConstantRange.h (original)
+++ llvm/trunk/include/llvm/IR/ConstantRange.h Wed May 18 22:53:06 2016
@@ -114,6 +114,11 @@ public:
                                                   const ConstantRange &Other,
                                                   unsigned NoWrapKind);
 
+  /// Set up \p Pred and \p RHS such that
+  /// ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.  Return true if
+  /// successful.
+  bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const;
+
   /// Return the lower value for this range.
   ///
   const APInt &getLower() const { return Lower; }

Modified: llvm/trunk/lib/IR/ConstantRange.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantRange.cpp?rev=270018&r1=270017&r2=270018&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantRange.cpp (original)
+++ llvm/trunk/lib/IR/ConstantRange.cpp Wed May 18 22:53:06 2016
@@ -139,6 +139,32 @@ ConstantRange ConstantRange::makeExactIC
   return makeAllowedICmpRegion(Pred, C);
 }
 
+bool ConstantRange::getEquivalentICmp(CmpInst::Predicate &Pred,
+                                      APInt &RHS) const {
+  bool Success = false;
+
+  if (isFullSet() || isEmptySet()) {
+    Pred = isEmptySet() ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE;
+    RHS = APInt(getBitWidth(), 0);
+    Success = true;
+  } else if (getLower().isMinSignedValue() || getLower().isMinValue()) {
+    Pred =
+        getLower().isMinSignedValue() ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT;
+    RHS = getUpper();
+    Success = true;
+  } else if (getUpper().isMinSignedValue() || getUpper().isMinValue()) {
+    Pred =
+        getUpper().isMinSignedValue() ? CmpInst::ICMP_SGE : CmpInst::ICMP_UGE;
+    RHS = getLower();
+    Success = true;
+  }
+
+  assert((!Success || ConstantRange::makeExactICmpRegion(Pred, RHS) == *this) &&
+         "Bad result!");
+
+  return Success;
+}
+
 ConstantRange
 ConstantRange::makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
                                           const ConstantRange &Other,

Modified: llvm/trunk/unittests/IR/ConstantRangeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/ConstantRangeTest.cpp?rev=270018&r1=270017&r2=270018&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/ConstantRangeTest.cpp (original)
+++ llvm/trunk/unittests/IR/ConstantRangeTest.cpp Wed May 18 22:53:06 2016
@@ -716,4 +716,50 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
             ConstantRange(APInt(32, 0), APInt(32, 1)));
 }
 
+TEST(ConstantRange, GetEquivalentICmp) {
+  APInt RHS;
+  CmpInst::Predicate Pred;
+
+  EXPECT_TRUE(ConstantRange(APInt::getMinValue(32), APInt(32, 100))
+                  .getEquivalentICmp(Pred, RHS));
+  EXPECT_EQ(Pred, CmpInst::ICMP_ULT);
+  EXPECT_EQ(RHS, APInt(32, 100));
+
+  EXPECT_TRUE(ConstantRange(APInt::getSignedMinValue(32), APInt(32, 100))
+                  .getEquivalentICmp(Pred, RHS));
+  EXPECT_EQ(Pred, CmpInst::ICMP_SLT);
+  EXPECT_EQ(RHS, APInt(32, 100));
+
+  EXPECT_TRUE(ConstantRange(APInt(32, 100), APInt::getMinValue(32))
+                  .getEquivalentICmp(Pred, RHS));
+  EXPECT_EQ(Pred, CmpInst::ICMP_UGE);
+  EXPECT_EQ(RHS, APInt(32, 100));
+
+  EXPECT_TRUE(ConstantRange(APInt(32, 100), APInt::getSignedMinValue(32))
+                  .getEquivalentICmp(Pred, RHS));
+  EXPECT_EQ(Pred, CmpInst::ICMP_SGE);
+  EXPECT_EQ(RHS, APInt(32, 100));
+
+  EXPECT_TRUE(
+      ConstantRange(32, /*isFullSet=*/true).getEquivalentICmp(Pred, RHS));
+  EXPECT_EQ(Pred, CmpInst::ICMP_UGE);
+  EXPECT_EQ(RHS, APInt(32, 0));
+
+  EXPECT_TRUE(
+      ConstantRange(32, /*isFullSet=*/false).getEquivalentICmp(Pred, RHS));
+  EXPECT_EQ(Pred, CmpInst::ICMP_ULT);
+  EXPECT_EQ(RHS, APInt(32, 0));
+
+  EXPECT_FALSE(ConstantRange(APInt(32, 100), APInt(32, 200))
+                   .getEquivalentICmp(Pred, RHS));
+
+  EXPECT_FALSE(ConstantRange(APInt::getSignedMinValue(32) - APInt(32, 100),
+                             APInt::getSignedMinValue(32) + APInt(32, 100))
+                   .getEquivalentICmp(Pred, RHS));
+
+  EXPECT_FALSE(ConstantRange(APInt::getMinValue(32) - APInt(32, 100),
+                             APInt::getMinValue(32) + APInt(32, 100))
+                   .getEquivalentICmp(Pred, RHS));
+}
+
 }  // anonymous namespace




More information about the llvm-commits mailing list