[Mlir-commits] [mlir] [mlir][memref] Add ValueBoundsOpInterface external models for the memref operations extract_strided_metadata and assume_alignment (PR #206466)

Hagai Lev Hacohen llvmlistbot at llvm.org
Mon Jun 29 06:08:34 PDT 2026


https://github.com/HagaiLevHacohen updated https://github.com/llvm/llvm-project/pull/206466

>From ff19e73a96368887c0166aae9733bbfc1ca66dca Mon Sep 17 00:00:00 2001
From: Hagai Lev Hacohen <hagai4000 at gmail.com>
Date: Mon, 29 Jun 2026 14:14:26 +0300
Subject: [PATCH 1/5] Add valuebounds implementation for
 memref.extract_strided_metadata and memref.assume_alignment

---
 mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp  |  2 +-
 .../MemRef/IR/ValueBoundsOpInterfaceImpl.cpp  | 48 +++++++++++++++++++
 .../value-bounds-op-interface-impl.mlir       | 37 ++++++++++++++
 3 files changed, 86 insertions(+), 1 deletion(-)

diff --git a/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp b/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
index a1e3f10a871c1..6b8dcf60792b9 100644
--- a/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
+++ b/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
@@ -56,7 +56,7 @@ void mlir::memref::MemRefDialect::initialize() {
                             AtomicRMWOp, CastOp, CopyOp, DimOp, ExpandShapeOp,
                             GenericAtomicRMWOp, LoadOp, StoreOp, SubViewOp>();
   declarePromisedInterfaces<ValueBoundsOpInterface, AllocOp, AllocaOp, CastOp,
-                            DimOp, GetGlobalOp, RankOp, SubViewOp>();
+                            DimOp, GetGlobalOp, RankOp, SubViewOp, AssumeAlignmentOp, ExtractStridedMetadataOp>();
   declarePromisedInterface<DestructurableTypeInterface, MemRefType>();
 }
 
diff --git a/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp b/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
index 69afbcadb0b07..6ee50cda71aee 100644
--- a/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
@@ -142,6 +142,50 @@ struct SubViewOpInterface
   }
 };
 
+struct AssumeAlignmentOpInterface
+    : public ValueBoundsOpInterface::ExternalModel<AssumeAlignmentOpInterface,
+                                                   memref::AssumeAlignmentOp> {
+  void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
+                                       ValueBoundsConstraintSet &cstr) const {
+    auto assumeAlignmentOp = cast<memref::AssumeAlignmentOp>(op);
+    assert(value == assumeAlignmentOp.getResult() && "invalid value");
+
+    cstr.bound(value)[dim] ==
+        cstr.getExpr(assumeAlignmentOp.getViewSource(), dim);
+  }
+};
+
+struct ExtractStridedMetadataOpInterface
+    : public ValueBoundsOpInterface::ExternalModel<
+          ExtractStridedMetadataOpInterface, memref::ExtractStridedMetadataOp> {
+  void populateBoundsForIndexValue(Operation *op, Value value,
+                                   ValueBoundsConstraintSet &cstr) const {
+    auto metadataOp = cast<memref::ExtractStridedMetadataOp>(op);
+
+    if (value == metadataOp.getOffset()) {
+      cstr.bound(value) == metadataOp.getConstifiedMixedOffset();
+      return;
+    }
+
+    for (auto [idx, size] : llvm::enumerate(metadataOp.getSizes())) {
+      if (value != size)
+        continue;
+      cstr.bound(value) >= 0;
+      cstr.bound(value) == cstr.getExpr(metadataOp.getSource(), idx);
+      return;
+    }
+
+    SmallVector<OpFoldResult> strides = metadataOp.getConstifiedMixedStrides();
+    for (auto [idx, stride] : llvm::enumerate(metadataOp.getStrides())) {
+      if (value != stride)
+        continue;
+      cstr.bound(value) == strides[idx];
+      return;
+    }
+    llvm_unreachable("unexpected index value from extract_strided_metadata");
+  }
+};
+
 } // namespace
 } // namespace memref
 } // namespace mlir
