[Instrumentation] Fix a warning
[llvm-project.git] / llvm / test / CodeGen / AArch64 / qmovn.ll
blob2685ea9fb5d202daf6fc15295dccd3516bb3b809
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-none-elf -verify-machineinstrs %s -o - | FileCheck %s
4 define <4 x i16> @vqmovni32_smaxmin(<4 x i32> %s0) {
5 ; CHECK-LABEL: vqmovni32_smaxmin:
6 ; CHECK:       // %bb.0: // %entry
7 ; CHECK-NEXT:    sqxtn v0.4h, v0.4s
8 ; CHECK-NEXT:    ret
9 entry:
10   %c1 = icmp slt <4 x i32> %s0, <i32 32767, i32 32767, i32 32767, i32 32767>
11   %s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>
12   %c2 = icmp sgt <4 x i32> %s1, <i32 -32768, i32 -32768, i32 -32768, i32 -32768>
13   %s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>
14   %t = trunc <4 x i32> %s2 to <4 x i16>
15   ret <4 x i16> %t
18 define <4 x i16> @vqmovni32_sminmax(<4 x i32> %s0) {
19 ; CHECK-LABEL: vqmovni32_sminmax:
20 ; CHECK:       // %bb.0: // %entry
21 ; CHECK-NEXT:    sqxtn v0.4h, v0.4s
22 ; CHECK-NEXT:    ret
23 entry:
24   %c1 = icmp sgt <4 x i32> %s0, <i32 -32768, i32 -32768, i32 -32768, i32 -32768>
25   %s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>
26   %c2 = icmp slt <4 x i32> %s1, <i32 32767, i32 32767, i32 32767, i32 32767>
27   %s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>
28   %t = trunc <4 x i32> %s2 to <4 x i16>
29   ret <4 x i16> %t
32 define <4 x i16> @vqmovni32_umaxmin(<4 x i32> %s0) {
33 ; CHECK-LABEL: vqmovni32_umaxmin:
34 ; CHECK:       // %bb.0: // %entry
35 ; CHECK-NEXT:    uqxtn v0.4h, v0.4s
36 ; CHECK-NEXT:    ret
37 entry:
38   %c1 = icmp ult <4 x i32> %s0, <i32 65535, i32 65535, i32 65535, i32 65535>
39   %s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>
40   %t = trunc <4 x i32> %s1 to <4 x i16>
41   ret <4 x i16> %t
44 define <8 x i8> @vqmovni16_smaxmin(<8 x i16> %s0) {
45 ; CHECK-LABEL: vqmovni16_smaxmin:
46 ; CHECK:       // %bb.0: // %entry
47 ; CHECK-NEXT:    sqxtn v0.8b, v0.8h
48 ; CHECK-NEXT:    ret
49 entry:
50   %c1 = icmp slt <8 x i16> %s0, <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>
51   %s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>
52   %c2 = icmp sgt <8 x i16> %s1, <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>
53   %s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>
54   %t = trunc <8 x i16> %s2 to <8 x i8>
55   ret <8 x i8> %t
58 define <8 x i8> @vqmovni16_sminmax(<8 x i16> %s0) {
59 ; CHECK-LABEL: vqmovni16_sminmax:
60 ; CHECK:       // %bb.0: // %entry
61 ; CHECK-NEXT:    sqxtn v0.8b, v0.8h
62 ; CHECK-NEXT:    ret
63 entry:
64   %c1 = icmp sgt <8 x i16> %s0, <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>
65   %s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>
66   %c2 = icmp slt <8 x i16> %s1, <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>
67   %s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>
68   %t = trunc <8 x i16> %s2 to <8 x i8>
69   ret <8 x i8> %t
72 define <8 x i8> @vqmovni16_umaxmin(<8 x i16> %s0) {
73 ; CHECK-LABEL: vqmovni16_umaxmin:
74 ; CHECK:       // %bb.0: // %entry
75 ; CHECK-NEXT:    uqxtn v0.8b, v0.8h
76 ; CHECK-NEXT:    ret
77 entry:
78   %c1 = icmp ult <8 x i16> %s0, <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
79   %s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
80   %t = trunc <8 x i16> %s1 to <8 x i8>
81   ret <8 x i8> %t
84 define <2 x i32> @vqmovni64_smaxmin(<2 x i64> %s0) {
85 ; CHECK-LABEL: vqmovni64_smaxmin:
86 ; CHECK:       // %bb.0: // %entry
87 ; CHECK-NEXT:    sqxtn v0.2s, v0.2d
88 ; CHECK-NEXT:    ret
89 entry:
90   %c1 = icmp slt <2 x i64> %s0, <i64 2147483647, i64 2147483647>
91   %s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 2147483647, i64 2147483647>
92   %c2 = icmp sgt <2 x i64> %s1, <i64 -2147483648, i64 -2147483648>
93   %s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> <i64 -2147483648, i64 -2147483648>
94   %t = trunc <2 x i64> %s2 to <2 x i32>
95   ret <2 x i32> %t
98 define <2 x i32> @vqmovni64_sminmax(<2 x i64> %s0) {
99 ; CHECK-LABEL: vqmovni64_sminmax:
100 ; CHECK:       // %bb.0: // %entry
101 ; CHECK-NEXT:    sqxtn v0.2s, v0.2d
102 ; CHECK-NEXT:    ret
103 entry:
104   %c1 = icmp sgt <2 x i64> %s0, <i64 -2147483648, i64 -2147483648>
105   %s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 -2147483648, i64 -2147483648>
106   %c2 = icmp slt <2 x i64> %s1, <i64 2147483647, i64 2147483647>
107   %s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> <i64 2147483647, i64 2147483647>
108   %t = trunc <2 x i64> %s2 to <2 x i32>
109   ret <2 x i32> %t
112 define <2 x i32> @vqmovni64_smaxmin_u(<2 x i64> %s0) {
113 ; CHECK-LABEL: vqmovni64_smaxmin_u:
114 ; CHECK:       // %bb.0: // %entry
115 ; CHECK-NEXT:    sqxtun v0.2s, v0.2d
116 ; CHECK-NEXT:    ret
117 entry:
118   %c1 = icmp slt <2 x i64> %s0, <i64 4294967295, i64 4294967295>
119   %s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 4294967295, i64 4294967295>
120   %c2 = icmp sgt <2 x i64> %s1, zeroinitializer
121   %s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> zeroinitializer
122   %t = trunc <2 x i64> %s2 to <2 x i32>
123   ret <2 x i32> %t
126 define <2 x i32> @vqmovni64_sminmax_u(<2 x i64> %s0) {
127 ; CHECK-LABEL: vqmovni64_sminmax_u:
128 ; CHECK:       // %bb.0: // %entry
129 ; CHECK-NEXT:    sqxtun v0.2s, v0.2d
130 ; CHECK-NEXT:    ret
131 entry:
132   %c1 = icmp sgt <2 x i64> %s0, zeroinitializer
133   %s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> zeroinitializer
134   %c2 = icmp slt <2 x i64> %s1, <i64 4294967295, i64 4294967295>
135   %s2 = select <2 x i1> %c2, <2 x i64> %s1, <2 x i64> <i64 4294967295, i64 4294967295>
136   %t = trunc <2 x i64> %s2 to <2 x i32>
137   ret <2 x i32> %t
140 define <4 x i16> @vqmovni32_smaxmin_u(<4 x i32> %s0) {
141 ; CHECK-LABEL: vqmovni32_smaxmin_u:
142 ; CHECK:       // %bb.0: // %entry
143 ; CHECK-NEXT:    sqxtun v0.4h, v0.4s
144 ; CHECK-NEXT:    ret
145 entry:
146   %c1 = icmp slt <4 x i32> %s0, <i32 65535, i32 65535, i32 65535, i32 65535>
147   %s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>
148   %c2 = icmp sgt <4 x i32> %s1, zeroinitializer
149   %s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> zeroinitializer
150   %t = trunc <4 x i32> %s2 to <4 x i16>
151   ret <4 x i16> %t
154 define <4 x i16> @vqmovni32_sminmax_u(<4 x i32> %s0) {
155 ; CHECK-LABEL: vqmovni32_sminmax_u:
156 ; CHECK:       // %bb.0: // %entry
157 ; CHECK-NEXT:    sqxtun v0.4h, v0.4s
158 ; CHECK-NEXT:    ret
159 entry:
160   %c1 = icmp sgt <4 x i32> %s0, zeroinitializer
161   %s1 = select <4 x i1> %c1, <4 x i32> %s0, <4 x i32> zeroinitializer
162   %c2 = icmp slt <4 x i32> %s1, <i32 65535, i32 65535, i32 65535, i32 65535>
163   %s2 = select <4 x i1> %c2, <4 x i32> %s1, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>
164   %t = trunc <4 x i32> %s2 to <4 x i16>
165   ret <4 x i16> %t
168 define <8 x i8> @vqmovni16_smaxmin_u(<8 x i16> %s0) {
169 ; CHECK-LABEL: vqmovni16_smaxmin_u:
170 ; CHECK:       // %bb.0: // %entry
171 ; CHECK-NEXT:    sqxtun v0.8b, v0.8h
172 ; CHECK-NEXT:    ret
173 entry:
174   %c1 = icmp slt <8 x i16> %s0, <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
175   %s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
176   %c2 = icmp sgt <8 x i16> %s1, zeroinitializer
177   %s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> zeroinitializer
178   %t = trunc <8 x i16> %s2 to <8 x i8>
179   ret <8 x i8> %t
182 define <8 x i8> @vqmovni16_sminmax_u(<8 x i16> %s0) {
183 ; CHECK-LABEL: vqmovni16_sminmax_u:
184 ; CHECK:       // %bb.0: // %entry
185 ; CHECK-NEXT:    sqxtun v0.8b, v0.8h
186 ; CHECK-NEXT:    ret
187 entry:
188   %c1 = icmp sgt <8 x i16> %s0, zeroinitializer
189   %s1 = select <8 x i1> %c1, <8 x i16> %s0, <8 x i16> zeroinitializer
190   %c2 = icmp slt <8 x i16> %s1, <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
191   %s2 = select <8 x i1> %c2, <8 x i16> %s1, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>
192   %t = trunc <8 x i16> %s2 to <8 x i8>
193   ret <8 x i8> %t
196 define <2 x i32> @vqmovni64_umaxmin(<2 x i64> %s0) {
197 ; CHECK-LABEL: vqmovni64_umaxmin:
198 ; CHECK:       // %bb.0: // %entry
199 ; CHECK-NEXT:    uqxtn v0.2s, v0.2d
200 ; CHECK-NEXT:    ret
201 entry:
202   %c1 = icmp ult <2 x i64> %s0, <i64 4294967295, i64 4294967295>
203   %s1 = select <2 x i1> %c1, <2 x i64> %s0, <2 x i64> <i64 4294967295, i64 4294967295>
204   %t = trunc <2 x i64> %s1 to <2 x i32>
205   ret <2 x i32> %t
208 ; Test the (concat_vectors (X), (trunc(smin(smax(Y, -2^n), 2^n-1))) pattern.
210 define <16 x i8> @signed_minmax_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {
211 ; CHECK-LABEL: signed_minmax_v8i16_to_v16i8:
212 ; CHECK:       // %bb.0: // %entry
213 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
214 ; CHECK-NEXT:    sqxtn2 v0.16b, v1.8h
215 ; CHECK-NEXT:    ret
216 entry:
217   %min = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %y, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>)
218   %max = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %min, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>)
219   %trunc = trunc <8 x i16> %max to <8 x i8>
220   %shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
221   ret <16 x i8> %shuffle
224 define <8 x i16> @signed_minmax_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {
225 ; CHECK-LABEL: signed_minmax_v4i32_to_v8i16:
226 ; CHECK:       // %bb.0: // %entry
227 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
228 ; CHECK-NEXT:    sqxtn2 v0.8h, v1.4s
229 ; CHECK-NEXT:    ret
230 entry:
231   %min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %y, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>)
232   %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %min, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
233   %trunc = trunc <4 x i32> %max to <4 x i16>
234   %shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
235   ret <8 x i16> %shuffle
238 define <4 x i32> @signed_minmax_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {
239 ; CHECK-LABEL: signed_minmax_v2i64_to_v4i32:
240 ; CHECK:       // %bb.0: // %entry
241 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
242 ; CHECK-NEXT:    sqxtn2 v0.4s, v1.2d
243 ; CHECK-NEXT:    ret
244 entry:
245   %min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %y, <2 x i64> <i64 2147483647, i64 2147483647>)
246   %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %min, <2 x i64> <i64 -2147483648, i64 -2147483648>)
247   %trunc = trunc <2 x i64> %max to <2 x i32>
248   %shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
249   ret <4 x i32> %shuffle
252 ; Test the (concat_vectors (X), (trunc(smax(smin(Y, 2^n-1), -2^n))) pattern.
254 define <16 x i8> @signed_maxmin_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {
255 ; CHECK-LABEL: signed_maxmin_v8i16_to_v16i8:
256 ; CHECK:       // %bb.0: // %entry
257 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
258 ; CHECK-NEXT:    sqxtn2 v0.16b, v1.8h
259 ; CHECK-NEXT:    ret
260 entry:
261   %max = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %y, <8 x i16> <i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128, i16 -128>)
262   %min = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %max, <8 x i16> <i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127, i16 127>)
263   %trunc = trunc <8 x i16> %min to <8 x i8>
264   %shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
265   ret <16 x i8> %shuffle
268 define <8 x i16> @signed_maxmin_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {
269 ; CHECK-LABEL: signed_maxmin_v4i32_to_v8i16:
270 ; CHECK:       // %bb.0: // %entry
271 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
272 ; CHECK-NEXT:    sqxtn2 v0.8h, v1.4s
273 ; CHECK-NEXT:    ret
274 entry:
275   %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
276   %min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %max, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>)
277   %trunc = trunc <4 x i32> %min to <4 x i16>
278   %shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
279   ret <8 x i16> %shuffle
282 define <4 x i32> @signed_maxmin_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {
283 ; CHECK-LABEL: signed_maxmin_v2i64_to_v4i32:
284 ; CHECK:       // %bb.0: // %entry
285 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
286 ; CHECK-NEXT:    sqxtn2 v0.4s, v1.2d
287 ; CHECK-NEXT:    ret
288 entry:
289   %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> <i64 -2147483648, i64 -2147483648>)
290   %min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %max, <2 x i64> <i64 2147483647, i64 2147483647>)
291   %trunc = trunc <2 x i64> %min to <2 x i32>
292   %shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
293   ret <4 x i32> %shuffle
296 ; Test the (concat_vectors (X), (trunc(umin(Y, 2^n)))) pattern.
298 define <16 x i8> @unsigned_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {
299 ; CHECK-LABEL: unsigned_v8i16_to_v16i8:
300 ; CHECK:       // %bb.0: // %entry
301 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
302 ; CHECK-NEXT:    uqxtn2 v0.16b, v1.8h
303 ; CHECK-NEXT:    ret
304 entry:
305   %min = call <8 x i16> @llvm.umin.v8i16(<8 x i16> %y, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
306   %trunc = trunc <8 x i16> %min to <8 x i8>
307   %shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
308   ret <16 x i8> %shuffle
311 define <8 x i16> @unsigned_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {
312 ; CHECK-LABEL: unsigned_v4i32_to_v8i16:
313 ; CHECK:       // %bb.0: // %entry
314 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
315 ; CHECK-NEXT:    uqxtn2 v0.8h, v1.4s
316 ; CHECK-NEXT:    ret
317 entry:
318   %min = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %y, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)
319   %trunc = trunc <4 x i32> %min to <4 x i16>
320   %shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
321   ret <8 x i16> %shuffle
324 define <4 x i32> @unsigned_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {
325 ; CHECK-LABEL: unsigned_v2i64_to_v4i32:
326 ; CHECK:       // %bb.0: // %entry
327 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
328 ; CHECK-NEXT:    uqxtn2 v0.4s, v1.2d
329 ; CHECK-NEXT:    ret
330 entry:
331   %min = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %y, <2 x i64> <i64 4294967295, i64 4294967295>)
332   %trunc = trunc <2 x i64> %min to <2 x i32>
333   %shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
334   ret <4 x i32> %shuffle
337 ; Test the (concat_vectors (X), (trunc(umin(smax(Y, 0), 2^n))))) pattern.
339 define <16 x i8> @us_maxmin_v8i16_to_v16i8(<8 x i8> %x, <8 x i16> %y) {
340 ; CHECK-LABEL: us_maxmin_v8i16_to_v16i8:
341 ; CHECK:       // %bb.0: // %entry
342 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
343 ; CHECK-NEXT:    sqxtun2 v0.16b, v1.8h
344 ; CHECK-NEXT:    ret
345 entry:
346   %max = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %y, <8 x i16> zeroinitializer)
347   %min = call <8 x i16> @llvm.umin.v8i16(<8 x i16> %max, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
348   %trunc = trunc <8 x i16> %min to <8 x i8>
349   %shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
350   ret <16 x i8> %shuffle
353 define <8 x i16> @us_maxmin_v4i32_to_v8i16(<4 x i16> %x, <4 x i32> %y) {
354 ; CHECK-LABEL: us_maxmin_v4i32_to_v8i16:
355 ; CHECK:       // %bb.0: // %entry
356 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
357 ; CHECK-NEXT:    sqxtun2 v0.8h, v1.4s
358 ; CHECK-NEXT:    ret
359 entry:
360   %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> zeroinitializer)
361   %min = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %max, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)
362   %trunc = trunc <4 x i32> %min to <4 x i16>
363   %shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
364   ret <8 x i16> %shuffle
367 define <4 x i32> @us_maxmin_v2i64_to_v4i32(<2 x i32> %x, <2 x i64> %y) {
368 ; CHECK-LABEL: us_maxmin_v2i64_to_v4i32:
369 ; CHECK:       // %bb.0: // %entry
370 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
371 ; CHECK-NEXT:    sqxtun2 v0.4s, v1.2d
372 ; CHECK-NEXT:    ret
373 entry:
374   %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> zeroinitializer)
375   %min = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %max, <2 x i64> <i64 4294967295, i64 4294967295>)
376   %trunc = trunc <2 x i64> %min to <2 x i32>
377   %shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
378   ret <4 x i32> %shuffle
381 ; Test the (concat_vectors (X), (trunc(smin(smax(Y, 0), 2^n))))) pattern.
383 define <16 x i8> @sminsmax_range_unsigned_i16_to_i8(<8 x i8> %x, <8 x i16> %y) {
384 ; CHECK-LABEL: sminsmax_range_unsigned_i16_to_i8:
385 ; CHECK:       // %bb.0: // %entry
386 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
387 ; CHECK-NEXT:    sqxtun2 v0.16b, v1.8h
388 ; CHECK-NEXT:    ret
389 entry:
390   %min = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %y, <8 x i16> zeroinitializer)
391   %max = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %min, <8 x i16> <i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255, i16 255>)
392   %trunc = trunc <8 x i16> %max to <8 x i8>
393   %shuffle = shufflevector <8 x i8> %x, <8 x i8> %trunc, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
394   ret <16 x i8> %shuffle
397 define <8 x i16> @sminsmax_range_unsigned_i32_to_i16(<4 x i16> %x, <4 x i32> %y) {
398 ; CHECK-LABEL: sminsmax_range_unsigned_i32_to_i16:
399 ; CHECK:       // %bb.0: // %entry
400 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
401 ; CHECK-NEXT:    sqxtun2 v0.8h, v1.4s
402 ; CHECK-NEXT:    ret
403 entry:
404   %smax = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> zeroinitializer)
405   %smin = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %smax, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)
406   %trunc = trunc <4 x i32> %smin to <4 x i16>
407   %shuffle = shufflevector <4 x i16> %x, <4 x i16> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
408   ret <8 x i16> %shuffle
411 define <4 x i32> @sminsmax_range_unsigned_i64_to_i32(<2 x i32> %x, <2 x i64> %y) {
412 ; CHECK-LABEL: sminsmax_range_unsigned_i64_to_i32:
413 ; CHECK:       // %bb.0: // %entry
414 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
415 ; CHECK-NEXT:    sqxtun2 v0.4s, v1.2d
416 ; CHECK-NEXT:    ret
417 entry:
418   %smax = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> zeroinitializer)
419   %smin = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %smax, <2 x i64> <i64 4294967295, i64 4294967295>)
420   %trunc = trunc <2 x i64> %smin to <2 x i32>
421   %shuffle = shufflevector <2 x i32> %x, <2 x i32> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
422   ret <4 x i32> %shuffle
425 ; Type support varification - not supported with saturated value
426 ; i64 -> i16
427 define <4 x i16> @sminsmax_range_unsigned_i64_to_i16(<2 x i16> %x, <2 x i64> %y) {
428 ; CHECK-LABEL: sminsmax_range_unsigned_i64_to_i16:
429 ; CHECK:       // %bb.0: // %entry
430 ; CHECK-NEXT:    cmgt v2.2d, v1.2d, #0
431 ; CHECK-NEXT:    movi v3.2d, #0x0000000000ffff
432 ; CHECK-NEXT:    and v1.16b, v1.16b, v2.16b
433 ; CHECK-NEXT:    cmgt v2.2d, v3.2d, v1.2d
434 ; CHECK-NEXT:    bif v1.16b, v3.16b, v2.16b
435 ; CHECK-NEXT:    xtn v1.2s, v1.2d
436 ; CHECK-NEXT:    uzp1 v0.4h, v0.4h, v1.4h
437 ; CHECK-NEXT:    ret
438 entry:
439   %smax = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> zeroinitializer)
440   %smin = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %smax, <2 x i64> <i64 65535, i64 65535>)
441   %trunc = trunc <2 x i64> %smin to <2 x i16>
442   %shuffle = shufflevector <2 x i16> %x, <2 x i16> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
443   ret <4 x i16> %shuffle
446 define <4 x i16> @sminsmax_range_signed_i64_to_i16(<2 x i16> %x, <2 x i64> %y) {
447 ; CHECK-LABEL: sminsmax_range_signed_i64_to_i16:
448 ; CHECK:       // %bb.0: // %entry
449 ; CHECK-NEXT:    mov x8, #-32768 // =0xffffffffffff8000
450 ; CHECK-NEXT:    dup v2.2d, x8
451 ; CHECK-NEXT:    mov w8, #32767 // =0x7fff
452 ; CHECK-NEXT:    cmgt v3.2d, v1.2d, v2.2d
453 ; CHECK-NEXT:    bif v1.16b, v2.16b, v3.16b
454 ; CHECK-NEXT:    dup v2.2d, x8
455 ; CHECK-NEXT:    cmgt v3.2d, v2.2d, v1.2d
456 ; CHECK-NEXT:    bif v1.16b, v2.16b, v3.16b
457 ; CHECK-NEXT:    xtn v1.2s, v1.2d
458 ; CHECK-NEXT:    uzp1 v0.4h, v0.4h, v1.4h
459 ; CHECK-NEXT:    ret
460 entry:
461   %smax = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %y, <2 x i64> <i64 -32768, i64 -32768>)
462   %smin = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %smax, <2 x i64> <i64 32767, i64 32767>)
463   %trunc = trunc <2 x i64> %smin to <2 x i16>
464   %shuffle = shufflevector <2 x i16> %x, <2 x i16> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
465   ret <4 x i16> %shuffle
468 define <4 x i16> @umin_range_unsigned_i64_to_i16(<2 x i16> %x, <2 x i64> %y) {
469 ; CHECK-LABEL: umin_range_unsigned_i64_to_i16:
470 ; CHECK:       // %bb.0: // %entry
471 ; CHECK-NEXT:    movi v2.2d, #0x0000000000ffff
472 ; CHECK-NEXT:    cmhi v3.2d, v2.2d, v1.2d
473 ; CHECK-NEXT:    bif v1.16b, v2.16b, v3.16b
474 ; CHECK-NEXT:    xtn v1.2s, v1.2d
475 ; CHECK-NEXT:    uzp1 v0.4h, v0.4h, v1.4h
476 ; CHECK-NEXT:    ret
477 entry:
478   %umin = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %y, <2 x i64> <i64 65535, i64 65535>)
479   %trunc = trunc <2 x i64> %umin to <2 x i16>
480   %shuffle = shufflevector <2 x i16> %x, <2 x i16> %trunc, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
481   ret <4 x i16> %shuffle
484 ; i32 -> i8
485 define <8 x i8> @sminsmax_range_unsigned_i64_to_i8(<4 x i8> %x, <4 x i32> %y) {
486 ; CHECK-LABEL: sminsmax_range_unsigned_i64_to_i8:
487 ; CHECK:       // %bb.0: // %entry
488 ; CHECK-NEXT:    movi v2.2d, #0000000000000000
489 ; CHECK-NEXT:    smax v1.4s, v1.4s, v2.4s
490 ; CHECK-NEXT:    movi v2.2d, #0x0000ff000000ff
491 ; CHECK-NEXT:    smin v1.4s, v1.4s, v2.4s
492 ; CHECK-NEXT:    xtn v1.4h, v1.4s
493 ; CHECK-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
494 ; CHECK-NEXT:    ret
495 entry:
496   %smax = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> zeroinitializer)
497   %smin = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %smax, <4 x i32> <i32 255, i32 255, i32 255, i32 255>)
498   %trunc = trunc <4 x i32> %smin to <4 x i8>
499   %shuffle = shufflevector <4 x i8> %x, <4 x i8> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
500   ret <8 x i8> %shuffle
503 define <8 x i8> @sminsmax_range_signed_i32_to_i8(<4 x i8> %x, <4 x i32> %y) {
504 ; CHECK-LABEL: sminsmax_range_signed_i32_to_i8:
505 ; CHECK:       // %bb.0: // %entry
506 ; CHECK-NEXT:    mvni v2.4s, #127
507 ; CHECK-NEXT:    smax v1.4s, v1.4s, v2.4s
508 ; CHECK-NEXT:    movi v2.4s, #127
509 ; CHECK-NEXT:    smin v1.4s, v1.4s, v2.4s
510 ; CHECK-NEXT:    xtn v1.4h, v1.4s
511 ; CHECK-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
512 ; CHECK-NEXT:    ret
513 entry:
514   %smax = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %y, <4 x i32> <i32 -128, i32 -128, i32 -128, i32 -128>)
515   %smin = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %smax, <4 x i32> <i32 127, i32 127, i32 127, i32 127>)
516   %trunc = trunc <4 x i32> %smin to <4 x i8>
517   %shuffle = shufflevector <4 x i8> %x, <4 x i8> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
518   ret <8 x i8> %shuffle
521 define <8 x i8> @umin_range_unsigned_i32_to_i8(<4 x i8> %x, <4 x i32> %y) {
522 ; CHECK-LABEL: umin_range_unsigned_i32_to_i8:
523 ; CHECK:       // %bb.0: // %entry
524 ; CHECK-NEXT:    movi v2.2d, #0x0000ff000000ff
525 ; CHECK-NEXT:    umin v1.4s, v1.4s, v2.4s
526 ; CHECK-NEXT:    xtn v1.4h, v1.4s
527 ; CHECK-NEXT:    uzp1 v0.8b, v0.8b, v1.8b
528 ; CHECK-NEXT:    ret
529 entry:
530   %umin = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %y, <4 x i32> <i32 255, i32 255, i32 255, i32 255>)
531   %trunc = trunc <4 x i32> %umin to <4 x i8>
532   %shuffle = shufflevector <4 x i8> %x, <4 x i8> %trunc, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
533   ret <8 x i8> %shuffle