Skip to content

Commit

Permalink
[CycleInfo] skip unreachable predecessors (llvm#101316)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ssahasra authored and clementval committed Jul 31, 2024
1 parent 576060b commit b584ca4
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
8 changes: 8 additions & 0 deletions llvm/include/llvm/ADT/GenericCycleImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ template <typename ContextT> class GenericCycleInfoCompute {
DFSInfo() = default;
explicit DFSInfo(unsigned Start) : Start(Start) {}

explicit operator bool() const { return Start; }

/// Whether this node is an ancestor (or equal to) the node \p Other
/// in the DFS tree.
bool isAncestorOf(const DFSInfo &Other) const {
Expand Down Expand Up @@ -231,6 +233,8 @@ void GenericCycleInfoCompute<ContextT>::run(BlockT *EntryBlock) {

for (BlockT *Pred : predecessors(HeaderCandidate)) {
const DFSInfo PredDFSInfo = BlockDFSInfo.lookup(Pred);
// This automatically ignores unreachable predecessors since they have
// zeros in their DFSInfo.
if (CandidateInfo.isAncestorOf(PredDFSInfo))
Worklist.push_back(Pred);
}
Expand All @@ -257,6 +261,10 @@ void GenericCycleInfoCompute<ContextT>::run(BlockT *EntryBlock) {
const DFSInfo PredDFSInfo = BlockDFSInfo.lookup(Pred);
if (CandidateInfo.isAncestorOf(PredDFSInfo)) {
Worklist.push_back(Pred);
} else if (!PredDFSInfo) {
// Ignore an unreachable predecessor. It will will incorrectly cause
// Block to be treated as a cycle entry.
LLVM_DEBUG(errs() << " skipped unreachable predecessor.\n");
} else {
IsEntry = true;
}
Expand Down
23 changes: 23 additions & 0 deletions llvm/test/Analysis/CycleInfo/unreachable-predecessor.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
; RUN: opt < %s -disable-output -passes='print<cycles>' 2>&1 | FileCheck %s
; CHECK-LABEL: CycleInfo for function: unreachable
; CHECK: depth=1: entries(loop.body) loop.latch inner.block
define void @unreachable(i32 %n) {
entry:
br label %loop.body

loop.body:
br label %inner.block

; This branch should not cause %inner.block to appear as an entry.
unreachable.block:
br label %inner.block

inner.block:
br i1 undef, label %loop.exit, label %loop.latch

loop.latch:
br label %loop.body

loop.exit:
ret void
}

0 comments on commit b584ca4

Please sign in to comment.