1*9880d681SAndroid Build Coastguard Worker //===-- ConstantRange.cpp - ConstantRange implementation ------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Represent a range of possible values that may occur when the program is run
11*9880d681SAndroid Build Coastguard Worker // for an integral value. This keeps track of a lower and upper bound for the
12*9880d681SAndroid Build Coastguard Worker // constant, which MAY wrap around the end of the numeric range. To do this, it
13*9880d681SAndroid Build Coastguard Worker // keeps track of a [lower, upper) bound, which specifies an interval just like
14*9880d681SAndroid Build Coastguard Worker // STL iterators. When used with boolean values, the following are important
15*9880d681SAndroid Build Coastguard Worker // ranges (other integral ranges use min/max values for special range values):
16*9880d681SAndroid Build Coastguard Worker //
17*9880d681SAndroid Build Coastguard Worker // [F, F) = {} = Empty set
18*9880d681SAndroid Build Coastguard Worker // [T, F) = {T}
19*9880d681SAndroid Build Coastguard Worker // [F, T) = {F}
20*9880d681SAndroid Build Coastguard Worker // [T, T) = {F, T} = Full set
21*9880d681SAndroid Build Coastguard Worker //
22*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instruction.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/InstrTypes.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Operator.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/ConstantRange.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
30*9880d681SAndroid Build Coastguard Worker using namespace llvm;
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker /// Initialize a full (the default) or empty set for the specified type.
33*9880d681SAndroid Build Coastguard Worker ///
ConstantRange(uint32_t BitWidth,bool Full)34*9880d681SAndroid Build Coastguard Worker ConstantRange::ConstantRange(uint32_t BitWidth, bool Full) {
35*9880d681SAndroid Build Coastguard Worker if (Full)
36*9880d681SAndroid Build Coastguard Worker Lower = Upper = APInt::getMaxValue(BitWidth);
37*9880d681SAndroid Build Coastguard Worker else
38*9880d681SAndroid Build Coastguard Worker Lower = Upper = APInt::getMinValue(BitWidth);
39*9880d681SAndroid Build Coastguard Worker }
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker /// Initialize a range to hold the single specified value.
42*9880d681SAndroid Build Coastguard Worker ///
ConstantRange(APIntMoveTy V)43*9880d681SAndroid Build Coastguard Worker ConstantRange::ConstantRange(APIntMoveTy V)
44*9880d681SAndroid Build Coastguard Worker : Lower(std::move(V)), Upper(Lower + 1) {}
45*9880d681SAndroid Build Coastguard Worker
ConstantRange(APIntMoveTy L,APIntMoveTy U)46*9880d681SAndroid Build Coastguard Worker ConstantRange::ConstantRange(APIntMoveTy L, APIntMoveTy U)
47*9880d681SAndroid Build Coastguard Worker : Lower(std::move(L)), Upper(std::move(U)) {
48*9880d681SAndroid Build Coastguard Worker assert(Lower.getBitWidth() == Upper.getBitWidth() &&
49*9880d681SAndroid Build Coastguard Worker "ConstantRange with unequal bit widths");
50*9880d681SAndroid Build Coastguard Worker assert((Lower != Upper || (Lower.isMaxValue() || Lower.isMinValue())) &&
51*9880d681SAndroid Build Coastguard Worker "Lower == Upper, but they aren't min or max value!");
52*9880d681SAndroid Build Coastguard Worker }
53*9880d681SAndroid Build Coastguard Worker
makeAllowedICmpRegion(CmpInst::Predicate Pred,const ConstantRange & CR)54*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::makeAllowedICmpRegion(CmpInst::Predicate Pred,
55*9880d681SAndroid Build Coastguard Worker const ConstantRange &CR) {
56*9880d681SAndroid Build Coastguard Worker if (CR.isEmptySet())
57*9880d681SAndroid Build Coastguard Worker return CR;
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker uint32_t W = CR.getBitWidth();
60*9880d681SAndroid Build Coastguard Worker switch (Pred) {
61*9880d681SAndroid Build Coastguard Worker default:
62*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid ICmp predicate to makeAllowedICmpRegion()");
63*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_EQ:
64*9880d681SAndroid Build Coastguard Worker return CR;
65*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_NE:
66*9880d681SAndroid Build Coastguard Worker if (CR.isSingleElement())
67*9880d681SAndroid Build Coastguard Worker return ConstantRange(CR.getUpper(), CR.getLower());
68*9880d681SAndroid Build Coastguard Worker return ConstantRange(W);
69*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_ULT: {
70*9880d681SAndroid Build Coastguard Worker APInt UMax(CR.getUnsignedMax());
71*9880d681SAndroid Build Coastguard Worker if (UMax.isMinValue())
72*9880d681SAndroid Build Coastguard Worker return ConstantRange(W, /* empty */ false);
73*9880d681SAndroid Build Coastguard Worker return ConstantRange(APInt::getMinValue(W), UMax);
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_SLT: {
76*9880d681SAndroid Build Coastguard Worker APInt SMax(CR.getSignedMax());
77*9880d681SAndroid Build Coastguard Worker if (SMax.isMinSignedValue())
78*9880d681SAndroid Build Coastguard Worker return ConstantRange(W, /* empty */ false);
79*9880d681SAndroid Build Coastguard Worker return ConstantRange(APInt::getSignedMinValue(W), SMax);
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_ULE: {
82*9880d681SAndroid Build Coastguard Worker APInt UMax(CR.getUnsignedMax());
83*9880d681SAndroid Build Coastguard Worker if (UMax.isMaxValue())
84*9880d681SAndroid Build Coastguard Worker return ConstantRange(W);
85*9880d681SAndroid Build Coastguard Worker return ConstantRange(APInt::getMinValue(W), UMax + 1);
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_SLE: {
88*9880d681SAndroid Build Coastguard Worker APInt SMax(CR.getSignedMax());
89*9880d681SAndroid Build Coastguard Worker if (SMax.isMaxSignedValue())
90*9880d681SAndroid Build Coastguard Worker return ConstantRange(W);
91*9880d681SAndroid Build Coastguard Worker return ConstantRange(APInt::getSignedMinValue(W), SMax + 1);
92*9880d681SAndroid Build Coastguard Worker }
93*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_UGT: {
94*9880d681SAndroid Build Coastguard Worker APInt UMin(CR.getUnsignedMin());
95*9880d681SAndroid Build Coastguard Worker if (UMin.isMaxValue())
96*9880d681SAndroid Build Coastguard Worker return ConstantRange(W, /* empty */ false);
97*9880d681SAndroid Build Coastguard Worker return ConstantRange(UMin + 1, APInt::getNullValue(W));
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_SGT: {
100*9880d681SAndroid Build Coastguard Worker APInt SMin(CR.getSignedMin());
101*9880d681SAndroid Build Coastguard Worker if (SMin.isMaxSignedValue())
102*9880d681SAndroid Build Coastguard Worker return ConstantRange(W, /* empty */ false);
103*9880d681SAndroid Build Coastguard Worker return ConstantRange(SMin + 1, APInt::getSignedMinValue(W));
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_UGE: {
106*9880d681SAndroid Build Coastguard Worker APInt UMin(CR.getUnsignedMin());
107*9880d681SAndroid Build Coastguard Worker if (UMin.isMinValue())
108*9880d681SAndroid Build Coastguard Worker return ConstantRange(W);
109*9880d681SAndroid Build Coastguard Worker return ConstantRange(UMin, APInt::getNullValue(W));
110*9880d681SAndroid Build Coastguard Worker }
111*9880d681SAndroid Build Coastguard Worker case CmpInst::ICMP_SGE: {
112*9880d681SAndroid Build Coastguard Worker APInt SMin(CR.getSignedMin());
113*9880d681SAndroid Build Coastguard Worker if (SMin.isMinSignedValue())
114*9880d681SAndroid Build Coastguard Worker return ConstantRange(W);
115*9880d681SAndroid Build Coastguard Worker return ConstantRange(SMin, APInt::getSignedMinValue(W));
116*9880d681SAndroid Build Coastguard Worker }
117*9880d681SAndroid Build Coastguard Worker }
118*9880d681SAndroid Build Coastguard Worker }
119*9880d681SAndroid Build Coastguard Worker
makeSatisfyingICmpRegion(CmpInst::Predicate Pred,const ConstantRange & CR)120*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::makeSatisfyingICmpRegion(CmpInst::Predicate Pred,
121*9880d681SAndroid Build Coastguard Worker const ConstantRange &CR) {
122*9880d681SAndroid Build Coastguard Worker // Follows from De-Morgan's laws:
123*9880d681SAndroid Build Coastguard Worker //
124*9880d681SAndroid Build Coastguard Worker // ~(~A union ~B) == A intersect B.
125*9880d681SAndroid Build Coastguard Worker //
126*9880d681SAndroid Build Coastguard Worker return makeAllowedICmpRegion(CmpInst::getInversePredicate(Pred), CR)
127*9880d681SAndroid Build Coastguard Worker .inverse();
128*9880d681SAndroid Build Coastguard Worker }
129*9880d681SAndroid Build Coastguard Worker
makeExactICmpRegion(CmpInst::Predicate Pred,const APInt & C)130*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::makeExactICmpRegion(CmpInst::Predicate Pred,
131*9880d681SAndroid Build Coastguard Worker const APInt &C) {
132*9880d681SAndroid Build Coastguard Worker // Computes the exact range that is equal to both the constant ranges returned
133*9880d681SAndroid Build Coastguard Worker // by makeAllowedICmpRegion and makeSatisfyingICmpRegion. This is always true
134*9880d681SAndroid Build Coastguard Worker // when RHS is a singleton such as an APInt and so the assert is valid.
135*9880d681SAndroid Build Coastguard Worker // However for non-singleton RHS, for example ult [2,5) makeAllowedICmpRegion
136*9880d681SAndroid Build Coastguard Worker // returns [0,4) but makeSatisfyICmpRegion returns [0,2).
137*9880d681SAndroid Build Coastguard Worker //
138*9880d681SAndroid Build Coastguard Worker assert(makeAllowedICmpRegion(Pred, C) == makeSatisfyingICmpRegion(Pred, C));
139*9880d681SAndroid Build Coastguard Worker return makeAllowedICmpRegion(Pred, C);
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker
getEquivalentICmp(CmpInst::Predicate & Pred,APInt & RHS) const142*9880d681SAndroid Build Coastguard Worker bool ConstantRange::getEquivalentICmp(CmpInst::Predicate &Pred,
143*9880d681SAndroid Build Coastguard Worker APInt &RHS) const {
144*9880d681SAndroid Build Coastguard Worker bool Success = false;
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker if (isFullSet() || isEmptySet()) {
147*9880d681SAndroid Build Coastguard Worker Pred = isEmptySet() ? CmpInst::ICMP_ULT : CmpInst::ICMP_UGE;
148*9880d681SAndroid Build Coastguard Worker RHS = APInt(getBitWidth(), 0);
149*9880d681SAndroid Build Coastguard Worker Success = true;
150*9880d681SAndroid Build Coastguard Worker } else if (getLower().isMinSignedValue() || getLower().isMinValue()) {
151*9880d681SAndroid Build Coastguard Worker Pred =
152*9880d681SAndroid Build Coastguard Worker getLower().isMinSignedValue() ? CmpInst::ICMP_SLT : CmpInst::ICMP_ULT;
153*9880d681SAndroid Build Coastguard Worker RHS = getUpper();
154*9880d681SAndroid Build Coastguard Worker Success = true;
155*9880d681SAndroid Build Coastguard Worker } else if (getUpper().isMinSignedValue() || getUpper().isMinValue()) {
156*9880d681SAndroid Build Coastguard Worker Pred =
157*9880d681SAndroid Build Coastguard Worker getUpper().isMinSignedValue() ? CmpInst::ICMP_SGE : CmpInst::ICMP_UGE;
158*9880d681SAndroid Build Coastguard Worker RHS = getLower();
159*9880d681SAndroid Build Coastguard Worker Success = true;
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Worker assert((!Success || ConstantRange::makeExactICmpRegion(Pred, RHS) == *this) &&
163*9880d681SAndroid Build Coastguard Worker "Bad result!");
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker return Success;
166*9880d681SAndroid Build Coastguard Worker }
167*9880d681SAndroid Build Coastguard Worker
168*9880d681SAndroid Build Coastguard Worker ConstantRange
makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,const ConstantRange & Other,unsigned NoWrapKind)169*9880d681SAndroid Build Coastguard Worker ConstantRange::makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
170*9880d681SAndroid Build Coastguard Worker const ConstantRange &Other,
171*9880d681SAndroid Build Coastguard Worker unsigned NoWrapKind) {
172*9880d681SAndroid Build Coastguard Worker typedef OverflowingBinaryOperator OBO;
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard Worker // Computes the intersection of CR0 and CR1. It is different from
175*9880d681SAndroid Build Coastguard Worker // intersectWith in that the ConstantRange returned will only contain elements
176*9880d681SAndroid Build Coastguard Worker // in both CR0 and CR1 (i.e. SubsetIntersect(X, Y) is a *subset*, proper or
177*9880d681SAndroid Build Coastguard Worker // not, of both X and Y).
178*9880d681SAndroid Build Coastguard Worker auto SubsetIntersect =
179*9880d681SAndroid Build Coastguard Worker [](const ConstantRange &CR0, const ConstantRange &CR1) {
180*9880d681SAndroid Build Coastguard Worker return CR0.inverse().unionWith(CR1.inverse()).inverse();
181*9880d681SAndroid Build Coastguard Worker };
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Worker assert(BinOp >= Instruction::BinaryOpsBegin &&
184*9880d681SAndroid Build Coastguard Worker BinOp < Instruction::BinaryOpsEnd && "Binary operators only!");
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker assert((NoWrapKind == OBO::NoSignedWrap ||
187*9880d681SAndroid Build Coastguard Worker NoWrapKind == OBO::NoUnsignedWrap ||
188*9880d681SAndroid Build Coastguard Worker NoWrapKind == (OBO::NoUnsignedWrap | OBO::NoSignedWrap)) &&
189*9880d681SAndroid Build Coastguard Worker "NoWrapKind invalid!");
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker unsigned BitWidth = Other.getBitWidth();
192*9880d681SAndroid Build Coastguard Worker if (BinOp != Instruction::Add)
193*9880d681SAndroid Build Coastguard Worker // Conservative answer: empty set
194*9880d681SAndroid Build Coastguard Worker return ConstantRange(BitWidth, false);
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker if (auto *C = Other.getSingleElement())
197*9880d681SAndroid Build Coastguard Worker if (C->isMinValue())
198*9880d681SAndroid Build Coastguard Worker // Full set: nothing signed / unsigned wraps when added to 0.
199*9880d681SAndroid Build Coastguard Worker return ConstantRange(BitWidth);
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker ConstantRange Result(BitWidth);
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker if (NoWrapKind & OBO::NoUnsignedWrap)
204*9880d681SAndroid Build Coastguard Worker Result =
205*9880d681SAndroid Build Coastguard Worker SubsetIntersect(Result, ConstantRange(APInt::getNullValue(BitWidth),
206*9880d681SAndroid Build Coastguard Worker -Other.getUnsignedMax()));
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker if (NoWrapKind & OBO::NoSignedWrap) {
209*9880d681SAndroid Build Coastguard Worker APInt SignedMin = Other.getSignedMin();
210*9880d681SAndroid Build Coastguard Worker APInt SignedMax = Other.getSignedMax();
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker if (SignedMax.isStrictlyPositive())
213*9880d681SAndroid Build Coastguard Worker Result = SubsetIntersect(
214*9880d681SAndroid Build Coastguard Worker Result,
215*9880d681SAndroid Build Coastguard Worker ConstantRange(APInt::getSignedMinValue(BitWidth),
216*9880d681SAndroid Build Coastguard Worker APInt::getSignedMinValue(BitWidth) - SignedMax));
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker if (SignedMin.isNegative())
219*9880d681SAndroid Build Coastguard Worker Result = SubsetIntersect(
220*9880d681SAndroid Build Coastguard Worker Result, ConstantRange(APInt::getSignedMinValue(BitWidth) - SignedMin,
221*9880d681SAndroid Build Coastguard Worker APInt::getSignedMinValue(BitWidth)));
222*9880d681SAndroid Build Coastguard Worker }
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Worker return Result;
225*9880d681SAndroid Build Coastguard Worker }
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Worker /// isFullSet - Return true if this set contains all of the elements possible
228*9880d681SAndroid Build Coastguard Worker /// for this data-type
isFullSet() const229*9880d681SAndroid Build Coastguard Worker bool ConstantRange::isFullSet() const {
230*9880d681SAndroid Build Coastguard Worker return Lower == Upper && Lower.isMaxValue();
231*9880d681SAndroid Build Coastguard Worker }
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard Worker /// isEmptySet - Return true if this set contains no members.
234*9880d681SAndroid Build Coastguard Worker ///
isEmptySet() const235*9880d681SAndroid Build Coastguard Worker bool ConstantRange::isEmptySet() const {
236*9880d681SAndroid Build Coastguard Worker return Lower == Upper && Lower.isMinValue();
237*9880d681SAndroid Build Coastguard Worker }
238*9880d681SAndroid Build Coastguard Worker
239*9880d681SAndroid Build Coastguard Worker /// isWrappedSet - Return true if this set wraps around the top of the range,
240*9880d681SAndroid Build Coastguard Worker /// for example: [100, 8)
241*9880d681SAndroid Build Coastguard Worker ///
isWrappedSet() const242*9880d681SAndroid Build Coastguard Worker bool ConstantRange::isWrappedSet() const {
243*9880d681SAndroid Build Coastguard Worker return Lower.ugt(Upper);
244*9880d681SAndroid Build Coastguard Worker }
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker /// isSignWrappedSet - Return true if this set wraps around the INT_MIN of
247*9880d681SAndroid Build Coastguard Worker /// its bitwidth, for example: i8 [120, 140).
248*9880d681SAndroid Build Coastguard Worker ///
isSignWrappedSet() const249*9880d681SAndroid Build Coastguard Worker bool ConstantRange::isSignWrappedSet() const {
250*9880d681SAndroid Build Coastguard Worker return contains(APInt::getSignedMaxValue(getBitWidth())) &&
251*9880d681SAndroid Build Coastguard Worker contains(APInt::getSignedMinValue(getBitWidth()));
252*9880d681SAndroid Build Coastguard Worker }
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Worker /// getSetSize - Return the number of elements in this set.
255*9880d681SAndroid Build Coastguard Worker ///
getSetSize() const256*9880d681SAndroid Build Coastguard Worker APInt ConstantRange::getSetSize() const {
257*9880d681SAndroid Build Coastguard Worker if (isFullSet()) {
258*9880d681SAndroid Build Coastguard Worker APInt Size(getBitWidth()+1, 0);
259*9880d681SAndroid Build Coastguard Worker Size.setBit(getBitWidth());
260*9880d681SAndroid Build Coastguard Worker return Size;
261*9880d681SAndroid Build Coastguard Worker }
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker // This is also correct for wrapped sets.
264*9880d681SAndroid Build Coastguard Worker return (Upper - Lower).zext(getBitWidth()+1);
265*9880d681SAndroid Build Coastguard Worker }
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker /// getUnsignedMax - Return the largest unsigned value contained in the
268*9880d681SAndroid Build Coastguard Worker /// ConstantRange.
269*9880d681SAndroid Build Coastguard Worker ///
getUnsignedMax() const270*9880d681SAndroid Build Coastguard Worker APInt ConstantRange::getUnsignedMax() const {
271*9880d681SAndroid Build Coastguard Worker if (isFullSet() || isWrappedSet())
272*9880d681SAndroid Build Coastguard Worker return APInt::getMaxValue(getBitWidth());
273*9880d681SAndroid Build Coastguard Worker return getUpper() - 1;
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker /// getUnsignedMin - Return the smallest unsigned value contained in the
277*9880d681SAndroid Build Coastguard Worker /// ConstantRange.
278*9880d681SAndroid Build Coastguard Worker ///
getUnsignedMin() const279*9880d681SAndroid Build Coastguard Worker APInt ConstantRange::getUnsignedMin() const {
280*9880d681SAndroid Build Coastguard Worker if (isFullSet() || (isWrappedSet() && getUpper() != 0))
281*9880d681SAndroid Build Coastguard Worker return APInt::getMinValue(getBitWidth());
282*9880d681SAndroid Build Coastguard Worker return getLower();
283*9880d681SAndroid Build Coastguard Worker }
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Worker /// getSignedMax - Return the largest signed value contained in the
286*9880d681SAndroid Build Coastguard Worker /// ConstantRange.
287*9880d681SAndroid Build Coastguard Worker ///
getSignedMax() const288*9880d681SAndroid Build Coastguard Worker APInt ConstantRange::getSignedMax() const {
289*9880d681SAndroid Build Coastguard Worker APInt SignedMax(APInt::getSignedMaxValue(getBitWidth()));
290*9880d681SAndroid Build Coastguard Worker if (!isWrappedSet()) {
291*9880d681SAndroid Build Coastguard Worker if (getLower().sle(getUpper() - 1))
292*9880d681SAndroid Build Coastguard Worker return getUpper() - 1;
293*9880d681SAndroid Build Coastguard Worker return SignedMax;
294*9880d681SAndroid Build Coastguard Worker }
295*9880d681SAndroid Build Coastguard Worker if (getLower().isNegative() == getUpper().isNegative())
296*9880d681SAndroid Build Coastguard Worker return SignedMax;
297*9880d681SAndroid Build Coastguard Worker return getUpper() - 1;
298*9880d681SAndroid Build Coastguard Worker }
299*9880d681SAndroid Build Coastguard Worker
300*9880d681SAndroid Build Coastguard Worker /// getSignedMin - Return the smallest signed value contained in the
301*9880d681SAndroid Build Coastguard Worker /// ConstantRange.
302*9880d681SAndroid Build Coastguard Worker ///
getSignedMin() const303*9880d681SAndroid Build Coastguard Worker APInt ConstantRange::getSignedMin() const {
304*9880d681SAndroid Build Coastguard Worker APInt SignedMin(APInt::getSignedMinValue(getBitWidth()));
305*9880d681SAndroid Build Coastguard Worker if (!isWrappedSet()) {
306*9880d681SAndroid Build Coastguard Worker if (getLower().sle(getUpper() - 1))
307*9880d681SAndroid Build Coastguard Worker return getLower();
308*9880d681SAndroid Build Coastguard Worker return SignedMin;
309*9880d681SAndroid Build Coastguard Worker }
310*9880d681SAndroid Build Coastguard Worker if ((getUpper() - 1).slt(getLower())) {
311*9880d681SAndroid Build Coastguard Worker if (getUpper() != SignedMin)
312*9880d681SAndroid Build Coastguard Worker return SignedMin;
313*9880d681SAndroid Build Coastguard Worker }
314*9880d681SAndroid Build Coastguard Worker return getLower();
315*9880d681SAndroid Build Coastguard Worker }
316*9880d681SAndroid Build Coastguard Worker
317*9880d681SAndroid Build Coastguard Worker /// contains - Return true if the specified value is in the set.
318*9880d681SAndroid Build Coastguard Worker ///
contains(const APInt & V) const319*9880d681SAndroid Build Coastguard Worker bool ConstantRange::contains(const APInt &V) const {
320*9880d681SAndroid Build Coastguard Worker if (Lower == Upper)
321*9880d681SAndroid Build Coastguard Worker return isFullSet();
322*9880d681SAndroid Build Coastguard Worker
323*9880d681SAndroid Build Coastguard Worker if (!isWrappedSet())
324*9880d681SAndroid Build Coastguard Worker return Lower.ule(V) && V.ult(Upper);
325*9880d681SAndroid Build Coastguard Worker return Lower.ule(V) || V.ult(Upper);
326*9880d681SAndroid Build Coastguard Worker }
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker /// contains - Return true if the argument is a subset of this range.
329*9880d681SAndroid Build Coastguard Worker /// Two equal sets contain each other. The empty set contained by all other
330*9880d681SAndroid Build Coastguard Worker /// sets.
331*9880d681SAndroid Build Coastguard Worker ///
contains(const ConstantRange & Other) const332*9880d681SAndroid Build Coastguard Worker bool ConstantRange::contains(const ConstantRange &Other) const {
333*9880d681SAndroid Build Coastguard Worker if (isFullSet() || Other.isEmptySet()) return true;
334*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isFullSet()) return false;
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker if (!isWrappedSet()) {
337*9880d681SAndroid Build Coastguard Worker if (Other.isWrappedSet())
338*9880d681SAndroid Build Coastguard Worker return false;
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker return Lower.ule(Other.getLower()) && Other.getUpper().ule(Upper);
341*9880d681SAndroid Build Coastguard Worker }
342*9880d681SAndroid Build Coastguard Worker
343*9880d681SAndroid Build Coastguard Worker if (!Other.isWrappedSet())
344*9880d681SAndroid Build Coastguard Worker return Other.getUpper().ule(Upper) ||
345*9880d681SAndroid Build Coastguard Worker Lower.ule(Other.getLower());
346*9880d681SAndroid Build Coastguard Worker
347*9880d681SAndroid Build Coastguard Worker return Other.getUpper().ule(Upper) && Lower.ule(Other.getLower());
348*9880d681SAndroid Build Coastguard Worker }
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker /// subtract - Subtract the specified constant from the endpoints of this
351*9880d681SAndroid Build Coastguard Worker /// constant range.
subtract(const APInt & Val) const352*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::subtract(const APInt &Val) const {
353*9880d681SAndroid Build Coastguard Worker assert(Val.getBitWidth() == getBitWidth() && "Wrong bit width");
354*9880d681SAndroid Build Coastguard Worker // If the set is empty or full, don't modify the endpoints.
355*9880d681SAndroid Build Coastguard Worker if (Lower == Upper)
356*9880d681SAndroid Build Coastguard Worker return *this;
357*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower - Val, Upper - Val);
358*9880d681SAndroid Build Coastguard Worker }
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Worker /// \brief Subtract the specified range from this range (aka relative complement
361*9880d681SAndroid Build Coastguard Worker /// of the sets).
difference(const ConstantRange & CR) const362*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::difference(const ConstantRange &CR) const {
363*9880d681SAndroid Build Coastguard Worker return intersectWith(CR.inverse());
364*9880d681SAndroid Build Coastguard Worker }
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker /// intersectWith - Return the range that results from the intersection of this
367*9880d681SAndroid Build Coastguard Worker /// range with another range. The resultant range is guaranteed to include all
368*9880d681SAndroid Build Coastguard Worker /// elements contained in both input ranges, and to have the smallest possible
369*9880d681SAndroid Build Coastguard Worker /// set size that does so. Because there may be two intersections with the
370*9880d681SAndroid Build Coastguard Worker /// same set size, A.intersectWith(B) might not be equal to B.intersectWith(A).
intersectWith(const ConstantRange & CR) const371*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const {
372*9880d681SAndroid Build Coastguard Worker assert(getBitWidth() == CR.getBitWidth() &&
373*9880d681SAndroid Build Coastguard Worker "ConstantRange types don't agree!");
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker // Handle common cases.
376*9880d681SAndroid Build Coastguard Worker if ( isEmptySet() || CR.isFullSet()) return *this;
377*9880d681SAndroid Build Coastguard Worker if (CR.isEmptySet() || isFullSet()) return CR;
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker if (!isWrappedSet() && CR.isWrappedSet())
380*9880d681SAndroid Build Coastguard Worker return CR.intersectWith(*this);
381*9880d681SAndroid Build Coastguard Worker
382*9880d681SAndroid Build Coastguard Worker if (!isWrappedSet() && !CR.isWrappedSet()) {
383*9880d681SAndroid Build Coastguard Worker if (Lower.ult(CR.Lower)) {
384*9880d681SAndroid Build Coastguard Worker if (Upper.ule(CR.Lower))
385*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), false);
386*9880d681SAndroid Build Coastguard Worker
387*9880d681SAndroid Build Coastguard Worker if (Upper.ult(CR.Upper))
388*9880d681SAndroid Build Coastguard Worker return ConstantRange(CR.Lower, Upper);
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker return CR;
391*9880d681SAndroid Build Coastguard Worker }
392*9880d681SAndroid Build Coastguard Worker if (Upper.ult(CR.Upper))
393*9880d681SAndroid Build Coastguard Worker return *this;
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Worker if (Lower.ult(CR.Upper))
396*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower, CR.Upper);
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), false);
399*9880d681SAndroid Build Coastguard Worker }
400*9880d681SAndroid Build Coastguard Worker
401*9880d681SAndroid Build Coastguard Worker if (isWrappedSet() && !CR.isWrappedSet()) {
402*9880d681SAndroid Build Coastguard Worker if (CR.Lower.ult(Upper)) {
403*9880d681SAndroid Build Coastguard Worker if (CR.Upper.ult(Upper))
404*9880d681SAndroid Build Coastguard Worker return CR;
405*9880d681SAndroid Build Coastguard Worker
406*9880d681SAndroid Build Coastguard Worker if (CR.Upper.ule(Lower))
407*9880d681SAndroid Build Coastguard Worker return ConstantRange(CR.Lower, Upper);
408*9880d681SAndroid Build Coastguard Worker
409*9880d681SAndroid Build Coastguard Worker if (getSetSize().ult(CR.getSetSize()))
410*9880d681SAndroid Build Coastguard Worker return *this;
411*9880d681SAndroid Build Coastguard Worker return CR;
412*9880d681SAndroid Build Coastguard Worker }
413*9880d681SAndroid Build Coastguard Worker if (CR.Lower.ult(Lower)) {
414*9880d681SAndroid Build Coastguard Worker if (CR.Upper.ule(Lower))
415*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), false);
416*9880d681SAndroid Build Coastguard Worker
417*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower, CR.Upper);
418*9880d681SAndroid Build Coastguard Worker }
419*9880d681SAndroid Build Coastguard Worker return CR;
420*9880d681SAndroid Build Coastguard Worker }
421*9880d681SAndroid Build Coastguard Worker
422*9880d681SAndroid Build Coastguard Worker if (CR.Upper.ult(Upper)) {
423*9880d681SAndroid Build Coastguard Worker if (CR.Lower.ult(Upper)) {
424*9880d681SAndroid Build Coastguard Worker if (getSetSize().ult(CR.getSetSize()))
425*9880d681SAndroid Build Coastguard Worker return *this;
426*9880d681SAndroid Build Coastguard Worker return CR;
427*9880d681SAndroid Build Coastguard Worker }
428*9880d681SAndroid Build Coastguard Worker
429*9880d681SAndroid Build Coastguard Worker if (CR.Lower.ult(Lower))
430*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower, CR.Upper);
431*9880d681SAndroid Build Coastguard Worker
432*9880d681SAndroid Build Coastguard Worker return CR;
433*9880d681SAndroid Build Coastguard Worker }
434*9880d681SAndroid Build Coastguard Worker if (CR.Upper.ule(Lower)) {
435*9880d681SAndroid Build Coastguard Worker if (CR.Lower.ult(Lower))
436*9880d681SAndroid Build Coastguard Worker return *this;
437*9880d681SAndroid Build Coastguard Worker
438*9880d681SAndroid Build Coastguard Worker return ConstantRange(CR.Lower, Upper);
439*9880d681SAndroid Build Coastguard Worker }
440*9880d681SAndroid Build Coastguard Worker if (getSetSize().ult(CR.getSetSize()))
441*9880d681SAndroid Build Coastguard Worker return *this;
442*9880d681SAndroid Build Coastguard Worker return CR;
443*9880d681SAndroid Build Coastguard Worker }
444*9880d681SAndroid Build Coastguard Worker
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker /// unionWith - Return the range that results from the union of this range with
447*9880d681SAndroid Build Coastguard Worker /// another range. The resultant range is guaranteed to include the elements of
448*9880d681SAndroid Build Coastguard Worker /// both sets, but may contain more. For example, [3, 9) union [12,15) is
449*9880d681SAndroid Build Coastguard Worker /// [3, 15), which includes 9, 10, and 11, which were not included in either
450*9880d681SAndroid Build Coastguard Worker /// set before.
451*9880d681SAndroid Build Coastguard Worker ///
unionWith(const ConstantRange & CR) const452*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const {
453*9880d681SAndroid Build Coastguard Worker assert(getBitWidth() == CR.getBitWidth() &&
454*9880d681SAndroid Build Coastguard Worker "ConstantRange types don't agree!");
455*9880d681SAndroid Build Coastguard Worker
456*9880d681SAndroid Build Coastguard Worker if ( isFullSet() || CR.isEmptySet()) return *this;
457*9880d681SAndroid Build Coastguard Worker if (CR.isFullSet() || isEmptySet()) return CR;
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker if (!isWrappedSet() && CR.isWrappedSet()) return CR.unionWith(*this);
460*9880d681SAndroid Build Coastguard Worker
461*9880d681SAndroid Build Coastguard Worker if (!isWrappedSet() && !CR.isWrappedSet()) {
462*9880d681SAndroid Build Coastguard Worker if (CR.Upper.ult(Lower) || Upper.ult(CR.Lower)) {
463*9880d681SAndroid Build Coastguard Worker // If the two ranges are disjoint, find the smaller gap and bridge it.
464*9880d681SAndroid Build Coastguard Worker APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper;
465*9880d681SAndroid Build Coastguard Worker if (d1.ult(d2))
466*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower, CR.Upper);
467*9880d681SAndroid Build Coastguard Worker return ConstantRange(CR.Lower, Upper);
468*9880d681SAndroid Build Coastguard Worker }
469*9880d681SAndroid Build Coastguard Worker
470*9880d681SAndroid Build Coastguard Worker APInt L = Lower, U = Upper;
471*9880d681SAndroid Build Coastguard Worker if (CR.Lower.ult(L))
472*9880d681SAndroid Build Coastguard Worker L = CR.Lower;
473*9880d681SAndroid Build Coastguard Worker if ((CR.Upper - 1).ugt(U - 1))
474*9880d681SAndroid Build Coastguard Worker U = CR.Upper;
475*9880d681SAndroid Build Coastguard Worker
476*9880d681SAndroid Build Coastguard Worker if (L == 0 && U == 0)
477*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth());
478*9880d681SAndroid Build Coastguard Worker
479*9880d681SAndroid Build Coastguard Worker return ConstantRange(L, U);
480*9880d681SAndroid Build Coastguard Worker }
481*9880d681SAndroid Build Coastguard Worker
482*9880d681SAndroid Build Coastguard Worker if (!CR.isWrappedSet()) {
483*9880d681SAndroid Build Coastguard Worker // ------U L----- and ------U L----- : this
484*9880d681SAndroid Build Coastguard Worker // L--U L--U : CR
485*9880d681SAndroid Build Coastguard Worker if (CR.Upper.ule(Upper) || CR.Lower.uge(Lower))
486*9880d681SAndroid Build Coastguard Worker return *this;
487*9880d681SAndroid Build Coastguard Worker
488*9880d681SAndroid Build Coastguard Worker // ------U L----- : this
489*9880d681SAndroid Build Coastguard Worker // L---------U : CR
490*9880d681SAndroid Build Coastguard Worker if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper))
491*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth());
492*9880d681SAndroid Build Coastguard Worker
493*9880d681SAndroid Build Coastguard Worker // ----U L---- : this
494*9880d681SAndroid Build Coastguard Worker // L---U : CR
495*9880d681SAndroid Build Coastguard Worker // <d1> <d2>
496*9880d681SAndroid Build Coastguard Worker if (Upper.ule(CR.Lower) && CR.Upper.ule(Lower)) {
497*9880d681SAndroid Build Coastguard Worker APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper;
498*9880d681SAndroid Build Coastguard Worker if (d1.ult(d2))
499*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower, CR.Upper);
500*9880d681SAndroid Build Coastguard Worker return ConstantRange(CR.Lower, Upper);
501*9880d681SAndroid Build Coastguard Worker }
502*9880d681SAndroid Build Coastguard Worker
503*9880d681SAndroid Build Coastguard Worker // ----U L----- : this
504*9880d681SAndroid Build Coastguard Worker // L----U : CR
505*9880d681SAndroid Build Coastguard Worker if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper))
506*9880d681SAndroid Build Coastguard Worker return ConstantRange(CR.Lower, Upper);
507*9880d681SAndroid Build Coastguard Worker
508*9880d681SAndroid Build Coastguard Worker // ------U L---- : this
509*9880d681SAndroid Build Coastguard Worker // L-----U : CR
510*9880d681SAndroid Build Coastguard Worker assert(CR.Lower.ult(Upper) && CR.Upper.ult(Lower) &&
511*9880d681SAndroid Build Coastguard Worker "ConstantRange::unionWith missed a case with one range wrapped");
512*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower, CR.Upper);
513*9880d681SAndroid Build Coastguard Worker }
514*9880d681SAndroid Build Coastguard Worker
515*9880d681SAndroid Build Coastguard Worker // ------U L---- and ------U L---- : this
516*9880d681SAndroid Build Coastguard Worker // -U L----------- and ------------U L : CR
517*9880d681SAndroid Build Coastguard Worker if (CR.Lower.ule(Upper) || Lower.ule(CR.Upper))
518*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth());
519*9880d681SAndroid Build Coastguard Worker
520*9880d681SAndroid Build Coastguard Worker APInt L = Lower, U = Upper;
521*9880d681SAndroid Build Coastguard Worker if (CR.Upper.ugt(U))
522*9880d681SAndroid Build Coastguard Worker U = CR.Upper;
523*9880d681SAndroid Build Coastguard Worker if (CR.Lower.ult(L))
524*9880d681SAndroid Build Coastguard Worker L = CR.Lower;
525*9880d681SAndroid Build Coastguard Worker
526*9880d681SAndroid Build Coastguard Worker return ConstantRange(L, U);
527*9880d681SAndroid Build Coastguard Worker }
528*9880d681SAndroid Build Coastguard Worker
529*9880d681SAndroid Build Coastguard Worker /// zeroExtend - Return a new range in the specified integer type, which must
530*9880d681SAndroid Build Coastguard Worker /// be strictly larger than the current type. The returned range will
531*9880d681SAndroid Build Coastguard Worker /// correspond to the possible range of values as if the source range had been
532*9880d681SAndroid Build Coastguard Worker /// zero extended.
zeroExtend(uint32_t DstTySize) const533*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const {
534*9880d681SAndroid Build Coastguard Worker if (isEmptySet()) return ConstantRange(DstTySize, /*isFullSet=*/false);
535*9880d681SAndroid Build Coastguard Worker
536*9880d681SAndroid Build Coastguard Worker unsigned SrcTySize = getBitWidth();
537*9880d681SAndroid Build Coastguard Worker assert(SrcTySize < DstTySize && "Not a value extension");
538*9880d681SAndroid Build Coastguard Worker if (isFullSet() || isWrappedSet()) {
539*9880d681SAndroid Build Coastguard Worker // Change into [0, 1 << src bit width)
540*9880d681SAndroid Build Coastguard Worker APInt LowerExt(DstTySize, 0);
541*9880d681SAndroid Build Coastguard Worker if (!Upper) // special case: [X, 0) -- not really wrapping around
542*9880d681SAndroid Build Coastguard Worker LowerExt = Lower.zext(DstTySize);
543*9880d681SAndroid Build Coastguard Worker return ConstantRange(LowerExt, APInt::getOneBitSet(DstTySize, SrcTySize));
544*9880d681SAndroid Build Coastguard Worker }
545*9880d681SAndroid Build Coastguard Worker
546*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower.zext(DstTySize), Upper.zext(DstTySize));
547*9880d681SAndroid Build Coastguard Worker }
548*9880d681SAndroid Build Coastguard Worker
549*9880d681SAndroid Build Coastguard Worker /// signExtend - Return a new range in the specified integer type, which must
550*9880d681SAndroid Build Coastguard Worker /// be strictly larger than the current type. The returned range will
551*9880d681SAndroid Build Coastguard Worker /// correspond to the possible range of values as if the source range had been
552*9880d681SAndroid Build Coastguard Worker /// sign extended.
signExtend(uint32_t DstTySize) const553*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const {
554*9880d681SAndroid Build Coastguard Worker if (isEmptySet()) return ConstantRange(DstTySize, /*isFullSet=*/false);
555*9880d681SAndroid Build Coastguard Worker
556*9880d681SAndroid Build Coastguard Worker unsigned SrcTySize = getBitWidth();
557*9880d681SAndroid Build Coastguard Worker assert(SrcTySize < DstTySize && "Not a value extension");
558*9880d681SAndroid Build Coastguard Worker
559*9880d681SAndroid Build Coastguard Worker // special case: [X, INT_MIN) -- not really wrapping around
560*9880d681SAndroid Build Coastguard Worker if (Upper.isMinSignedValue())
561*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower.sext(DstTySize), Upper.zext(DstTySize));
562*9880d681SAndroid Build Coastguard Worker
563*9880d681SAndroid Build Coastguard Worker if (isFullSet() || isSignWrappedSet()) {
564*9880d681SAndroid Build Coastguard Worker return ConstantRange(APInt::getHighBitsSet(DstTySize,DstTySize-SrcTySize+1),
565*9880d681SAndroid Build Coastguard Worker APInt::getLowBitsSet(DstTySize, SrcTySize-1) + 1);
566*9880d681SAndroid Build Coastguard Worker }
567*9880d681SAndroid Build Coastguard Worker
568*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower.sext(DstTySize), Upper.sext(DstTySize));
569*9880d681SAndroid Build Coastguard Worker }
570*9880d681SAndroid Build Coastguard Worker
571*9880d681SAndroid Build Coastguard Worker /// truncate - Return a new range in the specified integer type, which must be
572*9880d681SAndroid Build Coastguard Worker /// strictly smaller than the current type. The returned range will
573*9880d681SAndroid Build Coastguard Worker /// correspond to the possible range of values as if the source range had been
574*9880d681SAndroid Build Coastguard Worker /// truncated to the specified type.
truncate(uint32_t DstTySize) const575*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::truncate(uint32_t DstTySize) const {
576*9880d681SAndroid Build Coastguard Worker assert(getBitWidth() > DstTySize && "Not a value truncation");
577*9880d681SAndroid Build Coastguard Worker if (isEmptySet())
578*9880d681SAndroid Build Coastguard Worker return ConstantRange(DstTySize, /*isFullSet=*/false);
579*9880d681SAndroid Build Coastguard Worker if (isFullSet())
580*9880d681SAndroid Build Coastguard Worker return ConstantRange(DstTySize, /*isFullSet=*/true);
581*9880d681SAndroid Build Coastguard Worker
582*9880d681SAndroid Build Coastguard Worker APInt MaxValue = APInt::getMaxValue(DstTySize).zext(getBitWidth());
583*9880d681SAndroid Build Coastguard Worker APInt MaxBitValue(getBitWidth(), 0);
584*9880d681SAndroid Build Coastguard Worker MaxBitValue.setBit(DstTySize);
585*9880d681SAndroid Build Coastguard Worker
586*9880d681SAndroid Build Coastguard Worker APInt LowerDiv(Lower), UpperDiv(Upper);
587*9880d681SAndroid Build Coastguard Worker ConstantRange Union(DstTySize, /*isFullSet=*/false);
588*9880d681SAndroid Build Coastguard Worker
589*9880d681SAndroid Build Coastguard Worker // Analyze wrapped sets in their two parts: [0, Upper) \/ [Lower, MaxValue]
590*9880d681SAndroid Build Coastguard Worker // We use the non-wrapped set code to analyze the [Lower, MaxValue) part, and
591*9880d681SAndroid Build Coastguard Worker // then we do the union with [MaxValue, Upper)
592*9880d681SAndroid Build Coastguard Worker if (isWrappedSet()) {
593*9880d681SAndroid Build Coastguard Worker // If Upper is greater than Max Value, it covers the whole truncated range.
594*9880d681SAndroid Build Coastguard Worker if (Upper.uge(MaxValue))
595*9880d681SAndroid Build Coastguard Worker return ConstantRange(DstTySize, /*isFullSet=*/true);
596*9880d681SAndroid Build Coastguard Worker
597*9880d681SAndroid Build Coastguard Worker Union = ConstantRange(APInt::getMaxValue(DstTySize),Upper.trunc(DstTySize));
598*9880d681SAndroid Build Coastguard Worker UpperDiv = APInt::getMaxValue(getBitWidth());
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Worker // Union covers the MaxValue case, so return if the remaining range is just
601*9880d681SAndroid Build Coastguard Worker // MaxValue.
602*9880d681SAndroid Build Coastguard Worker if (LowerDiv == UpperDiv)
603*9880d681SAndroid Build Coastguard Worker return Union;
604*9880d681SAndroid Build Coastguard Worker }
605*9880d681SAndroid Build Coastguard Worker
606*9880d681SAndroid Build Coastguard Worker // Chop off the most significant bits that are past the destination bitwidth.
607*9880d681SAndroid Build Coastguard Worker if (LowerDiv.uge(MaxValue)) {
608*9880d681SAndroid Build Coastguard Worker APInt Div(getBitWidth(), 0);
609*9880d681SAndroid Build Coastguard Worker APInt::udivrem(LowerDiv, MaxBitValue, Div, LowerDiv);
610*9880d681SAndroid Build Coastguard Worker UpperDiv = UpperDiv - MaxBitValue * Div;
611*9880d681SAndroid Build Coastguard Worker }
612*9880d681SAndroid Build Coastguard Worker
613*9880d681SAndroid Build Coastguard Worker if (UpperDiv.ule(MaxValue))
614*9880d681SAndroid Build Coastguard Worker return ConstantRange(LowerDiv.trunc(DstTySize),
615*9880d681SAndroid Build Coastguard Worker UpperDiv.trunc(DstTySize)).unionWith(Union);
616*9880d681SAndroid Build Coastguard Worker
617*9880d681SAndroid Build Coastguard Worker // The truncated value wraps around. Check if we can do better than fullset.
618*9880d681SAndroid Build Coastguard Worker APInt UpperModulo = UpperDiv - MaxBitValue;
619*9880d681SAndroid Build Coastguard Worker if (UpperModulo.ult(LowerDiv))
620*9880d681SAndroid Build Coastguard Worker return ConstantRange(LowerDiv.trunc(DstTySize),
621*9880d681SAndroid Build Coastguard Worker UpperModulo.trunc(DstTySize)).unionWith(Union);
622*9880d681SAndroid Build Coastguard Worker
623*9880d681SAndroid Build Coastguard Worker return ConstantRange(DstTySize, /*isFullSet=*/true);
624*9880d681SAndroid Build Coastguard Worker }
625*9880d681SAndroid Build Coastguard Worker
626*9880d681SAndroid Build Coastguard Worker /// zextOrTrunc - make this range have the bit width given by \p DstTySize. The
627*9880d681SAndroid Build Coastguard Worker /// value is zero extended, truncated, or left alone to make it that width.
zextOrTrunc(uint32_t DstTySize) const628*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::zextOrTrunc(uint32_t DstTySize) const {
629*9880d681SAndroid Build Coastguard Worker unsigned SrcTySize = getBitWidth();
630*9880d681SAndroid Build Coastguard Worker if (SrcTySize > DstTySize)
631*9880d681SAndroid Build Coastguard Worker return truncate(DstTySize);
632*9880d681SAndroid Build Coastguard Worker if (SrcTySize < DstTySize)
633*9880d681SAndroid Build Coastguard Worker return zeroExtend(DstTySize);
634*9880d681SAndroid Build Coastguard Worker return *this;
635*9880d681SAndroid Build Coastguard Worker }
636*9880d681SAndroid Build Coastguard Worker
637*9880d681SAndroid Build Coastguard Worker /// sextOrTrunc - make this range have the bit width given by \p DstTySize. The
638*9880d681SAndroid Build Coastguard Worker /// value is sign extended, truncated, or left alone to make it that width.
sextOrTrunc(uint32_t DstTySize) const639*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::sextOrTrunc(uint32_t DstTySize) const {
640*9880d681SAndroid Build Coastguard Worker unsigned SrcTySize = getBitWidth();
641*9880d681SAndroid Build Coastguard Worker if (SrcTySize > DstTySize)
642*9880d681SAndroid Build Coastguard Worker return truncate(DstTySize);
643*9880d681SAndroid Build Coastguard Worker if (SrcTySize < DstTySize)
644*9880d681SAndroid Build Coastguard Worker return signExtend(DstTySize);
645*9880d681SAndroid Build Coastguard Worker return *this;
646*9880d681SAndroid Build Coastguard Worker }
647*9880d681SAndroid Build Coastguard Worker
648*9880d681SAndroid Build Coastguard Worker ConstantRange
add(const ConstantRange & Other) const649*9880d681SAndroid Build Coastguard Worker ConstantRange::add(const ConstantRange &Other) const {
650*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
651*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
652*9880d681SAndroid Build Coastguard Worker if (isFullSet() || Other.isFullSet())
653*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
654*9880d681SAndroid Build Coastguard Worker
655*9880d681SAndroid Build Coastguard Worker APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize();
656*9880d681SAndroid Build Coastguard Worker APInt NewLower = getLower() + Other.getLower();
657*9880d681SAndroid Build Coastguard Worker APInt NewUpper = getUpper() + Other.getUpper() - 1;
658*9880d681SAndroid Build Coastguard Worker if (NewLower == NewUpper)
659*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
660*9880d681SAndroid Build Coastguard Worker
661*9880d681SAndroid Build Coastguard Worker ConstantRange X = ConstantRange(NewLower, NewUpper);
662*9880d681SAndroid Build Coastguard Worker if (X.getSetSize().ult(Spread_X) || X.getSetSize().ult(Spread_Y))
663*9880d681SAndroid Build Coastguard Worker // We've wrapped, therefore, full set.
664*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
665*9880d681SAndroid Build Coastguard Worker
666*9880d681SAndroid Build Coastguard Worker return X;
667*9880d681SAndroid Build Coastguard Worker }
668*9880d681SAndroid Build Coastguard Worker
669*9880d681SAndroid Build Coastguard Worker ConstantRange
sub(const ConstantRange & Other) const670*9880d681SAndroid Build Coastguard Worker ConstantRange::sub(const ConstantRange &Other) const {
671*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
672*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
673*9880d681SAndroid Build Coastguard Worker if (isFullSet() || Other.isFullSet())
674*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
675*9880d681SAndroid Build Coastguard Worker
676*9880d681SAndroid Build Coastguard Worker APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize();
677*9880d681SAndroid Build Coastguard Worker APInt NewLower = getLower() - Other.getUpper() + 1;
678*9880d681SAndroid Build Coastguard Worker APInt NewUpper = getUpper() - Other.getLower();
679*9880d681SAndroid Build Coastguard Worker if (NewLower == NewUpper)
680*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
681*9880d681SAndroid Build Coastguard Worker
682*9880d681SAndroid Build Coastguard Worker ConstantRange X = ConstantRange(NewLower, NewUpper);
683*9880d681SAndroid Build Coastguard Worker if (X.getSetSize().ult(Spread_X) || X.getSetSize().ult(Spread_Y))
684*9880d681SAndroid Build Coastguard Worker // We've wrapped, therefore, full set.
685*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
686*9880d681SAndroid Build Coastguard Worker
687*9880d681SAndroid Build Coastguard Worker return X;
688*9880d681SAndroid Build Coastguard Worker }
689*9880d681SAndroid Build Coastguard Worker
690*9880d681SAndroid Build Coastguard Worker ConstantRange
multiply(const ConstantRange & Other) const691*9880d681SAndroid Build Coastguard Worker ConstantRange::multiply(const ConstantRange &Other) const {
692*9880d681SAndroid Build Coastguard Worker // TODO: If either operand is a single element and the multiply is known to
693*9880d681SAndroid Build Coastguard Worker // be non-wrapping, round the result min and max value to the appropriate
694*9880d681SAndroid Build Coastguard Worker // multiple of that element. If wrapping is possible, at least adjust the
695*9880d681SAndroid Build Coastguard Worker // range according to the greatest power-of-two factor of the single element.
696*9880d681SAndroid Build Coastguard Worker
697*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
698*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
699*9880d681SAndroid Build Coastguard Worker
700*9880d681SAndroid Build Coastguard Worker // Multiplication is signedness-independent. However different ranges can be
701*9880d681SAndroid Build Coastguard Worker // obtained depending on how the input ranges are treated. These different
702*9880d681SAndroid Build Coastguard Worker // ranges are all conservatively correct, but one might be better than the
703*9880d681SAndroid Build Coastguard Worker // other. We calculate two ranges; one treating the inputs as unsigned
704*9880d681SAndroid Build Coastguard Worker // and the other signed, then return the smallest of these ranges.
705*9880d681SAndroid Build Coastguard Worker
706*9880d681SAndroid Build Coastguard Worker // Unsigned range first.
707*9880d681SAndroid Build Coastguard Worker APInt this_min = getUnsignedMin().zext(getBitWidth() * 2);
708*9880d681SAndroid Build Coastguard Worker APInt this_max = getUnsignedMax().zext(getBitWidth() * 2);
709*9880d681SAndroid Build Coastguard Worker APInt Other_min = Other.getUnsignedMin().zext(getBitWidth() * 2);
710*9880d681SAndroid Build Coastguard Worker APInt Other_max = Other.getUnsignedMax().zext(getBitWidth() * 2);
711*9880d681SAndroid Build Coastguard Worker
712*9880d681SAndroid Build Coastguard Worker ConstantRange Result_zext = ConstantRange(this_min * Other_min,
713*9880d681SAndroid Build Coastguard Worker this_max * Other_max + 1);
714*9880d681SAndroid Build Coastguard Worker ConstantRange UR = Result_zext.truncate(getBitWidth());
715*9880d681SAndroid Build Coastguard Worker
716*9880d681SAndroid Build Coastguard Worker // If the unsigned range doesn't wrap, and isn't negative then it's a range
717*9880d681SAndroid Build Coastguard Worker // from one positive number to another which is as good as we can generate.
718*9880d681SAndroid Build Coastguard Worker // In this case, skip the extra work of generating signed ranges which aren't
719*9880d681SAndroid Build Coastguard Worker // going to be better than this range.
720*9880d681SAndroid Build Coastguard Worker if (!UR.isWrappedSet() && UR.getLower().isNonNegative())
721*9880d681SAndroid Build Coastguard Worker return UR;
722*9880d681SAndroid Build Coastguard Worker
723*9880d681SAndroid Build Coastguard Worker // Now the signed range. Because we could be dealing with negative numbers
724*9880d681SAndroid Build Coastguard Worker // here, the lower bound is the smallest of the cartesian product of the
725*9880d681SAndroid Build Coastguard Worker // lower and upper ranges; for example:
726*9880d681SAndroid Build Coastguard Worker // [-1,4) * [-2,3) = min(-1*-2, -1*2, 3*-2, 3*2) = -6.
727*9880d681SAndroid Build Coastguard Worker // Similarly for the upper bound, swapping min for max.
728*9880d681SAndroid Build Coastguard Worker
729*9880d681SAndroid Build Coastguard Worker this_min = getSignedMin().sext(getBitWidth() * 2);
730*9880d681SAndroid Build Coastguard Worker this_max = getSignedMax().sext(getBitWidth() * 2);
731*9880d681SAndroid Build Coastguard Worker Other_min = Other.getSignedMin().sext(getBitWidth() * 2);
732*9880d681SAndroid Build Coastguard Worker Other_max = Other.getSignedMax().sext(getBitWidth() * 2);
733*9880d681SAndroid Build Coastguard Worker
734*9880d681SAndroid Build Coastguard Worker auto L = {this_min * Other_min, this_min * Other_max,
735*9880d681SAndroid Build Coastguard Worker this_max * Other_min, this_max * Other_max};
736*9880d681SAndroid Build Coastguard Worker auto Compare = [](const APInt &A, const APInt &B) { return A.slt(B); };
737*9880d681SAndroid Build Coastguard Worker ConstantRange Result_sext(std::min(L, Compare), std::max(L, Compare) + 1);
738*9880d681SAndroid Build Coastguard Worker ConstantRange SR = Result_sext.truncate(getBitWidth());
739*9880d681SAndroid Build Coastguard Worker
740*9880d681SAndroid Build Coastguard Worker return UR.getSetSize().ult(SR.getSetSize()) ? UR : SR;
741*9880d681SAndroid Build Coastguard Worker }
742*9880d681SAndroid Build Coastguard Worker
743*9880d681SAndroid Build Coastguard Worker ConstantRange
smax(const ConstantRange & Other) const744*9880d681SAndroid Build Coastguard Worker ConstantRange::smax(const ConstantRange &Other) const {
745*9880d681SAndroid Build Coastguard Worker // X smax Y is: range(smax(X_smin, Y_smin),
746*9880d681SAndroid Build Coastguard Worker // smax(X_smax, Y_smax))
747*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
748*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
749*9880d681SAndroid Build Coastguard Worker APInt NewL = APIntOps::smax(getSignedMin(), Other.getSignedMin());
750*9880d681SAndroid Build Coastguard Worker APInt NewU = APIntOps::smax(getSignedMax(), Other.getSignedMax()) + 1;
751*9880d681SAndroid Build Coastguard Worker if (NewU == NewL)
752*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
753*9880d681SAndroid Build Coastguard Worker return ConstantRange(NewL, NewU);
754*9880d681SAndroid Build Coastguard Worker }
755*9880d681SAndroid Build Coastguard Worker
756*9880d681SAndroid Build Coastguard Worker ConstantRange
umax(const ConstantRange & Other) const757*9880d681SAndroid Build Coastguard Worker ConstantRange::umax(const ConstantRange &Other) const {
758*9880d681SAndroid Build Coastguard Worker // X umax Y is: range(umax(X_umin, Y_umin),
759*9880d681SAndroid Build Coastguard Worker // umax(X_umax, Y_umax))
760*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
761*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
762*9880d681SAndroid Build Coastguard Worker APInt NewL = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin());
763*9880d681SAndroid Build Coastguard Worker APInt NewU = APIntOps::umax(getUnsignedMax(), Other.getUnsignedMax()) + 1;
764*9880d681SAndroid Build Coastguard Worker if (NewU == NewL)
765*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
766*9880d681SAndroid Build Coastguard Worker return ConstantRange(NewL, NewU);
767*9880d681SAndroid Build Coastguard Worker }
768*9880d681SAndroid Build Coastguard Worker
769*9880d681SAndroid Build Coastguard Worker ConstantRange
smin(const ConstantRange & Other) const770*9880d681SAndroid Build Coastguard Worker ConstantRange::smin(const ConstantRange &Other) const {
771*9880d681SAndroid Build Coastguard Worker // X smin Y is: range(smin(X_smin, Y_smin),
772*9880d681SAndroid Build Coastguard Worker // smin(X_smax, Y_smax))
773*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
774*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
775*9880d681SAndroid Build Coastguard Worker APInt NewL = APIntOps::smin(getSignedMin(), Other.getSignedMin());
776*9880d681SAndroid Build Coastguard Worker APInt NewU = APIntOps::smin(getSignedMax(), Other.getSignedMax()) + 1;
777*9880d681SAndroid Build Coastguard Worker if (NewU == NewL)
778*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
779*9880d681SAndroid Build Coastguard Worker return ConstantRange(NewL, NewU);
780*9880d681SAndroid Build Coastguard Worker }
781*9880d681SAndroid Build Coastguard Worker
782*9880d681SAndroid Build Coastguard Worker ConstantRange
umin(const ConstantRange & Other) const783*9880d681SAndroid Build Coastguard Worker ConstantRange::umin(const ConstantRange &Other) const {
784*9880d681SAndroid Build Coastguard Worker // X umin Y is: range(umin(X_umin, Y_umin),
785*9880d681SAndroid Build Coastguard Worker // umin(X_umax, Y_umax))
786*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
787*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
788*9880d681SAndroid Build Coastguard Worker APInt NewL = APIntOps::umin(getUnsignedMin(), Other.getUnsignedMin());
789*9880d681SAndroid Build Coastguard Worker APInt NewU = APIntOps::umin(getUnsignedMax(), Other.getUnsignedMax()) + 1;
790*9880d681SAndroid Build Coastguard Worker if (NewU == NewL)
791*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
792*9880d681SAndroid Build Coastguard Worker return ConstantRange(NewL, NewU);
793*9880d681SAndroid Build Coastguard Worker }
794*9880d681SAndroid Build Coastguard Worker
795*9880d681SAndroid Build Coastguard Worker ConstantRange
udiv(const ConstantRange & RHS) const796*9880d681SAndroid Build Coastguard Worker ConstantRange::udiv(const ConstantRange &RHS) const {
797*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax() == 0)
798*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
799*9880d681SAndroid Build Coastguard Worker if (RHS.isFullSet())
800*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
801*9880d681SAndroid Build Coastguard Worker
802*9880d681SAndroid Build Coastguard Worker APInt Lower = getUnsignedMin().udiv(RHS.getUnsignedMax());
803*9880d681SAndroid Build Coastguard Worker
804*9880d681SAndroid Build Coastguard Worker APInt RHS_umin = RHS.getUnsignedMin();
805*9880d681SAndroid Build Coastguard Worker if (RHS_umin == 0) {
806*9880d681SAndroid Build Coastguard Worker // We want the lowest value in RHS excluding zero. Usually that would be 1
807*9880d681SAndroid Build Coastguard Worker // except for a range in the form of [X, 1) in which case it would be X.
808*9880d681SAndroid Build Coastguard Worker if (RHS.getUpper() == 1)
809*9880d681SAndroid Build Coastguard Worker RHS_umin = RHS.getLower();
810*9880d681SAndroid Build Coastguard Worker else
811*9880d681SAndroid Build Coastguard Worker RHS_umin = APInt(getBitWidth(), 1);
812*9880d681SAndroid Build Coastguard Worker }
813*9880d681SAndroid Build Coastguard Worker
814*9880d681SAndroid Build Coastguard Worker APInt Upper = getUnsignedMax().udiv(RHS_umin) + 1;
815*9880d681SAndroid Build Coastguard Worker
816*9880d681SAndroid Build Coastguard Worker // If the LHS is Full and the RHS is a wrapped interval containing 1 then
817*9880d681SAndroid Build Coastguard Worker // this could occur.
818*9880d681SAndroid Build Coastguard Worker if (Lower == Upper)
819*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
820*9880d681SAndroid Build Coastguard Worker
821*9880d681SAndroid Build Coastguard Worker return ConstantRange(Lower, Upper);
822*9880d681SAndroid Build Coastguard Worker }
823*9880d681SAndroid Build Coastguard Worker
824*9880d681SAndroid Build Coastguard Worker ConstantRange
binaryAnd(const ConstantRange & Other) const825*9880d681SAndroid Build Coastguard Worker ConstantRange::binaryAnd(const ConstantRange &Other) const {
826*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
827*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
828*9880d681SAndroid Build Coastguard Worker
829*9880d681SAndroid Build Coastguard Worker // TODO: replace this with something less conservative
830*9880d681SAndroid Build Coastguard Worker
831*9880d681SAndroid Build Coastguard Worker APInt umin = APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax());
832*9880d681SAndroid Build Coastguard Worker if (umin.isAllOnesValue())
833*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
834*9880d681SAndroid Build Coastguard Worker return ConstantRange(APInt::getNullValue(getBitWidth()), umin + 1);
835*9880d681SAndroid Build Coastguard Worker }
836*9880d681SAndroid Build Coastguard Worker
837*9880d681SAndroid Build Coastguard Worker ConstantRange
binaryOr(const ConstantRange & Other) const838*9880d681SAndroid Build Coastguard Worker ConstantRange::binaryOr(const ConstantRange &Other) const {
839*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
840*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
841*9880d681SAndroid Build Coastguard Worker
842*9880d681SAndroid Build Coastguard Worker // TODO: replace this with something less conservative
843*9880d681SAndroid Build Coastguard Worker
844*9880d681SAndroid Build Coastguard Worker APInt umax = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin());
845*9880d681SAndroid Build Coastguard Worker if (umax.isMinValue())
846*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
847*9880d681SAndroid Build Coastguard Worker return ConstantRange(umax, APInt::getNullValue(getBitWidth()));
848*9880d681SAndroid Build Coastguard Worker }
849*9880d681SAndroid Build Coastguard Worker
850*9880d681SAndroid Build Coastguard Worker ConstantRange
shl(const ConstantRange & Other) const851*9880d681SAndroid Build Coastguard Worker ConstantRange::shl(const ConstantRange &Other) const {
852*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
853*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
854*9880d681SAndroid Build Coastguard Worker
855*9880d681SAndroid Build Coastguard Worker APInt min = getUnsignedMin().shl(Other.getUnsignedMin());
856*9880d681SAndroid Build Coastguard Worker APInt max = getUnsignedMax().shl(Other.getUnsignedMax());
857*9880d681SAndroid Build Coastguard Worker
858*9880d681SAndroid Build Coastguard Worker // there's no overflow!
859*9880d681SAndroid Build Coastguard Worker APInt Zeros(getBitWidth(), getUnsignedMax().countLeadingZeros());
860*9880d681SAndroid Build Coastguard Worker if (Zeros.ugt(Other.getUnsignedMax()))
861*9880d681SAndroid Build Coastguard Worker return ConstantRange(min, max + 1);
862*9880d681SAndroid Build Coastguard Worker
863*9880d681SAndroid Build Coastguard Worker // FIXME: implement the other tricky cases
864*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
865*9880d681SAndroid Build Coastguard Worker }
866*9880d681SAndroid Build Coastguard Worker
867*9880d681SAndroid Build Coastguard Worker ConstantRange
lshr(const ConstantRange & Other) const868*9880d681SAndroid Build Coastguard Worker ConstantRange::lshr(const ConstantRange &Other) const {
869*9880d681SAndroid Build Coastguard Worker if (isEmptySet() || Other.isEmptySet())
870*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
871*9880d681SAndroid Build Coastguard Worker
872*9880d681SAndroid Build Coastguard Worker APInt max = getUnsignedMax().lshr(Other.getUnsignedMin());
873*9880d681SAndroid Build Coastguard Worker APInt min = getUnsignedMin().lshr(Other.getUnsignedMax());
874*9880d681SAndroid Build Coastguard Worker if (min == max + 1)
875*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
876*9880d681SAndroid Build Coastguard Worker
877*9880d681SAndroid Build Coastguard Worker return ConstantRange(min, max + 1);
878*9880d681SAndroid Build Coastguard Worker }
879*9880d681SAndroid Build Coastguard Worker
inverse() const880*9880d681SAndroid Build Coastguard Worker ConstantRange ConstantRange::inverse() const {
881*9880d681SAndroid Build Coastguard Worker if (isFullSet())
882*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/false);
883*9880d681SAndroid Build Coastguard Worker if (isEmptySet())
884*9880d681SAndroid Build Coastguard Worker return ConstantRange(getBitWidth(), /*isFullSet=*/true);
885*9880d681SAndroid Build Coastguard Worker return ConstantRange(Upper, Lower);
886*9880d681SAndroid Build Coastguard Worker }
887*9880d681SAndroid Build Coastguard Worker
888*9880d681SAndroid Build Coastguard Worker /// print - Print out the bounds to a stream...
889*9880d681SAndroid Build Coastguard Worker ///
print(raw_ostream & OS) const890*9880d681SAndroid Build Coastguard Worker void ConstantRange::print(raw_ostream &OS) const {
891*9880d681SAndroid Build Coastguard Worker if (isFullSet())
892*9880d681SAndroid Build Coastguard Worker OS << "full-set";
893*9880d681SAndroid Build Coastguard Worker else if (isEmptySet())
894*9880d681SAndroid Build Coastguard Worker OS << "empty-set";
895*9880d681SAndroid Build Coastguard Worker else
896*9880d681SAndroid Build Coastguard Worker OS << "[" << Lower << "," << Upper << ")";
897*9880d681SAndroid Build Coastguard Worker }
898*9880d681SAndroid Build Coastguard Worker
899*9880d681SAndroid Build Coastguard Worker /// dump - Allow printing from a debugger easily...
900*9880d681SAndroid Build Coastguard Worker ///
dump() const901*9880d681SAndroid Build Coastguard Worker LLVM_DUMP_METHOD void ConstantRange::dump() const {
902*9880d681SAndroid Build Coastguard Worker print(dbgs());
903*9880d681SAndroid Build Coastguard Worker }
904