@@ -162,5 +206,9 @@ void mlir::memref::registerValueBoundsOpInterfaceExternalModels(
     memref::GetGlobalOp::attachInterface<memref::GetGlobalOpInterface>(*ctx);
     memref::RankOp::attachInterface<memref::RankOpInterface>(*ctx);
     memref::SubViewOp::attachInterface<memref::SubViewOpInterface>(*ctx);
+    memref::AssumeAlignmentOp::attachInterface<memref::AssumeAlignmentOpInterface>(
+        *ctx);
+    memref::ExtractStridedMetadataOp::attachInterface<memref::ExtractStridedMetadataOpInterface>(
+        *ctx);
   });
 }
diff --git a/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir b/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir
index d0aec68d54988..7aa971916018f 100644
--- a/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir
+++ b/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir
@@ -127,3 +127,40 @@ func.func @memref_subview(%m: memref<?xf32>, %sz: index) -> index {
   %1 = "test.reify_bound"(%0) {dim = 0} : (memref<?xf32, strided<[1], offset: 2>>) -> (index)
   return %1 : index
 }
+
+// -----
+
+// CHECK-LABEL: func @memref_assume_alignment(
+//  CHECK-SAME:     %[[sz:.*]]: index
+//       CHECK:   %[[c6:.*]] = arith.constant 6 : index
+//       CHECK:   %[[c1:.*]] = arith.constant 1 : index
+//       CHECK:   %[[dim:.*]] = memref.dim %{{.*}}, %[[c1]] : memref<6x?xf32>
+//       CHECK:   return %[[c6]], %[[dim]]
+func.func @memref_assume_alignment(%sz: index) -> (index, index) {
+  %0 = memref.alloc(%sz) : memref<6x?xf32>
+  %1 = memref.assume_alignment %0, 16 : memref<6x?xf32>
+  %2 = "test.reify_bound"(%1) {dim = 0} : (memref<6x?xf32>) -> (index)
+  %3 = "test.reify_bound"(%1) {dim = 1} : (memref<6x?xf32>) -> (index)
+  return %2, %3 : index, index
+}
+
+// -----
+
+// CHECK-LABEL: func @memref_extract_strided_metadata(
+//  CHECK-SAME:     %[[sz:.*]]: index
+//       CHECK:   %[[c0:.*]] = arith.constant 0 : index
+//       CHECK:   %[[c10:.*]] = arith.constant 10 : index
+//       CHECK:   %[[c1:.*]] = arith.constant 1 : index
+//       CHECK:   %[[dim:.*]] = memref.dim %{{.*}}, %[[c1]] : memref<10x?xf32>
+//       CHECK:   %[[c1_0:.*]] = arith.constant 1 : index
+//       CHECK:   return %[[c0]], %[[c10]], %[[dim]], %[[c1_0]]
+func.func @memref_extract_strided_metadata(%sz: index) -> (index, index, index, index) {
+  %0 = memref.alloc(%sz) : memref<10x?xf32>
+  %base, %offset, %sizes:2, %strides:2 = memref.extract_strided_metadata %0
+    : memref<10x?xf32> -> memref<f32>, index, index, index, index, index
+  %1 = "test.reify_bound"(%offset) : (index) -> (index)
+  %2 = "test.reify_bound"(%sizes#0) : (index) -> (index)
+  %3 = "test.reify_bound"(%sizes#1) : (index) -> (index)
+  %4 = "test.reify_bound"(%strides#1) : (index) -> (index)
+  return %1, %2, %3, %4 : index, index, index, index
+}

>From 7ed9b02e0d70c38e802021a04402c05ff45247e0 Mon Sep 17 00:00:00 2001
From: Hagai Lev Hacohen <hagai4000 at gmail.com>
Date: Mon, 29 Jun 2026 14:14:56 +0300
Subject: [PATCH 2/5] clang format

---
 mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp              | 3 ++-
 mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp | 8 ++++----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp b/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
index 6b8dcf60792b9..5e07b1131b550 100644
--- a/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
+++ b/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
@@ -56,7 +56,8 @@ void mlir::memref::MemRefDialect::initialize() {
                             AtomicRMWOp, CastOp, CopyOp, DimOp, ExpandShapeOp,
                             GenericAtomicRMWOp, LoadOp, StoreOp, SubViewOp>();
   declarePromisedInterfaces<ValueBoundsOpInterface, AllocOp, AllocaOp, CastOp,
-                            DimOp, GetGlobalOp, RankOp, SubViewOp, AssumeAlignmentOp, ExtractStridedMetadataOp>();
+                            DimOp, GetGlobalOp, RankOp, SubViewOp,
+                            AssumeAlignmentOp, ExtractStridedMetadataOp>();
   declarePromisedInterface<DestructurableTypeInterface, MemRefType>();
 }
 
diff --git a/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp b/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
index 6ee50cda71aee..9c8074c377081 100644
--- a/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
@@ -206,9 +206,9 @@ void mlir::memref::registerValueBoundsOpInterfaceExternalModels(
     memref::GetGlobalOp::attachInterface<memref::GetGlobalOpInterface>(*ctx);
     memref::RankOp::attachInterface<memref::RankOpInterface>(*ctx);
     memref::SubViewOp::attachInterface<memref::SubViewOpInterface>(*ctx);
-    memref::AssumeAlignmentOp::attachInterface<memref::AssumeAlignmentOpInterface>(
-        *ctx);
-    memref::ExtractStridedMetadataOp::attachInterface<memref::ExtractStridedMetadataOpInterface>(
-        *ctx);
+    memref::AssumeAlignmentOp::attachInterface<
+        memref::AssumeAlignmentOpInterface>(*ctx);
+    memref::ExtractStridedMetadataOp::attachInterface<
+        memref::ExtractStridedMetadataOpInterface>(*ctx);
   });
 }

>From b13420ce234e69bb6856184106b34824d2142f56 Mon Sep 17 00:00:00 2001
From: Hagai Lev Hacohen <hagai4000 at gmail.com>
Date: Mon, 29 Jun 2026 14:50:49 +0300
Subject: [PATCH 3/5] rearrangement of placement of tests and functions

---
 mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp  |  5 +-
 .../MemRef/IR/ValueBoundsOpInterfaceImpl.cpp  | 88 +++++++++----------
 .../value-bounds-op-interface-impl.mlir       | 74 ++++++++--------
 3 files changed, 83 insertions(+), 84 deletions(-)

diff --git a/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp b/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
index 5e07b1131b550..69b25f97dcc31 100644
--- a/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
+++ b/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
@@ -55,9 +55,8 @@ void mlir::memref::MemRefDialect::initialize() {
   declarePromisedInterfaces<RuntimeVerifiableOpInterface, AssumeAlignmentOp,
                             AtomicRMWOp, CastOp, CopyOp, DimOp, ExpandShapeOp,
                             GenericAtomicRMWOp, LoadOp, StoreOp, SubViewOp>();
-  declarePromisedInterfaces<ValueBoundsOpInterface, AllocOp, AllocaOp, CastOp,
-                            DimOp, GetGlobalOp, RankOp, SubViewOp,
-                            AssumeAlignmentOp, ExtractStridedMetadataOp>();
+  declarePromisedInterfaces<ValueBoundsOpInterface, AllocOp, AllocaOp, AssumeAlignmentOp, CastOp,
+                            DimOp, ExtractStridedMetadataOp, GetGlobalOp, RankOp, SubViewOp>();
   declarePromisedInterface<DestructurableTypeInterface, MemRefType>();
 }
 
diff --git a/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp b/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
index 9c8074c377081..042c8920fadd8 100644
--- a/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
@@ -30,6 +30,19 @@ struct AllocOpInterface
   }
 };
 
