[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / WebAssembly / simd-reductions.ll
blob037cac514b03f30fc37fa555ea2c57ec6fa2645f
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 ; ==============================================================================
10 ; 16 x i8
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
23   ret i32 %c
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
34   ret i32 %c
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
45   ret i32 %c
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
56   ret i32 %c
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
67   ret i32 %c
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
78   ret i32 %c
81 ; ==============================================================================
82 ; 8 x i16
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
95   ret i32 %c
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
106   ret i32 %c
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
117   ret i32 %c
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
128   ret i32 %c
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
139   ret i32 %c
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
150   ret i32 %c
153 ; ==============================================================================
154 ; 4 x i32
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
167   ret i32 %c
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
178   ret i32 %c
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
189   ret i32 %c
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
200   ret i32 %c
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
211   ret i32 %c
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
222   ret i32 %c
225 ; ==============================================================================
226 ; 2 x i64
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
239   ret i32 %c
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
250   ret i32 %c
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
261   ret i32 %c
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
272   ret i32 %c
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
283   ret i32 %c
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
294   ret i32 %c