8484define <2 x i32 > @vqmovni64_smaxmin (<2 x i64 > %s0 ) {
8585; CHECK-LABEL: vqmovni64_smaxmin:
8686; CHECK: // %bb.0: // %entry
87- ; CHECK-NEXT: mov w8, #2147483647
87+ ; CHECK-NEXT: mov w8, #2147483647 // =0x7fffffff
8888; CHECK-NEXT: dup v1.2d, x8
89- ; CHECK-NEXT: mov x8, #-2147483648
89+ ; CHECK-NEXT: mov x8, #-2147483648 // =0xffffffff80000000
9090; CHECK-NEXT: cmgt v2.2d, v1.2d, v0.2d
9191; CHECK-NEXT: bif v0.16b, v1.16b, v2.16b
9292; CHECK-NEXT: dup v1.2d, x8
@@ -106,9 +106,9 @@ entry:
106106define <2 x i32 > @vqmovni64_sminmax (<2 x i64 > %s0 ) {
107107; CHECK-LABEL: vqmovni64_sminmax:
108108; CHECK: // %bb.0: // %entry
109- ; CHECK-NEXT: mov x8, #-2147483648
109+ ; CHECK-NEXT: mov x8, #-2147483648 // =0xffffffff80000000
110110; CHECK-NEXT: dup v1.2d, x8
111- ; CHECK-NEXT: mov w8, #2147483647
111+ ; CHECK-NEXT: mov w8, #2147483647 // =0x7fffffff
112112; CHECK-NEXT: cmgt v2.2d, v0.2d, v1.2d
113113; CHECK-NEXT: bif v0.16b, v1.16b, v2.16b
114114; CHECK-NEXT: dup v1.2d, x8
@@ -140,3 +140,214 @@ entry:
140140 %t = trunc <2 x i64 > %s1 to <2 x i32 >
141141 ret <2 x i32 > %t
142142}
143+
144+ ; Test the (concat_vectors (X), (trunc(smin(smax(Y, -2^n), 2^n-1))) pattern.
145+
146+ define <16 x i8 > @signed_minmax_v8i16_to_v16i8 (<8 x i8 > %x , <8 x i16 > %y ) {
147+ ; CHECK-LABEL: signed_minmax_v8i16_to_v16i8:
148+ ; CHECK: // %bb.0: // %entry
149+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
150+ ; CHECK-NEXT: sqxtn2 v0.16b, v1.8h
151+ ; CHECK-NEXT: ret
152+ entry:
153+ %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 >)
154+ %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 >)
155+ %trunc = trunc <8 x i16 > %max to <8 x i8 >
156+ %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 >
157+ ret <16 x i8 > %shuffle
158+ }
159+
160+ define <8 x i16 > @signed_minmax_v4i32_to_v8i16 (<4 x i16 > %x , <4 x i32 > %y ) {
161+ ; CHECK-LABEL: signed_minmax_v4i32_to_v8i16:
162+ ; CHECK: // %bb.0: // %entry
163+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
164+ ; CHECK-NEXT: sqxtn2 v0.8h, v1.4s
165+ ; CHECK-NEXT: ret
166+ entry:
167+ %min = call <4 x i32 > @llvm.smin.v4i32 (<4 x i32 > %y , <4 x i32 > <i32 32767 , i32 32767 , i32 32767 , i32 32767 >)
168+ %max = call <4 x i32 > @llvm.smax.v4i32 (<4 x i32 > %min , <4 x i32 > <i32 -32768 , i32 -32768 , i32 -32768 , i32 -32768 >)
169+ %trunc = trunc <4 x i32 > %max to <4 x i16 >
170+ %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 >
171+ ret <8 x i16 > %shuffle
172+ }
173+
174+ define <4 x i32 > @signed_minmax_v2i64_to_v4i32 (<2 x i32 > %x , <2 x i64 > %y ) {
175+ ; CHECK-LABEL: signed_minmax_v2i64_to_v4i32:
176+ ; CHECK: // %bb.0: // %entry
177+ ; CHECK-NEXT: mov w8, #2147483647 // =0x7fffffff
178+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
179+ ; CHECK-NEXT: dup v2.2d, x8
180+ ; CHECK-NEXT: mov x8, #-2147483648 // =0xffffffff80000000
181+ ; CHECK-NEXT: cmgt v3.2d, v2.2d, v1.2d
182+ ; CHECK-NEXT: bif v1.16b, v2.16b, v3.16b
183+ ; CHECK-NEXT: dup v2.2d, x8
184+ ; CHECK-NEXT: cmgt v3.2d, v1.2d, v2.2d
185+ ; CHECK-NEXT: bif v1.16b, v2.16b, v3.16b
186+ ; CHECK-NEXT: xtn2 v0.4s, v1.2d
187+ ; CHECK-NEXT: ret
188+ entry:
189+ %min = call <2 x i64 > @llvm.smin.v2i64 (<2 x i64 > %y , <2 x i64 > <i64 2147483647 , i64 2147483647 >)
190+ %max = call <2 x i64 > @llvm.smax.v2i64 (<2 x i64 > %min , <2 x i64 > <i64 -2147483648 , i64 -2147483648 >)
191+ %trunc = trunc <2 x i64 > %max to <2 x i32 >
192+ %shuffle = shufflevector <2 x i32 > %x , <2 x i32 > %trunc , <4 x i32 > <i32 0 , i32 1 , i32 2 , i32 3 >
193+ ret <4 x i32 > %shuffle
194+ }
195+
196+ ; Test the (concat_vectors (X), (trunc(smax(smin(Y, 2^n-1), -2^n))) pattern.
197+
198+ define <16 x i8 > @signed_maxmin_v8i16_to_v16i8 (<8 x i8 > %x , <8 x i16 > %y ) {
199+ ; CHECK-LABEL: signed_maxmin_v8i16_to_v16i8:
200+ ; CHECK: // %bb.0: // %entry
201+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
202+ ; CHECK-NEXT: sqxtn2 v0.16b, v1.8h
203+ ; CHECK-NEXT: ret
204+ entry:
205+ %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 >)
206+ %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 >)
207+ %trunc = trunc <8 x i16 > %min to <8 x i8 >
208+ %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 >
209+ ret <16 x i8 > %shuffle
210+ }
211+
212+ define <8 x i16 > @signed_maxmin_v4i32_to_v8i16 (<4 x i16 > %x , <4 x i32 > %y ) {
213+ ; CHECK-LABEL: signed_maxmin_v4i32_to_v8i16:
214+ ; CHECK: // %bb.0: // %entry
215+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
216+ ; CHECK-NEXT: sqxtn2 v0.8h, v1.4s
217+ ; CHECK-NEXT: ret
218+ entry:
219+ %max = call <4 x i32 > @llvm.smax.v4i32 (<4 x i32 > %y , <4 x i32 > <i32 -32768 , i32 -32768 , i32 -32768 , i32 -32768 >)
220+ %min = call <4 x i32 > @llvm.smin.v4i32 (<4 x i32 > %max , <4 x i32 > <i32 32767 , i32 32767 , i32 32767 , i32 32767 >)
221+ %trunc = trunc <4 x i32 > %min to <4 x i16 >
222+ %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 >
223+ ret <8 x i16 > %shuffle
224+ }
225+
226+ define <4 x i32 > @signed_maxmin_v2i64_to_v4i32 (<2 x i32 > %x , <2 x i64 > %y ) {
227+ ; CHECK-LABEL: signed_maxmin_v2i64_to_v4i32:
228+ ; CHECK: // %bb.0: // %entry
229+ ; CHECK-NEXT: mov x8, #-2147483648 // =0xffffffff80000000
230+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
231+ ; CHECK-NEXT: dup v2.2d, x8
232+ ; CHECK-NEXT: mov w8, #2147483647 // =0x7fffffff
233+ ; CHECK-NEXT: cmgt v3.2d, v1.2d, v2.2d
234+ ; CHECK-NEXT: bif v1.16b, v2.16b, v3.16b
235+ ; CHECK-NEXT: dup v2.2d, x8
236+ ; CHECK-NEXT: cmgt v3.2d, v2.2d, v1.2d
237+ ; CHECK-NEXT: bif v1.16b, v2.16b, v3.16b
238+ ; CHECK-NEXT: xtn2 v0.4s, v1.2d
239+ ; CHECK-NEXT: ret
240+ entry:
241+ %max = call <2 x i64 > @llvm.smax.v2i64 (<2 x i64 > %y , <2 x i64 > <i64 -2147483648 , i64 -2147483648 >)
242+ %min = call <2 x i64 > @llvm.smin.v2i64 (<2 x i64 > %max , <2 x i64 > <i64 2147483647 , i64 2147483647 >)
243+ %trunc = trunc <2 x i64 > %min to <2 x i32 >
244+ %shuffle = shufflevector <2 x i32 > %x , <2 x i32 > %trunc , <4 x i32 > <i32 0 , i32 1 , i32 2 , i32 3 >
245+ ret <4 x i32 > %shuffle
246+ }
247+
248+ ; Test the (concat_vectors (X), (trunc(umin(Y, 2^n)))) pattern.
249+
250+ define <16 x i8 > @unsigned_v8i16_to_v16i8 (<8 x i8 > %x , <8 x i16 > %y ) {
251+ ; CHECK-LABEL: unsigned_v8i16_to_v16i8:
252+ ; CHECK: // %bb.0: // %entry
253+ ; CHECK-NEXT: movi v2.2d, #0xff00ff00ff00ff
254+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
255+ ; CHECK-NEXT: umin v1.8h, v1.8h, v2.8h
256+ ; CHECK-NEXT: xtn2 v0.16b, v1.8h
257+ ; CHECK-NEXT: ret
258+ entry:
259+ %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 >)
260+ %trunc = trunc <8 x i16 > %min to <8 x i8 >
261+ %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 >
262+ ret <16 x i8 > %shuffle
263+ }
264+
265+ define <8 x i16 > @unsigned_v4i32_to_v8i16 (<4 x i16 > %x , <4 x i32 > %y ) {
266+ ; CHECK-LABEL: unsigned_v4i32_to_v8i16:
267+ ; CHECK: // %bb.0: // %entry
268+ ; CHECK-NEXT: movi v2.2d, #0x00ffff0000ffff
269+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
270+ ; CHECK-NEXT: umin v1.4s, v1.4s, v2.4s
271+ ; CHECK-NEXT: xtn2 v0.8h, v1.4s
272+ ; CHECK-NEXT: ret
273+ entry:
274+ %min = call <4 x i32 > @llvm.umin.v4i32 (<4 x i32 > %y , <4 x i32 > <i32 65535 , i32 65535 , i32 65535 , i32 65535 >)
275+ %trunc = trunc <4 x i32 > %min to <4 x i16 >
276+ %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 >
277+ ret <8 x i16 > %shuffle
278+ }
279+
280+ define <4 x i32 > @unsigned_v2i64_to_v4i32 (<2 x i32 > %x , <2 x i64 > %y ) {
281+ ; CHECK-LABEL: unsigned_v2i64_to_v4i32:
282+ ; CHECK: // %bb.0: // %entry
283+ ; CHECK-NEXT: movi v2.2d, #0x000000ffffffff
284+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
285+ ; CHECK-NEXT: cmhi v2.2d, v2.2d, v1.2d
286+ ; CHECK-NEXT: and v1.16b, v1.16b, v2.16b
287+ ; CHECK-NEXT: orn v1.16b, v1.16b, v2.16b
288+ ; CHECK-NEXT: xtn2 v0.4s, v1.2d
289+ ; CHECK-NEXT: ret
290+ entry:
291+ %min = call <2 x i64 > @llvm.umin.v2i64 (<2 x i64 > %y , <2 x i64 > <i64 4294967295 , i64 4294967295 >)
292+ %trunc = trunc <2 x i64 > %min to <2 x i32 >
293+ %shuffle = shufflevector <2 x i32 > %x , <2 x i32 > %trunc , <4 x i32 > <i32 0 , i32 1 , i32 2 , i32 3 >
294+ ret <4 x i32 > %shuffle
295+ }
296+
297+ ; Test the (concat_vectors (X), (trunc(umin(smax(Y, 0), 2^n))))) pattern.
298+
299+ define <16 x i8 > @us_maxmin_v8i16_to_v16i8 (<8 x i8 > %x , <8 x i16 > %y ) {
300+ ; CHECK-LABEL: us_maxmin_v8i16_to_v16i8:
301+ ; CHECK: // %bb.0: // %entry
302+ ; CHECK-NEXT: movi v2.2d, #0000000000000000
303+ ; CHECK-NEXT: movi v3.2d, #0xff00ff00ff00ff
304+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
305+ ; CHECK-NEXT: smax v1.8h, v1.8h, v2.8h
306+ ; CHECK-NEXT: smin v1.8h, v1.8h, v3.8h
307+ ; CHECK-NEXT: xtn2 v0.16b, v1.8h
308+ ; CHECK-NEXT: ret
309+ entry:
310+ %max = call <8 x i16 > @llvm.smax.v8i16 (<8 x i16 > %y , <8 x i16 > zeroinitializer )
311+ %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 >)
312+ %trunc = trunc <8 x i16 > %min to <8 x i8 >
313+ %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 >
314+ ret <16 x i8 > %shuffle
315+ }
316+
317+ define <8 x i16 > @us_maxmin_v4i32_to_v8i16 (<4 x i16 > %x , <4 x i32 > %y ) {
318+ ; CHECK-LABEL: us_maxmin_v4i32_to_v8i16:
319+ ; CHECK: // %bb.0: // %entry
320+ ; CHECK-NEXT: movi v2.2d, #0000000000000000
321+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
322+ ; CHECK-NEXT: smax v1.4s, v1.4s, v2.4s
323+ ; CHECK-NEXT: movi v2.2d, #0x00ffff0000ffff
324+ ; CHECK-NEXT: smin v1.4s, v1.4s, v2.4s
325+ ; CHECK-NEXT: xtn2 v0.8h, v1.4s
326+ ; CHECK-NEXT: ret
327+ entry:
328+ %max = call <4 x i32 > @llvm.smax.v4i32 (<4 x i32 > %y , <4 x i32 > zeroinitializer )
329+ %min = call <4 x i32 > @llvm.umin.v4i32 (<4 x i32 > %max , <4 x i32 > <i32 65535 , i32 65535 , i32 65535 , i32 65535 >)
330+ %trunc = trunc <4 x i32 > %min to <4 x i16 >
331+ %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 >
332+ ret <8 x i16 > %shuffle
333+ }
334+
335+ define <4 x i32 > @us_maxmin_v2i64_to_v4i32 (<2 x i32 > %x , <2 x i64 > %y ) {
336+ ; CHECK-LABEL: us_maxmin_v2i64_to_v4i32:
337+ ; CHECK: // %bb.0: // %entry
338+ ; CHECK-NEXT: cmgt v2.2d, v1.2d, #0
339+ ; CHECK-NEXT: movi v3.2d, #0x000000ffffffff
340+ ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
341+ ; CHECK-NEXT: and v1.16b, v1.16b, v2.16b
342+ ; CHECK-NEXT: cmgt v2.2d, v3.2d, v1.2d
343+ ; CHECK-NEXT: and v1.16b, v1.16b, v2.16b
344+ ; CHECK-NEXT: orn v1.16b, v1.16b, v2.16b
345+ ; CHECK-NEXT: xtn2 v0.4s, v1.2d
346+ ; CHECK-NEXT: ret
347+ entry:
348+ %max = call <2 x i64 > @llvm.smax.v2i64 (<2 x i64 > %y , <2 x i64 > zeroinitializer )
349+ %min = call <2 x i64 > @llvm.umin.v2i64 (<2 x i64 > %max , <2 x i64 > <i64 4294967295 , i64 4294967295 >)
350+ %trunc = trunc <2 x i64 > %min to <2 x i32 >
351+ %shuffle = shufflevector <2 x i32 > %x , <2 x i32 > %trunc , <4 x i32 > <i32 0 , i32 1 , i32 2 , i32 3 >
352+ ret <4 x i32 > %shuffle
353+ }
0 commit comments