[Mlir-commits] [mlir] [mlir][dataflow] Add visitBranchRegionArgument interface to SparseBackwardDataFlowAnalysis and apply it in LivenessAnalysis/RemoveDeadValues (PR #169816)

lonely eagle llvmlistbot at llvm.org
Sat Dec 27 07:20:06 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 1/9] 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 2/9] 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 3/9] 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 4/9] 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 5/9] 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 6/9] 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 7/9] 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 8/9] 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 9/9] 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



More information about the Mlir-commits mailing list