+struct AssumeAlignmentOpInterface
+    : public ValueBoundsOpInterface::ExternalModel<AssumeAlignmentOpInterface,
+                                                   memref::AssumeAlignmentOp> {
+  void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
+                                       ValueBoundsConstraintSet &cstr) const {
+    auto assumeAlignmentOp = cast<memref::AssumeAlignmentOp>(op);
+    assert(value == assumeAlignmentOp.getResult() && "invalid value");
+
+    cstr.bound(value)[dim] ==
+        cstr.getExpr(assumeAlignmentOp.getViewSource(), dim);
+  }
+};
+
 struct CastOpInterface
     : public ValueBoundsOpInterface::ExternalModel<CastOpInterface, CastOp> {
   void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
@@ -70,6 +83,37 @@ struct ExpandShapeOpInterface
   }
 };
 
+struct ExtractStridedMetadataOpInterface
+    : public ValueBoundsOpInterface::ExternalModel<
+          ExtractStridedMetadataOpInterface, memref::ExtractStridedMetadataOp> {
+  void populateBoundsForIndexValue(Operation *op, Value value,
+                                   ValueBoundsConstraintSet &cstr) const {
+    auto metadataOp = cast<memref::ExtractStridedMetadataOp>(op);
+
+    if (value == metadataOp.getOffset()) {
+      cstr.bound(value) == metadataOp.getConstifiedMixedOffset();
+      return;
+    }
+
+    for (auto [idx, size] : llvm::enumerate(metadataOp.getSizes())) {
+      if (value != size)
+        continue;
+      cstr.bound(value) >= 0;
+      cstr.bound(value) == cstr.getExpr(metadataOp.getSource(), idx);
+      return;
+    }
+
+    SmallVector<OpFoldResult> strides = metadataOp.getConstifiedMixedStrides();
+    for (auto [idx, stride] : llvm::enumerate(metadataOp.getStrides())) {
+      if (value != stride)
+        continue;
+      cstr.bound(value) == strides[idx];
+      return;
+    }
+    llvm_unreachable("unexpected index value from extract_strided_metadata");
+  }
+};
+
 struct GetGlobalOpInterface
     : public ValueBoundsOpInterface::ExternalModel<GetGlobalOpInterface,
                                                    GetGlobalOp> {
@@ -142,50 +186,6 @@ struct SubViewOpInterface
   }
 };
 
