Skip to content

Commit 5ab6c7e

Browse files
committed
[LoopSimplifyCFG] Add check for missing loop preheader
Adds a check for a missing loop preheader during analysis. This fixes a nullptr dereference that happened whenever LoopSimplify was unable to generate a preheader because the loop was entered by an indirectbr instruction (as stated in the LoopSimplify.cpp doc comment).
1 parent 34f59d7 commit 5ab6c7e

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ class ConstantTerminatorFoldingImpl {
128128
// from any other block. So this variable set to true means that loop's latch
129129
// has become unreachable from loop header.
130130
bool DeleteCurrentLoop = false;
131+
// Whether or not we enter the loop through an indirectbr.
132+
bool HasIndirectEntry = false;
131133

132134
// The blocks of the original loop that will still be reachable from entry
133135
// after the constant folding.
@@ -216,6 +218,17 @@ class ConstantTerminatorFoldingImpl {
216218
return;
217219
}
218220

221+
// We need a loop preheader to split in handleDeadExits(). If LoopSimplify
222+
// wasn't able to form one because the loop can be entered through an
223+
// indirectbr we cannot continue.
224+
if (!L.getLoopPreheader()) {
225+
assert(any_of(predecessors(L.getHeader()), [&](BasicBlock *Pred) {
226+
return isa<IndirectBrInst>(Pred->getTerminator());
227+
}) && "Loop should have preheader if it is not entered indirectly");
228+
HasIndirectEntry = true;
229+
return;
230+
}
231+
219232
// Collect live and dead loop blocks and exits.
220233
LiveLoopBlocks.insert(L.getHeader());
221234
for (auto I = DFS.beginRPO(), E = DFS.endRPO(); I != E; ++I) {
@@ -546,6 +559,12 @@ class ConstantTerminatorFoldingImpl {
546559
return false;
547560
}
548561

562+
if (HasIndirectEntry) {
563+
LLVM_DEBUG(dbgs() << "Loops which can be entered indirectly are not"
564+
" supported!\n");
565+
return false;
566+
}
567+
549568
// Nothing to constant-fold.
550569
if (FoldCandidates.empty()) {
551570
LLVM_DEBUG(
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(loop-simplifycfg)' -verify-loop-info -verify-dom-info -verify-loop-lcssa < %s | FileCheck %s
2+
3+
define void @test() {
4+
; CHECK-LABEL: @test(
5+
6+
indirectbr ptr null, [label %A, label %C]
7+
8+
A:
9+
br i1 true, label %B, label %C
10+
11+
B:
12+
br i1 true, label %A, label %C
13+
14+
C:
15+
unreachable
16+
}

0 commit comments

Comments
 (0)