[Mlir-commits] [mlir] [mlir][affine] Improve memref test-memref-dependence-check print format (PR #208656)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Jul 10 01:29:47 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-affine

Author: lonely eagle (linuxlonelyeagle)

<details>
<summary>Changes</summary>

The patch improve `memref test-memref-dependence-check` print format, add print dependence type and shorten distance vectors from.

---
Full diff: https://github.com/llvm/llvm-project/pull/208656.diff


2 Files Affected:

- (modified) mlir/test/Dialect/Affine/memref-dependence-check.mlir (+25-25) 
- (modified) mlir/test/lib/Analysis/TestMemRefDependenceCheck.cpp (+36-7) 


``````````diff
diff --git a/mlir/test/Dialect/Affine/memref-dependence-check.mlir b/mlir/test/Dialect/Affine/memref-dependence-check.mlir
index 0a96d1ac65e0a..f4b2b16249f0d 100644
--- a/mlir/test/Dialect/Affine/memref-dependence-check.mlir
+++ b/mlir/test/Dialect/Affine/memref-dependence-check.mlir
@@ -257,13 +257,13 @@ func.func @store_load_func_symbol(%arg0: index, %arg1: index) {
   affine.for %i0 = 0 to %arg1 {
     %a0 = affine.apply affine_map<(d0) -> (d0)> (%arg0)
     affine.store %c7, %m[%a0] : memref<100xf32>
-    // expected-remark at above {{dependence from 0 to 0 at depth 1 = [1, +inf]}}
+    // expected-remark at above {{dependence from 0 to 0 at depth 1 = ([1, +inf])}}
     // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
-    // expected-remark at above {{dependence from 0 to 1 at depth 1 = [1, +inf]}}
+    // expected-remark at above {{dependence from 0 to 1 at depth 1 = ([1, +inf])}}
     // expected-remark at above {{dependence from 0 to 1 at depth 2 = true}}
     %a1 = affine.apply affine_map<(d0) -> (d0)> (%arg0)
     %v0 = affine.load %m[%a1] : memref<100xf32>
-    // expected-remark at above {{dependence from 1 to 0 at depth 1 = [1, +inf]}}
+    // expected-remark at above {{dependence from 1 to 0 at depth 1 = ([1, +inf])}}
     // expected-remark at above {{dependence from 1 to 0 at depth 2 = false}}
     // expected-remark at above {{dependence from 1 to 1 at depth 1 = false}}
     // expected-remark at above {{dependence from 1 to 1 at depth 2 = false}}
@@ -291,7 +291,7 @@ func.func @store_range_load_last_in_range() {
     // For dependence from 1 to 0, we have write-after-read (WAR) dependences
     // for all loads in the loop to the store on the last iteration.
     %v0 = affine.load %m[%a1] : memref<100xf32>
-    // expected-remark at above {{dependence from 1 to 0 at depth 1 = [1, 9]}}
+    // expected-remark at above {{dependence from 1 to 0 at depth 1 = ([1, 9])}}
     // expected-remark at above {{dependence from 1 to 0 at depth 2 = false}}
     // expected-remark at above {{dependence from 1 to 1 at depth 1 = false}}
     // expected-remark at above {{dependence from 1 to 1 at depth 2 = false}}
@@ -336,7 +336,7 @@ func.func @store_range_load_first_in_range() {
     affine.store %c7, %m[%a0] : memref<100xf32>
     // expected-remark at above {{dependence from 0 to 0 at depth 1 = false}}
     // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
-    // expected-remark at above {{dependence from 0 to 1 at depth 1 = [1, 9]}}
+    // expected-remark at above {{dependence from 0 to 1 at depth 1 = ([1, 9])}}
     // expected-remark at above {{dependence from 0 to 1 at depth 2 = true}}
     %a1 = affine.apply affine_map<(d0) -> (d0 + 1)> (%c0)
     %v0 = affine.load %m[%a1] : memref<100xf32>
@@ -358,7 +358,7 @@ func.func @store_plus_3() {
     affine.store %c7, %m[%a0] : memref<100xf32>
     // expected-remark at above {{dependence from 0 to 0 at depth 1 = false}}
     // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
-    // expected-remark at above {{dependence from 0 to 1 at depth 1 = [3, 3]}}
+    // expected-remark at above {{dependence from 0 to 1 at depth 1 = (3)}}
     // expected-remark at above {{dependence from 0 to 1 at depth 2 = false}}
     %a1 = affine.apply affine_map<(d0) -> (d0)> (%i0)
     %v0 = affine.load %m[%a1] : memref<100xf32>
@@ -380,7 +380,7 @@ func.func @load_minus_2() {
     affine.store %c7, %m[%a0] : memref<100xf32>
     // expected-remark at above {{dependence from 0 to 0 at depth 1 = false}}
     // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
-    // expected-remark at above {{dependence from 0 to 1 at depth 1 = [2, 2]}}
+    // expected-remark at above {{dependence from 0 to 1 at depth 1 = (2)}}
     // expected-remark at above {{dependence from 0 to 1 at depth 2 = false}}
     %a1 = affine.apply affine_map<(d0) -> (d0 - 2)> (%i0)
     %v0 = affine.load %m[%a1] : memref<100xf32>
@@ -437,7 +437,7 @@ func.func @perfectly_nested_loops_loop_carried_at_depth1() {
       // expected-remark at above {{dependence from 0 to 0 at depth 1 = false}}
       // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
       // expected-remark at above {{dependence from 0 to 0 at depth 3 = false}}
-      // expected-remark at above {{dependence from 0 to 1 at depth 1 = [2, 2][0, 0]}}
+      // expected-remark at above {{dependence from 0 to 1 at depth 1 = (2, 0)}}
       // expected-remark at above {{dependence from 0 to 1 at depth 2 = false}}
       // expected-remark at above {{dependence from 0 to 1 at depth 3 = false}}
       %a10 = affine.apply affine_map<(d0, d1) -> (d0 - 2)> (%i0, %i1)
@@ -469,7 +469,7 @@ func.func @perfectly_nested_loops_loop_carried_at_depth2() {
       // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
       // expected-remark at above {{dependence from 0 to 0 at depth 3 = false}}
       // expected-remark at above {{dependence from 0 to 1 at depth 1 = false}}
-      // expected-remark at above {{dependence from 0 to 1 at depth 2 = [0, 0][3, 3]}}
+      // expected-remark at above {{dependence from 0 to 1 at depth 2 = (0, 3)}}
       // expected-remark at above {{dependence from 0 to 1 at depth 3 = false}}
       %a10 = affine.apply affine_map<(d0, d1) -> (d0)> (%i0, %i1)
       %a11 = affine.apply affine_map<(d0, d1) -> (d1 - 3)> (%i0, %i1)
@@ -558,7 +558,7 @@ func.func @dependence_cycle() {
     // expected-remark at above {{dependence from 2 to 3 at depth 2 = false}}
     %a3 = affine.apply affine_map<(d0) -> (d0 + 1)> (%i0)
     affine.store %v1, %m.a[%a3] : memref<100xf32>
-    // expected-remark at above {{dependence from 3 to 0 at depth 1 = [1, 1]}}
+    // expected-remark at above {{dependence from 3 to 0 at depth 1 = (1)}}
     // expected-remark at above {{dependence from 3 to 0 at depth 2 = false}}
     // expected-remark at above {{dependence from 3 to 1 at depth 1 = false}}
     // expected-remark at above {{dependence from 3 to 1 at depth 2 = false}}
@@ -589,7 +589,7 @@ func.func @negative_and_positive_direction_vectors(%arg0: index, %arg1: index) {
       %a10 = affine.apply affine_map<(d0, d1) -> (d0)> (%i0, %i1)
       %a11 = affine.apply affine_map<(d0, d1) -> (d1)> (%i0, %i1)
       affine.store %c7, %m[%a10, %a11] : memref<10x10xf32>
-      // expected-remark at above {{dependence from 1 to 0 at depth 1 = [1, 1][-1, -1]}}
+      // expected-remark at above {{dependence from 1 to 0 at depth 1 = (1, -1)}}
       // expected-remark at above {{dependence from 1 to 0 at depth 2 = false}}
       // expected-remark at above {{dependence from 1 to 0 at depth 3 = false}}
       // expected-remark at above {{dependence from 1 to 1 at depth 1 = false}}
@@ -612,15 +612,15 @@ func.func @war_raw_waw_deps() {
       // expected-remark at above {{dependence from 0 to 0 at depth 1 = false}}
       // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
       // expected-remark at above {{dependence from 0 to 0 at depth 3 = false}}
-      // expected-remark at above {{dependence from 0 to 1 at depth 1 = [1, 9][1, 1]}}
-      // expected-remark at above {{dependence from 0 to 1 at depth 2 = [0, 0][1, 1]}}
+      // expected-remark at above {{dependence from 0 to 1 at depth 1 = ([1, 9], 1)}}
+      // expected-remark at above {{dependence from 0 to 1 at depth 2 = (0, 1)}}
       // expected-remark at above {{dependence from 0 to 1 at depth 3 = false}}
       %a1 = affine.apply affine_map<(d0) -> (d0)> (%i1)
       affine.store %c7, %m[%a1] : memref<100xf32>
-      // expected-remark at above {{dependence from 1 to 0 at depth 1 = [1, 9][-1, -1]}}
+      // expected-remark at above {{dependence from 1 to 0 at depth 1 = ([1, 9], -1)}}
       // expected-remark at above {{dependence from 1 to 0 at depth 2 = false}}
       // expected-remark at above {{dependence from 1 to 0 at depth 3 = false}}
-      // expected-remark at above {{dependence from 1 to 1 at depth 1 = [1, 9][0, 0]}}
+      // expected-remark at above {{dependence from 1 to 1 at depth 1 = ([1, 9], 0)}}
       // expected-remark at above {{dependence from 1 to 1 at depth 2 = false}}
       // expected-remark at above {{dependence from 1 to 1 at depth 3 = false}}
     }
@@ -640,13 +640,13 @@ func.func @mod_deps() {
     %v0 = affine.load %m[%a0] : memref<100xf32>
     // expected-remark at above {{dependence from 0 to 0 at depth 1 = false}}
     // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
-    // expected-remark at above {{dependence from 0 to 1 at depth 1 = [1, 9]}}
+    // expected-remark at above {{dependence from 0 to 1 at depth 1 = ([1, 9])}}
     // expected-remark at above {{dependence from 0 to 1 at depth 2 = false}}
     %a1 = affine.apply affine_map<(d0) -> ( (d0 + 1) mod 2)> (%i0)
     affine.store %c7, %m[%a1] : memref<100xf32>
-    // expected-remark at above {{dependence from 1 to 0 at depth 1 = [1, 9]}}
+    // expected-remark at above {{dependence from 1 to 0 at depth 1 = ([1, 9])}}
     // expected-remark at above {{dependence from 1 to 0 at depth 2 = false}}
-    // expected-remark at above {{dependence from 1 to 1 at depth 1 = [2, 9]}}
+    // expected-remark at above {{dependence from 1 to 1 at depth 1 = ([2, 9])}}
     // expected-remark at above {{dependence from 1 to 1 at depth 2 = false}}
   }
   return
@@ -700,9 +700,9 @@ func.func @mod_div_3d() {
         %idx1 = affine.apply affine_map<(d0, d1, d2) -> (d1 mod 2)> (%i0, %i1, %i2)
         %idx2 = affine.apply affine_map<(d0, d1, d2) -> (d2 floordiv 4)> (%i0, %i1, %i2)
         affine.store %c0, %M[%idx0, %idx1, %idx2] : memref<2 x 2 x 2 x i32>
-        // expected-remark at above {{dependence from 0 to 0 at depth 1 = [1, 3][-7, 7][-3, 3]}}
-        // expected-remark at above {{dependence from 0 to 0 at depth 2 = [0, 0][2, 7][-3, 3]}}
-        // expected-remark at above {{dependence from 0 to 0 at depth 3 = [0, 0][0, 0][1, 3]}}
+        // expected-remark at above {{dependence from 0 to 0 at depth 1 = ([1, 3], [-7, 7], [-3, 3])}}
+        // expected-remark at above {{dependence from 0 to 0 at depth 2 = (0, [2, 7], [-3, 3])}}
+        // expected-remark at above {{dependence from 0 to 0 at depth 3 = (0, 0, [1, 3])}}
         // expected-remark at above {{dependence from 0 to 0 at depth 4 = false}}
       }
     }
@@ -840,7 +840,7 @@ func.func @strided_loop_with_loop_carried_dependence_at_depth1() {
     affine.store %cf0, %0[%a0] : memref<10xf32>
     // expected-remark at above {{dependence from 0 to 0 at depth 1 = false}}
     // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
-    // expected-remark at above {{dependence from 0 to 1 at depth 1 = [4, 4]}}
+    // expected-remark at above {{dependence from 0 to 1 at depth 1 = (4)}}
     // expected-remark at above {{dependence from 0 to 1 at depth 2 = false}}
     %v0 = affine.load %0[%i0] : memref<10xf32>
     // expected-remark at above {{dependence from 1 to 0 at depth 1 = false}}
@@ -868,7 +868,7 @@ func.func @test_dep_store_depth1_load_depth2() {
     // expected-remark at above {{dependence from 0 to 1 at depth 2 = false}}
     affine.for %i1 = affine_map<(d0) -> (d0)>(%i0) to affine_map<(d0) -> (d0 + 1)>(%i0) {
       %1 = affine.load %0[%i1] : memref<100xf32>
-      // expected-remark at above {{dependence from 1 to 0 at depth 1 = [1, 1]}}
+      // expected-remark at above {{dependence from 1 to 0 at depth 1 = (1)}}
       // expected-remark at above {{dependence from 1 to 0 at depth 2 = false}}
       // expected-remark at above {{dependence from 1 to 1 at depth 1 = false}}
       // expected-remark at above {{dependence from 1 to 1 at depth 2 = false}}
@@ -892,7 +892,7 @@ func.func @test_dep_store_depth2_load_depth1() {
       // expected-remark at above {{dependence from 0 to 0 at depth 1 = false}}
       // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
       // expected-remark at above {{dependence from 0 to 0 at depth 3 = false}}
-      // expected-remark at above {{dependence from 0 to 1 at depth 1 = [2, 2]}}
+      // expected-remark at above {{dependence from 0 to 1 at depth 1 = (2)}}
       // expected-remark at above {{dependence from 0 to 1 at depth 2 = false}}
     }
     %a0 = affine.apply affine_map<(d0) -> (d0 - 2)>(%i0)
@@ -1160,7 +1160,7 @@ func.func @affine_parallel_min_max_bounds(%arg0: memref<4090x2040xf32>, %arg1: f
       affine.store %arg1, %arg0[%arg2 + 3968, %arg3] : memref<4090x2040xf32>
       // expected-remark at above {{dependence from 0 to 0 at depth 1 = false}}
       // expected-remark at above {{dependence from 0 to 0 at depth 2 = false}}
-      // expected-remark at above {{dependence from 0 to 0 at depth 3 = [0, 0][0, 0][1, 99]}}
+      // expected-remark at above {{dependence from 0 to 0 at depth 3 = (0, 0, [1, 99])}}
       // expected-remark at above {{dependence from 0 to 0 at depth 4 = false}}
     }
   }
diff --git a/mlir/test/lib/Analysis/TestMemRefDependenceCheck.cpp b/mlir/test/lib/Analysis/TestMemRefDependenceCheck.cpp
index b3b9a590773b0..91b7f8a4c1d53 100644
--- a/mlir/test/lib/Analysis/TestMemRefDependenceCheck.cpp
+++ b/mlir/test/lib/Analysis/TestMemRefDependenceCheck.cpp
@@ -51,7 +51,9 @@ getDirectionVectorStr(bool ret, unsigned numCommonLoops, unsigned loopNestDepth,
   if (dependenceComponents.empty() || loopNestDepth > numCommonLoops)
     return "true";
   std::string result;
-  for (const auto &dependenceComponent : dependenceComponents) {
+  result += "(";
+  for (size_t i = 0, e = dependenceComponents.size(); i < e; ++i) {
+    const auto &dependenceComponent = dependenceComponents[i];
     std::string lbStr = "-inf";
     if (dependenceComponent.lb.has_value() &&
         *dependenceComponent.lb != std::numeric_limits<int64_t>::min())
@@ -62,11 +64,40 @@ getDirectionVectorStr(bool ret, unsigned numCommonLoops, unsigned loopNestDepth,
         *dependenceComponent.ub != std::numeric_limits<int64_t>::max())
       ubStr = std::to_string(*dependenceComponent.ub);
 
-    result += "[" + lbStr + ", " + ubStr + "]";
+    if (lbStr == ubStr)
+      result += lbStr;
+    else
+      result += "[" + lbStr + ", " + ubStr + "]";
+
+    if (i < e - 1)
+      result += ", ";
   }
+  result += ")";
   return result;
 }
 
+static std::string getDependenceType(Operation *srcOp, Operation *dstOp) {
+  std::string depandenceRelation;
+
+  auto getAccessTypeLabel = [](Operation *op) {
+    std::string str;
+    if (isa<AffineLoadOp>(op))
+      str += "R";
+    if (isa<AffineStoreOp>(op))
+      str += "W";
+    return str;
+  };
+
+  // A dependence is a pair of statement instances that expresses that the
+  // second statement instance should be executed after the first instance.
+  depandenceRelation += getAccessTypeLabel(dstOp);
+  depandenceRelation += "A";
+  depandenceRelation += getAccessTypeLabel(srcOp);
+  assert(depandenceRelation.size() == 3 &&
+         "srcOp/desOp must be AffineLoadOp/AffineStoreOp");
+  return depandenceRelation;
+}
+
 // For each access in 'loadsAndStores', runs a dependence check between this
 // "source" access and all subsequent "destination" accesses in
 // 'loadsAndStores'. Emits the result of the dependence check as a note with
@@ -90,11 +121,9 @@ static void checkDependences(ArrayRef<Operation *> loadsAndStores) {
           srcOpInst->emitError("dependence check failed");
         } else {
           bool ret = hasDependence(result);
-          // TODO: Print dependence type (i.e. RAW, etc) and print
-          // distance vectors as: ([2, 3], [0, 10]). Also, shorten distance
-          // vectors from ([1, 1], [3, 3]) to (1, 3).
-          srcOpInst->emitRemark("dependence from ")
-              << i << " to " << j << " at depth " << d << " = "
+          srcOpInst->emitRemark(getDependenceType(srcOpInst, dstOpInst))
+              << " dependence from " << i << " to " << j << " at depth " << d
+              << " = "
               << getDirectionVectorStr(ret, numCommonLoops, d,
                                        dependenceComponents);
         }

``````````

</details>


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


More information about the Mlir-commits mailing list