-struct AssumeAlignmentOpInterface
-    : public ValueBoundsOpInterface::ExternalModel<AssumeAlignmentOpInterface,
-                                                   memref::AssumeAlignmentOp> {
-  void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
-                                       ValueBoundsConstraintSet &cstr) const {
-    auto assumeAlignmentOp = cast<memref::AssumeAlignmentOp>(op);
-    assert(value == assumeAlignmentOp.getResult() && "invalid value");
-
-    cstr.bound(value)[dim] ==
-        cstr.getExpr(assumeAlignmentOp.getViewSource(), dim);
-  }
-};
-
-struct ExtractStridedMetadataOpInterface
-    : public ValueBoundsOpInterface::ExternalModel<
-          ExtractStridedMetadataOpInterface, memref::ExtractStridedMetadataOp> {
-  void populateBoundsForIndexValue(Operation *op, Value value,
-                                   ValueBoundsConstraintSet &cstr) const {
-    auto metadataOp = cast<memref::ExtractStridedMetadataOp>(op);
-
-    if (value == metadataOp.getOffset()) {
-      cstr.bound(value) == metadataOp.getConstifiedMixedOffset();
-      return;
-    }
-
-    for (auto [idx, size] : llvm::enumerate(metadataOp.getSizes())) {
-      if (value != size)
-        continue;
-      cstr.bound(value) >= 0;
-      cstr.bound(value) == cstr.getExpr(metadataOp.getSource(), idx);
-      return;
-    }
-
-    SmallVector<OpFoldResult> strides = metadataOp.getConstifiedMixedStrides();
-    for (auto [idx, stride] : llvm::enumerate(metadataOp.getStrides())) {
-      if (value != stride)
-        continue;
-      cstr.bound(value) == strides[idx];
-      return;
-    }
-    llvm_unreachable("unexpected index value from extract_strided_metadata");
-  }
-};
-
 } // namespace
 } // namespace memref
 } // namespace mlir
