[Mlir-commits] [mlir] c9938eb - [mlir][arith] Implement ValueBoundsOpInterface for min/max ops (#203269)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Jun 12 09:01:52 PDT 2026
Author: nirhersh
Date: 2026-06-12T16:01:46Z
New Revision: c9938eb76ca653abff8d0b7c99bd74aec57c4758
URL: https://github.com/llvm/llvm-project/commit/c9938eb76ca653abff8d0b7c99bd74aec57c4758
DIFF: https://github.com/llvm/llvm-project/commit/c9938eb76ca653abff8d0b7c99bd74aec57c4758.diff
LOG: [mlir][arith] Implement ValueBoundsOpInterface for min/max ops (#203269)
Add ValueBoundsOpInterface external models for the arith integer min/max operations: arith.minsi and arith.maxsi.
---------
Co-authored-by: Nir Herscovici <nir.herscovici at mobileye.com>
Added:
Modified:
mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
mlir/lib/Dialect/Arith/IR/ValueBoundsOpInterfaceImpl.cpp
mlir/test/Dialect/Arith/value-bounds-op-interface-impl.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
index e7cbee6b06c45..ec611ca7924be 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithDialect.cpp
@@ -56,7 +56,7 @@ void arith::ArithDialect::initialize() {
declarePromisedInterfaces<bufferization::BufferizableOpInterface, ConstantOp,
IndexCastOp, SelectOp>();
declarePromisedInterfaces<ValueBoundsOpInterface, AddIOp, ConstantOp, SubIOp,
- MulIOp>();
+ MulIOp, SelectOp, FloorDivSIOp, MinSIOp, MaxSIOp>();
}
/// Materialize an integer or floating point constant.
diff --git a/mlir/lib/Dialect/Arith/IR/ValueBoundsOpInterfaceImpl.cpp b/mlir/lib/Dialect/Arith/IR/ValueBoundsOpInterfaceImpl.cpp
index bd0c262f932e3..3440c60f169d3 100644
--- a/mlir/lib/Dialect/Arith/IR/ValueBoundsOpInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ValueBoundsOpInterfaceImpl.cpp
@@ -160,6 +160,36 @@ struct SelectOpInterface
populateBounds(cast<SelectOp>(op), dim, cstr);
}
};
+
+struct MinSIOpInterface
+ : public ValueBoundsOpInterface::ExternalModel<MinSIOpInterface,
+ arith::MinSIOp> {
+ void populateBoundsForIndexValue(Operation *op, Value value,
+ ValueBoundsConstraintSet &cstr) const {
+ auto minOp = cast<arith::MinSIOp>(op);
+ assert(value == minOp.getResult() && "invalid value");
+
+ AffineExpr lhs = cstr.getExpr(minOp.getLhs());
+ AffineExpr rhs = cstr.getExpr(minOp.getRhs());
+ cstr.bound(value) <= lhs;
+ cstr.bound(value) <= rhs;
+ }
+};
+
+struct MaxSIOpInterface
+ : public ValueBoundsOpInterface::ExternalModel<MaxSIOpInterface,
+ arith::MaxSIOp> {
+ void populateBoundsForIndexValue(Operation *op, Value value,
+ ValueBoundsConstraintSet &cstr) const {
+ auto maxOp = cast<arith::MaxSIOp>(op);
+ assert(value == maxOp.getResult() && "invalid value");
+
+ AffineExpr lhs = cstr.getExpr(maxOp.getLhs());
+ AffineExpr rhs = cstr.getExpr(maxOp.getRhs());
+ cstr.bound(value) >= lhs;
+ cstr.bound(value) >= rhs;
+ }
+};
} // namespace
} // namespace arith
} // namespace mlir
@@ -173,5 +203,7 @@ void mlir::arith::registerValueBoundsOpInterfaceExternalModels(
arith::MulIOp::attachInterface<arith::MulIOpInterface>(*ctx);
arith::FloorDivSIOp::attachInterface<arith::FloorDivSIOpInterface>(*ctx);
arith::SelectOp::attachInterface<arith::SelectOpInterface>(*ctx);
+ arith::MinSIOp::attachInterface<arith::MinSIOpInterface>(*ctx);
+ arith::MaxSIOp::attachInterface<arith::MaxSIOpInterface>(*ctx);
});
}
diff --git a/mlir/test/Dialect/Arith/value-bounds-op-interface-impl.mlir b/mlir/test/Dialect/Arith/value-bounds-op-interface-impl.mlir
index 78802a282f096..3f55037f46f09 100644
--- a/mlir/test/Dialect/Arith/value-bounds-op-interface-impl.mlir
+++ b/mlir/test/Dialect/Arith/value-bounds-op-interface-impl.mlir
@@ -168,3 +168,52 @@ func.func @arith_select_elementwise(%a: tensor<?xf32>, %b: tensor<?xf32>, %c: te
// CHECK: return %[[dim]]
return %0 : index
}
+
+// -----
+
+// CHECK-LABEL: func @arith_minsi(
+// CHECK-SAME: %[[a:.*]]: index
+// CHECK: %[[ub:.*]] = arith.constant 5 : index
+// CHECK: return %[[ub]]
+func.func @arith_minsi(%a: index) -> index {
+ %c4 = arith.constant 4 : index
+ %0 = arith.minsi %a, %c4 : index
+ %1 = "test.reify_bound"(%0) {type = "UB"} : (index) -> (index)
+ return %1 : index
+}
+
+// -----
+
+func.func @arith_minsi_lb(%a: index) -> index {
+ %c4 = arith.constant 4 : index
+ %0 = arith.minsi %a, %c4 : index
+ // Signed min has no lower bound.
+ // expected-error @below{{could not reify bound}}
+ %1 = "test.reify_bound"(%0) {type = "LB"} : (index) -> (index)
+ return %1 : index
+}
+
+// -----
+
+// CHECK-LABEL: func @arith_maxsi(
+// CHECK-SAME: %[[a:.*]]: index
+// CHECK: arith.constant 4 : index
+// CHECK: %[[lb:.*]] = arith.constant 4 : index
+// CHECK: return %[[lb]]
+func.func @arith_maxsi(%a: index) -> index {
+ %c4 = arith.constant 4 : index
+ %0 = arith.maxsi %a, %c4 : index
+ %1 = "test.reify_bound"(%0) {type = "LB"} : (index) -> (index)
+ return %1 : index
+}
+
+// -----
+
+func.func @arith_maxsi_ub(%a: index) -> index {
+ %c4 = arith.constant 4 : index
+ %0 = arith.maxsi %a, %c4 : index
+ // Signed max has no upper bound.
+ // expected-error @below{{could not reify bound}}
+ %1 = "test.reify_bound"(%0) {type = "UB"} : (index) -> (index)
+ return %1 : index
+}
More information about the Mlir-commits
mailing list