1 ; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s
3 ; Tests that redundant masking and conversions are folded out
4 ; following SIMD reduction instructions.
6 target triple = "wasm32-unknown-unknown"
8 ; ==============================================================================
10 ; ==============================================================================
11 declare i32 @llvm.wasm.anytrue.v16i8(<16 x i8>)
12 declare i32 @llvm.wasm.alltrue.v16i8(<16 x i8>)
14 ; CHECK-LABEL: any_v16i8_trunc:
15 ; CHECK-NEXT: .functype any_v16i8_trunc (v128) -> (i32){{$}}
16 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
17 ; CHECK-NEXT: return $pop[[R]]{{$}}
18 define i32 @any_v16i8_trunc(<16 x i8> %x) {
19 %a = call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x)
20 %b = trunc i32 %a to i1
21 %c = zext i1 %b to i32
25 ; CHECK-LABEL: any_v16i8_ne:
26 ; CHECK-NEXT: .functype any_v16i8_ne (v128) -> (i32){{$}}
27 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
28 ; CHECK-NEXT: return $pop[[R]]{{$}}
29 define i32 @any_v16i8_ne(<16 x i8> %x) {
30 %a = call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x)
31 %b = icmp ne i32 %a, 0
32 %c = zext i1 %b to i32
36 ; CHECK-LABEL: any_v16i8_eq:
37 ; CHECK-NEXT: .functype any_v16i8_eq (v128) -> (i32){{$}}
38 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
39 ; CHECK-NEXT: return $pop[[R]]{{$}}
40 define i32 @any_v16i8_eq(<16 x i8> %x) {
41 %a = call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x)
42 %b = icmp eq i32 %a, 1
43 %c = zext i1 %b to i32
47 ; CHECK-LABEL: all_v16i8_trunc:
48 ; CHECK-NEXT: .functype all_v16i8_trunc (v128) -> (i32){{$}}
49 ; CHECK-NEXT: i8x16.all_true $push[[R:[0-9]+]]=, $0{{$}}
50 ; CHECK-NEXT: return $pop[[R]]{{$}}
51 define i32 @all_v16i8_trunc(<16 x i8> %x) {
52 %a = call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> %x)
53 %b = trunc i32 %a to i1
54 %c = zext i1 %b to i32
58 ; CHECK-LABEL: all_v16i8_ne:
59 ; CHECK-NEXT: .functype all_v16i8_ne (v128) -> (i32){{$}}
60 ; CHECK-NEXT: i8x16.all_true $push[[R:[0-9]+]]=, $0{{$}}
61 ; CHECK-NEXT: return $pop[[R]]{{$}}
62 define i32 @all_v16i8_ne(<16 x i8> %x) {
63 %a = call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> %x)
64 %b = icmp ne i32 %a, 0
65 %c = zext i1 %b to i32
69 ; CHECK-LABEL: all_v16i8_eq:
70 ; CHECK-NEXT: .functype all_v16i8_eq (v128) -> (i32){{$}}
71 ; CHECK-NEXT: i8x16.all_true $push[[R:[0-9]+]]=, $0{{$}}
72 ; CHECK-NEXT: return $pop[[R]]{{$}}
73 define i32 @all_v16i8_eq(<16 x i8> %x) {
74 %a = call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> %x)
75 %b = icmp eq i32 %a, 1
76 %c = zext i1 %b to i32
80 ; ==============================================================================
82 ; ==============================================================================
83 declare i32 @llvm.wasm.anytrue.v8i16(<8 x i16>)
84 declare i32 @llvm.wasm.alltrue.v8i16(<8 x i16>)
86 ; CHECK-LABEL: any_v8i16_trunc:
87 ; CHECK-NEXT: .functype any_v8i16_trunc (v128) -> (i32){{$}}
88 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
89 ; CHECK-NEXT: return $pop[[R]]{{$}}
90 define i32 @any_v8i16_trunc(<8 x i16> %x) {
91 %a = call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> %x)
92 %b = trunc i32 %a to i1
93 %c = zext i1 %b to i32
97 ; CHECK-LABEL: any_v8i16_ne:
98 ; CHECK-NEXT: .functype any_v8i16_ne (v128) -> (i32){{$}}
99 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
100 ; CHECK-NEXT: return $pop[[R]]{{$}}
101 define i32 @any_v8i16_ne(<8 x i16> %x) {
102 %a = call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> %x)
103 %b = icmp ne i32 %a, 0
104 %c = zext i1 %b to i32
108 ; CHECK-LABEL: any_v8i16_eq:
109 ; CHECK-NEXT: .functype any_v8i16_eq (v128) -> (i32){{$}}
110 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
111 ; CHECK-NEXT: return $pop[[R]]{{$}}
112 define i32 @any_v8i16_eq(<8 x i16> %x) {
113 %a = call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> %x)
114 %b = icmp eq i32 %a, 1
115 %c = zext i1 %b to i32
119 ; CHECK-LABEL: all_v8i16_trunc:
120 ; CHECK-NEXT: .functype all_v8i16_trunc (v128) -> (i32){{$}}
121 ; CHECK-NEXT: i16x8.all_true $push[[R:[0-9]+]]=, $0{{$}}
122 ; CHECK-NEXT: return $pop[[R]]{{$}}
123 define i32 @all_v8i16_trunc(<8 x i16> %x) {
124 %a = call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> %x)
125 %b = trunc i32 %a to i1
126 %c = zext i1 %b to i32
130 ; CHECK-LABEL: all_v8i16_ne:
131 ; CHECK-NEXT: .functype all_v8i16_ne (v128) -> (i32){{$}}
132 ; CHECK-NEXT: i16x8.all_true $push[[R:[0-9]+]]=, $0{{$}}
133 ; CHECK-NEXT: return $pop[[R]]{{$}}
134 define i32 @all_v8i16_ne(<8 x i16> %x) {
135 %a = call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> %x)
136 %b = icmp ne i32 %a, 0
137 %c = zext i1 %b to i32
141 ; CHECK-LABEL: all_v8i16_eq:
142 ; CHECK-NEXT: .functype all_v8i16_eq (v128) -> (i32){{$}}
143 ; CHECK-NEXT: i16x8.all_true $push[[R:[0-9]+]]=, $0{{$}}
144 ; CHECK-NEXT: return $pop[[R]]{{$}}
145 define i32 @all_v8i16_eq(<8 x i16> %x) {
146 %a = call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> %x)
147 %b = icmp eq i32 %a, 1
148 %c = zext i1 %b to i32
152 ; ==============================================================================
154 ; ==============================================================================
155 declare i32 @llvm.wasm.anytrue.v4i32(<4 x i32>)
156 declare i32 @llvm.wasm.alltrue.v4i32(<4 x i32>)
158 ; CHECK-LABEL: any_v4i32_trunc:
159 ; CHECK-NEXT: .functype any_v4i32_trunc (v128) -> (i32){{$}}
160 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
161 ; CHECK-NEXT: return $pop[[R]]{{$}}
162 define i32 @any_v4i32_trunc(<4 x i32> %x) {
163 %a = call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> %x)
164 %b = trunc i32 %a to i1
165 %c = zext i1 %b to i32
169 ; CHECK-LABEL: any_v4i32_ne:
170 ; CHECK-NEXT: .functype any_v4i32_ne (v128) -> (i32){{$}}
171 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
172 ; CHECK-NEXT: return $pop[[R]]{{$}}
173 define i32 @any_v4i32_ne(<4 x i32> %x) {
174 %a = call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> %x)
175 %b = icmp ne i32 %a, 0
176 %c = zext i1 %b to i32
180 ; CHECK-LABEL: any_v4i32_eq:
181 ; CHECK-NEXT: .functype any_v4i32_eq (v128) -> (i32){{$}}
182 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
183 ; CHECK-NEXT: return $pop[[R]]{{$}}
184 define i32 @any_v4i32_eq(<4 x i32> %x) {
185 %a = call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> %x)
186 %b = icmp eq i32 %a, 1
187 %c = zext i1 %b to i32
191 ; CHECK-LABEL: all_v4i32_trunc:
192 ; CHECK-NEXT: .functype all_v4i32_trunc (v128) -> (i32){{$}}
193 ; CHECK-NEXT: i32x4.all_true $push[[R:[0-9]+]]=, $0{{$}}
194 ; CHECK-NEXT: return $pop[[R]]{{$}}
195 define i32 @all_v4i32_trunc(<4 x i32> %x) {
196 %a = call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> %x)
197 %b = trunc i32 %a to i1
198 %c = zext i1 %b to i32
202 ; CHECK-LABEL: all_v4i32_ne:
203 ; CHECK-NEXT: .functype all_v4i32_ne (v128) -> (i32){{$}}
204 ; CHECK-NEXT: i32x4.all_true $push[[R:[0-9]+]]=, $0{{$}}
205 ; CHECK-NEXT: return $pop[[R]]{{$}}
206 define i32 @all_v4i32_ne(<4 x i32> %x) {
207 %a = call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> %x)
208 %b = icmp ne i32 %a, 0
209 %c = zext i1 %b to i32
213 ; CHECK-LABEL: all_v4i32_eq:
214 ; CHECK-NEXT: .functype all_v4i32_eq (v128) -> (i32){{$}}
215 ; CHECK-NEXT: i32x4.all_true $push[[R:[0-9]+]]=, $0{{$}}
216 ; CHECK-NEXT: return $pop[[R]]{{$}}
217 define i32 @all_v4i32_eq(<4 x i32> %x) {
218 %a = call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> %x)
219 %b = icmp eq i32 %a, 1
220 %c = zext i1 %b to i32
224 ; ==============================================================================
226 ; ==============================================================================
227 declare i32 @llvm.wasm.anytrue.v2i64(<2 x i64>)
228 declare i32 @llvm.wasm.alltrue.v2i64(<2 x i64>)
230 ; CHECK-LABEL: any_v2i64_trunc:
231 ; CHECK-NEXT: .functype any_v2i64_trunc (v128) -> (i32){{$}}
232 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
233 ; CHECK-NEXT: return $pop[[R]]{{$}}
234 define i32 @any_v2i64_trunc(<2 x i64> %x) {
235 %a = call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> %x)
236 %b = trunc i32 %a to i1
237 %c = zext i1 %b to i32
241 ; CHECK-LABEL: any_v2i64_ne:
242 ; CHECK-NEXT: .functype any_v2i64_ne (v128) -> (i32){{$}}
243 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
244 ; CHECK-NEXT: return $pop[[R]]{{$}}
245 define i32 @any_v2i64_ne(<2 x i64> %x) {
246 %a = call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> %x)
247 %b = icmp ne i32 %a, 0
248 %c = zext i1 %b to i32
252 ; CHECK-LABEL: any_v2i64_eq:
253 ; CHECK-NEXT: .functype any_v2i64_eq (v128) -> (i32){{$}}
254 ; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}}
255 ; CHECK-NEXT: return $pop[[R]]{{$}}
256 define i32 @any_v2i64_eq(<2 x i64> %x) {
257 %a = call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> %x)
258 %b = icmp eq i32 %a, 1
259 %c = zext i1 %b to i32
263 ; CHECK-LABEL: all_v2i64_trunc:
264 ; CHECK-NEXT: .functype all_v2i64_trunc (v128) -> (i32){{$}}
265 ; CHECK-NEXT: i64x2.all_true $push[[R:[0-9]+]]=, $0{{$}}
266 ; CHECK-NEXT: return $pop[[R]]{{$}}
267 define i32 @all_v2i64_trunc(<2 x i64> %x) {
268 %a = call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> %x)
269 %b = trunc i32 %a to i1
270 %c = zext i1 %b to i32
274 ; CHECK-LABEL: all_v2i64_ne:
275 ; CHECK-NEXT: .functype all_v2i64_ne (v128) -> (i32){{$}}
276 ; CHECK-NEXT: i64x2.all_true $push[[R:[0-9]+]]=, $0{{$}}
277 ; CHECK-NEXT: return $pop[[R]]{{$}}
278 define i32 @all_v2i64_ne(<2 x i64> %x) {
279 %a = call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> %x)
280 %b = icmp ne i32 %a, 0
281 %c = zext i1 %b to i32
285 ; CHECK-LABEL: all_v2i64_eq:
286 ; CHECK-NEXT: .functype all_v2i64_eq (v128) -> (i32){{$}}
287 ; CHECK-NEXT: i64x2.all_true $push[[R:[0-9]+]]=, $0{{$}}
288 ; CHECK-NEXT: return $pop[[R]]{{$}}
289 define i32 @all_v2i64_eq(<2 x i64> %x) {
290 %a = call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> %x)
291 %b = icmp eq i32 %a, 1
292 %c = zext i1 %b to i32