llvm.org GIT mirror llvm / abc5ee6
[SimpleLoopUnswitch] After unswitch delete dead blocks in parent loops Summary: Assert from PR38737 happens on the dead block inside the parent loop after unswitching nontrivial switch in the inner loop. deleteDeadBlocksFromLoop now takes extra care to detect/remove dead blocks in all the parent loops in addition to the blocks from original loop being unswitched. Reviewers: asbirlea, chandlerc Reviewed By: asbirlea Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D51415 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340955 91177308-0d34-0410-b5e6-96231b3b80d8 Fedor Sergeev 1 year, 18 days ago
2 changed file(s) with 55 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
13791379 DominatorTree &DT, LoopInfo &LI) {
13801380 // Find all the dead blocks, and remove them from their successors.
13811381 SmallVector DeadBlocks;
1382 for (BasicBlock *BB : llvm::concat(L.blocks(), ExitBlocks))
1382 for (BasicBlock *BB : ExitBlocks)
13831383 if (!DT.isReachableFromEntry(BB)) {
13841384 for (BasicBlock *SuccBB : successors(BB))
13851385 SuccBB->removePredecessor(BB);
13861386 DeadBlocks.push_back(BB);
13871387 }
1388
1389 for (Loop *ParentL = &L; ParentL; ParentL = ParentL->getParentLoop())
1390 for (BasicBlock *BB : ParentL->blocks())
1391 if (!DT.isReachableFromEntry(BB)) {
1392 for (BasicBlock *SuccBB : successors(BB))
1393 SuccBB->removePredecessor(BB);
1394 DeadBlocks.push_back(BB);
1395 }
13881396
13891397 SmallPtrSet DeadBlockSet(DeadBlocks.begin(),
13901398 DeadBlocks.end());
14301438
14311439 // Actually delete the blocks now that they've been fully unhooked from the
14321440 // IR.
1433 for (auto *BB : DeadBlocks)
1441 for (auto *BB : DeadBlockSet)
14341442 BB->eraseFromParent();
14351443 }
14361444
0 ; RUN: opt < %s -simple-loop-unswitch -enable-nontrivial-unswitch -S 2>&1 | FileCheck %s
1 ; RUN: opt < %s -passes=unswitch -enable-nontrivial-unswitch -S 2>&1 | FileCheck %s
2 ;
3 ; Checking that (dead) blocks from inner loop are deleted after unswitch.
4 ;
5 declare void @foo()
6
7 ; CHECK-LABEL: @Test
8 define void @Test(i32) {
9 entry:
10 br label %outer
11 outer:
12 %oi = phi i32 [ 0, %entry ], [ %oinc, %outer_continue]
13 br label %inner
14 inner:
15 %ii = phi i32 [ 0, %outer ], [ %iinc, %continue]
16 call void @foo()
17 switch i32 %0, label %get_out2 [
18 i32 0, label %continue
19 i32 1, label %case1
20 i32 2, label %get_out
21 ]
22 ;
23 ; since we unswitch on the above switch, %case1 and %continue blocks
24 ; become dead in the original loop
25 ;
26 ; CHECK-NOT: case1:
27 case1:
28 br label %continue
29 ; CHECK-NOT: {{^}}continue:
30 continue:
31 %iinc = add i32 %ii, 1
32 %icmp = icmp eq i32 %ii, 100
33 br i1 %icmp, label %inner, label %outer_continue
34
35 outer_continue:
36 %oinc = add i32 %oi, 1
37 %ocmp = icmp eq i32 %oi, 100
38 br i1 %ocmp, label %outer, label %get_out
39
40 get_out:
41 ret void
42 get_out2:
43 unreachable
44 }