[LoopUnroll] First form LCSSA, then loop-simplify

Running non-LCSSA-preserving LoopSimplify followed by LCSSA on (roughly) the
same loop is incorrect, since LoopSimplify may break LCSSA arbitrarily higher
in the loop nest. Instead, run LCSSA first, and then run LCSSA-preserving
LoopSimplify on the result.

This fixes PR31718.

Differential Revision: https://reviews.llvm.org/D29055

llvm-svn: 292854
This commit is contained in:
Michael Kuperstein 2017-01-23 23:45:42 +00:00
parent a63528cf9c
commit 461aa57ad3
2 changed files with 71 additions and 17 deletions

View File

@ -748,26 +748,25 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
// OuterL includes all loops for which we can break loop-simplify, so // OuterL includes all loops for which we can break loop-simplify, so
// it's sufficient to simplify only it (it'll recursively simplify inner // it's sufficient to simplify only it (it'll recursively simplify inner
// loops too). // loops too).
// TODO: That potentially might be compile-time expensive. We should try if (NeedToFixLCSSA) {
// to fix the loop-simplified form incrementally. // LCSSA must be performed on the outermost affected loop. The unrolled
// Note that we only preserve LCSSA at this stage if we need to and if we // loop's last loop latch is guaranteed to be in the outermost loop
// won't end up fixing it. If we end up fixing it anyways, we don't need // after LoopInfo's been updated by markAsRemoved.
// to preserve it here and in fact we can't because it isn't correct. Loop *LatchLoop = LI->getLoopFor(Latches.back());
simplifyLoop(OuterL, DT, LI, SE, AC, PreserveLCSSA && !NeedToFixLCSSA); Loop *FixLCSSALoop = OuterL;
if (!FixLCSSALoop->contains(LatchLoop))
while (FixLCSSALoop->getParentLoop() != LatchLoop)
FixLCSSALoop = FixLCSSALoop->getParentLoop();
// LCSSA must be performed on the outermost affected loop. The unrolled formLCSSARecursively(*FixLCSSALoop, *DT, LI, SE);
// loop's last loop latch is guaranteed to be in the outermost loop after } else if (PreserveLCSSA) {
// LoopInfo's been updated by markAsRemoved.
Loop *LatchLoop = LI->getLoopFor(Latches.back());
if (!OuterL->contains(LatchLoop))
while (OuterL->getParentLoop() != LatchLoop)
OuterL = OuterL->getParentLoop();
if (NeedToFixLCSSA)
formLCSSARecursively(*OuterL, *DT, LI, SE);
else if (PreserveLCSSA)
assert(OuterL->isLCSSAForm(*DT) && assert(OuterL->isLCSSAForm(*DT) &&
"Loops should be in LCSSA form after loop-unroll."); "Loops should be in LCSSA form after loop-unroll.");
}
// TODO: That potentially might be compile-time expensive. We should try
// to fix the loop-simplified form incrementally.
simplifyLoop(OuterL, DT, LI, SE, AC, PreserveLCSSA);
} else { } else {
// Simplify loops for which we might've broken loop-simplify form. // Simplify loops for which we might've broken loop-simplify form.
for (Loop *SubLoop : LoopsToSimplify) for (Loop *SubLoop : LoopsToSimplify)

View File

@ -0,0 +1,55 @@
; RUN: opt -loop-unroll -verify-loop-lcssa -S < %s | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@b = external local_unnamed_addr global i32, align 4
; CHECK-LABEL: @main
; CHECK: exit.loopexit:
; CHECK: {{.*}} = phi i32 [ %d.0, %h3 ]
; CHECK: br label %exit
; CHECK: exit.loopexit1:
; CHECK: {{.*}} = phi i32 [ %d.0, %h3.1 ]
; CHECK: br label %exit
define void @main() local_unnamed_addr #0 {
ph1:
br label %h1
h1:
%d.0 = phi i32 [ %1, %latch1 ], [ undef, %ph1 ]
br label %ph2
ph2:
br label %h2
h2:
%0 = phi i32 [ 0, %ph2 ], [ %inc, %latch2 ]
br label %h3
h3:
br i1 undef, label %latch3, label %exit
latch3:
br i1 false, label %exit3, label %h3
exit3:
br label %latch2
latch2:
%inc = add nuw nsw i32 %0, 1
%cmp = icmp slt i32 %inc, 2
br i1 %cmp, label %h2, label %exit2
exit2:
br i1 undef, label %latch1, label %ph2
latch1: ; preds = %exit2
%1 = load i32, i32* @b, align 4
br label %h1
exit:
%d.0.lcssa = phi i32 [ %d.0, %h3 ]
ret void
}