Skip to content

Commit 715137d

Browse files
committed
[MLIR] Fix memref get constant bound size and shape method
Fix FlatAffineConstraints::getConstantBoundOnDimSize to ensure that returned bounds on dim size are always non-negative regardless of the constraints on that dimension. Add an assertion at the user. Differential Revision: https://reviews.llvm.org/D105171
1 parent b931c2a commit 715137d

File tree

5 files changed

+36
-27
lines changed

5 files changed

+36
-27
lines changed

mlir/include/mlir/Analysis/AffineStructures.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -491,18 +491,19 @@ class FlatAffineConstraints {
491491
/// Returns the smallest known constant bound for the extent of the specified
492492
/// identifier (pos^th), i.e., the smallest known constant that is greater
493493
/// than or equal to 'exclusive upper bound' - 'lower bound' of the
494-
/// identifier. Returns None if it's not a constant. This method employs
495-
/// trivial (low complexity / cost) checks and detection. Symbolic identifiers
496-
/// are treated specially, i.e., it looks for constant differences between
497-
/// affine expressions involving only the symbolic identifiers. `lb` and
498-
/// `ub` (along with the `boundFloorDivisor`) are set to represent the lower
499-
/// and upper bound associated with the constant difference: `lb`, `ub` have
500-
/// the coefficients, and boundFloorDivisor, their divisor. `minLbPos` and
501-
/// `minUbPos` if non-null are set to the position of the constant lower bound
502-
/// and upper bound respectively (to the same if they are from an equality).
503-
/// Ex: if the lower bound is [(s0 + s2 - 1) floordiv 32] for a system with
504-
/// three symbolic identifiers, *lb = [1, 0, 1], lbDivisor = 32. See comments
505-
/// at function definition for examples.
494+
/// identifier. This constant bound is guaranteed to be non-negative. Returns
495+
/// None if it's not a constant. This method employs trivial (low complexity /
496+
/// cost) checks and detection. Symbolic identifiers are treated specially,
497+
/// i.e., it looks for constant differences between affine expressions
498+
/// involving only the symbolic identifiers. `lb` and `ub` (along with the
499+
/// `boundFloorDivisor`) are set to represent the lower and upper bound
500+
/// associated with the constant difference: `lb`, `ub` have the coefficients,
501+
/// and boundFloorDivisor, their divisor. `minLbPos` and `minUbPos` if
502+
/// non-null are set to the position of the constant lower bound and upper
503+
/// bound respectively (to the same if they are from an equality). Ex: if the
504+
/// lower bound is [(s0 + s2 - 1) floordiv 32] for a system with three
505+
/// symbolic identifiers, *lb = [1, 0, 1], lbDivisor = 32. See comments at
506+
/// function definition for examples.
506507
Optional<int64_t> getConstantBoundOnDimSize(
507508
unsigned pos, SmallVectorImpl<int64_t> *lb = nullptr,
508509
int64_t *boundFloorDivisor = nullptr,

mlir/include/mlir/Analysis/Utils.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,11 @@ struct MemRefRegion {
279279
/// otherwise. Note that the symbols of the region are treated specially,
280280
/// i.e., the returned bounding constant holds for *any given* value of the
281281
/// symbol identifiers. The 'shape' vector is set to the corresponding
282-
/// dimension-wise bounds major to minor. We use int64_t instead of uint64_t
283-
/// since index types can be at most int64_t. `lbs` are set to the lower
284-
/// bounds for each of the rank dimensions, and lbDivisors contains the
285-
/// corresponding denominators for floorDivs.
282+
/// dimension-wise bounds major to minor. The number of elements and all the
283+
/// dimension-wise bounds are guaranteed to be non-negative. We use int64_t
284+
/// instead of uint64_t since index types can be at most int64_t. `lbs` are
285+
/// set to the lower bounds for each of the rank dimensions, and lbDivisors
286+
/// contains the corresponding denominators for floorDivs.
286287
Optional<int64_t> getConstantBoundingSizeAndShape(
287288
SmallVectorImpl<int64_t> *shape = nullptr,
288289
std::vector<SmallVector<int64_t, 4>> *lbs = nullptr,

mlir/lib/Analysis/AffineStructures.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,14 +2285,15 @@ void FlatAffineConstraints::constantFoldIdRange(unsigned pos, unsigned num) {
22852285
}
22862286
}
22872287

2288-
/// Returns the extent (upper bound - lower bound) of the specified
2289-
/// identifier if it is found to be a constant; returns None if it's not a
2290-
/// constant. This methods treats symbolic identifiers specially, i.e.,
2291-
/// it looks for constant differences between affine expressions involving
2292-
/// only the symbolic identifiers. See comments at function definition for
2293-
/// example. 'lb', if provided, is set to the lower bound associated with the
2294-
/// constant difference. Note that 'lb' is purely symbolic and thus will contain
2295-
/// the coefficients of the symbolic identifiers and the constant coefficient.
2288+
/// Returns a non-negative constant bound on the extent (upper bound - lower
2289+
/// bound) of the specified identifier if it is found to be a constant; returns
2290+
/// None if it's not a constant. This methods treats symbolic identifiers
2291+
/// specially, i.e., it looks for constant differences between affine
2292+
/// expressions involving only the symbolic identifiers. See comments at
2293+
/// function definition for example. 'lb', if provided, is set to the lower
2294+
/// bound associated with the constant difference. Note that 'lb' is purely
2295+
/// symbolic and thus will contain the coefficients of the symbolic identifiers
2296+
/// and the constant coefficient.
22962297
// Egs: 0 <= i <= 15, return 16.
22972298
// s0 + 2 <= i <= s0 + 17, returns 16. (s0 has to be a symbol)
22982299
// s0 + s1 + 16 <= d0 <= s0 + s1 + 31, returns 16.
@@ -2384,6 +2385,8 @@ Optional<int64_t> FlatAffineConstraints::getConstantBoundOnDimSize(
23842385
int64_t diff = ceilDiv(atIneq(ubPos, getNumCols() - 1) +
23852386
atIneq(lbPos, getNumCols() - 1) + 1,
23862387
atIneq(lbPos, pos));
2388+
// This bound is non-negative by definition.
2389+
diff = std::max<int64_t>(diff, 0);
23872390
if (minDiff == None || diff < minDiff) {
23882391
minDiff = diff;
23892392
minLbPosition = lbPos;

mlir/lib/Analysis/Utils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ Optional<int64_t> MemRefRegion::getConstantBoundingSizeAndShape(
374374
cstWithShapeBounds.getConstantBoundOnDimSize(d, &lb, &lbDivisor);
375375
if (diff.hasValue()) {
376376
diffConstant = diff.getValue();
377+
assert(diffConstant >= 0 && "Dim size bound can't be negative");
377378
assert(lbDivisor > 0);
378379
} else {
379380
// If no constant bound is found, then it can always be bound by the

mlir/test/Dialect/Affine/affine-data-copy.mlir

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,12 +273,15 @@ func @max_lower_bound(%M: memref<2048x516xf64>, %i : index, %j : index) {
273273

274274
// -----
275275

276-
// CHECK-LABEL: func @empty_loop
277-
func @empty_loop(%arg0: memref<1024x1024xf64>) {
278-
// Empty loop - so no copy generation happens.
276+
// CHECK-LABEL: func @empty_loops
277+
func @empty_loops(%arg0: memref<1024x1024xf64>) {
278+
// Empty loops - so no copy generation happens.
279279
affine.for %i = 0 to 0 {
280280
affine.load %arg0[0, %i] : memref<1024x1024xf64>
281281
}
282+
affine.for %i = 0 to -16 {
283+
affine.load %arg0[0, %i] : memref<1024x1024xf64>
284+
}
282285
return
283286
// CHECK-NOT: memref.alloc
284287
// CHECK: return

0 commit comments

Comments
 (0)