1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefixes=SSE,SSE2
3 ; RUN: llc < %s -mtriple=x86_64-linux -mattr=+sse4.2 | FileCheck %s --check-prefixes=SSE,SSE42
4 ; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1
5 ; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2
6 ; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx512vl | FileCheck %s --check-prefixes=AVX,AVX512
9 ; trunc(abs(sub(zext(a),zext(b)))) -> abdu(a,b)
12 define <16 x i8> @abd_ext_v16i8(<16 x i8> %a, <16 x i8> %b) nounwind {
13 ; SSE-LABEL: abd_ext_v16i8:
15 ; SSE-NEXT: movdqa %xmm0, %xmm2
16 ; SSE-NEXT: pminub %xmm1, %xmm2
17 ; SSE-NEXT: pmaxub %xmm1, %xmm0
18 ; SSE-NEXT: psubb %xmm2, %xmm0
21 ; AVX-LABEL: abd_ext_v16i8:
23 ; AVX-NEXT: vpminub %xmm1, %xmm0, %xmm2
24 ; AVX-NEXT: vpmaxub %xmm1, %xmm0, %xmm0
25 ; AVX-NEXT: vpsubb %xmm2, %xmm0, %xmm0
27 %aext = zext <16 x i8> %a to <16 x i64>
28 %bext = zext <16 x i8> %b to <16 x i64>
29 %sub = sub <16 x i64> %aext, %bext
30 %abs = call <16 x i64> @llvm.abs.v16i64(<16 x i64> %sub, i1 false)
31 %trunc = trunc <16 x i64> %abs to <16 x i8>
35 define <16 x i8> @abd_ext_v16i8_undef(<16 x i8> %a, <16 x i8> %b) nounwind {
36 ; SSE-LABEL: abd_ext_v16i8_undef:
38 ; SSE-NEXT: movdqa %xmm0, %xmm2
39 ; SSE-NEXT: pminub %xmm1, %xmm2
40 ; SSE-NEXT: pmaxub %xmm1, %xmm0
41 ; SSE-NEXT: psubb %xmm2, %xmm0
44 ; AVX-LABEL: abd_ext_v16i8_undef:
46 ; AVX-NEXT: vpminub %xmm1, %xmm0, %xmm2
47 ; AVX-NEXT: vpmaxub %xmm1, %xmm0, %xmm0
48 ; AVX-NEXT: vpsubb %xmm2, %xmm0, %xmm0
50 %aext = zext <16 x i8> %a to <16 x i64>
51 %bext = zext <16 x i8> %b to <16 x i64>
52 %sub = sub <16 x i64> %aext, %bext
53 %abs = call <16 x i64> @llvm.abs.v16i64(<16 x i64> %sub, i1 true)
54 %trunc = trunc <16 x i64> %abs to <16 x i8>
58 define <8 x i16> @abd_ext_v8i16(<8 x i16> %a, <8 x i16> %b) nounwind {
59 ; SSE2-LABEL: abd_ext_v8i16:
61 ; SSE2-NEXT: movdqa %xmm1, %xmm2
62 ; SSE2-NEXT: psubusw %xmm0, %xmm2
63 ; SSE2-NEXT: psubusw %xmm1, %xmm0
64 ; SSE2-NEXT: por %xmm2, %xmm0
67 ; SSE42-LABEL: abd_ext_v8i16:
69 ; SSE42-NEXT: movdqa %xmm0, %xmm2
70 ; SSE42-NEXT: pminuw %xmm1, %xmm2
71 ; SSE42-NEXT: pmaxuw %xmm1, %xmm0
72 ; SSE42-NEXT: psubw %xmm2, %xmm0
75 ; AVX-LABEL: abd_ext_v8i16:
77 ; AVX-NEXT: vpminuw %xmm1, %xmm0, %xmm2
78 ; AVX-NEXT: vpmaxuw %xmm1, %xmm0, %xmm0
79 ; AVX-NEXT: vpsubw %xmm2, %xmm0, %xmm0
81 %aext = zext <8 x i16> %a to <8 x i64>
82 %bext = zext <8 x i16> %b to <8 x i64>
83 %sub = sub <8 x i64> %aext, %bext
84 %abs = call <8 x i64> @llvm.abs.v8i64(<8 x i64> %sub, i1 false)
85 %trunc = trunc <8 x i64> %abs to <8 x i16>
89 define <8 x i16> @abd_ext_v8i16_undef(<8 x i16> %a, <8 x i16> %b) nounwind {
90 ; SSE2-LABEL: abd_ext_v8i16_undef:
92 ; SSE2-NEXT: movdqa %xmm1, %xmm2
93 ; SSE2-NEXT: psubusw %xmm0, %xmm2
94 ; SSE2-NEXT: psubusw %xmm1, %xmm0
95 ; SSE2-NEXT: por %xmm2, %xmm0
98 ; SSE42-LABEL: abd_ext_v8i16_undef:
100 ; SSE42-NEXT: movdqa %xmm0, %xmm2
101 ; SSE42-NEXT: pminuw %xmm1, %xmm2
102 ; SSE42-NEXT: pmaxuw %xmm1, %xmm0
103 ; SSE42-NEXT: psubw %xmm2, %xmm0
106 ; AVX-LABEL: abd_ext_v8i16_undef:
108 ; AVX-NEXT: vpminuw %xmm1, %xmm0, %xmm2
109 ; AVX-NEXT: vpmaxuw %xmm1, %xmm0, %xmm0
110 ; AVX-NEXT: vpsubw %xmm2, %xmm0, %xmm0
112 %aext = zext <8 x i16> %a to <8 x i64>
113 %bext = zext <8 x i16> %b to <8 x i64>
114 %sub = sub <8 x i64> %aext, %bext
115 %abs = call <8 x i64> @llvm.abs.v8i64(<8 x i64> %sub, i1 true)
116 %trunc = trunc <8 x i64> %abs to <8 x i16>
120 define <4 x i32> @abd_ext_v4i32(<4 x i32> %a, <4 x i32> %b) nounwind {
121 ; SSE2-LABEL: abd_ext_v4i32:
123 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
124 ; SSE2-NEXT: movdqa %xmm1, %xmm3
125 ; SSE2-NEXT: pxor %xmm2, %xmm3
126 ; SSE2-NEXT: pxor %xmm0, %xmm2
127 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm2
128 ; SSE2-NEXT: movdqa %xmm1, %xmm3
129 ; SSE2-NEXT: psubd %xmm0, %xmm3
130 ; SSE2-NEXT: psubd %xmm1, %xmm0
131 ; SSE2-NEXT: pand %xmm2, %xmm0
132 ; SSE2-NEXT: pandn %xmm3, %xmm2
133 ; SSE2-NEXT: por %xmm2, %xmm0
136 ; SSE42-LABEL: abd_ext_v4i32:
138 ; SSE42-NEXT: movdqa %xmm0, %xmm2
139 ; SSE42-NEXT: pminud %xmm1, %xmm2
140 ; SSE42-NEXT: pmaxud %xmm1, %xmm0
141 ; SSE42-NEXT: psubd %xmm2, %xmm0
144 ; AVX-LABEL: abd_ext_v4i32:
146 ; AVX-NEXT: vpminud %xmm1, %xmm0, %xmm2
147 ; AVX-NEXT: vpmaxud %xmm1, %xmm0, %xmm0
148 ; AVX-NEXT: vpsubd %xmm2, %xmm0, %xmm0
150 %aext = zext <4 x i32> %a to <4 x i64>
151 %bext = zext <4 x i32> %b to <4 x i64>
152 %sub = sub <4 x i64> %aext, %bext
153 %abs = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %sub, i1 false)
154 %trunc = trunc <4 x i64> %abs to <4 x i32>
158 define <4 x i32> @abd_ext_v4i32_undef(<4 x i32> %a, <4 x i32> %b) nounwind {
159 ; SSE2-LABEL: abd_ext_v4i32_undef:
161 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
162 ; SSE2-NEXT: movdqa %xmm1, %xmm3
163 ; SSE2-NEXT: pxor %xmm2, %xmm3
164 ; SSE2-NEXT: pxor %xmm0, %xmm2
165 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm2
166 ; SSE2-NEXT: movdqa %xmm1, %xmm3
167 ; SSE2-NEXT: psubd %xmm0, %xmm3
168 ; SSE2-NEXT: psubd %xmm1, %xmm0
169 ; SSE2-NEXT: pand %xmm2, %xmm0
170 ; SSE2-NEXT: pandn %xmm3, %xmm2
171 ; SSE2-NEXT: por %xmm2, %xmm0
174 ; SSE42-LABEL: abd_ext_v4i32_undef:
176 ; SSE42-NEXT: movdqa %xmm0, %xmm2
177 ; SSE42-NEXT: pminud %xmm1, %xmm2
178 ; SSE42-NEXT: pmaxud %xmm1, %xmm0
179 ; SSE42-NEXT: psubd %xmm2, %xmm0
182 ; AVX-LABEL: abd_ext_v4i32_undef:
184 ; AVX-NEXT: vpminud %xmm1, %xmm0, %xmm2
185 ; AVX-NEXT: vpmaxud %xmm1, %xmm0, %xmm0
186 ; AVX-NEXT: vpsubd %xmm2, %xmm0, %xmm0
188 %aext = zext <4 x i32> %a to <4 x i64>
189 %bext = zext <4 x i32> %b to <4 x i64>
190 %sub = sub <4 x i64> %aext, %bext
191 %abs = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %sub, i1 true)
192 %trunc = trunc <4 x i64> %abs to <4 x i32>
196 define <2 x i64> @abd_ext_v2i64(<2 x i64> %a, <2 x i64> %b) nounwind {
197 ; SSE2-LABEL: abd_ext_v2i64:
199 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
200 ; SSE2-NEXT: movq %xmm2, %rax
201 ; SSE2-NEXT: movq %xmm0, %rcx
202 ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
203 ; SSE2-NEXT: movq %xmm0, %rdx
204 ; SSE2-NEXT: movq %xmm1, %rsi
205 ; SSE2-NEXT: xorl %edi, %edi
206 ; SSE2-NEXT: subq %rsi, %rcx
207 ; SSE2-NEXT: movl $0, %esi
208 ; SSE2-NEXT: sbbq %rsi, %rsi
209 ; SSE2-NEXT: subq %rdx, %rax
210 ; SSE2-NEXT: sbbq %rdi, %rdi
211 ; SSE2-NEXT: sarq $63, %rdi
212 ; SSE2-NEXT: xorq %rdi, %rax
213 ; SSE2-NEXT: subq %rdi, %rax
214 ; SSE2-NEXT: sarq $63, %rsi
215 ; SSE2-NEXT: xorq %rsi, %rcx
216 ; SSE2-NEXT: subq %rsi, %rcx
217 ; SSE2-NEXT: movq %rcx, %xmm0
218 ; SSE2-NEXT: movq %rax, %xmm1
219 ; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
222 ; SSE42-LABEL: abd_ext_v2i64:
224 ; SSE42-NEXT: movdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
225 ; SSE42-NEXT: movdqa %xmm1, %xmm3
226 ; SSE42-NEXT: pxor %xmm2, %xmm3
227 ; SSE42-NEXT: pxor %xmm0, %xmm2
228 ; SSE42-NEXT: pcmpgtq %xmm3, %xmm2
229 ; SSE42-NEXT: movdqa %xmm0, %xmm3
230 ; SSE42-NEXT: psubq %xmm1, %xmm3
231 ; SSE42-NEXT: psubq %xmm0, %xmm1
232 ; SSE42-NEXT: movdqa %xmm2, %xmm0
233 ; SSE42-NEXT: blendvpd %xmm0, %xmm3, %xmm1
234 ; SSE42-NEXT: movapd %xmm1, %xmm0
237 ; AVX1-LABEL: abd_ext_v2i64:
239 ; AVX1-NEXT: vmovddup {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
240 ; AVX1-NEXT: # xmm2 = mem[0,0]
241 ; AVX1-NEXT: vpxor %xmm2, %xmm1, %xmm3
242 ; AVX1-NEXT: vpxor %xmm2, %xmm0, %xmm2
243 ; AVX1-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2
244 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm3
245 ; AVX1-NEXT: vpsubq %xmm0, %xmm1, %xmm0
246 ; AVX1-NEXT: vblendvpd %xmm2, %xmm3, %xmm0, %xmm0
249 ; AVX2-LABEL: abd_ext_v2i64:
251 ; AVX2-NEXT: vpbroadcastq {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
252 ; AVX2-NEXT: vpxor %xmm2, %xmm1, %xmm3
253 ; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm2
254 ; AVX2-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2
255 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm3
256 ; AVX2-NEXT: vpsubq %xmm0, %xmm1, %xmm0
257 ; AVX2-NEXT: vblendvpd %xmm2, %xmm3, %xmm0, %xmm0
260 ; AVX512-LABEL: abd_ext_v2i64:
262 ; AVX512-NEXT: vpminuq %xmm1, %xmm0, %xmm2
263 ; AVX512-NEXT: vpmaxuq %xmm1, %xmm0, %xmm0
264 ; AVX512-NEXT: vpsubq %xmm2, %xmm0, %xmm0
266 %aext = zext <2 x i64> %a to <2 x i128>
267 %bext = zext <2 x i64> %b to <2 x i128>
268 %sub = sub <2 x i128> %aext, %bext
269 %abs = call <2 x i128> @llvm.abs.v2i128(<2 x i128> %sub, i1 false)
270 %trunc = trunc <2 x i128> %abs to <2 x i64>
274 define <2 x i64> @abd_ext_v2i64_undef(<2 x i64> %a, <2 x i64> %b) nounwind {
275 ; SSE2-LABEL: abd_ext_v2i64_undef:
277 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm0[2,3,2,3]
278 ; SSE2-NEXT: movq %xmm2, %rax
279 ; SSE2-NEXT: movq %xmm0, %rcx
280 ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
281 ; SSE2-NEXT: movq %xmm0, %rdx
282 ; SSE2-NEXT: movq %xmm1, %rsi
283 ; SSE2-NEXT: xorl %edi, %edi
284 ; SSE2-NEXT: subq %rsi, %rcx
285 ; SSE2-NEXT: movl $0, %esi
286 ; SSE2-NEXT: sbbq %rsi, %rsi
287 ; SSE2-NEXT: subq %rdx, %rax
288 ; SSE2-NEXT: sbbq %rdi, %rdi
289 ; SSE2-NEXT: sarq $63, %rdi
290 ; SSE2-NEXT: xorq %rdi, %rax
291 ; SSE2-NEXT: subq %rdi, %rax
292 ; SSE2-NEXT: sarq $63, %rsi
293 ; SSE2-NEXT: xorq %rsi, %rcx
294 ; SSE2-NEXT: subq %rsi, %rcx
295 ; SSE2-NEXT: movq %rcx, %xmm0
296 ; SSE2-NEXT: movq %rax, %xmm1
297 ; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
300 ; SSE42-LABEL: abd_ext_v2i64_undef:
302 ; SSE42-NEXT: movdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
303 ; SSE42-NEXT: movdqa %xmm1, %xmm3
304 ; SSE42-NEXT: pxor %xmm2, %xmm3
305 ; SSE42-NEXT: pxor %xmm0, %xmm2
306 ; SSE42-NEXT: pcmpgtq %xmm3, %xmm2
307 ; SSE42-NEXT: movdqa %xmm0, %xmm3
308 ; SSE42-NEXT: psubq %xmm1, %xmm3
309 ; SSE42-NEXT: psubq %xmm0, %xmm1
310 ; SSE42-NEXT: movdqa %xmm2, %xmm0
311 ; SSE42-NEXT: blendvpd %xmm0, %xmm3, %xmm1
312 ; SSE42-NEXT: movapd %xmm1, %xmm0
315 ; AVX1-LABEL: abd_ext_v2i64_undef:
317 ; AVX1-NEXT: vmovddup {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
318 ; AVX1-NEXT: # xmm2 = mem[0,0]
319 ; AVX1-NEXT: vpxor %xmm2, %xmm1, %xmm3
320 ; AVX1-NEXT: vpxor %xmm2, %xmm0, %xmm2
321 ; AVX1-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2
322 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm3
323 ; AVX1-NEXT: vpsubq %xmm0, %xmm1, %xmm0
324 ; AVX1-NEXT: vblendvpd %xmm2, %xmm3, %xmm0, %xmm0
327 ; AVX2-LABEL: abd_ext_v2i64_undef:
329 ; AVX2-NEXT: vpbroadcastq {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
330 ; AVX2-NEXT: vpxor %xmm2, %xmm1, %xmm3
331 ; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm2
332 ; AVX2-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2
333 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm3
334 ; AVX2-NEXT: vpsubq %xmm0, %xmm1, %xmm0
335 ; AVX2-NEXT: vblendvpd %xmm2, %xmm3, %xmm0, %xmm0
338 ; AVX512-LABEL: abd_ext_v2i64_undef:
340 ; AVX512-NEXT: vpminuq %xmm1, %xmm0, %xmm2
341 ; AVX512-NEXT: vpmaxuq %xmm1, %xmm0, %xmm0
342 ; AVX512-NEXT: vpsubq %xmm2, %xmm0, %xmm0
344 %aext = zext <2 x i64> %a to <2 x i128>
345 %bext = zext <2 x i64> %b to <2 x i128>
346 %sub = sub <2 x i128> %aext, %bext
347 %abs = call <2 x i128> @llvm.abs.v2i128(<2 x i128> %sub, i1 true)
348 %trunc = trunc <2 x i128> %abs to <2 x i64>
353 ; sub(umax(a,b),umin(a,b)) -> abdu(a,b)
356 define <16 x i8> @abd_minmax_v16i8(<16 x i8> %a, <16 x i8> %b) nounwind {
357 ; SSE-LABEL: abd_minmax_v16i8:
359 ; SSE-NEXT: movdqa %xmm0, %xmm2
360 ; SSE-NEXT: pminub %xmm1, %xmm2
361 ; SSE-NEXT: pmaxub %xmm1, %xmm0
362 ; SSE-NEXT: psubb %xmm2, %xmm0
365 ; AVX-LABEL: abd_minmax_v16i8:
367 ; AVX-NEXT: vpminub %xmm1, %xmm0, %xmm2
368 ; AVX-NEXT: vpmaxub %xmm1, %xmm0, %xmm0
369 ; AVX-NEXT: vpsubb %xmm2, %xmm0, %xmm0
371 %min = call <16 x i8> @llvm.umin.v16i8(<16 x i8> %a, <16 x i8> %b)
372 %max = call <16 x i8> @llvm.umax.v16i8(<16 x i8> %a, <16 x i8> %b)
373 %sub = sub <16 x i8> %max, %min
377 define <8 x i16> @abd_minmax_v8i16(<8 x i16> %a, <8 x i16> %b) nounwind {
378 ; SSE2-LABEL: abd_minmax_v8i16:
380 ; SSE2-NEXT: movdqa %xmm1, %xmm2
381 ; SSE2-NEXT: psubusw %xmm0, %xmm2
382 ; SSE2-NEXT: psubusw %xmm1, %xmm0
383 ; SSE2-NEXT: por %xmm2, %xmm0
386 ; SSE42-LABEL: abd_minmax_v8i16:
388 ; SSE42-NEXT: movdqa %xmm0, %xmm2
389 ; SSE42-NEXT: pminuw %xmm1, %xmm2
390 ; SSE42-NEXT: pmaxuw %xmm1, %xmm0
391 ; SSE42-NEXT: psubw %xmm2, %xmm0
394 ; AVX-LABEL: abd_minmax_v8i16:
396 ; AVX-NEXT: vpminuw %xmm1, %xmm0, %xmm2
397 ; AVX-NEXT: vpmaxuw %xmm1, %xmm0, %xmm0
398 ; AVX-NEXT: vpsubw %xmm2, %xmm0, %xmm0
400 %min = call <8 x i16> @llvm.umin.v8i16(<8 x i16> %a, <8 x i16> %b)
401 %max = call <8 x i16> @llvm.umax.v8i16(<8 x i16> %a, <8 x i16> %b)
402 %sub = sub <8 x i16> %max, %min
406 define <4 x i32> @abd_minmax_v4i32(<4 x i32> %a, <4 x i32> %b) nounwind {
407 ; SSE2-LABEL: abd_minmax_v4i32:
409 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
410 ; SSE2-NEXT: movdqa %xmm1, %xmm3
411 ; SSE2-NEXT: pxor %xmm2, %xmm3
412 ; SSE2-NEXT: pxor %xmm0, %xmm2
413 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm2
414 ; SSE2-NEXT: movdqa %xmm1, %xmm3
415 ; SSE2-NEXT: psubd %xmm0, %xmm3
416 ; SSE2-NEXT: psubd %xmm1, %xmm0
417 ; SSE2-NEXT: pand %xmm2, %xmm0
418 ; SSE2-NEXT: pandn %xmm3, %xmm2
419 ; SSE2-NEXT: por %xmm2, %xmm0
422 ; SSE42-LABEL: abd_minmax_v4i32:
424 ; SSE42-NEXT: movdqa %xmm0, %xmm2
425 ; SSE42-NEXT: pminud %xmm1, %xmm2
426 ; SSE42-NEXT: pmaxud %xmm1, %xmm0
427 ; SSE42-NEXT: psubd %xmm2, %xmm0
430 ; AVX-LABEL: abd_minmax_v4i32:
432 ; AVX-NEXT: vpminud %xmm1, %xmm0, %xmm2
433 ; AVX-NEXT: vpmaxud %xmm1, %xmm0, %xmm0
434 ; AVX-NEXT: vpsubd %xmm2, %xmm0, %xmm0
436 %min = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %a, <4 x i32> %b)
437 %max = call <4 x i32> @llvm.umax.v4i32(<4 x i32> %a, <4 x i32> %b)
438 %sub = sub <4 x i32> %max, %min
442 define <2 x i64> @abd_minmax_v2i64(<2 x i64> %a, <2 x i64> %b) nounwind {
443 ; SSE2-LABEL: abd_minmax_v2i64:
445 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [9223372039002259456,9223372039002259456]
446 ; SSE2-NEXT: movdqa %xmm1, %xmm3
447 ; SSE2-NEXT: pxor %xmm2, %xmm3
448 ; SSE2-NEXT: pxor %xmm0, %xmm2
449 ; SSE2-NEXT: movdqa %xmm2, %xmm4
450 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm4
451 ; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
452 ; SSE2-NEXT: pcmpeqd %xmm3, %xmm2
453 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
454 ; SSE2-NEXT: pand %xmm5, %xmm2
455 ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm4[1,1,3,3]
456 ; SSE2-NEXT: por %xmm2, %xmm3
457 ; SSE2-NEXT: movdqa %xmm3, %xmm2
458 ; SSE2-NEXT: pandn %xmm0, %xmm2
459 ; SSE2-NEXT: movdqa %xmm3, %xmm4
460 ; SSE2-NEXT: pandn %xmm1, %xmm4
461 ; SSE2-NEXT: pand %xmm3, %xmm1
462 ; SSE2-NEXT: por %xmm2, %xmm1
463 ; SSE2-NEXT: pand %xmm3, %xmm0
464 ; SSE2-NEXT: por %xmm4, %xmm0
465 ; SSE2-NEXT: psubq %xmm1, %xmm0
468 ; SSE42-LABEL: abd_minmax_v2i64:
470 ; SSE42-NEXT: movdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
471 ; SSE42-NEXT: movdqa %xmm1, %xmm3
472 ; SSE42-NEXT: pxor %xmm2, %xmm3
473 ; SSE42-NEXT: pxor %xmm0, %xmm2
474 ; SSE42-NEXT: pcmpgtq %xmm3, %xmm2
475 ; SSE42-NEXT: movdqa %xmm0, %xmm3
476 ; SSE42-NEXT: psubq %xmm1, %xmm3
477 ; SSE42-NEXT: psubq %xmm0, %xmm1
478 ; SSE42-NEXT: movdqa %xmm2, %xmm0
479 ; SSE42-NEXT: blendvpd %xmm0, %xmm3, %xmm1
480 ; SSE42-NEXT: movapd %xmm1, %xmm0
483 ; AVX1-LABEL: abd_minmax_v2i64:
485 ; AVX1-NEXT: vmovddup {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
486 ; AVX1-NEXT: # xmm2 = mem[0,0]
487 ; AVX1-NEXT: vpxor %xmm2, %xmm1, %xmm3
488 ; AVX1-NEXT: vpxor %xmm2, %xmm0, %xmm2
489 ; AVX1-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2
490 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm3
491 ; AVX1-NEXT: vpsubq %xmm0, %xmm1, %xmm0
492 ; AVX1-NEXT: vblendvpd %xmm2, %xmm3, %xmm0, %xmm0
495 ; AVX2-LABEL: abd_minmax_v2i64:
497 ; AVX2-NEXT: vpbroadcastq {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
498 ; AVX2-NEXT: vpxor %xmm2, %xmm1, %xmm3
499 ; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm2
500 ; AVX2-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2
501 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm3
502 ; AVX2-NEXT: vpsubq %xmm0, %xmm1, %xmm0
503 ; AVX2-NEXT: vblendvpd %xmm2, %xmm3, %xmm0, %xmm0
506 ; AVX512-LABEL: abd_minmax_v2i64:
508 ; AVX512-NEXT: vpminuq %xmm1, %xmm0, %xmm2
509 ; AVX512-NEXT: vpmaxuq %xmm1, %xmm0, %xmm0
510 ; AVX512-NEXT: vpsubq %xmm2, %xmm0, %xmm0
512 %min = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %a, <2 x i64> %b)
513 %max = call <2 x i64> @llvm.umax.v2i64(<2 x i64> %a, <2 x i64> %b)
514 %sub = sub <2 x i64> %max, %min
519 ; select(icmp(a,b),sub(a,b),sub(b,a)) -> abdu(a,b)
522 define <16 x i8> @abd_cmp_v16i8(<16 x i8> %a, <16 x i8> %b) nounwind {
523 ; SSE-LABEL: abd_cmp_v16i8:
525 ; SSE-NEXT: movdqa %xmm0, %xmm2
526 ; SSE-NEXT: pminub %xmm1, %xmm2
527 ; SSE-NEXT: pmaxub %xmm1, %xmm0
528 ; SSE-NEXT: psubb %xmm2, %xmm0
531 ; AVX-LABEL: abd_cmp_v16i8:
533 ; AVX-NEXT: vpminub %xmm1, %xmm0, %xmm2
534 ; AVX-NEXT: vpmaxub %xmm1, %xmm0, %xmm0
535 ; AVX-NEXT: vpsubb %xmm2, %xmm0, %xmm0
537 %cmp = icmp ugt <16 x i8> %a, %b
538 %ab = sub <16 x i8> %a, %b
539 %ba = sub <16 x i8> %b, %a
540 %sel = select <16 x i1> %cmp, <16 x i8> %ab, <16 x i8> %ba
544 define <8 x i16> @abd_cmp_v8i16(<8 x i16> %a, <8 x i16> %b) nounwind {
545 ; SSE2-LABEL: abd_cmp_v8i16:
547 ; SSE2-NEXT: movdqa %xmm1, %xmm2
548 ; SSE2-NEXT: psubusw %xmm0, %xmm2
549 ; SSE2-NEXT: psubusw %xmm1, %xmm0
550 ; SSE2-NEXT: por %xmm2, %xmm0
553 ; SSE42-LABEL: abd_cmp_v8i16:
555 ; SSE42-NEXT: movdqa %xmm0, %xmm2
556 ; SSE42-NEXT: pminuw %xmm1, %xmm2
557 ; SSE42-NEXT: pmaxuw %xmm1, %xmm0
558 ; SSE42-NEXT: psubw %xmm2, %xmm0
561 ; AVX-LABEL: abd_cmp_v8i16:
563 ; AVX-NEXT: vpminuw %xmm1, %xmm0, %xmm2
564 ; AVX-NEXT: vpmaxuw %xmm1, %xmm0, %xmm0
565 ; AVX-NEXT: vpsubw %xmm2, %xmm0, %xmm0
567 %cmp = icmp uge <8 x i16> %a, %b
568 %ab = sub <8 x i16> %a, %b
569 %ba = sub <8 x i16> %b, %a
570 %sel = select <8 x i1> %cmp, <8 x i16> %ab, <8 x i16> %ba
574 define <4 x i32> @abd_cmp_v4i32(<4 x i32> %a, <4 x i32> %b) nounwind {
575 ; SSE2-LABEL: abd_cmp_v4i32:
577 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]
578 ; SSE2-NEXT: movdqa %xmm1, %xmm3
579 ; SSE2-NEXT: pxor %xmm2, %xmm3
580 ; SSE2-NEXT: pxor %xmm0, %xmm2
581 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm2
582 ; SSE2-NEXT: movdqa %xmm1, %xmm3
583 ; SSE2-NEXT: psubd %xmm0, %xmm3
584 ; SSE2-NEXT: psubd %xmm1, %xmm0
585 ; SSE2-NEXT: pand %xmm2, %xmm0
586 ; SSE2-NEXT: pandn %xmm3, %xmm2
587 ; SSE2-NEXT: por %xmm2, %xmm0
590 ; SSE42-LABEL: abd_cmp_v4i32:
592 ; SSE42-NEXT: movdqa %xmm0, %xmm2
593 ; SSE42-NEXT: pminud %xmm1, %xmm2
594 ; SSE42-NEXT: pmaxud %xmm1, %xmm0
595 ; SSE42-NEXT: psubd %xmm2, %xmm0
598 ; AVX-LABEL: abd_cmp_v4i32:
600 ; AVX-NEXT: vpminud %xmm1, %xmm0, %xmm2
601 ; AVX-NEXT: vpmaxud %xmm1, %xmm0, %xmm0
602 ; AVX-NEXT: vpsubd %xmm2, %xmm0, %xmm0
604 %cmp = icmp ult <4 x i32> %a, %b
605 %ab = sub <4 x i32> %a, %b
606 %ba = sub <4 x i32> %b, %a
607 %sel = select <4 x i1> %cmp, <4 x i32> %ba, <4 x i32> %ab
611 define <2 x i64> @abd_cmp_v2i64(<2 x i64> %a, <2 x i64> %b) nounwind {
612 ; SSE2-LABEL: abd_cmp_v2i64:
614 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [9223372039002259456,9223372039002259456]
615 ; SSE2-NEXT: movdqa %xmm0, %xmm3
616 ; SSE2-NEXT: pxor %xmm2, %xmm3
617 ; SSE2-NEXT: pxor %xmm1, %xmm2
618 ; SSE2-NEXT: movdqa %xmm2, %xmm4
619 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm4
620 ; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
621 ; SSE2-NEXT: pcmpeqd %xmm3, %xmm2
622 ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
623 ; SSE2-NEXT: pand %xmm5, %xmm3
624 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm4[1,1,3,3]
625 ; SSE2-NEXT: por %xmm3, %xmm2
626 ; SSE2-NEXT: movdqa %xmm0, %xmm3
627 ; SSE2-NEXT: psubq %xmm1, %xmm3
628 ; SSE2-NEXT: psubq %xmm0, %xmm1
629 ; SSE2-NEXT: pand %xmm2, %xmm1
630 ; SSE2-NEXT: pandn %xmm3, %xmm2
631 ; SSE2-NEXT: por %xmm1, %xmm2
632 ; SSE2-NEXT: movdqa %xmm2, %xmm0
635 ; SSE42-LABEL: abd_cmp_v2i64:
637 ; SSE42-NEXT: movdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
638 ; SSE42-NEXT: movdqa %xmm1, %xmm3
639 ; SSE42-NEXT: pxor %xmm2, %xmm3
640 ; SSE42-NEXT: pxor %xmm0, %xmm2
641 ; SSE42-NEXT: pcmpgtq %xmm3, %xmm2
642 ; SSE42-NEXT: movdqa %xmm0, %xmm3
643 ; SSE42-NEXT: psubq %xmm1, %xmm3
644 ; SSE42-NEXT: psubq %xmm0, %xmm1
645 ; SSE42-NEXT: movdqa %xmm2, %xmm0
646 ; SSE42-NEXT: blendvpd %xmm0, %xmm3, %xmm1
647 ; SSE42-NEXT: movapd %xmm1, %xmm0
650 ; AVX1-LABEL: abd_cmp_v2i64:
652 ; AVX1-NEXT: vmovddup {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
653 ; AVX1-NEXT: # xmm2 = mem[0,0]
654 ; AVX1-NEXT: vpxor %xmm2, %xmm1, %xmm3
655 ; AVX1-NEXT: vpxor %xmm2, %xmm0, %xmm2
656 ; AVX1-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2
657 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm3
658 ; AVX1-NEXT: vpsubq %xmm0, %xmm1, %xmm0
659 ; AVX1-NEXT: vblendvpd %xmm2, %xmm3, %xmm0, %xmm0
662 ; AVX2-LABEL: abd_cmp_v2i64:
664 ; AVX2-NEXT: vpbroadcastq {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
665 ; AVX2-NEXT: vpxor %xmm2, %xmm1, %xmm3
666 ; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm2
667 ; AVX2-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2
668 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm3
669 ; AVX2-NEXT: vpsubq %xmm0, %xmm1, %xmm0
670 ; AVX2-NEXT: vblendvpd %xmm2, %xmm3, %xmm0, %xmm0
673 ; AVX512-LABEL: abd_cmp_v2i64:
675 ; AVX512-NEXT: vpminuq %xmm1, %xmm0, %xmm2
676 ; AVX512-NEXT: vpmaxuq %xmm1, %xmm0, %xmm0
677 ; AVX512-NEXT: vpsubq %xmm2, %xmm0, %xmm0
679 %cmp = icmp uge <2 x i64> %a, %b
680 %ab = sub <2 x i64> %a, %b
681 %ba = sub <2 x i64> %b, %a
682 %sel = select <2 x i1> %cmp, <2 x i64> %ab, <2 x i64> %ba
690 define <2 x i64> @abd_cmp_v2i64_multiuse_cmp(<2 x i64> %a, <2 x i64> %b) nounwind {
691 ; SSE2-LABEL: abd_cmp_v2i64_multiuse_cmp:
693 ; SSE2-NEXT: movdqa %xmm0, %xmm2
694 ; SSE2-NEXT: psubq %xmm1, %xmm2
695 ; SSE2-NEXT: movdqa %xmm1, %xmm3
696 ; SSE2-NEXT: psubq %xmm0, %xmm3
697 ; SSE2-NEXT: movdqa {{.*#+}} xmm4 = [9223372039002259456,9223372039002259456]
698 ; SSE2-NEXT: pxor %xmm4, %xmm1
699 ; SSE2-NEXT: pxor %xmm4, %xmm0
700 ; SSE2-NEXT: movdqa %xmm0, %xmm4
701 ; SSE2-NEXT: pcmpgtd %xmm1, %xmm4
702 ; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
703 ; SSE2-NEXT: pcmpeqd %xmm1, %xmm0
704 ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
705 ; SSE2-NEXT: pand %xmm5, %xmm0
706 ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm4[1,1,3,3]
707 ; SSE2-NEXT: por %xmm0, %xmm1
708 ; SSE2-NEXT: movdqa %xmm1, %xmm0
709 ; SSE2-NEXT: pandn %xmm3, %xmm0
710 ; SSE2-NEXT: pand %xmm1, %xmm2
711 ; SSE2-NEXT: por %xmm0, %xmm2
712 ; SSE2-NEXT: paddq %xmm1, %xmm2
713 ; SSE2-NEXT: movdqa %xmm2, %xmm0
716 ; SSE42-LABEL: abd_cmp_v2i64_multiuse_cmp:
718 ; SSE42-NEXT: movdqa {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
719 ; SSE42-NEXT: movdqa %xmm1, %xmm3
720 ; SSE42-NEXT: pxor %xmm2, %xmm3
721 ; SSE42-NEXT: pxor %xmm0, %xmm2
722 ; SSE42-NEXT: pcmpgtq %xmm3, %xmm2
723 ; SSE42-NEXT: movdqa %xmm0, %xmm3
724 ; SSE42-NEXT: psubq %xmm1, %xmm3
725 ; SSE42-NEXT: psubq %xmm0, %xmm1
726 ; SSE42-NEXT: movdqa %xmm2, %xmm0
727 ; SSE42-NEXT: blendvpd %xmm0, %xmm3, %xmm1
728 ; SSE42-NEXT: paddq %xmm1, %xmm2
729 ; SSE42-NEXT: movdqa %xmm2, %xmm0
732 ; AVX1-LABEL: abd_cmp_v2i64_multiuse_cmp:
734 ; AVX1-NEXT: vmovddup {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
735 ; AVX1-NEXT: # xmm2 = mem[0,0]
736 ; AVX1-NEXT: vpxor %xmm2, %xmm1, %xmm3
737 ; AVX1-NEXT: vpxor %xmm2, %xmm0, %xmm2
738 ; AVX1-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2
739 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm3
740 ; AVX1-NEXT: vpsubq %xmm0, %xmm1, %xmm0
741 ; AVX1-NEXT: vblendvpd %xmm2, %xmm3, %xmm0, %xmm0
742 ; AVX1-NEXT: vpaddq %xmm0, %xmm2, %xmm0
745 ; AVX2-LABEL: abd_cmp_v2i64_multiuse_cmp:
747 ; AVX2-NEXT: vpbroadcastq {{.*#+}} xmm2 = [9223372036854775808,9223372036854775808]
748 ; AVX2-NEXT: vpxor %xmm2, %xmm1, %xmm3
749 ; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm2
750 ; AVX2-NEXT: vpcmpgtq %xmm3, %xmm2, %xmm2
751 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm3
752 ; AVX2-NEXT: vpsubq %xmm0, %xmm1, %xmm0
753 ; AVX2-NEXT: vblendvpd %xmm2, %xmm3, %xmm0, %xmm0
754 ; AVX2-NEXT: vpaddq %xmm0, %xmm2, %xmm0
757 ; AVX512-LABEL: abd_cmp_v2i64_multiuse_cmp:
759 ; AVX512-NEXT: vpcmpnleuq %xmm1, %xmm0, %k1
760 ; AVX512-NEXT: vpminuq %xmm1, %xmm0, %xmm2
761 ; AVX512-NEXT: vpmaxuq %xmm1, %xmm0, %xmm0
762 ; AVX512-NEXT: vpsubq %xmm2, %xmm0, %xmm0
763 ; AVX512-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
764 ; AVX512-NEXT: vpaddq %xmm1, %xmm0, %xmm0 {%k1}
766 %cmp = icmp ugt <2 x i64> %a, %b
767 %ab = sub <2 x i64> %a, %b
768 %ba = sub <2 x i64> %b, %a
769 %sel = select <2 x i1> %cmp, <2 x i64> %ab, <2 x i64> %ba
770 %ext = sext <2 x i1> %cmp to <2 x i64>
771 %res = add <2 x i64> %ext, %sel
775 define <8 x i16> @abd_cmp_v8i16_multiuse_sub(<8 x i16> %a, <8 x i16> %b) nounwind {
776 ; SSE2-LABEL: abd_cmp_v8i16_multiuse_sub:
778 ; SSE2-NEXT: movdqa %xmm0, %xmm2
779 ; SSE2-NEXT: psubw %xmm1, %xmm2
780 ; SSE2-NEXT: movdqa %xmm1, %xmm3
781 ; SSE2-NEXT: psubusw %xmm0, %xmm3
782 ; SSE2-NEXT: psubusw %xmm1, %xmm0
783 ; SSE2-NEXT: por %xmm3, %xmm0
784 ; SSE2-NEXT: paddw %xmm2, %xmm0
787 ; SSE42-LABEL: abd_cmp_v8i16_multiuse_sub:
789 ; SSE42-NEXT: movdqa %xmm0, %xmm2
790 ; SSE42-NEXT: psubw %xmm1, %xmm2
791 ; SSE42-NEXT: movdqa %xmm0, %xmm3
792 ; SSE42-NEXT: pminuw %xmm1, %xmm3
793 ; SSE42-NEXT: pmaxuw %xmm1, %xmm0
794 ; SSE42-NEXT: psubw %xmm3, %xmm0
795 ; SSE42-NEXT: paddw %xmm2, %xmm0
798 ; AVX-LABEL: abd_cmp_v8i16_multiuse_sub:
800 ; AVX-NEXT: vpsubw %xmm1, %xmm0, %xmm2
801 ; AVX-NEXT: vpminuw %xmm1, %xmm0, %xmm3
802 ; AVX-NEXT: vpmaxuw %xmm1, %xmm0, %xmm0
803 ; AVX-NEXT: vpsubw %xmm3, %xmm0, %xmm0
804 ; AVX-NEXT: vpaddw %xmm0, %xmm2, %xmm0
806 %cmp = icmp uge <8 x i16> %a, %b
807 %ab = sub <8 x i16> %a, %b
808 %ba = sub <8 x i16> %b, %a
809 %sel = select <8 x i1> %cmp, <8 x i16> %ab, <8 x i16> %ba
810 %res = add <8 x i16> %ab, %sel
814 declare <16 x i8> @llvm.abs.v16i8(<16 x i8>, i1)
815 declare <8 x i16> @llvm.abs.v8i16(<8 x i16>, i1)
816 declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1)
817 declare <2 x i64> @llvm.abs.v2i64(<2 x i64>, i1)
818 declare <4 x i64> @llvm.abs.v4i64(<4 x i64>, i1)
819 declare <8 x i64> @llvm.abs.v8i64(<8 x i64>, i1)
820 declare <16 x i64> @llvm.abs.v16i64(<16 x i64>, i1)
821 declare <2 x i128> @llvm.abs.v2i128(<2 x i128>, i1)
823 declare <16 x i8> @llvm.umax.v16i8(<16 x i8>, <16 x i8>)
824 declare <8 x i16> @llvm.umax.v8i16(<8 x i16>, <8 x i16>)
825 declare <4 x i32> @llvm.umax.v4i32(<4 x i32>, <4 x i32>)
826 declare <2 x i64> @llvm.umax.v2i64(<2 x i64>, <2 x i64>)
828 declare <16 x i8> @llvm.umin.v16i8(<16 x i8>, <16 x i8>)
829 declare <8 x i16> @llvm.umin.v8i16(<8 x i16>, <8 x i16>)
830 declare <4 x i32> @llvm.umin.v4i32(<4 x i32>, <4 x i32>)
831 declare <2 x i64> @llvm.umin.v2i64(<2 x i64>, <2 x i64>)