[Mlir-commits] [mlir] [mlir][linalg] Fix rank-reducing insert_slice vectorization writing to wrong dims (PR #226490)
Dhairyashil R G
llvmlistbot at llvm.org
Sun Oct 4 09:14:18 PDT 2026
================
@@ -581,37 +581,41 @@ Operation *vector::createWriteOrMaskedWrite(OpBuilder &builder, Location loc,
if (useInBoundsInsteadOfMasking)
return write;
+ // The dest dims written to are those the permutation map selects. A null map
+ // means a minor identity: the trailing dims.
+ AffineMap map = permutationMap
+ ? permutationMap
+ : AffineMap::getMinorIdentityMap(destRank, vecToStoreRank,
+ builder.getContext());
+
// Check if masking is needed. If not, exit.
- if (llvm::equal(vecToStoreShape, destShape.take_back(vecToStoreRank)))
+ if (llvm::equal(vecToStoreShape, applyPermutationMap(map, destShape)))
return write;
// Compute the mask and mask the write Op.
- auto writeMaskType = VectorType::get(vecToStoreShape, builder.getI1Type(),
- vecToStoreType.getScalableDims());
+ VectorType writeMaskType = inferTransferOpMaskType(vecToStoreType, map);
SmallVector<OpFoldResult> destSizes =
isa<MemRefType>(dest.getType())
? memref::getMixedSizes(builder, loc, dest)
: tensor::getMixedSizes(builder, loc, dest);
- // Compute sizes for write-mask
+ // Compute sizes for write-mask: `dim - index` for each dest dim written to,
+ // in increasing order, as the mask dims are.
+ SmallVector<int64_t> writtenDims;
+ for (AffineExpr expr : map.getResults())
+ writtenDims.push_back(cast<AffineDimExpr>(expr).getPosition());
+ llvm::sort(writtenDims);
SmallVector<OpFoldResult> maskSizes;
- if (useDefaultWriteIdxs) {
- maskSizes = SmallVector<OpFoldResult>(destSizes.end() - vecToStoreRank,
- destSizes.end());
- } else {
- size_t diff = destShape.size() - vecToStoreRank;
- for (int64_t idx = 0; idx < vecToStoreRank; idx++) {
- auto value =
- getValueOrCreateConstantIndexOp(builder, loc, destSizes[diff + idx]);
- auto neg =
- builder.createOrFold<arith::SubIOp>(loc, value, writeIndices[idx]);
- maskSizes.push_back(OpFoldResult(neg));
- }
+ for (int64_t dim : writtenDims) {
+ Value size = getValueOrCreateConstantIndexOp(builder, loc, destSizes[dim]);
+ maskSizes.push_back(
+ builder.createOrFold<arith::SubIOp>(loc, size, writeIndices[dim]));
}
- if (isMaskTriviallyFoldable(maskSizes, writeIndices, destShape,
- vecToStoreShape))
+ // isMaskTriviallyFoldable does not take a permutation map.
----------------
dhairyashilRG wrote:
Yes, I've made it a TODO. `isMaskTriviallyFoldable` checks the trailing dims against the leading indices, so with a map it can drop a mask that is needed: without this check, `@insert_slice_leading_unit_dim_dropped_non_zero_offset` loses its mask. For now, a mask that could be dropped is kept when there is a map, and `-canonicalize` removes it. I can fix this in a follow-up.
https://github.com/llvm/llvm-project/pull/226490
More information about the Mlir-commits
mailing list