Skip to content

Commit ea5b728

Browse files
author
Michael Zolotukhin
committedJul 18, 2016
[LoopSimplify] Update LCSSA after separating nested loops.
Summary: Usually LCSSA survives this transformation, but in some cases (see attached test) it doesn't: values from the original loop after separating might be used from the outer loop. Before the transformation it was the same loop, so LCSSA phis were not required. This fixes PR28272. Reviewers: sanjoy, hfinkel, chandlerc Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D21665 llvm-svn: 275891
1 parent c93e10f commit ea5b728

File tree

2 files changed

+126
-12
lines changed

2 files changed

+126
-12
lines changed
 

‎llvm/lib/Transforms/Utils/LoopSimplify.cpp

+50-12
Original file line numberDiff line numberDiff line change
@@ -327,19 +327,62 @@ static Loop *separateNestedLoop(Loop *L, BasicBlock *Preheader,
327327
else
328328
NewOuter->addChildLoop(L->removeChildLoop(SubLoops.begin() + I));
329329

330+
SmallVector<BasicBlock *, 8> OuterLoopBlocks;
331+
OuterLoopBlocks.push_back(NewBB);
330332
// Now that we know which blocks are in L and which need to be moved to
331333
// OuterLoop, move any blocks that need it.
332334
for (unsigned i = 0; i != L->getBlocks().size(); ++i) {
333335
BasicBlock *BB = L->getBlocks()[i];
334336
if (!BlocksInL.count(BB)) {
335337
// Move this block to the parent, updating the exit blocks sets
336338
L->removeBlockFromLoop(BB);
337-
if ((*LI)[BB] == L)
339+
if ((*LI)[BB] == L) {
338340
LI->changeLoopFor(BB, NewOuter);
341+
OuterLoopBlocks.push_back(BB);
342+
}
339343
--i;
340344
}
341345
}
342346

347+
// Split edges to exit blocks from the inner loop, if they emerged in the
348+
// process of separating the outer one.
349+
SmallVector<BasicBlock *, 8> ExitBlocks;
350+
L->getExitBlocks(ExitBlocks);
351+
SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(),
352+
ExitBlocks.end());
353+
for (BasicBlock *ExitBlock : ExitBlockSet) {
354+
if (any_of(predecessors(ExitBlock),
355+
[L](BasicBlock *BB) { return !L->contains(BB); })) {
356+
rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA);
357+
}
358+
}
359+
360+
if (PreserveLCSSA) {
361+
// Fix LCSSA form for L. Some values, which previously were only used inside
362+
// L, can now be used in NewOuter loop. We need to insert phi-nodes for them
363+
// in corresponding exit blocks.
364+
365+
// Go through all instructions in OuterLoopBlocks and check if they are
366+
// using operands from the inner loop. In this case we'll need to fix LCSSA
367+
// for these instructions.
368+
SmallSetVector<Instruction *, 8> WorklistSet;
369+
for (BasicBlock *OuterBB: OuterLoopBlocks) {
370+
for (Instruction &I : *OuterBB) {
371+
for (Value *Op : I.operands()) {
372+
Instruction *OpI = dyn_cast<Instruction>(Op);
373+
if (!OpI || !L->contains(OpI))
374+
continue;
375+
WorklistSet.insert(OpI);
376+
}
377+
}
378+
}
379+
SmallVector<Instruction *, 8> Worklist(WorklistSet.begin(),
380+
WorklistSet.end());
381+
formLCSSAForInstructions(Worklist, *DT, *LI);
382+
assert(NewOuter->isRecursivelyLCSSAForm(*DT) &&
383+
"LCSSA is broken after separating nested loops!");
384+
}
385+
343386
return NewOuter;
344387
}
345388

@@ -541,17 +584,12 @@ static bool simplifyOneLoop(Loop *L, SmallVectorImpl<Loop *> &Worklist,
541584
SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(),
542585
ExitBlocks.end());
543586
for (BasicBlock *ExitBlock : ExitBlockSet) {
544-
for (pred_iterator PI = pred_begin(ExitBlock), PE = pred_end(ExitBlock);
545-
PI != PE; ++PI)
546-
// Must be exactly this loop: no subloops, parent loops, or non-loop preds
547-
// allowed.
548-
if (!L->contains(*PI)) {
549-
if (rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA)) {
550-
++NumInserted;
551-
Changed = true;
552-
}
553-
break;
554-
}
587+
if (any_of(predecessors(ExitBlock),
588+
[L](BasicBlock *BB) { return !L->contains(BB); })) {
589+
rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA);
590+
++NumInserted;
591+
Changed = true;
592+
}
555593
}
556594

557595
// If the header has more than two predecessors at this point (from the
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
; RUN: opt < %s -lcssa -loop-unroll -S | FileCheck %s
2+
target triple = "x86_64-unknown-linux-gnu"
3+
4+
; PR28272
5+
; When LoopSimplify separates nested loops, it might break LCSSA form: values
6+
; from the original loop might be used in the outer loop. This test invokes
7+
; loop-unroll, which calls loop-simplify before itself. If LCSSA is broken
8+
; after loop-simplify, we crash on assertion.
9+
10+
; CHECK-LABEL: @foo
11+
define void @foo() {
12+
entry:
13+
br label %header
14+
15+
header:
16+
br label %loop1
17+
18+
loop1:
19+
br i1 true, label %loop1, label %bb43
20+
21+
bb43:
22+
%a = phi i32 [ undef, %loop1 ], [ 0, %bb45 ], [ %a, %bb54 ]
23+
%b = phi i32 [ 0, %loop1 ], [ 1, %bb54 ], [ %c, %bb45 ]
24+
br i1 true, label %bb114, label %header
25+
26+
bb114:
27+
%c = add i32 0, 1
28+
%d = add i32 0, 1
29+
br i1 true, label %bb45, label %bb54
30+
31+
bb45:
32+
%x = add i32 %d, 0
33+
br label %bb43
34+
35+
bb54:
36+
br label %bb43
37+
}
38+
39+
; CHECK-LABEL: @foo2
40+
define void @foo2() {
41+
entry:
42+
br label %outer
43+
44+
outer.loopexit:
45+
br label %outer
46+
47+
outer:
48+
br label %loop1
49+
50+
loop1:
51+
br i1 true, label %loop1, label %loop2.preheader
52+
53+
loop2.preheader:
54+
%a.ph = phi i32 [ undef, %loop1 ]
55+
%b.ph = phi i32 [ 0, %loop1 ]
56+
br label %loop2
57+
58+
loop2:
59+
%a = phi i32 [ 0, %loop2.if.true ], [ %a, %loop2.if.false ], [ %a.ph, %loop2.preheader ], [0, %bb]
60+
%b = phi i32 [ 1, %loop2.if.false ], [ %c, %loop2.if.true ], [ %b.ph, %loop2.preheader ], [%c, %bb]
61+
br i1 true, label %loop2.if, label %outer.loopexit
62+
63+
loop2.if:
64+
%c = add i32 0, 1
65+
switch i32 undef, label %loop2.if.false [i32 0, label %loop2.if.true
66+
i32 1, label %bb]
67+
68+
loop2.if.true:
69+
br i1 undef, label %loop2, label %bb
70+
71+
loop2.if.false:
72+
br label %loop2
73+
74+
bb:
75+
br label %loop2
76+
}

0 commit comments

Comments
 (0)
Please sign in to comment.