[Mlir-commits] [mlir] [MLIR][Vector] Fix ShapeCastBroadcastFolder when shape_cast changes non-unit dim strides (PR #227574)
Federico Bruzzone
llvmlistbot at llvm.org
Wed Oct 14 03:48:20 PDT 2026
================
@@ -7173,37 +7157,65 @@ class ShapeCastBroadcastFolder final : public OpRewritePattern<ShapeCastOp> {
if (!broadcastOp)
return failure();
- auto srcVectorType = dyn_cast<VectorType>(broadcastOp.getSourceType());
- bool srcIsScalar = !srcVectorType;
-
// Replace Y = ShapeCast(Broadcast(X)) with Y = Broadcast(X)
// Example
// %0 = vector.broadcast %in : vector<3xf32> to vector<2x4x3xf32>
// %1 = vector.shape_cast %0 : vector<2x4x3xf32> to vector<8x3xf32>
// to
// %1 = vector.broadcast %in : vector<3xf32> to vector<8x3xf32>
+ auto srcVectorType = dyn_cast<VectorType>(broadcastOp.getSourceType());
+ bool srcIsScalar = !srcVectorType;
VectorType dstVectorType = shapeCastOp.getResultVectorType();
- ArrayRef<int64_t> dstShape = dstVectorType.getShape();
- ArrayRef<int64_t> srcShape =
- srcIsScalar ? ArrayRef<int64_t>{} : srcVectorType.getShape();
- ArrayRef<int64_t> broadcastShape =
- broadcastOp.getResultVectorType().getShape();
if (!srcIsScalar) {
if (isBroadcastableTo(srcVectorType, dstVectorType) !=
BroadcastableToResult::Success) {
return failure();
}
- // Avoid folding if this would result in switching between the two
- // distinct semantic modes of vector.broadcast (duplication vs
- // stretching). See https://github.com/llvm/llvm-project/issues/190614.
- // This is detected by a change in the stretching factor. However if the
- // source has a single element, there is no ambiguity.
- if (srcVectorType.getNumElements() != 1) {
- if (getBroadcastStretchingFactor(srcShape, dstShape) !=
- getBroadcastStretchingFactor(srcShape, broadcastShape)) {
+ // `shape_cast` preserves the flattened 1-D (row-major) element order.
+ // Thus, `shape_cast(broadcast(src, broadcastShape), dstShape)` produces
+ // the exact same elements as `broadcast(src, dstShape)` if and only if
+ // every non-unit dimension of `src` has the same linear stride in both
+ // `broadcastShape` and `dstShape`.
+ //
+ // A scalable dimension of static size D has runtime size D * vscale.
+ // A linear stride through trailing dimensions is thus:
+ // stride = staticStride * (vscale ^ numScalableDims)
+ // Since vscale is an unknown runtime quantity (vscale >= 1), both
+ // staticStride and numScalableDims must match to guarantee stride
+ // equivalence across all targets.
+ VectorType broadcastVectorType = broadcastOp.getResultVectorType();
+ SmallVector<int64_t> bcastStrides =
+ computeStrides(broadcastVectorType.getShape());
+ SmallVector<int64_t> dstStrides =
----------------
FedericoBruzzone wrote:
Missing test coverage for rank-0 source, maybe?
https://github.com/llvm/llvm-project/pull/227574
More information about the Mlir-commits
mailing list