Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:57

0001 //===- ConstantRange.h - Represent a range ----------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Represent a range of possible values that may occur when the program is run
0010 // for an integral value.  This keeps track of a lower and upper bound for the
0011 // constant, which MAY wrap around the end of the numeric range.  To do this, it
0012 // keeps track of a [lower, upper) bound, which specifies an interval just like
0013 // STL iterators.  When used with boolean values, the following are important
0014 // ranges: :
0015 //
0016 //  [F, F) = {}     = Empty set
0017 //  [T, F) = {T}
0018 //  [F, T) = {F}
0019 //  [T, T) = {F, T} = Full set
0020 //
0021 // The other integral ranges use min/max values for special range values. For
0022 // example, for 8-bit types, it uses:
0023 // [0, 0)     = {}       = Empty set
0024 // [255, 255) = {0..255} = Full Set
0025 //
0026 // Note that ConstantRange can be used to represent either signed or
0027 // unsigned ranges.
0028 //
0029 //===----------------------------------------------------------------------===//
0030 
0031 #ifndef LLVM_IR_CONSTANTRANGE_H
0032 #define LLVM_IR_CONSTANTRANGE_H
0033 
0034 #include "llvm/ADT/APInt.h"
0035 #include "llvm/IR/InstrTypes.h"
0036 #include "llvm/IR/Instruction.h"
0037 #include "llvm/Support/Compiler.h"
0038 #include <cstdint>
0039 
0040 namespace llvm {
0041 
0042 class MDNode;
0043 class raw_ostream;
0044 struct KnownBits;
0045 
0046 /// This class represents a range of values.
0047 class [[nodiscard]] ConstantRange {
0048   APInt Lower, Upper;
0049 
0050   /// Create empty constant range with same bitwidth.
0051   ConstantRange getEmpty() const {
0052     return ConstantRange(getBitWidth(), false);
0053   }
0054 
0055   /// Create full constant range with same bitwidth.
0056   ConstantRange getFull() const {
0057     return ConstantRange(getBitWidth(), true);
0058   }
0059 
0060 public:
0061   /// Initialize a full or empty set for the specified bit width.
0062   explicit ConstantRange(uint32_t BitWidth, bool isFullSet);
0063 
0064   /// Initialize a range to hold the single specified value.
0065   ConstantRange(APInt Value);
0066 
0067   /// Initialize a range of values explicitly. This will assert out if
0068   /// Lower==Upper and Lower != Min or Max value for its type. It will also
0069   /// assert out if the two APInt's are not the same bit width.
0070   ConstantRange(APInt Lower, APInt Upper);
0071 
0072   /// Create empty constant range with the given bit width.
0073   static ConstantRange getEmpty(uint32_t BitWidth) {
0074     return ConstantRange(BitWidth, false);
0075   }
0076 
0077   /// Create full constant range with the given bit width.
0078   static ConstantRange getFull(uint32_t BitWidth) {
0079     return ConstantRange(BitWidth, true);
0080   }
0081 
0082   /// Create non-empty constant range with the given bounds. If Lower and
0083   /// Upper are the same, a full range is returned.
0084   static ConstantRange getNonEmpty(APInt Lower, APInt Upper) {
0085     if (Lower == Upper)
0086       return getFull(Lower.getBitWidth());
0087     return ConstantRange(std::move(Lower), std::move(Upper));
0088   }
0089 
0090   /// Initialize a range based on a known bits constraint. The IsSigned flag
0091   /// indicates whether the constant range should not wrap in the signed or
0092   /// unsigned domain.
0093   static ConstantRange fromKnownBits(const KnownBits &Known, bool IsSigned);
0094 
0095   /// Produce the smallest range such that all values that may satisfy the given
0096   /// predicate with any value contained within Other is contained in the
0097   /// returned range.  Formally, this returns a superset of
0098   /// 'union over all y in Other . { x : icmp op x y is true }'.  If the exact
0099   /// answer is not representable as a ConstantRange, the return value will be a
0100   /// proper superset of the above.
0101   ///
0102   /// Example: Pred = ult and Other = i8 [2, 5) returns Result = [0, 4)
0103   static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred,
0104                                              const ConstantRange &Other);
0105 
0106   /// Produce the largest range such that all values in the returned range
0107   /// satisfy the given predicate with all values contained within Other.
0108   /// Formally, this returns a subset of
0109   /// 'intersection over all y in Other . { x : icmp op x y is true }'.  If the
0110   /// exact answer is not representable as a ConstantRange, the return value
0111   /// will be a proper subset of the above.
0112   ///
0113   /// Example: Pred = ult and Other = i8 [2, 5) returns [0, 2)
0114   static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred,
0115                                                 const ConstantRange &Other);
0116 
0117   /// Produce the exact range such that all values in the returned range satisfy
0118   /// the given predicate with any value contained within Other. Formally, this
0119   /// returns the exact answer when the superset of 'union over all y in Other
0120   /// is exactly same as the subset of intersection over all y in Other.
0121   /// { x : icmp op x y is true}'.
0122   ///
0123   /// Example: Pred = ult and Other = i8 3 returns [0, 3)
0124   static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred,
0125                                            const APInt &Other);
0126 
0127   /// Does the predicate \p Pred hold between ranges this and \p Other?
0128   /// NOTE: false does not mean that inverse predicate holds!
0129   bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const;
0130 
0131   /// Return true iff CR1 ult CR2 is equivalent to CR1 slt CR2.
0132   /// Does not depend on strictness/direction of the predicate.
0133   static bool
0134   areInsensitiveToSignednessOfICmpPredicate(const ConstantRange &CR1,
0135                                             const ConstantRange &CR2);
0136 
0137   /// Return true iff CR1 ult CR2 is equivalent to CR1 sge CR2.
0138   /// Does not depend on strictness/direction of the predicate.
0139   static bool
0140   areInsensitiveToSignednessOfInvertedICmpPredicate(const ConstantRange &CR1,
0141                                                     const ConstantRange &CR2);
0142 
0143   /// If the comparison between constant ranges this and Other
0144   /// is insensitive to the signedness of the comparison predicate,
0145   /// return a predicate equivalent to \p Pred, with flipped signedness
0146   /// (i.e. unsigned instead of signed or vice versa), and maybe inverted,
0147   /// otherwise returns CmpInst::Predicate::BAD_ICMP_PREDICATE.
0148   static CmpInst::Predicate
0149   getEquivalentPredWithFlippedSignedness(CmpInst::Predicate Pred,
0150                                          const ConstantRange &CR1,
0151                                          const ConstantRange &CR2);
0152 
0153   /// Produce the largest range containing all X such that "X BinOp Y" is
0154   /// guaranteed not to wrap (overflow) for *all* Y in Other. However, there may
0155   /// be *some* Y in Other for which additional X not contained in the result
0156   /// also do not overflow.
0157   ///
0158   /// NoWrapKind must be one of OBO::NoUnsignedWrap or OBO::NoSignedWrap.
0159   ///
0160   /// Examples:
0161   ///  typedef OverflowingBinaryOperator OBO;
0162   ///  #define MGNR makeGuaranteedNoWrapRegion
0163   ///  MGNR(Add, [i8 1, 2), OBO::NoSignedWrap) == [-128, 127)
0164   ///  MGNR(Add, [i8 1, 2), OBO::NoUnsignedWrap) == [0, -1)
0165   ///  MGNR(Add, [i8 0, 1), OBO::NoUnsignedWrap) == Full Set
0166   ///  MGNR(Add, [i8 -1, 6), OBO::NoSignedWrap) == [INT_MIN+1, INT_MAX-4)
0167   ///  MGNR(Sub, [i8 1, 2), OBO::NoSignedWrap) == [-127, 128)
0168   ///  MGNR(Sub, [i8 1, 2), OBO::NoUnsignedWrap) == [1, 0)
0169   static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
0170                                                   const ConstantRange &Other,
0171                                                   unsigned NoWrapKind);
0172 
0173   /// Produce the range that contains X if and only if "X BinOp Other" does
0174   /// not wrap.
0175   static ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp,
0176                                              const APInt &Other,
0177                                              unsigned NoWrapKind);
0178 
0179   /// Initialize a range containing all values X that satisfy `(X & Mask)
0180   /// != C`. Note that the range returned may contain values where `(X & Mask)
0181   /// == C` holds, making it less precise, but still conservative.
0182   static ConstantRange makeMaskNotEqualRange(const APInt &Mask, const APInt &C);
0183 
0184   /// Returns true if ConstantRange calculations are supported for intrinsic
0185   /// with \p IntrinsicID.
0186   static bool isIntrinsicSupported(Intrinsic::ID IntrinsicID);
0187 
0188   /// Compute range of intrinsic result for the given operand ranges.
0189   static ConstantRange intrinsic(Intrinsic::ID IntrinsicID,
0190                                  ArrayRef<ConstantRange> Ops);
0191 
0192   /// Set up \p Pred and \p RHS such that
0193   /// ConstantRange::makeExactICmpRegion(Pred, RHS) == *this.  Return true if
0194   /// successful.
0195   bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const;
0196 
0197   /// Set up \p Pred, \p RHS and \p Offset such that (V + Offset) Pred RHS
0198   /// is true iff V is in the range. Prefers using Offset == 0 if possible.
0199   void
0200   getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS, APInt &Offset) const;
0201 
0202   /// Return the lower value for this range.
0203   const APInt &getLower() const { return Lower; }
0204 
0205   /// Return the upper value for this range.
0206   const APInt &getUpper() const { return Upper; }
0207 
0208   /// Get the bit width of this ConstantRange.
0209   uint32_t getBitWidth() const { return Lower.getBitWidth(); }
0210 
0211   /// Return true if this set contains all of the elements possible
0212   /// for this data-type.
0213   bool isFullSet() const;
0214 
0215   /// Return true if this set contains no members.
0216   bool isEmptySet() const;
0217 
0218   /// Return true if this set wraps around the unsigned domain. Special cases:
0219   ///  * Empty set: Not wrapped.
0220   ///  * Full set: Not wrapped.
0221   ///  * [X, 0) == [X, Max]: Not wrapped.
0222   bool isWrappedSet() const;
0223 
0224   /// Return true if the exclusive upper bound wraps around the unsigned
0225   /// domain. Special cases:
0226   ///  * Empty set: Not wrapped.
0227   ///  * Full set: Not wrapped.
0228   ///  * [X, 0): Wrapped.
0229   bool isUpperWrapped() const;
0230 
0231   /// Return true if this set wraps around the signed domain. Special cases:
0232   ///  * Empty set: Not wrapped.
0233   ///  * Full set: Not wrapped.
0234   ///  * [X, SignedMin) == [X, SignedMax]: Not wrapped.
0235   bool isSignWrappedSet() const;
0236 
0237   /// Return true if the (exclusive) upper bound wraps around the signed
0238   /// domain. Special cases:
0239   ///  * Empty set: Not wrapped.
0240   ///  * Full set: Not wrapped.
0241   ///  * [X, SignedMin): Wrapped.
0242   bool isUpperSignWrapped() const;
0243 
0244   /// Return true if the specified value is in the set.
0245   bool contains(const APInt &Val) const;
0246 
0247   /// Return true if the other range is a subset of this one.
0248   bool contains(const ConstantRange &CR) const;
0249 
0250   /// If this set contains a single element, return it, otherwise return null.
0251   const APInt *getSingleElement() const {
0252     if (Upper == Lower + 1)
0253       return &Lower;
0254     return nullptr;
0255   }
0256 
0257   /// If this set contains all but a single element, return it, otherwise return
0258   /// null.
0259   const APInt *getSingleMissingElement() const {
0260     if (Lower == Upper + 1)
0261       return &Upper;
0262     return nullptr;
0263   }
0264 
0265   /// Return true if this set contains exactly one member.
0266   bool isSingleElement() const { return getSingleElement() != nullptr; }
0267 
0268   /// Compare set size of this range with the range CR.
0269   bool isSizeStrictlySmallerThan(const ConstantRange &CR) const;
0270 
0271   /// Compare set size of this range with Value.
0272   bool isSizeLargerThan(uint64_t MaxSize) const;
0273 
0274   /// Return true if all values in this range are negative.
0275   bool isAllNegative() const;
0276 
0277   /// Return true if all values in this range are non-negative.
0278   bool isAllNonNegative() const;
0279 
0280   /// Return true if all values in this range are positive.
0281   bool isAllPositive() const;
0282 
0283   /// Return the largest unsigned value contained in the ConstantRange.
0284   APInt getUnsignedMax() const;
0285 
0286   /// Return the smallest unsigned value contained in the ConstantRange.
0287   APInt getUnsignedMin() const;
0288 
0289   /// Return the largest signed value contained in the ConstantRange.
0290   APInt getSignedMax() const;
0291 
0292   /// Return the smallest signed value contained in the ConstantRange.
0293   APInt getSignedMin() const;
0294 
0295   /// Return true if this range is equal to another range.
0296   bool operator==(const ConstantRange &CR) const {
0297     return Lower == CR.Lower && Upper == CR.Upper;
0298   }
0299   bool operator!=(const ConstantRange &CR) const {
0300     return !operator==(CR);
0301   }
0302 
0303   /// Compute the maximal number of active bits needed to represent every value
0304   /// in this range.
0305   unsigned getActiveBits() const;
0306 
0307   /// Compute the maximal number of bits needed to represent every value
0308   /// in this signed range.
0309   unsigned getMinSignedBits() const;
0310 
0311   /// Subtract the specified constant from the endpoints of this constant range.
0312   ConstantRange subtract(const APInt &CI) const;
0313 
0314   /// Subtract the specified range from this range (aka relative complement of
0315   /// the sets).
0316   ConstantRange difference(const ConstantRange &CR) const;
0317 
0318   /// If represented precisely, the result of some range operations may consist
0319   /// of multiple disjoint ranges. As only a single range may be returned, any
0320   /// range covering these disjoint ranges constitutes a valid result, but some
0321   /// may be more useful than others depending on context. The preferred range
0322   /// type specifies whether a range that is non-wrapping in the unsigned or
0323   /// signed domain, or has the smallest size, is preferred. If a signedness is
0324   /// preferred but all ranges are non-wrapping or all wrapping, then the
0325   /// smallest set size is preferred. If there are multiple smallest sets, any
0326   /// one of them may be returned.
0327   enum PreferredRangeType { Smallest, Unsigned, Signed };
0328 
0329   /// Return the range that results from the intersection of this range with
0330   /// another range. If the intersection is disjoint, such that two results
0331   /// are possible, the preferred range is determined by the PreferredRangeType.
0332   ConstantRange intersectWith(const ConstantRange &CR,
0333                               PreferredRangeType Type = Smallest) const;
0334 
0335   /// Return the range that results from the union of this range
0336   /// with another range.  The resultant range is guaranteed to include the
0337   /// elements of both sets, but may contain more.  For example, [3, 9) union
0338   /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included
0339   /// in either set before.
0340   ConstantRange unionWith(const ConstantRange &CR,
0341                           PreferredRangeType Type = Smallest) const;
0342 
0343   /// Intersect the two ranges and return the result if it can be represented
0344   /// exactly, otherwise return std::nullopt.
0345   std::optional<ConstantRange>
0346   exactIntersectWith(const ConstantRange &CR) const;
0347 
0348   /// Union the two ranges and return the result if it can be represented
0349   /// exactly, otherwise return std::nullopt.
0350   std::optional<ConstantRange> exactUnionWith(const ConstantRange &CR) const;
0351 
0352   /// Return a new range representing the possible values resulting
0353   /// from an application of the specified cast operator to this range. \p
0354   /// BitWidth is the target bitwidth of the cast.  For casts which don't
0355   /// change bitwidth, it must be the same as the source bitwidth.  For casts
0356   /// which do change bitwidth, the bitwidth must be consistent with the
0357   /// requested cast and source bitwidth.
0358   ConstantRange castOp(Instruction::CastOps CastOp,
0359                        uint32_t BitWidth) const;
0360 
0361   /// Return a new range in the specified integer type, which must
0362   /// be strictly larger than the current type.  The returned range will
0363   /// correspond to the possible range of values if the source range had been
0364   /// zero extended to BitWidth.
0365   ConstantRange zeroExtend(uint32_t BitWidth) const;
0366 
0367   /// Return a new range in the specified integer type, which must
0368   /// be strictly larger than the current type.  The returned range will
0369   /// correspond to the possible range of values if the source range had been
0370   /// sign extended to BitWidth.
0371   ConstantRange signExtend(uint32_t BitWidth) const;
0372 
0373   /// Return a new range in the specified integer type, which must be
0374   /// strictly smaller than the current type.  The returned range will
0375   /// correspond to the possible range of values if the source range had been
0376   /// truncated to the specified type.
0377   ConstantRange truncate(uint32_t BitWidth) const;
0378 
0379   /// Make this range have the bit width given by \p BitWidth. The
0380   /// value is zero extended, truncated, or left alone to make it that width.
0381   ConstantRange zextOrTrunc(uint32_t BitWidth) const;
0382 
0383   /// Make this range have the bit width given by \p BitWidth. The
0384   /// value is sign extended, truncated, or left alone to make it that width.
0385   ConstantRange sextOrTrunc(uint32_t BitWidth) const;
0386 
0387   /// Return a new range representing the possible values resulting
0388   /// from an application of the specified binary operator to an left hand side
0389   /// of this range and a right hand side of \p Other.
0390   ConstantRange binaryOp(Instruction::BinaryOps BinOp,
0391                          const ConstantRange &Other) const;
0392 
0393   /// Return a new range representing the possible values resulting
0394   /// from an application of the specified overflowing binary operator to a
0395   /// left hand side of this range and a right hand side of \p Other given
0396   /// the provided knowledge about lack of wrapping \p NoWrapKind.
0397   ConstantRange overflowingBinaryOp(Instruction::BinaryOps BinOp,
0398                                     const ConstantRange &Other,
0399                                     unsigned NoWrapKind) const;
0400 
0401   /// Return a new range representing the possible values resulting
0402   /// from an addition of a value in this range and a value in \p Other.
0403   ConstantRange add(const ConstantRange &Other) const;
0404 
0405   /// Return a new range representing the possible values resulting
0406   /// from an addition with wrap type \p NoWrapKind of a value in this
0407   /// range and a value in \p Other.
0408   /// If the result range is disjoint, the preferred range is determined by the
0409   /// \p PreferredRangeType.
0410   ConstantRange addWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind,
0411                               PreferredRangeType RangeType = Smallest) const;
0412 
0413   /// Return a new range representing the possible values resulting
0414   /// from a subtraction of a value in this range and a value in \p Other.
0415   ConstantRange sub(const ConstantRange &Other) const;
0416 
0417   /// Return a new range representing the possible values resulting
0418   /// from an subtraction with wrap type \p NoWrapKind of a value in this
0419   /// range and a value in \p Other.
0420   /// If the result range is disjoint, the preferred range is determined by the
0421   /// \p PreferredRangeType.
0422   ConstantRange subWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind,
0423                               PreferredRangeType RangeType = Smallest) const;
0424 
0425   /// Return a new range representing the possible values resulting
0426   /// from a multiplication of a value in this range and a value in \p Other,
0427   /// treating both this and \p Other as unsigned ranges.
0428   ConstantRange multiply(const ConstantRange &Other) const;
0429 
0430   /// Return a new range representing the possible values resulting
0431   /// from a multiplication with wrap type \p NoWrapKind of a value in this
0432   /// range and a value in \p Other.
0433   /// If the result range is disjoint, the preferred range is determined by the
0434   /// \p PreferredRangeType.
0435   ConstantRange
0436   multiplyWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind,
0437                      PreferredRangeType RangeType = Smallest) const;
0438 
0439   /// Return range of possible values for a signed multiplication of this and
0440   /// \p Other. However, if overflow is possible always return a full range
0441   /// rather than trying to determine a more precise result.
0442   ConstantRange smul_fast(const ConstantRange &Other) const;
0443 
0444   /// Return a new range representing the possible values resulting
0445   /// from a signed maximum of a value in this range and a value in \p Other.
0446   ConstantRange smax(const ConstantRange &Other) const;
0447 
0448   /// Return a new range representing the possible values resulting
0449   /// from an unsigned maximum of a value in this range and a value in \p Other.
0450   ConstantRange umax(const ConstantRange &Other) const;
0451 
0452   /// Return a new range representing the possible values resulting
0453   /// from a signed minimum of a value in this range and a value in \p Other.
0454   ConstantRange smin(const ConstantRange &Other) const;
0455 
0456   /// Return a new range representing the possible values resulting
0457   /// from an unsigned minimum of a value in this range and a value in \p Other.
0458   ConstantRange umin(const ConstantRange &Other) const;
0459 
0460   /// Return a new range representing the possible values resulting
0461   /// from an unsigned division of a value in this range and a value in
0462   /// \p Other.
0463   ConstantRange udiv(const ConstantRange &Other) const;
0464 
0465   /// Return a new range representing the possible values resulting
0466   /// from a signed division of a value in this range and a value in
0467   /// \p Other. Division by zero and division of SignedMin by -1 are considered
0468   /// undefined behavior, in line with IR, and do not contribute towards the
0469   /// result.
0470   ConstantRange sdiv(const ConstantRange &Other) const;
0471 
0472   /// Return a new range representing the possible values resulting
0473   /// from an unsigned remainder operation of a value in this range and a
0474   /// value in \p Other.
0475   ConstantRange urem(const ConstantRange &Other) const;
0476 
0477   /// Return a new range representing the possible values resulting
0478   /// from a signed remainder operation of a value in this range and a
0479   /// value in \p Other.
0480   ConstantRange srem(const ConstantRange &Other) const;
0481 
0482   /// Return a new range representing the possible values resulting from
0483   /// a binary-xor of a value in this range by an all-one value,
0484   /// aka bitwise complement operation.
0485   ConstantRange binaryNot() const;
0486 
0487   /// Return a new range representing the possible values resulting
0488   /// from a binary-and of a value in this range by a value in \p Other.
0489   ConstantRange binaryAnd(const ConstantRange &Other) const;
0490 
0491   /// Return a new range representing the possible values resulting
0492   /// from a binary-or of a value in this range by a value in \p Other.
0493   ConstantRange binaryOr(const ConstantRange &Other) const;
0494 
0495   /// Return a new range representing the possible values resulting
0496   /// from a binary-xor of a value in this range by a value in \p Other.
0497   ConstantRange binaryXor(const ConstantRange &Other) const;
0498 
0499   /// Return a new range representing the possible values resulting
0500   /// from a left shift of a value in this range by a value in \p Other.
0501   /// TODO: This isn't fully implemented yet.
0502   ConstantRange shl(const ConstantRange &Other) const;
0503 
0504   /// Return a new range representing the possible values resulting
0505   /// from a left shift with wrap type \p NoWrapKind of a value in this
0506   /// range and a value in \p Other.
0507   /// If the result range is disjoint, the preferred range is determined by the
0508   /// \p PreferredRangeType.
0509   ConstantRange shlWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind,
0510                               PreferredRangeType RangeType = Smallest) const;
0511 
0512   /// Return a new range representing the possible values resulting from a
0513   /// logical right shift of a value in this range and a value in \p Other.
0514   ConstantRange lshr(const ConstantRange &Other) const;
0515 
0516   /// Return a new range representing the possible values resulting from a
0517   /// arithmetic right shift of a value in this range and a value in \p Other.
0518   ConstantRange ashr(const ConstantRange &Other) const;
0519 
0520   /// Perform an unsigned saturating addition of two constant ranges.
0521   ConstantRange uadd_sat(const ConstantRange &Other) const;
0522 
0523   /// Perform a signed saturating addition of two constant ranges.
0524   ConstantRange sadd_sat(const ConstantRange &Other) const;
0525 
0526   /// Perform an unsigned saturating subtraction of two constant ranges.
0527   ConstantRange usub_sat(const ConstantRange &Other) const;
0528 
0529   /// Perform a signed saturating subtraction of two constant ranges.
0530   ConstantRange ssub_sat(const ConstantRange &Other) const;
0531 
0532   /// Perform an unsigned saturating multiplication of two constant ranges.
0533   ConstantRange umul_sat(const ConstantRange &Other) const;
0534 
0535   /// Perform a signed saturating multiplication of two constant ranges.
0536   ConstantRange smul_sat(const ConstantRange &Other) const;
0537 
0538   /// Perform an unsigned saturating left shift of this constant range by a
0539   /// value in \p Other.
0540   ConstantRange ushl_sat(const ConstantRange &Other) const;
0541 
0542   /// Perform a signed saturating left shift of this constant range by a
0543   /// value in \p Other.
0544   ConstantRange sshl_sat(const ConstantRange &Other) const;
0545 
0546   /// Return a new range that is the logical not of the current set.
0547   ConstantRange inverse() const;
0548 
0549   /// Calculate absolute value range. If the original range contains signed
0550   /// min, then the resulting range will contain signed min if and only if
0551   /// \p IntMinIsPoison is false.
0552   ConstantRange abs(bool IntMinIsPoison = false) const;
0553 
0554   /// Calculate ctlz range. If \p ZeroIsPoison is set, the range is computed
0555   /// ignoring a possible zero value contained in the input range.
0556   ConstantRange ctlz(bool ZeroIsPoison = false) const;
0557 
0558   /// Calculate cttz range. If \p ZeroIsPoison is set, the range is computed
0559   /// ignoring a possible zero value contained in the input range.
0560   ConstantRange cttz(bool ZeroIsPoison = false) const;
0561 
0562   /// Calculate ctpop range.
0563   ConstantRange ctpop() const;
0564 
0565   /// Represents whether an operation on the given constant range is known to
0566   /// always or never overflow.
0567   enum class OverflowResult {
0568     /// Always overflows in the direction of signed/unsigned min value.
0569     AlwaysOverflowsLow,
0570     /// Always overflows in the direction of signed/unsigned max value.
0571     AlwaysOverflowsHigh,
0572     /// May or may not overflow.
0573     MayOverflow,
0574     /// Never overflows.
0575     NeverOverflows,
0576   };
0577 
0578   /// Return whether unsigned add of the two ranges always/never overflows.
0579   OverflowResult unsignedAddMayOverflow(const ConstantRange &Other) const;
0580 
0581   /// Return whether signed add of the two ranges always/never overflows.
0582   OverflowResult signedAddMayOverflow(const ConstantRange &Other) const;
0583 
0584   /// Return whether unsigned sub of the two ranges always/never overflows.
0585   OverflowResult unsignedSubMayOverflow(const ConstantRange &Other) const;
0586 
0587   /// Return whether signed sub of the two ranges always/never overflows.
0588   OverflowResult signedSubMayOverflow(const ConstantRange &Other) const;
0589 
0590   /// Return whether unsigned mul of the two ranges always/never overflows.
0591   OverflowResult unsignedMulMayOverflow(const ConstantRange &Other) const;
0592 
0593   /// Return known bits for values in this range.
0594   KnownBits toKnownBits() const;
0595 
0596   /// Print out the bounds to a stream.
0597   void print(raw_ostream &OS) const;
0598 
0599   /// Allow printing from a debugger easily.
0600   void dump() const;
0601 };
0602 
0603 inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) {
0604   CR.print(OS);
0605   return OS;
0606 }
0607 
0608 /// Parse out a conservative ConstantRange from !range metadata.
0609 ///
0610 /// E.g. if RangeMD is !{i32 0, i32 10, i32 15, i32 20} then return [0, 20).
0611 ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD);
0612 
0613 } // end namespace llvm
0614 
0615 #endif // LLVM_IR_CONSTANTRANGE_H