1 //===-- ConstantRange.cpp - ConstantRange implementation ------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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):
17 // [F, F) = {} = Empty set
20 // [T, T) = {F, T} = Full set
22 //===----------------------------------------------------------------------===//
24 #include "llvm/Support/ConstantRange.h"
25 #include "llvm/Support/raw_ostream.h"
28 /// Initialize a full (the default) or empty set for the specified type.
30 ConstantRange::ConstantRange(uint32_t BitWidth
, bool Full
) :
31 Lower(BitWidth
, 0), Upper(BitWidth
, 0) {
33 Lower
= Upper
= APInt::getMaxValue(BitWidth
);
35 Lower
= Upper
= APInt::getMinValue(BitWidth
);
38 /// Initialize a range to hold the single specified value.
40 ConstantRange::ConstantRange(const APInt
& V
) : Lower(V
), Upper(V
+ 1) { }
42 ConstantRange::ConstantRange(const APInt
&L
, const APInt
&U
) :
44 assert(L
.getBitWidth() == U
.getBitWidth() &&
45 "ConstantRange with unequal bit widths");
46 assert((L
!= U
|| (L
.isMaxValue() || L
.isMinValue())) &&
47 "Lower == Upper, but they aren't min or max value!");
50 /// isFullSet - Return true if this set contains all of the elements possible
51 /// for this data-type
52 bool ConstantRange::isFullSet() const {
53 return Lower
== Upper
&& Lower
.isMaxValue();
56 /// isEmptySet - Return true if this set contains no members.
58 bool ConstantRange::isEmptySet() const {
59 return Lower
== Upper
&& Lower
.isMinValue();
62 /// isWrappedSet - Return true if this set wraps around the top of the range,
63 /// for example: [100, 8)
65 bool ConstantRange::isWrappedSet() const {
66 return Lower
.ugt(Upper
);
69 /// getSetSize - Return the number of elements in this set.
71 APInt
ConstantRange::getSetSize() const {
73 return APInt(getBitWidth(), 0);
74 if (getBitWidth() == 1) {
75 if (Lower
!= Upper
) // One of T or F in the set...
77 return APInt(2, 2); // Must be full set...
80 // Simply subtract the bounds...
84 /// getUnsignedMax - Return the largest unsigned value contained in the
87 APInt
ConstantRange::getUnsignedMax() const {
88 if (isFullSet() || isWrappedSet())
89 return APInt::getMaxValue(getBitWidth());
91 return getUpper() - 1;
94 /// getUnsignedMin - Return the smallest unsigned value contained in the
97 APInt
ConstantRange::getUnsignedMin() const {
98 if (isFullSet() || (isWrappedSet() && getUpper() != 0))
99 return APInt::getMinValue(getBitWidth());
104 /// getSignedMax - Return the largest signed value contained in the
107 APInt
ConstantRange::getSignedMax() const {
108 APInt
SignedMax(APInt::getSignedMaxValue(getBitWidth()));
109 if (!isWrappedSet()) {
110 if (getLower().sle(getUpper() - 1))
111 return getUpper() - 1;
115 if ((getUpper() - 1).slt(getLower())) {
116 if (getLower() != SignedMax
)
119 return getUpper() - 1;
121 return getUpper() - 1;
126 /// getSignedMin - Return the smallest signed value contained in the
129 APInt
ConstantRange::getSignedMin() const {
130 APInt
SignedMin(APInt::getSignedMinValue(getBitWidth()));
131 if (!isWrappedSet()) {
132 if (getLower().sle(getUpper() - 1))
137 if ((getUpper() - 1).slt(getLower())) {
138 if (getUpper() != SignedMin
)
148 /// contains - Return true if the specified value is in the set.
150 bool ConstantRange::contains(const APInt
&V
) const {
155 return Lower
.ule(V
) && V
.ult(Upper
);
157 return Lower
.ule(V
) || V
.ult(Upper
);
160 /// subtract - Subtract the specified constant from the endpoints of this
162 ConstantRange
ConstantRange::subtract(const APInt
&Val
) const {
163 assert(Val
.getBitWidth() == getBitWidth() && "Wrong bit width");
164 // If the set is empty or full, don't modify the endpoints.
167 return ConstantRange(Lower
- Val
, Upper
- Val
);
171 // intersect1Wrapped - This helper function is used to intersect two ranges when
172 // it is known that LHS is wrapped and RHS isn't.
175 ConstantRange::intersect1Wrapped(const ConstantRange
&LHS
,
176 const ConstantRange
&RHS
) {
177 assert(LHS
.isWrappedSet() && !RHS
.isWrappedSet());
179 // Check to see if we overlap on the Left side of RHS...
181 if (RHS
.Lower
.ult(LHS
.Upper
)) {
182 // We do overlap on the left side of RHS, see if we overlap on the right of
184 if (RHS
.Upper
.ugt(LHS
.Lower
)) {
185 // Ok, the result overlaps on both the left and right sides. See if the
186 // resultant interval will be smaller if we wrap or not...
188 if (LHS
.getSetSize().ult(RHS
.getSetSize()))
194 // No overlap on the right, just on the left.
195 return ConstantRange(RHS
.Lower
, LHS
.Upper
);
198 // We don't overlap on the left side of RHS, see if we overlap on the right
200 if (RHS
.Upper
.ugt(LHS
.Lower
)) {
202 return ConstantRange(LHS
.Lower
, RHS
.Upper
);
205 return ConstantRange(LHS
.getBitWidth(), false);
210 /// intersectWith - Return the range that results from the intersection of this
211 /// range with another range.
213 ConstantRange
ConstantRange::intersectWith(const ConstantRange
&CR
) const {
214 assert(getBitWidth() == CR
.getBitWidth() &&
215 "ConstantRange types don't agree!");
216 // Handle common special cases
217 if (isEmptySet() || CR
.isFullSet())
219 if (isFullSet() || CR
.isEmptySet())
222 if (!isWrappedSet()) {
223 if (!CR
.isWrappedSet()) {
224 using namespace APIntOps
;
225 APInt L
= umax(Lower
, CR
.Lower
);
226 APInt U
= umin(Upper
, CR
.Upper
);
228 if (L
.ult(U
)) // If range isn't empty...
229 return ConstantRange(L
, U
);
231 return ConstantRange(getBitWidth(), false);// Otherwise, empty set
233 return intersect1Wrapped(CR
, *this);
234 } else { // We know "this" is wrapped...
235 if (!CR
.isWrappedSet())
236 return intersect1Wrapped(*this, CR
);
238 // Both ranges are wrapped...
239 using namespace APIntOps
;
240 APInt L
= umax(Lower
, CR
.Lower
);
241 APInt U
= umin(Upper
, CR
.Upper
);
242 return ConstantRange(L
, U
);
248 /// maximalIntersectWith - Return the range that results from the intersection
249 /// of this range with another range. The resultant range is guaranteed to
250 /// include all elements contained in both input ranges, and to have the
251 /// smallest possible set size that does so. Because there may be two
252 /// intersections with the same set size, A.maximalIntersectWith(B) might not
253 /// be equal to B.maximalIntersect(A).
254 ConstantRange
ConstantRange::maximalIntersectWith(const ConstantRange
&CR
) const {
255 assert(getBitWidth() == CR
.getBitWidth() &&
256 "ConstantRange types don't agree!");
258 // Handle common cases.
259 if ( isEmptySet() || CR
.isFullSet()) return *this;
260 if (CR
.isEmptySet() || isFullSet()) return CR
;
262 if (!isWrappedSet() && CR
.isWrappedSet())
263 return CR
.maximalIntersectWith(*this);
265 if (!isWrappedSet() && !CR
.isWrappedSet()) {
266 if (Lower
.ult(CR
.Lower
)) {
267 if (Upper
.ule(CR
.Lower
))
268 return ConstantRange(getBitWidth(), false);
270 if (Upper
.ult(CR
.Upper
))
271 return ConstantRange(CR
.Lower
, Upper
);
275 if (Upper
.ult(CR
.Upper
))
278 if (Lower
.ult(CR
.Upper
))
279 return ConstantRange(Lower
, CR
.Upper
);
281 return ConstantRange(getBitWidth(), false);
285 if (isWrappedSet() && !CR
.isWrappedSet()) {
286 if (CR
.Lower
.ult(Upper
)) {
287 if (CR
.Upper
.ult(Upper
))
290 if (CR
.Upper
.ult(Lower
))
291 return ConstantRange(CR
.Lower
, Upper
);
293 if (getSetSize().ult(CR
.getSetSize()))
297 } else if (CR
.Lower
.ult(Lower
)) {
298 if (CR
.Upper
.ule(Lower
))
299 return ConstantRange(getBitWidth(), false);
301 return ConstantRange(Lower
, CR
.Upper
);
306 if (CR
.Upper
.ult(Upper
)) {
307 if (CR
.Lower
.ult(Upper
)) {
308 if (getSetSize().ult(CR
.getSetSize()))
314 if (CR
.Lower
.ult(Lower
))
315 return ConstantRange(Lower
, CR
.Upper
);
318 } else if (CR
.Upper
.ult(Lower
)) {
319 if (CR
.Lower
.ult(Lower
))
322 return ConstantRange(CR
.Lower
, Upper
);
324 if (getSetSize().ult(CR
.getSetSize()))
331 /// unionWith - Return the range that results from the union of this range with
332 /// another range. The resultant range is guaranteed to include the elements of
333 /// both sets, but may contain more. For example, [3, 9) union [12,15) is
334 /// [3, 15), which includes 9, 10, and 11, which were not included in either
337 ConstantRange
ConstantRange::unionWith(const ConstantRange
&CR
) const {
338 assert(getBitWidth() == CR
.getBitWidth() &&
339 "ConstantRange types don't agree!");
341 if ( isFullSet() || CR
.isEmptySet()) return *this;
342 if (CR
.isFullSet() || isEmptySet()) return CR
;
344 if (!isWrappedSet() && CR
.isWrappedSet()) return CR
.unionWith(*this);
346 APInt L
= Lower
, U
= Upper
;
348 if (!isWrappedSet() && !CR
.isWrappedSet()) {
356 if (isWrappedSet() && !CR
.isWrappedSet()) {
357 if ((CR
.Lower
.ult(Upper
) && CR
.Upper
.ult(Upper
)) ||
358 (CR
.Lower
.ugt(Lower
) && CR
.Upper
.ugt(Lower
))) {
362 if (CR
.Lower
.ule(Upper
) && Lower
.ule(CR
.Upper
)) {
363 return ConstantRange(getBitWidth());
366 if (CR
.Lower
.ule(Upper
) && CR
.Upper
.ule(Lower
)) {
367 APInt d1
= CR
.Upper
- Upper
, d2
= Lower
- CR
.Upper
;
375 if (Upper
.ult(CR
.Lower
) && CR
.Upper
.ult(Lower
)) {
376 APInt d1
= CR
.Lower
- Upper
, d2
= Lower
- CR
.Upper
;
384 if (Upper
.ult(CR
.Lower
) && Lower
.ult(CR
.Upper
)) {
385 APInt d1
= CR
.Lower
- Upper
, d2
= Lower
- CR
.Lower
;
395 if (isWrappedSet() && CR
.isWrappedSet()) {
396 if (Lower
.ult(CR
.Upper
) || CR
.Lower
.ult(Upper
))
397 return ConstantRange(getBitWidth());
399 if (CR
.Upper
.ugt(U
)) {
403 if (CR
.Lower
.ult(L
)) {
407 if (L
== U
) return ConstantRange(getBitWidth());
410 return ConstantRange(L
, U
);
413 /// zeroExtend - Return a new range in the specified integer type, which must
414 /// be strictly larger than the current type. The returned range will
415 /// correspond to the possible range of values as if the source range had been
417 ConstantRange
ConstantRange::zeroExtend(uint32_t DstTySize
) const {
418 unsigned SrcTySize
= getBitWidth();
419 assert(SrcTySize
< DstTySize
&& "Not a value extension");
421 // Change a source full set into [0, 1 << 8*numbytes)
422 return ConstantRange(APInt(DstTySize
,0), APInt(DstTySize
,1).shl(SrcTySize
));
424 APInt L
= Lower
; L
.zext(DstTySize
);
425 APInt U
= Upper
; U
.zext(DstTySize
);
426 return ConstantRange(L
, U
);
429 /// signExtend - Return a new range in the specified integer type, which must
430 /// be strictly larger than the current type. The returned range will
431 /// correspond to the possible range of values as if the source range had been
433 ConstantRange
ConstantRange::signExtend(uint32_t DstTySize
) const {
434 unsigned SrcTySize
= getBitWidth();
435 assert(SrcTySize
< DstTySize
&& "Not a value extension");
437 return ConstantRange(APInt::getHighBitsSet(DstTySize
,DstTySize
-SrcTySize
+1),
438 APInt::getLowBitsSet(DstTySize
, SrcTySize
-1));
441 APInt L
= Lower
; L
.sext(DstTySize
);
442 APInt U
= Upper
; U
.sext(DstTySize
);
443 return ConstantRange(L
, U
);
446 /// truncate - Return a new range in the specified integer type, which must be
447 /// strictly smaller than the current type. The returned range will
448 /// correspond to the possible range of values as if the source range had been
449 /// truncated to the specified type.
450 ConstantRange
ConstantRange::truncate(uint32_t DstTySize
) const {
451 unsigned SrcTySize
= getBitWidth();
452 assert(SrcTySize
> DstTySize
&& "Not a value truncation");
453 APInt
Size(APInt::getLowBitsSet(SrcTySize
, DstTySize
));
454 if (isFullSet() || getSetSize().ugt(Size
))
455 return ConstantRange(DstTySize
);
457 APInt L
= Lower
; L
.trunc(DstTySize
);
458 APInt U
= Upper
; U
.trunc(DstTySize
);
459 return ConstantRange(L
, U
);
462 /// print - Print out the bounds to a stream...
464 void ConstantRange::print(raw_ostream
&OS
) const {
465 OS
<< "[" << Lower
<< "," << Upper
<< ")";
468 /// dump - Allow printing from a debugger easily...
470 void ConstantRange::dump() const {