[Mlir-commits] [mlir] [mlir][Vector] Add load, store, etc. to dropleadunitdim (PR #195686)

Diego Caballero llvmlistbot at llvm.org
Mon May 4 20:59:34 PDT 2026


================
@@ -537,6 +537,101 @@ class CastAwayElementwiseLeadingOneDim : public RewritePattern {
     return success();
   }
 };
+} // namespace
+
+// Drops `dropDim` leading dimensions from `operand` using vector.extract when
+// those dims are all non-scalable units (the cheap, structural rewrite); falls
+// back to vector.shape_cast otherwise.
+static Value dropLeadingOneDimsFromOperand(OpBuilder &b, Location loc,
+                                           Value operand, int64_t nDropped) {
+  auto oldType = cast<VectorType>(operand.getType());
+  ArrayRef<int64_t> leadingShape = oldType.getShape().take_front(nDropped);
+  ArrayRef<bool> leadingScalable =
+      oldType.getScalableDims().take_front(nDropped);
+  bool extractable =
+      llvm::all_of(leadingShape, [](int64_t d) { return d == 1; }) &&
+      llvm::none_of(leadingScalable, [](bool s) { return s; });
+  if (extractable)
+    return vector::ExtractOp::create(b, loc, operand, splatZero(nDropped));
+  VectorType newType = VectorType::get(
+      oldType.getShape().drop_front(nDropped), oldType.getElementType(),
+      oldType.getScalableDims().drop_front(nDropped));
+  return vector::ShapeCastOp::create(b, loc, newType, operand);
+}
+
+namespace {
+
+// Drops leading 1 dimensions from load-like memory operaitons. REmoves leading
+// unit dimensions from the result types and then broadcasts back in those 1s,
+// while also extracting (or shape_cast-ing) any leading unit dimensions on
+// the input operands.
+template <typename OpTy>
+struct CastAwayLoadLikeLeadingOneDim : public OpRewritePattern<OpTy> {
+  using OpRewritePattern<OpTy>::OpRewritePattern;
+
+  LogicalResult matchAndRewrite(OpTy op,
+                                PatternRewriter &rewriter) const override {
+    VectorType oldResultType = op.getVectorType();
+    VectorType newResultType = trimLeadingOneDims(oldResultType);
+    if (newResultType == oldResultType)
+      return failure();
+    int64_t nDropped = oldResultType.getRank() - newResultType.getRank();
+
+    Location loc = op.getLoc();
+    SmallVector<Value> newOperands;
+    newOperands.reserve(op->getNumOperands());
+    for (Value operand : op->getOperands()) {
+      if (isa<VectorType>(operand.getType())) {
+        newOperands.push_back(
+            dropLeadingOneDimsFromOperand(rewriter, loc, operand, nDropped));
+      } else {
+        newOperands.push_back(operand);
+      }
+    }
+
+    Operation *newOp =
+        rewriter.create(loc, op->getName().getIdentifier(), newOperands,
+                        TypeRange{newResultType}, op->getAttrs());
+    rewriter.replaceOpWithNewOp<vector::BroadcastOp>(op, oldResultType,
+                                                     newOp->getResult(0));
----------------
dcaballe wrote:

We are generating a `vector.shape_cast` to remove the unit dimension and a `vector.broadcast` to bring it back. Could we consistently use `vector.shape_cast`?

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


More information about the Mlir-commits mailing list