[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / Thumb2 / mve-minmax.ll
blob14b1f466bf669321c7f186afb1ae05cb6b46290b
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=thumbv8.1m.main-arm-none-eabi -mattr=+mve,+fullfp16 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MVE
3 ; RUN: llc -mtriple=thumbv8.1m.main-arm-none-eabi -mattr=+mve.fp -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MVEFP
5 define arm_aapcs_vfpcc <16 x i8> @smin_v16i8(<16 x i8> %s1, <16 x i8> %s2) {
6 ; CHECK-LABEL: smin_v16i8:
7 ; CHECK:       @ %bb.0: @ %entry
8 ; CHECK-NEXT:    vmin.s8 q0, q0, q1
9 ; CHECK-NEXT:    bx lr
10 entry:
11   %0 = icmp slt <16 x i8> %s1, %s2
12   %1 = select <16 x i1> %0, <16 x i8> %s1, <16 x i8> %s2
13   ret <16 x i8> %1
16 define arm_aapcs_vfpcc <8 x i16> @smin_v8i16(<8 x i16> %s1, <8 x i16> %s2) {
17 ; CHECK-LABEL: smin_v8i16:
18 ; CHECK:       @ %bb.0: @ %entry
19 ; CHECK-NEXT:    vmin.s16 q0, q0, q1
20 ; CHECK-NEXT:    bx lr
21 entry:
22   %0 = icmp slt <8 x i16> %s1, %s2
23   %1 = select <8 x i1> %0, <8 x i16> %s1, <8 x i16> %s2
24   ret <8 x i16> %1
27 define arm_aapcs_vfpcc <4 x i32> @smin_v4i32(<4 x i32> %s1, <4 x i32> %s2) {
28 ; CHECK-LABEL: smin_v4i32:
29 ; CHECK:       @ %bb.0: @ %entry
30 ; CHECK-NEXT:    vmin.s32 q0, q0, q1
31 ; CHECK-NEXT:    bx lr
32 entry:
33   %0 = icmp slt <4 x i32> %s1, %s2
34   %1 = select <4 x i1> %0, <4 x i32> %s1, <4 x i32> %s2
35   ret <4 x i32> %1
38 define arm_aapcs_vfpcc <2 x i64> @smin_v2i64(<2 x i64> %s1, <2 x i64> %s2) {
39 ; CHECK-LABEL: smin_v2i64:
40 ; CHECK:       @ %bb.0: @ %entry
41 ; CHECK-NEXT:    .save {r7, lr}
42 ; CHECK-NEXT:    push {r7, lr}
43 ; CHECK-NEXT:    vmov r2, s6
44 ; CHECK-NEXT:    movs r0, #0
45 ; CHECK-NEXT:    vmov r3, s2
46 ; CHECK-NEXT:    vmov r12, s7
47 ; CHECK-NEXT:    vmov r1, s3
48 ; CHECK-NEXT:    vmov lr, s1
49 ; CHECK-NEXT:    subs r2, r3, r2
50 ; CHECK-NEXT:    vmov r3, s0
51 ; CHECK-NEXT:    vmov r2, s4
52 ; CHECK-NEXT:    sbcs.w r1, r1, r12
53 ; CHECK-NEXT:    vmov r12, s5
54 ; CHECK-NEXT:    mov.w r1, #0
55 ; CHECK-NEXT:    it lt
56 ; CHECK-NEXT:    movlt r1, #1
57 ; CHECK-NEXT:    cmp r1, #0
58 ; CHECK-NEXT:    csetm r1, ne
59 ; CHECK-NEXT:    subs r2, r3, r2
60 ; CHECK-NEXT:    sbcs.w r2, lr, r12
61 ; CHECK-NEXT:    it lt
62 ; CHECK-NEXT:    movlt r0, #1
63 ; CHECK-NEXT:    cmp r0, #0
64 ; CHECK-NEXT:    csetm r0, ne
65 ; CHECK-NEXT:    vmov.32 q2[0], r0
66 ; CHECK-NEXT:    vmov.32 q2[1], r0
67 ; CHECK-NEXT:    vmov.32 q2[2], r1
68 ; CHECK-NEXT:    vmov.32 q2[3], r1
69 ; CHECK-NEXT:    vbic q1, q1, q2
70 ; CHECK-NEXT:    vand q0, q0, q2
71 ; CHECK-NEXT:    vorr q0, q0, q1
72 ; CHECK-NEXT:    pop {r7, pc}
73 entry:
74   %0 = icmp slt <2 x i64> %s1, %s2
75   %1 = select <2 x i1> %0, <2 x i64> %s1, <2 x i64> %s2
76   ret <2 x i64> %1
79 define arm_aapcs_vfpcc <16 x i8> @umin_v16i8(<16 x i8> %s1, <16 x i8> %s2) {
80 ; CHECK-LABEL: umin_v16i8:
81 ; CHECK:       @ %bb.0: @ %entry
82 ; CHECK-NEXT:    vmin.u8 q0, q0, q1
83 ; CHECK-NEXT:    bx lr
84 entry:
85   %0 = icmp ult <16 x i8> %s1, %s2
86   %1 = select <16 x i1> %0, <16 x i8> %s1, <16 x i8> %s2
87   ret <16 x i8> %1
90 define arm_aapcs_vfpcc <8 x i16> @umin_v8i16(<8 x i16> %s1, <8 x i16> %s2) {
91 ; CHECK-LABEL: umin_v8i16:
92 ; CHECK:       @ %bb.0: @ %entry
93 ; CHECK-NEXT:    vmin.u16 q0, q0, q1
94 ; CHECK-NEXT:    bx lr
95 entry:
96   %0 = icmp ult <8 x i16> %s1, %s2
97   %1 = select <8 x i1> %0, <8 x i16> %s1, <8 x i16> %s2
98   ret <8 x i16> %1
101 define arm_aapcs_vfpcc <4 x i32> @umin_v4i32(<4 x i32> %s1, <4 x i32> %s2) {
102 ; CHECK-LABEL: umin_v4i32:
103 ; CHECK:       @ %bb.0: @ %entry
104 ; CHECK-NEXT:    vmin.u32 q0, q0, q1
105 ; CHECK-NEXT:    bx lr
106 entry:
107   %0 = icmp ult <4 x i32> %s1, %s2
108   %1 = select <4 x i1> %0, <4 x i32> %s1, <4 x i32> %s2
109   ret <4 x i32> %1
112 define arm_aapcs_vfpcc <2 x i64> @umin_v2i64(<2 x i64> %s1, <2 x i64> %s2) {
113 ; CHECK-LABEL: umin_v2i64:
114 ; CHECK:       @ %bb.0: @ %entry
115 ; CHECK-NEXT:    .save {r7, lr}
116 ; CHECK-NEXT:    push {r7, lr}
117 ; CHECK-NEXT:    vmov r2, s6
118 ; CHECK-NEXT:    movs r0, #0
119 ; CHECK-NEXT:    vmov r3, s2
120 ; CHECK-NEXT:    vmov r12, s7
121 ; CHECK-NEXT:    vmov r1, s3
122 ; CHECK-NEXT:    vmov lr, s1
123 ; CHECK-NEXT:    subs r2, r3, r2
124 ; CHECK-NEXT:    vmov r3, s0
125 ; CHECK-NEXT:    vmov r2, s4
126 ; CHECK-NEXT:    sbcs.w r1, r1, r12
127 ; CHECK-NEXT:    vmov r12, s5
128 ; CHECK-NEXT:    mov.w r1, #0
129 ; CHECK-NEXT:    it lo
130 ; CHECK-NEXT:    movlo r1, #1
131 ; CHECK-NEXT:    cmp r1, #0
132 ; CHECK-NEXT:    csetm r1, ne
133 ; CHECK-NEXT:    subs r2, r3, r2
134 ; CHECK-NEXT:    sbcs.w r2, lr, r12
135 ; CHECK-NEXT:    it lo
136 ; CHECK-NEXT:    movlo r0, #1
137 ; CHECK-NEXT:    cmp r0, #0
138 ; CHECK-NEXT:    csetm r0, ne
139 ; CHECK-NEXT:    vmov.32 q2[0], r0
140 ; CHECK-NEXT:    vmov.32 q2[1], r0
141 ; CHECK-NEXT:    vmov.32 q2[2], r1
142 ; CHECK-NEXT:    vmov.32 q2[3], r1
143 ; CHECK-NEXT:    vbic q1, q1, q2
144 ; CHECK-NEXT:    vand q0, q0, q2
145 ; CHECK-NEXT:    vorr q0, q0, q1
146 ; CHECK-NEXT:    pop {r7, pc}
147 entry:
148   %0 = icmp ult <2 x i64> %s1, %s2
149   %1 = select <2 x i1> %0, <2 x i64> %s1, <2 x i64> %s2
150   ret <2 x i64> %1
154 define arm_aapcs_vfpcc <16 x i8> @smax_v16i8(<16 x i8> %s1, <16 x i8> %s2) {
155 ; CHECK-LABEL: smax_v16i8:
156 ; CHECK:       @ %bb.0: @ %entry
157 ; CHECK-NEXT:    vmax.s8 q0, q0, q1
158 ; CHECK-NEXT:    bx lr
159 entry:
160   %0 = icmp sgt <16 x i8> %s1, %s2
161   %1 = select <16 x i1> %0, <16 x i8> %s1, <16 x i8> %s2
162   ret <16 x i8> %1
165 define arm_aapcs_vfpcc <8 x i16> @smax_v8i16(<8 x i16> %s1, <8 x i16> %s2) {
166 ; CHECK-LABEL: smax_v8i16:
167 ; CHECK:       @ %bb.0: @ %entry
168 ; CHECK-NEXT:    vmax.s16 q0, q0, q1
169 ; CHECK-NEXT:    bx lr
170 entry:
171   %0 = icmp sgt <8 x i16> %s1, %s2
172   %1 = select <8 x i1> %0, <8 x i16> %s1, <8 x i16> %s2
173   ret <8 x i16> %1
176 define arm_aapcs_vfpcc <4 x i32> @smax_v4i32(<4 x i32> %s1, <4 x i32> %s2) {
177 ; CHECK-LABEL: smax_v4i32:
178 ; CHECK:       @ %bb.0: @ %entry
179 ; CHECK-NEXT:    vmax.s32 q0, q0, q1
180 ; CHECK-NEXT:    bx lr
181 entry:
182   %0 = icmp sgt <4 x i32> %s1, %s2
183   %1 = select <4 x i1> %0, <4 x i32> %s1, <4 x i32> %s2
184   ret <4 x i32> %1
187 define arm_aapcs_vfpcc <2 x i64> @smax_v2i64(<2 x i64> %s1, <2 x i64> %s2) {
188 ; CHECK-LABEL: smax_v2i64:
189 ; CHECK:       @ %bb.0: @ %entry
190 ; CHECK-NEXT:    .save {r7, lr}
191 ; CHECK-NEXT:    push {r7, lr}
192 ; CHECK-NEXT:    vmov r2, s2
193 ; CHECK-NEXT:    movs r0, #0
194 ; CHECK-NEXT:    vmov r3, s6
195 ; CHECK-NEXT:    vmov r12, s3
196 ; CHECK-NEXT:    vmov r1, s7
197 ; CHECK-NEXT:    vmov lr, s5
198 ; CHECK-NEXT:    subs r2, r3, r2
199 ; CHECK-NEXT:    vmov r3, s4
200 ; CHECK-NEXT:    vmov r2, s0
201 ; CHECK-NEXT:    sbcs.w r1, r1, r12
202 ; CHECK-NEXT:    vmov r12, s1
203 ; CHECK-NEXT:    mov.w r1, #0
204 ; CHECK-NEXT:    it lt
205 ; CHECK-NEXT:    movlt r1, #1
206 ; CHECK-NEXT:    cmp r1, #0
207 ; CHECK-NEXT:    csetm r1, ne
208 ; CHECK-NEXT:    subs r2, r3, r2
209 ; CHECK-NEXT:    sbcs.w r2, lr, r12
210 ; CHECK-NEXT:    it lt
211 ; CHECK-NEXT:    movlt r0, #1
212 ; CHECK-NEXT:    cmp r0, #0
213 ; CHECK-NEXT:    csetm r0, ne
214 ; CHECK-NEXT:    vmov.32 q2[0], r0
215 ; CHECK-NEXT:    vmov.32 q2[1], r0
216 ; CHECK-NEXT:    vmov.32 q2[2], r1
217 ; CHECK-NEXT:    vmov.32 q2[3], r1
218 ; CHECK-NEXT:    vbic q1, q1, q2
219 ; CHECK-NEXT:    vand q0, q0, q2
220 ; CHECK-NEXT:    vorr q0, q0, q1
221 ; CHECK-NEXT:    pop {r7, pc}
222 entry:
223   %0 = icmp sgt <2 x i64> %s1, %s2
224   %1 = select <2 x i1> %0, <2 x i64> %s1, <2 x i64> %s2
225   ret <2 x i64> %1
228 define arm_aapcs_vfpcc <16 x i8> @umax_v16i8(<16 x i8> %s1, <16 x i8> %s2) {
229 ; CHECK-LABEL: umax_v16i8:
230 ; CHECK:       @ %bb.0: @ %entry
231 ; CHECK-NEXT:    vmax.u8 q0, q0, q1
232 ; CHECK-NEXT:    bx lr
233 entry:
234   %0 = icmp ugt <16 x i8> %s1, %s2
235   %1 = select <16 x i1> %0, <16 x i8> %s1, <16 x i8> %s2
236   ret <16 x i8> %1
239 define arm_aapcs_vfpcc <8 x i16> @umax_v8i16(<8 x i16> %s1, <8 x i16> %s2) {
240 ; CHECK-LABEL: umax_v8i16:
241 ; CHECK:       @ %bb.0: @ %entry
242 ; CHECK-NEXT:    vmax.u16 q0, q0, q1
243 ; CHECK-NEXT:    bx lr
244 entry:
245   %0 = icmp ugt <8 x i16> %s1, %s2
246   %1 = select <8 x i1> %0, <8 x i16> %s1, <8 x i16> %s2
247   ret <8 x i16> %1
250 define arm_aapcs_vfpcc <4 x i32> @umax_v4i32(<4 x i32> %s1, <4 x i32> %s2) {
251 ; CHECK-LABEL: umax_v4i32:
252 ; CHECK:       @ %bb.0: @ %entry
253 ; CHECK-NEXT:    vmax.u32 q0, q0, q1
254 ; CHECK-NEXT:    bx lr
255 entry:
256   %0 = icmp ugt <4 x i32> %s1, %s2
257   %1 = select <4 x i1> %0, <4 x i32> %s1, <4 x i32> %s2
258   ret <4 x i32> %1
261 define arm_aapcs_vfpcc <2 x i64> @umax_v2i64(<2 x i64> %s1, <2 x i64> %s2) {
262 ; CHECK-LABEL: umax_v2i64:
263 ; CHECK:       @ %bb.0: @ %entry
264 ; CHECK-NEXT:    .save {r7, lr}
265 ; CHECK-NEXT:    push {r7, lr}
266 ; CHECK-NEXT:    vmov r2, s2
267 ; CHECK-NEXT:    movs r0, #0
268 ; CHECK-NEXT:    vmov r3, s6
269 ; CHECK-NEXT:    vmov r12, s3
270 ; CHECK-NEXT:    vmov r1, s7
271 ; CHECK-NEXT:    vmov lr, s5
272 ; CHECK-NEXT:    subs r2, r3, r2
273 ; CHECK-NEXT:    vmov r3, s4
274 ; CHECK-NEXT:    vmov r2, s0
275 ; CHECK-NEXT:    sbcs.w r1, r1, r12
276 ; CHECK-NEXT:    vmov r12, s1
277 ; CHECK-NEXT:    mov.w r1, #0
278 ; CHECK-NEXT:    it lo
279 ; CHECK-NEXT:    movlo r1, #1
280 ; CHECK-NEXT:    cmp r1, #0
281 ; CHECK-NEXT:    csetm r1, ne
282 ; CHECK-NEXT:    subs r2, r3, r2
283 ; CHECK-NEXT:    sbcs.w r2, lr, r12
284 ; CHECK-NEXT:    it lo
285 ; CHECK-NEXT:    movlo r0, #1
286 ; CHECK-NEXT:    cmp r0, #0
287 ; CHECK-NEXT:    csetm r0, ne
288 ; CHECK-NEXT:    vmov.32 q2[0], r0
289 ; CHECK-NEXT:    vmov.32 q2[1], r0
290 ; CHECK-NEXT:    vmov.32 q2[2], r1
291 ; CHECK-NEXT:    vmov.32 q2[3], r1
292 ; CHECK-NEXT:    vbic q1, q1, q2
293 ; CHECK-NEXT:    vand q0, q0, q2
294 ; CHECK-NEXT:    vorr q0, q0, q1
295 ; CHECK-NEXT:    pop {r7, pc}
296 entry:
297   %0 = icmp ugt <2 x i64> %s1, %s2
298   %1 = select <2 x i1> %0, <2 x i64> %s1, <2 x i64> %s2
299   ret <2 x i64> %1
303 define arm_aapcs_vfpcc <4 x float> @maxnm_float32_t(<4 x float> %src1, <4 x float> %src2) {
304 ; CHECK-MVE-LABEL: maxnm_float32_t:
305 ; CHECK-MVE:       @ %bb.0: @ %entry
306 ; CHECK-MVE-NEXT:    vmaxnm.f32 s11, s7, s3
307 ; CHECK-MVE-NEXT:    vmaxnm.f32 s10, s6, s2
308 ; CHECK-MVE-NEXT:    vmaxnm.f32 s9, s5, s1
309 ; CHECK-MVE-NEXT:    vmaxnm.f32 s8, s4, s0
310 ; CHECK-MVE-NEXT:    vmov q0, q2
311 ; CHECK-MVE-NEXT:    bx lr
313 ; CHECK-MVEFP-LABEL: maxnm_float32_t:
314 ; CHECK-MVEFP:       @ %bb.0: @ %entry
315 ; CHECK-MVEFP-NEXT:    vmaxnm.f32 q0, q1, q0
316 ; CHECK-MVEFP-NEXT:    bx lr
317 entry:
318   %cmp = fcmp fast ogt <4 x float> %src2, %src1
319   %0 = select <4 x i1> %cmp, <4 x float> %src2, <4 x float> %src1
320   ret <4 x float> %0
323 define arm_aapcs_vfpcc <8 x half> @minnm_float16_t(<8 x half> %src1, <8 x half> %src2) {
324 ; CHECK-MVE-LABEL: minnm_float16_t:
325 ; CHECK-MVE:       @ %bb.0: @ %entry
326 ; CHECK-MVE-NEXT:    vminnm.f16 s8, s4, s0
327 ; CHECK-MVE-NEXT:    vmovx.f16 s10, s4
328 ; CHECK-MVE-NEXT:    vmov r0, s8
329 ; CHECK-MVE-NEXT:    vmovx.f16 s8, s0
330 ; CHECK-MVE-NEXT:    vminnm.f16 s8, s10, s8
331 ; CHECK-MVE-NEXT:    vminnm.f16 s12, s5, s1
332 ; CHECK-MVE-NEXT:    vmov r1, s8
333 ; CHECK-MVE-NEXT:    vmov.16 q2[0], r0
334 ; CHECK-MVE-NEXT:    vmov r0, s12
335 ; CHECK-MVE-NEXT:    vmovx.f16 s12, s1
336 ; CHECK-MVE-NEXT:    vmovx.f16 s14, s5
337 ; CHECK-MVE-NEXT:    vmov.16 q2[1], r1
338 ; CHECK-MVE-NEXT:    vminnm.f16 s12, s14, s12
339 ; CHECK-MVE-NEXT:    vmov.16 q2[2], r0
340 ; CHECK-MVE-NEXT:    vmov r0, s12
341 ; CHECK-MVE-NEXT:    vminnm.f16 s12, s6, s2
342 ; CHECK-MVE-NEXT:    vmov.16 q2[3], r0
343 ; CHECK-MVE-NEXT:    vmov r0, s12
344 ; CHECK-MVE-NEXT:    vmovx.f16 s12, s2
345 ; CHECK-MVE-NEXT:    vmovx.f16 s14, s6
346 ; CHECK-MVE-NEXT:    vminnm.f16 s12, s14, s12
347 ; CHECK-MVE-NEXT:    vmov.16 q2[4], r0
348 ; CHECK-MVE-NEXT:    vmov r0, s12
349 ; CHECK-MVE-NEXT:    vmovx.f16 s0, s3
350 ; CHECK-MVE-NEXT:    vmovx.f16 s2, s7
351 ; CHECK-MVE-NEXT:    vminnm.f16 s12, s7, s3
352 ; CHECK-MVE-NEXT:    vmov.16 q2[5], r0
353 ; CHECK-MVE-NEXT:    vmov r0, s12
354 ; CHECK-MVE-NEXT:    vminnm.f16 s0, s2, s0
355 ; CHECK-MVE-NEXT:    vmov.16 q2[6], r0
356 ; CHECK-MVE-NEXT:    vmov r0, s0
357 ; CHECK-MVE-NEXT:    vmov.16 q2[7], r0
358 ; CHECK-MVE-NEXT:    vmov q0, q2
359 ; CHECK-MVE-NEXT:    bx lr
361 ; CHECK-MVEFP-LABEL: minnm_float16_t:
362 ; CHECK-MVEFP:       @ %bb.0: @ %entry
363 ; CHECK-MVEFP-NEXT:    vminnm.f16 q0, q1, q0
364 ; CHECK-MVEFP-NEXT:    bx lr
365 entry:
366   %cmp = fcmp fast ogt <8 x half> %src2, %src1
367   %0 = select <8 x i1> %cmp, <8 x half> %src1, <8 x half> %src2
368   ret <8 x half> %0
371 define arm_aapcs_vfpcc <2 x double> @maxnm_float64_t(<2 x double> %src1, <2 x double> %src2) {
372 ; CHECK-LABEL: maxnm_float64_t:
373 ; CHECK:       @ %bb.0: @ %entry
374 ; CHECK-NEXT:    .save {r4, lr}
375 ; CHECK-NEXT:    push {r4, lr}
376 ; CHECK-NEXT:    .vsave {d8, d9, d10, d11}
377 ; CHECK-NEXT:    vpush {d8, d9, d10, d11}
378 ; CHECK-NEXT:    vmov q4, q1
379 ; CHECK-NEXT:    vmov q5, q0
380 ; CHECK-NEXT:    vmov r0, r1, d9
381 ; CHECK-NEXT:    vmov r2, r3, d11
382 ; CHECK-NEXT:    bl __aeabi_dcmpgt
383 ; CHECK-NEXT:    vmov r12, r1, d8
384 ; CHECK-NEXT:    cmp r0, #0
385 ; CHECK-NEXT:    vmov r2, r3, d10
386 ; CHECK-NEXT:    it ne
387 ; CHECK-NEXT:    movne r0, #1
388 ; CHECK-NEXT:    cmp r0, #0
389 ; CHECK-NEXT:    csetm r4, ne
390 ; CHECK-NEXT:    mov r0, r12
391 ; CHECK-NEXT:    bl __aeabi_dcmpgt
392 ; CHECK-NEXT:    cmp r0, #0
393 ; CHECK-NEXT:    it ne
394 ; CHECK-NEXT:    movne r0, #1
395 ; CHECK-NEXT:    cmp r0, #0
396 ; CHECK-NEXT:    csetm r0, ne
397 ; CHECK-NEXT:    vmov.32 q0[0], r0
398 ; CHECK-NEXT:    vmov.32 q0[1], r0
399 ; CHECK-NEXT:    vmov.32 q0[2], r4
400 ; CHECK-NEXT:    vmov.32 q0[3], r4
401 ; CHECK-NEXT:    vbic q1, q5, q0
402 ; CHECK-NEXT:    vand q0, q4, q0
403 ; CHECK-NEXT:    vorr q0, q0, q1
404 ; CHECK-NEXT:    vpop {d8, d9, d10, d11}
405 ; CHECK-NEXT:    pop {r4, pc}
406 entry:
407   %cmp = fcmp fast ogt <2 x double> %src2, %src1
408   %0 = select <2 x i1> %cmp, <2 x double> %src2, <2 x double> %src1
409   ret <2 x double> %0