[Mlir-commits] [mlir] [mlir][dataflow] Add new visitNonControlFlowArgumentst API to SparseDataFlowAnalysis and apply it in LivenessAnalysis/RemoveDeadValues/IntegerRangeAnalysis (PR #169816)

lonely eagle llvmlistbot at llvm.org
Wed Dec 31 21:37:47 PST 2025


https://github.com/linuxlonelyeagle updated https://github.com/llvm/llvm-project/pull/169816

>From 0d92e8db2519fcdf97517d0df395f509e26ee266 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Thu, 27 Nov 2025 13:56:51 +0000
Subject: [PATCH 01/15] add visitBranchRegionArgument interface to sparse
 backward dataflow analysis and apply it to LivenessAnalysis.

---
 .../mlir/Analysis/DataFlow/LivenessAnalysis.h |  2 ++
 .../mlir/Analysis/DataFlow/SparseAnalysis.h   |  2 ++
 .../Analysis/DataFlow/LivenessAnalysis.cpp    | 20 +++++++++++++++++++
 mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 14 ++++++++++++-
 .../XeGPU/Transforms/XeGPUPropagateLayout.cpp |  2 ++
 .../TestSparseBackwardDataFlowAnalysis.cpp    |  2 ++
 6 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
index cf1fd6e2d48ca..80d63ad5715ac 100644
--- a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
@@ -87,6 +87,8 @@ class LivenessAnalysis : public SparseBackwardDataFlowAnalysis<Liveness> {
   void visitCallOperand(OpOperand &operand) override;
 
   void setToExitState(Liveness *lattice) override;
+
+  void visitBranchRegionArgument(BlockArgument &argument) override;
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
index 360d3c7e62000..097da72fb6bb3 100644
--- a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
@@ -431,6 +431,8 @@ class AbstractSparseBackwardDataFlowAnalysis : public DataFlowAnalysis {
   // Visit operands on branch instructions that are not forwarded.
   virtual void visitBranchOperand(OpOperand &operand) = 0;
 
+  virtual void visitBranchRegionArgument(BlockArgument &argument) = 0;
+
   // Visit operands on call instructions that are not forwarded.
   virtual void visitCallOperand(OpOperand &operand) = 0;
 
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index 20be50c8e8a5b..69c945e83c141 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -303,6 +303,26 @@ void LivenessAnalysis::visitCallOperand(OpOperand &operand) {
   propagateIfChanged(operandLiveness, operandLiveness->markLive());
 }
 
+void LivenessAnalysis::visitBranchRegionArgument(BlockArgument &blockArgument) {
+  Operation *parentOp = blockArgument.getOwner()->getParentOp();
+  LDBG() << "Visiting branch region argument: " << blockArgument
+         << "in op: " << OpWithFlags(parentOp, OpPrintingFlags().skipRegions());
+  Liveness *argumentLiveness = getLatticeElement(blockArgument);
+  SmallVector<Liveness *> parentResultsLiveness;
+  for (Value result : parentOp->getResults())
+    parentResultsLiveness.push_back(getLatticeElement(result));
+
+  for (Liveness *resultLattice : parentResultsLiveness) {
+    if (resultLattice->isLive) {
+      LDBG() << "Marking branch argument live: " << blockArgument;
+      propagateIfChanged(argumentLiveness, argumentLiveness->markLive());
+      return;
+    }
+  }
+  (void)visitOperation(parentOp, ArrayRef<Liveness *>{argumentLiveness},
+                       parentResultsLiveness);
+}
+
 void LivenessAnalysis::setToExitState(Liveness *lattice) {
   LDBG() << "setToExitState for lattice: " << lattice;
   if (lattice->isLive) {
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index 8e63ae86753b4..d442135363392 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -599,7 +599,7 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
   // All operands not forwarded to any successor. This set can be non-contiguous
   // in the presence of multiple successors.
   BitVector unaccounted(op->getNumOperands(), true);
-
+  SmallVector<BlockArgument> regionArguments;
   for (RegionSuccessor &successor : successors) {
     OperandRange operands = branch.getEntrySuccessorOperands(successor);
     MutableArrayRef<OpOperand> opoperands = operandsToOpOperands(operands);
@@ -609,12 +609,24 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
            *getLatticeElementFor(getProgramPointAfter(op), input));
       unaccounted.reset(operand.getOperandNumber());
     }
+
+    if (successor.isParent())
+      continue;
+    auto arguments = successor.getSuccessor()->getArguments();
+    for (BlockArgument argument : arguments) {
+      if (llvm::find(inputs, argument) == inputs.end()) {
+        regionArguments.push_back(argument);
+      }
+    }
   }
   // All operands not forwarded to regions are typically parameters of the
   // branch operation itself (for example the boolean for if/else).
   for (int index : unaccounted.set_bits()) {
     visitBranchOperand(op->getOpOperand(index));
   }
+  for (BlockArgument argument : regionArguments) {
+    visitBranchRegionArgument(argument);
+  }
 }
 
 void AbstractSparseBackwardDataFlowAnalysis::
diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
index 7fc75e7294ea3..a27abb569a38b 100644
--- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
+++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
@@ -449,6 +449,8 @@ class LayoutInfoPropagation
 
   void visitCallOperand(OpOperand &operand) override {};
 
+  void visitBranchRegionArgument(BlockArgument &argument) override {};
+
   void visitExternalCall(CallOpInterface call,
                          ArrayRef<LayoutInfoLattice *> operands,
                          ArrayRef<const LayoutInfoLattice *> results) override {
diff --git a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
index 0bdb7c25c3b5f..c7c2e68e9d95d 100644
--- a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
+++ b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
@@ -82,6 +82,8 @@ class WrittenToAnalysis : public SparseBackwardDataFlowAnalysis<WrittenTo> {
 
   void visitCallOperand(OpOperand &operand) override;
 
+  void visitBranchRegionArgument(BlockArgument &argument) override {}
+
   void visitExternalCall(CallOpInterface call, ArrayRef<WrittenTo *> operands,
                          ArrayRef<const WrittenTo *> results) override;
 

>From d48c19bfc4170bc65b9624d3d52ce87e9162451b Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Thu, 27 Nov 2025 14:28:51 +0000
Subject: [PATCH 02/15] rebase main and add test.

---
 .../Analysis/DataFlow/LivenessAnalysis.cpp    | 32 -------------------
 mlir/test/Transforms/remove-dead-values.mlir  | 17 ++++++++++
 2 files changed, 17 insertions(+), 32 deletions(-)

diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index 69c945e83c141..70ee411b03c99 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -137,7 +137,6 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
   // Populating such blocks in `blocks`.
   bool mayLive = false;
   SmallVector<Block *, 4> blocks;
-  SmallVector<BlockArgument> argumentNotOperand;
   if (auto regionBranchOp = dyn_cast<RegionBranchOpInterface>(op)) {
     if (op->getNumResults() != 0) {
       // This mark value of type 1.c liveness as may live, because the region
@@ -166,25 +165,6 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
           blocks.push_back(&block);
       }
     }
-
-    // In the block of the successor block argument of RegionBranchOpInterface,
-    // there may be arguments of RegionBranchOpInterface, such as the IV of
-    // scf.forOp. Explicitly set this argument to live.
-    for (Region &region : op->getRegions()) {
-      SmallVector<RegionSuccessor> successors;
-      regionBranchOp.getSuccessorRegions(region, successors);
-      for (RegionSuccessor successor : successors) {
-        if (successor.isParent())
-          continue;
-        auto arguments = successor.getSuccessor()->getArguments();
-        ValueRange regionInputs = successor.getSuccessorInputs();
-        for (auto argument : arguments) {
-          if (llvm::find(regionInputs, argument) == regionInputs.end()) {
-            argumentNotOperand.push_back(argument);
-          }
-        }
-      }
-    }
   } else if (isa<BranchOpInterface>(op)) {
     // We cannot track all successor blocks of the branch operation(More
     // specifically, it's the successor's successor). Additionally, different
@@ -244,24 +224,12 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
     Liveness *operandLiveness = getLatticeElement(operand.get());
     LDBG() << "Marking branch operand live: " << operand.get();
     propagateIfChanged(operandLiveness, operandLiveness->markLive());
-    for (BlockArgument argument : argumentNotOperand) {
-      Liveness *argumentLiveness = getLatticeElement(argument);
-      LDBG() << "Marking RegionBranchOp's argument live: " << argument;
-      // TODO: this is overly conservative: we should be able to eliminate
-      // unused values in a RegionBranchOpInterface operation but that may
-      // requires removing operation results which is beyond current
-      // capabilities of this pass right now.
-      propagateIfChanged(argumentLiveness, argumentLiveness->markLive());
-    }
   }
 
   // Now that we have checked for memory-effecting ops in the blocks of concern,
   // we will simply visit the op with this non-forwarded operand to potentially
   // mark it "live" due to type (1.a/3) liveness.
   SmallVector<Liveness *, 4> operandLiveness;
-  operandLiveness.push_back(getLatticeElement(operand.get()));
-  for (BlockArgument argument : argumentNotOperand)
-    operandLiveness.push_back(getLatticeElement(argument));
   SmallVector<const Liveness *, 4> resultsLiveness;
   for (const Value result : op->getResults())
     resultsLiveness.push_back(getLatticeElement(result));
diff --git a/mlir/test/Transforms/remove-dead-values.mlir b/mlir/test/Transforms/remove-dead-values.mlir
index 71306676d48e9..bd730915c6dcd 100644
--- a/mlir/test/Transforms/remove-dead-values.mlir
+++ b/mlir/test/Transforms/remove-dead-values.mlir
@@ -714,3 +714,20 @@ func.func private @remove_dead_branch_op(%c: i1, %arg0: i64, %arg1: i64) -> (i64
 ^bb2:
   return %arg1 : i64
 }
+
+// -----
+
+// CHECK-LABEL: func @affine_loop_no_use_iv_has_side_effect_op
+func.func @affine_loop_no_use_iv_has_side_effect_op() {
+  %c1 = arith.constant 1 : index
+  %alloc = memref.alloc() : memref<10xindex>
+  affine.for %arg0 = 0 to 79 {
+    memref.store %c1, %alloc[%c1] : memref<10xindex>
+  }
+// CHECK: %[[C1:.*]] = arith.constant 1 : index
+// CHECK: %[[ALLOC:.*]] = memref.alloc() : memref<10xindex>
+// CHECK: affine.for %[[VAL_0:.*]] = 0 to 79 {
+// CHECK:   memref.store %[[C1]], %[[ALLOC]]{{\[}}%[[C1]]] : memref<10xindex>
+// CHECK: }
+  return
+}

>From b828788bca2ccb0bdf11b9475f63c64405eea655 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Fri, 28 Nov 2025 08:51:21 +0000
Subject: [PATCH 03/15] add test-liveness-analysis test.

---
 .../DataFlow/test-liveness-analysis.mlir      | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir b/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir
index 768f1cfcb3d02..f92c3ff7c46a8 100644
--- a/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir
+++ b/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir
@@ -315,3 +315,28 @@ func.func @dead_block() {
   ^bb4:
     return
 }
+
+// -----
+
+// CHECK-LABEL: test_tag: for:
+// CHECK-NEXT: region: #0:
+// CHECK-NEXT:   argument: #0: live
+func.func @affine_loop_no_use_iv_has_side_effect_op() {
+  %c1 = arith.constant 1 : index
+  %alloc = memref.alloc() : memref<10xindex>
+  affine.for %arg0 = 0 to 79 {
+    memref.store %c1, %alloc[%c1] : memref<10xindex>
+  } {tag = "for"}
+  return
+}
+
+// -----
+
+// CHECK-LABEL: test_tag: for:
+// CHECK-NEXT: region: #0:
+// CHECK-NEXT:   argument: #0: not live
+func.func @affine_loop_no_use_iv() {
+  affine.for %arg0 = 0 to 79 { 
+  } {tag = "for"}
+  return
+}

>From d83d7287737036426eb18e20c292c6358cb76414 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Mon, 1 Dec 2025 01:58:37 +0000
Subject: [PATCH 04/15] update code.

---
 mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp | 2 +-
 mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp   | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index 70ee411b03c99..f7c32be572bd0 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -276,7 +276,7 @@ void LivenessAnalysis::visitBranchRegionArgument(BlockArgument &blockArgument) {
   LDBG() << "Visiting branch region argument: " << blockArgument
          << "in op: " << OpWithFlags(parentOp, OpPrintingFlags().skipRegions());
   Liveness *argumentLiveness = getLatticeElement(blockArgument);
-  SmallVector<Liveness *> parentResultsLiveness;
+  SmallVector<Liveness *, 4> parentResultsLiveness;
   for (Value result : parentOp->getResults())
     parentResultsLiveness.push_back(getLatticeElement(result));
 
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index d442135363392..7fd8a97f88a17 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -612,9 +612,10 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
 
     if (successor.isParent())
       continue;
-    auto arguments = successor.getSuccessor()->getArguments();
+    MutableArrayRef<BlockArgument> arguments =
+        successor.getSuccessor()->getArguments();
     for (BlockArgument argument : arguments) {
-      if (llvm::find(inputs, argument) == inputs.end()) {
+      if (!llvm::is_contained(inputs, argument)) {
         regionArguments.push_back(argument);
       }
     }

>From 6ff0ed62e7394f5b01145b8c0274b270eab42524 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Mon, 1 Dec 2025 08:02:58 +0000
Subject: [PATCH 05/15] add comment.

---
 mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index 7fd8a97f88a17..a2b5c75ea90f3 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -615,6 +615,8 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
     MutableArrayRef<BlockArgument> arguments =
         successor.getSuccessor()->getArguments();
     for (BlockArgument argument : arguments) {
+      // Visit property blockArgument of RegionBranchOp which isn't "control
+      // flow block arguments". For example, the IV of a loop.
       if (!llvm::is_contained(inputs, argument)) {
         regionArguments.push_back(argument);
       }

>From bb94dfb598fb58ba4f861c1bcab65bec2ad38fa0 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Mon, 1 Dec 2025 17:51:13 +0000
Subject: [PATCH 06/15] reserve parentResultsLiveness.

---
 mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index f7c32be572bd0..5c90a5f14540b 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -276,7 +276,8 @@ void LivenessAnalysis::visitBranchRegionArgument(BlockArgument &blockArgument) {
   LDBG() << "Visiting branch region argument: " << blockArgument
          << "in op: " << OpWithFlags(parentOp, OpPrintingFlags().skipRegions());
   Liveness *argumentLiveness = getLatticeElement(blockArgument);
-  SmallVector<Liveness *, 4> parentResultsLiveness;
+  SmallVector<Liveness *> parentResultsLiveness;
+  parentResultsLiveness.reserve(parentOp->getNumResults());
   for (Value result : parentOp->getResults())
     parentResultsLiveness.push_back(getLatticeElement(result));
 

>From 3a2ede3c72c22295b5a7c2868911a43eb4d9712e Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Thu, 18 Dec 2025 10:16:27 +0000
Subject: [PATCH 07/15] add
 operandLiveness.push_back(getLatticeElement(operand.get()));

---
 mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index 5c90a5f14540b..a43ac15ce65a6 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -230,6 +230,7 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
   // we will simply visit the op with this non-forwarded operand to potentially
   // mark it "live" due to type (1.a/3) liveness.
   SmallVector<Liveness *, 4> operandLiveness;
+  operandLiveness.push_back(getLatticeElement(operand.get()));
   SmallVector<const Liveness *, 4> resultsLiveness;
   for (const Value result : op->getResults())
     resultsLiveness.push_back(getLatticeElement(result));

>From 82d4d4f0c095840c9ff6e56ef1b7175a1efce0c7 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Sat, 27 Dec 2025 12:17:21 +0000
Subject: [PATCH 08/15] basic change bug test fail.

---
 .../Analysis/DataFlow/IntegerRangeAnalysis.h  |  3 ++
 .../mlir/Analysis/DataFlow/LivenessAnalysis.h |  2 +-
 .../mlir/Analysis/DataFlow/SparseAnalysis.h   | 19 +++++++++++-
 .../DataFlow/IntegerRangeAnalysis.cpp         | 31 ++++++++++---------
 .../Analysis/DataFlow/LivenessAnalysis.cpp    |  3 +-
 mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 25 ++++++++++++---
 .../XeGPU/Transforms/XeGPUPropagateLayout.cpp |  2 +-
 .../TestSparseBackwardDataFlowAnalysis.cpp    |  2 +-
 8 files changed, 62 insertions(+), 25 deletions(-)

diff --git a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
index 4975cedb282e4..c3db94e0f9a26 100644
--- a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
@@ -70,6 +70,9 @@ class IntegerRangeAnalysis
   visitNonControlFlowArguments(Operation *op, const RegionSuccessor &successor,
                                ArrayRef<IntegerValueRangeLattice *> argLattices,
                                unsigned firstIndex) override;
+
+
+  void visitBranchPropertyArgument(SmallVector<BlockArgument> arguments, ArrayRef<IntegerValueRangeLattice *> argLattices) override; 
 };
 
 /// Succeeds if an op can be converted to its unsigned equivalent without
diff --git a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
index 80d63ad5715ac..3edee8c60f188 100644
--- a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
@@ -88,7 +88,7 @@ class LivenessAnalysis : public SparseBackwardDataFlowAnalysis<Liveness> {
 
   void setToExitState(Liveness *lattice) override;
 
-  void visitBranchRegionArgument(BlockArgument &argument) override;
+  void visitBranchPropertyArgument(BlockArgument &argument) override;
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
index 097da72fb6bb3..9f542773e0a20 100644
--- a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
@@ -217,6 +217,10 @@ class AbstractSparseForwardDataFlowAnalysis : public DataFlowAnalysis {
       Operation *op, const RegionSuccessor &successor,
       ArrayRef<AbstractSparseLattice *> argLattices, unsigned firstIndex) = 0;
 
+  virtual void visitBranchPropertyArgumentImpl(
+      SmallVector<BlockArgument> arguments,
+      ArrayRef<AbstractSparseLattice *> argLattices) = 0;
+
   /// Get the lattice element of a value.
   virtual AbstractSparseLattice *getLatticeElement(Value value) = 0;
 
@@ -335,6 +339,11 @@ class SparseForwardDataFlowAnalysis
         firstIndex + successor.getSuccessorInputs().size()));
   }
 
+  virtual void visitBranchPropertyArgument(SmallVector<BlockArgument> arguments,
+                                           ArrayRef<StateT *> argLattices) {
+    setAllToEntryStates(argLattices);
+  }
+
 protected:
   /// Get the lattice element for a value.
   StateT *getLatticeElement(Value value) override {
@@ -391,6 +400,14 @@ class SparseForwardDataFlowAnalysis
          argLattices.size()},
         firstIndex);
   }
+  void visitBranchPropertyArgumentImpl(
+      SmallVector<BlockArgument> arguments,
+      ArrayRef<AbstractSparseLattice *> argLattices) override {
+    visitBranchPropertyArgument(
+        arguments, {reinterpret_cast<StateT *const *>(argLattices.begin()),
+                    argLattices.size()});
+  }
+
   void setToEntryState(AbstractSparseLattice *lattice) override {
     return setToEntryState(reinterpret_cast<StateT *>(lattice));
   }
@@ -431,7 +448,7 @@ class AbstractSparseBackwardDataFlowAnalysis : public DataFlowAnalysis {
   // Visit operands on branch instructions that are not forwarded.
   virtual void visitBranchOperand(OpOperand &operand) = 0;
 
-  virtual void visitBranchRegionArgument(BlockArgument &argument) = 0;
+  virtual void visitBranchPropertyArgument(BlockArgument &argument) = 0;
 
   // Visit operands on call instructions that are not forwarded.
   virtual void visitCallOperand(OpOperand &operand) = 0;
diff --git a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
index a93e605445465..912c6ff4327e7 100644
--- a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
@@ -180,6 +180,14 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
     return;
   }
 
+  return SparseForwardDataFlowAnalysis::visitNonControlFlowArguments(
+      op, successor, argLattices, firstIndex);
+}
+
+void IntegerRangeAnalysis::visitBranchPropertyArgument(
+    SmallVector<BlockArgument> arguments,
+    ArrayRef<IntegerValueRangeLattice *> argLattices) {
+
   /// Given a lower bound, upper bound, or step from a LoopLikeInterface return
   /// the lower/upper bound for that result if possible.
   auto getLoopBoundFromFold = [&](OpFoldResult loopBound, Type boundType,
@@ -202,21 +210,16 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
                     : APInt::getSignedMinValue(width);
   };
 
+  Operation *op = arguments.front().getOwner()->getParentOp();
   // Infer bounds for loop arguments that have static bounds
   if (auto loop = dyn_cast<LoopLikeOpInterface>(op)) {
-    std::optional<llvm::SmallVector<Value>> maybeIvs =
-        loop.getLoopInductionVars();
-    if (!maybeIvs) {
-      return SparseForwardDataFlowAnalysis ::visitNonControlFlowArguments(
-          op, successor, argLattices, firstIndex);
-    }
     // This shouldn't be returning nullopt if there are indunction variables.
     SmallVector<OpFoldResult> lowerBounds = *loop.getLoopLowerBounds();
     SmallVector<OpFoldResult> upperBounds = *loop.getLoopUpperBounds();
     SmallVector<OpFoldResult> steps = *loop.getLoopSteps();
-    for (auto [iv, lowerBound, upperBound, step] :
-         llvm::zip_equal(*maybeIvs, lowerBounds, upperBounds, steps)) {
-      Block *block = iv.getParentBlock();
+    for (auto [iv, lowerBound, upperBound, step, argLattice] : llvm::zip_equal(
+             arguments, lowerBounds, upperBounds, steps, argLattices)) {
+      Block *block = iv.getOwner();
       APInt min = getLoopBoundFromFold(lowerBound, iv.getType(), block,
                                        /*getUpper=*/false);
       APInt max = getLoopBoundFromFold(upperBound, iv.getType(), block,
@@ -237,14 +240,12 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
       // resulting range is meaningless and should not be used in further
       // inferences.
       if (max.sge(min)) {
-        IntegerValueRangeLattice *ivEntry = getLatticeElement(iv);
         auto ivRange = ConstantIntRanges::fromSigned(min, max);
-        propagateIfChanged(ivEntry, ivEntry->join(IntegerValueRange{ivRange}));
+        propagateIfChanged(argLattice,
+                           argLattice->join(IntegerValueRange{ivRange}));
       }
     }
     return;
   }
-
-  return SparseForwardDataFlowAnalysis::visitNonControlFlowArguments(
-      op, successor, argLattices, firstIndex);
-}
+  // setAllToEntryStates(argLattices);
+}
\ No newline at end of file
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index a43ac15ce65a6..5cd2a250bf334 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -272,7 +272,8 @@ void LivenessAnalysis::visitCallOperand(OpOperand &operand) {
   propagateIfChanged(operandLiveness, operandLiveness->markLive());
 }
 
-void LivenessAnalysis::visitBranchRegionArgument(BlockArgument &blockArgument) {
+void LivenessAnalysis::visitBranchPropertyArgument(
+    BlockArgument &blockArgument) {
   Operation *parentOp = blockArgument.getOwner()->getParentOp();
   LDBG() << "Visiting branch region argument: " << blockArgument
          << "in op: " << OpWithFlags(parentOp, OpPrintingFlags().skipRegions());
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index a2b5c75ea90f3..06299a91e6597 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -320,11 +320,26 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
         if (!inputs.empty())
           firstIndex = cast<BlockArgument>(inputs.front()).getArgNumber();
         Region *region = point->getBlock()->getParent();
+        auto nonControlFlowArguments =
+            region->getArguments().slice(firstIndex, inputs.size());
         visitNonControlFlowArgumentsImpl(
-            branch,
-            RegionSuccessor(region, region->getArguments().slice(
-                                        firstIndex, inputs.size())),
-            lattices, firstIndex);
+            branch, RegionSuccessor(region, nonControlFlowArguments), lattices,
+            firstIndex);
+        MutableArrayRef<BlockArgument> propertyArguments =
+            nonControlFlowArguments.empty()
+                ? region->getArguments()
+                : region->getArguments().slice(0, firstIndex);
+        SmallVector<AbstractSparseLattice *> propertyArgumentLattices;
+        propertyArgumentLattices.reserve(propertyArguments.size());
+        for (BlockArgument argument : propertyArguments) {
+          AbstractSparseLattice *propertyArgumentLattice =
+              getLatticeElement(argument);
+          propertyArgumentLattices.push_back(propertyArgumentLattice);
+        }
+        if (!propertyArguments.empty())
+          visitBranchPropertyArgumentImpl(
+              {propertyArguments.begin(), propertyArguments.end()},
+              propertyArgumentLattices);
       }
     }
 
@@ -628,7 +643,7 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
     visitBranchOperand(op->getOpOperand(index));
   }
   for (BlockArgument argument : regionArguments) {
-    visitBranchRegionArgument(argument);
+    visitBranchPropertyArgument(argument);
   }
 }
 
diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
index a27abb569a38b..ae2fbf0ba0a92 100644
--- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
+++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
@@ -449,7 +449,7 @@ class LayoutInfoPropagation
 
   void visitCallOperand(OpOperand &operand) override {};
 
-  void visitBranchRegionArgument(BlockArgument &argument) override {};
+  void visitBranchPropertyArgument(BlockArgument &argument) override {};
 
   void visitExternalCall(CallOpInterface call,
                          ArrayRef<LayoutInfoLattice *> operands,
diff --git a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
index c7c2e68e9d95d..076231d0e22db 100644
--- a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
+++ b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
@@ -82,7 +82,7 @@ class WrittenToAnalysis : public SparseBackwardDataFlowAnalysis<WrittenTo> {
 
   void visitCallOperand(OpOperand &operand) override;
 
-  void visitBranchRegionArgument(BlockArgument &argument) override {}
+  void visitBranchPropertyArgument(BlockArgument &argument) override {}
 
   void visitExternalCall(CallOpInterface call, ArrayRef<WrittenTo *> operands,
                          ArrayRef<const WrittenTo *> results) override;

>From 236adceab74198a2a7677f0afe52d88f7e0aa980 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Sat, 27 Dec 2025 15:19:00 +0000
Subject: [PATCH 09/15] rebase main and clang-format.

---
 mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
index c3db94e0f9a26..5f280be4445d7 100644
--- a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
@@ -71,8 +71,9 @@ class IntegerRangeAnalysis
                                ArrayRef<IntegerValueRangeLattice *> argLattices,
                                unsigned firstIndex) override;
 
-
-  void visitBranchPropertyArgument(SmallVector<BlockArgument> arguments, ArrayRef<IntegerValueRangeLattice *> argLattices) override; 
+  void visitBranchPropertyArgument(
+      SmallVector<BlockArgument> arguments,
+      ArrayRef<IntegerValueRangeLattice *> argLattices) override;
 };
 
 /// Succeeds if an op can be converted to its unsigned equivalent without

