[Mlir-commits] [mlir] [mlir][ValueBounds] Skip analysis for identical slice components (PR #226894)

Ziliang Zhang llvmlistbot at llvm.org
Sun Sep 27 23:07:20 PDT 2026


https://github.com/ziliangzl updated https://github.com/llvm/llvm-project/pull/226894

>From 4df93794112769d12db071e5ed00c31d2e56b60b Mon Sep 17 00:00:00 2001
From: Ziliang Zhang <zzl.coding at gmail.com>
Date: Mon, 28 Sep 2026 13:46:30 +0800
Subject: [PATCH 1/2] [mlir][ValueBounds] Skip analysis for identical slice
 components

One-Shot Bufferize repeatedly compares subset slices whose offsets, sizes, and strides often reuse the same SSA values and attributes. Avoid constructing a ValueBounds constraint set when the two OpFoldResults are already identical, while preserving the existing solver fallback for distinct values.
---
 .../lib/Interfaces/ValueBoundsOpInterface.cpp |  8 +++
 mlir/unittests/Interfaces/CMakeLists.txt      |  2 +
 .../Interfaces/ValueBoundsOpInterfaceTest.cpp | 61 +++++++++++++++++++
 3 files changed, 71 insertions(+)
 create mode 100644 mlir/unittests/Interfaces/ValueBoundsOpInterfaceTest.cpp

diff --git a/mlir/lib/Interfaces/ValueBoundsOpInterface.cpp b/mlir/lib/Interfaces/ValueBoundsOpInterface.cpp
index d6d3b4d43cb55..0d22b1d39c14e 100644
--- a/mlir/lib/Interfaces/ValueBoundsOpInterface.cpp
+++ b/mlir/lib/Interfaces/ValueBoundsOpInterface.cpp
@@ -955,6 +955,10 @@ FailureOr<bool> ValueBoundsConstraintSet::areEquivalentSlices(
   // "failure".
   for (auto [offset1, offset2] :
        llvm::zip_equal(slice1.getMixedOffsets(), slice2.getMixedOffsets())) {
+    // Avoid constructing a constraint set for values/attributes that are
+    // already known to be identical.
+    if (offset1 == offset2)
+      continue;
     FailureOr<bool> equal = areEqual(offset1, offset2);
     if (failed(equal))
       return failure();
@@ -963,6 +967,8 @@ FailureOr<bool> ValueBoundsConstraintSet::areEquivalentSlices(
   }
   for (auto [size1, size2] :
        llvm::zip_equal(slice1.getMixedSizes(), slice2.getMixedSizes())) {
+    if (size1 == size2)
+      continue;
     FailureOr<bool> equal = areEqual(size1, size2);
     if (failed(equal))
       return failure();
@@ -971,6 +977,8 @@ FailureOr<bool> ValueBoundsConstraintSet::areEquivalentSlices(
   }
   for (auto [stride1, stride2] :
        llvm::zip_equal(slice1.getMixedStrides(), slice2.getMixedStrides())) {
+    if (stride1 == stride2)
+      continue;
     FailureOr<bool> equal = areEqual(stride1, stride2);
     if (failed(equal))
       return failure();
diff --git a/mlir/unittests/Interfaces/CMakeLists.txt b/mlir/unittests/Interfaces/CMakeLists.txt
index 193edda6bf8d8..5cb2948c814cd 100644
--- a/mlir/unittests/Interfaces/CMakeLists.txt
+++ b/mlir/unittests/Interfaces/CMakeLists.txt
@@ -5,6 +5,7 @@ add_mlir_unittest(MLIRInterfacesTests
   MemorySlotUtilsTest.cpp
   SideEffectInterfacesTest.cpp
   InferTypeOpInterfaceTest.cpp
+  ValueBoundsOpInterfaceTest.cpp
 
   DEPENDS
   MLIRTestInterfaceIncGen
@@ -23,5 +24,6 @@ mlir_target_link_libraries(MLIRInterfacesTests
   MLIRMemorySlotUtils
   MLIRParser
   MLIRSideEffectInterfaces
+  MLIRValueBoundsOpInterface
 )
 target_link_libraries(MLIRInterfacesTests PRIVATE MLIRTestDialect)
diff --git a/mlir/unittests/Interfaces/ValueBoundsOpInterfaceTest.cpp b/mlir/unittests/Interfaces/ValueBoundsOpInterfaceTest.cpp
new file mode 100644
index 0000000000000..1a7de44ecc7da
--- /dev/null
+++ b/mlir/unittests/Interfaces/ValueBoundsOpInterfaceTest.cpp
@@ -0,0 +1,61 @@
+//===- ValueBoundsOpInterfaceTest.cpp - ValueBounds unit tests -----------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Interfaces/ValueBoundsOpInterface.h"
+
+#include <gtest/gtest.h>
+
+using namespace mlir;
+
+namespace {
+
+TEST(ValueBoundsOpInterfaceTest, EquivalentSlices) {
+  MLIRContext context;
+  context.loadDialect<func::FuncDialect>();
+  OpBuilder builder(&context);
+
+  auto function = func::FuncOp::create(
+      builder.getUnknownLoc(), "test",
+      builder.getFunctionType({builder.getIndexType(), builder.getIndexType()},
+                              {}));
+  Block *entryBlock = function.addEntryBlock();
+  Value dynamicValue = entryBlock->getArgument(0);
+  Value otherDynamicValue = entryBlock->getArgument(1);
+
+  OpFoldResult zero = builder.getIndexAttr(0);
+  OpFoldResult one = builder.getIndexAttr(1);
+  OpFoldResult four = builder.getIndexAttr(4);
+  OpFoldResult five = builder.getIndexAttr(5);
+
+  HyperrectangularSlice slice({zero, dynamicValue}, {four, dynamicValue},
+                              {one, one});
+  HyperrectangularSlice identicalSlice({zero, dynamicValue},
+                                       {four, dynamicValue}, {one, one});
+  FailureOr<bool> equivalent = ValueBoundsConstraintSet::areEquivalentSlices(
+      &context, slice, identicalSlice);
+  ASSERT_TRUE(succeeded(equivalent));
+  EXPECT_TRUE(*equivalent);
+
+  // Identical components must not hide a later non-equivalent component.
+  HyperrectangularSlice differentSlice({zero, dynamicValue},
+                                       {five, dynamicValue}, {one, one});
+  equivalent = ValueBoundsConstraintSet::areEquivalentSlices(
+      &context, slice, differentSlice);
+  ASSERT_TRUE(succeeded(equivalent));
+  EXPECT_FALSE(*equivalent);
+
+  // Distinct dynamic values continue to use the ValueBounds fallback.
+  HyperrectangularSlice unknownSlice({zero, otherDynamicValue},
+                                     {four, dynamicValue}, {one, one});
+  equivalent = ValueBoundsConstraintSet::areEquivalentSlices(
+      &context, slice, unknownSlice);
+  EXPECT_TRUE(failed(equivalent));
+}
+
+} // namespace

>From c3b2807b58c14cbfe8f0d2e92cb7b591314b0019 Mon Sep 17 00:00:00 2001
From: Ziliang Zhang <zzl.coding at gmail.com>
Date: Mon, 28 Sep 2026 14:07:02 +0800
Subject: [PATCH 2/2] [mlir][ValueBounds] Fix unit test formatting

---
 .../Interfaces/ValueBoundsOpInterfaceTest.cpp          | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/mlir/unittests/Interfaces/ValueBoundsOpInterfaceTest.cpp b/mlir/unittests/Interfaces/ValueBoundsOpInterfaceTest.cpp
index 1a7de44ecc7da..1571ab924bf6f 100644
--- a/mlir/unittests/Interfaces/ValueBoundsOpInterfaceTest.cpp
+++ b/mlir/unittests/Interfaces/ValueBoundsOpInterfaceTest.cpp
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/Interfaces/ValueBoundsOpInterface.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
 
 #include <gtest/gtest.h>
 
@@ -45,16 +45,16 @@ TEST(ValueBoundsOpInterfaceTest, EquivalentSlices) {
   // Identical components must not hide a later non-equivalent component.
   HyperrectangularSlice differentSlice({zero, dynamicValue},
                                        {five, dynamicValue}, {one, one});
-  equivalent = ValueBoundsConstraintSet::areEquivalentSlices(
-      &context, slice, differentSlice);
+  equivalent = ValueBoundsConstraintSet::areEquivalentSlices(&context, slice,
+                                                             differentSlice);
   ASSERT_TRUE(succeeded(equivalent));
   EXPECT_FALSE(*equivalent);
 
   // Distinct dynamic values continue to use the ValueBounds fallback.
   HyperrectangularSlice unknownSlice({zero, otherDynamicValue},
                                      {four, dynamicValue}, {one, one});
-  equivalent = ValueBoundsConstraintSet::areEquivalentSlices(
-      &context, slice, unknownSlice);
+  equivalent = ValueBoundsConstraintSet::areEquivalentSlices(&context, slice,
+                                                             unknownSlice);
   EXPECT_TRUE(failed(equivalent));
 }
 



More information about the Mlir-commits mailing list