diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h index 27a9b136444..17c39a6ef9b 100644 --- a/include/llvm/IR/ConstantRange.h +++ b/include/llvm/IR/ConstantRange.h @@ -184,6 +184,10 @@ public: /// APInt getSetSize() const; + /// Compare set size of this range with the range CR. + /// + bool isSizeStrictlySmallerThanOf(const ConstantRange &CR) const; + /// Return the largest unsigned value contained in the ConstantRange. /// APInt getUnsignedMax() const; diff --git a/lib/IR/ConstantRange.cpp b/lib/IR/ConstantRange.cpp index f940955a745..f1826c02979 100644 --- a/lib/IR/ConstantRange.cpp +++ b/lib/IR/ConstantRange.cpp @@ -272,6 +272,22 @@ APInt ConstantRange::getSetSize() const { return (Upper - Lower).zext(getBitWidth()+1); } +/// isSizeStrictlySmallerThanOf - Compare set size of this range with the range +/// CR. +/// This function is faster than comparing results of getSetSize for the two +/// ranges, because we don't need to extend bitwidth of APInts we're operating +/// with. +/// +bool +ConstantRange::isSizeStrictlySmallerThanOf(const ConstantRange &Other) const { + assert(getBitWidth() == Other.getBitWidth()); + if (isFullSet()) + return false; + if (Other.isFullSet()) + return true; + return (Upper - Lower).ult(Other.Upper - Other.Lower); +} + /// getUnsignedMax - Return the largest unsigned value contained in the /// ConstantRange. /// @@ -414,7 +430,7 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const { if (CR.Upper.ule(Lower)) return ConstantRange(CR.Lower, Upper); - if (getSetSize().ult(CR.getSetSize())) + if (isSizeStrictlySmallerThanOf(CR)) return *this; return CR; } @@ -429,7 +445,7 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const { if (CR.Upper.ult(Upper)) { if (CR.Lower.ult(Upper)) { - if (getSetSize().ult(CR.getSetSize())) + if (isSizeStrictlySmallerThanOf(CR)) return *this; return CR; } @@ -445,7 +461,7 @@ ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const { return ConstantRange(CR.Lower, Upper); } - if (getSetSize().ult(CR.getSetSize())) + if (isSizeStrictlySmallerThanOf(CR)) return *this; return CR; } @@ -739,17 +755,16 @@ ConstantRange::add(const ConstantRange &Other) const { if (isFullSet() || Other.isFullSet()) return ConstantRange(getBitWidth(), /*isFullSet=*/true); - APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize(); APInt NewLower = getLower() + Other.getLower(); APInt NewUpper = getUpper() + Other.getUpper() - 1; if (NewLower == NewUpper) return ConstantRange(getBitWidth(), /*isFullSet=*/true); ConstantRange X = ConstantRange(NewLower, NewUpper); - if (X.getSetSize().ult(Spread_X) || X.getSetSize().ult(Spread_Y)) + if (X.isSizeStrictlySmallerThanOf(*this) || + X.isSizeStrictlySmallerThanOf(Other)) // We've wrapped, therefore, full set. return ConstantRange(getBitWidth(), /*isFullSet=*/true); - return X; } @@ -773,17 +788,16 @@ ConstantRange::sub(const ConstantRange &Other) const { if (isFullSet() || Other.isFullSet()) return ConstantRange(getBitWidth(), /*isFullSet=*/true); - APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize(); APInt NewLower = getLower() - Other.getUpper() + 1; APInt NewUpper = getUpper() - Other.getLower(); if (NewLower == NewUpper) return ConstantRange(getBitWidth(), /*isFullSet=*/true); ConstantRange X = ConstantRange(NewLower, NewUpper); - if (X.getSetSize().ult(Spread_X) || X.getSetSize().ult(Spread_Y)) + if (X.isSizeStrictlySmallerThanOf(*this) || + X.isSizeStrictlySmallerThanOf(Other)) // We've wrapped, therefore, full set. return ConstantRange(getBitWidth(), /*isFullSet=*/true); - return X; } @@ -837,7 +851,7 @@ ConstantRange::multiply(const ConstantRange &Other) const { ConstantRange Result_sext(std::min(L, Compare), std::max(L, Compare) + 1); ConstantRange SR = Result_sext.truncate(getBitWidth()); - return UR.getSetSize().ult(SR.getSetSize()) ? UR : SR; + return UR.isSizeStrictlySmallerThanOf(SR) ? UR : SR; } ConstantRange