diff options
| author | Krzysztof Drewniak <Krzysztof.Drewniak@amd.com> | 2025-01-29 16:43:53 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-29 18:43:53 -0600 |
| commit | cdc09a118a7107b8e13ba5a254d3d794f51f9818 (patch) | |
| tree | de29fe1eb61c1940ea034eeaaab97458df829e07 /mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp | |
| parent | de7438e472839df63e1f10478436c2f15b8e4184 (diff) | |
[mlir][IntRangeInference] Infer values for {memref,tensor}.dim (#122945)
Implement the integer range inference niterface for memref.dim and
tetnor.dim using shared code. The inference will infer the `dim` of
dynamic dimensions to [0, index_max] and take the union of all the
dimensions that the `dim` argument could be validly referring to.
Diffstat (limited to 'mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp')
| -rw-r--r-- | mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp b/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp index 1eab4139488b..2f47939df5a0 100644 --- a/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp +++ b/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp @@ -14,6 +14,7 @@ #include "mlir/Interfaces/Utils/InferIntRangeCommon.h" #include "mlir/Interfaces/InferIntRangeInterface.h" +#include "mlir/Interfaces/ShapedOpInterfaces.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" @@ -725,3 +726,46 @@ std::optional<bool> mlir::intrange::evaluatePred(CmpPredicate pred, return false; return std::nullopt; } + +//===----------------------------------------------------------------------===// +// Shaped type dimension accessors / ShapedDimOpInterface +//===----------------------------------------------------------------------===// + +ConstantIntRanges +mlir::intrange::inferShapedDimOpInterface(ShapedDimOpInterface op, + const IntegerValueRange &maybeDim) { + unsigned width = + ConstantIntRanges::getStorageBitwidth(op->getResult(0).getType()); + APInt zero = APInt::getZero(width); + APInt typeMax = APInt::getSignedMaxValue(width); + + auto shapedTy = cast<ShapedType>(op.getShapedValue().getType()); + if (!shapedTy.hasRank()) + return ConstantIntRanges::fromSigned(zero, typeMax); + + int64_t rank = shapedTy.getRank(); + int64_t minDim = 0; + int64_t maxDim = rank - 1; + if (!maybeDim.isUninitialized()) { + const ConstantIntRanges &dim = maybeDim.getValue(); + minDim = std::max(minDim, dim.smin().getSExtValue()); + maxDim = std::min(maxDim, dim.smax().getSExtValue()); + } + + std::optional<ConstantIntRanges> result; + auto joinResult = [&](const ConstantIntRanges &thisResult) { + if (!result.has_value()) + result = thisResult; + else + result = result->rangeUnion(thisResult); + }; + for (int64_t i = minDim; i <= maxDim; ++i) { + int64_t length = shapedTy.getDimSize(i); + + if (ShapedType::isDynamic(length)) + joinResult(ConstantIntRanges::fromSigned(zero, typeMax)); + else + joinResult(ConstantIntRanges::constant(APInt(width, length))); + } + return result.value_or(ConstantIntRanges::fromSigned(zero, typeMax)); +} |
