summaryrefslogtreecommitdiff
path: root/lib/Support/ConstantRange.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2009-07-11 06:15:39 +0000
committerNick Lewycky <nicholas@mxc.ca>2009-07-11 06:15:39 +0000
commitbf8c7f0adf90c8271c790be9922a2f97d19d4c01 (patch)
treeb84d8f3e90e0792979e903143e8d348386694c98 /lib/Support/ConstantRange.cpp
parent8955e93b1ffa7645beea0b51e4b091b96063f613 (diff)
downloadllvm-bf8c7f0adf90c8271c790be9922a2f97d19d4c01.tar.gz
llvm-bf8c7f0adf90c8271c790be9922a2f97d19d4c01.tar.bz2
llvm-bf8c7f0adf90c8271c790be9922a2f97d19d4c01.tar.xz
Move a method that creates constant ranges relative to another constant range
per icmp predicate out of predsimplify and into ConstantRange. Add another utility method that determines whether one range is a subset of another. Combine with the former to determine whether icmp pred range, range is known to be true or not. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75357 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/ConstantRange.cpp')
-rw-r--r--lib/Support/ConstantRange.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp
index 809a024115..e04272348d 100644
--- a/lib/Support/ConstantRange.cpp
+++ b/lib/Support/ConstantRange.cpp
@@ -23,6 +23,7 @@
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Instructions.h"
using namespace llvm;
/// Initialize a full (the default) or empty set for the specified type.
@@ -46,6 +47,53 @@ ConstantRange::ConstantRange(const APInt &L, const APInt &U) :
"Lower == Upper, but they aren't min or max value!");
}
+ConstantRange ConstantRange::makeICmpRegion(unsigned Pred,
+ const ConstantRange &CR) {
+ uint32_t W = CR.getBitWidth();
+ switch (Pred) {
+ default: assert(!"Invalid ICmp predicate to makeICmpRegion()");
+ case ICmpInst::ICMP_EQ:
+ return ConstantRange(CR.getLower(), CR.getUpper());
+ case ICmpInst::ICMP_NE:
+ if (CR.isSingleElement())
+ return ConstantRange(CR.getUpper(), CR.getLower());
+ return ConstantRange(W);
+ case ICmpInst::ICMP_ULT:
+ return ConstantRange(APInt::getMinValue(W), CR.getUnsignedMax());
+ case ICmpInst::ICMP_SLT:
+ return ConstantRange(APInt::getSignedMinValue(W), CR.getSignedMax());
+ case ICmpInst::ICMP_ULE: {
+ APInt UMax(CR.getUnsignedMax());
+ if (UMax.isMaxValue())
+ return ConstantRange(W);
+ return ConstantRange(APInt::getMinValue(W), UMax + 1);
+ }
+ case ICmpInst::ICMP_SLE: {
+ APInt SMax(CR.getSignedMax());
+ if (SMax.isMaxSignedValue() || (SMax+1).isMaxSignedValue())
+ return ConstantRange(W);
+ return ConstantRange(APInt::getSignedMinValue(W), SMax + 1);
+ }
+ case ICmpInst::ICMP_UGT:
+ return ConstantRange(CR.getUnsignedMin() + 1, APInt::getNullValue(W));
+ case ICmpInst::ICMP_SGT:
+ return ConstantRange(CR.getSignedMin() + 1,
+ APInt::getSignedMinValue(W));
+ case ICmpInst::ICMP_UGE: {
+ APInt UMin(CR.getUnsignedMin());
+ if (UMin.isMinValue())
+ return ConstantRange(W);
+ return ConstantRange(UMin, APInt::getNullValue(W));
+ }
+ case ICmpInst::ICMP_SGE: {
+ APInt SMin(CR.getSignedMin());
+ if (SMin.isMinSignedValue())
+ return ConstantRange(W);
+ return ConstantRange(SMin, APInt::getSignedMinValue(W));
+ }
+ }
+}
+
/// isFullSet - Return true if this set contains all of the elements possible
/// for this data-type
bool ConstantRange::isFullSet() const {
@@ -156,6 +204,30 @@ bool ConstantRange::contains(const APInt &V) const {
return Lower.ule(V) || V.ult(Upper);
}
+/// contains - Return true if the argument is a subset of this range.
+/// Two equal set contain each other. The empty set is considered to be
+/// contained by all other sets.
+///
+bool ConstantRange::contains(const ConstantRange &Other) const {
+ if (isFullSet()) return true;
+ if (Other.isFullSet()) return false;
+ if (Other.isEmptySet()) return true;
+ if (isEmptySet()) return false;
+
+ if (!isWrappedSet()) {
+ if (Other.isWrappedSet())
+ return false;
+
+ return Lower.ule(Other.getLower()) && Other.getUpper().ule(Upper);
+ }
+
+ if (!Other.isWrappedSet())
+ return Other.getUpper().ule(Upper) ||
+ Lower.ule(Other.getLower());
+
+ return Other.getUpper().ule(Upper) && Lower.ule(Other.getLower());
+}
+
/// subtract - Subtract the specified constant from the endpoints of this
/// constant range.
ConstantRange ConstantRange::subtract(const APInt &Val) const {