blob: 876ade24d9621d7e23c024c477454ea496d6059c [file] [log] [blame]
Chris Lattner645e00d2002-09-01 23:53:36 +00001//===-- ConstantRange.cpp - ConstantRange implementation ------------------===//
Misha Brukmanfd939082005-04-21 23:48:37 +00002//
John Criswellb576c942003-10-20 19:43:21 +00003// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukmanfd939082005-04-21 23:48:37 +00007//
John Criswellb576c942003-10-20 19:43:21 +00008//===----------------------------------------------------------------------===//
Chris Lattner645e00d2002-09-01 23:53:36 +00009//
10// Represent a range of possible values that may occur when the program is run
11// for an integral value. This keeps track of a lower and upper bound for the
12// constant, which MAY wrap around the end of the numeric range. To do this, it
13// keeps track of a [lower, upper) bound, which specifies an interval just like
14// STL iterators. When used with boolean values, the following are important
15// ranges (other integral ranges use min/max values for special range values):
16//
17// [F, F) = {} = Empty set
18// [T, F) = {T}
19// [F, T) = {F}
20// [T, T) = {F, T} = Full set
21//
22//===----------------------------------------------------------------------===//
23
24#include "llvm/Support/ConstantRange.h"
Chris Lattner67bb7602004-01-12 20:13:04 +000025#include "llvm/Constants.h"
Chris Lattner645e00d2002-09-01 23:53:36 +000026#include "llvm/Instruction.h"
Reid Spencere4d87aa2006-12-23 06:05:41 +000027#include "llvm/Instructions.h"
Chris Lattner67bb7602004-01-12 20:13:04 +000028#include "llvm/Type.h"
Reid Spencerc1030572007-01-19 21:13:56 +000029#include "llvm/DerivedTypes.h"
Bill Wendling6f81b512006-11-28 22:46:12 +000030#include "llvm/Support/Streams.h"
31#include <ostream>
Chris Lattner2cdd21c2003-12-14 21:35:53 +000032using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000033
Chris Lattner645e00d2002-09-01 23:53:36 +000034/// Initialize a full (the default) or empty set for the specified type.
35///
Reid Spencer663e7112007-02-28 17:36:23 +000036ConstantRange::ConstantRange(const Type *Ty, bool Full) :
37 Lower(cast<IntegerType>(Ty)->getBitWidth(), 0),
38 Upper(cast<IntegerType>(Ty)->getBitWidth(), 0) {
39 uint32_t BitWidth = cast<IntegerType>(Ty)->getBitWidth();
Chris Lattner645e00d2002-09-01 23:53:36 +000040 if (Full)
Reid Spencer663e7112007-02-28 17:36:23 +000041 Lower = Upper = APInt::getMaxValue(BitWidth);
Chris Lattner645e00d2002-09-01 23:53:36 +000042 else
Reid Spencer663e7112007-02-28 17:36:23 +000043 Lower = Upper = APInt::getMinValue(BitWidth);
Chris Lattner645e00d2002-09-01 23:53:36 +000044}
45
Chris Lattnerfc33d302004-03-30 00:20:08 +000046/// Initialize a range to hold the single specified value.
47///
Reid Spencere4d87aa2006-12-23 06:05:41 +000048ConstantRange::ConstantRange(Constant *V)
Reid Spencer663e7112007-02-28 17:36:23 +000049 : Lower(cast<ConstantInt>(V)->getValue()),
50 Upper(cast<ConstantInt>(V)->getValue() + 1) { }
Chris Lattnerfc33d302004-03-30 00:20:08 +000051
Chris Lattner645e00d2002-09-01 23:53:36 +000052/// Initialize a range of values explicitly... this will assert out if
53/// Lower==Upper and Lower != Min or Max for its type (or if the two constants
54/// have different types)
55///
Reid Spencere4d87aa2006-12-23 06:05:41 +000056ConstantRange::ConstantRange(Constant *L, Constant *U)
Reid Spencer663e7112007-02-28 17:36:23 +000057 : Lower(cast<ConstantInt>(L)->getValue()),
58 Upper(cast<ConstantInt>(U)->getValue()) {
59 assert(L->getType() == U->getType() && "Invalid ConstantRange types!");
60 assert(L->getType()->isInteger() && "Invalid ConstantRange types!");
Misha Brukmanfd939082005-04-21 23:48:37 +000061
Chris Lattner645e00d2002-09-01 23:53:36 +000062 // Make sure that if L & U are equal that they are either Min or Max...
Reid Spencer663e7112007-02-28 17:36:23 +000063
64 uint32_t BitWidth = cast<IntegerType>(L->getType())->getBitWidth();
65 const IntegerType *Ty = cast<IntegerType>(L->getType());
66 assert((L != U || (L == ConstantInt::get(Ty, APInt::getMaxValue(BitWidth))
67 || L == ConstantInt::get(Ty, APInt::getMinValue(BitWidth))))
Reid Spencere4d87aa2006-12-23 06:05:41 +000068 && "Lower == Upper, but they aren't min or max for type!");
Chris Lattner645e00d2002-09-01 23:53:36 +000069}
70
Reid Spencer663e7112007-02-28 17:36:23 +000071ConstantRange::ConstantRange(const APInt &L, const APInt &U) :
72 Lower(L), Upper(U) {
73 assert(L.getBitWidth() == U.getBitWidth() &&
74 "ConstantRange with unequal bit widths");
75 uint32_t BitWidth = L.getBitWidth();
76 assert((L != U || (L == APInt::getMaxValue(BitWidth) ||
77 L == APInt::getMinValue(BitWidth))) &&
78 "Lower == Upper, but they aren't min or max value!");
79}
80
Chris Lattner645e00d2002-09-01 23:53:36 +000081/// Initialize a set of values that all satisfy the condition with C.
82///
Reid Spencer663e7112007-02-28 17:36:23 +000083ConstantRange::ConstantRange(unsigned short ICmpOpcode, ConstantInt *C)
84 : Lower(cast<IntegerType>(C->getType())->getBitWidth(), 0),
85 Upper(cast<IntegerType>(C->getType())->getBitWidth(), 0) {
86 const APInt& Val = C->getValue();
87 uint32_t BitWidth = cast<IntegerType>(C->getType())->getBitWidth();
Reid Spencere4d87aa2006-12-23 06:05:41 +000088 switch (ICmpOpcode) {
89 default: assert(0 && "Invalid ICmp opcode to ConstantRange ctor!");
Reid Spencer663e7112007-02-28 17:36:23 +000090 case ICmpInst::ICMP_EQ: Lower = Val; Upper = Val + 1; return;
91 case ICmpInst::ICMP_NE: Upper = Val; Lower = Val + 1; return;
Reid Spencere4d87aa2006-12-23 06:05:41 +000092 case ICmpInst::ICMP_ULT:
Reid Spencer663e7112007-02-28 17:36:23 +000093 Lower = APInt::getMinValue(BitWidth);
94 Upper = Val;
Chris Lattner645e00d2002-09-01 23:53:36 +000095 return;
Reid Spencere4d87aa2006-12-23 06:05:41 +000096 case ICmpInst::ICMP_SLT:
Reid Spencer663e7112007-02-28 17:36:23 +000097 Lower = APInt::getSignedMinValue(BitWidth);
98 Upper = Val;
Chris Lattner645e00d2002-09-01 23:53:36 +000099 return;
Reid Spencere4d87aa2006-12-23 06:05:41 +0000100 case ICmpInst::ICMP_UGT:
Reid Spencer663e7112007-02-28 17:36:23 +0000101 Lower = Val + 1;
102 Upper = APInt::getMinValue(BitWidth); // Min = Next(Max)
Reid Spencere4d87aa2006-12-23 06:05:41 +0000103 return;
104 case ICmpInst::ICMP_SGT:
Reid Spencer663e7112007-02-28 17:36:23 +0000105 Lower = Val + 1;
106 Upper = APInt::getSignedMinValue(BitWidth); // Min = Next(Max)
Reid Spencere4d87aa2006-12-23 06:05:41 +0000107 return;
108 case ICmpInst::ICMP_ULE:
Reid Spencer663e7112007-02-28 17:36:23 +0000109 Lower = APInt::getMinValue(BitWidth);
110 Upper = Val + 1;
Chris Lattner645e00d2002-09-01 23:53:36 +0000111 return;
Reid Spencere4d87aa2006-12-23 06:05:41 +0000112 case ICmpInst::ICMP_SLE:
Reid Spencer663e7112007-02-28 17:36:23 +0000113 Lower = APInt::getSignedMinValue(BitWidth);
114 Upper = Val + 1;
Reid Spencere4d87aa2006-12-23 06:05:41 +0000115 return;
116 case ICmpInst::ICMP_UGE:
Reid Spencer663e7112007-02-28 17:36:23 +0000117 Lower = Val;
118 Upper = APInt::getMinValue(BitWidth); // Min = Next(Max)
Reid Spencere4d87aa2006-12-23 06:05:41 +0000119 return;
120 case ICmpInst::ICMP_SGE:
Reid Spencer663e7112007-02-28 17:36:23 +0000121 Lower = Val;
122 Upper = APInt::getSignedMinValue(BitWidth); // Min = Next(Max)
Chris Lattner645e00d2002-09-01 23:53:36 +0000123 return;
124 }
125}
126
127/// getType - Return the LLVM data type of this range.
128///
Reid Spencer663e7112007-02-28 17:36:23 +0000129const Type *ConstantRange::getType() const {
130 return IntegerType::get(Lower.getBitWidth());
131}
132
133ConstantInt *ConstantRange::getLower() const {
134 return ConstantInt::get(getType(), Lower);
135}
136
137ConstantInt *ConstantRange::getUpper() const {
138 return ConstantInt::get(getType(), Upper);
139}
Chris Lattner645e00d2002-09-01 23:53:36 +0000140
141/// isFullSet - Return true if this set contains all of the elements possible
142/// for this data-type
143bool ConstantRange::isFullSet() const {
Reid Spencer663e7112007-02-28 17:36:23 +0000144 return Lower == Upper && Lower == APInt::getMaxValue(Lower.getBitWidth());
Chris Lattner645e00d2002-09-01 23:53:36 +0000145}
Misha Brukmanfd939082005-04-21 23:48:37 +0000146
Chris Lattner645e00d2002-09-01 23:53:36 +0000147/// isEmptySet - Return true if this set contains no members.
148///
149bool ConstantRange::isEmptySet() const {
Reid Spencer663e7112007-02-28 17:36:23 +0000150 return Lower == Upper && Lower == APInt::getMinValue(Lower.getBitWidth());
Chris Lattner645e00d2002-09-01 23:53:36 +0000151}
152
153/// isWrappedSet - Return true if this set wraps around the top of the range,
154/// for example: [100, 8)
155///
Reid Spencere4d87aa2006-12-23 06:05:41 +0000156bool ConstantRange::isWrappedSet(bool isSigned) const {
Reid Spencer663e7112007-02-28 17:36:23 +0000157 if (isSigned)
158 return Lower.sgt(Upper);
159 return Lower.ugt(Upper);
Chris Lattner645e00d2002-09-01 23:53:36 +0000160}
161
Chris Lattner645e00d2002-09-01 23:53:36 +0000162/// getSingleElement - If this set contains a single element, return it,
163/// otherwise return null.
Zhou Sheng6b6b6ef2007-01-11 12:24:14 +0000164ConstantInt *ConstantRange::getSingleElement() const {
Reid Spencer663e7112007-02-28 17:36:23 +0000165 if (Upper == Lower + 1) // Is it a single element range?
166 return ConstantInt::get(getType(), Lower);
Chris Lattner645e00d2002-09-01 23:53:36 +0000167 return 0;
168}
169
170/// getSetSize - Return the number of elements in this set.
171///
Reid Spencer663e7112007-02-28 17:36:23 +0000172APInt ConstantRange::getSetSize() const {
173 if (isEmptySet())
174 return APInt(Lower.getBitWidth(), 0);
Reid Spencer4fe16d62007-01-11 18:21:29 +0000175 if (getType() == Type::Int1Ty) {
Chris Lattner645e00d2002-09-01 23:53:36 +0000176 if (Lower != Upper) // One of T or F in the set...
Reid Spencer663e7112007-02-28 17:36:23 +0000177 return APInt(Lower.getBitWidth(), 1);
178 return APInt(Lower.getBitWidth(), 2); // Must be full set...
Chris Lattner645e00d2002-09-01 23:53:36 +0000179 }
Misha Brukmanfd939082005-04-21 23:48:37 +0000180
Chris Lattner645e00d2002-09-01 23:53:36 +0000181 // Simply subtract the bounds...
Reid Spencer663e7112007-02-28 17:36:23 +0000182 return Upper - Lower;
Chris Lattner645e00d2002-09-01 23:53:36 +0000183}
184
Chris Lattnerfc33d302004-03-30 00:20:08 +0000185/// contains - Return true if the specified value is in the set.
186///
Reid Spencere4d87aa2006-12-23 06:05:41 +0000187bool ConstantRange::contains(ConstantInt *Val, bool isSigned) const {
Chris Lattnerfc33d302004-03-30 00:20:08 +0000188 if (Lower == Upper) {
Reid Spencer663e7112007-02-28 17:36:23 +0000189 if (isFullSet())
190 return true;
Chris Lattnerfc33d302004-03-30 00:20:08 +0000191 return false;
192 }
Chris Lattner645e00d2002-09-01 23:53:36 +0000193
Reid Spencer663e7112007-02-28 17:36:23 +0000194 const APInt &V = Val->getValue();
Reid Spencere4d87aa2006-12-23 06:05:41 +0000195 if (!isWrappedSet(isSigned))
Reid Spencer663e7112007-02-28 17:36:23 +0000196 if (isSigned)
197 return Lower.sle(V) && V.slt(Upper);
198 else
199 return Lower.ule(V) && V.ult(Upper);
200 if (isSigned)
201 return Lower.sle(V) || V.slt(Upper);
202 else
203 return Lower.ule(V) || V.ult(Upper);
Chris Lattnerfc33d302004-03-30 00:20:08 +0000204}
205
Chris Lattnerfc33d302004-03-30 00:20:08 +0000206/// subtract - Subtract the specified constant from the endpoints of this
207/// constant range.
208ConstantRange ConstantRange::subtract(ConstantInt *CI) const {
Reid Spencer663e7112007-02-28 17:36:23 +0000209 assert(CI->getType() == getType() &&
Chris Lattnerfc33d302004-03-30 00:20:08 +0000210 "Cannot subtract from different type range or non-integer!");
211 // If the set is empty or full, don't modify the endpoints.
Reid Spencer663e7112007-02-28 17:36:23 +0000212 if (Lower == Upper)
213 return *this;
214
215 const APInt &Val = CI->getValue();
216 return ConstantRange(Lower - Val, Upper - Val);
Chris Lattnerfc33d302004-03-30 00:20:08 +0000217}
Chris Lattner645e00d2002-09-01 23:53:36 +0000218
219
220// intersect1Wrapped - This helper function is used to intersect two ranges when
221// it is known that LHS is wrapped and RHS isn't.
222//
Reid Spencer663e7112007-02-28 17:36:23 +0000223ConstantRange
224ConstantRange::intersect1Wrapped(const ConstantRange &LHS,
225 const ConstantRange &RHS, bool isSigned) {
Reid Spencere4d87aa2006-12-23 06:05:41 +0000226 assert(LHS.isWrappedSet(isSigned) && !RHS.isWrappedSet(isSigned));
Chris Lattner645e00d2002-09-01 23:53:36 +0000227
Chris Lattner645e00d2002-09-01 23:53:36 +0000228 // Check to see if we overlap on the Left side of RHS...
229 //
Reid Spencer663e7112007-02-28 17:36:23 +0000230 bool LT = (isSigned ? RHS.Lower.slt(LHS.Upper) : RHS.Lower.ult(LHS.Upper));
231 bool GT = (isSigned ? RHS.Upper.sgt(LHS.Lower) : RHS.Upper.ugt(LHS.Lower));
232 if (LT) {
Chris Lattner645e00d2002-09-01 23:53:36 +0000233 // We do overlap on the left side of RHS, see if we overlap on the right of
234 // RHS...
Reid Spencer663e7112007-02-28 17:36:23 +0000235 if (GT) {
Chris Lattner645e00d2002-09-01 23:53:36 +0000236 // Ok, the result overlaps on both the left and right sides. See if the
237 // resultant interval will be smaller if we wrap or not...
238 //
Reid Spencer663e7112007-02-28 17:36:23 +0000239 if (LHS.getSetSize().ult(RHS.getSetSize()))
Chris Lattner645e00d2002-09-01 23:53:36 +0000240 return LHS;
241 else
242 return RHS;
243
244 } else {
245 // No overlap on the right, just on the left.
246 return ConstantRange(RHS.getLower(), LHS.getUpper());
247 }
Chris Lattner645e00d2002-09-01 23:53:36 +0000248 } else {
249 // We don't overlap on the left side of RHS, see if we overlap on the right
250 // of RHS...
Reid Spencer663e7112007-02-28 17:36:23 +0000251 if (GT) {
Chris Lattner645e00d2002-09-01 23:53:36 +0000252 // Simple overlap...
253 return ConstantRange(LHS.getLower(), RHS.getUpper());
254 } else {
255 // No overlap...
256 return ConstantRange(LHS.getType(), false);
257 }
258 }
259}
260
Nick Lewycky3e051642007-02-11 00:58:49 +0000261/// intersectWith - Return the range that results from the intersection of this
Chris Lattner645e00d2002-09-01 23:53:36 +0000262/// range with another range.
263///
Reid Spencere4d87aa2006-12-23 06:05:41 +0000264ConstantRange ConstantRange::intersectWith(const ConstantRange &CR,
265 bool isSigned) const {
Chris Lattner645e00d2002-09-01 23:53:36 +0000266 assert(getType() == CR.getType() && "ConstantRange types don't agree!");
Chris Lattnerd122f4b2002-09-02 20:49:27 +0000267 // Handle common special cases
Reid Spencer663e7112007-02-28 17:36:23 +0000268 if (isEmptySet() || CR.isFullSet())
269 return *this;
270 if (isFullSet() || CR.isEmptySet())
271 return CR;
Chris Lattner645e00d2002-09-01 23:53:36 +0000272
Reid Spencere4d87aa2006-12-23 06:05:41 +0000273 if (!isWrappedSet(isSigned)) {
274 if (!CR.isWrappedSet(isSigned)) {
Reid Spencer663e7112007-02-28 17:36:23 +0000275 using namespace APIntOps;
276 APInt L = isSigned ? smax(Lower, CR.Lower) : umax(Lower, CR.Lower);
277 APInt U = isSigned ? smin(Upper, CR.Upper) : umin(Upper, CR.Upper);
Chris Lattner645e00d2002-09-01 23:53:36 +0000278
Reid Spencer663e7112007-02-28 17:36:23 +0000279 if (isSigned ? L.slt(U) : L.ult(U)) // If range isn't empty...
Chris Lattnerd122f4b2002-09-02 20:49:27 +0000280 return ConstantRange(L, U);
Chris Lattner645e00d2002-09-01 23:53:36 +0000281 else
282 return ConstantRange(getType(), false); // Otherwise, return empty set
283 } else
Reid Spencere4d87aa2006-12-23 06:05:41 +0000284 return intersect1Wrapped(CR, *this, isSigned);
Chris Lattner645e00d2002-09-01 23:53:36 +0000285 } else { // We know "this" is wrapped...
Reid Spencere4d87aa2006-12-23 06:05:41 +0000286 if (!CR.isWrappedSet(isSigned))
287 return intersect1Wrapped(*this, CR, isSigned);
Chris Lattner645e00d2002-09-01 23:53:36 +0000288 else {
289 // Both ranges are wrapped...
Reid Spencer663e7112007-02-28 17:36:23 +0000290 using namespace APIntOps;
291 APInt L = isSigned ? smax(Lower, CR.Lower) : umax(Lower, CR.Lower);
292 APInt U = isSigned ? smin(Upper, CR.Upper) : umin(Upper, CR.Upper);
Chris Lattnerd122f4b2002-09-02 20:49:27 +0000293 return ConstantRange(L, U);
Chris Lattner645e00d2002-09-01 23:53:36 +0000294 }
295 }
296 return *this;
297}
298
Nick Lewycky3e051642007-02-11 00:58:49 +0000299/// unionWith - Return the range that results from the union of this range with
Chris Lattner645e00d2002-09-01 23:53:36 +0000300/// another range. The resultant range is guaranteed to include the elements of
301/// both sets, but may contain more. For example, [3, 9) union [12,15) is [3,
302/// 15), which includes 9, 10, and 11, which were not included in either set
303/// before.
304///
Reid Spencere4d87aa2006-12-23 06:05:41 +0000305ConstantRange ConstantRange::unionWith(const ConstantRange &CR,
306 bool isSigned) const {
Chris Lattner645e00d2002-09-01 23:53:36 +0000307 assert(getType() == CR.getType() && "ConstantRange types don't agree!");
308
309 assert(0 && "Range union not implemented yet!");
310
311 return *this;
312}
Chris Lattner96f9d722002-09-02 00:18:22 +0000313
Chris Lattnerfc33d302004-03-30 00:20:08 +0000314/// zeroExtend - Return a new range in the specified integer type, which must
315/// be strictly larger than the current type. The returned range will
Reid Spencere4d87aa2006-12-23 06:05:41 +0000316/// correspond to the possible range of values as if the source range had been
Chris Lattnerfc33d302004-03-30 00:20:08 +0000317/// zero extended.
318ConstantRange ConstantRange::zeroExtend(const Type *Ty) const {
Reid Spencer663e7112007-02-28 17:36:23 +0000319 unsigned SrcTySize = Lower.getBitWidth();
320 unsigned DstTySize = Ty->getPrimitiveSizeInBits();
321 assert(SrcTySize < DstTySize && "Not a value extension");
Chris Lattnerfc33d302004-03-30 00:20:08 +0000322 if (isFullSet()) {
323 // Change a source full set into [0, 1 << 8*numbytes)
Chris Lattnerfc33d302004-03-30 00:20:08 +0000324 return ConstantRange(Constant::getNullValue(Ty),
Reid Spencere7ca0422007-01-08 01:26:33 +0000325 ConstantInt::get(Ty, 1ULL << SrcTySize));
Chris Lattnerfc33d302004-03-30 00:20:08 +0000326 }
327
Reid Spencer663e7112007-02-28 17:36:23 +0000328 APInt L = Lower; L.zext(DstTySize);
329 APInt U = Upper; U.zext(DstTySize);
330 return ConstantRange(L, U);
Chris Lattnerfc33d302004-03-30 00:20:08 +0000331}
332
333/// truncate - Return a new range in the specified integer type, which must be
334/// strictly smaller than the current type. The returned range will
Reid Spencere4d87aa2006-12-23 06:05:41 +0000335/// correspond to the possible range of values as if the source range had been
Chris Lattnerfc33d302004-03-30 00:20:08 +0000336/// truncated to the specified type.
337ConstantRange ConstantRange::truncate(const Type *Ty) const {
Reid Spencer663e7112007-02-28 17:36:23 +0000338 unsigned SrcTySize = Lower.getBitWidth();
339 unsigned DstTySize = Ty->getPrimitiveSizeInBits();
340 assert(SrcTySize > DstTySize && "Not a value truncation");
341 APInt Size = APInt::getMaxValue(DstTySize).zext(SrcTySize);
342 if (isFullSet() || getSetSize().ugt(Size))
Chris Lattnerfc33d302004-03-30 00:20:08 +0000343 return ConstantRange(getType());
344
Reid Spencer663e7112007-02-28 17:36:23 +0000345 APInt L = Lower; L.trunc(DstTySize);
346 APInt U = Upper; U.trunc(DstTySize);
347 return ConstantRange(L, U);
Chris Lattnerfc33d302004-03-30 00:20:08 +0000348}
349
Chris Lattner96f9d722002-09-02 00:18:22 +0000350/// print - Print out the bounds to a stream...
351///
352void ConstantRange::print(std::ostream &OS) const {
Reid Spencer663e7112007-02-28 17:36:23 +0000353 OS << "[" << Lower.toStringSigned(10) << ","
354 << Upper.toStringSigned(10) << " )";
Chris Lattner96f9d722002-09-02 00:18:22 +0000355}
356
357/// dump - Allow printing from a debugger easily...
358///
359void ConstantRange::dump() const {
Bill Wendlinge8156192006-12-07 01:30:32 +0000360 print(cerr);
Chris Lattner96f9d722002-09-02 00:18:22 +0000361}