>From 3502e5ab86a6c958ac9aa41146b4f03942f03693 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Sat, 27 Dec 2025 16:50:17 +0000
Subject: [PATCH 10/15] test success.

---
 .../DataFlow/IntegerRangeAnalysis.cpp         |  6 -----
 mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 22 ++++++++++++++++---
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
index 912c6ff4327e7..6ad3d3c81b403 100644
--- a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
@@ -177,11 +177,7 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
     };
 
     inferrable.inferResultRangesFromOptional(argRanges, joinCallback);
-    return;
   }
-
-  return SparseForwardDataFlowAnalysis::visitNonControlFlowArguments(
-      op, successor, argLattices, firstIndex);
 }
 
 void IntegerRangeAnalysis::visitBranchPropertyArgument(
@@ -245,7 +241,5 @@ void IntegerRangeAnalysis::visitBranchPropertyArgument(
                            argLattice->join(IntegerValueRange{ivRange}));
       }
     }
-    return;
   }
-  // setAllToEntryStates(argLattices);
 }
\ No newline at end of file
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index 06299a91e6597..05998285251ac 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -311,6 +311,21 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
       if (!point->isBlockStart()) {
         if (!inputs.empty())
           firstIndex = cast<OpResult>(inputs.front()).getResultNumber();
+
+        Region *region = point->getBlock()->getParent();
+        MutableArrayRef<BlockArgument> propertyArguments =
+            region->getArguments().drop_back(inputs.size());
+        SmallVector<AbstractSparseLattice *> propertyArgumentLattices;
+        propertyArgumentLattices.reserve(propertyArguments.size());
+        for (BlockArgument argument : propertyArguments) {
+          AbstractSparseLattice *propertyArgumentLattice =
+              getLatticeElement(argument);
+          propertyArgumentLattices.push_back(propertyArgumentLattice);
+        }
+        if (!propertyArguments.empty())
+          visitBranchPropertyArgumentImpl(
+              {propertyArguments.begin(), propertyArguments.end()},
+              propertyArgumentLattices);
         visitNonControlFlowArgumentsImpl(
             branch,
             RegionSuccessor(
@@ -322,9 +337,7 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
         Region *region = point->getBlock()->getParent();
         auto nonControlFlowArguments =
             region->getArguments().slice(firstIndex, inputs.size());
-        visitNonControlFlowArgumentsImpl(
-            branch, RegionSuccessor(region, nonControlFlowArguments), lattices,
-            firstIndex);
+
         MutableArrayRef<BlockArgument> propertyArguments =
             nonControlFlowArguments.empty()
                 ? region->getArguments()
@@ -340,6 +353,9 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
           visitBranchPropertyArgumentImpl(
               {propertyArguments.begin(), propertyArguments.end()},
               propertyArgumentLattices);
+        visitNonControlFlowArgumentsImpl(
+            branch, RegionSuccessor(region, nonControlFlowArguments), lattices,
+            firstIndex);
       }
     }
 

>From c12bd52956a788ce6c6933ceafcc853fdea4bc14 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Sat, 27 Dec 2025 17:02:48 +0000
Subject: [PATCH 11/15] add simple doc and fix nit.

---
 .../mlir/Analysis/DataFlow/IntegerRangeAnalysis.h      |  2 +-
 mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h   | 10 +++++++---
 mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp    |  4 ++--
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
index 5f280be4445d7..f0c517bf75eba 100644
--- a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
@@ -72,7 +72,7 @@ class IntegerRangeAnalysis
                                unsigned firstIndex) override;
 
   void visitBranchPropertyArgument(
-      SmallVector<BlockArgument> arguments,
+      ArrayRef<BlockArgument> arguments,
       ArrayRef<IntegerValueRangeLattice *> argLattices) override;
 };
 
