From: Michael Kuperstein Date: Mon, 23 Jan 2017 23:45:42 +0000 (+0000) Subject: [LoopUnroll] First form LCSSA, then loop-simplify X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e78d6b06406b5672ce207acf844f0e759dfbcf49;p=llvm [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292854 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Utils/LoopUnroll.cpp b/lib/Transforms/Utils/LoopUnroll.cpp index ea867127c56..7cd69d2b847 100644 --- a/lib/Transforms/Utils/LoopUnroll.cpp +++ b/lib/Transforms/Utils/LoopUnroll.cpp @@ -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 // it's sufficient to simplify only it (it'll recursively simplify inner // loops too). - // TODO: That potentially might be compile-time expensive. We should try - // to fix the loop-simplified form incrementally. - // Note that we only preserve LCSSA at this stage if we need to and if we - // won't end up fixing it. If we end up fixing it anyways, we don't need - // to preserve it here and in fact we can't because it isn't correct. - simplifyLoop(OuterL, DT, LI, SE, AC, PreserveLCSSA && !NeedToFixLCSSA); - - // LCSSA must be performed on the outermost affected loop. The unrolled - // loop's last loop latch is guaranteed to be in the outermost loop after - // 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) + if (NeedToFixLCSSA) { + // LCSSA must be performed on the outermost affected loop. The unrolled + // loop's last loop latch is guaranteed to be in the outermost loop + // after LoopInfo's been updated by markAsRemoved. + Loop *LatchLoop = LI->getLoopFor(Latches.back()); + Loop *FixLCSSALoop = OuterL; + if (!FixLCSSALoop->contains(LatchLoop)) + while (FixLCSSALoop->getParentLoop() != LatchLoop) + FixLCSSALoop = FixLCSSALoop->getParentLoop(); + + formLCSSARecursively(*FixLCSSALoop, *DT, LI, SE); + } else if (PreserveLCSSA) { assert(OuterL->isLCSSAForm(*DT) && "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 { // Simplify loops for which we might've broken loop-simplify form. for (Loop *SubLoop : LoopsToSimplify) diff --git a/test/Transforms/LoopUnroll/pr31718.ll b/test/Transforms/LoopUnroll/pr31718.ll new file mode 100644 index 00000000000..014ef7e501e --- /dev/null +++ b/test/Transforms/LoopUnroll/pr31718.ll @@ -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 +}