[Mlir-commits] [mlir] AffineExpr: Fix result of d0 + (d0 // -c) * c. (PR #107530)

Johannes Reifferscheid llvmlistbot at llvm.org
Fri Sep 6 00:11:29 PDT 2024


https://github.com/jreiffers created https://github.com/llvm/llvm-project/pull/107530

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.

>From 7f7d75bfaa0294fe3d95cb15486c2c05f074b6ca Mon Sep 17 00:00:00 2001
From: Johannes Reifferscheid <jreiffers at google.com>
Date: Fri, 6 Sep 2024 09:08:05 +0200
Subject: [PATCH] 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.
---
 mlir/lib/IR/AffineExpr.cpp           |  5 ++++-
 mlir/unittests/IR/AffineExprTest.cpp | 10 ++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/mlir/lib/IR/AffineExpr.cpp b/mlir/lib/IR/AffineExpr.cpp
index fc7ede279643ed..0b078966aeb85b 100644
--- a/mlir/lib/IR/AffineExpr.cpp
+++ b/mlir/lib/IR/AffineExpr.cpp
@@ -760,8 +760,11 @@ static AffineExpr simplifyAdd(AffineExpr lhs, AffineExpr rhs) {
 
   llrhs = lrBinOpExpr.getLHS();
   rlrhs = lrBinOpExpr.getRHS();
+  auto rlrhsConstOpExpr = dyn_cast<AffineConstantExpr>(rlrhs);
+  // We don't support modulo with a negative RHS.
+  bool isPositiveRhs = rlrhsConstOpExpr && rlrhsConstOpExpr.getValue() > 0;
 
-  if (lhs == llrhs && rlrhs == -rrhs) {
+  if (isPositiveRhs && lhs == llrhs && rlrhs == -rrhs) {
     return lhs % rlrhs;
   }
   return nullptr;
diff --git a/mlir/unittests/IR/AffineExprTest.cpp b/mlir/unittests/IR/AffineExprTest.cpp
index dc78bbac85f3cf..300791fff68e57 100644
--- a/mlir/unittests/IR/AffineExprTest.cpp
+++ b/mlir/unittests/IR/AffineExprTest.cpp
@@ -112,3 +112,13 @@ TEST(AffineExprTest, divisorOfNegativeFloorDiv) {
   OpBuilder b(&ctx);
   ASSERT_EQ(b.getAffineDimExpr(0).floorDiv(-1).getLargestKnownDivisor(), 1);
 }
+
+TEST(AffineExprTest, d0PlusD0FloorDivNeg2) {
+  // Regression test for a bug where this was rewritten to d0 mod -2. We do not
+  // support a negative RHS for mod in LowerAffinePass.
+  MLIRContext ctx;
+  OpBuilder b(&ctx);
+  auto d0 = b.getAffineDimExpr(0);
+  auto sum = d0 + d0.floorDiv(-2) * 2;
+  ASSERT_EQ(toString(sum), "d0 + (d0 floordiv -2) * 2");
+}



More information about the Mlir-commits mailing list