1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -disable-block-placement -verify-machineinstrs | FileCheck %s
2
3; Test switch instructions. Block placement is disabled because it reorders
4; the blocks in a way that isn't interesting here.
5
6target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
7target triple = "wasm32-unknown-unknown"
8
9declare void @foo0()
10declare void @foo1()
11declare void @foo2()
12declare void @foo3()
13declare void @foo4()
14declare void @foo5()
15
16; CHECK-LABEL: bar32:
17; CHECK: block   {{$}}
18; CHECK: block   {{$}}
19; CHECK: block   {{$}}
20; CHECK: block   {{$}}
21; CHECK: block   {{$}}
22; CHECK: block   {{$}}
23; CHECK: block   {{$}}
24; CHECK: br_table {{[^,]+}}, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 4, 5, 6{{$}}
25; CHECK: .LBB{{[0-9]+}}_1:
26; CHECK:   call foo0{{$}}
27; CHECK: .LBB{{[0-9]+}}_2:
28; CHECK:   call foo1{{$}}
29; CHECK: .LBB{{[0-9]+}}_3:
30; CHECK:   call foo2{{$}}
31; CHECK: .LBB{{[0-9]+}}_4:
32; CHECK:   call foo3{{$}}
33; CHECK: .LBB{{[0-9]+}}_5:
34; CHECK:   call foo4{{$}}
35; CHECK: .LBB{{[0-9]+}}_6:
36; CHECK:   call foo5{{$}}
37; CHECK: .LBB{{[0-9]+}}_7:
38; CHECK:   return{{$}}
39define void @bar32(i32 %n) {
40entry:
41  switch i32 %n, label %sw.epilog [
42    i32 0, label %sw.bb
43    i32 1, label %sw.bb
44    i32 2, label %sw.bb
45    i32 3, label %sw.bb
46    i32 4, label %sw.bb
47    i32 5, label %sw.bb
48    i32 6, label %sw.bb
49    i32 7, label %sw.bb.1
50    i32 8, label %sw.bb.1
51    i32 9, label %sw.bb.1
52    i32 10, label %sw.bb.1
53    i32 11, label %sw.bb.1
54    i32 12, label %sw.bb.1
55    i32 13, label %sw.bb.1
56    i32 14, label %sw.bb.1
57    i32 15, label %sw.bb.2
58    i32 16, label %sw.bb.2
59    i32 17, label %sw.bb.2
60    i32 18, label %sw.bb.2
61    i32 19, label %sw.bb.2
62    i32 20, label %sw.bb.2
63    i32 21, label %sw.bb.3
64    i32 22, label %sw.bb.4
65    i32 23, label %sw.bb.5
66  ]
67
68sw.bb:                                            ; preds = %entry, %entry, %entry, %entry, %entry, %entry, %entry
69  tail call void @foo0()
70  br label %sw.epilog
71
72sw.bb.1:                                          ; preds = %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry
73  tail call void @foo1()
74  br label %sw.epilog
75
76sw.bb.2:                                          ; preds = %entry, %entry, %entry, %entry, %entry, %entry
77  tail call void @foo2()
78  br label %sw.epilog
79
80sw.bb.3:                                          ; preds = %entry
81  tail call void @foo3()
82  br label %sw.epilog
83
84sw.bb.4:                                          ; preds = %entry
85  tail call void @foo4()
86  br label %sw.epilog
87
88sw.bb.5:                                          ; preds = %entry
89  tail call void @foo5()
90  br label %sw.epilog
91
92sw.epilog:                                        ; preds = %entry, %sw.bb.5, %sw.bb.4, %sw.bb.3, %sw.bb.2, %sw.bb.1, %sw.bb
93  ret void
94}
95
96; CHECK-LABEL: bar64:
97; CHECK: block   {{$}}
98; CHECK: i64.const
99; CHECK: i64.gt_u
100; CHECK: br_if 0
101; CHECK: block   {{$}}
102; CHECK: block   {{$}}
103; CHECK: block   {{$}}
104; CHECK: block   {{$}}
105; CHECK: block   {{$}}
106; CHECK: block   {{$}}
107; CHECK: i32.wrap_i64
108; CHECK: br_table {{[^,]+}}, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 4, 5, 0{{$}}
109; CHECK: .LBB{{[0-9]+}}_2:
110; CHECK:   call foo0{{$}}
111; CHECK: .LBB{{[0-9]+}}_3:
112; CHECK:   call foo1{{$}}
113; CHECK: .LBB{{[0-9]+}}_4:
114; CHECK:   call foo2{{$}}
115; CHECK: .LBB{{[0-9]+}}_5:
116; CHECK:   call foo3{{$}}
117; CHECK: .LBB{{[0-9]+}}_6:
118; CHECK:   call foo4{{$}}
119; CHECK: .LBB{{[0-9]+}}_7:
120; CHECK:   call foo5{{$}}
121; CHECK: .LBB{{[0-9]+}}_8:
122; CHECK:   return{{$}}
123define void @bar64(i64 %n) {
124entry:
125  switch i64 %n, label %sw.epilog [
126    i64 0, label %sw.bb
127    i64 1, label %sw.bb
128    i64 2, label %sw.bb
129    i64 3, label %sw.bb
130    i64 4, label %sw.bb
131    i64 5, label %sw.bb
132    i64 6, label %sw.bb
133    i64 7, label %sw.bb.1
134    i64 8, label %sw.bb.1
135    i64 9, label %sw.bb.1
136    i64 10, label %sw.bb.1
137    i64 11, label %sw.bb.1
138    i64 12, label %sw.bb.1
139    i64 13, label %sw.bb.1
140    i64 14, label %sw.bb.1
141    i64 15, label %sw.bb.2
142    i64 16, label %sw.bb.2
143    i64 17, label %sw.bb.2
144    i64 18, label %sw.bb.2
145    i64 19, label %sw.bb.2
146    i64 20, label %sw.bb.2
147    i64 21, label %sw.bb.3
148    i64 22, label %sw.bb.4
149    i64 23, label %sw.bb.5
150  ]
151
152sw.bb:                                            ; preds = %entry, %entry, %entry, %entry, %entry, %entry, %entry
153  tail call void @foo0()
154  br label %sw.epilog
155
156sw.bb.1:                                          ; preds = %entry, %entry, %entry, %entry, %entry, %entry, %entry, %entry
157  tail call void @foo1()
158  br label %sw.epilog
159
160sw.bb.2:                                          ; preds = %entry, %entry, %entry, %entry, %entry, %entry
161  tail call void @foo2()
162  br label %sw.epilog
163
164sw.bb.3:                                          ; preds = %entry
165  tail call void @foo3()
166  br label %sw.epilog
167
168sw.bb.4:                                          ; preds = %entry
169  tail call void @foo4()
170  br label %sw.epilog
171
172sw.bb.5:                                          ; preds = %entry
173  tail call void @foo5()
174  br label %sw.epilog
175
176sw.epilog:                                        ; preds = %entry, %sw.bb.5, %sw.bb.4, %sw.bb.3, %sw.bb.2, %sw.bb.1, %sw.bb
177  ret void
178}
179
180; CHECK-LABEL: truncated:
181; CHECK:   block
182; CHECK:   block
183; CHECK:   block
184; CHECK:   i32.wrap_i64
185; CHECK:   br_table {{[^,]+}}, 0, 1, 2{{$}}
186; CHECK: .LBB{{[0-9]+}}_1
187; CHECK:   end_block
188; CHECK:   call foo0{{$}}
189; CHECK:   return{{$}}
190; CHECK: .LBB{{[0-9]+}}_2
191; CHECK:   end_block
192; CHECK:   call foo1{{$}}
193; CHECK:   return{{$}}
194; CHECK: .LBB{{[0-9]+}}_3
195; CHECK:   end_block
196; CHECK:   call foo2{{$}}
197; CHECK:   return{{$}}
198; CHECK:   end_function
199define void @truncated(i64 %n) {
200entry:
201  %m = trunc i64 %n to i32
202  switch i32 %m, label %default [
203    i32 0, label %bb1
204    i32 1, label %bb2
205  ]
206
207bb1:
208  tail call void @foo0()
209  ret void
210
211bb2:
212  tail call void @foo1()
213  ret void
214
215default:
216  tail call void @foo2()
217  ret void
218}
219