diff --git a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
index 9f542773e0a20..5b0c3249fc7fc 100644
--- a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
@@ -218,7 +218,7 @@ class AbstractSparseForwardDataFlowAnalysis : public DataFlowAnalysis {
       ArrayRef<AbstractSparseLattice *> argLattices, unsigned firstIndex) = 0;
 
   virtual void visitBranchPropertyArgumentImpl(
-      SmallVector<BlockArgument> arguments,
+      ArrayRef<BlockArgument> arguments,
       ArrayRef<AbstractSparseLattice *> argLattices) = 0;
 
   /// Get the lattice element of a value.
@@ -339,7 +339,9 @@ class SparseForwardDataFlowAnalysis
         firstIndex + successor.getSuccessorInputs().size()));
   }
 
-  virtual void visitBranchPropertyArgument(SmallVector<BlockArgument> arguments,
+  // visitBranchPropertyArgument is used to visit the property argument of a
+  // branch op, such as the loop's IV.
+  virtual void visitBranchPropertyArgument(ArrayRef<BlockArgument> arguments,
                                            ArrayRef<StateT *> argLattices) {
     setAllToEntryStates(argLattices);
   }
@@ -401,7 +403,7 @@ class SparseForwardDataFlowAnalysis
         firstIndex);
   }
   void visitBranchPropertyArgumentImpl(
-      SmallVector<BlockArgument> arguments,
+      ArrayRef<BlockArgument> arguments,
       ArrayRef<AbstractSparseLattice *> argLattices) override {
     visitBranchPropertyArgument(
         arguments, {reinterpret_cast<StateT *const *>(argLattices.begin()),
@@ -448,6 +450,8 @@ class AbstractSparseBackwardDataFlowAnalysis : public DataFlowAnalysis {
   // Visit operands on branch instructions that are not forwarded.
   virtual void visitBranchOperand(OpOperand &operand) = 0;
 
+  // visitBranchPropertyArgument is used to visit the property argument of a
+  // branch op, such as the loop's IV
   virtual void visitBranchPropertyArgument(BlockArgument &argument) = 0;
 
   // Visit operands on call instructions that are not forwarded.
diff --git a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
index 6ad3d3c81b403..76dd7669af674 100644
--- a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
@@ -181,7 +181,7 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
 }
 
 void IntegerRangeAnalysis::visitBranchPropertyArgument(
-    SmallVector<BlockArgument> arguments,
+    ArrayRef<BlockArgument> arguments,
     ArrayRef<IntegerValueRangeLattice *> argLattices) {
 
   /// Given a lower bound, upper bound, or step from a LoopLikeInterface return
@@ -242,4 +242,4 @@ void IntegerRangeAnalysis::visitBranchPropertyArgument(
       }
     }
   }
-}
\ No newline at end of file
+}

