summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-04-07 20:20:24 +0000
committerNikita Popov <nikita.ppv@gmail.com>2019-04-07 20:20:24 +0000
commitf38b46ffca9b55d476229dce6bca4f3274cffb6d (patch)
tree122253afe36fad0ddc08482ab936168a76b4bf1f /llvm/lib/IR/ConstantRange.cpp
parent424417da79c60c8d67de6b0bb55e9d8404764707 (diff)
downloadbcm5719-llvm-f38b46ffca9b55d476229dce6bca4f3274cffb6d.tar.gz
bcm5719-llvm-f38b46ffca9b55d476229dce6bca4f3274cffb6d.zip
[ConstantRange] Add signed/unsigned unionWith()
This extends D59959 to unionWith(), allowing to specify that a non-wrapping unsigned/signed range is preferred. This is somewhat less useful than the intersect case, because union operations are rarer. An example use would the the phi union computed in SCEV. The implementation is mostly a straightforward use of getPreferredRange(), but I also had to adjust some <=/< checks to make sure that no ranges with lower==upper get constructed before they're passed to getPreferredRange(), as these have additional constraints. Differential Revision: https://reviews.llvm.org/D60377 llvm-svn: 357876
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp38
1 files changed, 20 insertions, 18 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index 80981788eb9..f48fe9f737d 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -593,23 +593,26 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
return getPreferredRange(*this, CR, Type);
}
-ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const {
+ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
+ PreferredRangeType Type) const {
assert(getBitWidth() == CR.getBitWidth() &&
"ConstantRange types don't agree!");
if ( isFullSet() || CR.isEmptySet()) return *this;
if (CR.isFullSet() || isEmptySet()) return CR;
- if (!isUpperWrapped() && CR.isUpperWrapped()) return CR.unionWith(*this);
+ if (!isUpperWrapped() && CR.isUpperWrapped())
+ return CR.unionWith(*this, Type);
if (!isUpperWrapped() && !CR.isUpperWrapped()) {
- 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);
- return ConstantRange(CR.Lower, Upper);
- }
+ // L---U and L---U : this
+ // L---U L---U : CR
+ // result in one of
+ // L---------U
+ // -----U L-----
+ if (CR.Upper.ult(Lower) || Upper.ult(CR.Lower))
+ return getPreferredRange(
+ ConstantRange(Lower, CR.Upper), ConstantRange(CR.Lower, Upper), Type);
APInt L = CR.Lower.ult(Lower) ? CR.Lower : Lower;
APInt U = (CR.Upper - 1).ugt(Upper - 1) ? CR.Upper : Upper;
@@ -633,22 +636,21 @@ ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const {
// ----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))
- return ConstantRange(Lower, CR.Upper);
- return ConstantRange(CR.Lower, Upper);
- }
+ // results in one of
+ // ----------U L----
+ // ----U L----------
+ if (Upper.ult(CR.Lower) && CR.Upper.ult(Lower))
+ return getPreferredRange(
+ ConstantRange(Lower, CR.Upper), ConstantRange(CR.Lower, Upper), Type);
// ----U L----- : this
// L----U : CR
- if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper))
+ if (Upper.ult(CR.Lower) && Lower.ule(CR.Upper))
return ConstantRange(CR.Lower, Upper);
// ------U L---- : this
// L-----U : CR
- assert(CR.Lower.ult(Upper) && CR.Upper.ult(Lower) &&
+ assert(CR.Lower.ule(Upper) && CR.Upper.ult(Lower) &&
"ConstantRange::unionWith missed a case with one range wrapped");
return ConstantRange(Lower, CR.Upper);
}
OpenPOWER on IntegriCloud