Skip to content

Commit 84157c0

Browse files
committed
[mlir][affine] Modify assertion into a user visible diagnostic
1 parent 35f4cdb commit 84157c0

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,14 @@ static AffineMap makePermutationMap(
141141
unsigned countInvariantIndices = 0;
142142
for (unsigned dim = 0; dim < numIndices; ++dim) {
143143
if (!invariants.count(indices[dim])) {
144-
assert(perm[kvp.second] == getAffineConstantExpr(0, context) &&
145-
"permutationMap already has an entry along dim");
144+
if (perm[kvp.second] != getAffineConstantExpr(0, context)) {
145+
auto loopOp = cast<affine::AffineForOp>(kvp.first);
146+
loopOp->emitError(
147+
"loop induction variable is used in multiple indices, which is "
148+
"unsupported for vectorization. Consider using nested loops "
149+
"instead of a single loop with affine.apply.");
150+
return AffineMap();
151+
}
146152
perm[kvp.second] = getAffineDimExpr(dim, context);
147153
} else {
148154
++countInvariantIndices;

mlir/test/Dialect/Affine/SuperVectorize/vectorize_unsupported.mlir

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,38 @@ func.func @unparallel_loop_reduction_unsupported(%in: memref<256x512xf32>, %out:
99
}
1010
return
1111
}
12+
13+
// -----
14+
15+
#map = affine_map<(d0)[s0] -> (d0 mod s0)>
16+
#map1 = affine_map<(d0)[s0] -> (d0 floordiv s0)>
17+
18+
func.func @single_loop_unrolling_2D_access_pattern(%arg0: index) -> memref<2x2xf32> {
19+
%c2 = arith.constant 2 : index
20+
%cst = arith.constant 1.0 : f32
21+
%alloc = memref.alloc() : memref<2x2xf32>
22+
23+
affine.for %i = 0 to 4 {
24+
%row = affine.apply #map1(%i)[%c2]
25+
%col = affine.apply #map(%i)[%c2]
26+
affine.store %cst, %alloc[%row, %col] : memref<2x2xf32>
27+
}
28+
29+
return %alloc : memref<2x2xf32>
30+
}
31+
32+
// CHECK: #[[$ATTR_0:.+]] = affine_map<(d0)[s0] -> (d0 floordiv s0)>
33+
// CHECK: #[[$ATTR_1:.+]] = affine_map<(d0)[s0] -> (d0 mod s0)>
34+
35+
// CHECK-LABEL: func.func @single_loop_unrolling_2D_access_pattern(
36+
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: index) -> memref<2x2xf32> {
37+
// CHECK: %[[VAL_1:.*]] = arith.constant 2 : index
38+
// CHECK: %[[VAL_2:.*]] = arith.constant 1.000000e+00 : f32
39+
// CHECK: %[[VAL_3:.*]] = memref.alloc() : memref<2x2xf32>
40+
// CHECK: affine.for %[[VAL_4:.*]] = 0 to 4 {
41+
// CHECK: %[[VAL_5:.*]] = affine.apply #[[$ATTR_0]](%[[VAL_4]]){{\[}}%[[VAL_1]]]
42+
// CHECK: %[[VAL_6:.*]] = affine.apply #[[$ATTR_1]](%[[VAL_4]]){{\[}}%[[VAL_1]]]
43+
// CHECK: affine.store %[[VAL_2]], %[[VAL_3]]{{\[}}%[[VAL_5]], %[[VAL_6]]] : memref<2x2xf32>
44+
// CHECK: }
45+
// CHECK: return %[[VAL_3]] : memref<2x2xf32>
46+
// CHECK: }

0 commit comments

Comments
 (0)