llvm.org GIT mirror llvm / c24eb21
Avoid infinite loops in branch folding Differential Revision: https://reviews.llvm.org/D27582 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289486 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Kaylor 3 years ago
3 changed file(s) with 83 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
16231623
16241624 // Okay, there is no really great place to put this block. If, however,
16251625 // the block before this one would be a fall-through if this block were
1626 // removed, move this block to the end of the function.
1626 // removed, move this block to the end of the function. There is no real
1627 // advantage in "falling through" to an EH block, so we don't want to
1628 // perform this transformation for that case.
1629 //
1630 // Also, Windows EH introduced the possibility of an arbitrary number of
1631 // successors to a given block. The analyzeBranch call does not consider
1632 // exception handling and so we can get in a state where a block
1633 // containing a call is followed by multiple EH blocks that would be
1634 // rotated infinitely at the end of the function if the transformation
1635 // below were performed for EH "FallThrough" blocks. Therefore, even if
1636 // that appears not to be happening anymore, we should assume that it is
1637 // possible and not remove the "!FallThrough()->isEHPad" condition below.
16271638 MachineBasicBlock *PrevTBB = nullptr, *PrevFBB = nullptr;
16281639 SmallVector PrevCond;
16291640 if (FallThrough != MF.end() &&
1641 !FallThrough->isEHPad() &&
16301642 !TII->analyzeBranch(PrevBB, PrevTBB, PrevFBB, PrevCond, true) &&
16311643 PrevBB.isSuccessor(&*FallThrough)) {
16321644 MBB->moveAfter(&MF.back());
4949 ; CXX-NEXT: .long 1
5050 ; CXX-NEXT: .long .Ltmp1@IMGREL+1
5151 ; CXX-NEXT: .long -1
52 ; CXX-NEXT: .long "?catch$2@?0?test@4HA"@IMGREL
52 ; CXX-NEXT: .long "?catch$3@?0?test@4HA"@IMGREL
5353 ; CXX-NEXT: .long 2
5454 ; CXX-NEXT: .long .Ltmp2@IMGREL+1
5555 ; CXX-NEXT: .long 3
5656 ; CXX-NEXT: .long .Ltmp3@IMGREL+1
5757 ; CXX-NEXT: .long 2
58 ; CXX-NEXT: .long "?catch$4@?0?test@4HA"@IMGREL
58 ; CXX-NEXT: .long "?catch$5@?0?test@4HA"@IMGREL
5959 ; CXX-NEXT: .long 4
6060
6161 ; SEH-LABEL: test:
6363 ; SEH-NEXT: .long .Ltmp0@IMGREL+1
6464 ; SEH-NEXT: .long .Ltmp1@IMGREL+1
6565 ; SEH-NEXT: .long dummy_filter@IMGREL
66 ; SEH-NEXT: .long .LBB0_2@IMGREL
66 ; SEH-NEXT: .long .LBB0_3@IMGREL
6767 ; SEH-NEXT: .long .Ltmp0@IMGREL+1
6868 ; SEH-NEXT: .long .Ltmp1@IMGREL+1
6969 ; SEH-NEXT: .long dummy_filter@IMGREL
70 ; SEH-NEXT: .long .LBB0_4@IMGREL
70 ; SEH-NEXT: .long .LBB0_5@IMGREL
7171 ; SEH-NEXT: .long .Ltmp2@IMGREL+1
7272 ; SEH-NEXT: .long .Ltmp3@IMGREL+1
73 ; SEH-NEXT: .long "?dtor$5@?0?test@4HA"@IMGREL
73 ; SEH-NEXT: .long "?dtor$2@?0?test@4HA"@IMGREL
7474 ; SEH-NEXT: .long 0
7575 ; SEH-NEXT: .long .Ltmp2@IMGREL+1
7676 ; SEH-NEXT: .long .Ltmp3@IMGREL+1
7777 ; SEH-NEXT: .long dummy_filter@IMGREL
78 ; SEH-NEXT: .long .LBB0_4@IMGREL
78 ; SEH-NEXT: .long .LBB0_5@IMGREL
7979 ; SEH-NEXT: .Llsda_end0:
9292 ;
9393 ; CHECK-LABEL: .def test2;
9494
95 declare void @g()
96
97 define void @test3() optsize personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
98 entry:
99 switch i32 undef, label %if.end57 [
100 i32 64, label %sw.bb
101 i32 128, label %sw.epilog
102 i32 256, label %if.then56
103 i32 1024, label %sw.bb
104 i32 4096, label %sw.bb33
105 i32 16, label %sw.epilog
106 i32 8, label %sw.epilog
107 i32 32, label %sw.bb44
108 ]
109
110 sw.bb:
111 unreachable
112
113 sw.bb33:
114 br i1 undef, label %if.end57, label %while.cond.i163.preheader
115
116 while.cond.i163.preheader:
117 unreachable
118
119 sw.bb44:
120 %temp0 = load void ()*, void ()** undef
121 invoke void %temp0()
122 to label %if.end57 unwind label %catch.dispatch
123
124 sw.epilog:
125 %temp1 = load i8*, i8** undef
126 br label %if.end57
127
128 catch.dispatch:
129 %cs = catchswitch within none [label %catch1, label %catch2, label %catch3] unwind to caller
130
131 catch1:
132 %c1 = catchpad within %cs [i8* null, i32 8, i8* null]
133 unreachable
134
135 catch2:
136 %c2 = catchpad within %cs [i8* null, i32 32, i8* null]
137 unreachable
138
139 catch3:
140 %c3 = catchpad within %cs [i8* null, i32 64, i8* null]
141 unreachable
142
143 if.then56:
144 call void @g()
145 br label %if.end57
146
147 if.end57:
148 ret void
149 }
150
151 ; This test exercises a complex case that produced an infinite loop during
152 ; compilation when the two cases above did not. The multiple targets from the
153 ; entry switch are not actually fundamental to the failure, but they are
154 ; necessary to suppress various control flow optimizations that would prevent
155 ; the conditions that lead to the failure.
156 ;
157 ; CHECK-LABEL: .def test3;
158