llvm.org GIT mirror llvm / 7729976
[SimpleLoopUnswitch] Form dedicated exits after trivial unswitches. Summary: Form dedicated exits after trivial unswitches. Fixes PR38737, PR38283. Reviewers: chandlerc, fedor.sergeev Subscribers: sanjoy, jlebar, uabelho, llvm-commits Differential Revision: https://reviews.llvm.org/D51375 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340871 91177308-0d34-0410-b5e6-96231b3b80d8 Alina Sbirlea 1 year, 21 days ago
4 changed file(s) with 92 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
301301 formLCSSA(*OldContainingL, DT, &LI, nullptr);
302302
303303 // We shouldn't need to form dedicated exits because the exit introduced
304 // here is the (just split by unswitching) preheader. As such, it is
305 // necessarily dedicated.
306 assert(OldContainingL->hasDedicatedExits() &&
307 "Unexpected predecessor of hoisted loop preheader!");
304 // here is the (just split by unswitching) preheader. However, after trivial
305 // unswitching it is possible to get new non-dedicated exits out of parent
306 // loop so let's conservatively form dedicated exit blocks and figure out
307 // if we can optimize later.
308 formDedicatedExitBlocks(OldContainingL, &DT, &LI, /*PreserveLCSSA*/ true);
308309 }
309310 }
310311
481482 if (FullUnswitch)
482483 hoistLoopToNewParent(L, *NewPH, DT, LI);
483484
485 LLVM_DEBUG(dbgs() << " done: unswitching trivial branch...\n");
484486 ++NumTrivial;
485487 ++NumBranches;
486488 return true;
538540 else if (ExitCaseIndices.empty())
539541 return false;
540542
541 LLVM_DEBUG(dbgs() << " unswitching trivial cases...\n");
543 LLVM_DEBUG(dbgs() << " unswitching trivial switch...\n");
542544
543545 // We may need to invalidate SCEVs for the outermost loop reached by any of
544546 // the exits.
738740
739741 ++NumTrivial;
740742 ++NumSwitches;
743 LLVM_DEBUG(dbgs() << " done: unswitching trivial switch...\n");
741744 return true;
742745 }
743746
0 ; RUN: opt < %s -simple-loop-unswitch -disable-output
1
2 ; PR38283
3 ; PR38737
4 define void @f1() {
5 for.cond1thread-pre-split.lr.ph.lr.ph:
6 %tobool4 = icmp eq i16 undef, 0
7 br label %for.cond1thread-pre-split
8
9 for.cond1thread-pre-split: ; preds = %if.end, %for.cond1thread-pre-split.lr.ph.lr.ph
10 %tobool3 = icmp eq i16 undef, 0
11 br label %for.body2
12
13 for.body2: ; preds = %if.end6, %for.cond1thread-pre-split
14 br i1 %tobool3, label %if.end, label %for.end
15
16 if.end: ; preds = %for.body2
17 br i1 %tobool4, label %if.end6, label %for.cond1thread-pre-split
18
19 if.end6: ; preds = %if.end
20 br i1 undef, label %for.body2, label %for.end
21
22 for.end: ; preds = %if.end6, %for.body2
23 ret void
24 }
0 ; RUN: opt < %s -simple-loop-unswitch -disable-output
1
2 ; PR38283
3 ; PR38737
4 define void @Test(i32) {
5 entry:
6 %trunc = trunc i32 %0 to i3
7 br label %outer
8 outer:
9 br label %inner
10 inner:
11 switch i3 %trunc, label %crit_edge [
12 i3 2, label %break
13 i3 1, label %loopexit
14 ]
15 crit_edge:
16 br i1 true, label %loopexit, label %inner
17 loopexit:
18 ret void
19 break:
20 br label %outer
21 }
0 ; RUN: opt < %s -simple-loop-unswitch -disable-output
1
2 ; PR38283
3 ; PR38737
4 declare void @func_1()
5
6 define void @func_9(i32 signext %arg) {
7 bb:
8 br label %bb5
9 bb5: ; preds = %bb24, %bb
10 %tmp3.0 = phi i32 [ undef, %bb ], [ %tmp29, %bb24 ]
11 %tmp11 = icmp eq i32 %arg, 0
12 %tmp15 = icmp eq i32 %tmp3.0, 0
13 %spec.select = select i1 %tmp15, i32 0, i32 49
14 %tmp1.2 = select i1 %tmp11, i32 %spec.select, i32 9
15 %trunc = trunc i32 %tmp1.2 to i6
16 br label %bb9
17
18 bb9: ; preds = %bb5, %bb19
19 %tmp2.03 = phi i32 [ 0, %bb5 ], [ %tmp21, %bb19 ]
20 switch i6 %trunc, label %bb24 [
21 i6 0, label %bb19
22 i6 -15, label %bb22
23 ]
24
25 bb19: ; preds = %bb9
26 %tmp21 = add nuw nsw i32 %tmp2.03, 1
27 %tmp8 = icmp eq i32 %tmp21, 25
28 br i1 %tmp8, label %bb22, label %bb9
29
30 bb22: ; preds = %bb19, %bb9
31 unreachable
32
33 bb24: ; preds = %bb9
34 %tmp29 = or i32 %tmp3.0, 1
35 br label %bb5
36 }