[Mlir-commits] [mlir] [MLIR] Support scalars in ValueBounds of linalg.index (PR #230962)
Alexey Kreshchuk
llvmlistbot at llvm.org
Sun Oct 11 07:02:12 PDT 2026
https://github.com/krsch-mobileye updated https://github.com/llvm/llvm-project/pull/230962
>From 35fd1f20369ac9aa4045077381addbffd0cacb90 Mon Sep 17 00:00:00 2001
From: Alexey Kreshchuk <alexey.kreshchuk at mobileye.com>
Date: Sun, 11 Oct 2026 16:47:44 +0300
Subject: [PATCH 1/2] [MLIR] Support scalars in ValueBounds of linalg.index
ValueBoundsOpInterfaceImpl for linalg.index expects every operand to be
ShapedType, but linalg.generic also supports scalars as operands. I've
made it query the rank with linalgOp.getRank
---
.../Linalg/IR/ValueBoundsOpInterfaceImpl.cpp | 11 +++--
.../value-bounds-op-interface-impl.mlir | 48 +++++++++++++++++++
2 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/mlir/lib/Dialect/Linalg/IR/ValueBoundsOpInterfaceImpl.cpp b/mlir/lib/Dialect/Linalg/IR/ValueBoundsOpInterfaceImpl.cpp
index f56ef485069f8..12cad71d403b1 100644
--- a/mlir/lib/Dialect/Linalg/IR/ValueBoundsOpInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/Linalg/IR/ValueBoundsOpInterfaceImpl.cpp
@@ -35,14 +35,15 @@ struct IndexOpInterface
.getPosition();
// Find the `flatDimPos`-th operand dimension.
int64_t flatDimCtr = 0;
- for (Value operand : linalgOp->getOperands()) {
+ for (OpOperand &operand : linalgOp->getOpOperands()) {
assert(flatDimPos >= flatDimCtr && "invalid pos");
- auto shapedType = llvm::cast<ShapedType>(operand.getType());
- if (flatDimPos < flatDimCtr + shapedType.getRank()) {
- cstr.bound(value) < cstr.getExpr(operand, flatDimPos - flatDimCtr);
+ // Scalar operands do not contribute dimensions to the flattened shape.
+ int64_t rank = linalgOp.getRank(&operand);
+ if (flatDimPos < flatDimCtr + rank) {
+ cstr.bound(value) < cstr.getExpr(operand.get(), flatDimPos - flatDimCtr);
break;
}
- flatDimCtr += shapedType.getRank();
+ flatDimCtr += rank;
}
}
};
diff --git a/mlir/test/Dialect/Linalg/value-bounds-op-interface-impl.mlir b/mlir/test/Dialect/Linalg/value-bounds-op-interface-impl.mlir
index bcd330443cc44..e68d1332bcc03 100644
--- a/mlir/test/Dialect/Linalg/value-bounds-op-interface-impl.mlir
+++ b/mlir/test/Dialect/Linalg/value-bounds-op-interface-impl.mlir
@@ -62,3 +62,51 @@ func.func @linalg_index(%arg0: memref<?x?xf32>,
}
return
}
+
+// -----
+
+// CHECK-LABEL: func @linalg_index_scalar_input(
+func.func @linalg_index_scalar_input(%scalar: i32, %out: tensor<4xi32>) -> tensor<4xi32> {
+ %result = linalg.generic {
+ indexing_maps = [affine_map<(d0) -> ()>, affine_map<(d0) -> (d0)>],
+ iterator_types = ["parallel"]}
+ ins(%scalar : i32) outs(%out : tensor<4xi32>) {
+ ^bb0(%in: i32, %old: i32):
+ %i = linalg.index 0 : index
+ // CHECK: %[[UB:.*]] = arith.constant 4 : index
+ // CHECK: %[[VALUE:.*]] = arith.index_cast %[[UB]] : index to i32
+ // CHECK: linalg.yield %[[VALUE]] : i32
+ %ub = "test.reify_bound"(%i) {type = "UB"} : (index) -> index
+ %value = arith.index_cast %ub : index to i32
+ linalg.yield %value : i32
+ } -> tensor<4xi32>
+ return %result : tensor<4xi32>
+}
+
+// -----
+
+// CHECK-LABEL: func @linalg_index_scalar_input_dynamic(
+// CHECK-SAME: %[[OUT:[^ ,:]+]]: tensor<?x?xi32>
+func.func @linalg_index_scalar_input_dynamic(%input: tensor<?xi32>, %scalar: i32,
+ %rank_zero: tensor<i32>,
+ %out: tensor<?x?xi32>) -> tensor<?x?xi32> {
+ %result = linalg.generic {
+ indexing_maps = [affine_map<(d0, d1) -> (d0)>,
+ affine_map<(d0, d1) -> ()>,
+ affine_map<(d0, d1) -> ()>,
+ affine_map<(d0, d1) -> (d0, d1)>],
+ iterator_types = ["parallel", "parallel"]}
+ ins(%input, %scalar, %rank_zero : tensor<?xi32>, i32, tensor<i32>)
+ outs(%out : tensor<?x?xi32>) {
+ ^bb0(%in: i32, %s: i32, %r: i32, %old: i32):
+ %i = linalg.index 1 : index
+ // CHECK: %[[C1:.*]] = arith.constant 1 : index
+ // CHECK: %[[UB:.*]] = tensor.dim %[[OUT]], %[[C1]]
+ // CHECK: %[[VALUE:.*]] = arith.index_cast %[[UB]] : index to i32
+ // CHECK: linalg.yield %[[VALUE]] : i32
+ %ub = "test.reify_bound"(%i) {type = "UB"} : (index) -> index
+ %value = arith.index_cast %ub : index to i32
+ linalg.yield %value : i32
+ } -> tensor<?x?xi32>
+ return %result : tensor<?x?xi32>
+}
>From d02b463053ff9aa1baa82287c13924e658dc8444 Mon Sep 17 00:00:00 2001
From: Alexey Kreshchuk <alexey.kreshchuk at mobileye.com>
Date: Sun, 11 Oct 2026 17:01:49 +0300
Subject: [PATCH 2/2] format
---
mlir/lib/Dialect/Linalg/IR/ValueBoundsOpInterfaceImpl.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/Linalg/IR/ValueBoundsOpInterfaceImpl.cpp b/mlir/lib/Dialect/Linalg/IR/ValueBoundsOpInterfaceImpl.cpp
index 12cad71d403b1..dbcc3fa63f03a 100644
--- a/mlir/lib/Dialect/Linalg/IR/ValueBoundsOpInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/Linalg/IR/ValueBoundsOpInterfaceImpl.cpp
@@ -40,7 +40,8 @@ struct IndexOpInterface
// Scalar operands do not contribute dimensions to the flattened shape.
int64_t rank = linalgOp.getRank(&operand);
if (flatDimPos < flatDimCtr + rank) {
- cstr.bound(value) < cstr.getExpr(operand.get(), flatDimPos - flatDimCtr);
+ cstr.bound(value) <
+ cstr.getExpr(operand.get(), flatDimPos - flatDimCtr);
break;
}
flatDimCtr += rank;
More information about the Mlir-commits
mailing list