MLIR  20.0.0git
InferIntRangeCommon.h
Go to the documentation of this file.
1 //===- InferIntRangeCommon.cpp - Inference for common ops --*- 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 // This file declares implementations of range inference for operations that are
10 // common to both the `arith` and `index` dialects to facilitate reuse.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_INTERFACES_UTILS_INFERINTRANGECOMMON_H
15 #define MLIR_INTERFACES_UTILS_INFERINTRANGECOMMON_H
16 
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/BitmaskEnum.h"
20 #include <optional>
21 
22 namespace mlir {
23 namespace intrange {
24 /// Function that performs inference on an array of `ConstantIntRanges`,
25 /// abstracted away here to permit writing the function that handles both
26 /// 64- and 32-bit index types.
27 using InferRangeFn =
29 
30 /// Function that performs inferrence on an array of `IntegerValueRange`.
33 
34 static constexpr unsigned indexMinWidth = 32;
35 static constexpr unsigned indexMaxWidth = 64;
36 
37 enum class CmpMode : uint32_t { Both, Signed, Unsigned };
38 
39 enum class OverflowFlags : uint32_t {
40  None = 0,
41  Nsw = 1,
42  Nuw = 2,
43  LLVM_MARK_AS_BITMASK_ENUM(Nuw)
44 };
45 
46 /// Function that performs inference on an array of `ConstantIntRanges` while
47 /// taking special overflow behavior into account.
50 
51 /// Compute `inferFn` on `ranges`, whose size should be the index storage
52 /// bitwidth. Then, compute the function on `argRanges` again after truncating
53 /// the ranges to 32 bits. Finally, if the truncation of the 64-bit result is
54 /// equal to the 32-bit result, use it (to preserve compatibility with folders
55 /// and inference precision), and take the union of the results otherwise.
56 ///
57 /// The `mode` argument specifies if the unsigned, signed, or both results of
58 /// the inference computation should be used when comparing the results.
61  CmpMode mode);
62 
63 /// Independently zero-extend the unsigned values and sign-extend the signed
64 /// values in `range` to `destWidth` bits, returning the resulting range.
65 ConstantIntRanges extRange(const ConstantIntRanges &range, unsigned destWidth);
66 
67 /// Use the unsigned values in `range` to zero-extend it to `destWidth`.
69  unsigned destWidth);
70 
71 /// Use the signed values in `range` to sign-extend it to `destWidth`.
73  unsigned destWidth);
74 
75 /// Truncate `range` to `destWidth` bits, taking care to handle cases such as
76 /// the truncation of [255, 256] to i8 not being a uniform range.
78  unsigned destWidth);
79 
82 
85 
88 
90 
92 
94 
96 
98 
100 
102 
104 
106 
108 
110 
112 
114 
116 
119 
121 
123 
124 /// Copy of the enum from `arith` and `index` to allow the common integer range
125 /// infrastructure to not depend on either dialect.
126 enum class CmpPredicate : uint64_t {
127  eq,
128  ne,
129  slt,
130  sle,
131  sgt,
132  sge,
133  ult,
134  ule,
135  ugt,
136  uge,
137 };
138 
139 /// Returns a boolean value if `pred` is statically true or false for
140 /// anypossible inputs falling within `lhs` and `rhs`, and std::nullopt if the
141 /// value of the predicate cannot be determined.
142 std::optional<bool> evaluatePred(CmpPredicate pred,
143  const ConstantIntRanges &lhs,
144  const ConstantIntRanges &rhs);
145 
146 } // namespace intrange
147 } // namespace mlir
148 
149 #endif // MLIR_INTERFACES_UTILS_INFERINTRANGECOMMON_H
A set of arbitrary-precision integers representing bounds on a given integer value.
This lattice value represents the integer range of an SSA value.
ConstantIntRanges inferAnd(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges inferShl(ArrayRef< ConstantIntRanges > argRanges, OverflowFlags ovfFlags=OverflowFlags::None)
ConstantIntRanges inferIndexOp(const InferRangeFn &inferFn, ArrayRef< ConstantIntRanges > argRanges, CmpMode mode)
Compute inferFn on ranges, whose size should be the index storage bitwidth.
std::function< IntegerValueRange(ArrayRef< IntegerValueRange >)> InferIntegerValueRangeFn
Function that performs inferrence on an array of IntegerValueRange.
ConstantIntRanges inferShrS(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges extSIRange(const ConstantIntRanges &range, unsigned destWidth)
Use the signed values in range to sign-extend it to destWidth.
std::optional< bool > evaluatePred(CmpPredicate pred, const ConstantIntRanges &lhs, const ConstantIntRanges &rhs)
Returns a boolean value if pred is statically true or false for anypossible inputs falling within lhs...
ConstantIntRanges inferMinS(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges inferMaxU(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges inferRemS(ArrayRef< ConstantIntRanges > argRanges)
CmpPredicate
Copy of the enum from arith and index to allow the common integer range infrastructure to not depend ...
ConstantIntRanges inferOr(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges extRange(const ConstantIntRanges &range, unsigned destWidth)
Independently zero-extend the unsigned values and sign-extend the signed values in range to destWidth...
ConstantIntRanges inferSub(ArrayRef< ConstantIntRanges > argRanges, OverflowFlags ovfFlags=OverflowFlags::None)
ConstantIntRanges inferAdd(ArrayRef< ConstantIntRanges > argRanges, OverflowFlags ovfFlags=OverflowFlags::None)
ConstantIntRanges truncRange(const ConstantIntRanges &range, unsigned destWidth)
Truncate range to destWidth bits, taking care to handle cases such as the truncation of [255,...
ConstantIntRanges inferDivU(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges inferCeilDivS(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges inferMinU(ArrayRef< ConstantIntRanges > argRanges)
std::function< ConstantIntRanges(ArrayRef< ConstantIntRanges >)> InferRangeFn
Function that performs inference on an array of ConstantIntRanges, abstracted away here to permit wri...
ConstantIntRanges inferMul(ArrayRef< ConstantIntRanges > argRanges, OverflowFlags ovfFlags=OverflowFlags::None)
ConstantIntRanges inferXor(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges inferDivS(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges inferShrU(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges inferRemU(ArrayRef< ConstantIntRanges > argRanges)
static constexpr unsigned indexMinWidth
ConstantIntRanges inferFloorDivS(ArrayRef< ConstantIntRanges > argRanges)
static constexpr unsigned indexMaxWidth
ConstantIntRanges inferCeilDivU(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges extUIRange(const ConstantIntRanges &range, unsigned destWidth)
Use the unsigned values in range to zero-extend it to destWidth.
ConstantIntRanges inferMaxS(ArrayRef< ConstantIntRanges > argRanges)
Include the generated interface declarations.