MLIR  21.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 class ShapedDimOpInterface;
24 
25 namespace intrange {
26 /// Function that performs inference on an array of `ConstantIntRanges`,
27 /// abstracted away here to permit writing the function that handles both
28 /// 64- and 32-bit index types.
29 using InferRangeFn =
31 
32 /// Function that performs inferrence on an array of `IntegerValueRange`.
35 
36 static constexpr unsigned indexMinWidth = 32;
37 static constexpr unsigned indexMaxWidth = 64;
38 
39 enum class CmpMode : uint32_t { Both, Signed, Unsigned };
40 
41 enum class OverflowFlags : uint32_t {
42  None = 0,
43  Nsw = 1,
44  Nuw = 2,
45  LLVM_MARK_AS_BITMASK_ENUM(Nuw)
46 };
47 
48 /// Function that performs inference on an array of `ConstantIntRanges` while
49 /// taking special overflow behavior into account.
52 
53 /// Compute `inferFn` on `ranges`, whose size should be the index storage
54 /// bitwidth. Then, compute the function on `argRanges` again after truncating
55 /// the ranges to 32 bits. Finally, if the truncation of the 64-bit result is
56 /// equal to the 32-bit result, use it (to preserve compatibility with folders
57 /// and inference precision), and take the union of the results otherwise.
58 ///
59 /// The `mode` argument specifies if the unsigned, signed, or both results of
60 /// the inference computation should be used when comparing the results.
63  CmpMode mode);
64 
65 /// Independently zero-extend the unsigned values and sign-extend the signed
66 /// values in `range` to `destWidth` bits, returning the resulting range.
67 ConstantIntRanges extRange(const ConstantIntRanges &range, unsigned destWidth);
68 
69 /// Use the unsigned values in `range` to zero-extend it to `destWidth`.
71  unsigned destWidth);
72 
73 /// Use the signed values in `range` to sign-extend it to `destWidth`.
75  unsigned destWidth);
76 
77 /// Truncate `range` to `destWidth` bits, taking care to handle cases such as
78 /// the truncation of [255, 256] to i8 not being a uniform range.
80  unsigned destWidth);
81 
84 
87 
90 
92 
94 
96 
98 
100 
102 
104 
106 
108 
110 
112 
114 
116 
118 
121 
123 
125 
126 /// Copy of the enum from `arith` and `index` to allow the common integer range
127 /// infrastructure to not depend on either dialect.
128 enum class CmpPredicate : uint64_t {
129  eq,
130  ne,
131  slt,
132  sle,
133  sgt,
134  sge,
135  ult,
136  ule,
137  ugt,
138  uge,
139 };
140 
141 /// Returns a boolean value if `pred` is statically true or false for
142 /// anypossible inputs falling within `lhs` and `rhs`, and std::nullopt if the
143 /// value of the predicate cannot be determined.
144 std::optional<bool> evaluatePred(CmpPredicate pred,
145  const ConstantIntRanges &lhs,
146  const ConstantIntRanges &rhs);
147 
148 /// Returns the integer range for the result of a `ShapedDimOpInterface` given
149 /// the optional inferred ranges for the `dimension` index `maybeDim`. When a
150 /// dynamic dimension is encountered, returns [0, signed_max(type(result))].
151 ConstantIntRanges inferShapedDimOpInterface(ShapedDimOpInterface op,
152  const IntegerValueRange &maybeDim);
153 
154 } // namespace intrange
155 } // namespace mlir
156 
157 #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 inferShapedDimOpInterface(ShapedDimOpInterface op, const IntegerValueRange &maybeDim)
Returns the integer range for the result of a ShapedDimOpInterface given the optional inferred ranges...
ConstantIntRanges inferMaxS(ArrayRef< ConstantIntRanges > argRanges)
Include the generated interface declarations.