[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / preserve-branchweights-switch-create.ll
blob5cea6c879dd531faf5aacebbb5eebee02339f9b9
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
10 ;; and N == 4.
11 define void @test1(i32 %N) nounwind uwtable {
12 ; CHECK-LABEL: @test1(
13 ; CHECK-NEXT:  entry:
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
18 ; CHECK:       if.then:
19 ; CHECK-NEXT:    call void @func2(i32 [[N]]) #[[ATTR1:[0-9]+]]
20 ; CHECK-NEXT:    br label [[IF_END9:%.*]]
21 ; CHECK:       if.then7:
22 ; CHECK-NEXT:    call void @func4(i32 [[N]]) #[[ATTR1]]
23 ; CHECK-NEXT:    br label [[IF_END9]]
24 ; CHECK:       if.else8:
25 ; CHECK-NEXT:    call void @func8(i32 [[N]]) #[[ATTR1]]
26 ; CHECK-NEXT:    br label [[IF_END9]]
27 ; CHECK:       if.end9:
28 ; CHECK-NEXT:    ret void
30 entry:
31   %cmp = icmp eq i32 %N, 2
32   br i1 %cmp, label %if.then, label %if.else, !prof !0
34 if.then:
35   call void @func2(i32 %N) nounwind
36   br label %if.end9
38 if.else:
39   %cmp2 = icmp eq i32 %N, 4
40   br i1 %cmp2, label %if.then7, label %if.else8, !prof !1
42 if.then7:
43   call void @func4(i32 %N) nounwind
44   br label %if.end
46 if.else8:
47   call void @func8(i32 %N) nounwind
48   br label %if.end
50 if.end:
51   br label %if.end9
53 if.end9:
54   ret void
57 ;; test2 - Merge two switches where PredDefault == BB.
58 define void @test2(i32 %M, i32 %N) nounwind uwtable {
59 ; CHECK-LABEL: @test2(
60 ; CHECK-NEXT:  entry:
61 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[M:%.*]], 2
62 ; CHECK-NEXT:    br i1 [[CMP]], label [[SW1:%.*]], label [[SW2:%.*]]
63 ; CHECK:       sw1:
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
69 ; CHECK:       sw.bb:
70 ; CHECK-NEXT:    call void @func2(i32 [[N]]) #[[ATTR1]]
71 ; CHECK-NEXT:    br label [[SW_EPILOG]]
72 ; CHECK:       sw.bb1:
73 ; CHECK-NEXT:    call void @func4(i32 [[N]]) #[[ATTR1]]
74 ; CHECK-NEXT:    br label [[SW_EPILOG]]
75 ; CHECK:       sw2:
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
80 ; CHECK:       sw.bb4:
81 ; CHECK-NEXT:    call void @func6(i32 [[N]]) #[[ATTR1]]
82 ; CHECK-NEXT:    br label [[SW_EPILOG]]
83 ; CHECK:       sw.bb5:
84 ; CHECK-NEXT:    call void @func8(i32 [[N]]) #[[ATTR1]]
85 ; CHECK-NEXT:    br label [[SW_EPILOG]]
86 ; CHECK:       sw.epilog:
87 ; CHECK-NEXT:    ret void
89 entry:
90   %cmp = icmp sgt i32 %M, 2
91   br i1 %cmp, label %sw1, label %sw2
93 sw1:
94   switch i32 %N, label %sw2 [
95   i32 2, label %sw.bb
96   i32 3, label %sw.bb1
97   ], !prof !2
99 sw.bb:
100   call void @func2(i32 %N) nounwind
101   br label %sw.epilog
103 sw.bb1:
104   call void @func4(i32 %N) nounwind
105   br label %sw.epilog
107 sw2:
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 [
111   i32 2, label %sw.bb4
112   i32 4, label %sw.bb5
113   ], !prof !3
115 sw.bb4:
116   call void @func6(i32 %N) nounwind
117   br label %sw.epilog
119 sw.bb5:
120   call void @func8(i32 %N) nounwind
121   br label %sw.epilog
123 sw.epilog:
124   ret void
127 ;; test3 - Merge two switches where PredDefault != BB.
128 define void @test3(i32 %M, i32 %N) nounwind uwtable {
129 ; CHECK-LABEL: @test3(
130 ; CHECK-NEXT:  entry:
131 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[M:%.*]], 2
132 ; CHECK-NEXT:    br i1 [[CMP]], label [[SW1:%.*]], label [[SW2:%.*]]
133 ; CHECK:       sw1:
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
139 ; CHECK:       sw.bb:
140 ; CHECK-NEXT:    call void @func2(i32 [[N]]) #[[ATTR1]]
141 ; CHECK-NEXT:    br label [[SW_EPILOG]]
142 ; CHECK:       sw.bb1:
143 ; CHECK-NEXT:    call void @func4(i32 [[N]]) #[[ATTR1]]
144 ; CHECK-NEXT:    br label [[SW_EPILOG]]
145 ; CHECK:       sw2:
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
150 ; CHECK:       sw.bb4:
151 ; CHECK-NEXT:    call void @func6(i32 [[N]]) #[[ATTR1]]
152 ; CHECK-NEXT:    br label [[SW_EPILOG]]
153 ; CHECK:       sw.bb5:
154 ; CHECK-NEXT:    call void @func8(i32 [[N]]) #[[ATTR1]]
155 ; CHECK-NEXT:    br label [[SW_EPILOG]]
156 ; CHECK:       sw.epilog:
157 ; CHECK-NEXT:    ret void
159 entry:
160   %cmp = icmp sgt i32 %M, 2
161   br i1 %cmp, label %sw1, label %sw2
163 sw1:
164   switch i32 %N, label %sw.bb [
165   i32 2, label %sw2
166   i32 3, label %sw2
167   i32 1, label %sw.bb1
168   ], !prof !4
170 sw.bb:
171   call void @func2(i32 %N) nounwind
172   br label %sw.epilog
174 sw.bb1:
175   call void @func4(i32 %N) nounwind
176   br label %sw.epilog
178 sw2:
179   switch i32 %N, label %sw.epilog [
180   i32 3, label %sw.bb4
181   i32 4, label %sw.bb5
182   ], !prof !5
184 sw.bb4:
185   call void @func6(i32 %N) nounwind
186   br label %sw.epilog
188 sw.bb5:
189   call void @func8(i32 %N) nounwind
190   br label %sw.epilog
192 sw.epilog:
193   ret void
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}