summaryrefslogtreecommitdiff
path: root/mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
diff options
context:
space:
mode:
authorKrzysztof Drewniak <Krzysztof.Drewniak@amd.com>2025-01-29 16:43:53 -0800
committerGitHub <noreply@github.com>2025-01-29 18:43:53 -0600
commitcdc09a118a7107b8e13ba5a254d3d794f51f9818 (patch)
treede29fe1eb61c1940ea034eeaaab97458df829e07 /mlir/lib/Interfaces/Utils/InferIntRangeCommon.cpp
parentde7438e472839df63e1f10478436c2f15b8e4184 (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.cpp44
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));
+}