1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -ipsccp < %s | FileCheck %s
3
4; Make sure we always consider the default edge executable for a switch
5; with no cases.
6declare void @foo()
7define void @test1() {
8; CHECK-LABEL: @test1(
9; CHECK-NEXT:    switch i32 undef, label [[D:%.*]] [
10; CHECK-NEXT:    ]
11; CHECK:       d:
12; CHECK-NEXT:    call void @foo()
13; CHECK-NEXT:    ret void
14;
15  switch i32 undef, label %d []
16d:
17  call void @foo()
18  ret void
19}
20
21define i32 @test_duplicate_successors_phi(i1 %c, i32 %x) {
22; CHECK-LABEL: @test_duplicate_successors_phi(
23; CHECK-NEXT:  entry:
24; CHECK-NEXT:    br i1 [[C:%.*]], label [[SWITCH:%.*]], label [[END:%.*]]
25; CHECK:       switch:
26; CHECK-NEXT:    br label [[SWITCH_DEFAULT:%.*]]
27; CHECK:       switch.default:
28; CHECK-NEXT:    ret i32 -1
29; CHECK:       end:
30; CHECK-NEXT:    ret i32 [[X:%.*]]
31;
32entry:
33  br i1 %c, label %switch, label %end
34
35switch:
36  switch i32 -1, label %switch.default [
37  i32 0, label %end
38  i32 1, label %end
39  ]
40
41switch.default:
42  ret i32 -1
43
44end:
45  %phi = phi i32 [ %x, %entry ], [ 1, %switch ], [ 1, %switch ]
46  ret i32 %phi
47}
48
49define i32 @test_duplicate_successors_phi_2(i1 %c, i32 %x) {
50; CHECK-LABEL: @test_duplicate_successors_phi_2(
51; CHECK-NEXT:  entry:
52; CHECK-NEXT:    br i1 [[C:%.*]], label [[SWITCH:%.*]], label [[END:%.*]]
53; CHECK:       switch:
54; CHECK-NEXT:    br label [[END]]
55; CHECK:       end:
56; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[X:%.*]], [[ENTRY:%.*]] ], [ 1, [[SWITCH]] ]
57; CHECK-NEXT:    ret i32 [[PHI]]
58;
59entry:
60  br i1 %c, label %switch, label %end
61
62switch:
63  switch i32 0, label %switch.default [
64  i32 0, label %end
65  i32 1, label %end
66  ]
67
68switch.default:
69  ret i32 -1
70
71end:
72  %phi = phi i32 [ %x, %entry ], [ 1, %switch ], [ 1, %switch ]
73  ret i32 %phi
74}
75
76define i32 @test_duplicate_successors_phi_3(i1 %c1, i32* %p, i32 %y) {
77; CHECK-LABEL: @test_duplicate_successors_phi_3(
78; CHECK-NEXT:  entry:
79; CHECK-NEXT:    br i1 [[C1:%.*]], label [[SWITCH:%.*]], label [[SWITCH_1:%.*]]
80; CHECK:       switch:
81; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[P:%.*]], align 4, !range !0
82; CHECK-NEXT:    switch i32 [[X]], label [[SWITCH_DEFAULT:%.*]] [
83; CHECK-NEXT:    i32 0, label [[SWITCH_DEFAULT]]
84; CHECK-NEXT:    i32 1, label [[SWITCH_0:%.*]]
85; CHECK-NEXT:    i32 2, label [[SWITCH_0]]
86; CHECK-NEXT:    ]
87; CHECK:       switch.default:
88; CHECK-NEXT:    ret i32 -1
89; CHECK:       switch.0:
90; CHECK-NEXT:    ret i32 0
91; CHECK:       switch.1:
92; CHECK-NEXT:    ret i32 [[Y:%.*]]
93;
94entry:
95  br i1 %c1, label %switch, label %switch.1
96
97switch:
98  %x = load i32, i32* %p, !range !{i32 0, i32 3}
99  switch i32 %x, label %switch.default [
100  i32 0, label %switch.default
101  i32 1, label %switch.0
102  i32 2, label %switch.0
103  i32 3, label %switch.1
104  i32 4, label %switch.1
105  ]
106
107switch.default:
108  ret i32 -1
109
110switch.0:
111  ret i32 0
112
113switch.1:
114  %phi = phi i32 [ %y, %entry ], [ 0, %switch ], [ 0, %switch ]
115  ret i32 %phi
116}
117
118; TODO: Determine that the default destination is dead.
119define i32 @test_local_range(i32* %p) {
120; CHECK-LABEL: @test_local_range(
121; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[P:%.*]], align 4, !range !0
122; CHECK-NEXT:    switch i32 [[X]], label [[SWITCH_DEFAULT:%.*]] [
123; CHECK-NEXT:    i32 0, label [[SWITCH_0:%.*]]
124; CHECK-NEXT:    i32 1, label [[SWITCH_1:%.*]]
125; CHECK-NEXT:    i32 2, label [[SWITCH_2:%.*]]
126; CHECK-NEXT:    ]
127; CHECK:       switch.default:
128; CHECK-NEXT:    ret i32 -1
129; CHECK:       switch.0:
130; CHECK-NEXT:    ret i32 0
131; CHECK:       switch.1:
132; CHECK-NEXT:    ret i32 1
133; CHECK:       switch.2:
134; CHECK-NEXT:    ret i32 2
135;
136  %x = load i32, i32* %p, !range !{i32 0, i32 3}
137  switch i32 %x, label %switch.default [
138  i32 0, label %switch.0
139  i32 1, label %switch.1
140  i32 2, label %switch.2
141  i32 3, label %switch.3
142  ]
143
144switch.default:
145  ret i32 -1
146
147switch.0:
148  ret i32 0
149
150switch.1:
151  ret i32 1
152
153switch.2:
154  ret i32 2
155
156switch.3:
157  ret i32 3
158}
159
160; TODO: Determine that case i3 is dead, even though the edge is shared?
161define i32 @test_duplicate_successors(i32* %p) {
162; CHECK-LABEL: @test_duplicate_successors(
163; CHECK-NEXT:    [[X:%.*]] = load i32, i32* [[P:%.*]], align 4, !range !0
164; CHECK-NEXT:    switch i32 [[X]], label [[SWITCH_DEFAULT:%.*]] [
165; CHECK-NEXT:    i32 0, label [[SWITCH_0:%.*]]
166; CHECK-NEXT:    i32 1, label [[SWITCH_0]]
167; CHECK-NEXT:    i32 2, label [[SWITCH_1:%.*]]
168; CHECK-NEXT:    i32 3, label [[SWITCH_1]]
169; CHECK-NEXT:    ]
170; CHECK:       switch.default:
171; CHECK-NEXT:    ret i32 -1
172; CHECK:       switch.0:
173; CHECK-NEXT:    ret i32 0
174; CHECK:       switch.1:
175; CHECK-NEXT:    ret i32 1
176;
177  %x = load i32, i32* %p, !range !{i32 0, i32 3}
178  switch i32 %x, label %switch.default [
179  i32 0, label %switch.0
180  i32 1, label %switch.0
181  i32 2, label %switch.1
182  i32 3, label %switch.1
183  i32 4, label %switch.2
184  i32 5, label %switch.2
185  ]
186
187switch.default:
188  ret i32 -1
189
190switch.0:
191  ret i32 0
192
193switch.1:
194  ret i32 1
195
196switch.2:
197  ret i32 2
198}
199
200; Case i32 2 is dead as well, but this cannot be determined based on
201; range information.
202define internal i32 @test_ip_range(i32 %x) {
203; CHECK-LABEL: @test_ip_range(
204; CHECK-NEXT:    switch i32 [[X:%.*]], label [[SWITCH_DEFAULT:%.*]] [
205; CHECK-NEXT:    i32 3, label [[SWITCH_3:%.*]]
206; CHECK-NEXT:    i32 1, label [[SWITCH_1:%.*]]
207; CHECK-NEXT:    i32 2, label [[SWITCH_2:%.*]]
208; CHECK-NEXT:    ], !prof !1
209; CHECK:       switch.default:
210; CHECK-NEXT:    ret i32 -1
211; CHECK:       switch.1:
212; CHECK-NEXT:    ret i32 1
213; CHECK:       switch.2:
214; CHECK-NEXT:    ret i32 2
215; CHECK:       switch.3:
216; CHECK-NEXT:    ret i32 3
217;
218  switch i32 %x, label %switch.default [
219  i32 0, label %switch.0
220  i32 1, label %switch.1
221  i32 2, label %switch.2
222  i32 3, label %switch.3
223  ], !prof !{!"branch_weights", i32 1, i32 2, i32 3, i32 4, i32 5}
224
225switch.default:
226  ret i32 -1
227
228switch.0:
229  ret i32 0
230
231switch.1:
232  ret i32 1
233
234switch.2:
235  ret i32 2
236
237switch.3:
238  ret i32 3
239}
240
241define void @call_test_ip_range() {
242; CHECK-LABEL: @call_test_ip_range(
243; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @test_ip_range(i32 1)
244; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @test_ip_range(i32 3)
245; CHECK-NEXT:    ret void
246;
247  call i32 @test_ip_range(i32 1)
248  call i32 @test_ip_range(i32 3)
249  ret void
250}
251
252declare void @llvm.assume(i1)
253
254; CHECK: !1 = !{!"branch_weights", i32 1, i32 5, i32 3, i32 4}
255