Index: llvm/trunk/include/llvm/IR/ConstantRange.h =================================================================== --- llvm/trunk/include/llvm/IR/ConstantRange.h +++ llvm/trunk/include/llvm/IR/ConstantRange.h @@ -184,6 +184,10 @@ /// 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; Index: llvm/trunk/lib/IR/ConstantRange.cpp =================================================================== --- llvm/trunk/lib/IR/ConstantRange.cpp +++ llvm/trunk/lib/IR/ConstantRange.cpp @@ -272,6 +272,22 @@ 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 @@ 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 @@ 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 @@ return ConstantRange(CR.Lower, Upper); } - if (getSetSize().ult(CR.getSetSize())) + if (isSizeStrictlySmallerThanOf(CR)) return *this; return CR; } @@ -739,17 +755,16 @@ 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 @@ 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 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