diff --git a/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir b/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir
index 7aa971916018f..53a73a77b99c3 100644
--- a/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir
+++ b/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir
@@ -27,6 +27,22 @@ func.func @memref_alloca(%sz: index) -> (index, index) {
 
 // -----
 
+// CHECK-LABEL: func @memref_assume_alignment(
+//  CHECK-SAME:     %[[sz:.*]]: index
+//       CHECK:   %[[c6:.*]] = arith.constant 6 : index
+//       CHECK:   %[[c1:.*]] = arith.constant 1 : index
+//       CHECK:   %[[dim:.*]] = memref.dim %{{.*}}, %[[c1]] : memref<6x?xf32>
+//       CHECK:   return %[[c6]], %[[dim]]
+func.func @memref_assume_alignment(%sz: index) -> (index, index) {
+  %0 = memref.alloc(%sz) : memref<6x?xf32>
+  %1 = memref.assume_alignment %0, 16 : memref<6x?xf32>
+  %2 = "test.reify_bound"(%1) {dim = 0} : (memref<6x?xf32>) -> (index)
+  %3 = "test.reify_bound"(%1) {dim = 1} : (memref<6x?xf32>) -> (index)
+  return %2, %3 : index, index
+}
+
+// -----
+
 // CHECK-LABEL: func @memref_cast(
 //       CHECK:   %[[c10:.*]] = arith.constant 10 : index
 //       CHECK:   return %[[c10]]
@@ -77,6 +93,27 @@ func.func @memref_expand(%m: memref<?xf32>, %sz: index) -> (index, index) {
 
 // -----
 
+// CHECK-LABEL: func @memref_extract_strided_metadata(
+//  CHECK-SAME:     %[[sz:.*]]: index
+//       CHECK:   %[[c0:.*]] = arith.constant 0 : index
+//       CHECK:   %[[c10:.*]] = arith.constant 10 : index
+//       CHECK:   %[[c1:.*]] = arith.constant 1 : index
+//       CHECK:   %[[dim:.*]] = memref.dim %{{.*}}, %[[c1]] : memref<10x?xf32>
+//       CHECK:   %[[c1_0:.*]] = arith.constant 1 : index
+//       CHECK:   return %[[c0]], %[[c10]], %[[dim]], %[[c1_0]]
+func.func @memref_extract_strided_metadata(%sz: index) -> (index, index, index, index) {
+  %0 = memref.alloc(%sz) : memref<10x?xf32>
+  %base, %offset, %sizes:2, %strides:2 = memref.extract_strided_metadata %0
+    : memref<10x?xf32> -> memref<f32>, index, index, index, index, index
+  %1 = "test.reify_bound"(%offset) : (index) -> (index)
+  %2 = "test.reify_bound"(%sizes#0) : (index) -> (index)
+  %3 = "test.reify_bound"(%sizes#1) : (index) -> (index)
+  %4 = "test.reify_bound"(%strides#1) : (index) -> (index)
+  return %1, %2, %3, %4 : index, index, index, index
+}
+
+// -----
+
 //       CHECK: #[[$MAP:.+]] = affine_map<()[s0] -> (s0 * 2)>
 // CHECK-LABEL: func @memref_collapse(
 //  CHECK-SAME:     %[[sz0:.*]]: index
@@ -127,40 +164,3 @@ func.func @memref_subview(%m: memref<?xf32>, %sz: index) -> index {
   %1 = "test.reify_bound"(%0) {dim = 0} : (memref<?xf32, strided<[1], offset: 2>>) -> (index)
   return %1 : index
 }
-
-// -----
-
-// CHECK-LABEL: func @memref_assume_alignment(
-//  CHECK-SAME:     %[[sz:.*]]: index
-//       CHECK:   %[[c6:.*]] = arith.constant 6 : index
-//       CHECK:   %[[c1:.*]] = arith.constant 1 : index
-//       CHECK:   %[[dim:.*]] = memref.dim %{{.*}}, %[[c1]] : memref<6x?xf32>
-//       CHECK:   return %[[c6]], %[[dim]]
-func.func @memref_assume_alignment(%sz: index) -> (index, index) {
-  %0 = memref.alloc(%sz) : memref<6x?xf32>
-  %1 = memref.assume_alignment %0, 16 : memref<6x?xf32>
-  %2 = "test.reify_bound"(%1) {dim = 0} : (memref<6x?xf32>) -> (index)
-  %3 = "test.reify_bound"(%1) {dim = 1} : (memref<6x?xf32>) -> (index)
-  return %2, %3 : index, index
-}
-
-// -----
-
-// CHECK-LABEL: func @memref_extract_strided_metadata(
-//  CHECK-SAME:     %[[sz:.*]]: index
-//       CHECK:   %[[c0:.*]] = arith.constant 0 : index
-//       CHECK:   %[[c10:.*]] = arith.constant 10 : index
-//       CHECK:   %[[c1:.*]] = arith.constant 1 : index
-//       CHECK:   %[[dim:.*]] = memref.dim %{{.*}}, %[[c1]] : memref<10x?xf32>
-//       CHECK:   %[[c1_0:.*]] = arith.constant 1 : index
-//       CHECK:   return %[[c0]], %[[c10]], %[[dim]], %[[c1_0]]
-func.func @memref_extract_strided_metadata(%sz: index) -> (index, index, index, index) {
-  %0 = memref.alloc(%sz) : memref<10x?xf32>
-  %base, %offset, %sizes:2, %strides:2 = memref.extract_strided_metadata %0
-    : memref<10x?xf32> -> memref<f32>, index, index, index, index, index
-  %1 = "test.reify_bound"(%offset) : (index) -> (index)
-  %2 = "test.reify_bound"(%sizes#0) : (index) -> (index)
-  %3 = "test.reify_bound"(%sizes#1) : (index) -> (index)
-  %4 = "test.reify_bound"(%strides#1) : (index) -> (index)
-  return %1, %2, %3, %4 : index, index, index, index
-}

>From 3e63cab4bce2217a81b21562797db2d2aa6da382 Mon Sep 17 00:00:00 2001
From: Hagai Lev Hacohen <hagai4000 at gmail.com>
Date: Mon, 29 Jun 2026 14:51:16 +0300
Subject: [PATCH 4/5] clang format

---
 mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp b/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
index 69b25f97dcc31..8cecf5a4897e9 100644
--- a/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
+++ b/mlir/lib/Dialect/MemRef/IR/MemRefDialect.cpp
@@ -55,8 +55,9 @@ void mlir::memref::MemRefDialect::initialize() {
   declarePromisedInterfaces<RuntimeVerifiableOpInterface, AssumeAlignmentOp,
                             AtomicRMWOp, CastOp, CopyOp, DimOp, ExpandShapeOp,
                             GenericAtomicRMWOp, LoadOp, StoreOp, SubViewOp>();
-  declarePromisedInterfaces<ValueBoundsOpInterface, AllocOp, AllocaOp, AssumeAlignmentOp, CastOp,
-                            DimOp, ExtractStridedMetadataOp, GetGlobalOp, RankOp, SubViewOp>();
+  declarePromisedInterfaces<
+      ValueBoundsOpInterface, AllocOp, AllocaOp, AssumeAlignmentOp, CastOp,
+      DimOp, ExtractStridedMetadataOp, GetGlobalOp, RankOp, SubViewOp>();
   declarePromisedInterface<DestructurableTypeInterface, MemRefType>();
 }
 

>From 2facf25a33b1bd534650d7be87e2b21ed4af761e Mon Sep 17 00:00:00 2001
From: Hagai Lev Hacohen <hagai4000 at gmail.com>
Date: Mon, 29 Jun 2026 16:08:06 +0300
Subject: [PATCH 5/5] made changes according to review

---
 .../MemRef/IR/ValueBoundsOpInterfaceImpl.cpp  | 21 +++++++-----
 .../value-bounds-op-interface-impl.mlir       | 32 ++++++++++---------
 2 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp b/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
index 042c8920fadd8..aacdd8d9caa9f 100644
--- a/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
+++ b/mlir/lib/Dialect/MemRef/IR/ValueBoundsOpInterfaceImpl.cpp
@@ -89,24 +89,29 @@ struct ExtractStridedMetadataOpInterface
   void populateBoundsForIndexValue(Operation *op, Value value,
                                    ValueBoundsConstraintSet &cstr) const {
     auto metadataOp = cast<memref::ExtractStridedMetadataOp>(op);
+    auto result = llvm::cast<OpResult>(value);
+    assert(result.getOwner() == op && "invalid value");
+    int64_t resultNumber = result.getResultNumber();
 
-    if (value == metadataOp.getOffset()) {
+    if (resultNumber == 1) {
       cstr.bound(value) == metadataOp.getConstifiedMixedOffset();
       return;
     }
 
-    for (auto [idx, size] : llvm::enumerate(metadataOp.getSizes())) {
-      if (value != size)
-        continue;
+    int64_t sourceRank = metadataOp.getSource().getType().getRank();
+    int64_t sizeStart = 2;
+    int64_t strideStart = sizeStart + sourceRank;
+    if (resultNumber >= sizeStart && resultNumber < strideStart) {
+      int64_t idx = resultNumber - sizeStart;
       cstr.bound(value) >= 0;
       cstr.bound(value) == cstr.getExpr(metadataOp.getSource(), idx);
       return;
     }
 
-    SmallVector<OpFoldResult> strides = metadataOp.getConstifiedMixedStrides();
-    for (auto [idx, stride] : llvm::enumerate(metadataOp.getStrides())) {
-      if (value != stride)
-        continue;
+    int64_t strideEnd = strideStart + sourceRank;
+    if (resultNumber >= strideStart && resultNumber < strideEnd) {
+      int64_t idx = resultNumber - strideStart;
+      SmallVector<OpFoldResult> strides = metadataOp.getConstifiedMixedStrides();
       cstr.bound(value) == strides[idx];
       return;
     }
diff --git a/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir b/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir
index 53a73a77b99c3..32af830aa1ea7 100644
--- a/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir
+++ b/mlir/test/Dialect/MemRef/value-bounds-op-interface-impl.mlir
@@ -93,23 +93,25 @@ func.func @memref_expand(%m: memref<?xf32>, %sz: index) -> (index, index) {
 
 // -----
 
-// CHECK-LABEL: func @memref_extract_strided_metadata(
-//  CHECK-SAME:     %[[sz:.*]]: index
-//       CHECK:   %[[c0:.*]] = arith.constant 0 : index
-//       CHECK:   %[[c10:.*]] = arith.constant 10 : index
+// CHECK-LABEL: func @memref_extract_strided_metadata_static_metadata(
+//  CHECK-SAME:     %[[m:.*]]: memref<4x?xf32, strided<[11, 7], offset: 5>>
+//       CHECK:   %[[c5:.*]] = arith.constant 5 : index
+//       CHECK:   %[[c4:.*]] = arith.constant 4 : index
 //       CHECK:   %[[c1:.*]] = arith.constant 1 : index
-//       CHECK:   %[[dim:.*]] = memref.dim %{{.*}}, %[[c1]] : memref<10x?xf32>
-//       CHECK:   %[[c1_0:.*]] = arith.constant 1 : index
-//       CHECK:   return %[[c0]], %[[c10]], %[[dim]], %[[c1_0]]
-func.func @memref_extract_strided_metadata(%sz: index) -> (index, index, index, index) {
-  %0 = memref.alloc(%sz) : memref<10x?xf32>
-  %base, %offset, %sizes:2, %strides:2 = memref.extract_strided_metadata %0
-    : memref<10x?xf32> -> memref<f32>, index, index, index, index, index
-  %1 = "test.reify_bound"(%offset) : (index) -> (index)
-  %2 = "test.reify_bound"(%sizes#0) : (index) -> (index)
-  %3 = "test.reify_bound"(%sizes#1) : (index) -> (index)
+//       CHECK:   %[[dim:.*]] = memref.dim %[[m]], %[[c1]]
+//       CHECK:   %[[c11:.*]] = arith.constant 11 : index
+//       CHECK:   %[[c7:.*]] = arith.constant 7 : index
+//       CHECK:   return %[[c5]], %[[c4]], %[[dim]], %[[c11]], %[[c7]]
+func.func @memref_extract_strided_metadata_static_metadata(
+    %m: memref<4x?xf32, strided<[11, 7], offset: 5>>) -> (index, index, index, index, index) {
+  %base, %offset, %sizes:2, %strides:2 = memref.extract_strided_metadata %m
+    : memref<4x?xf32, strided<[11, 7], offset: 5>> -> memref<f32>, index, index, index, index, index
+  %0 = "test.reify_bound"(%offset) : (index) -> (index)
+  %1 = "test.reify_bound"(%sizes#0) : (index) -> (index)
+  %2 = "test.reify_bound"(%sizes#1) : (index) -> (index)
+  %3 = "test.reify_bound"(%strides#0) : (index) -> (index)
   %4 = "test.reify_bound"(%strides#1) : (index) -> (index)
-  return %1, %2, %3, %4 : index, index, index, index
+  return %0, %1, %2, %3, %4 : index, index, index, index, index
 }
 
 // -----



More information about the Mlir-commits mailing list