[Mlir-commits] [mlir] [mlir][vector] Implement IndexedAccessOpInterface for load, store, etc. (PR #196216)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed May 6 18:49:15 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir

Author: Krzysztof Drewniak (krzysz00)

<details>
<summary>Changes</summary>

This commit adds simple (not trying to account for unit dimensions that could be cast away) implementations of IndexedAccessOpInterface to low-level vector operations like vector.load and vector.store, eliminating the need for the old-style code in FoldMemRefAliasOps.cpp. After this commit, it'll be possible to migrate all the other memref-rewriting passes (ExpandAddressComputation and FlattenMemRefs) to use the interface, taking a bunch of dialect dependencies off of memref/transforms.

Assisted-By: GPT 5.5 (pulled in old code, wrote some new tests)

---

Patch is 33.83 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/196216.diff


9 Files Affected:

- (modified) mlir/include/mlir/Dialect/MemRef/IR/MemoryAccessOpInterfaces.td (+5-1) 
- (modified) mlir/include/mlir/Dialect/Vector/IR/VectorOps.td (+6) 
- (added) mlir/include/mlir/Dialect/Vector/Transforms/IndexedAccessOpInterfaceImpl.h (+21) 
- (modified) mlir/lib/Dialect/MemRef/Transforms/FoldMemRefAliasOps.cpp (+13-318) 
- (modified) mlir/lib/Dialect/Vector/IR/VectorOps.cpp (+4) 
- (modified) mlir/lib/Dialect/Vector/Transforms/CMakeLists.txt (+1) 
- (added) mlir/lib/Dialect/Vector/Transforms/IndexedAccessOpInterfaceImpl.cpp (+101) 
- (modified) mlir/lib/RegisterAllDialects.cpp (+2) 
- (modified) mlir/test/Dialect/MemRef/fold-memref-alias-ops.mlir (+124) 


``````````diff
diff --git a/mlir/include/mlir/Dialect/MemRef/IR/MemoryAccessOpInterfaces.td b/mlir/include/mlir/Dialect/MemRef/IR/MemoryAccessOpInterfaces.td
index 7fc69b4fabca6..0f1ef521afc57 100644
--- a/mlir/include/mlir/Dialect/MemRef/IR/MemoryAccessOpInterfaces.td
+++ b/mlir/include/mlir/Dialect/MemRef/IR/MemoryAccessOpInterfaces.td
@@ -53,7 +53,11 @@ def IndexedAccessOpInterface : OpInterface<"IndexedAccessOpInterface"> {
     InterfaceMethod<
       /*desc=*/[{
         Return the shape of the portion of the memref that is being accessed by
-        this operation, if known, ignoring leading unit dimensions.
+        this operation, if known. This shape describes the access dimensions
+        whose strides are semantically important for this operation.
+        Implementations shall omit dimensions whose strides do not affect the
+        operation semantics. (In particular, if an operation will access one
+        element of the base memref, this method should return `{}`.)
 
         Reindexing transformations may not modify the *strides* of the trailing
         N dimensions, where N is the size returned value, and should ensure that
diff --git a/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td b/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
index 8f4fa5ca6a844..28a8109cb59c0 100644
--- a/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
+++ b/mlir/include/mlir/Dialect/Vector/IR/VectorOps.td
@@ -1658,6 +1658,7 @@ def Vector_TransferWriteOp :
   let hasVerifier = 1;
 }
 
+// Promises IndexedAccessOpInterface.
 def Vector_LoadOp : Vector_Op<"load", [
     DeclareOpInterfaceMethods<VectorUnrollOpInterface, ["getShapeForUnroll"]>,
     DeclareOpInterfaceMethods<MemorySpaceCastConsumerOpInterface>,
@@ -1776,6 +1777,7 @@ def Vector_LoadOp : Vector_Op<"load", [
       "$base `[` $indices `]` attr-dict `:` type($base) `,` type($result)";
 }
 
+// Promises IndexedAccessOpInterface.
 def Vector_StoreOp : Vector_Op<"store", [
     DeclareOpInterfaceMethods<VectorUnrollOpInterface, ["getShapeForUnroll"]>,
     DeclareOpInterfaceMethods<MemorySpaceCastConsumerOpInterface>,
@@ -1883,6 +1885,7 @@ def Vector_StoreOp : Vector_Op<"store", [
                        "`:` type($base) `,` type($valueToStore)";
 }
 
+// Promises IndexedAccessOpInterface.
 def Vector_MaskedLoadOp :
   Vector_Op<"maskedload", [
       DeclareOpInterfaceMethods<MemorySpaceCastConsumerOpInterface>,
@@ -1978,6 +1981,7 @@ def Vector_MaskedLoadOp :
   ];
 }
 
+// Promises IndexedAccessOpInterface.
 def Vector_MaskedStoreOp :
   Vector_Op<"maskedstore", [
       DeclareOpInterfaceMethods<MemorySpaceCastConsumerOpInterface>,
@@ -2251,6 +2255,7 @@ def Vector_ScatterOp
     }]>];
 }
 
+// Promises IndexedAccessOpInterface.
 def Vector_ExpandLoadOp :
   Vector_Op<"expandload", [
       DeclareOpInterfaceMethods<MemorySpaceCastConsumerOpInterface>,
@@ -2342,6 +2347,7 @@ def Vector_ExpandLoadOp :
   ];
 }
 
