xref: /aosp_15_r20/external/llvm/lib/IR/ConstantRange.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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