>From 185aebc605c6f341e6a01ac049409021b12a8782 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Mon, 29 Dec 2025 17:19:35 +0000
Subject: [PATCH 12/15] Making changes based on the suggestions

---
 .../Analysis/DataFlow/IntegerRangeAnalysis.h  |  2 +-
 .../mlir/Analysis/DataFlow/LivenessAnalysis.h |  2 +-
 .../mlir/Analysis/DataFlow/SparseAnalysis.h   | 22 ++++---
 .../DataFlow/IntegerRangeAnalysis.cpp         |  2 +-
 .../Analysis/DataFlow/LivenessAnalysis.cpp    |  2 +-
 mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 63 ++++++++++++-------
 .../XeGPU/Transforms/XeGPUPropagateLayout.cpp |  2 +-
 .../TestSparseBackwardDataFlowAnalysis.cpp    |  2 +-
 8 files changed, 57 insertions(+), 40 deletions(-)

diff --git a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
index f0c517bf75eba..e1e0699217093 100644
--- a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
@@ -71,7 +71,7 @@ class IntegerRangeAnalysis
                                ArrayRef<IntegerValueRangeLattice *> argLattices,
                                unsigned firstIndex) override;
 
-  void visitBranchPropertyArgument(
+  void visitNonControlFlowArguments(
       ArrayRef<BlockArgument> arguments,
       ArrayRef<IntegerValueRangeLattice *> argLattices) override;
 };
diff --git a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
index 3edee8c60f188..190bf1e3caaa9 100644
--- a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
@@ -88,7 +88,7 @@ class LivenessAnalysis : public SparseBackwardDataFlowAnalysis<Liveness> {
 
   void setToExitState(Liveness *lattice) override;
 
-  void visitBranchPropertyArgument(BlockArgument &argument) override;
+  void visitNonControlFlowArguments(BlockArgument &argument) override;
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
index 5b0c3249fc7fc..30b6fa1a733ec 100644
--- a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
@@ -217,7 +217,7 @@ class AbstractSparseForwardDataFlowAnalysis : public DataFlowAnalysis {
       Operation *op, const RegionSuccessor &successor,
       ArrayRef<AbstractSparseLattice *> argLattices, unsigned firstIndex) = 0;
 
-  virtual void visitBranchPropertyArgumentImpl(
+  virtual void visitNonControlFlowArgumentsImpl(
       ArrayRef<BlockArgument> arguments,
       ArrayRef<AbstractSparseLattice *> argLattices) = 0;
 
@@ -339,10 +339,12 @@ class SparseForwardDataFlowAnalysis
         firstIndex + successor.getSuccessorInputs().size()));
   }
 
-  // visitBranchPropertyArgument is used to visit the property argument of a
-  // branch op, such as the loop's IV.
-  virtual void visitBranchPropertyArgument(ArrayRef<BlockArgument> arguments,
-                                           ArrayRef<StateT *> argLattices) {
+  // It is used to access the non-forwarded variables of a region, such as the
+  // induction variables of a loop. The sizes of `arguments` and `argLattices`
+  // are the same, each argument corresponds to an argLattice at the same
+  // position.
+  virtual void visitNonControlFlowArguments(ArrayRef<BlockArgument> arguments,
+                                            ArrayRef<StateT *> argLattices) {
     setAllToEntryStates(argLattices);
   }
 
@@ -402,10 +404,10 @@ class SparseForwardDataFlowAnalysis
          argLattices.size()},
         firstIndex);
   }
