Skip to content

Commit 7f7d75b

Browse files
committed
Fix d0 + (d0 // -c) * c.
Currently, this is rewritten to d0 mod -c. However, we do not support modulo with a negative RHS in our lowering passes, so this triggers undefined behavior. It would be better to not have these ad hoc simplifications at all, but I guess that ship has sailed.
1 parent ddf40e0 commit 7f7d75b

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

mlir/lib/IR/AffineExpr.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,8 +760,11 @@ static AffineExpr simplifyAdd(AffineExpr lhs, AffineExpr rhs) {
760760

761761
llrhs = lrBinOpExpr.getLHS();
762762
rlrhs = lrBinOpExpr.getRHS();
763+
auto rlrhsConstOpExpr = dyn_cast<AffineConstantExpr>(rlrhs);
764+
// We don't support modulo with a negative RHS.
765+
bool isPositiveRhs = rlrhsConstOpExpr && rlrhsConstOpExpr.getValue() > 0;
763766

764-
if (lhs == llrhs && rlrhs == -rrhs) {
767+
if (isPositiveRhs && lhs == llrhs && rlrhs == -rrhs) {
765768
return lhs % rlrhs;
766769
}
767770
return nullptr;

mlir/unittests/IR/AffineExprTest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,13 @@ TEST(AffineExprTest, divisorOfNegativeFloorDiv) {
112112
OpBuilder b(&ctx);
113113
ASSERT_EQ(b.getAffineDimExpr(0).floorDiv(-1).getLargestKnownDivisor(), 1);
114114
}
115+
116+
TEST(AffineExprTest, d0PlusD0FloorDivNeg2) {
117+
// Regression test for a bug where this was rewritten to d0 mod -2. We do not
118+
// support a negative RHS for mod in LowerAffinePass.
119+
MLIRContext ctx;
120+
OpBuilder b(&ctx);
121+
auto d0 = b.getAffineDimExpr(0);
122+
auto sum = d0 + d0.floorDiv(-2) * 2;
123+
ASSERT_EQ(toString(sum), "d0 + (d0 floordiv -2) * 2");
124+
}

0 commit comments

Comments
 (0)