1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefixes CHECK,SLOW
2; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -fast-isel -fast-isel-abort=1 | FileCheck %s
3
4; Test that wasm select instruction is selected from LLVM select instruction.
5
6target triple = "wasm32-unknown-unknown"
7
8; CHECK-LABEL: select_i32_bool:
9; CHECK-NEXT: .functype select_i32_bool (i32, i32, i32) -> (i32){{$}}
10; CHECK-NEXT: i32.select $push0=, $1, $2, $0{{$}}
11; CHECK-NEXT: return     $pop0{{$}}
12define i32 @select_i32_bool(i1 zeroext %a, i32 %b, i32 %c) {
13  %cond = select i1 %a, i32 %b, i32 %c
14  ret i32 %cond
15}
16
17; CHECK-LABEL: select_i32_bool_nozext:
18; CHECK-NEXT: .functype select_i32_bool_nozext (i32, i32, i32) -> (i32){{$}}
19; CHECK-NEXT: i32.const  $push0=, 1{{$}}
20; CHECK-NEXT: i32.and    $push1=, $0, $pop0{{$}}
21; CHECK-NEXT: i32.select $push2=, $1, $2, $pop1{{$}}
22; CHECK-NEXT: return     $pop2{{$}}
23define i32 @select_i32_bool_nozext(i1 %a, i32 %b, i32 %c) {
24  %cond = select i1 %a, i32 %b, i32 %c
25  ret i32 %cond
26}
27
28; CHECK-LABEL: select_i32_eq:
29; CHECK-NEXT: .functype select_i32_eq (i32, i32, i32) -> (i32){{$}}
30; CHECK-NEXT: i32.select $push0=, $2, $1, $0{{$}}
31; CHECK-NEXT: return     $pop0{{$}}
32define i32 @select_i32_eq(i32 %a, i32 %b, i32 %c) {
33  %cmp = icmp eq i32 %a, 0
34  %cond = select i1 %cmp, i32 %b, i32 %c
35  ret i32 %cond
36}
37
38; CHECK-LABEL: select_i32_ne:
39; CHECK-NEXT: .functype select_i32_ne (i32, i32, i32) -> (i32){{$}}
40; CHECK-NEXT: i32.select $push0=, $1, $2, $0{{$}}
41; CHECK-NEXT: return     $pop0{{$}}
42define i32 @select_i32_ne(i32 %a, i32 %b, i32 %c) {
43  %cmp = icmp ne i32 %a, 0
44  %cond = select i1 %cmp, i32 %b, i32 %c
45  ret i32 %cond
46}
47
48; CHECK-LABEL: select_i64_bool:
49; CHECK-NEXT: .functype select_i64_bool (i32, i64, i64) -> (i64){{$}}
50; CHECK-NEXT: i64.select $push0=, $1, $2, $0{{$}}
51; CHECK-NEXT: return     $pop0{{$}}
52define i64 @select_i64_bool(i1 zeroext %a, i64 %b, i64 %c) {
53  %cond = select i1 %a, i64 %b, i64 %c
54  ret i64 %cond
55}
56
57; CHECK-LABEL: select_i64_bool_nozext:
58; CHECK-NEXT: .functype select_i64_bool_nozext (i32, i64, i64) -> (i64){{$}}
59; CHECK-NEXT: i32.const  $push0=, 1{{$}}
60; CHECK-NEXT: i32.and    $push1=, $0, $pop0{{$}}
61; CHECK-NEXT: i64.select $push2=, $1, $2, $pop1{{$}}
62; CHECK-NEXT: return     $pop2{{$}}
63define i64 @select_i64_bool_nozext(i1 %a, i64 %b, i64 %c) {
64  %cond = select i1 %a, i64 %b, i64 %c
65  ret i64 %cond
66}
67
68; CHECK-LABEL: select_i64_eq:
69; CHECK-NEXT: .functype select_i64_eq (i32, i64, i64) -> (i64){{$}}
70; CHECK-NEXT: i64.select $push0=, $2, $1, $0{{$}}
71; CHECK-NEXT: return     $pop0{{$}}
72define i64 @select_i64_eq(i32 %a, i64 %b, i64 %c) {
73  %cmp = icmp eq i32 %a, 0
74  %cond = select i1 %cmp, i64 %b, i64 %c
75  ret i64 %cond
76}
77
78; CHECK-LABEL: select_i64_ne:
79; CHECK-NEXT: .functype select_i64_ne (i32, i64, i64) -> (i64){{$}}
80; CHECK-NEXT: i64.select $push0=, $1, $2, $0{{$}}
81; CHECK-NEXT: return     $pop0{{$}}
82define i64 @select_i64_ne(i32 %a, i64 %b, i64 %c) {
83  %cmp = icmp ne i32 %a, 0
84  %cond = select i1 %cmp, i64 %b, i64 %c
85  ret i64 %cond
86}
87
88; CHECK-LABEL: select_f32_bool:
89; CHECK-NEXT: .functype select_f32_bool (i32, f32, f32) -> (f32){{$}}
90; CHECK-NEXT: f32.select $push0=, $1, $2, $0{{$}}
91; CHECK-NEXT: return     $pop0{{$}}
92define float @select_f32_bool(i1 zeroext %a, float %b, float %c) {
93  %cond = select i1 %a, float %b, float %c
94  ret float %cond
95}
96
97; CHECK-LABEL: select_f32_bool_nozext:
98; CHECK-NEXT: .functype select_f32_bool_nozext (i32, f32, f32) -> (f32){{$}}
99; CHECK-NEXT: i32.const  $push0=, 1{{$}}
100; CHECK-NEXT: i32.and    $push1=, $0, $pop0{{$}}
101; CHECK-NEXT: f32.select $push2=, $1, $2, $pop1{{$}}
102; CHECK-NEXT: return     $pop2{{$}}
103define float @select_f32_bool_nozext(i1 %a, float %b, float %c) {
104  %cond = select i1 %a, float %b, float %c
105  ret float %cond
106}
107
108; CHECK-LABEL: select_f32_eq:
109; CHECK-NEXT: .functype select_f32_eq (i32, f32, f32) -> (f32){{$}}
110; CHECK-NEXT: f32.select $push0=, $2, $1, $0{{$}}
111; CHECK-NEXT: return     $pop0{{$}}
112define float @select_f32_eq(i32 %a, float %b, float %c) {
113  %cmp = icmp eq i32 %a, 0
114  %cond = select i1 %cmp, float %b, float %c
115  ret float %cond
116}
117
118; CHECK-LABEL: select_f32_ne:
119; CHECK-NEXT: .functype select_f32_ne (i32, f32, f32) -> (f32){{$}}
120; CHECK-NEXT: f32.select $push0=, $1, $2, $0{{$}}
121; CHECK-NEXT: return     $pop0{{$}}
122define float @select_f32_ne(i32 %a, float %b, float %c) {
123  %cmp = icmp ne i32 %a, 0
124  %cond = select i1 %cmp, float %b, float %c
125  ret float %cond
126}
127
128; CHECK-LABEL: select_f64_bool:
129; CHECK-NEXT: .functype select_f64_bool (i32, f64, f64) -> (f64){{$}}
130; CHECK-NEXT: f64.select $push0=, $1, $2, $0{{$}}
131; CHECK-NEXT: return     $pop0{{$}}
132define double @select_f64_bool(i1 zeroext %a, double %b, double %c) {
133  %cond = select i1 %a, double %b, double %c
134  ret double %cond
135}
136
137; CHECK-LABEL: select_f64_bool_nozext:
138; CHECK-NEXT: .functype select_f64_bool_nozext (i32, f64, f64) -> (f64){{$}}
139; CHECK-NEXT: i32.const  $push0=, 1{{$}}
140; CHECK-NEXT: i32.and    $push1=, $0, $pop0{{$}}
141; CHECK-NEXT: f64.select $push2=, $1, $2, $pop1{{$}}
142; CHECK-NEXT: return     $pop2{{$}}
143define double @select_f64_bool_nozext(i1 %a, double %b, double %c) {
144  %cond = select i1 %a, double %b, double %c
145  ret double %cond
146}
147
148; CHECK-LABEL: select_f64_eq:
149; CHECK-NEXT: .functype select_f64_eq (i32, f64, f64) -> (f64){{$}}
150; CHECK-NEXT: f64.select $push0=, $2, $1, $0{{$}}
151; CHECK-NEXT: return     $pop0{{$}}
152define double @select_f64_eq(i32 %a, double %b, double %c) {
153  %cmp = icmp eq i32 %a, 0
154  %cond = select i1 %cmp, double %b, double %c
155  ret double %cond
156}
157
158; CHECK-LABEL: select_f64_ne:
159; CHECK-NEXT: .functype select_f64_ne (i32, f64, f64) -> (f64){{$}}
160; CHECK-NEXT: f64.select $push0=, $1, $2, $0{{$}}
161; CHECK-NEXT: return     $pop0{{$}}
162define double @select_f64_ne(i32 %a, double %b, double %c) {
163  %cmp = icmp ne i32 %a, 0
164  %cond = select i1 %cmp, double %b, double %c
165  ret double %cond
166}
167
168; CHECK-LABEL: pr40805_i32:
169; CHECK-NEXT: .functype pr40805_i32 (i32, i32, i32) -> (i32){{$}}
170; SLOW-NEXT: i32.const  $push0=, 1{{$}}
171; SLOW-NEXT: i32.and    $push1=, $0, $pop0{{$}}
172; SLOW-NEXT: i32.select $push2=, $1, $2, $pop1{{$}}
173; SLOW-NEXT: return     $pop2{{$}}
174define i32 @pr40805_i32(i32 %x, i32 %y, i32 %z) {
175  %a = and i32 %x, 1
176  %b = icmp ne i32 %a, 0
177  %c = select i1 %b, i32 %y, i32 %z
178  ret i32 %c
179}
180
181; CHECK-LABEL: pr40805_i64:
182; CHECK-NEXT: .functype pr40805_i64 (i64, i64, i64) -> (i64){{$}}
183; SLOW-NEXT: i32.wrap_i64 $push0=, $0{{$}}
184; SLOW-NEXT: i32.const  $push1=, 1{{$}}
185; SLOW-NEXT: i32.and    $push2=, $pop0, $pop1{{$}}
186; SLOW-NEXT: i64.select $push3=, $1, $2, $pop2{{$}}
187; SLOW-NEXT: return     $pop3{{$}}
188define i64 @pr40805_i64(i64 %x, i64 %y, i64 %z) {
189  %a = and i64 %x, 1
190  %b = icmp ne i64 %a, 0
191  %c = select i1 %b, i64 %y, i64 %z
192  ret i64 %c
193}
194
195; CHECK-LABEL: pr44012_i32:
196; CHECK-NEXT: .functype pr44012_i32 (i32, f32, f32) -> (f32){{$}}
197; SLOW-NEXT: i32.const  $push0=, 1{{$}}
198; SLOW-NEXT: i32.and    $push1=, $0, $pop0{{$}}
199; SLOW-NEXT: f32.select $push2=, $1, $2, $pop1{{$}}
200; SLOW-NEXT: return     $pop2{{$}}
201define float @pr44012_i32(i32 %x, float %y, float %z) {
202  %a = and i32 %x, 1
203  %b = icmp ne i32 %a, 0
204  %c = select i1 %b, float %y, float %z
205  ret float %c
206}
207
208; CHECK-LABEL: pr44012_i64:
209; CHECK-NEXT: .functype pr44012_i64 (i64, f32, f32) -> (f32){{$}}
210; SLOW-NEXT: i32.wrap_i64 $push0=, $0{{$}}
211; SLOW-NEXT: i32.const  $push1=, 1{{$}}
212; SLOW-NEXT: i32.and    $push2=, $pop0, $pop1{{$}}
213; SLOW-NEXT: f32.select $push3=, $1, $2, $pop2{{$}}
214; SLOW-NEXT: return     $pop3{{$}}
215define float @pr44012_i64(i64 %x, float %y, float %z) {
216  %a = and i64 %x, 1
217  %b = icmp ne i64 %a, 0
218  %c = select i1 %b, float %y, float %z
219  ret float %c
220}
221