15 #define DEBUG_TYPE "int-range-analysis"
24 if (bitEnumContainsAny(flags, arith::IntegerOverflowFlags::nsw))
26 if (bitEnumContainsAny(flags, arith::IntegerOverflowFlags::nuw))
37 if (
auto scalarCstAttr = llvm::dyn_cast_or_null<IntegerAttr>(getValue())) {
38 const APInt &value = scalarCstAttr.getValue();
42 if (
auto arrayCstAttr =
43 llvm::dyn_cast_or_null<DenseIntElementsAttr>(getValue())) {
44 if (arrayCstAttr.isSplat()) {
46 arrayCstAttr.getSplatValue<APInt>()));
50 std::optional<ConstantIntRanges> result;
51 for (
const APInt &val : arrayCstAttr) {
53 result = (result ? result->rangeUnion(range) : range);
56 assert(result &&
"Zero-sized vectors are not allowed");
57 setResultRange(getResult(), *result);
69 getOverflowFlags())));
79 getOverflowFlags())));
89 getOverflowFlags())));
98 setResultRange(getResult(),
inferDivU(argRanges));
107 setResultRange(getResult(),
inferDivS(argRanges));
114 void arith::CeilDivUIOp::inferResultRanges(
123 void arith::CeilDivSIOp::inferResultRanges(
132 void arith::FloorDivSIOp::inferResultRanges(
143 setResultRange(getResult(),
inferRemU(argRanges));
152 setResultRange(getResult(),
inferRemS(argRanges));
161 setResultRange(getResult(),
inferAnd(argRanges));
170 setResultRange(getResult(),
inferOr(argRanges));
179 setResultRange(getResult(),
inferXor(argRanges));
188 setResultRange(getResult(),
inferMaxS(argRanges));
197 setResultRange(getResult(),
inferMaxU(argRanges));
206 setResultRange(getResult(),
inferMinS(argRanges));
215 setResultRange(getResult(),
inferMinU(argRanges));
226 setResultRange(getResult(),
extUIRange(argRanges[0], destWidth));
237 setResultRange(getResult(),
extSIRange(argRanges[0], destWidth));
248 setResultRange(getResult(),
truncRange(argRanges[0], destWidth));
255 void arith::IndexCastOp::inferResultRanges(
257 Type sourceType = getOperand().getType();
258 Type destType = getResult().getType();
262 if (srcWidth < destWidth)
263 setResultRange(getResult(),
extSIRange(argRanges[0], destWidth));
264 else if (srcWidth > destWidth)
265 setResultRange(getResult(),
truncRange(argRanges[0], destWidth));
267 setResultRange(getResult(), argRanges[0]);
274 void arith::IndexCastUIOp::inferResultRanges(
276 Type sourceType = getOperand().getType();
277 Type destType = getResult().getType();
281 if (srcWidth < destWidth)
282 setResultRange(getResult(),
extUIRange(argRanges[0], destWidth));
283 else if (srcWidth > destWidth)
284 setResultRange(getResult(),
truncRange(argRanges[0], destWidth));
286 setResultRange(getResult(), argRanges[0]);
295 arith::CmpIPredicate arithPred = getPredicate();
300 APInt
max = APInt::getAllOnes(1);
303 if (truthValue.has_value() && *truthValue)
305 else if (truthValue.has_value() && !(*truthValue))
315 void arith::SelectOp::inferResultRangesFromOptional(
317 std::optional<APInt> mbCondVal =
318 argRanges[0].isUninitialized()
320 : argRanges[0].getValue().getConstantValue();
326 if (mbCondVal->isZero())
327 setResultRange(getResult(), falseCase);
329 setResultRange(getResult(), trueCase);
342 getOverflowFlags())));
351 setResultRange(getResult(),
inferShrU(argRanges));
360 setResultRange(getResult(),
inferShrS(argRanges));
static intrange::OverflowFlags convertArithOverflowFlags(arith::IntegerOverflowFlags flags)
static Value getZero(OpBuilder &b, Location loc, Type elementType)
Get zero value for an element type.
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)
static Value min(ImplicitLocOpBuilder &builder, Value value, Value bound)
A set of arbitrary-precision integers representing bounds on a given integer value.
static ConstantIntRanges constant(const APInt &value)
Create a ConstantIntRanges with a constant value - that is, with the bounds [value,...
static ConstantIntRanges fromUnsigned(const APInt &umin, const APInt &umax)
Create an ConstantIntRanges with the unsigned minimum and maximum equal to umin and umax and the sign...
static unsigned getStorageBitwidth(Type type)
Return the bitwidth that should be used for integer ranges describing type.
This lattice value represents the integer range of an SSA value.
static IntegerValueRange join(const IntegerValueRange &lhs, const IntegerValueRange &rhs)
Compute the least upper bound of two ranges.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
ConstantIntRanges inferAnd(ArrayRef< ConstantIntRanges > argRanges)
ConstantIntRanges inferShl(ArrayRef< ConstantIntRanges > argRanges, OverflowFlags ovfFlags=OverflowFlags::None)
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 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)
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)
ConstantIntRanges inferFloorDivS(ArrayRef< ConstantIntRanges > argRanges)
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.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.