1; RUN: opt -lowerswitch -S < %s | FileCheck %s
2
3; Test that we don't crash and have a different basic block for each incoming edge.
4define void @test0() {
5; CHECK-LABEL: @test0
6; CHECK: %merge = phi i64 [ 1, %BB3 ], [ 0, %NodeBlock5 ], [ 0, %LeafBlock1 ], [ 0, %NewDefault ]
7BB1:
8  switch i32 undef, label %BB2 [
9    i32 3, label %BB2
10    i32 5, label %BB2
11    i32 0, label %BB3
12    i32 2, label %BB3
13    i32 4, label %BB3
14  ]
15
16BB2:
17  %merge = phi i64 [ 1, %BB3 ], [ 0, %BB1 ], [ 0, %BB1 ], [ 0, %BB1 ]
18  ret void
19
20BB3:
21  br label %BB2
22}
23
24; Test switch cases that are merged into a single case during lowerswitch
25; (take 84 and 85 below) - check that the number of incoming phi values match
26; the number of branches.
27define void @test1() {
28; CHECK-LABEL: @test1
29entry:
30  br label %bb1
31
32bb1:
33  switch i32 undef, label %bb1 [
34    i32 84, label %bb3
35    i32 85, label %bb3
36    i32 86, label %bb2
37    i32 78, label %exit
38    i32 99, label %bb3
39  ]
40
41bb2:
42  br label %bb3
43
44bb3:
45; CHECK-LABEL: bb3
46; CHECK: %tmp = phi i32 [ 1, %NodeBlock ], [ 0, %bb2 ], [ 1, %LeafBlock3 ]
47  %tmp = phi i32 [ 1, %bb1 ], [ 0, %bb2 ], [ 1, %bb1 ], [ 1, %bb1 ]
48; CHECK-NEXT: %tmp2 = phi i32 [ 2, %NodeBlock ], [ 5, %bb2 ], [ 2, %LeafBlock3 ]
49  %tmp2 = phi i32 [ 2, %bb1 ], [ 2, %bb1 ], [ 5, %bb2 ], [ 2, %bb1 ]
50  br label %exit
51
52exit:
53  ret void
54}
55
56; Test that we don't crash.
57define void @test2(i32 %mode) {
58; CHECK-LABEL: @test2
59  br i1 undef, label %1, label %._crit_edge
60
61; <label>:1                                       ; preds = %0
62  switch i32 %mode, label %33 [
63    i32 2, label %2
64    i32 3, label %3
65    i32 4, label %4
66    i32 5, label %5
67    i32 6, label %6
68    i32 7, label %7
69    i32 8, label %8
70    i32 9, label %9
71    i32 10, label %10
72    i32 11, label %14
73    i32 12, label %18
74    i32 13, label %22
75    i32 14, label %26
76    i32 15, label %27
77    i32 16, label %34
78    i32 17, label %34
79    i32 18, label %34
80    i32 19, label %34
81    i32 22, label %34
82    i32 20, label %31
83    i32 21, label %32
84  ]
85
86; <label>:2                                       ; preds = %1
87  br label %34
88
89; <label>:3                                       ; preds = %1
90  br label %34
91
92; <label>:4                                       ; preds = %1
93  br label %34
94
95; <label>:5                                       ; preds = %1
96  br label %34
97
98; <label>:6                                       ; preds = %1
99  br label %34
100
101; <label>:7                                       ; preds = %1
102  br label %34
103
104; <label>:8                                       ; preds = %1
105  br label %34
106
107; <label>:9                                       ; preds = %1
108  br label %34
109
110; <label>:10                                      ; preds = %1
111  br i1 undef, label %11, label %12
112
113; <label>:11                                      ; preds = %10
114  br label %13
115
116; <label>:12                                      ; preds = %10
117  br label %13
118
119; <label>:13                                      ; preds = %12, %11
120  br label %34
121
122; <label>:14                                      ; preds = %1
123  br i1 undef, label %15, label %16
124
125; <label>:15                                      ; preds = %14
126  br label %17
127
128; <label>:16                                      ; preds = %14
129  br label %17
130
131; <label>:17                                      ; preds = %16, %15
132  br label %34
133
134; <label>:18                                      ; preds = %1
135  br i1 undef, label %19, label %20
136
137; <label>:19                                      ; preds = %18
138  br label %21
139
140; <label>:20                                      ; preds = %18
141  br label %21
142
143; <label>:21                                      ; preds = %20, %19
144  br label %34
145
146; <label>:22                                      ; preds = %1
147  br i1 undef, label %23, label %24
148
149; <label>:23                                      ; preds = %22
150  br label %25
151
152; <label>:24                                      ; preds = %22
153  br label %25
154
155; <label>:25                                      ; preds = %24, %23
156  br label %34
157
158; <label>:26                                      ; preds = %1
159  br label %34
160
161; <label>:27                                      ; preds = %1
162  br i1 undef, label %28, label %29
163
164; <label>:28                                      ; preds = %27
165  br label %30
166
167; <label>:29                                      ; preds = %27
168  br label %30
169
170; <label>:30                                      ; preds = %29, %28
171  br label %34
172
173; <label>:31                                      ; preds = %1
174  br label %34
175
176; <label>:32                                      ; preds = %1
177  br label %34
178
179; <label>:33                                      ; preds = %1
180  br label %34
181
182; <label>:34                                      ; preds = %33, %32, %31, %30, %26, %25, %21, %17, %13, %9, %8, %7, %6, %5, %4, %3, %2, %1, %1, %1, %1, %1
183  %o.0 = phi float [ undef, %33 ], [ undef, %32 ], [ undef, %31 ], [ undef, %30 ], [ undef, %26 ], [ undef, %25 ], [ undef, %21 ], [ undef, %17 ], [ undef, %13 ], [ undef, %9 ], [ undef, %8 ], [ undef, %7 ], [ undef, %6 ], [ undef, %5 ], [ undef, %4 ], [ undef, %3 ], [ undef, %2 ], [ undef, %1 ], [ undef, %1 ], [ undef, %1 ], [ undef, %1 ], [ undef, %1 ]
184  br label %._crit_edge
185
186._crit_edge:                                      ; preds = %34, %0
187  ret void
188}
189
190; Test that the PHI node in for.cond should have one entry for each predecessor
191; of its parent basic block after lowerswitch merged several cases into a new
192; default block.
193define void @test3() {
194; CHECK-LABEL: @test3
195entry:
196  br label %lbl1
197
198lbl1:                                             ; preds = %cleanup, %entry
199  br label %lbl2
200
201lbl2:                                             ; preds = %cleanup, %lbl1
202  br label %for.cond
203
204for.cond:                                         ; preds = %cleanup, %cleanup, %lbl2
205; CHECK: for.cond:
206; CHECK: phi i16 [ undef, %lbl2 ], [ %b.3, %NewDefault ]{{$}}
207; CHECK: for.cond1:
208  %b.2 = phi i16 [ undef, %lbl2 ], [ %b.3, %cleanup ], [ %b.3, %cleanup ]
209  br label %for.cond1
210
211for.cond1:                                        ; preds = %for.inc, %for.cond
212  %b.3 = phi i16 [ %b.2, %for.cond ], [ undef, %for.inc ]
213  %tobool = icmp ne i16 %b.3, 0
214  br i1 %tobool, label %for.body, label %for.end
215
216for.body:                                         ; preds = %for.cond1
217  br i1 undef, label %if.then, label %for.inc
218
219if.then:                                          ; preds = %for.body
220  br label %cleanup
221
222for.inc:                                          ; preds = %for.body
223  br label %for.cond1
224
225for.end:                                          ; preds = %for.cond1
226  br i1 undef, label %if.then4, label %for.body7
227
228if.then4:                                         ; preds = %for.end
229  br label %cleanup
230
231for.body7:                                        ; preds = %for.end
232  br label %cleanup
233
234cleanup:                                          ; preds = %for.body7, %if.then4, %if.then
235  switch i32 undef, label %unreachable [
236    i32 0, label %for.cond
237    i32 2, label %lbl1
238    i32 5, label %for.cond
239    i32 3, label %lbl2
240  ]
241
242unreachable:                                      ; preds = %cleanup
243  unreachable
244}
245
246; Test that the PHI node in cleanup17 is removed as the switch default block is
247; not reachable.
248define void @test4() {
249; CHECK-LABEL: @test4
250entry:
251  switch i32 undef, label %cleanup17 [
252    i32 0, label %return
253    i32 9, label %return
254  ]
255
256cleanup17:
257; CHECK: cleanup17:
258; CHECK-NOT: phi i16 [ undef, %entry ]
259; CHECK: return:
260
261  %retval.4 = phi i16 [ undef, %entry ]
262  unreachable
263
264return:
265  ret void
266}
267
268; Test that the PHI node in for.inc is updated correctly as the switch is
269; replaced with a single branch to for.inc
270define void @test5() {
271; CHECK-LABEL: @test5
272entry:
273  br i1 undef, label %cleanup10, label %cleanup10.thread
274
275cleanup10.thread:
276  br label %for.inc
277
278cleanup10:
279  switch i32 undef, label %unreachable [
280    i32 0, label %for.inc
281    i32 4, label %for.inc
282  ]
283
284for.inc:
285; CHECK: for.inc:
286; CHECK-NEXT: phi i16 [ 0, %cleanup10.thread ], [ undef, %cleanup10 ]
287%0 = phi i16 [ undef, %cleanup10 ], [ 0, %cleanup10.thread ], [ undef, %cleanup10 ]
288  unreachable
289
290unreachable:
291  unreachable
292}
293