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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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>
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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