Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- ConstantRange.h - Represent a range ----------------------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | // |
||
9 | // Represent a range of possible values that may occur when the program is run |
||
10 | // for an integral value. This keeps track of a lower and upper bound for the |
||
11 | // constant, which MAY wrap around the end of the numeric range. To do this, it |
||
12 | // keeps track of a [lower, upper) bound, which specifies an interval just like |
||
13 | // STL iterators. When used with boolean values, the following are important |
||
14 | // ranges: : |
||
15 | // |
||
16 | // [F, F) = {} = Empty set |
||
17 | // [T, F) = {T} |
||
18 | // [F, T) = {F} |
||
19 | // [T, T) = {F, T} = Full set |
||
20 | // |
||
21 | // The other integral ranges use min/max values for special range values. For |
||
22 | // example, for 8-bit types, it uses: |
||
23 | // [0, 0) = {} = Empty set |
||
24 | // [255, 255) = {0..255} = Full Set |
||
25 | // |
||
26 | // Note that ConstantRange can be used to represent either signed or |
||
27 | // unsigned ranges. |
||
28 | // |
||
29 | //===----------------------------------------------------------------------===// |
||
30 | |||
31 | #ifndef LLVM_IR_CONSTANTRANGE_H |
||
32 | #define LLVM_IR_CONSTANTRANGE_H |
||
33 | |||
34 | #include "llvm/ADT/APInt.h" |
||
35 | #include "llvm/IR/InstrTypes.h" |
||
36 | #include "llvm/IR/Instruction.h" |
||
37 | #include "llvm/Support/Compiler.h" |
||
38 | #include <cstdint> |
||
39 | |||
40 | namespace llvm { |
||
41 | |||
42 | class MDNode; |
||
43 | class raw_ostream; |
||
44 | struct KnownBits; |
||
45 | |||
46 | /// This class represents a range of values. |
||
47 | class [[nodiscard]] ConstantRange { |
||
48 | APInt Lower, Upper; |
||
49 | |||
50 | /// Create empty constant range with same bitwidth. |
||
51 | ConstantRange getEmpty() const { |
||
52 | return ConstantRange(getBitWidth(), false); |
||
53 | } |
||
54 | |||
55 | /// Create full constant range with same bitwidth. |
||
56 | ConstantRange getFull() const { |
||
57 | return ConstantRange(getBitWidth(), true); |
||
58 | } |
||
59 | |||
60 | public: |
||
61 | /// Initialize a full or empty set for the specified bit width. |
||
62 | explicit ConstantRange(uint32_t BitWidth, bool isFullSet); |
||
63 | |||
64 | /// Initialize a range to hold the single specified value. |
||
65 | ConstantRange(APInt Value); |
||
66 | |||
67 | /// Initialize a range of values explicitly. This will assert out if |
||
68 | /// Lower==Upper and Lower != Min or Max value for its type. It will also |
||
69 | /// assert out if the two APInt's are not the same bit width. |
||
70 | ConstantRange(APInt Lower, APInt Upper); |
||
71 | |||
72 | /// Create empty constant range with the given bit width. |
||
73 | static ConstantRange getEmpty(uint32_t BitWidth) { |
||
74 | return ConstantRange(BitWidth, false); |
||
75 | } |
||
76 | |||
77 | /// Create full constant range with the given bit width. |
||
78 | static ConstantRange getFull(uint32_t BitWidth) { |
||
79 | return ConstantRange(BitWidth, true); |
||
80 | } |
||
81 | |||
82 | /// Create non-empty constant range with the given bounds. If Lower and |
||
83 | /// Upper are the same, a full range is returned. |
||
84 | static ConstantRange getNonEmpty(APInt Lower, APInt Upper) { |
||
85 | if (Lower == Upper) |
||
86 | return getFull(Lower.getBitWidth()); |
||
87 | return ConstantRange(std::move(Lower), std::move(Upper)); |
||
88 | } |
||
89 | |||
90 | /// Initialize a range based on a known bits constraint. The IsSigned flag |
||
91 | /// indicates whether the constant range should not wrap in the signed or |
||
92 | /// unsigned domain. |
||
93 | static ConstantRange fromKnownBits(const KnownBits &Known, bool IsSigned); |
||
94 | |||
95 | /// Produce the smallest range such that all values that may satisfy the given |
||
96 | /// predicate with any value contained within Other is contained in the |
||
97 | /// returned range. Formally, this returns a superset of |
||
98 | /// 'union over all y in Other . { x : icmp op x y is true }'. If the exact |
||
99 | /// answer is not representable as a ConstantRange, the return value will be a |
||
100 | /// proper superset of the above. |
||
101 | /// |
||
102 | /// Example: Pred = ult and Other = i8 [2, 5) returns Result = [0, 4) |
||
103 | static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, |
||
104 | const ConstantRange &Other); |
||
105 | |||
106 | /// Produce the largest range such that all values in the returned range |
||
107 | /// satisfy the given predicate with all values contained within Other. |
||
108 | /// Formally, this returns a subset of |
||
109 | /// 'intersection over all y in Other . { x : icmp op x y is true }'. If the |
||
110 | /// exact answer is not representable as a ConstantRange, the return value |
||
111 | /// will be a proper subset of the above. |
||
112 | /// |
||
113 | /// Example: Pred = ult and Other = i8 [2, 5) returns [0, 2) |
||
114 | static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred, |
||
115 | const ConstantRange &Other); |
||
116 | |||
117 | /// Produce the exact range such that all values in the returned range satisfy |
||
118 | /// the given predicate with any value contained within Other. Formally, this |
||
119 | /// returns the exact answer when the superset of 'union over all y in Other |
||
120 | /// is exactly same as the subset of intersection over all y in Other. |
||
121 | /// { x : icmp op x y is true}'. |
||
122 | /// |
||
123 | /// Example: Pred = ult and Other = i8 3 returns [0, 3) |
||
124 | static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred, |
||
125 | const APInt &Other); |
||
126 | |||
127 | /// Does the predicate \p Pred hold between ranges this and \p Other? |
||
128 | /// NOTE: false does not mean that inverse predicate holds! |
||
129 | bool icmp(CmpInst::Predicate Pred, const ConstantRange &Other) const; |
||
130 | |||
131 | /// Return true iff CR1 ult CR2 is equivalent to CR1 slt CR2. |
||
132 | /// Does not depend on strictness/direction of the predicate. |
||
133 | static bool |
||
134 | areInsensitiveToSignednessOfICmpPredicate(const ConstantRange &CR1, |
||
135 | const ConstantRange &CR2); |
||
136 | |||
137 | /// Return true iff CR1 ult CR2 is equivalent to CR1 sge CR2. |
||
138 | /// Does not depend on strictness/direction of the predicate. |
||
139 | static bool |
||
140 | areInsensitiveToSignednessOfInvertedICmpPredicate(const ConstantRange &CR1, |
||
141 | const ConstantRange &CR2); |
||
142 | |||
143 | /// If the comparison between constant ranges this and Other |
||
144 | /// is insensitive to the signedness of the comparison predicate, |
||
145 | /// return a predicate equivalent to \p Pred, with flipped signedness |
||
146 | /// (i.e. unsigned instead of signed or vice versa), and maybe inverted, |
||
147 | /// otherwise returns CmpInst::Predicate::BAD_ICMP_PREDICATE. |
||
148 | static CmpInst::Predicate |
||
149 | getEquivalentPredWithFlippedSignedness(CmpInst::Predicate Pred, |
||
150 | const ConstantRange &CR1, |
||
151 | const ConstantRange &CR2); |
||
152 | |||
153 | /// Produce the largest range containing all X such that "X BinOp Y" is |
||
154 | /// guaranteed not to wrap (overflow) for *all* Y in Other. However, there may |
||
155 | /// be *some* Y in Other for which additional X not contained in the result |
||
156 | /// also do not overflow. |
||
157 | /// |
||
158 | /// NoWrapKind must be one of OBO::NoUnsignedWrap or OBO::NoSignedWrap. |
||
159 | /// |
||
160 | /// Examples: |
||
161 | /// typedef OverflowingBinaryOperator OBO; |
||
162 | /// #define MGNR makeGuaranteedNoWrapRegion |
||
163 | /// MGNR(Add, [i8 1, 2), OBO::NoSignedWrap) == [-128, 127) |
||
164 | /// MGNR(Add, [i8 1, 2), OBO::NoUnsignedWrap) == [0, -1) |
||
165 | /// MGNR(Add, [i8 0, 1), OBO::NoUnsignedWrap) == Full Set |
||
166 | /// MGNR(Add, [i8 -1, 6), OBO::NoSignedWrap) == [INT_MIN+1, INT_MAX-4) |
||
167 | /// MGNR(Sub, [i8 1, 2), OBO::NoSignedWrap) == [-127, 128) |
||
168 | /// MGNR(Sub, [i8 1, 2), OBO::NoUnsignedWrap) == [1, 0) |
||
169 | static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp, |
||
170 | const ConstantRange &Other, |
||
171 | unsigned NoWrapKind); |
||
172 | |||
173 | /// Produce the range that contains X if and only if "X BinOp Other" does |
||
174 | /// not wrap. |
||
175 | static ConstantRange makeExactNoWrapRegion(Instruction::BinaryOps BinOp, |
||
176 | const APInt &Other, |
||
177 | unsigned NoWrapKind); |
||
178 | |||
179 | /// Returns true if ConstantRange calculations are supported for intrinsic |
||
180 | /// with \p IntrinsicID. |
||
181 | static bool isIntrinsicSupported(Intrinsic::ID IntrinsicID); |
||
182 | |||
183 | /// Compute range of intrinsic result for the given operand ranges. |
||
184 | static ConstantRange intrinsic(Intrinsic::ID IntrinsicID, |
||
185 | ArrayRef<ConstantRange> Ops); |
||
186 | |||
187 | /// Set up \p Pred and \p RHS such that |
||
188 | /// ConstantRange::makeExactICmpRegion(Pred, RHS) == *this. Return true if |
||
189 | /// successful. |
||
190 | bool getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS) const; |
||
191 | |||
192 | /// Set up \p Pred, \p RHS and \p Offset such that (V + Offset) Pred RHS |
||
193 | /// is true iff V is in the range. Prefers using Offset == 0 if possible. |
||
194 | void |
||
195 | getEquivalentICmp(CmpInst::Predicate &Pred, APInt &RHS, APInt &Offset) const; |
||
196 | |||
197 | /// Return the lower value for this range. |
||
198 | const APInt &getLower() const { return Lower; } |
||
199 | |||
200 | /// Return the upper value for this range. |
||
201 | const APInt &getUpper() const { return Upper; } |
||
202 | |||
203 | /// Get the bit width of this ConstantRange. |
||
204 | uint32_t getBitWidth() const { return Lower.getBitWidth(); } |
||
205 | |||
206 | /// Return true if this set contains all of the elements possible |
||
207 | /// for this data-type. |
||
208 | bool isFullSet() const; |
||
209 | |||
210 | /// Return true if this set contains no members. |
||
211 | bool isEmptySet() const; |
||
212 | |||
213 | /// Return true if this set wraps around the unsigned domain. Special cases: |
||
214 | /// * Empty set: Not wrapped. |
||
215 | /// * Full set: Not wrapped. |
||
216 | /// * [X, 0) == [X, Max]: Not wrapped. |
||
217 | bool isWrappedSet() const; |
||
218 | |||
219 | /// Return true if the exclusive upper bound wraps around the unsigned |
||
220 | /// domain. Special cases: |
||
221 | /// * Empty set: Not wrapped. |
||
222 | /// * Full set: Not wrapped. |
||
223 | /// * [X, 0): Wrapped. |
||
224 | bool isUpperWrapped() const; |
||
225 | |||
226 | /// Return true if this set wraps around the signed domain. Special cases: |
||
227 | /// * Empty set: Not wrapped. |
||
228 | /// * Full set: Not wrapped. |
||
229 | /// * [X, SignedMin) == [X, SignedMax]: Not wrapped. |
||
230 | bool isSignWrappedSet() const; |
||
231 | |||
232 | /// Return true if the (exclusive) upper bound wraps around the signed |
||
233 | /// domain. Special cases: |
||
234 | /// * Empty set: Not wrapped. |
||
235 | /// * Full set: Not wrapped. |
||
236 | /// * [X, SignedMin): Wrapped. |
||
237 | bool isUpperSignWrapped() const; |
||
238 | |||
239 | /// Return true if the specified value is in the set. |
||
240 | bool contains(const APInt &Val) const; |
||
241 | |||
242 | /// Return true if the other range is a subset of this one. |
||
243 | bool contains(const ConstantRange &CR) const; |
||
244 | |||
245 | /// If this set contains a single element, return it, otherwise return null. |
||
246 | const APInt *getSingleElement() const { |
||
247 | if (Upper == Lower + 1) |
||
248 | return &Lower; |
||
249 | return nullptr; |
||
250 | } |
||
251 | |||
252 | /// If this set contains all but a single element, return it, otherwise return |
||
253 | /// null. |
||
254 | const APInt *getSingleMissingElement() const { |
||
255 | if (Lower == Upper + 1) |
||
256 | return &Upper; |
||
257 | return nullptr; |
||
258 | } |
||
259 | |||
260 | /// Return true if this set contains exactly one member. |
||
261 | bool isSingleElement() const { return getSingleElement() != nullptr; } |
||
262 | |||
263 | /// Compare set size of this range with the range CR. |
||
264 | bool isSizeStrictlySmallerThan(const ConstantRange &CR) const; |
||
265 | |||
266 | /// Compare set size of this range with Value. |
||
267 | bool isSizeLargerThan(uint64_t MaxSize) const; |
||
268 | |||
269 | /// Return true if all values in this range are negative. |
||
270 | bool isAllNegative() const; |
||
271 | |||
272 | /// Return true if all values in this range are non-negative. |
||
273 | bool isAllNonNegative() const; |
||
274 | |||
275 | /// Return the largest unsigned value contained in the ConstantRange. |
||
276 | APInt getUnsignedMax() const; |
||
277 | |||
278 | /// Return the smallest unsigned value contained in the ConstantRange. |
||
279 | APInt getUnsignedMin() const; |
||
280 | |||
281 | /// Return the largest signed value contained in the ConstantRange. |
||
282 | APInt getSignedMax() const; |
||
283 | |||
284 | /// Return the smallest signed value contained in the ConstantRange. |
||
285 | APInt getSignedMin() const; |
||
286 | |||
287 | /// Return true if this range is equal to another range. |
||
288 | bool operator==(const ConstantRange &CR) const { |
||
289 | return Lower == CR.Lower && Upper == CR.Upper; |
||
290 | } |
||
291 | bool operator!=(const ConstantRange &CR) const { |
||
292 | return !operator==(CR); |
||
293 | } |
||
294 | |||
295 | /// Compute the maximal number of active bits needed to represent every value |
||
296 | /// in this range. |
||
297 | unsigned getActiveBits() const; |
||
298 | |||
299 | /// Compute the maximal number of bits needed to represent every value |
||
300 | /// in this signed range. |
||
301 | unsigned getMinSignedBits() const; |
||
302 | |||
303 | /// Subtract the specified constant from the endpoints of this constant range. |
||
304 | ConstantRange subtract(const APInt &CI) const; |
||
305 | |||
306 | /// Subtract the specified range from this range (aka relative complement of |
||
307 | /// the sets). |
||
308 | ConstantRange difference(const ConstantRange &CR) const; |
||
309 | |||
310 | /// If represented precisely, the result of some range operations may consist |
||
311 | /// of multiple disjoint ranges. As only a single range may be returned, any |
||
312 | /// range covering these disjoint ranges constitutes a valid result, but some |
||
313 | /// may be more useful than others depending on context. The preferred range |
||
314 | /// type specifies whether a range that is non-wrapping in the unsigned or |
||
315 | /// signed domain, or has the smallest size, is preferred. If a signedness is |
||
316 | /// preferred but all ranges are non-wrapping or all wrapping, then the |
||
317 | /// smallest set size is preferred. If there are multiple smallest sets, any |
||
318 | /// one of them may be returned. |
||
319 | enum PreferredRangeType { Smallest, Unsigned, Signed }; |
||
320 | |||
321 | /// Return the range that results from the intersection of this range with |
||
322 | /// another range. If the intersection is disjoint, such that two results |
||
323 | /// are possible, the preferred range is determined by the PreferredRangeType. |
||
324 | ConstantRange intersectWith(const ConstantRange &CR, |
||
325 | PreferredRangeType Type = Smallest) const; |
||
326 | |||
327 | /// Return the range that results from the union of this range |
||
328 | /// with another range. The resultant range is guaranteed to include the |
||
329 | /// elements of both sets, but may contain more. For example, [3, 9) union |
||
330 | /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included |
||
331 | /// in either set before. |
||
332 | ConstantRange unionWith(const ConstantRange &CR, |
||
333 | PreferredRangeType Type = Smallest) const; |
||
334 | |||
335 | /// Intersect the two ranges and return the result if it can be represented |
||
336 | /// exactly, otherwise return std::nullopt. |
||
337 | std::optional<ConstantRange> |
||
338 | exactIntersectWith(const ConstantRange &CR) const; |
||
339 | |||
340 | /// Union the two ranges and return the result if it can be represented |
||
341 | /// exactly, otherwise return std::nullopt. |
||
342 | std::optional<ConstantRange> exactUnionWith(const ConstantRange &CR) const; |
||
343 | |||
344 | /// Return a new range representing the possible values resulting |
||
345 | /// from an application of the specified cast operator to this range. \p |
||
346 | /// BitWidth is the target bitwidth of the cast. For casts which don't |
||
347 | /// change bitwidth, it must be the same as the source bitwidth. For casts |
||
348 | /// which do change bitwidth, the bitwidth must be consistent with the |
||
349 | /// requested cast and source bitwidth. |
||
350 | ConstantRange castOp(Instruction::CastOps CastOp, |
||
351 | uint32_t BitWidth) const; |
||
352 | |||
353 | /// Return a new range in the specified integer type, which must |
||
354 | /// be strictly larger than the current type. The returned range will |
||
355 | /// correspond to the possible range of values if the source range had been |
||
356 | /// zero extended to BitWidth. |
||
357 | ConstantRange zeroExtend(uint32_t BitWidth) const; |
||
358 | |||
359 | /// Return a new range in the specified integer type, which must |
||
360 | /// be strictly larger than the current type. The returned range will |
||
361 | /// correspond to the possible range of values if the source range had been |
||
362 | /// sign extended to BitWidth. |
||
363 | ConstantRange signExtend(uint32_t BitWidth) const; |
||
364 | |||
365 | /// Return a new range in the specified integer type, which must be |
||
366 | /// strictly smaller than the current type. The returned range will |
||
367 | /// correspond to the possible range of values if the source range had been |
||
368 | /// truncated to the specified type. |
||
369 | ConstantRange truncate(uint32_t BitWidth) const; |
||
370 | |||
371 | /// Make this range have the bit width given by \p BitWidth. The |
||
372 | /// value is zero extended, truncated, or left alone to make it that width. |
||
373 | ConstantRange zextOrTrunc(uint32_t BitWidth) const; |
||
374 | |||
375 | /// Make this range have the bit width given by \p BitWidth. The |
||
376 | /// value is sign extended, truncated, or left alone to make it that width. |
||
377 | ConstantRange sextOrTrunc(uint32_t BitWidth) const; |
||
378 | |||
379 | /// Return a new range representing the possible values resulting |
||
380 | /// from an application of the specified binary operator to an left hand side |
||
381 | /// of this range and a right hand side of \p Other. |
||
382 | ConstantRange binaryOp(Instruction::BinaryOps BinOp, |
||
383 | const ConstantRange &Other) const; |
||
384 | |||
385 | /// Return a new range representing the possible values resulting |
||
386 | /// from an application of the specified overflowing binary operator to a |
||
387 | /// left hand side of this range and a right hand side of \p Other given |
||
388 | /// the provided knowledge about lack of wrapping \p NoWrapKind. |
||
389 | ConstantRange overflowingBinaryOp(Instruction::BinaryOps BinOp, |
||
390 | const ConstantRange &Other, |
||
391 | unsigned NoWrapKind) const; |
||
392 | |||
393 | /// Return a new range representing the possible values resulting |
||
394 | /// from an addition of a value in this range and a value in \p Other. |
||
395 | ConstantRange add(const ConstantRange &Other) const; |
||
396 | |||
397 | /// Return a new range representing the possible values resulting |
||
398 | /// from an addition with wrap type \p NoWrapKind of a value in this |
||
399 | /// range and a value in \p Other. |
||
400 | /// If the result range is disjoint, the preferred range is determined by the |
||
401 | /// \p PreferredRangeType. |
||
402 | ConstantRange addWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind, |
||
403 | PreferredRangeType RangeType = Smallest) const; |
||
404 | |||
405 | /// Return a new range representing the possible values resulting |
||
406 | /// from a subtraction of a value in this range and a value in \p Other. |
||
407 | ConstantRange sub(const ConstantRange &Other) const; |
||
408 | |||
409 | /// Return a new range representing the possible values resulting |
||
410 | /// from an subtraction with wrap type \p NoWrapKind of a value in this |
||
411 | /// range and a value in \p Other. |
||
412 | /// If the result range is disjoint, the preferred range is determined by the |
||
413 | /// \p PreferredRangeType. |
||
414 | ConstantRange subWithNoWrap(const ConstantRange &Other, unsigned NoWrapKind, |
||
415 | PreferredRangeType RangeType = Smallest) const; |
||
416 | |||
417 | /// Return a new range representing the possible values resulting |
||
418 | /// from a multiplication of a value in this range and a value in \p Other, |
||
419 | /// treating both this and \p Other as unsigned ranges. |
||
420 | ConstantRange multiply(const ConstantRange &Other) const; |
||
421 | |||
422 | /// Return range of possible values for a signed multiplication of this and |
||
423 | /// \p Other. However, if overflow is possible always return a full range |
||
424 | /// rather than trying to determine a more precise result. |
||
425 | ConstantRange smul_fast(const ConstantRange &Other) const; |
||
426 | |||
427 | /// Return a new range representing the possible values resulting |
||
428 | /// from a signed maximum of a value in this range and a value in \p Other. |
||
429 | ConstantRange smax(const ConstantRange &Other) const; |
||
430 | |||
431 | /// Return a new range representing the possible values resulting |
||
432 | /// from an unsigned maximum of a value in this range and a value in \p Other. |
||
433 | ConstantRange umax(const ConstantRange &Other) const; |
||
434 | |||
435 | /// Return a new range representing the possible values resulting |
||
436 | /// from a signed minimum of a value in this range and a value in \p Other. |
||
437 | ConstantRange smin(const ConstantRange &Other) const; |
||
438 | |||
439 | /// Return a new range representing the possible values resulting |
||
440 | /// from an unsigned minimum of a value in this range and a value in \p Other. |
||
441 | ConstantRange umin(const ConstantRange &Other) const; |
||
442 | |||
443 | /// Return a new range representing the possible values resulting |
||
444 | /// from an unsigned division of a value in this range and a value in |
||
445 | /// \p Other. |
||
446 | ConstantRange udiv(const ConstantRange &Other) const; |
||
447 | |||
448 | /// Return a new range representing the possible values resulting |
||
449 | /// from a signed division of a value in this range and a value in |
||
450 | /// \p Other. Division by zero and division of SignedMin by -1 are considered |
||
451 | /// undefined behavior, in line with IR, and do not contribute towards the |
||
452 | /// result. |
||
453 | ConstantRange sdiv(const ConstantRange &Other) const; |
||
454 | |||
455 | /// Return a new range representing the possible values resulting |
||
456 | /// from an unsigned remainder operation of a value in this range and a |
||
457 | /// value in \p Other. |
||
458 | ConstantRange urem(const ConstantRange &Other) const; |
||
459 | |||
460 | /// Return a new range representing the possible values resulting |
||
461 | /// from a signed remainder operation of a value in this range and a |
||
462 | /// value in \p Other. |
||
463 | ConstantRange srem(const ConstantRange &Other) const; |
||
464 | |||
465 | /// Return a new range representing the possible values resulting from |
||
466 | /// a binary-xor of a value in this range by an all-one value, |
||
467 | /// aka bitwise complement operation. |
||
468 | ConstantRange binaryNot() const; |
||
469 | |||
470 | /// Return a new range representing the possible values resulting |
||
471 | /// from a binary-and of a value in this range by a value in \p Other. |
||
472 | ConstantRange binaryAnd(const ConstantRange &Other) const; |
||
473 | |||
474 | /// Return a new range representing the possible values resulting |
||
475 | /// from a binary-or of a value in this range by a value in \p Other. |
||
476 | ConstantRange binaryOr(const ConstantRange &Other) const; |
||
477 | |||
478 | /// Return a new range representing the possible values resulting |
||
479 | /// from a binary-xor of a value in this range by a value in \p Other. |
||
480 | ConstantRange binaryXor(const ConstantRange &Other) const; |
||
481 | |||
482 | /// Return a new range representing the possible values resulting |
||
483 | /// from a left shift of a value in this range by a value in \p Other. |
||
484 | /// TODO: This isn't fully implemented yet. |
||
485 | ConstantRange shl(const ConstantRange &Other) const; |
||
486 | |||
487 | /// Return a new range representing the possible values resulting from a |
||
488 | /// logical right shift of a value in this range and a value in \p Other. |
||
489 | ConstantRange lshr(const ConstantRange &Other) const; |
||
490 | |||
491 | /// Return a new range representing the possible values resulting from a |
||
492 | /// arithmetic right shift of a value in this range and a value in \p Other. |
||
493 | ConstantRange ashr(const ConstantRange &Other) const; |
||
494 | |||
495 | /// Perform an unsigned saturating addition of two constant ranges. |
||
496 | ConstantRange uadd_sat(const ConstantRange &Other) const; |
||
497 | |||
498 | /// Perform a signed saturating addition of two constant ranges. |
||
499 | ConstantRange sadd_sat(const ConstantRange &Other) const; |
||
500 | |||
501 | /// Perform an unsigned saturating subtraction of two constant ranges. |
||
502 | ConstantRange usub_sat(const ConstantRange &Other) const; |
||
503 | |||
504 | /// Perform a signed saturating subtraction of two constant ranges. |
||
505 | ConstantRange ssub_sat(const ConstantRange &Other) const; |
||
506 | |||
507 | /// Perform an unsigned saturating multiplication of two constant ranges. |
||
508 | ConstantRange umul_sat(const ConstantRange &Other) const; |
||
509 | |||
510 | /// Perform a signed saturating multiplication of two constant ranges. |
||
511 | ConstantRange smul_sat(const ConstantRange &Other) const; |
||
512 | |||
513 | /// Perform an unsigned saturating left shift of this constant range by a |
||
514 | /// value in \p Other. |
||
515 | ConstantRange ushl_sat(const ConstantRange &Other) const; |
||
516 | |||
517 | /// Perform a signed saturating left shift of this constant range by a |
||
518 | /// value in \p Other. |
||
519 | ConstantRange sshl_sat(const ConstantRange &Other) const; |
||
520 | |||
521 | /// Return a new range that is the logical not of the current set. |
||
522 | ConstantRange inverse() const; |
||
523 | |||
524 | /// Calculate absolute value range. If the original range contains signed |
||
525 | /// min, then the resulting range will contain signed min if and only if |
||
526 | /// \p IntMinIsPoison is false. |
||
527 | ConstantRange abs(bool IntMinIsPoison = false) const; |
||
528 | |||
529 | /// Represents whether an operation on the given constant range is known to |
||
530 | /// always or never overflow. |
||
531 | enum class OverflowResult { |
||
532 | /// Always overflows in the direction of signed/unsigned min value. |
||
533 | AlwaysOverflowsLow, |
||
534 | /// Always overflows in the direction of signed/unsigned max value. |
||
535 | AlwaysOverflowsHigh, |
||
536 | /// May or may not overflow. |
||
537 | MayOverflow, |
||
538 | /// Never overflows. |
||
539 | NeverOverflows, |
||
540 | }; |
||
541 | |||
542 | /// Return whether unsigned add of the two ranges always/never overflows. |
||
543 | OverflowResult unsignedAddMayOverflow(const ConstantRange &Other) const; |
||
544 | |||
545 | /// Return whether signed add of the two ranges always/never overflows. |
||
546 | OverflowResult signedAddMayOverflow(const ConstantRange &Other) const; |
||
547 | |||
548 | /// Return whether unsigned sub of the two ranges always/never overflows. |
||
549 | OverflowResult unsignedSubMayOverflow(const ConstantRange &Other) const; |
||
550 | |||
551 | /// Return whether signed sub of the two ranges always/never overflows. |
||
552 | OverflowResult signedSubMayOverflow(const ConstantRange &Other) const; |
||
553 | |||
554 | /// Return whether unsigned mul of the two ranges always/never overflows. |
||
555 | OverflowResult unsignedMulMayOverflow(const ConstantRange &Other) const; |
||
556 | |||
557 | /// Return known bits for values in this range. |
||
558 | KnownBits toKnownBits() const; |
||
559 | |||
560 | /// Print out the bounds to a stream. |
||
561 | void print(raw_ostream &OS) const; |
||
562 | |||
563 | /// Allow printing from a debugger easily. |
||
564 | void dump() const; |
||
565 | }; |
||
566 | |||
567 | inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) { |
||
568 | CR.print(OS); |
||
569 | return OS; |
||
570 | } |
||
571 | |||
572 | /// Parse out a conservative ConstantRange from !range metadata. |
||
573 | /// |
||
574 | /// E.g. if RangeMD is !{i32 0, i32 10, i32 15, i32 20} then return [0, 20). |
||
575 | ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD); |
||
576 | |||
577 | } // end namespace llvm |
||
578 | |||
579 | #endif // LLVM_IR_CONSTANTRANGE_H |