Skip to content

Commit e1cfe4d

Browse files
use RegionBranchOpInterface fix the bug.
1 parent 1bf4f12 commit e1cfe4d

File tree

2 files changed

+36
-15
lines changed

2 files changed

+36
-15
lines changed

mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include <mlir/IR/Operation.h>
1818
#include <mlir/IR/Value.h>
1919
#include <mlir/Interfaces/CallInterfaces.h>
20-
#include <mlir/Interfaces/LoopLikeInterface.h>
2120
#include <mlir/Interfaces/SideEffectInterfaces.h>
2221
#include <mlir/Support/LLVM.h>
2322

@@ -166,6 +165,28 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
166165
blocks.push_back(&block);
167166
}
168167
}
168+
169+
// In the block of the successor block argument of RegionBranchOpInterface,
170+
// there may be arguments of RegionBranchOpInterface, such as the IV of
171+
// scf.forOp. Explicitly set this argument to live.
172+
auto regionBranchOp = cast<RegionBranchOpInterface>(op);
173+
for (size_t i = 0, e = op->getNumRegions(); i < e; ++i) {
174+
SmallVector<RegionSuccessor> successors;
175+
regionBranchOp.getSuccessorRegions(op->getRegion(i), successors);
176+
for (RegionSuccessor successor : successors) {
177+
if (successor.isParent())
178+
continue;
179+
auto arguments = successor.getSuccessor()->getArguments();
180+
ValueRange regionInputs = successor.getSuccessorInputs();
181+
for (auto argument : arguments) {
182+
if (llvm::find(regionInputs, argument) == regionInputs.end()) {
183+
(void)getLatticeElement(argument)->markLive();
184+
LDBG() << "Marking RegionBranchOp's success argument live: "
185+
<< argument;
186+
}
187+
}
188+
}
189+
}
169190
} else if (isa<BranchOpInterface>(op)) {
170191
// We cannot track all successor blocks of the branch operation(More
171192
// specifically, it's the successor's successor). Additionally, different
@@ -196,18 +217,6 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
196217
break;
197218
}
198219
}
199-
200-
// If the parentOp is live and it implements the LoopLiveOpInterface, then
201-
// set its IV as live.
202-
if (mayLive && isa<LoopLikeOpInterface>(parentOp)) {
203-
auto loopOp = cast<LoopLikeOpInterface>(parentOp);
204-
std::optional<SmallVector<Value>> ivs = loopOp.getLoopInductionVars();
205-
if (ivs.has_value()) {
206-
for (auto iv : *ivs) {
207-
getLatticeElement(iv)->markLive();
208-
}
209-
}
210-
}
211220
} else {
212221
// When the op is a `RegionBranchTerminatorOpInterface`, like an
213222
// `scf.condition` op or return-like, like an `scf.yield` op, its branch

mlir/test/Transforms/remove-dead-values.mlir

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -652,13 +652,25 @@ func.func @callee(%arg0: index, %arg1: index, %arg2: index) -> index {
652652

653653
// -----
654654

655-
// This test verifies that the induction variables in loops are not deleted.
655+
// This test verifies that the induction variables in loops are not deleted, the loop has results.
656656

657657
// CHECK-LABEL: func @dead_value_loop_ivs
658-
func.func @dead_value_loop_ivs(%lb: index, %ub: index, %step: index, %b : i1) -> i1 {
658+
func.func @dead_value_loop_ivs_has_result(%lb: index, %ub: index, %step: index, %b: i1) -> i1 {
659659
%loop_ret = scf.for %iv = %lb to %ub step %step iter_args(%iter = %b) -> (i1) {
660660
cf.assert %b, "loop not dead"
661661
scf.yield %b : i1
662662
}
663663
return %loop_ret : i1
664664
}
665+
666+
// -----
667+
668+
// This test verifies that the induction variables in loops are not deleted, the loop has no results.
669+
670+
// CHECK-LABEL: func @dead_value_loop_ivs_no_result
671+
func.func @dead_value_loop_ivs_no_result(%lb: index, %ub: index, %step: index, %input: memref<?xf32>, %value: f32, %pos: index) {
672+
scf.for %iv = %lb to %ub step %step {
673+
memref.store %value, %input[%pos] : memref<?xf32>
674+
}
675+
return
676+
}

0 commit comments

Comments
 (0)