-  void visitBranchPropertyArgumentImpl(
+  void visitNonControlFlowArgumentsImpl(
       ArrayRef<BlockArgument> arguments,
       ArrayRef<AbstractSparseLattice *> argLattices) override {
-    visitBranchPropertyArgument(
+    visitNonControlFlowArguments(
         arguments, {reinterpret_cast<StateT *const *>(argLattices.begin()),
                     argLattices.size()});
   }
@@ -450,9 +452,9 @@ class AbstractSparseBackwardDataFlowAnalysis : public DataFlowAnalysis {
   // Visit operands on branch instructions that are not forwarded.
   virtual void visitBranchOperand(OpOperand &operand) = 0;
 
-  // visitBranchPropertyArgument is used to visit the property argument of a
-  // branch op, such as the loop's IV
-  virtual void visitBranchPropertyArgument(BlockArgument &argument) = 0;
+  // Visit the non-forwarded variables of a region, such as the
+  // induction variables of a loop.
+  virtual void visitNonControlFlowArgumentst(BlockArgument &argument) = 0;
 
   // Visit operands on call instructions that are not forwarded.
   virtual void visitCallOperand(OpOperand &operand) = 0;
diff --git a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
index 76dd7669af674..18bf721a62ed4 100644
--- a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
@@ -180,7 +180,7 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
   }
 }
 
-void IntegerRangeAnalysis::visitBranchPropertyArgument(
+void IntegerRangeAnalysis::visitNonControlFlowArguments(
     ArrayRef<BlockArgument> arguments,
     ArrayRef<IntegerValueRangeLattice *> argLattices) {
 
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index 5cd2a250bf334..3a8f222135a3e 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -272,7 +272,7 @@ void LivenessAnalysis::visitCallOperand(OpOperand &operand) {
   propagateIfChanged(operandLiveness, operandLiveness->markLive());
 }
 
-void LivenessAnalysis::visitBranchPropertyArgument(
+void LivenessAnalysis::visitNonControlFlowArguments(
     BlockArgument &blockArgument) {
   Operation *parentOp = blockArgument.getOwner()->getParentOp();
   LDBG() << "Visiting branch region argument: " << blockArgument
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index 05998285251ac..6c68b2dc7a7dd 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -312,20 +312,35 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
         if (!inputs.empty())
           firstIndex = cast<OpResult>(inputs.front()).getResultNumber();
 
+        SmallVector<BlockArgument> notSuccessorInputsArguments;
         Region *region = point->getBlock()->getParent();
-        MutableArrayRef<BlockArgument> propertyArguments =
-            region->getArguments().drop_back(inputs.size());
-        SmallVector<AbstractSparseLattice *> propertyArgumentLattices;
-        propertyArgumentLattices.reserve(propertyArguments.size());
-        for (BlockArgument argument : propertyArguments) {
-          AbstractSparseLattice *propertyArgumentLattice =
+        SmallVector<RegionSuccessor> successors;
+        branch.getSuccessorRegions(*region, successors);
+        for (RegionSuccessor successor : successors) {
+          if (successor.isParent())
+            continue;
+          auto arguments = successor.getSuccessor()->getArguments();
+          ValueRange regionInputs = successor.getSuccessorInputs();
+          for (auto argument : arguments) {
+            if (llvm::find(regionInputs, argument) == regionInputs.end()) {
+              notSuccessorInputsArguments.push_back(argument);
+            }
+          }
+        }
+
+        SmallVector<AbstractSparseLattice *>
+            notSuccessorInputsArgumentsLattices;
+        notSuccessorInputsArgumentsLattices.reserve(
+            notSuccessorInputsArguments.size());
+        for (BlockArgument argument : notSuccessorInputsArguments) {
+          AbstractSparseLattice *notSuccessorInputsArgumentsLattice =
               getLatticeElement(argument);
-          propertyArgumentLattices.push_back(propertyArgumentLattice);
+          notSuccessorInputsArgumentsLattices.push_back(
+              notSuccessorInputsArgumentsLattice);
         }
-        if (!propertyArguments.empty())
-          visitBranchPropertyArgumentImpl(
-              {propertyArguments.begin(), propertyArguments.end()},
-              propertyArgumentLattices);
+        if (!notSuccessorInputsArguments.empty())
+          visitNonControlFlowArgumentsImpl(notSuccessorInputsArguments,
+                                           notSuccessorInputsArgumentsLattices);
         visitNonControlFlowArgumentsImpl(
             branch,
             RegionSuccessor(
@@ -335,26 +350,26 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
         if (!inputs.empty())
           firstIndex = cast<BlockArgument>(inputs.front()).getArgNumber();
         Region *region = point->getBlock()->getParent();
-        auto nonControlFlowArguments =
+        auto controlFlowArguments =
             region->getArguments().slice(firstIndex, inputs.size());
 
-        MutableArrayRef<BlockArgument> propertyArguments =
-            nonControlFlowArguments.empty()
+        MutableArrayRef<BlockArgument> notSuccessorInputsArguments =
+            controlFlowArguments.empty()
                 ? region->getArguments()
                 : region->getArguments().slice(0, firstIndex);
         SmallVector<AbstractSparseLattice *> propertyArgumentLattices;
-        propertyArgumentLattices.reserve(propertyArguments.size());
-        for (BlockArgument argument : propertyArguments) {
-          AbstractSparseLattice *propertyArgumentLattice =
+        propertyArgumentLattices.reserve(notSuccessorInputsArguments.size());
+        for (BlockArgument argument : notSuccessorInputsArguments) {
+          AbstractSparseLattice *notSuccessorInputsArgumentsLattice =
               getLatticeElement(argument);
-          propertyArgumentLattices.push_back(propertyArgumentLattice);
+          propertyArgumentLattices.push_back(
+              notSuccessorInputsArgumentsLattice);
         }
-        if (!propertyArguments.empty())
-          visitBranchPropertyArgumentImpl(
-              {propertyArguments.begin(), propertyArguments.end()},
-              propertyArgumentLattices);
+        if (!notSuccessorInputsArguments.empty())
+          visitNonControlFlowArgumentsImpl(notSuccessorInputsArguments,
+                                           propertyArgumentLattices);
         visitNonControlFlowArgumentsImpl(
-            branch, RegionSuccessor(region, nonControlFlowArguments), lattices,
+            branch, RegionSuccessor(region, controlFlowArguments), lattices,
             firstIndex);
       }
     }
@@ -659,7 +674,7 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
     visitBranchOperand(op->getOpOperand(index));
   }
   for (BlockArgument argument : regionArguments) {
-    visitBranchPropertyArgument(argument);
+    visitNonControlFlowArguments(argument);
   }
 }
 
diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
index ae2fbf0ba0a92..8eaaddd1b0228 100644
--- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
+++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
@@ -449,7 +449,7 @@ class LayoutInfoPropagation
 
   void visitCallOperand(OpOperand &operand) override {};
 
-  void visitBranchPropertyArgument(BlockArgument &argument) override {};
+  void visitNonControlFlowArguments(BlockArgument &argument) override {};
 
   void visitExternalCall(CallOpInterface call,
                          ArrayRef<LayoutInfoLattice *> operands,
diff --git a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
index 076231d0e22db..ba42752258bd8 100644
--- a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
+++ b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
@@ -82,7 +82,7 @@ class WrittenToAnalysis : public SparseBackwardDataFlowAnalysis<WrittenTo> {
 
   void visitCallOperand(OpOperand &operand) override;
 
-  void visitBranchPropertyArgument(BlockArgument &argument) override {}
+  void visitNonControlFlowArguments(BlockArgument &argument) override {}
 
   void visitExternalCall(CallOpInterface call, ArrayRef<WrittenTo *> operands,
                          ArrayRef<const WrittenTo *> results) override;

>From bc3b077852d0bd8889561580cd109dd7b7a73ca1 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Mon, 29 Dec 2025 18:11:33 +0000
Subject: [PATCH 13/15] fix nit and test.

---
 mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h | 2 +-
 mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp        | 9 +++++----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
index 30b6fa1a733ec..4ddf1451c6126 100644
--- a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
@@ -454,7 +454,7 @@ class AbstractSparseBackwardDataFlowAnalysis : public DataFlowAnalysis {
 
   // Visit the non-forwarded variables of a region, such as the
   // induction variables of a loop.
-  virtual void visitNonControlFlowArgumentst(BlockArgument &argument) = 0;
+  virtual void visitNonControlFlowArguments(BlockArgument &argument) = 0;
 
   // Visit operands on call instructions that are not forwarded.
   virtual void visitCallOperand(OpOperand &operand) = 0;
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index 6c68b2dc7a7dd..b6daa812c7fea 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -319,10 +319,11 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
         for (RegionSuccessor successor : successors) {
           if (successor.isParent())
             continue;
-          auto arguments = successor.getSuccessor()->getArguments();
+          Region::BlockArgListType arguments =
+              successor.getSuccessor()->getArguments();
           ValueRange regionInputs = successor.getSuccessorInputs();
-          for (auto argument : arguments) {
-            if (llvm::find(regionInputs, argument) == regionInputs.end()) {
+          for (BlockArgument argument : arguments) {
+            if (!llvm::is_contained(regionInputs, argument)) {
               notSuccessorInputsArguments.push_back(argument);
             }
           }
@@ -350,7 +351,7 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
         if (!inputs.empty())
           firstIndex = cast<BlockArgument>(inputs.front()).getArgNumber();
         Region *region = point->getBlock()->getParent();
-        auto controlFlowArguments =
+        MutableArrayRef<BlockArgument> controlFlowArguments =
             region->getArguments().slice(firstIndex, inputs.size());
 
         MutableArrayRef<BlockArgument> notSuccessorInputsArguments =

>From aa6300de08126ca655fc84548bd1296e4d843246 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Tue, 30 Dec 2025 17:53:17 +0000
Subject: [PATCH 14/15] remove forward visit API and add forall test.

---
 .../Analysis/DataFlow/IntegerRangeAnalysis.h  |  4 --
 .../mlir/Analysis/DataFlow/SparseAnalysis.h   | 21 -------
 .../DataFlow/IntegerRangeAnalysis.cpp         | 27 +++++----
 mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 55 ++-----------------
 .../DataFlow/test-liveness-analysis.mlir      | 17 ++++++
 5 files changed, 37 insertions(+), 87 deletions(-)

diff --git a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
index e1e0699217093..4975cedb282e4 100644
--- a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
@@ -70,10 +70,6 @@ class IntegerRangeAnalysis
   visitNonControlFlowArguments(Operation *op, const RegionSuccessor &successor,
                                ArrayRef<IntegerValueRangeLattice *> argLattices,
                                unsigned firstIndex) override;
-
-  void visitNonControlFlowArguments(
-      ArrayRef<BlockArgument> arguments,
-      ArrayRef<IntegerValueRangeLattice *> argLattices) override;
 };
 
 /// Succeeds if an op can be converted to its unsigned equivalent without
diff --git a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
index 4ddf1451c6126..53ac4b6b16783 100644
--- a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
@@ -217,10 +217,6 @@ class AbstractSparseForwardDataFlowAnalysis : public DataFlowAnalysis {
       Operation *op, const RegionSuccessor &successor,
       ArrayRef<AbstractSparseLattice *> argLattices, unsigned firstIndex) = 0;
 
-  virtual void visitNonControlFlowArgumentsImpl(
-      ArrayRef<BlockArgument> arguments,
-      ArrayRef<AbstractSparseLattice *> argLattices) = 0;
-
   /// Get the lattice element of a value.
   virtual AbstractSparseLattice *getLatticeElement(Value value) = 0;
 
@@ -339,15 +335,6 @@ class SparseForwardDataFlowAnalysis
         firstIndex + successor.getSuccessorInputs().size()));
   }
 
-  // It is used to access the non-forwarded variables of a region, such as the
-  // induction variables of a loop. The sizes of `arguments` and `argLattices`
-  // are the same, each argument corresponds to an argLattice at the same
-  // position.
-  virtual void visitNonControlFlowArguments(ArrayRef<BlockArgument> arguments,
-                                            ArrayRef<StateT *> argLattices) {
-    setAllToEntryStates(argLattices);
-  }
-
 protected:
   /// Get the lattice element for a value.
   StateT *getLatticeElement(Value value) override {
@@ -404,14 +391,6 @@ class SparseForwardDataFlowAnalysis
          argLattices.size()},
         firstIndex);
   }
-  void visitNonControlFlowArgumentsImpl(
-      ArrayRef<BlockArgument> arguments,
-      ArrayRef<AbstractSparseLattice *> argLattices) override {
-    visitNonControlFlowArguments(
-        arguments, {reinterpret_cast<StateT *const *>(argLattices.begin()),
-                    argLattices.size()});
-  }
-
   void setToEntryState(AbstractSparseLattice *lattice) override {
     return setToEntryState(reinterpret_cast<StateT *>(lattice));
   }
diff --git a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
index 18bf721a62ed4..a93e605445465 100644
--- a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
@@ -177,12 +177,8 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
     };
 
     inferrable.inferResultRangesFromOptional(argRanges, joinCallback);
+    return;
   }
-}
-
-void IntegerRangeAnalysis::visitNonControlFlowArguments(
-    ArrayRef<BlockArgument> arguments,
-    ArrayRef<IntegerValueRangeLattice *> argLattices) {
 
   /// Given a lower bound, upper bound, or step from a LoopLikeInterface return
   /// the lower/upper bound for that result if possible.
@@ -206,16 +202,21 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
                     : APInt::getSignedMinValue(width);
   };
 
-  Operation *op = arguments.front().getOwner()->getParentOp();
   // Infer bounds for loop arguments that have static bounds
   if (auto loop = dyn_cast<LoopLikeOpInterface>(op)) {
+    std::optional<llvm::SmallVector<Value>> maybeIvs =
+        loop.getLoopInductionVars();
+    if (!maybeIvs) {
+      return SparseForwardDataFlowAnalysis ::visitNonControlFlowArguments(
+          op, successor, argLattices, firstIndex);
+    }
     // This shouldn't be returning nullopt if there are indunction variables.
     SmallVector<OpFoldResult> lowerBounds = *loop.getLoopLowerBounds();
     SmallVector<OpFoldResult> upperBounds = *loop.getLoopUpperBounds();
     SmallVector<OpFoldResult> steps = *loop.getLoopSteps();
-    for (auto [iv, lowerBound, upperBound, step, argLattice] : llvm::zip_equal(
-             arguments, lowerBounds, upperBounds, steps, argLattices)) {
-      Block *block = iv.getOwner();
+    for (auto [iv, lowerBound, upperBound, step] :
+         llvm::zip_equal(*maybeIvs, lowerBounds, upperBounds, steps)) {
+      Block *block = iv.getParentBlock();
       APInt min = getLoopBoundFromFold(lowerBound, iv.getType(), block,
                                        /*getUpper=*/false);
       APInt max = getLoopBoundFromFold(upperBound, iv.getType(), block,
@@ -236,10 +237,14 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
       // resulting range is meaningless and should not be used in further
       // inferences.
       if (max.sge(min)) {
+        IntegerValueRangeLattice *ivEntry = getLatticeElement(iv);
         auto ivRange = ConstantIntRanges::fromSigned(min, max);
-        propagateIfChanged(argLattice,
-                           argLattice->join(IntegerValueRange{ivRange}));
+        propagateIfChanged(ivEntry, ivEntry->join(IntegerValueRange{ivRange}));
       }
     }
+    return;
   }
+
+  return SparseForwardDataFlowAnalysis::visitNonControlFlowArguments(
+      op, successor, argLattices, firstIndex);
 }
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index b6daa812c7fea..da76ef098fe4e 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -311,37 +311,6 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
       if (!point->isBlockStart()) {
         if (!inputs.empty())
           firstIndex = cast<OpResult>(inputs.front()).getResultNumber();
-
-        SmallVector<BlockArgument> notSuccessorInputsArguments;
-        Region *region = point->getBlock()->getParent();
-        SmallVector<RegionSuccessor> successors;
-        branch.getSuccessorRegions(*region, successors);
-        for (RegionSuccessor successor : successors) {
-          if (successor.isParent())
-            continue;
-          Region::BlockArgListType arguments =
-              successor.getSuccessor()->getArguments();
-          ValueRange regionInputs = successor.getSuccessorInputs();
-          for (BlockArgument argument : arguments) {
-            if (!llvm::is_contained(regionInputs, argument)) {
-              notSuccessorInputsArguments.push_back(argument);
-            }
-          }
-        }
-
-        SmallVector<AbstractSparseLattice *>
-            notSuccessorInputsArgumentsLattices;
-        notSuccessorInputsArgumentsLattices.reserve(
-            notSuccessorInputsArguments.size());
-        for (BlockArgument argument : notSuccessorInputsArguments) {
-          AbstractSparseLattice *notSuccessorInputsArgumentsLattice =
-              getLatticeElement(argument);
-          notSuccessorInputsArgumentsLattices.push_back(
-              notSuccessorInputsArgumentsLattice);
-        }
-        if (!notSuccessorInputsArguments.empty())
-          visitNonControlFlowArgumentsImpl(notSuccessorInputsArguments,
-                                           notSuccessorInputsArgumentsLattices);
         visitNonControlFlowArgumentsImpl(
             branch,
             RegionSuccessor(
@@ -351,27 +320,11 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
         if (!inputs.empty())
           firstIndex = cast<BlockArgument>(inputs.front()).getArgNumber();
         Region *region = point->getBlock()->getParent();
-        MutableArrayRef<BlockArgument> controlFlowArguments =
-            region->getArguments().slice(firstIndex, inputs.size());
-
-        MutableArrayRef<BlockArgument> notSuccessorInputsArguments =
-            controlFlowArguments.empty()
-                ? region->getArguments()
-                : region->getArguments().slice(0, firstIndex);
-        SmallVector<AbstractSparseLattice *> propertyArgumentLattices;
-        propertyArgumentLattices.reserve(notSuccessorInputsArguments.size());
-        for (BlockArgument argument : notSuccessorInputsArguments) {
-          AbstractSparseLattice *notSuccessorInputsArgumentsLattice =
-              getLatticeElement(argument);
-          propertyArgumentLattices.push_back(
-              notSuccessorInputsArgumentsLattice);
-        }
-        if (!notSuccessorInputsArguments.empty())
-          visitNonControlFlowArgumentsImpl(notSuccessorInputsArguments,
-                                           propertyArgumentLattices);
         visitNonControlFlowArgumentsImpl(
-            branch, RegionSuccessor(region, controlFlowArguments), lattices,
-            firstIndex);
+            branch,
+            RegionSuccessor(region, region->getArguments().slice(
+                                        firstIndex, inputs.size())),
+            lattices, firstIndex);
       }
     }
 
diff --git a/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir b/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir
index f92c3ff7c46a8..171a35fdeafb9 100644
--- a/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir
+++ b/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir
@@ -340,3 +340,20 @@ func.func @affine_loop_no_use_iv() {
   } {tag = "for"}
   return
 }
+
+// -----
+
+// CHECK-LABEL: test_tag: forall:
+// CHECK-NEXT: operand #0: live
+// CHECK-NEXT: region: #0:
+// CHECK-NEXT:   argument: #0: live
+
+func.func @forall_no_use_iv_has_side_effect_op(%idx1: index, %idx2: index) {
+  scf.parallel (%i) = (%idx1) to (%idx2) step (%idx2) {
+    %r = memref.alloca() : memref<10xf32>
+    scf.forall (%e2) in (%idx2) {
+      %a = memref.load %r[%idx2] : memref<10xf32>
+    } {tag = "forall"}
+  } 
+  return
+}

>From 531e8be5772b9fd0c5eff8732a05869e3dcdc901 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Thu, 1 Jan 2026 01:23:06 +0000
Subject: [PATCH 15/15] solve API issue.

---
 .../mlir/Analysis/DataFlow/LivenessAnalysis.h |  3 +-
 .../mlir/Analysis/DataFlow/SparseAnalysis.h   |  6 ++--
 .../Analysis/DataFlow/LivenessAnalysis.cpp    | 30 ++++++++++---------
 mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 10 +++----
 .../XeGPU/Transforms/XeGPUPropagateLayout.cpp |  4 ++-
 .../TestSparseBackwardDataFlowAnalysis.cpp    |  4 ++-
 6 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
index 190bf1e3caaa9..90947d06e7999 100644
--- a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
@@ -88,7 +88,8 @@ class LivenessAnalysis : public SparseBackwardDataFlowAnalysis<Liveness> {
 
   void setToExitState(Liveness *lattice) override;
 
-  void visitNonControlFlowArguments(BlockArgument &argument) override;
+  void visitNonControlFlowArguments(RegionSuccessor &successor,
+                                    ArrayRef<BlockArgument> arguments) override;
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
index 53ac4b6b16783..1bb42a246b701 100644
--- a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
@@ -431,9 +431,11 @@ class AbstractSparseBackwardDataFlowAnalysis : public DataFlowAnalysis {
   // Visit operands on branch instructions that are not forwarded.
   virtual void visitBranchOperand(OpOperand &operand) = 0;
 
-  // Visit the non-forwarded variables of a region, such as the
+  // Visit the non-forwarded arguments of a region, such as the
   // induction variables of a loop.
-  virtual void visitNonControlFlowArguments(BlockArgument &argument) = 0;
+  virtual void
+  visitNonControlFlowArguments(RegionSuccessor &successor,
+                               ArrayRef<BlockArgument> arguments) = 0;
 
   // Visit operands on call instructions that are not forwarded.
   virtual void visitCallOperand(OpOperand &operand) = 0;
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index 3a8f222135a3e..ec7fec86f0c51 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -273,25 +273,27 @@ void LivenessAnalysis::visitCallOperand(OpOperand &operand) {
 }
 
 void LivenessAnalysis::visitNonControlFlowArguments(
-    BlockArgument &blockArgument) {
-  Operation *parentOp = blockArgument.getOwner()->getParentOp();
-  LDBG() << "Visiting branch region argument: " << blockArgument
-         << "in op: " << OpWithFlags(parentOp, OpPrintingFlags().skipRegions());
-  Liveness *argumentLiveness = getLatticeElement(blockArgument);
-  SmallVector<Liveness *> parentResultsLiveness;
-  parentResultsLiveness.reserve(parentOp->getNumResults());
-  for (Value result : parentOp->getResults())
-    parentResultsLiveness.push_back(getLatticeElement(result));
+    RegionSuccessor &successor, ArrayRef<BlockArgument> arguments) {
+  Operation *parentOp = successor.getSuccessor()->getParentOp();
+  LDBG() << "visitNonControlFlowArguments visit the region # "
+         << successor.getSuccessor()->getRegionNumber() << "of "
+         << OpWithFlags(parentOp, OpPrintingFlags().skipRegions());
+  auto valuesToLattices = [&](Value value) { return getLatticeElement(value); };
+  SmallVector<Liveness *> argumentLattices =
+      llvm::map_to_vector(arguments, valuesToLattices);
+  SmallVector<Liveness *> parentResultLattices =
+      llvm::map_to_vector(parentOp->getResults(), valuesToLattices);
 
-  for (Liveness *resultLattice : parentResultsLiveness) {
+  for (Liveness *resultLattice : parentResultLattices) {
     if (resultLattice->isLive) {
-      LDBG() << "Marking branch argument live: " << blockArgument;
-      propagateIfChanged(argumentLiveness, argumentLiveness->markLive());
+      for (Liveness *argumentLattice : argumentLattices) {
+        LDBG() << "make lattice: " << argumentLattice << " live";
+        propagateIfChanged(argumentLattice, argumentLattice->markLive());
+      }
       return;
     }
   }
-  (void)visitOperation(parentOp, ArrayRef<Liveness *>{argumentLiveness},
-                       parentResultsLiveness);
+  (void)visitOperation(parentOp, argumentLattices, parentResultLattices);
 }
 
 void LivenessAnalysis::setToExitState(Liveness *lattice) {
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index da76ef098fe4e..61baba797d659 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -599,7 +599,6 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
   // All operands not forwarded to any successor. This set can be non-contiguous
   // in the presence of multiple successors.
   BitVector unaccounted(op->getNumOperands(), true);
-  SmallVector<BlockArgument> regionArguments;
   for (RegionSuccessor &successor : successors) {
     OperandRange operands = branch.getEntrySuccessorOperands(successor);
     MutableArrayRef<OpOperand> opoperands = operandsToOpOperands(operands);
@@ -612,24 +611,23 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
 
     if (successor.isParent())
       continue;
+    SmallVector<BlockArgument> noControlFlowArguments;
     MutableArrayRef<BlockArgument> arguments =
         successor.getSuccessor()->getArguments();
     for (BlockArgument argument : arguments) {
-      // Visit property blockArgument of RegionBranchOp which isn't "control
+      // Visit blockArgument of RegionBranchOp which isn't "control
       // flow block arguments". For example, the IV of a loop.
       if (!llvm::is_contained(inputs, argument)) {
-        regionArguments.push_back(argument);
+        noControlFlowArguments.push_back(argument);
       }
     }
+    visitNonControlFlowArguments(successor, noControlFlowArguments);
   }
   // All operands not forwarded to regions are typically parameters of the
   // branch operation itself (for example the boolean for if/else).
   for (int index : unaccounted.set_bits()) {
     visitBranchOperand(op->getOpOperand(index));
   }
-  for (BlockArgument argument : regionArguments) {
-    visitNonControlFlowArguments(argument);
-  }
 }
 
 void AbstractSparseBackwardDataFlowAnalysis::
diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
index 8eaaddd1b0228..07deafb8f4f6d 100644
--- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
+++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
@@ -449,7 +449,9 @@ class LayoutInfoPropagation
 
   void visitCallOperand(OpOperand &operand) override {};
 
-  void visitNonControlFlowArguments(BlockArgument &argument) override {};
+  void
+  visitNonControlFlowArguments(RegionSuccessor &successor,
+                               ArrayRef<BlockArgument> arguments) override {};
 
   void visitExternalCall(CallOpInterface call,
                          ArrayRef<LayoutInfoLattice *> operands,
diff --git a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
index ba42752258bd8..86d4b972de953 100644
--- a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
+++ b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
@@ -82,7 +82,9 @@ class WrittenToAnalysis : public SparseBackwardDataFlowAnalysis<WrittenTo> {
 
   void visitCallOperand(OpOperand &operand) override;
 
-  void visitNonControlFlowArguments(BlockArgument &argument) override {}
+  void
+  visitNonControlFlowArguments(RegionSuccessor &successor,
+                               ArrayRef<BlockArgument> arguments) override {}
 
   void visitExternalCall(CallOpInterface call, ArrayRef<WrittenTo *> operands,
                          ArrayRef<const WrittenTo *> results) override;



More information about the Mlir-commits mailing list