Skip to content

Commit 05c3a4b

Browse files
authored
[CycleInfo] skip unreachable predecessors (#101316)
If an unreachable block B branches to a block S inside a cycle, it may cause S to be incorrectly treated as an entry to the cycle. We avoid that by skipping unreachable predecessors when locating entries.
1 parent 93fecc2 commit 05c3a4b

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

llvm/include/llvm/ADT/GenericCycleImpl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ template <typename ContextT> class GenericCycleInfoCompute {
134134
DFSInfo() = default;
135135
explicit DFSInfo(unsigned Start) : Start(Start) {}
136136

137+
explicit operator bool() const { return Start; }
138+
137139
/// Whether this node is an ancestor (or equal to) the node \p Other
138140
/// in the DFS tree.
139141
bool isAncestorOf(const DFSInfo &Other) const {
@@ -231,6 +233,8 @@ void GenericCycleInfoCompute<ContextT>::run(BlockT *EntryBlock) {
231233

232234
for (BlockT *Pred : predecessors(HeaderCandidate)) {
233235
const DFSInfo PredDFSInfo = BlockDFSInfo.lookup(Pred);
236+
// This automatically ignores unreachable predecessors since they have
237+
// zeros in their DFSInfo.
234238
if (CandidateInfo.isAncestorOf(PredDFSInfo))
235239
Worklist.push_back(Pred);
236240
}
@@ -257,6 +261,10 @@ void GenericCycleInfoCompute<ContextT>::run(BlockT *EntryBlock) {
257261
const DFSInfo PredDFSInfo = BlockDFSInfo.lookup(Pred);
258262
if (CandidateInfo.isAncestorOf(PredDFSInfo)) {
259263
Worklist.push_back(Pred);
264+
} else if (!PredDFSInfo) {
265+
// Ignore an unreachable predecessor. It will will incorrectly cause
266+
// Block to be treated as a cycle entry.
267+
LLVM_DEBUG(errs() << " skipped unreachable predecessor.\n");
260268
} else {
261269
IsEntry = true;
262270
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; RUN: opt < %s -disable-output -passes='print<cycles>' 2>&1 | FileCheck %s
2+
; CHECK-LABEL: CycleInfo for function: unreachable
3+
; CHECK: depth=1: entries(loop.body) loop.latch inner.block
4+
define void @unreachable(i32 %n) {
5+
entry:
6+
br label %loop.body
7+
8+
loop.body:
9+
br label %inner.block
10+
11+
; This branch should not cause %inner.block to appear as an entry.
12+
unreachable.block:
13+
br label %inner.block
14+
15+
inner.block:
16+
br i1 undef, label %loop.exit, label %loop.latch
17+
18+
loop.latch:
19+
br label %loop.body
20+
21+
loop.exit:
22+
ret void
23+
}

0 commit comments

Comments
 (0)