diff options
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
| -rw-r--r-- | llvm/lib/IR/ConstantRange.cpp | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp index 4b0ad1bd25a0..0649776dbc22 100644 --- a/llvm/lib/IR/ConstantRange.cpp +++ b/llvm/lib/IR/ConstantRange.cpp @@ -181,6 +181,11 @@ bool ConstantRange::getEquivalentICmp(CmpInst::Predicate &Pred, return Success; } +bool ConstantRange::icmp(CmpInst::Predicate Pred, + const ConstantRange &Other) const { + return makeSatisfyingICmpRegion(Pred, Other).contains(*this); +} + /// Exact mul nuw region for single element RHS. static ConstantRange makeExactMulNUWRegion(const APInt &V) { unsigned BitWidth = V.getBitWidth(); @@ -1058,7 +1063,10 @@ ConstantRange::smax(const ConstantRange &Other) const { return getEmpty(); APInt NewL = APIntOps::smax(getSignedMin(), Other.getSignedMin()); APInt NewU = APIntOps::smax(getSignedMax(), Other.getSignedMax()) + 1; - return getNonEmpty(std::move(NewL), std::move(NewU)); + ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU)); + if (isSignWrappedSet() || Other.isSignWrappedSet()) + return Res.intersectWith(unionWith(Other, Signed), Signed); + return Res; } ConstantRange @@ -1069,7 +1077,10 @@ ConstantRange::umax(const ConstantRange &Other) const { return getEmpty(); APInt NewL = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin()); APInt NewU = APIntOps::umax(getUnsignedMax(), Other.getUnsignedMax()) + 1; - return getNonEmpty(std::move(NewL), std::move(NewU)); + ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU)); + if (isWrappedSet() || Other.isWrappedSet()) + return Res.intersectWith(unionWith(Other, Unsigned), Unsigned); + return Res; } ConstantRange @@ -1080,7 +1091,10 @@ ConstantRange::smin(const ConstantRange &Other) const { return getEmpty(); APInt NewL = APIntOps::smin(getSignedMin(), Other.getSignedMin()); APInt NewU = APIntOps::smin(getSignedMax(), Other.getSignedMax()) + 1; - return getNonEmpty(std::move(NewL), std::move(NewU)); + ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU)); + if (isSignWrappedSet() || Other.isSignWrappedSet()) + return Res.intersectWith(unionWith(Other, Signed), Signed); + return Res; } ConstantRange @@ -1091,7 +1105,10 @@ ConstantRange::umin(const ConstantRange &Other) const { return getEmpty(); APInt NewL = APIntOps::umin(getUnsignedMin(), Other.getUnsignedMin()); APInt NewU = APIntOps::umin(getUnsignedMax(), Other.getUnsignedMax()) + 1; - return getNonEmpty(std::move(NewL), std::move(NewU)); + ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU)); + if (isWrappedSet() || Other.isWrappedSet()) + return Res.intersectWith(unionWith(Other, Unsigned), Unsigned); + return Res; } ConstantRange @@ -1204,6 +1221,15 @@ ConstantRange ConstantRange::urem(const ConstantRange &RHS) const { if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isNullValue()) return getEmpty(); + if (const APInt *RHSInt = RHS.getSingleElement()) { + // UREM by null is UB. + if (RHSInt->isNullValue()) + return getEmpty(); + // Use APInt's implementation of UREM for single element ranges. + if (const APInt *LHSInt = getSingleElement()) + return {LHSInt->urem(*RHSInt)}; + } + // L % R for L < R is L. if (getUnsignedMax().ult(RHS.getUnsignedMin())) return *this; @@ -1217,6 +1243,15 @@ ConstantRange ConstantRange::srem(const ConstantRange &RHS) const { if (isEmptySet() || RHS.isEmptySet()) return getEmpty(); + if (const APInt *RHSInt = RHS.getSingleElement()) { + // SREM by null is UB. + if (RHSInt->isNullValue()) + return getEmpty(); + // Use APInt's implementation of SREM for single element ranges. + if (const APInt *LHSInt = getSingleElement()) + return {LHSInt->srem(*RHSInt)}; + } + ConstantRange AbsRHS = RHS.abs(); APInt MinAbsRHS = AbsRHS.getUnsignedMin(); APInt MaxAbsRHS = AbsRHS.getUnsignedMax(); @@ -1256,12 +1291,6 @@ ConstantRange ConstantRange::srem(const ConstantRange &RHS) const { } ConstantRange ConstantRange::binaryNot() const { - if (isEmptySet()) - return getEmpty(); - - if (isWrappedSet()) - return getFull(); - return ConstantRange(APInt::getAllOnesValue(getBitWidth())).sub(*this); } |
