Skip to content

Commit 92be720

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
1 parent dc32f35 commit 92be720

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
@@ -686,8 +686,10 @@ static bool simplifyOneLoop(Loop *L, SmallVectorImpl<Loop *> &Worklist,
686686
}
687687
DT->eraseNode(ExitingBlock);
688688

689-
BI->getSuccessor(0)->removePredecessor(ExitingBlock);
690-
BI->getSuccessor(1)->removePredecessor(ExitingBlock);
689+
BI->getSuccessor(0)->removePredecessor(
690+
ExitingBlock, /* DontDeleteUselessPHIs */ PreserveLCSSA);
691+
BI->getSuccessor(1)->removePredecessor(
692+
ExitingBlock, /* DontDeleteUselessPHIs */ PreserveLCSSA);
691693
ExitingBlock->eraseFromParent();
692694
}
693695
}
@@ -748,6 +750,7 @@ namespace {
748750
AU.addPreserved<GlobalsAAWrapperPass>();
749751
AU.addPreserved<ScalarEvolutionWrapperPass>();
750752
AU.addPreserved<SCEVAAWrapperPass>();
753+
AU.addPreservedID(LCSSAID);
751754
AU.addPreserved<DependenceAnalysisWrapperPass>();
752755
AU.addPreservedID(BreakCriticalEdgesID); // No critical edges added.
753756
}
@@ -781,11 +784,27 @@ bool LoopSimplify::runOnFunction(Function &F) {
781784
SE = SEWP ? &SEWP->getSE() : nullptr;
782785
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
783786
bool PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
787+
#ifndef NDEBUG
788+
if (PreserveLCSSA) {
789+
assert(DT && "DT not available.");
790+
assert(LI && "LI not available.");
791+
bool InLCSSA =
792+
all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); });
793+
assert(InLCSSA && "Requested to preserve LCSSA, but it's already broken.");
794+
}
795+
#endif
784796

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

801+
#ifndef NDEBUG
802+
if (PreserveLCSSA) {
803+
bool InLCSSA =
804+
all_of(*LI, [&](Loop *L) { return L->isRecursivelyLCSSAForm(*DT); });
805+
assert(InLCSSA && "LCSSA is broken after loop-simplify.");
806+
}
807+
#endif
789808
return Changed;
790809
}
791810

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)