1c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===- ConstantRange.h - Represent a range ----------------------*- C++ -*-===// 2c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 3c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// The LLVM Compiler Infrastructure 4c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 5c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This file is distributed under the University of Illinois Open Source 6c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// License. See LICENSE.TXT for details. 7c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 8c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===// 9c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 10c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// Represent a range of possible values that may occur when the program is run 11c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// for an integral value. This keeps track of a lower and upper bound for the 12c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// constant, which MAY wrap around the end of the numeric range. To do this, it 13c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// keeps track of a [lower, upper) bound, which specifies an interval just like 14c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// STL iterators. When used with boolean values, the following are important 15c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// ranges: : 16c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 17c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// [F, F) = {} = Empty set 18c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// [T, F) = {T} 19c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// [F, T) = {F} 20c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// [T, T) = {F, T} = Full set 21c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 22c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// The other integral ranges use min/max values for special range values. For 23c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// example, for 8-bit types, it uses: 24c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// [0, 0) = {} = Empty set 25c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// [255, 255) = {0..255} = Full Set 26c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 27c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// Note that ConstantRange can be used to represent either signed or 28c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// unsigned ranges. 29c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// 30c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===// 31c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 32c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#ifndef LLVM_IR_CONSTANTRANGE_H 33c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#define LLVM_IR_CONSTANTRANGE_H 34c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 35c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/APInt.h" 36c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/InstrTypes.h" 37c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/IR/Instruction.h" 38c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/Compiler.h" 39c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cstdint> 40c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 41c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotnamespace llvm { 42c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 43c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass MDNode; 44c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass raw_ostream; 45c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 46c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This class represents a range of values. 47c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass LLVM_NODISCARD ConstantRange { 48c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot APInt Lower, Upper; 49c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 50c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic: 51c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Initialize a full (the default) or empty set for the specified bit width. 52c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true); 53c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 54c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Initialize a range to hold the single specified value. 55c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange(APInt Value); 56c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 57c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// @brief Initialize a range of values explicitly. This will assert out if 58c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Lower==Upper and Lower != Min or Max value for its type. It will also 59c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// assert out if the two APInt's are not the same bit width. 60c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange(APInt Lower, APInt Upper); 61c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 62c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Produce the smallest range such that all values that may satisfy the given 63c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// predicate with any value contained within Other is contained in the 64c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// returned range. Formally, this returns a superset of 65c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 'union over all y in Other . { x : icmp op x y is true }'. If the exact 66c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// answer is not representable as a ConstantRange, the return value will be a 67c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// proper superset of the above. 68c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 69c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Example: Pred = ult and Other = i8 [2, 5) returns Result = [0, 4) 70c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, 71c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ConstantRange &Other); 72c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 73c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Produce the largest range such that all values in the returned range 74c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// satisfy the given predicate with all values contained within Other. 75c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Formally, this returns a subset of 76c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 'intersection over all y in Other . { x : icmp op x y is true }'. If the 77c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// exact answer is not representable as a ConstantRange, the return value 78c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// will be a proper subset of the above. 79c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 80c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Example: Pred = ult and Other = i8 [2, 5) returns [0, 2) 81c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred, 82c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ConstantRange &Other); 83c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 84c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Produce the exact range such that all values in the returned range satisfy 85c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the given predicate with any value contained within Other. Formally, this 86c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// returns the exact answer when the superset of 'union over all y in Other 87c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// is exactly same as the subset of intersection over all y in Other. 88c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// { x : icmp op x y is true}'. 89c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 90c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Example: Pred = ult and Other = i8 3 returns [0, 3) 91c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, 92c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const APInt &Other); 93c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 94c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the largest range containing all X such that "X BinOpC Y" is 95c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// guaranteed not to wrap (overflow) for all Y in Other. 96c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 97c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// NB! The returned set does *not* contain **all** possible values of X for 98c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// which "X BinOpC Y" does not wrap -- some viable values of X may be 99c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// missing, so you cannot use this to constrain X's range. E.g. in the 100c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// fourth example, "(-2) + 1" is both nsw and nuw (so the "X" could be -2), 101c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// but (-2) is not in the set returned. 102c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// 103c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Examples: 104c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// typedef OverflowingBinaryOperator OBO; 105c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// #define MGNR makeGuaranteedNoWrapRegion 106c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// MGNR(Add, [i8 1, 2), OBO::NoSignedWrap) == [-128, 127) 107c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// MGNR(Add, [i8 1, 2), OBO::NoUnsignedWrap) == [0, -1) 108c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// MGNR(Add, [i8 0, 1), OBO::NoUnsignedWrap) == Full Set 109c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// MGNR(Add, [i8 1, 2), OBO::NoUnsignedWrap | OBO::NoSignedWrap) 110c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// == [0,INT_MAX) 111c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// MGNR(Add, [i8 -1, 6), OBO::NoSignedWrap) == [INT_MIN+1, INT_MAX-4) 112c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// MGNR(Sub, [i8 1, 2), OBO::NoSignedWrap) == [-127, 128) 113c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// MGNR(Sub, [i8 1, 2), OBO::NoUnsignedWrap) == [1, 0) 114c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// MGNR(Sub, [i8 1, 2), OBO::NoUnsignedWrap | OBO::NoSignedWrap) 115c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// == [1,INT_MAX) 116c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp, 117c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ConstantRange &Other, 118c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot unsigned NoWrapKind); 119c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 120c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Set up \p Pred and \p RHS such that 121c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// ConstantRange::makeExactICmpRegion(Pred, RHS) == *this. Return true if 122c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// successful. 123c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const; 124c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 125c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the lower value for this range. 126c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const APInt &getLower() const { return Lower; } 127c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 128c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the upper value for this range. 129c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const APInt &getUpper() const { return Upper; } 130c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 131c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Get the bit width of this ConstantRange. 132c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot uint32_t getBitWidth() const { return Lower.getBitWidth(); } 133c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 134c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if this set contains all of the elements possible 135c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// for this data-type. 136c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isFullSet() const; 137c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 138c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if this set contains no members. 139c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isEmptySet() const; 140c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 141c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if this set wraps around the top of the range. 142c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// For example: [100, 8). 143c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isWrappedSet() const; 144c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 145c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if this set wraps around the INT_MIN of 146c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// its bitwidth. For example: i8 [120, 140). 147c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isSignWrappedSet() const; 148c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 149c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the specified value is in the set. 150c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool contains(const APInt &Val) const; 151c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 152c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if the other range is a subset of this one. 153c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool contains(const ConstantRange &CR) const; 154c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 155c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If this set contains a single element, return it, otherwise return null. 156c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const APInt *getSingleElement() const { 157c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (Upper == Lower + 1) 158c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return &Lower; 159c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return nullptr; 160c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 161c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 162c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// If this set contains all but a single element, return it, otherwise return 163c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// null. 164c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const APInt *getSingleMissingElement() const { 165c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot if (Lower == Upper + 1) 166c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return &Upper; 167c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return nullptr; 168c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 169c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 170c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if this set contains exactly one member. 171c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isSingleElement() const { return getSingleElement() != nullptr; } 172c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 173c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the number of elements in this set. 174c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot APInt getSetSize() const; 175c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 176c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Compare set size of this range with the range CR. 177c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isSizeStrictlySmallerThan(const ConstantRange &CR) const; 178c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 179c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot // Compare set size of this range with Value. 180c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool isSizeLargerThan(uint64_t MaxSize) const; 181c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 182c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the largest unsigned value contained in the ConstantRange. 183c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot APInt getUnsignedMax() const; 184c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 185c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the smallest unsigned value contained in the ConstantRange. 186c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot APInt getUnsignedMin() const; 187c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 188c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the largest signed value contained in the ConstantRange. 189c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot APInt getSignedMax() const; 190c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 191c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the smallest signed value contained in the ConstantRange. 192c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot APInt getSignedMin() const; 193c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 194c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return true if this range is equal to another range. 195c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool operator==(const ConstantRange &CR) const { 196c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return Lower == CR.Lower && Upper == CR.Upper; 197c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 198c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot bool operator!=(const ConstantRange &CR) const { 199c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return !operator==(CR); 200c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot } 201c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 202c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Subtract the specified constant from the endpoints of this constant range. 203c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange subtract(const APInt &CI) const; 204c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 205c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Subtract the specified range from this range (aka relative complement of 206c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// the sets). 207c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange difference(const ConstantRange &CR) const; 208c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 209c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the range that results from the intersection of 210c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// this range with another range. The resultant range is guaranteed to 211c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// include all elements contained in both input ranges, and to have the 212c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// smallest possible set size that does so. Because there may be two 213c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// intersections with the same set size, A.intersectWith(B) might not 214c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// be equal to B.intersectWith(A). 215c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange intersectWith(const ConstantRange &CR) const; 216c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 217c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return the range that results from the union of this range 218c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// with another range. The resultant range is guaranteed to include the 219c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// elements of both sets, but may contain more. For example, [3, 9) union 220c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included 221c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// in either set before. 222c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange unionWith(const ConstantRange &CR) const; 223c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 224c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 225c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from an application of the specified cast operator to this range. \p 226c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// BitWidth is the target bitwidth of the cast. For casts which don't 227c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// change bitwidth, it must be the same as the source bitwidth. For casts 228c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// which do change bitwidth, the bitwidth must be consistent with the 229c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// requested cast and source bitwidth. 230c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange castOp(Instruction::CastOps CastOp, 231c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot uint32_t BitWidth) const; 232c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 233c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range in the specified integer type, which must 234c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// be strictly larger than the current type. The returned range will 235c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// correspond to the possible range of values if the source range had been 236c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// zero extended to BitWidth. 237c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange zeroExtend(uint32_t BitWidth) const; 238c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 239c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range in the specified integer type, which must 240c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// be strictly larger than the current type. The returned range will 241c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// correspond to the possible range of values if the source range had been 242c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// sign extended to BitWidth. 243c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange signExtend(uint32_t BitWidth) const; 244c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 245c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range in the specified integer type, which must be 246c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// strictly smaller than the current type. The returned range will 247c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// correspond to the possible range of values if the source range had been 248c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// truncated to the specified type. 249c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange truncate(uint32_t BitWidth) const; 250c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 251c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Make this range have the bit width given by \p BitWidth. The 252c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// value is zero extended, truncated, or left alone to make it that width. 253c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange zextOrTrunc(uint32_t BitWidth) const; 254c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 255c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Make this range have the bit width given by \p BitWidth. The 256c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// value is sign extended, truncated, or left alone to make it that width. 257c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange sextOrTrunc(uint32_t BitWidth) const; 258c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 259c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 260c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from an application of the specified binary operator to an left hand side 261c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// of this range and a right hand side of \p Other. 262c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange binaryOp(Instruction::BinaryOps BinOp, 263c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot const ConstantRange &Other) const; 264c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 265c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 266c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from an addition of a value in this range and a value in \p Other. 267c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange add(const ConstantRange &Other) const; 268c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 269c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting from a 270c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// known NSW addition of a value in this range and \p Other constant. 271c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange addWithNoSignedWrap(const APInt &Other) const; 272c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 273c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 274c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from a subtraction of a value in this range and a value in \p Other. 275c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange sub(const ConstantRange &Other) const; 276c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 277c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 278c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from a multiplication of a value in this range and a value in \p Other, 279c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// treating both this and \p Other as unsigned ranges. 280c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange multiply(const ConstantRange &Other) const; 281c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 282c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 283c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from a signed maximum of a value in this range and a value in \p Other. 284c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange smax(const ConstantRange &Other) const; 285c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 286c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 287c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from an unsigned maximum of a value in this range and a value in \p Other. 288c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange umax(const ConstantRange &Other) const; 289c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 290c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 291c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from a signed minimum of a value in this range and a value in \p Other. 292c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange smin(const ConstantRange &Other) const; 293c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 294c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 295c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from an unsigned minimum of a value in this range and a value in \p Other. 296c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange umin(const ConstantRange &Other) const; 297c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 298c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 299c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from an unsigned division of a value in this range and a value in 300c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// \p Other. 301c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange udiv(const ConstantRange &Other) const; 302c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 303c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 304c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from a binary-and of a value in this range by a value in \p Other. 305c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange binaryAnd(const ConstantRange &Other) const; 306c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 307c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 308c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from a binary-or of a value in this range by a value in \p Other. 309c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange binaryOr(const ConstantRange &Other) const; 310c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 311c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting 312c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// from a left shift of a value in this range by a value in \p Other. 313c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// TODO: This isn't fully implemented yet. 314c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange shl(const ConstantRange &Other) const; 315c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 316c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range representing the possible values resulting from a 317c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// logical right shift of a value in this range and a value in \p Other. 318c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange lshr(const ConstantRange &Other) const; 319c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 320c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Return a new range that is the logical not of the current set. 321c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot ConstantRange inverse() const; 322c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 323c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Print out the bounds to a stream. 324c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void print(raw_ostream &OS) const; 325c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 326c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot /// Allow printing from a debugger easily. 327c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot void dump() const; 328c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot}; 329c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 330c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotinline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) { 331c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot CR.print(OS); 332c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot return OS; 333c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} 334c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 335c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Parse out a conservative ConstantRange from !range metadata. 336c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// 337c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// E.g. if RangeMD is !{i32 0, i32 10, i32 15, i32 20} then return [0, 20). 338c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team RobotConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD); 339c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 340c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} // end namespace llvm 341c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot 342c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#endif // LLVM_IR_CONSTANTRANGE_H 343