[Mlir-commits] [mlir] [mlir][vector] Fold transpose(broadcast(shape_cast)) to broadcast (PR #215940)

Adam Siemieniuk llvmlistbot at llvm.org
Fri Aug 21 01:59:49 PDT 2026


================
@@ -7556,64 +7568,116 @@ class FoldTransposeBroadcast : public OpRewritePattern<vector::TransposeOp> {
 
   LogicalResult matchAndRewrite(vector::TransposeOp transpose,
                                 PatternRewriter &rewriter) const override {
-
     vector::BroadcastOp broadcast =
         transpose.getVector().getDefiningOp<vector::BroadcastOp>();
-    if (!broadcast) {
+    if (!broadcast)
       return rewriter.notifyMatchFailure(transpose,
                                          "not preceded by a broadcast");
-    }
-
-    auto inputType = dyn_cast<VectorType>(broadcast.getSourceType());
-    VectorType outputType = transpose.getResultVectorType();
 
-    // transpose(broadcast(scalar)) -> broadcast(scalar) is always valid
-    bool inputIsScalar = !inputType;
-    if (inputIsScalar) {
-      rewriter.replaceOpWithNewOp<vector::BroadcastOp>(transpose, outputType,
-                                                       broadcast.getSource());
-      return success();
-    }
-
-    ArrayRef<int64_t> permutation = transpose.getPermutation();
-    ArrayRef<int64_t> inputShape = inputType.getShape();
-    int64_t inputRank = inputType.getRank();
-    int64_t outputRank = transpose.getType().getRank();
-    int64_t deltaRank = outputRank - inputRank;
-
-    int low = 0;
-    for (int inputIndex = 0; inputIndex < inputRank; ++inputIndex) {
-      bool notOne = inputShape[inputIndex] != 1;
-      bool prevNotOne = (inputIndex != 0 && inputShape[inputIndex - 1] != 1);
-      bool groupEndFound = notOne || prevNotOne;
-      if (groupEndFound) {
-        int high = inputIndex + deltaRank;
-        // Return failure if not all permutation destinations for indices in
-        // [low, high) are in [low, high), i.e. the permutation is not local to
-        // the group.
-        for (int i = low; i < high; ++i) {
-          if (permutation[i] < low || permutation[i] >= high) {
-            return rewriter.notifyMatchFailure(
-                transpose, "permutation not local to group");
-          }
-        }
-        low = high;
-      }
+    VectorType outType = transpose.getResultVectorType();
+    auto srcType = dyn_cast<VectorType>(broadcast.getSourceType());
+
+    // transpose(broadcast(scalar)) always folds. Otherwise the source must be
+    // broadcastable to the result and the transpose must leave its non-broadcast
+    // dims in place, i.e. map each to itself (from == to).
+    if (srcType) {
+      if (vector::isBroadcastableTo(srcType, outType) !=
+          vector::BroadcastableToResult::Success)
+        return rewriter.notifyMatchFailure(transpose, "not broadcastable");
+
+      int64_t rankDelta = outType.getRank() - srcType.getRank();
+      SmallVector<int64_t> axes;
+      for (int64_t axis : nonBroadcastAxes(srcType))
+        axes.push_back(axis + rankDelta);
+      if (!transposeMapsAxes(axes, axes, transpose.getPermutation()))
+        return rewriter.notifyMatchFailure(transpose,
+                                           "not an order-preserving broadcast");
----------------
adam-smnk wrote:

nit: isn't it the "transpose" that has to be order-preserving?

https://github.com/llvm/llvm-project/pull/215940


More information about the Mlir-commits mailing list