xref: /llvm-project/mlir/lib/Dialect/Index/IR/InferIntRangeInterfaceImpls.cpp (revision 2034f2fc8729bd4645ef7caa3c5c6efa284d2d3f)
15af9d16dSKrzysztof Drewniak //===- InferIntRangeInterfaceImpls.cpp - Integer range impls for arith -===//
25af9d16dSKrzysztof Drewniak //
35af9d16dSKrzysztof Drewniak // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45af9d16dSKrzysztof Drewniak // See https://llvm.org/LICENSE.txt for license information.
55af9d16dSKrzysztof Drewniak // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65af9d16dSKrzysztof Drewniak //
75af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
85af9d16dSKrzysztof Drewniak 
95af9d16dSKrzysztof Drewniak #include "mlir/Dialect/Index/IR/IndexOps.h"
105af9d16dSKrzysztof Drewniak #include "mlir/Interfaces/InferIntRangeInterface.h"
115af9d16dSKrzysztof Drewniak #include "mlir/Interfaces/Utils/InferIntRangeCommon.h"
125af9d16dSKrzysztof Drewniak 
135af9d16dSKrzysztof Drewniak #include "llvm/Support/Debug.h"
145c9013e2SKazu Hirata #include <optional>
155af9d16dSKrzysztof Drewniak 
165af9d16dSKrzysztof Drewniak #define DEBUG_TYPE "int-range-analysis"
175af9d16dSKrzysztof Drewniak 
185af9d16dSKrzysztof Drewniak using namespace mlir;
195af9d16dSKrzysztof Drewniak using namespace mlir::index;
205af9d16dSKrzysztof Drewniak using namespace mlir::intrange;
215af9d16dSKrzysztof Drewniak 
225af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
235af9d16dSKrzysztof Drewniak // Constants
245af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
255af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)265af9d16dSKrzysztof Drewniak void ConstantOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
275af9d16dSKrzysztof Drewniak                                    SetIntRangeFn setResultRange) {
285af9d16dSKrzysztof Drewniak   const APInt &value = getValue();
295af9d16dSKrzysztof Drewniak   setResultRange(getResult(), ConstantIntRanges::constant(value));
305af9d16dSKrzysztof Drewniak }
315af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)325af9d16dSKrzysztof Drewniak void BoolConstantOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
335af9d16dSKrzysztof Drewniak                                        SetIntRangeFn setResultRange) {
345af9d16dSKrzysztof Drewniak   bool value = getValue();
355af9d16dSKrzysztof Drewniak   APInt asInt(/*numBits=*/1, value);
365af9d16dSKrzysztof Drewniak   setResultRange(getResult(), ConstantIntRanges::constant(asInt));
375af9d16dSKrzysztof Drewniak }
385af9d16dSKrzysztof Drewniak 
395af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
405af9d16dSKrzysztof Drewniak // Arithmec operations. All of these operations will have their results inferred
415af9d16dSKrzysztof Drewniak // using both the 64-bit values and truncated 32-bit values of their inputs,
425af9d16dSKrzysztof Drewniak // with the results being the union of those inferences, except where the
435af9d16dSKrzysztof Drewniak // truncation of the 64-bit result is equal to the 32-bit result (at which time
445af9d16dSKrzysztof Drewniak // we take the 64-bit result).
455af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
465af9d16dSKrzysztof Drewniak 
47*2034f2fcSFelix Schneider // Some arithmetic inference functions allow specifying special overflow / wrap
48*2034f2fcSFelix Schneider // behavior. We do not require this for the IndexOps and use this helper to call
49*2034f2fcSFelix Schneider // the inference function without any `OverflowFlags`.
50*2034f2fcSFelix Schneider static std::function<ConstantIntRanges(ArrayRef<ConstantIntRanges>)>
inferWithoutOverflowFlags(InferRangeWithOvfFlagsFn inferWithOvfFn)51*2034f2fcSFelix Schneider inferWithoutOverflowFlags(InferRangeWithOvfFlagsFn inferWithOvfFn) {
52*2034f2fcSFelix Schneider   return [inferWithOvfFn](ArrayRef<ConstantIntRanges> argRanges) {
53*2034f2fcSFelix Schneider     return inferWithOvfFn(argRanges, OverflowFlags::None);
54*2034f2fcSFelix Schneider   };
55*2034f2fcSFelix Schneider }
56*2034f2fcSFelix Schneider 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)575af9d16dSKrzysztof Drewniak void AddOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
585af9d16dSKrzysztof Drewniak                               SetIntRangeFn setResultRange) {
59*2034f2fcSFelix Schneider   setResultRange(getResult(), inferIndexOp(inferWithoutOverflowFlags(inferAdd),
60*2034f2fcSFelix Schneider                                            argRanges, CmpMode::Both));
615af9d16dSKrzysztof Drewniak }
625af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)635af9d16dSKrzysztof Drewniak void SubOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
645af9d16dSKrzysztof Drewniak                               SetIntRangeFn setResultRange) {
65*2034f2fcSFelix Schneider   setResultRange(getResult(), inferIndexOp(inferWithoutOverflowFlags(inferSub),
66*2034f2fcSFelix Schneider                                            argRanges, CmpMode::Both));
675af9d16dSKrzysztof Drewniak }
685af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)695af9d16dSKrzysztof Drewniak void MulOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
705af9d16dSKrzysztof Drewniak                               SetIntRangeFn setResultRange) {
71*2034f2fcSFelix Schneider   setResultRange(getResult(), inferIndexOp(inferWithoutOverflowFlags(inferMul),
72*2034f2fcSFelix Schneider                                            argRanges, CmpMode::Both));
735af9d16dSKrzysztof Drewniak }
745af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)755af9d16dSKrzysztof Drewniak void DivUOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
765af9d16dSKrzysztof Drewniak                                SetIntRangeFn setResultRange) {
775af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
785af9d16dSKrzysztof Drewniak                  inferIndexOp(inferDivU, argRanges, CmpMode::Unsigned));
795af9d16dSKrzysztof Drewniak }
805af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)815af9d16dSKrzysztof Drewniak void DivSOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
825af9d16dSKrzysztof Drewniak                                SetIntRangeFn setResultRange) {
835af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
845af9d16dSKrzysztof Drewniak                  inferIndexOp(inferDivS, argRanges, CmpMode::Signed));
855af9d16dSKrzysztof Drewniak }
865af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)875af9d16dSKrzysztof Drewniak void CeilDivUOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
885af9d16dSKrzysztof Drewniak                                    SetIntRangeFn setResultRange) {
895af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
905af9d16dSKrzysztof Drewniak                  inferIndexOp(inferCeilDivU, argRanges, CmpMode::Unsigned));
915af9d16dSKrzysztof Drewniak }
925af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)935af9d16dSKrzysztof Drewniak void CeilDivSOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
945af9d16dSKrzysztof Drewniak                                    SetIntRangeFn setResultRange) {
955af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
965af9d16dSKrzysztof Drewniak                  inferIndexOp(inferCeilDivS, argRanges, CmpMode::Signed));
975af9d16dSKrzysztof Drewniak }
985af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)995af9d16dSKrzysztof Drewniak void FloorDivSOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1005af9d16dSKrzysztof Drewniak                                     SetIntRangeFn setResultRange) {
1015af9d16dSKrzysztof Drewniak   return setResultRange(
1025af9d16dSKrzysztof Drewniak       getResult(), inferIndexOp(inferFloorDivS, argRanges, CmpMode::Signed));
1035af9d16dSKrzysztof Drewniak }
1045af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1055af9d16dSKrzysztof Drewniak void RemSOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1065af9d16dSKrzysztof Drewniak                                SetIntRangeFn setResultRange) {
1075af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1085af9d16dSKrzysztof Drewniak                  inferIndexOp(inferRemS, argRanges, CmpMode::Signed));
1095af9d16dSKrzysztof Drewniak }
1105af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1115af9d16dSKrzysztof Drewniak void RemUOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1125af9d16dSKrzysztof Drewniak                                SetIntRangeFn setResultRange) {
1135af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1145af9d16dSKrzysztof Drewniak                  inferIndexOp(inferRemU, argRanges, CmpMode::Unsigned));
1155af9d16dSKrzysztof Drewniak }
1165af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1175af9d16dSKrzysztof Drewniak void MaxSOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1185af9d16dSKrzysztof Drewniak                                SetIntRangeFn setResultRange) {
1195af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1205af9d16dSKrzysztof Drewniak                  inferIndexOp(inferMaxS, argRanges, CmpMode::Signed));
1215af9d16dSKrzysztof Drewniak }
1225af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1235af9d16dSKrzysztof Drewniak void MaxUOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1245af9d16dSKrzysztof Drewniak                                SetIntRangeFn setResultRange) {
1255af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1265af9d16dSKrzysztof Drewniak                  inferIndexOp(inferMaxU, argRanges, CmpMode::Unsigned));
1275af9d16dSKrzysztof Drewniak }
1285af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1295af9d16dSKrzysztof Drewniak void MinSOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1305af9d16dSKrzysztof Drewniak                                SetIntRangeFn setResultRange) {
1315af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1325af9d16dSKrzysztof Drewniak                  inferIndexOp(inferMinS, argRanges, CmpMode::Signed));
1335af9d16dSKrzysztof Drewniak }
1345af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1355af9d16dSKrzysztof Drewniak void MinUOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1365af9d16dSKrzysztof Drewniak                                SetIntRangeFn setResultRange) {
1375af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1385af9d16dSKrzysztof Drewniak                  inferIndexOp(inferMinU, argRanges, CmpMode::Unsigned));
1395af9d16dSKrzysztof Drewniak }
1405af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1415af9d16dSKrzysztof Drewniak void ShlOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1425af9d16dSKrzysztof Drewniak                               SetIntRangeFn setResultRange) {
143*2034f2fcSFelix Schneider   setResultRange(getResult(), inferIndexOp(inferWithoutOverflowFlags(inferShl),
144*2034f2fcSFelix Schneider                                            argRanges, CmpMode::Both));
1455af9d16dSKrzysztof Drewniak }
1465af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1475af9d16dSKrzysztof Drewniak void ShrSOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1485af9d16dSKrzysztof Drewniak                                SetIntRangeFn setResultRange) {
1495af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1505af9d16dSKrzysztof Drewniak                  inferIndexOp(inferShrS, argRanges, CmpMode::Signed));
1515af9d16dSKrzysztof Drewniak }
1525af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1535af9d16dSKrzysztof Drewniak void ShrUOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1545af9d16dSKrzysztof Drewniak                                SetIntRangeFn setResultRange) {
1555af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1565af9d16dSKrzysztof Drewniak                  inferIndexOp(inferShrU, argRanges, CmpMode::Unsigned));
1575af9d16dSKrzysztof Drewniak }
1585af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1595af9d16dSKrzysztof Drewniak void AndOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1605af9d16dSKrzysztof Drewniak                               SetIntRangeFn setResultRange) {
1615af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1625af9d16dSKrzysztof Drewniak                  inferIndexOp(inferAnd, argRanges, CmpMode::Unsigned));
1635af9d16dSKrzysztof Drewniak }
1645af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1655af9d16dSKrzysztof Drewniak void OrOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1665af9d16dSKrzysztof Drewniak                              SetIntRangeFn setResultRange) {
1675af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1685af9d16dSKrzysztof Drewniak                  inferIndexOp(inferOr, argRanges, CmpMode::Unsigned));
1695af9d16dSKrzysztof Drewniak }
1705af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)1715af9d16dSKrzysztof Drewniak void XOrOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
1725af9d16dSKrzysztof Drewniak                               SetIntRangeFn setResultRange) {
1735af9d16dSKrzysztof Drewniak   setResultRange(getResult(),
1745af9d16dSKrzysztof Drewniak                  inferIndexOp(inferXor, argRanges, CmpMode::Unsigned));
1755af9d16dSKrzysztof Drewniak }
1765af9d16dSKrzysztof Drewniak 
1775af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
1785af9d16dSKrzysztof Drewniak // Casts
1795af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
1805af9d16dSKrzysztof Drewniak 
makeLikeDest(const ConstantIntRanges & range,unsigned srcWidth,unsigned destWidth,bool isSigned)1815af9d16dSKrzysztof Drewniak static ConstantIntRanges makeLikeDest(const ConstantIntRanges &range,
1825af9d16dSKrzysztof Drewniak                                       unsigned srcWidth, unsigned destWidth,
1835af9d16dSKrzysztof Drewniak                                       bool isSigned) {
1845af9d16dSKrzysztof Drewniak   if (srcWidth < destWidth)
1855af9d16dSKrzysztof Drewniak     return isSigned ? extSIRange(range, destWidth)
1865af9d16dSKrzysztof Drewniak                     : extUIRange(range, destWidth);
1875af9d16dSKrzysztof Drewniak   if (srcWidth > destWidth)
1885af9d16dSKrzysztof Drewniak     return truncRange(range, destWidth);
1895af9d16dSKrzysztof Drewniak   return range;
1905af9d16dSKrzysztof Drewniak }
1915af9d16dSKrzysztof Drewniak 
1925af9d16dSKrzysztof Drewniak // When casting to `index`, we will take the union of the possible fixed-width
1935af9d16dSKrzysztof Drewniak // casts.
inferIndexCast(const ConstantIntRanges & range,Type sourceType,Type destType,bool isSigned)1945af9d16dSKrzysztof Drewniak static ConstantIntRanges inferIndexCast(const ConstantIntRanges &range,
1955af9d16dSKrzysztof Drewniak                                         Type sourceType, Type destType,
1965af9d16dSKrzysztof Drewniak                                         bool isSigned) {
1975af9d16dSKrzysztof Drewniak   unsigned srcWidth = ConstantIntRanges::getStorageBitwidth(sourceType);
1985af9d16dSKrzysztof Drewniak   unsigned destWidth = ConstantIntRanges::getStorageBitwidth(destType);
1995af9d16dSKrzysztof Drewniak   if (sourceType.isIndex())
2005af9d16dSKrzysztof Drewniak     return makeLikeDest(range, srcWidth, destWidth, isSigned);
2015af9d16dSKrzysztof Drewniak   // We are casting to indexs, so use the union of the 32-bit and 64-bit casts
2025af9d16dSKrzysztof Drewniak   ConstantIntRanges storageRange =
2035af9d16dSKrzysztof Drewniak       makeLikeDest(range, srcWidth, destWidth, isSigned);
2045af9d16dSKrzysztof Drewniak   ConstantIntRanges minWidthRange =
2055af9d16dSKrzysztof Drewniak       makeLikeDest(range, srcWidth, indexMinWidth, isSigned);
2065af9d16dSKrzysztof Drewniak   ConstantIntRanges minWidthExt = extRange(minWidthRange, destWidth);
2075af9d16dSKrzysztof Drewniak   ConstantIntRanges ret = storageRange.rangeUnion(minWidthExt);
2085af9d16dSKrzysztof Drewniak   return ret;
2095af9d16dSKrzysztof Drewniak }
2105af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)2115af9d16dSKrzysztof Drewniak void CastSOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
2125af9d16dSKrzysztof Drewniak                                 SetIntRangeFn setResultRange) {
2135af9d16dSKrzysztof Drewniak   Type sourceType = getOperand().getType();
2145af9d16dSKrzysztof Drewniak   Type destType = getResult().getType();
2155af9d16dSKrzysztof Drewniak   setResultRange(getResult(), inferIndexCast(argRanges[0], sourceType, destType,
2165af9d16dSKrzysztof Drewniak                                              /*isSigned=*/true));
2175af9d16dSKrzysztof Drewniak }
2185af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)2195af9d16dSKrzysztof Drewniak void CastUOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
2205af9d16dSKrzysztof Drewniak                                 SetIntRangeFn setResultRange) {
2215af9d16dSKrzysztof Drewniak   Type sourceType = getOperand().getType();
2225af9d16dSKrzysztof Drewniak   Type destType = getResult().getType();
2235af9d16dSKrzysztof Drewniak   setResultRange(getResult(), inferIndexCast(argRanges[0], sourceType, destType,
2245af9d16dSKrzysztof Drewniak                                              /*isSigned=*/false));
2255af9d16dSKrzysztof Drewniak }
2265af9d16dSKrzysztof Drewniak 
2275af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
2285af9d16dSKrzysztof Drewniak // CmpOp
2295af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
2305af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)2315af9d16dSKrzysztof Drewniak void CmpOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
2325af9d16dSKrzysztof Drewniak                               SetIntRangeFn setResultRange) {
2335af9d16dSKrzysztof Drewniak   index::IndexCmpPredicate indexPred = getPred();
2345af9d16dSKrzysztof Drewniak   intrange::CmpPredicate pred = static_cast<intrange::CmpPredicate>(indexPred);
2355af9d16dSKrzysztof Drewniak   const ConstantIntRanges &lhs = argRanges[0], &rhs = argRanges[1];
2365af9d16dSKrzysztof Drewniak 
2375af9d16dSKrzysztof Drewniak   APInt min = APInt::getZero(1);
238b7ffd968SKazu Hirata   APInt max = APInt::getAllOnes(1);
2395af9d16dSKrzysztof Drewniak 
2405c9013e2SKazu Hirata   std::optional<bool> truthValue64 = intrange::evaluatePred(pred, lhs, rhs);
2415af9d16dSKrzysztof Drewniak 
2425af9d16dSKrzysztof Drewniak   ConstantIntRanges lhsTrunc = truncRange(lhs, indexMinWidth),
2435af9d16dSKrzysztof Drewniak                     rhsTrunc = truncRange(rhs, indexMinWidth);
2445c9013e2SKazu Hirata   std::optional<bool> truthValue32 =
2455af9d16dSKrzysztof Drewniak       intrange::evaluatePred(pred, lhsTrunc, rhsTrunc);
2465af9d16dSKrzysztof Drewniak 
2475af9d16dSKrzysztof Drewniak   if (truthValue64 == truthValue32) {
2485af9d16dSKrzysztof Drewniak     if (truthValue64.has_value() && *truthValue64)
2495af9d16dSKrzysztof Drewniak       min = max;
2505af9d16dSKrzysztof Drewniak     else if (truthValue64.has_value() && !(*truthValue64))
2515af9d16dSKrzysztof Drewniak       max = min;
2525af9d16dSKrzysztof Drewniak   }
2535af9d16dSKrzysztof Drewniak   setResultRange(getResult(), ConstantIntRanges::fromUnsigned(min, max));
2545af9d16dSKrzysztof Drewniak }
2555af9d16dSKrzysztof Drewniak 
2565af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
2575af9d16dSKrzysztof Drewniak // SizeOf, which is bounded between the two supported bitwidth (32 and 64).
2585af9d16dSKrzysztof Drewniak //===----------------------------------------------------------------------===//
2595af9d16dSKrzysztof Drewniak 
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRange)2605af9d16dSKrzysztof Drewniak void SizeOfOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
2615af9d16dSKrzysztof Drewniak                                  SetIntRangeFn setResultRange) {
2625af9d16dSKrzysztof Drewniak   unsigned storageWidth =
2635af9d16dSKrzysztof Drewniak       ConstantIntRanges::getStorageBitwidth(getResult().getType());
2645af9d16dSKrzysztof Drewniak   APInt min(/*numBits=*/storageWidth, indexMinWidth);
2655af9d16dSKrzysztof Drewniak   APInt max(/*numBits=*/storageWidth, indexMaxWidth);
2665af9d16dSKrzysztof Drewniak   setResultRange(getResult(), ConstantIntRanges::fromUnsigned(min, max));
2675af9d16dSKrzysztof Drewniak }
268