diff --git a/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/llvm/lib/Transforms/Utils/LoopUnroll.cpp index ea867127c569..7cd69d2b847d 100644 --- a/llvm/lib/Transforms/Utils/LoopUnroll.cpp +++ b/llvm/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); + 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(); - // 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) + 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/llvm/test/Transforms/LoopUnroll/pr31718.ll b/llvm/test/Transforms/LoopUnroll/pr31718.ll new file mode 100644 index 000000000000..014ef7e501ec --- /dev/null +++ b/llvm/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 +}