summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp78
1 files changed, 65 insertions, 13 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index d048b8c2ed5..80981788eb9 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -467,7 +467,28 @@ ConstantRange ConstantRange::difference(const ConstantRange &CR) const {
return intersectWith(CR.inverse());
}
-ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const {
+static ConstantRange getPreferredRange(
+ const ConstantRange &CR1, const ConstantRange &CR2,
+ ConstantRange::PreferredRangeType Type) {
+ if (Type == ConstantRange::Unsigned) {
+ if (!CR1.isWrappedSet() && CR2.isWrappedSet())
+ return CR1;
+ if (CR1.isWrappedSet() && !CR2.isWrappedSet())
+ return CR2;
+ } else if (Type == ConstantRange::Signed) {
+ if (!CR1.isSignWrappedSet() && CR2.isSignWrappedSet())
+ return CR1;
+ if (CR1.isSignWrappedSet() && !CR2.isSignWrappedSet())
+ return CR2;
+ }
+
+ if (CR1.isSizeStrictlySmallerThan(CR2))
+ return CR1;
+ return CR2;
+}
+
+ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
+ PreferredRangeType Type) const {
assert(getBitWidth() == CR.getBitWidth() &&
"ConstantRange types don't agree!");
@@ -476,69 +497,100 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const {
if (CR.isEmptySet() || isFullSet()) return CR;
if (!isUpperWrapped() && CR.isUpperWrapped())
- return CR.intersectWith(*this);
+ return CR.intersectWith(*this, Type);
if (!isUpperWrapped() && !CR.isUpperWrapped()) {
if (Lower.ult(CR.Lower)) {
+ // L---U : this
+ // L---U : CR
if (Upper.ule(CR.Lower))
return getEmpty();
+ // L---U : this
+ // L---U : CR
if (Upper.ult(CR.Upper))
return ConstantRange(CR.Lower, Upper);
+ // L-------U : this
+ // L---U : CR
return CR;
}
+ // L---U : this
+ // L-------U : CR
if (Upper.ult(CR.Upper))
return *this;
+ // L-----U : this
+ // L-----U : CR
if (Lower.ult(CR.Upper))
return ConstantRange(Lower, CR.Upper);
+ // L---U : this
+ // L---U : CR
return getEmpty();
}
if (isUpperWrapped() && !CR.isUpperWrapped()) {
if (CR.Lower.ult(Upper)) {
+ // ------U L--- : this
+ // L--U : CR
if (CR.Upper.ult(Upper))
return CR;
+ // ------U L--- : this
+ // L------U : CR
if (CR.Upper.ule(Lower))
return ConstantRange(CR.Lower, Upper);
- if (isSizeStrictlySmallerThan(CR))
- return *this;
- return CR;
+ // ------U L--- : this
+ // L----------U : CR
+ return getPreferredRange(*this, CR, Type);
}
if (CR.Lower.ult(Lower)) {
+ // --U L---- : this
+ // L--U : CR
if (CR.Upper.ule(Lower))
return getEmpty();
+ // --U L---- : this
+ // L------U : CR
return ConstantRange(Lower, CR.Upper);
}
+
+ // --U L------ : this
+ // L--U : CR
return CR;
}
if (CR.Upper.ult(Upper)) {
- if (CR.Lower.ult(Upper)) {
- if (isSizeStrictlySmallerThan(CR))
- return *this;
- return CR;
- }
+ // ------U L-- : this
+ // --U L------ : CR
+ if (CR.Lower.ult(Upper))
+ return getPreferredRange(*this, CR, Type);
+ // ----U L-- : this
+ // --U L---- : CR
if (CR.Lower.ult(Lower))
return ConstantRange(Lower, CR.Upper);
+ // ----U L---- : this
+ // --U L-- : CR
return CR;
}
if (CR.Upper.ule(Lower)) {
+ // --U L-- : this
+ // ----U L---- : CR
if (CR.Lower.ult(Lower))
return *this;
+ // --U L---- : this
+ // ----U L-- : CR
return ConstantRange(CR.Lower, Upper);
}
- if (isSizeStrictlySmallerThan(CR))
- return *this;
- return CR;
+
+ // --U L------ : this
+ // ------U L-- : CR
+ return getPreferredRange(*this, CR, Type);
}
ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const {
OpenPOWER on IntegriCloud