[Mlir-commits] [mlir] [MLIR][Affine] Guard maximal slice mismatch (PR #206236)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Sat Jun 27 02:54:37 PDT 2026


https://github.com/mygitljf created https://github.com/llvm/llvm-project/pull/206236

I added a conservative guard for affine loop fusion when maximal slice analysis reaches constraints with incompatible Presburger spaces. In that case the pass now treats maximality as unknown instead of continuing into the path that asserts.
Added a regression with a dynamic producer bound to cover the crash path while keeping the expected fusion behavior for the independent constant-bound producer.
Fixes #206081

>From 8b77ac4434a02441cee2cba118fb96c8e55ddfca Mon Sep 17 00:00:00 2001
From: mygitljf <2410316423 at qq.com>
Date: Sat, 27 Jun 2026 17:54:12 +0000
Subject: [PATCH] [MLIR][Affine] Guard maximal slice mismatch

---
 mlir/lib/Dialect/Affine/Analysis/Utils.cpp  |  3 +++
 mlir/test/Dialect/Affine/loop-fusion-4.mlir | 22 +++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/mlir/lib/Dialect/Affine/Analysis/Utils.cpp b/mlir/lib/Dialect/Affine/Analysis/Utils.cpp
index cac305df8ba75..1a0dfa95e205d 100644
--- a/mlir/lib/Dialect/Affine/Analysis/Utils.cpp
+++ b/mlir/lib/Dialect/Affine/Analysis/Utils.cpp
@@ -1142,6 +1142,9 @@ std::optional<bool> ComputationSliceState::isMaximal() const {
     // computed so we don't know if the slice is maximal.
     return std::nullopt;
 
+  if (!srcConstraints.getSpace().isCompatible(sliceConstraints.getSpace()))
+    return std::nullopt;
+
   // Compute the difference between the src loop nest and the slice integer
   // sets.
   PresburgerSet srcSet(srcConstraints);
diff --git a/mlir/test/Dialect/Affine/loop-fusion-4.mlir b/mlir/test/Dialect/Affine/loop-fusion-4.mlir
index cf530016c201a..9ce1cdb203ae0 100644
--- a/mlir/test/Dialect/Affine/loop-fusion-4.mlir
+++ b/mlir/test/Dialect/Affine/loop-fusion-4.mlir
@@ -831,6 +831,28 @@ func.func @fusion_non_constant_bounds_1(%N: index, %M: memref<?xf32>, %cst: f32)
   return
 }
 
+// PRODUCER-CONSUMER-MAXIMAL-LABEL: func @maximal_fusion_dynamic_source_bound
+func.func @maximal_fusion_dynamic_source_bound(%N: index, %M: memref<100xf64>) {
+  %cst = arith.constant 0.000000e+00 : f64
+  affine.for %i = 0 to 10 {
+    affine.store %cst, %M[%i] : memref<100xf64>
+  }
+  affine.for %i = 0 to %N {
+    affine.store %cst, %M[%i] : memref<100xf64>
+  }
+  affine.for %i = 0 to 10 {
+    affine.load %M[%i] : memref<100xf64>
+  }
+  return
+}
+// PRODUCER-CONSUMER-MAXIMAL:      affine.for %{{.*}} = 0 to %{{.*}} {
+// PRODUCER-CONSUMER-MAXIMAL-NEXT:   affine.store
+// PRODUCER-CONSUMER-MAXIMAL-NEXT: }
+// PRODUCER-CONSUMER-MAXIMAL:      affine.for %{{.*}} = 0 to 10 {
+// PRODUCER-CONSUMER-MAXIMAL-NEXT:   affine.store
+// PRODUCER-CONSUMER-MAXIMAL-NEXT:   affine.load
+// PRODUCER-CONSUMER-MAXIMAL-NEXT: }
+
 // No fusion here as the cost models computing slice costs run out of 64-bit precision.
 
 // PRODUCER-CONSUMER-LABEL: func @high_trip_count



More information about the Mlir-commits mailing list