1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S -o - < %s | FileCheck %s
4 declare void @func2(i32)
5 declare void @func4(i32)
6 declare void @func6(i32)
7 declare void @func8(i32)
9 ;; test1 - create a switch with case 2 and case 4 from two branches: N == 2
11 define void @test1(i32 %N) nounwind uwtable {
12 ; CHECK-LABEL: @test1(
14 ; CHECK-NEXT: switch i32 [[N:%.*]], label [[IF_ELSE8:%.*]] [
15 ; CHECK-NEXT: i32 2, label [[IF_THEN:%.*]]
16 ; CHECK-NEXT: i32 4, label [[IF_THEN7:%.*]]
17 ; CHECK-NEXT: ], !prof !0
19 ; CHECK-NEXT: call void @func2(i32 [[N]]) #[[ATTR1:[0-9]+]]
20 ; CHECK-NEXT: br label [[IF_END9:%.*]]
22 ; CHECK-NEXT: call void @func4(i32 [[N]]) #[[ATTR1]]
23 ; CHECK-NEXT: br label [[IF_END9]]
25 ; CHECK-NEXT: call void @func8(i32 [[N]]) #[[ATTR1]]
26 ; CHECK-NEXT: br label [[IF_END9]]
28 ; CHECK-NEXT: ret void
31 %cmp = icmp eq i32 %N, 2
32 br i1 %cmp, label %if.then, label %if.else, !prof !0
35 call void @func2(i32 %N) nounwind
39 %cmp2 = icmp eq i32 %N, 4
40 br i1 %cmp2, label %if.then7, label %if.else8, !prof !1
43 call void @func4(i32 %N) nounwind
47 call void @func8(i32 %N) nounwind
57 ;; test2 - Merge two switches where PredDefault == BB.
58 define void @test2(i32 %M, i32 %N) nounwind uwtable {
59 ; CHECK-LABEL: @test2(
61 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[M:%.*]], 2
62 ; CHECK-NEXT: br i1 [[CMP]], label [[SW1:%.*]], label [[SW2:%.*]]
64 ; CHECK-NEXT: switch i32 [[N:%.*]], label [[SW_EPILOG:%.*]] [
65 ; CHECK-NEXT: i32 2, label [[SW_BB:%.*]]
66 ; CHECK-NEXT: i32 3, label [[SW_BB1:%.*]]
67 ; CHECK-NEXT: i32 4, label [[SW_BB5:%.*]]
68 ; CHECK-NEXT: ], !prof !1
70 ; CHECK-NEXT: call void @func2(i32 [[N]]) #[[ATTR1]]
71 ; CHECK-NEXT: br label [[SW_EPILOG]]
73 ; CHECK-NEXT: call void @func4(i32 [[N]]) #[[ATTR1]]
74 ; CHECK-NEXT: br label [[SW_EPILOG]]
76 ; CHECK-NEXT: switch i32 [[N]], label [[SW_EPILOG]] [
77 ; CHECK-NEXT: i32 2, label [[SW_BB4:%.*]]
78 ; CHECK-NEXT: i32 4, label [[SW_BB5]]
79 ; CHECK-NEXT: ], !prof !2
81 ; CHECK-NEXT: call void @func6(i32 [[N]]) #[[ATTR1]]
82 ; CHECK-NEXT: br label [[SW_EPILOG]]
84 ; CHECK-NEXT: call void @func8(i32 [[N]]) #[[ATTR1]]
85 ; CHECK-NEXT: br label [[SW_EPILOG]]
87 ; CHECK-NEXT: ret void
90 %cmp = icmp sgt i32 %M, 2
91 br i1 %cmp, label %sw1, label %sw2
94 switch i32 %N, label %sw2 [
100 call void @func2(i32 %N) nounwind
104 call void @func4(i32 %N) nounwind
108 ;; Here "case 2" is invalidated if control is transferred through default case
109 ;; of the first switch.
110 switch i32 %N, label %sw.epilog [
116 call void @func6(i32 %N) nounwind
120 call void @func8(i32 %N) nounwind
127 ;; test3 - Merge two switches where PredDefault != BB.
128 define void @test3(i32 %M, i32 %N) nounwind uwtable {
129 ; CHECK-LABEL: @test3(
131 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[M:%.*]], 2
132 ; CHECK-NEXT: br i1 [[CMP]], label [[SW1:%.*]], label [[SW2:%.*]]
134 ; CHECK-NEXT: switch i32 [[N:%.*]], label [[SW_BB:%.*]] [
135 ; CHECK-NEXT: i32 1, label [[SW_BB1:%.*]]
136 ; CHECK-NEXT: i32 3, label [[SW_BB4:%.*]]
137 ; CHECK-NEXT: i32 2, label [[SW_EPILOG:%.*]]
138 ; CHECK-NEXT: ], !prof !3
140 ; CHECK-NEXT: call void @func2(i32 [[N]]) #[[ATTR1]]
141 ; CHECK-NEXT: br label [[SW_EPILOG]]
143 ; CHECK-NEXT: call void @func4(i32 [[N]]) #[[ATTR1]]
144 ; CHECK-NEXT: br label [[SW_EPILOG]]
146 ; CHECK-NEXT: switch i32 [[N]], label [[SW_EPILOG]] [
147 ; CHECK-NEXT: i32 3, label [[SW_BB4]]
148 ; CHECK-NEXT: i32 4, label [[SW_BB5:%.*]]
149 ; CHECK-NEXT: ], !prof !4
151 ; CHECK-NEXT: call void @func6(i32 [[N]]) #[[ATTR1]]
152 ; CHECK-NEXT: br label [[SW_EPILOG]]
154 ; CHECK-NEXT: call void @func8(i32 [[N]]) #[[ATTR1]]
155 ; CHECK-NEXT: br label [[SW_EPILOG]]
157 ; CHECK-NEXT: ret void
160 %cmp = icmp sgt i32 %M, 2
161 br i1 %cmp, label %sw1, label %sw2
164 switch i32 %N, label %sw.bb [
171 call void @func2(i32 %N) nounwind
175 call void @func4(i32 %N) nounwind
179 switch i32 %N, label %sw.epilog [
185 call void @func6(i32 %N) nounwind
189 call void @func8(i32 %N) nounwind
196 !0 = !{!"branch_weights", i32 64, i32 4}
197 !1 = !{!"branch_weights", i32 4, i32 64}
198 ; CHECK: !0 = !{!"branch_weights", i32 256, i32 4352, i32 16}
199 !2 = !{!"branch_weights", i32 4, i32 4, i32 8}
200 !3 = !{!"branch_weights", i32 8, i32 8, i32 4}
201 ; CHECK: !1 = !{!"branch_weights", i32 32, i32 48, i32 96, i32 16}
202 !4 = !{!"branch_weights", i32 7, i32 6, i32 4, i32 3}
203 !5 = !{!"branch_weights", i32 17, i32 13, i32 9}
204 ; CHECK: !3 = !{!"branch_weights", i32 7, i32 3, i32 4, i32 6}