+// Promises IndexedAccessOpInterface.
 def Vector_CompressStoreOp :
   Vector_Op<"compressstore", [
       DeclareOpInterfaceMethods<MemorySpaceCastConsumerOpInterface>,
diff --git a/mlir/include/mlir/Dialect/Vector/Transforms/IndexedAccessOpInterfaceImpl.h b/mlir/include/mlir/Dialect/Vector/Transforms/IndexedAccessOpInterfaceImpl.h
new file mode 100644
index 0000000000000..57fe661ad81f0
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Vector/Transforms/IndexedAccessOpInterfaceImpl.h
@@ -0,0 +1,21 @@
+//===- IndexedAccessOpInterfaceImpl.h ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_VECTOR_TRANSFORMS_INDEXEDACCESSOPINTERFACEIMPL_H
+#define MLIR_DIALECT_VECTOR_TRANSFORMS_INDEXEDACCESSOPINTERFACEIMPL_H
+
+namespace mlir {
+
+class DialectRegistry;
+
+namespace vector {
+void registerIndexedAccessOpInterfaceExternalModels(DialectRegistry &registry);
+} // namespace vector
+} // namespace mlir
+
+#endif // MLIR_DIALECT_VECTOR_TRANSFORMS_INDEXEDACCESSOPINTERFACEIMPL_H
diff --git a/mlir/lib/Dialect/MemRef/Transforms/FoldMemRefAliasOps.cpp b/mlir/lib/Dialect/MemRef/Transforms/FoldMemRefAliasOps.cpp
index e36ddfa063e11..de7662753d142 100644
--- a/mlir/lib/Dialect/MemRef/Transforms/FoldMemRefAliasOps.cpp
+++ b/mlir/lib/Dialect/MemRef/Transforms/FoldMemRefAliasOps.cpp
@@ -25,7 +25,6 @@
 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallBitVector.h"
-#include "llvm/ADT/TypeSwitch.h"
 #include "llvm/Support/Debug.h"
 #include <cstdint>
 
@@ -52,6 +51,8 @@ hasTrivialReassociationSuffix(ArrayRef<ReassociationIndices> reassocs,
                               int64_t n) {
   if (n <= 0)
     return true;
+  if (n > static_cast<int64_t>(reassocs.size()))
+    return false;
   return llvm::all_of(
       reassocs.take_back(n),
       [&](const ReassociationIndices &indices) { return indices.size() == 1; });
@@ -60,89 +61,17 @@ hasTrivialReassociationSuffix(ArrayRef<ReassociationIndices> reassocs,
 static bool hasTrailingUnitStrides(memref::SubViewOp subview, int64_t n) {
   if (n <= 0)
     return true;
-  return llvm::all_of(subview.getStaticStrides().take_back(n),
-                      [](int64_t s) { return s == 1; });
+  ArrayRef<int64_t> strides = subview.getStaticStrides();
+  if (n > static_cast<int64_t>(strides.size()))
+    return false;
+  return llvm::all_of(strides.take_back(n), [](int64_t s) { return s == 1; });
 }
 
-/// Helpers to access the memref operand for each op.
-template <typename LoadOrStoreOpTy>
-static Value getMemRefOperand(LoadOrStoreOpTy op) {
-  return op.getMemref();
-}
-
-static Value getMemRefOperand(vector::LoadOp op) { return op.getBase(); }
-
-static Value getMemRefOperand(vector::StoreOp op) { return op.getBase(); }
-
-static Value getMemRefOperand(vector::MaskedLoadOp op) { return op.getBase(); }
-
-static Value getMemRefOperand(vector::MaskedStoreOp op) { return op.getBase(); }
-
 //===----------------------------------------------------------------------===//
 // Patterns
 //===----------------------------------------------------------------------===//
 
 namespace {
-/// Merges subview operation with load/transferRead operation.
-template <typename OpTy>
-class LoadOpOfSubViewOpFolder final : public OpRewritePattern<OpTy> {
-public:
-  using OpRewritePattern<OpTy>::OpRewritePattern;
-
-  LogicalResult matchAndRewrite(OpTy loadOp,
-                                PatternRewriter &rewriter) const override;
-};
-
-/// Merges expand_shape operation with load/transferRead operation.
-template <typename OpTy>
-class LoadOpOfExpandShapeOpFolder final : public OpRewritePattern<OpTy> {
-public:
-  using OpRewritePattern<OpTy>::OpRewritePattern;
-
-  LogicalResult matchAndRewrite(OpTy loadOp,
-                                PatternRewriter &rewriter) const override;
-};
-
-/// Merges collapse_shape operation with load/transferRead operation.
-template <typename OpTy>
-class LoadOpOfCollapseShapeOpFolder final : public OpRewritePattern<OpTy> {
-public:
-  using OpRewritePattern<OpTy>::OpRewritePattern;
-
-  LogicalResult matchAndRewrite(OpTy loadOp,
-                                PatternRewriter &rewriter) const override;
-};
-
-/// Merges subview operation with store/transferWriteOp operation.
-template <typename OpTy>
-class StoreOpOfSubViewOpFolder final : public OpRewritePattern<OpTy> {
-public:
-  using OpRewritePattern<OpTy>::OpRewritePattern;
-
-  LogicalResult matchAndRewrite(OpTy storeOp,
-                                PatternRewriter &rewriter) const override;
-};
-
-/// Merges expand_shape operation with store/transferWriteOp operation.
-template <typename OpTy>
-class StoreOpOfExpandShapeOpFolder final : public OpRewritePattern<OpTy> {
-public:
-  using OpRewritePattern<OpTy>::OpRewritePattern;
-
-  LogicalResult matchAndRewrite(OpTy storeOp,
-                                PatternRewriter &rewriter) const override;
-};
-
-/// Merges collapse_shape operation with store/transferWriteOp operation.
-template <typename OpTy>
-class StoreOpOfCollapseShapeOpFolder final : public OpRewritePattern<OpTy> {
-public:
-  using OpRewritePattern<OpTy>::OpRewritePattern;
-
-  LogicalResult matchAndRewrite(OpTy storeOp,
-                                PatternRewriter &rewriter) const override;
-};
-
 /// Folds subview(subview(x)) to a single subview(x).
 class SubViewOfSubViewFolder : public OpRewritePattern<memref::SubViewOp> {
 public:
@@ -286,226 +215,6 @@ struct TransferOpOfCollapseShapeOpFolder final
 };
 } // namespace
 
-static LogicalResult preconditionsFoldSubViewOp(RewriterBase &rewriter,
-                                                Operation *op,
-                                                memref::SubViewOp subviewOp) {
-  return success();
-}
-
-template <typename OpTy>
-LogicalResult LoadOpOfSubViewOpFolder<OpTy>::matchAndRewrite(
-    OpTy loadOp, PatternRewriter &rewriter) const {
-  auto subViewOp =
-      getMemRefOperand(loadOp).template getDefiningOp<memref::SubViewOp>();
-
-  if (!subViewOp)
-    return rewriter.notifyMatchFailure(loadOp, "not a subview producer");
-
-  LogicalResult preconditionResult =
-      preconditionsFoldSubViewOp(rewriter, loadOp, subViewOp);
-  if (failed(preconditionResult))
-    return preconditionResult;
-
-  SmallVector<Value> sourceIndices;
-  affine::resolveIndicesIntoOpWithOffsetsAndStrides(
-      rewriter, loadOp.getLoc(), subViewOp.getMixedOffsets(),
-      subViewOp.getMixedStrides(), subViewOp.getDroppedDims(),
-      loadOp.getIndices(), sourceIndices);
-
-  llvm::TypeSwitch<Operation *, void>(loadOp)
-      .Case([&](memref::LoadOp op) {
-        rewriter.replaceOpWithNewOp<memref::LoadOp>(
-            loadOp, subViewOp.getSource(), sourceIndices, op.getNontemporal());
-      })
-      .Case([&](vector::LoadOp op) {
-        rewriter.replaceOpWithNewOp<vector::LoadOp>(
-            op, op.getType(), subViewOp.getSource(), sourceIndices);
-      })
-      .Case([&](vector::MaskedLoadOp op) {
-        rewriter.replaceOpWithNewOp<vector::MaskedLoadOp>(
-            op, op.getType(), subViewOp.getSource(), sourceIndices,
-            op.getMask(), op.getPassThru());
-      })
-      .DefaultUnreachable("unexpected operation");
-  return success();
-}
-
-template <typename OpTy>
-LogicalResult LoadOpOfExpandShapeOpFolder<OpTy>::matchAndRewrite(
-    OpTy loadOp, PatternRewriter &rewriter) const {
-  auto expandShapeOp =
-      getMemRefOperand(loadOp).template getDefiningOp<memref::ExpandShapeOp>();
-
-  if (!expandShapeOp)
-    return failure();
-
-  SmallVector<Value> sourceIndices;
-  // memref.load guarantees that indexes start inbounds while the vector
-  // operations don't. This impacts if our linearization is `disjoint`
-  resolveSourceIndicesExpandShape(loadOp.getLoc(), rewriter, expandShapeOp,
-                                  loadOp.getIndices(), sourceIndices,
-                                  isa<memref::LoadOp>(loadOp.getOperation()));
-
-  return llvm::TypeSwitch<Operation *, LogicalResult>(loadOp)
-      .Case([&](memref::LoadOp op) {
-        rewriter.replaceOpWithNewOp<memref::LoadOp>(
-            loadOp, expandShapeOp.getViewSource(), sourceIndices,
-            op.getNontemporal());
-        return success();
-      })
-      .Case([&](vector::LoadOp op) {
-        rewriter.replaceOpWithNewOp<vector::LoadOp>(
-            op, op.getType(), expandShapeOp.getViewSource(), sourceIndices,
-            op.getNontemporal());
-        return success();
-      })
-      .Case([&](vector::MaskedLoadOp op) {
-        rewriter.replaceOpWithNewOp<vector::MaskedLoadOp>(
-            op, op.getType(), expandShapeOp.getViewSource(), sourceIndices,
-            op.getMask(), op.getPassThru());
-        return success();
-      })
-      .DefaultUnreachable("unexpected operation");
-}
-
-template <typename OpTy>
-LogicalResult LoadOpOfCollapseShapeOpFolder<OpTy>::matchAndRewrite(
-    OpTy loadOp, PatternRewriter &rewriter) const {
-  auto collapseShapeOp = getMemRefOperand(loadOp)
-                             .template getDefiningOp<memref::CollapseShapeOp>();
-
-  if (!collapseShapeOp)
-    return failure();
-
-  SmallVector<Value> sourceIndices;
-  resolveSourceIndicesCollapseShape(loadOp.getLoc(), rewriter, collapseShapeOp,
-                                    loadOp.getIndices(), sourceIndices);
-  llvm::TypeSwitch<Operation *, void>(loadOp)
-      .Case([&](memref::LoadOp op) {
-        rewriter.replaceOpWithNewOp<memref::LoadOp>(
-            loadOp, collapseShapeOp.getViewSource(), sourceIndices,
-            op.getNontemporal());
-      })
-      .Case([&](vector::LoadOp op) {
-        rewriter.replaceOpWithNewOp<vector::LoadOp>(
-            op, op.getType(), collapseShapeOp.getViewSource(), sourceIndices,
-            op.getNontemporal());
-      })
-      .Case([&](vector::MaskedLoadOp op) {
-        rewriter.replaceOpWithNewOp<vector::MaskedLoadOp>(
-            op, op.getType(), collapseShapeOp.getViewSource(), sourceIndices,
-            op.getMask(), op.getPassThru());
-      })
-      .DefaultUnreachable("unexpected operation");
-  return success();
-}
-
-template <typename OpTy>
-LogicalResult StoreOpOfSubViewOpFolder<OpTy>::matchAndRewrite(
-    OpTy storeOp, PatternRewriter &rewriter) const {
-  auto subViewOp =
-      getMemRefOperand(storeOp).template getDefiningOp<memref::SubViewOp>();
-
-  if (!subViewOp)
-    return rewriter.notifyMatchFailure(storeOp, "not a subview producer");
-
-  LogicalResult preconditionResult =
-      preconditionsFoldSubViewOp(rewriter, storeOp, subViewOp);
-  if (failed(preconditionResult))
-    return preconditionResult;
-
-  SmallVector<Value> sourceIndices;
-  affine::resolveIndicesIntoOpWithOffsetsAndStrides(
-      rewriter, storeOp.getLoc(), subViewOp.getMixedOffsets(),
-      subViewOp.getMixedStrides(), subViewOp.getDroppedDims(),
-      storeOp.getIndices(), sourceIndices);
-
-  llvm::TypeSwitch<Operation *, void>(storeOp)
-      .Case([&](memref::StoreOp op) {
-        rewriter.replaceOpWithNewOp<memref::StoreOp>(
-            op, op.getValue(), subViewOp.getSource(), sourceIndices,
-            op.getNontemporal());
-      })
-      .Case([&](vector::StoreOp op) {
-        rewriter.replaceOpWithNewOp<vector::StoreOp>(
-            op, op.getValueToStore(), subViewOp.getSource(), sourceIndices);
-      })
-      .Case([&](vector::MaskedStoreOp op) {
-        rewriter.replaceOpWithNewOp<vector::MaskedStoreOp>(
-            op, subViewOp.getSource(), sourceIndices, op.getMask(),
-            op.getValueToStore());
-      })
-      .DefaultUnreachable("unexpected operation");
-  return success();
-}
-
-template <typename OpTy>
-LogicalResult StoreOpOfExpandShapeOpFolder<OpTy>::matchAndRewrite(
-    OpTy storeOp, PatternRewriter &rewriter) const {
-  auto expandShapeOp =
-      getMemRefOperand(storeOp).template getDefiningOp<memref::ExpandShapeOp>();
-
-  if (!expandShapeOp)
-    return failure();
-
-  SmallVector<Value> sourceIndices;
-  // memref.store guarantees that indexes start inbounds while the vector
-  // operations don't. This impacts if our linearization is `disjoint`
-  resolveSourceIndicesExpandShape(storeOp.getLoc(), rewriter, expandShapeOp,
-                                  storeOp.getIndices(), sourceIndices,
-                                  isa<memref::StoreOp>(storeOp.getOperation()));
-  llvm::TypeSwitch<Operation *, void>(storeOp)
-      .Case([&](memref::StoreOp op) {
-        rewriter.replaceOpWithNewOp<memref::StoreOp>(
-            storeOp, op.getValueToStore(), expandShapeOp.getViewSource(),
-            sourceIndices, op.getNontemporal());
-      })
-      .Case([&](vector::StoreOp op) {
-        rewriter.replaceOpWithNewOp<vector::StoreOp>(
-            op, op.getValueToStore(), expandShapeOp.getViewSource(),
-            sourceIndices, op.getNontemporal());
-      })
-      .Case([&](vector::MaskedStoreOp op) {
-        rewriter.replaceOpWithNewOp<vector::MaskedStoreOp>(
-            op, expandShapeOp.getViewSource(), sourceIndices, op.getMask(),
-            op.getValueToStore());
-      })
-      .DefaultUnreachable("unexpected operation");
-  return success();
-}
-
-template <typename OpTy>
-LogicalResult StoreOpOfCollapseShapeOpFolder<OpTy>::matchAndRewrite(
-    OpTy storeOp, PatternRewriter &rewriter) const {
-  auto collapseShapeOp = getMemRefOperand(storeOp)
-                             .template getDefiningOp<memref::CollapseShapeOp>();
-
-  if (!collapseShapeOp)
-    return failure();
-
-  SmallVector<Value> sourceIndices;
-  resolveSourceIndicesCollapseShape(storeOp.getLoc(), rewriter, collapseShapeOp,
-                                    storeOp.getIndices(), sourceIndices);
-  llvm::TypeSwitch<Operation *, void>(storeOp)
-      .Case([&](memref::StoreOp op) {
-        rewriter.replaceOpWithNewOp<memref::StoreOp>(
-            storeOp, op.getValueToStore(), collapseShapeOp.getViewSource(),
-            sourceIndices, op.getNontemporal());
-      })
-      .Case([&](vector::StoreOp op) {
-        rewriter.replaceOpWithNewOp<vector::StoreOp>(
-            op, op.getValueToStore(), collapseShapeOp.getViewSource(),
-            sourceIndices, op.getNontemporal());
-      })
-      .Case([&](vector::MaskedStoreOp op) {
-        rewriter.replaceOpWithNewOp<vector::MaskedStoreOp>(
-            op, collapseShapeOp.getViewSource(), sourceIndices, op.getMask(),
-            op.getValueToStore());
-      })
-      .DefaultUnreachable("unexpected operation");
-  return success();
-}
-
 LogicalResult
 AccessOpOfSubViewOpFolder::matchAndRewrite(memref::IndexedAccessOpInterface op,
                                            PatternRewriter &rewriter) const {
@@ -849,27 +558,13 @@ LogicalResult TransferOpOfCollapseShapeOpFolder::matchAndRewrite(
 }
 
 void memref::populateFoldMemRefAliasOpPatterns(RewritePatternSet &patterns) {
-  patterns.add<
-      // Interface-based patterns to which we will be migrating.
-      AccessOpOfSubViewOpFolder, AccessOpOfExpandShapeOpFolder,
-      AccessOpOfCollapseShapeOpFolder, IndexedMemCopyOpOfSubViewOpFolder,
-      IndexedMemCopyOpOfExpandShapeOpFolder,
-      IndexedMemCopyOpOfCollapseShapeOpFolder, TransferOpOfSubViewOpFolder,
-      TransferOpOfExpandShapeOpFolder, TransferOpOfCollapseShapeOpFolder,
-      // The old way of doing things. Don't add more of these.
-      LoadOpOfSubViewOpFolder<vector::LoadOp>,
-      LoadOpOfSubViewOpFolder<vector::MaskedLoadOp>,
-      StoreOpOfSubViewOpFolder<vector::StoreOp>,
-      StoreOpOfSubViewOpFolder<vector::MaskedStoreOp>,
-      LoadOpOfExpandShapeOpFolder<vector::LoadOp>,
-      LoadOpOfExpandShapeOpFolder<vector::MaskedLoadOp>,
-      StoreOpOfExpandShapeOpFolder<vector::StoreOp>,
-      StoreOpOfExpandShapeOpFolder<vector::MaskedStoreOp>,
-      LoadOpOfCollapseShapeOpFolder<vector::LoadOp>,
-      LoadOpOfCollapseShapeOpFolder<vector::MaskedLoadOp>,
-      StoreOpOfCollapseShapeOpFolder<vector::StoreOp>,
-      StoreOpOfCollapseShapeOpFolder<vector::MaskedStoreOp>,
-      SubViewOfSubViewFolder>(patterns.getContext());
+  patterns
+      .add<AccessOpOfSubViewOpFolder, AccessOpOfExpandShapeOpFolder,
+           AccessOpOfCollapseShapeOpFolder, IndexedMemCopyOpOfSubViewOpFolder,
+           IndexedMemCopyOpOfExpandShapeOpFolder,
+           IndexedMemCopyOpOfCollapseShapeOpFolder, TransferOpOfSubViewOpFolder,
+           TransferOpOfExpandShapeOpFolder, TransferOpOfCollapseShapeOpFolder,
+           SubViewOfSubViewFolder>(patterns.getContext());
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
index 780b0cbb36120..51be1e4431e70 100644
--- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
@@ -19,6 +19,7 @@
 #include "mlir/Dialect/Arith/Utils/Utils.h"
 #include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/MemRef/IR/MemoryAccessOpInterfaces.h"
 #include "mlir/Dialect/Tensor/IR/Tensor.h"
 #include "mlir/Dialect/UB/IR/UBMatchers.h"
 #include "mlir/Dialect/Utils/IndexingUtils.h"
@@ -483,6 +484,9 @@ void VectorDialect::initialize() {
 
   addInterfaces<Vector...
[truncated]

``````````

</details>


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


More information about the Mlir-commits mailing list