Skip to content

Commit 8112d1a

Browse files
committed
Add check to ensure pass fails gracefully
1 parent 84157c0 commit 8112d1a

File tree

3 files changed

+67
-10
lines changed

3 files changed

+67
-10
lines changed

mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,21 @@ static Operation *vectorizeAffineLoad(AffineLoadOp loadOp,
12171217
indices.append(mapOperands.begin(), mapOperands.end());
12181218
}
12191219

1220+
for (auto &kvp : state.vecLoopToVecDim) {
1221+
AffineForOp forOp = cast<AffineForOp>(kvp.first);
1222+
auto invariants =
1223+
affine::getInvariantAccesses(forOp.getInductionVar(), indices);
1224+
unsigned nonInvariant = 0;
1225+
for (Value idx : indices)
1226+
if (!invariants.count(idx))
1227+
++nonInvariant;
1228+
if (nonInvariant > 1) {
1229+
LLVM_DEBUG(dbgs() << "\n[early-vect] Bail out: loop IV "
1230+
<< forOp.getInductionVar() << " drives " << nonInvariant
1231+
<< " indices (must be ≤1)\n");
1232+
return nullptr;
1233+
}
1234+
}
12201235
// Compute permutation map using the information of new vector loops.
12211236
auto permutationMap = makePermutationMap(state.builder.getInsertionBlock(),
12221237
indices, state.vecLoopToVecDim);
@@ -1262,6 +1277,21 @@ static Operation *vectorizeAffineStore(AffineStoreOp storeOp,
12621277
else
12631278
indices.append(mapOperands.begin(), mapOperands.end());
12641279

1280+
for (auto &kvp : state.vecLoopToVecDim) {
1281+
AffineForOp forOp = cast<AffineForOp>(kvp.first);
1282+
auto invariants =
1283+
affine::getInvariantAccesses(forOp.getInductionVar(), indices);
1284+
unsigned nonInvariant = 0;
1285+
for (Value idx : indices)
1286+
if (!invariants.count(idx))
1287+
++nonInvariant;
1288+
if (nonInvariant > 1) {
1289+
LLVM_DEBUG(dbgs() << "\n[early-vect] Bail out: loop IV "
1290+
<< forOp.getInductionVar() << " drives " << nonInvariant
1291+
<< " indices (must be ≤1)\n");
1292+
return nullptr;
1293+
}
1294+
}
12651295
// Compute permutation map using the information of new vector loops.
12661296
auto permutationMap = makePermutationMap(state.builder.getInsertionBlock(),
12671297
indices, state.vecLoopToVecDim);

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,8 @@ static AffineMap makePermutationMap(
141141
unsigned countInvariantIndices = 0;
142142
for (unsigned dim = 0; dim < numIndices; ++dim) {
143143
if (!invariants.count(indices[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-
}
144+
assert(perm[kvp.second] == getAffineConstantExpr(0, context) &&
145+
"permutationMap already has an entry along dim");
152146
perm[kvp.second] = getAffineDimExpr(dim, context);
153147
} else {
154148
++countInvariantIndices;

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

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func.func @unparallel_loop_reduction_unsupported(%in: memref<256x512xf32>, %out:
1515
#map = affine_map<(d0)[s0] -> (d0 mod s0)>
1616
#map1 = affine_map<(d0)[s0] -> (d0 floordiv s0)>
1717

18-
func.func @single_loop_unrolling_2D_access_pattern(%arg0: index) -> memref<2x2xf32> {
18+
func.func @single_loop_unrolling_2D_access_pattern_storeOp(%arg0: index) -> memref<2x2xf32> {
1919
%c2 = arith.constant 2 : index
2020
%cst = arith.constant 1.0 : f32
2121
%alloc = memref.alloc() : memref<2x2xf32>
@@ -33,7 +33,7 @@ func.func @single_loop_unrolling_2D_access_pattern(%arg0: index) -> memref<2x2xf
3333
// CHECK: #[[$ATTR_1:.+]] = affine_map<(d0)[s0] -> (d0 mod s0)>
3434

3535
// 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> {
36+
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: index) -> memref<2x2xf32> {
3737
// CHECK: %[[VAL_1:.*]] = arith.constant 2 : index
3838
// CHECK: %[[VAL_2:.*]] = arith.constant 1.000000e+00 : f32
3939
// CHECK: %[[VAL_3:.*]] = memref.alloc() : memref<2x2xf32>
@@ -43,4 +43,37 @@ func.func @single_loop_unrolling_2D_access_pattern(%arg0: index) -> memref<2x2xf
4343
// CHECK: affine.store %[[VAL_2]], %[[VAL_3]]{{\[}}%[[VAL_5]], %[[VAL_6]]] : memref<2x2xf32>
4444
// CHECK: }
4545
// CHECK: return %[[VAL_3]] : memref<2x2xf32>
46+
// CHECK: }
47+
48+
// -----
49+
50+
#map = affine_map<(d0)[s0] -> (d0 mod s0)>
51+
#map1 = affine_map<(d0)[s0] -> (d0 floordiv s0)>
52+
53+
func.func @single_loop_unrolling_2D_access_pattern_loadOp(%arg0: index) -> memref<2x2xf32> {
54+
%c2 = arith.constant 2 : index
55+
%alloc = memref.alloc() : memref<2x2xf32>
56+
57+
affine.for %i = 0 to 4 {
58+
%row = affine.apply #map1(%i)[%c2]
59+
%col = affine.apply #map(%i)[%c2]
60+
%val = affine.load %alloc[%row, %col] : memref<2x2xf32>
61+
}
62+
63+
return %alloc : memref<2x2xf32>
64+
}
65+
66+
// CHECK: #[[$ATTR_0:.+]] = affine_map<(d0)[s0] -> (d0 floordiv s0)>
67+
// CHECK: #[[$ATTR_1:.+]] = affine_map<(d0)[s0] -> (d0 mod s0)>
68+
69+
// CHECK-LABEL: func.func @single_loop_unrolling_2D_access_pattern(
70+
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: index) -> memref<2x2xf32> {
71+
// CHECK: %[[VAL_1:.*]] = arith.constant 2 : index
72+
// CHECK: %[[VAL_2:.*]] = memref.alloc() : memref<2x2xf32>
73+
// CHECK: affine.for %[[VAL_3:.*]] = 0 to 4 {
74+
// CHECK: %[[VAL_4:.*]] = affine.apply #[[$ATTR_0]](%[[VAL_3]]){{\[}}%[[VAL_1]]]
75+
// CHECK: %[[VAL_5:.*]] = affine.apply #[[$ATTR_1]](%[[VAL_3]]){{\[}}%[[VAL_1]]]
76+
// CHECK: %[[VAL_6:.*]] = affine.load %[[VAL_2]]{{\[}}%[[VAL_4]], %[[VAL_5]]] : memref<2x2xf32>
77+
// CHECK: }
78+
// CHECK: return %[[VAL_2]] : memref<2x2xf32>
4679
// CHECK: }

0 commit comments

Comments
 (0)