[Mlir-commits] [mlir] 7eeaa78 - [MLIR] FlatAffineConstraints: Fixed bug where some divisions were not being detected
Arjun P
llvmlistbot at llvm.org
Mon Aug 2 05:24:01 PDT 2021
Author: Kunwar Shaanjeet Singh Grover
Date: 2021-08-02T17:51:48+05:30
New Revision: 7eeaa782c430dd47c7da04b79f2d3f87cde77b4e
URL: https://github.com/llvm/llvm-project/commit/7eeaa782c430dd47c7da04b79f2d3f87cde77b4e
DIFF: https://github.com/llvm/llvm-project/commit/7eeaa782c430dd47c7da04b79f2d3f87cde77b4e.diff
LOG: [MLIR] FlatAffineConstraints: Fixed bug where some divisions were not being detected
This patch fixes a bug in the existing implementation of detectAsFloorDiv,
where floordivs with numerator with non-zero constant term and floordivs with
numerator only consisting of a constant term were not being detected.
Reviewed By: vinayaka-polymage
Differential Revision: https://reviews.llvm.org/D107214
Added:
Modified:
mlir/lib/Analysis/AffineStructures.cpp
mlir/unittests/Analysis/AffineStructuresTest.cpp
Removed:
################################################################################
diff --git a/mlir/lib/Analysis/AffineStructures.cpp b/mlir/lib/Analysis/AffineStructures.cpp
index d2e2e1314dc4f..a198d1a208b72 100644
--- a/mlir/lib/Analysis/AffineStructures.cpp
+++ b/mlir/lib/Analysis/AffineStructures.cpp
@@ -1524,59 +1524,62 @@ static bool detectAsFloorDiv(const FlatAffineConstraints &cst, unsigned pos,
// divisor * id <= expr <-- Upper bound for 'id'
// Then, 'id' is equivalent to 'expr floordiv divisor'. (where divisor > 1).
//
- // For example, if -32*k + 16*i + j >= 0
- // 32*k - 16*i - j + 31 >= 0 <=>
- // k = ( 16*i + j ) floordiv 32
- unsigned seenDividends = 0;
+ // For example:
+ // 32*k >= 16*i + j - 31 <-- Lower bound for 'k'
+ // 32*k <= 16*i + j <-- Upper bound for 'k'
+ // expr = 16*i + j, divisor = 32
+ // k = ( 16*i + j ) floordiv 32
+ //
+ // 4q >= i + j - 2 <-- Lower bound for 'q'
+ // 4q <= i + j + 1 <-- Upper bound for 'q'
+ // expr = i + j + 1, divisor = 4
+ // q = (i + j + 1) floordiv 4
for (auto ubPos : ubIndices) {
for (auto lbPos : lbIndices) {
- // Check if the lower bound's constant term is divisor - 1. The
- // 'divisor' here is cst.atIneq(lbPos, pos) and we already know that it's
- // positive (since cst.Ineq(lbPos, ...) is a lower bound expr for 'pos'.
+ // Due to the form of the inequalities, the sum of constants of upper
+ // bound and lower bound is divisor - 1. The 'divisor' here is
+ // cst.atIneq(lbPos, pos) and we already know that it's positive (since
+ // cst.Ineq(lbPos, ...) is a lower bound expr for 'pos'.
+ // Check if this sum of constants is divisor - 1.
int64_t divisor = cst.atIneq(lbPos, pos);
- int64_t lbConstTerm = cst.atIneq(lbPos, cst.getNumCols() - 1);
- if (lbConstTerm != divisor - 1)
- continue;
- // Check if upper bound's constant term is 0.
- if (cst.atIneq(ubPos, cst.getNumCols() - 1) != 0)
+ int64_t constantSum = cst.atIneq(lbPos, cst.getNumCols() - 1) +
+ cst.atIneq(ubPos, cst.getNumCols() - 1);
+ if (constantSum != divisor - 1)
continue;
// For the remaining part, check if the lower bound expr's coeff's are
// negations of corresponding upper bound ones'.
unsigned c, f;
- for (c = 0, f = cst.getNumCols() - 1; c < f; c++) {
+ for (c = 0, f = cst.getNumCols() - 1; c < f; ++c)
if (cst.atIneq(lbPos, c) != -cst.atIneq(ubPos, c))
break;
- if (c != pos && cst.atIneq(lbPos, c) != 0)
- seenDividends++;
- }
// Lb coeff's aren't negative of ub coeff's (for the non constant term
// part).
if (c < f)
continue;
- if (seenDividends >= 1) {
- // Construct the dividend expression.
- auto dividendExpr = getAffineConstantExpr(0, context);
- unsigned c, f;
- for (c = 0, f = cst.getNumCols() - 1; c < f; c++) {
- if (c == pos)
- continue;
- int64_t ubVal = cst.atIneq(ubPos, c);
- if (ubVal == 0)
- continue;
- if (!exprs[c])
- break;
- dividendExpr = dividendExpr + ubVal * exprs[c];
- }
- // Expression can't be constructed as it depends on a yet unknown
- // identifier.
- // TODO: Visit/compute the identifiers in an order so that this doesn't
- // happen. More complex but much more efficient.
- if (c < f)
+ // Due to the form of the upper bound inequality, the constant term of
+ // `expr` is the constant term of upper bound inequality.
+ int64_t divConstantTerm = cst.atIneq(ubPos, cst.getNumCols() - 1);
+ // Construct the dividend expression.
+ auto dividendExpr = getAffineConstantExpr(divConstantTerm, context);
+ for (c = 0, f = cst.getNumCols() - 1; c < f; ++c) {
+ if (c == pos)
continue;
- // Successfully detected the floordiv.
- exprs[pos] = dividendExpr.floorDiv(divisor);
- return true;
+ int64_t ubVal = cst.atIneq(ubPos, c);
+ if (ubVal == 0)
+ continue;
+ if (!exprs[c])
+ break;
+ dividendExpr = dividendExpr + ubVal * exprs[c];
}
+ // Expression can't be constructed as it depends on a yet unknown
+ // identifier.
+ // TODO: Visit/compute the identifiers in an order so that this doesn't
+ // happen. More complex but much more efficient.
+ if (c < f)
+ continue;
+ // Successfully detected the floordiv.
+ exprs[pos] = dividendExpr.floorDiv(divisor);
+ return true;
}
}
return false;
diff --git a/mlir/unittests/Analysis/AffineStructuresTest.cpp b/mlir/unittests/Analysis/AffineStructuresTest.cpp
index 3ee6f049c9a20..a0344a43e670f 100644
--- a/mlir/unittests/Analysis/AffineStructuresTest.cpp
+++ b/mlir/unittests/Analysis/AffineStructuresTest.cpp
@@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include "mlir/Analysis/AffineStructures.h"
+#include "mlir/IR/IntegerSet.h"
+#include "mlir/IR/MLIRContext.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -587,4 +589,25 @@ TEST(FlatAffineConstraintsTest, clearConstraints) {
EXPECT_EQ(fac.atIneq(0, 1), 0);
}
+TEST(FlatAffineConstraintsTest, constantDivs) {
+ // This test checks if floordivs with numerator containing non zero constant
+ // term can be computed from a FlatAffineConstraints instance.
+ FlatAffineConstraints fac = makeFACFromConstraints(4, {}, {});
+
+ // Build a FlatAffineConstraints instance with floordivs containing numerator
+ // with non zero constant term.
+ fac.addLocalFloorDiv({0, 1, 0, 0, 10}, 30);
+ fac.addLocalFloorDiv({1, 0, 0, 0, 0, 99}, 101);
+
+ // Add inequalities using the local variables created above.
+ fac.addInequality({1, 0, 0, 0, 1, 0, 2});
+ fac.addInequality({1, 0, 0, 0, 0, 1, 5});
+
+ // FlatAffineConstraints::getAsIntegerSet returns a null integer set if an
+ // explicit representation for each local variable could not be found.
+ MLIRContext ctx;
+ IntegerSet iSet = fac.getAsIntegerSet(&ctx);
+ EXPECT_TRUE((bool)iSet);
+}
+
} // namespace mlir
More information about the Mlir-commits
mailing list