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