Skip to content

Commit ea3959e

Browse files
authored
[MLIR][Arith] Add ValueBoundsOpInterface for FloorDivSI (#137879)
Enables value bounds inference through signed division operations.
1 parent 0bd992a commit ea3959e

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

mlir/lib/Dialect/Arith/IR/ValueBoundsOpInterfaceImpl.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,20 @@ struct MulIOpInterface
7575
}
7676
};
7777

78+
struct FloorDivSIOpInterface
79+
: public ValueBoundsOpInterface::ExternalModel<FloorDivSIOpInterface,
80+
FloorDivSIOp> {
81+
void populateBoundsForIndexValue(Operation *op, Value value,
82+
ValueBoundsConstraintSet &cstr) const {
83+
auto divSIOp = cast<FloorDivSIOp>(op);
84+
assert(value == divSIOp.getResult() && "invalid value");
85+
86+
AffineExpr lhs = cstr.getExpr(divSIOp.getLhs());
87+
AffineExpr rhs = cstr.getExpr(divSIOp.getRhs());
88+
cstr.bound(value) == lhs.floorDiv(rhs);
89+
}
90+
};
91+
7892
struct SelectOpInterface
7993
: public ValueBoundsOpInterface::ExternalModel<SelectOpInterface,
8094
SelectOp> {
@@ -157,6 +171,7 @@ void mlir::arith::registerValueBoundsOpInterfaceExternalModels(
157171
arith::ConstantOp::attachInterface<arith::ConstantOpInterface>(*ctx);
158172
arith::SubIOp::attachInterface<arith::SubIOpInterface>(*ctx);
159173
arith::MulIOp::attachInterface<arith::MulIOpInterface>(*ctx);
174+
arith::FloorDivSIOp::attachInterface<arith::FloorDivSIOpInterface>(*ctx);
160175
arith::SelectOp::attachInterface<arith::SelectOpInterface>(*ctx);
161176
});
162177
}

mlir/test/Dialect/Arith/value-bounds-op-interface-impl.mlir

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,30 @@ func.func @arith_muli_non_pure(%a: index, %b: index) -> index {
6565

6666
// -----
6767

68+
// CHECK: #[[$map:.*]] = affine_map<()[s0] -> (s0 floordiv 5)>
69+
// CHECK-LABEL: func @arith_floordivsi(
70+
// CHECK-SAME: %[[a:.*]]: index
71+
// CHECK: %[[apply:.*]] = affine.apply #[[$map]]()[%[[a]]]
72+
// CHECK: return %[[apply]]
73+
func.func @arith_floordivsi(%a: index) -> index {
74+
%0 = arith.constant 5 : index
75+
%1 = arith.floordivsi %a, %0 : index
76+
%2 = "test.reify_bound"(%1) : (index) -> (index)
77+
return %2 : index
78+
}
79+
80+
// -----
81+
82+
func.func @arith_floordivsi_non_pure(%a: index, %b: index) -> index {
83+
%0 = arith.floordivsi %a, %b : index
84+
// Semi-affine expressions (such as "symbol * symbol") are not supported.
85+
// expected-error @below{{could not reify bound}}
86+
%1 = "test.reify_bound"(%0) : (index) -> (index)
87+
return %1 : index
88+
}
89+
90+
// -----
91+
6892
// CHECK-LABEL: func @arith_const()
6993
// CHECK: %[[c5:.*]] = arith.constant 5 : index
7094
// CHECK: %[[c5:.*]] = arith.constant 5 : index

0 commit comments

Comments
 (0)