xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/preserve-branchweights-switch-create.ll (revision 07b9d231ff9baa6473b0dd588a3ce5330d3e4871)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S -o - < %s | FileCheck %s
3
4declare void @func2(i32)
5declare void @func4(i32)
6declare void @func6(i32)
7declare void @func8(i32)
8
9;; test1 - create a switch with case 2 and case 4 from two branches: N == 2
10;; and N == 4.
11define 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 [[PROF0:![0-9]+]]
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
29;
30entry:
31  %cmp = icmp eq i32 %N, 2
32  br i1 %cmp, label %if.then, label %if.else, !prof !0
33
34if.then:
35  call void @func2(i32 %N) nounwind
36  br label %if.end9
37
38if.else:
39  %cmp2 = icmp eq i32 %N, 4
40  br i1 %cmp2, label %if.then7, label %if.else8, !prof !1
41
42if.then7:
43  call void @func4(i32 %N) nounwind
44  br label %if.end
45
46if.else8:
47  call void @func8(i32 %N) nounwind
48  br label %if.end
49
50if.end:
51  br label %if.end9
52
53if.end9:
54  ret void
55}
56
57;; test2 - Merge two switches where PredDefault == BB.
58define 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 [[PROF1:![0-9]+]]
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 [[PROF2:![0-9]+]]
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
88;
89entry:
90  %cmp = icmp sgt i32 %M, 2
91  br i1 %cmp, label %sw1, label %sw2
92
93sw1:
94  switch i32 %N, label %sw2 [
95  i32 2, label %sw.bb
96  i32 3, label %sw.bb1
97  ], !prof !2
98
99sw.bb:
100  call void @func2(i32 %N) nounwind
101  br label %sw.epilog
102
103sw.bb1:
104  call void @func4(i32 %N) nounwind
105  br label %sw.epilog
106
107sw2:
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
114
115sw.bb4:
116  call void @func6(i32 %N) nounwind
117  br label %sw.epilog
118
119sw.bb5:
120  call void @func8(i32 %N) nounwind
121  br label %sw.epilog
122
123sw.epilog:
124  ret void
125}
126
127;; test3 - Merge two switches where PredDefault != BB.
128define 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 [[PROF3:![0-9]+]]
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 [[PROF4:![0-9]+]]
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
158;
159entry:
160  %cmp = icmp sgt i32 %M, 2
161  br i1 %cmp, label %sw1, label %sw2
162
163sw1:
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
169
170sw.bb:
171  call void @func2(i32 %N) nounwind
172  br label %sw.epilog
173
174sw.bb1:
175  call void @func4(i32 %N) nounwind
176  br label %sw.epilog
177
178sw2:
179  switch i32 %N, label %sw.epilog [
180  i32 3, label %sw.bb4
181  i32 4, label %sw.bb5
182  ], !prof !5
183
184sw.bb4:
185  call void @func6(i32 %N) nounwind
186  br label %sw.epilog
187
188sw.bb5:
189  call void @func8(i32 %N) nounwind
190  br label %sw.epilog
191
192sw.epilog:
193  ret void
194}
195
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}
205