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