Skip to content

Commit 59ca41f

Browse files
author
Michael Zolotukhin
committed
[LoopSimplify] Preserve LCSSA when merging exit blocks.
Summary: This fixes PR26682. Also add LCSSA as a preserved pass to LoopSimplify, that looks correct to me and allows to write a test for the issue. Reviewers: chandlerc, bogner, sanjoy Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D21112 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272224 91177308-0d34-0410-b5e6-96231b3b80d8 (cherry picked from commit 92be720)
1 parent acb339d commit 59ca41f

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

lib/Transforms/Utils/LoopSimplify.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,8 +691,10 @@ static bool simplifyOneLoop(Loop *L, SmallVectorImpl<Loop *> &Worklist,
691691
}
692692
DT->eraseNode(ExitingBlock);
693693

694-
BI->getSuccessor(0)->removePredecessor(ExitingBlock);
695-
BI->getSuccessor(1)->removePredecessor(ExitingBlock);
694+
BI->getSuccessor(0)->removePredecessor(
695+
ExitingBlock, /* DontDeleteUselessPHIs */ PreserveLCSSA);
696+
BI->getSuccessor(1)->removePredecessor(
697+
ExitingBlock, /* DontDeleteUselessPHIs */ PreserveLCSSA);
696698
ExitingBlock->eraseFromParent();
697699
}
698700
}
@@ -754,6 +756,7 @@ namespace {
754756
AU.addPreserved<ScalarEvolutionWrapperPass>();
755757
AU.addPreserved<SCEVAAWrapperPass>();
756758
AU.addPreserved<DependenceAnalysis>();
759+
AU.addPreservedID(LCSSAID);
757760
AU.addPreservedID(BreakCriticalEdgesID); // No critical edges added.
758761
}
759762

@@ -789,11 +792,27 @@ bool LoopSimplify::runOnFunction(Function &F) {
789792
SE = SEWP ? &SEWP->getSE() : nullptr;
790793
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
791794
bool PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
795+
#ifndef NDEBUG
796+
if (PreserveLCSSA) {
797+
assert(DT && "DT not available.");
798+
assert(LI && "LI not available.");
799+
bool InLCSSA =
800+
all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); });
801+
assert(InLCSSA && "Requested to preserve LCSSA, but it's already broken.");
802+
}
803+
#endif
792804

793805
// Simplify each loop nest in the function.
794806
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
795807
Changed |= simplifyLoop(*I, DT, LI, SE, AC, PreserveLCSSA);
796808

809+
#ifndef NDEBUG
810+
if (PreserveLCSSA) {
811+
bool InLCSSA =
812+
all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); });
813+
assert(InLCSSA && "LCSSA is broken after loop-simplify.");
814+
}
815+
#endif
797816
return Changed;
798817
}
799818

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; RUN: opt < %s -lcssa -loop-simplify -indvars -S | FileCheck %s
2+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
3+
target triple = "x86_64-unknown-unknown"
4+
5+
@a = external global i32, align 4
6+
7+
; Check that loop-simplify merges two loop exits, but preserves LCSSA form.
8+
; CHECK-LABEL: @foo
9+
; CHECK: for:
10+
; CHECK: %or.cond = and i1 %cmp1, %cmp2
11+
; CHECK-NOT: for.cond:
12+
; CHECK: for.end:
13+
; CHECK: %a.lcssa = phi i32 [ %a, %for ]
14+
define i32 @foo(i32 %x) {
15+
entry:
16+
br label %for
17+
18+
for:
19+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %for.cond ]
20+
%cmp1 = icmp eq i32 %x, 0
21+
%iv.next = add nuw nsw i32 %iv, 1
22+
%a = load i32, i32* @a
23+
br i1 %cmp1, label %for.cond, label %for.end
24+
25+
for.cond:
26+
%cmp2 = icmp slt i32 %iv.next, 4
27+
br i1 %cmp2, label %for, label %for.end
28+
29+
for.end:
30+
%a.lcssa = phi i32 [ %a, %for ], [ %a, %for.cond ]
31+
ret i32 %a.lcssa
32+
}

0 commit comments

Comments
 (0)