Index: lib/Transforms/Scalar/LoopSimplifyCFG.cpp =================================================================== --- lib/Transforms/Scalar/LoopSimplifyCFG.cpp +++ lib/Transforms/Scalar/LoopSimplifyCFG.cpp @@ -89,6 +89,7 @@ DominatorTree &DT; ScalarEvolution &SE; MemorySSAUpdater *MSSAU; + DomTreeUpdater DTU; // Whether or not the current loop has irreducible CFG. bool HasIrreducibleCFG = false; @@ -317,7 +318,6 @@ // Construct split preheader and the dummy switch to thread edges from it to // dead exits. - DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); BasicBlock *Preheader = L.getLoopPreheader(); BasicBlock *NewPreheader = Preheader->splitBasicBlock( Preheader->getTerminator(), @@ -387,6 +387,8 @@ while (FixLCSSALoop->getParentLoop() != StillReachable) FixLCSSALoop = FixLCSSALoop->getParentLoop(); assert(FixLCSSALoop && "Should be a loop!"); + // We need all DT updates to be done before forming LCSSA. + DTU.flush(); formLCSSARecursively(*FixLCSSALoop, DT, &LI, &SE); } } @@ -395,7 +397,6 @@ /// Delete loop blocks that have become unreachable after folding. Make all /// relevant updates to DT and LI. void deleteDeadLoopBlocks() { - DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); if (MSSAU) { SmallPtrSet DeadLoopBlocksSet(DeadLoopBlocks.begin(), DeadLoopBlocks.end()); @@ -429,8 +430,6 @@ /// Constant-fold terminators of blocks acculumated in FoldCandidates into the /// unconditional branches. void foldTerminators() { - DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); - for (BasicBlock *BB : FoldCandidates) { assert(LI.getLoopFor(BB) == &L && "Should be a loop block!"); BasicBlock *TheOnlySucc = getOnlyLiveSuccessor(BB); @@ -482,7 +481,8 @@ ConstantTerminatorFoldingImpl(Loop &L, LoopInfo &LI, DominatorTree &DT, ScalarEvolution &SE, MemorySSAUpdater *MSSAU) - : L(L), LI(LI), DT(DT), SE(SE), MSSAU(MSSAU) {} + : L(L), LI(LI), DT(DT), SE(SE), MSSAU(MSSAU), + DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy) {} bool run() { assert(L.getLoopLatch() && "Should be single latch!"); @@ -548,6 +548,7 @@ deleteDeadLoopBlocks(); } + DTU.flush(); #ifndef NDEBUG // Make sure that we have preserved all data structures after the transform. DT.verify(); Index: test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll =================================================================== --- test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll +++ test/Transforms/LoopSimplifyCFG/constant-fold-branch.ll @@ -1,5 +1,4 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; XFAIL: * ; REQUIRES: asserts ; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s ; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require,loop(simplify-cfg)' -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s @@ -2584,6 +2583,84 @@ } define void @test_crash_01() { +; CHECK-LABEL: @test_crash_01( +; CHECK-NEXT: bb: +; CHECK-NEXT: br label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: br i1 undef, label [[BB17:%.*]], label [[BB2:%.*]] +; CHECK: bb2: +; CHECK-NEXT: switch i32 0, label [[BB2_SPLIT:%.*]] [ +; CHECK-NEXT: i32 1, label [[BB19:%.*]] +; CHECK-NEXT: ] +; CHECK: bb2-split: +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb3: +; CHECK-NEXT: switch i32 undef, label [[BB16:%.*]] [ +; CHECK-NEXT: i32 0, label [[BB15:%.*]] +; CHECK-NEXT: i32 1, label [[BB14:%.*]] +; CHECK-NEXT: i32 2, label [[BB13:%.*]] +; CHECK-NEXT: i32 3, label [[BB12:%.*]] +; CHECK-NEXT: i32 4, label [[BB11:%.*]] +; CHECK-NEXT: i32 5, label [[BB8:%.*]] +; CHECK-NEXT: i32 6, label [[BB10:%.*]] +; CHECK-NEXT: i32 7, label [[BB9:%.*]] +; CHECK-NEXT: i32 8, label [[BB7:%.*]] +; CHECK-NEXT: ] +; CHECK: bb7: +; CHECK-NEXT: unreachable +; CHECK: bb8: +; CHECK-NEXT: switch i32 undef, label [[BB28:%.*]] [ +; CHECK-NEXT: i32 0, label [[BB27:%.*]] +; CHECK-NEXT: i32 1, label [[BB26:%.*]] +; CHECK-NEXT: i32 2, label [[BB23:%.*]] +; CHECK-NEXT: i32 3, label [[BB24:%.*]] +; CHECK-NEXT: i32 4, label [[BB25:%.*]] +; CHECK-NEXT: i32 5, label [[BB29:%.*]] +; CHECK-NEXT: i32 6, label [[BB22:%.*]] +; CHECK-NEXT: i32 7, label [[BB20:%.*]] +; CHECK-NEXT: i32 8, label [[BB21:%.*]] +; CHECK-NEXT: ] +; CHECK: bb9: +; CHECK-NEXT: unreachable +; CHECK: bb10: +; CHECK-NEXT: unreachable +; CHECK: bb11: +; CHECK-NEXT: br label [[BB8]] +; CHECK: bb12: +; CHECK-NEXT: unreachable +; CHECK: bb13: +; CHECK-NEXT: unreachable +; CHECK: bb14: +; CHECK-NEXT: unreachable +; CHECK: bb15: +; CHECK-NEXT: unreachable +; CHECK: bb16: +; CHECK-NEXT: unreachable +; CHECK: bb17: +; CHECK-NEXT: ret void +; CHECK: bb19: +; CHECK-NEXT: ret void +; CHECK: bb20: +; CHECK-NEXT: unreachable +; CHECK: bb21: +; CHECK-NEXT: unreachable +; CHECK: bb22: +; CHECK-NEXT: unreachable +; CHECK: bb23: +; CHECK-NEXT: unreachable +; CHECK: bb24: +; CHECK-NEXT: unreachable +; CHECK: bb25: +; CHECK-NEXT: unreachable +; CHECK: bb26: +; CHECK-NEXT: unreachable +; CHECK: bb27: +; CHECK-NEXT: unreachable +; CHECK: bb28: +; CHECK-NEXT: unreachable +; CHECK: bb29: +; CHECK-NEXT: br label [[BB3]] +; bb: br label %bb1 @@ -2598,21 +2675,21 @@ bb4: ; preds = %bb3 switch i32 0, label %bb5 [ - i32 1, label %bb19 - i32 2, label %bb18 + i32 1, label %bb19 + i32 2, label %bb18 ] bb5: ; preds = %bb4 switch i32 undef, label %bb16 [ - i32 0, label %bb15 - i32 1, label %bb14 - i32 2, label %bb13 - i32 3, label %bb12 - i32 4, label %bb11 - i32 5, label %bb8 - i32 6, label %bb10 - i32 7, label %bb9 - i32 8, label %bb7 + i32 0, label %bb15 + i32 1, label %bb14 + i32 2, label %bb13 + i32 3, label %bb12 + i32 4, label %bb11 + i32 5, label %bb8 + i32 6, label %bb10 + i32 7, label %bb9 + i32 8, label %bb7 ] bb6: ; preds = %bb29, %bb18 @@ -2623,15 +2700,15 @@ bb8: ; preds = %bb11, %bb5 switch i32 undef, label %bb28 [ - i32 0, label %bb27 - i32 1, label %bb26 - i32 2, label %bb23 - i32 3, label %bb24 - i32 4, label %bb25 - i32 5, label %bb29 - i32 6, label %bb22 - i32 7, label %bb20 - i32 8, label %bb21 + i32 0, label %bb27 + i32 1, label %bb26 + i32 2, label %bb23 + i32 3, label %bb24 + i32 4, label %bb25 + i32 5, label %bb29 + i32 6, label %bb22 + i32 7, label %bb20 + i32 8, label %bb21 ] bb9: ; preds = %bb5