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(sext(a),sext(b)))) -> abds(a,b)
12 define <16 x i8> @abd_ext_v16i8(<16 x i8> %a, <16 x i8> %b) nounwind {
13 ; SSE2-LABEL: abd_ext_v16i8:
15 ; SSE2-NEXT: movdqa %xmm0, %xmm2
16 ; SSE2-NEXT: pcmpgtb %xmm1, %xmm2
17 ; SSE2-NEXT: psubb %xmm1, %xmm0
18 ; SSE2-NEXT: pxor %xmm2, %xmm0
19 ; SSE2-NEXT: psubb %xmm0, %xmm2
20 ; SSE2-NEXT: movdqa %xmm2, %xmm0
23 ; SSE42-LABEL: abd_ext_v16i8:
25 ; SSE42-NEXT: movdqa %xmm0, %xmm2
26 ; SSE42-NEXT: pminsb %xmm1, %xmm2
27 ; SSE42-NEXT: pmaxsb %xmm1, %xmm0
28 ; SSE42-NEXT: psubb %xmm2, %xmm0
31 ; AVX-LABEL: abd_ext_v16i8:
33 ; AVX-NEXT: vpminsb %xmm1, %xmm0, %xmm2
34 ; AVX-NEXT: vpmaxsb %xmm1, %xmm0, %xmm0
35 ; AVX-NEXT: vpsubb %xmm2, %xmm0, %xmm0
37 %aext = sext <16 x i8> %a to <16 x i64>
38 %bext = sext <16 x i8> %b to <16 x i64>
39 %sub = sub <16 x i64> %aext, %bext
40 %abs = call <16 x i64> @llvm.abs.v16i64(<16 x i64> %sub, i1 false)
41 %trunc = trunc <16 x i64> %abs to <16 x i8>
45 define <16 x i8> @abd_ext_v16i8_undef(<16 x i8> %a, <16 x i8> %b) nounwind {
46 ; SSE2-LABEL: abd_ext_v16i8_undef:
48 ; SSE2-NEXT: movdqa %xmm0, %xmm2
49 ; SSE2-NEXT: pcmpgtb %xmm1, %xmm2
50 ; SSE2-NEXT: psubb %xmm1, %xmm0
51 ; SSE2-NEXT: pxor %xmm2, %xmm0
52 ; SSE2-NEXT: psubb %xmm0, %xmm2
53 ; SSE2-NEXT: movdqa %xmm2, %xmm0
56 ; SSE42-LABEL: abd_ext_v16i8_undef:
58 ; SSE42-NEXT: movdqa %xmm0, %xmm2
59 ; SSE42-NEXT: pminsb %xmm1, %xmm2
60 ; SSE42-NEXT: pmaxsb %xmm1, %xmm0
61 ; SSE42-NEXT: psubb %xmm2, %xmm0
64 ; AVX-LABEL: abd_ext_v16i8_undef:
66 ; AVX-NEXT: vpminsb %xmm1, %xmm0, %xmm2
67 ; AVX-NEXT: vpmaxsb %xmm1, %xmm0, %xmm0
68 ; AVX-NEXT: vpsubb %xmm2, %xmm0, %xmm0
70 %aext = sext <16 x i8> %a to <16 x i64>
71 %bext = sext <16 x i8> %b to <16 x i64>
72 %sub = sub <16 x i64> %aext, %bext
73 %abs = call <16 x i64> @llvm.abs.v16i64(<16 x i64> %sub, i1 true)
74 %trunc = trunc <16 x i64> %abs to <16 x i8>
78 define <8 x i16> @abd_ext_v8i16(<8 x i16> %a, <8 x i16> %b) nounwind {
79 ; SSE-LABEL: abd_ext_v8i16:
81 ; SSE-NEXT: movdqa %xmm0, %xmm2
82 ; SSE-NEXT: pminsw %xmm1, %xmm2
83 ; SSE-NEXT: pmaxsw %xmm1, %xmm0
84 ; SSE-NEXT: psubw %xmm2, %xmm0
87 ; AVX-LABEL: abd_ext_v8i16:
89 ; AVX-NEXT: vpminsw %xmm1, %xmm0, %xmm2
90 ; AVX-NEXT: vpmaxsw %xmm1, %xmm0, %xmm0
91 ; AVX-NEXT: vpsubw %xmm2, %xmm0, %xmm0
93 %aext = sext <8 x i16> %a to <8 x i64>
94 %bext = sext <8 x i16> %b to <8 x i64>
95 %sub = sub <8 x i64> %aext, %bext
96 %abs = call <8 x i64> @llvm.abs.v8i64(<8 x i64> %sub, i1 false)
97 %trunc = trunc <8 x i64> %abs to <8 x i16>
101 define <8 x i16> @abd_ext_v8i16_undef(<8 x i16> %a, <8 x i16> %b) nounwind {
102 ; SSE-LABEL: abd_ext_v8i16_undef:
104 ; SSE-NEXT: movdqa %xmm0, %xmm2
105 ; SSE-NEXT: pminsw %xmm1, %xmm2
106 ; SSE-NEXT: pmaxsw %xmm1, %xmm0
107 ; SSE-NEXT: psubw %xmm2, %xmm0
110 ; AVX-LABEL: abd_ext_v8i16_undef:
112 ; AVX-NEXT: vpminsw %xmm1, %xmm0, %xmm2
113 ; AVX-NEXT: vpmaxsw %xmm1, %xmm0, %xmm0
114 ; AVX-NEXT: vpsubw %xmm2, %xmm0, %xmm0
116 %aext = sext <8 x i16> %a to <8 x i64>
117 %bext = sext <8 x i16> %b to <8 x i64>
118 %sub = sub <8 x i64> %aext, %bext
119 %abs = call <8 x i64> @llvm.abs.v8i64(<8 x i64> %sub, i1 true)
120 %trunc = trunc <8 x i64> %abs to <8 x i16>
124 define <4 x i32> @abd_ext_v4i32(<4 x i32> %a, <4 x i32> %b) nounwind {
125 ; SSE2-LABEL: abd_ext_v4i32:
127 ; SSE2-NEXT: movdqa %xmm0, %xmm2
128 ; SSE2-NEXT: pcmpgtd %xmm1, %xmm2
129 ; SSE2-NEXT: psubd %xmm1, %xmm0
130 ; SSE2-NEXT: pxor %xmm2, %xmm0
131 ; SSE2-NEXT: psubd %xmm0, %xmm2
132 ; SSE2-NEXT: movdqa %xmm2, %xmm0
135 ; SSE42-LABEL: abd_ext_v4i32:
137 ; SSE42-NEXT: movdqa %xmm0, %xmm2
138 ; SSE42-NEXT: pminsd %xmm1, %xmm2
139 ; SSE42-NEXT: pmaxsd %xmm1, %xmm0
140 ; SSE42-NEXT: psubd %xmm2, %xmm0
143 ; AVX-LABEL: abd_ext_v4i32:
145 ; AVX-NEXT: vpminsd %xmm1, %xmm0, %xmm2
146 ; AVX-NEXT: vpmaxsd %xmm1, %xmm0, %xmm0
147 ; AVX-NEXT: vpsubd %xmm2, %xmm0, %xmm0
149 %aext = sext <4 x i32> %a to <4 x i64>
150 %bext = sext <4 x i32> %b to <4 x i64>
151 %sub = sub <4 x i64> %aext, %bext
152 %abs = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %sub, i1 false)
153 %trunc = trunc <4 x i64> %abs to <4 x i32>
157 define <4 x i32> @abd_ext_v4i32_undef(<4 x i32> %a, <4 x i32> %b) nounwind {
158 ; SSE2-LABEL: abd_ext_v4i32_undef:
160 ; SSE2-NEXT: movdqa %xmm0, %xmm2
161 ; SSE2-NEXT: pcmpgtd %xmm1, %xmm2
162 ; SSE2-NEXT: psubd %xmm1, %xmm0
163 ; SSE2-NEXT: pxor %xmm2, %xmm0
164 ; SSE2-NEXT: psubd %xmm0, %xmm2
165 ; SSE2-NEXT: movdqa %xmm2, %xmm0
168 ; SSE42-LABEL: abd_ext_v4i32_undef:
170 ; SSE42-NEXT: movdqa %xmm0, %xmm2
171 ; SSE42-NEXT: pminsd %xmm1, %xmm2
172 ; SSE42-NEXT: pmaxsd %xmm1, %xmm0
173 ; SSE42-NEXT: psubd %xmm2, %xmm0
176 ; AVX-LABEL: abd_ext_v4i32_undef:
178 ; AVX-NEXT: vpminsd %xmm1, %xmm0, %xmm2
179 ; AVX-NEXT: vpmaxsd %xmm1, %xmm0, %xmm0
180 ; AVX-NEXT: vpsubd %xmm2, %xmm0, %xmm0
182 %aext = sext <4 x i32> %a to <4 x i64>
183 %bext = sext <4 x i32> %b to <4 x i64>
184 %sub = sub <4 x i64> %aext, %bext
185 %abs = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %sub, i1 true)
186 %trunc = trunc <4 x i64> %abs to <4 x i32>
190 define <2 x i64> @abd_ext_v2i64(<2 x i64> %a, <2 x i64> %b) nounwind {
191 ; SSE2-LABEL: abd_ext_v2i64:
193 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648]
194 ; SSE2-NEXT: movdqa %xmm1, %xmm3
195 ; SSE2-NEXT: pxor %xmm2, %xmm3
196 ; SSE2-NEXT: pxor %xmm0, %xmm2
197 ; SSE2-NEXT: movdqa %xmm2, %xmm4
198 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm4
199 ; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
200 ; SSE2-NEXT: pcmpeqd %xmm3, %xmm2
201 ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
202 ; SSE2-NEXT: pand %xmm5, %xmm3
203 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm4[1,1,3,3]
204 ; SSE2-NEXT: por %xmm3, %xmm2
205 ; SSE2-NEXT: psubq %xmm1, %xmm0
206 ; SSE2-NEXT: pxor %xmm2, %xmm0
207 ; SSE2-NEXT: psubq %xmm0, %xmm2
208 ; SSE2-NEXT: movdqa %xmm2, %xmm0
211 ; SSE42-LABEL: abd_ext_v2i64:
213 ; SSE42-NEXT: movdqa %xmm0, %xmm2
214 ; SSE42-NEXT: pcmpgtq %xmm1, %xmm2
215 ; SSE42-NEXT: psubq %xmm1, %xmm0
216 ; SSE42-NEXT: pxor %xmm2, %xmm0
217 ; SSE42-NEXT: psubq %xmm0, %xmm2
218 ; SSE42-NEXT: movdqa %xmm2, %xmm0
221 ; AVX1-LABEL: abd_ext_v2i64:
223 ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm2
224 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0
225 ; AVX1-NEXT: vpxor %xmm2, %xmm0, %xmm0
226 ; AVX1-NEXT: vpsubq %xmm0, %xmm2, %xmm0
229 ; AVX2-LABEL: abd_ext_v2i64:
231 ; AVX2-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm2
232 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm0
233 ; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm0
234 ; AVX2-NEXT: vpsubq %xmm0, %xmm2, %xmm0
237 ; AVX512-LABEL: abd_ext_v2i64:
239 ; AVX512-NEXT: vpminsq %xmm1, %xmm0, %xmm2
240 ; AVX512-NEXT: vpmaxsq %xmm1, %xmm0, %xmm0
241 ; AVX512-NEXT: vpsubq %xmm2, %xmm0, %xmm0
243 %aext = sext <2 x i64> %a to <2 x i128>
244 %bext = sext <2 x i64> %b to <2 x i128>
245 %sub = sub <2 x i128> %aext, %bext
246 %abs = call <2 x i128> @llvm.abs.v2i128(<2 x i128> %sub, i1 false)
247 %trunc = trunc <2 x i128> %abs to <2 x i64>
251 define <2 x i64> @abd_ext_v2i64_undef(<2 x i64> %a, <2 x i64> %b) nounwind {
252 ; SSE2-LABEL: abd_ext_v2i64_undef:
254 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648]
255 ; SSE2-NEXT: movdqa %xmm1, %xmm3
256 ; SSE2-NEXT: pxor %xmm2, %xmm3
257 ; SSE2-NEXT: pxor %xmm0, %xmm2
258 ; SSE2-NEXT: movdqa %xmm2, %xmm4
259 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm4
260 ; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
261 ; SSE2-NEXT: pcmpeqd %xmm3, %xmm2
262 ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
263 ; SSE2-NEXT: pand %xmm5, %xmm3
264 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm4[1,1,3,3]
265 ; SSE2-NEXT: por %xmm3, %xmm2
266 ; SSE2-NEXT: psubq %xmm1, %xmm0
267 ; SSE2-NEXT: pxor %xmm2, %xmm0
268 ; SSE2-NEXT: psubq %xmm0, %xmm2
269 ; SSE2-NEXT: movdqa %xmm2, %xmm0
272 ; SSE42-LABEL: abd_ext_v2i64_undef:
274 ; SSE42-NEXT: movdqa %xmm0, %xmm2
275 ; SSE42-NEXT: pcmpgtq %xmm1, %xmm2
276 ; SSE42-NEXT: psubq %xmm1, %xmm0
277 ; SSE42-NEXT: pxor %xmm2, %xmm0
278 ; SSE42-NEXT: psubq %xmm0, %xmm2
279 ; SSE42-NEXT: movdqa %xmm2, %xmm0
282 ; AVX1-LABEL: abd_ext_v2i64_undef:
284 ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm2
285 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0
286 ; AVX1-NEXT: vpxor %xmm2, %xmm0, %xmm0
287 ; AVX1-NEXT: vpsubq %xmm0, %xmm2, %xmm0
290 ; AVX2-LABEL: abd_ext_v2i64_undef:
292 ; AVX2-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm2
293 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm0
294 ; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm0
295 ; AVX2-NEXT: vpsubq %xmm0, %xmm2, %xmm0
298 ; AVX512-LABEL: abd_ext_v2i64_undef:
300 ; AVX512-NEXT: vpminsq %xmm1, %xmm0, %xmm2
301 ; AVX512-NEXT: vpmaxsq %xmm1, %xmm0, %xmm0
302 ; AVX512-NEXT: vpsubq %xmm2, %xmm0, %xmm0
304 %aext = sext <2 x i64> %a to <2 x i128>
305 %bext = sext <2 x i64> %b to <2 x i128>
306 %sub = sub <2 x i128> %aext, %bext
307 %abs = call <2 x i128> @llvm.abs.v2i128(<2 x i128> %sub, i1 true)
308 %trunc = trunc <2 x i128> %abs to <2 x i64>
313 ; sub(smax(a,b),smin(a,b)) -> abds(a,b)
316 define <16 x i8> @abd_minmax_v16i8(<16 x i8> %a, <16 x i8> %b) nounwind {
317 ; SSE2-LABEL: abd_minmax_v16i8:
319 ; SSE2-NEXT: movdqa %xmm0, %xmm2
320 ; SSE2-NEXT: pcmpgtb %xmm1, %xmm2
321 ; SSE2-NEXT: psubb %xmm1, %xmm0
322 ; SSE2-NEXT: pxor %xmm2, %xmm0
323 ; SSE2-NEXT: psubb %xmm0, %xmm2
324 ; SSE2-NEXT: movdqa %xmm2, %xmm0
327 ; SSE42-LABEL: abd_minmax_v16i8:
329 ; SSE42-NEXT: movdqa %xmm0, %xmm2
330 ; SSE42-NEXT: pminsb %xmm1, %xmm2
331 ; SSE42-NEXT: pmaxsb %xmm1, %xmm0
332 ; SSE42-NEXT: psubb %xmm2, %xmm0
335 ; AVX-LABEL: abd_minmax_v16i8:
337 ; AVX-NEXT: vpminsb %xmm1, %xmm0, %xmm2
338 ; AVX-NEXT: vpmaxsb %xmm1, %xmm0, %xmm0
339 ; AVX-NEXT: vpsubb %xmm2, %xmm0, %xmm0
341 %min = call <16 x i8> @llvm.smin.v16i8(<16 x i8> %a, <16 x i8> %b)
342 %max = call <16 x i8> @llvm.smax.v16i8(<16 x i8> %a, <16 x i8> %b)
343 %sub = sub <16 x i8> %max, %min
347 define <8 x i16> @abd_minmax_v8i16(<8 x i16> %a, <8 x i16> %b) nounwind {
348 ; SSE-LABEL: abd_minmax_v8i16:
350 ; SSE-NEXT: movdqa %xmm0, %xmm2
351 ; SSE-NEXT: pminsw %xmm1, %xmm2
352 ; SSE-NEXT: pmaxsw %xmm1, %xmm0
353 ; SSE-NEXT: psubw %xmm2, %xmm0
356 ; AVX-LABEL: abd_minmax_v8i16:
358 ; AVX-NEXT: vpminsw %xmm1, %xmm0, %xmm2
359 ; AVX-NEXT: vpmaxsw %xmm1, %xmm0, %xmm0
360 ; AVX-NEXT: vpsubw %xmm2, %xmm0, %xmm0
362 %min = call <8 x i16> @llvm.smin.v8i16(<8 x i16> %a, <8 x i16> %b)
363 %max = call <8 x i16> @llvm.smax.v8i16(<8 x i16> %a, <8 x i16> %b)
364 %sub = sub <8 x i16> %max, %min
368 define <4 x i32> @abd_minmax_v4i32(<4 x i32> %a, <4 x i32> %b) nounwind {
369 ; SSE2-LABEL: abd_minmax_v4i32:
371 ; SSE2-NEXT: movdqa %xmm0, %xmm2
372 ; SSE2-NEXT: pcmpgtd %xmm1, %xmm2
373 ; SSE2-NEXT: psubd %xmm1, %xmm0
374 ; SSE2-NEXT: pxor %xmm2, %xmm0
375 ; SSE2-NEXT: psubd %xmm0, %xmm2
376 ; SSE2-NEXT: movdqa %xmm2, %xmm0
379 ; SSE42-LABEL: abd_minmax_v4i32:
381 ; SSE42-NEXT: movdqa %xmm0, %xmm2
382 ; SSE42-NEXT: pminsd %xmm1, %xmm2
383 ; SSE42-NEXT: pmaxsd %xmm1, %xmm0
384 ; SSE42-NEXT: psubd %xmm2, %xmm0
387 ; AVX-LABEL: abd_minmax_v4i32:
389 ; AVX-NEXT: vpminsd %xmm1, %xmm0, %xmm2
390 ; AVX-NEXT: vpmaxsd %xmm1, %xmm0, %xmm0
391 ; AVX-NEXT: vpsubd %xmm2, %xmm0, %xmm0
393 %min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %a, <4 x i32> %b)
394 %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %a, <4 x i32> %b)
395 %sub = sub <4 x i32> %max, %min
399 define <2 x i64> @abd_minmax_v2i64(<2 x i64> %a, <2 x i64> %b) nounwind {
400 ; SSE2-LABEL: abd_minmax_v2i64:
402 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648]
403 ; SSE2-NEXT: movdqa %xmm1, %xmm3
404 ; SSE2-NEXT: pxor %xmm2, %xmm3
405 ; SSE2-NEXT: pxor %xmm0, %xmm2
406 ; SSE2-NEXT: movdqa %xmm2, %xmm4
407 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm4
408 ; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
409 ; SSE2-NEXT: pcmpeqd %xmm3, %xmm2
410 ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
411 ; SSE2-NEXT: pand %xmm5, %xmm3
412 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm4[1,1,3,3]
413 ; SSE2-NEXT: por %xmm3, %xmm2
414 ; SSE2-NEXT: psubq %xmm1, %xmm0
415 ; SSE2-NEXT: pxor %xmm2, %xmm0
416 ; SSE2-NEXT: psubq %xmm0, %xmm2
417 ; SSE2-NEXT: movdqa %xmm2, %xmm0
420 ; SSE42-LABEL: abd_minmax_v2i64:
422 ; SSE42-NEXT: movdqa %xmm0, %xmm2
423 ; SSE42-NEXT: pcmpgtq %xmm1, %xmm2
424 ; SSE42-NEXT: psubq %xmm1, %xmm0
425 ; SSE42-NEXT: pxor %xmm2, %xmm0
426 ; SSE42-NEXT: psubq %xmm0, %xmm2
427 ; SSE42-NEXT: movdqa %xmm2, %xmm0
430 ; AVX1-LABEL: abd_minmax_v2i64:
432 ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm2
433 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0
434 ; AVX1-NEXT: vpxor %xmm2, %xmm0, %xmm0
435 ; AVX1-NEXT: vpsubq %xmm0, %xmm2, %xmm0
438 ; AVX2-LABEL: abd_minmax_v2i64:
440 ; AVX2-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm2
441 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm0
442 ; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm0
443 ; AVX2-NEXT: vpsubq %xmm0, %xmm2, %xmm0
446 ; AVX512-LABEL: abd_minmax_v2i64:
448 ; AVX512-NEXT: vpminsq %xmm1, %xmm0, %xmm2
449 ; AVX512-NEXT: vpmaxsq %xmm1, %xmm0, %xmm0
450 ; AVX512-NEXT: vpsubq %xmm2, %xmm0, %xmm0
452 %min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %a, <2 x i64> %b)
453 %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %a, <2 x i64> %b)
454 %sub = sub <2 x i64> %max, %min
459 ; select(icmp(a,b),sub(a,b),sub(b,a)) -> abds(a,b)
462 define <16 x i8> @abd_cmp_v16i8(<16 x i8> %a, <16 x i8> %b) nounwind {
463 ; SSE2-LABEL: abd_cmp_v16i8:
465 ; SSE2-NEXT: movdqa %xmm0, %xmm2
466 ; SSE2-NEXT: pcmpgtb %xmm1, %xmm2
467 ; SSE2-NEXT: psubb %xmm1, %xmm0
468 ; SSE2-NEXT: pxor %xmm2, %xmm0
469 ; SSE2-NEXT: psubb %xmm0, %xmm2
470 ; SSE2-NEXT: movdqa %xmm2, %xmm0
473 ; SSE42-LABEL: abd_cmp_v16i8:
475 ; SSE42-NEXT: movdqa %xmm0, %xmm2
476 ; SSE42-NEXT: pminsb %xmm1, %xmm2
477 ; SSE42-NEXT: pmaxsb %xmm1, %xmm0
478 ; SSE42-NEXT: psubb %xmm2, %xmm0
481 ; AVX-LABEL: abd_cmp_v16i8:
483 ; AVX-NEXT: vpminsb %xmm1, %xmm0, %xmm2
484 ; AVX-NEXT: vpmaxsb %xmm1, %xmm0, %xmm0
485 ; AVX-NEXT: vpsubb %xmm2, %xmm0, %xmm0
487 %cmp = icmp sgt <16 x i8> %a, %b
488 %ab = sub <16 x i8> %a, %b
489 %ba = sub <16 x i8> %b, %a
490 %sel = select <16 x i1> %cmp, <16 x i8> %ab, <16 x i8> %ba
494 define <8 x i16> @abd_cmp_v8i16(<8 x i16> %a, <8 x i16> %b) nounwind {
495 ; SSE-LABEL: abd_cmp_v8i16:
497 ; SSE-NEXT: movdqa %xmm0, %xmm2
498 ; SSE-NEXT: pminsw %xmm1, %xmm2
499 ; SSE-NEXT: pmaxsw %xmm1, %xmm0
500 ; SSE-NEXT: psubw %xmm2, %xmm0
503 ; AVX-LABEL: abd_cmp_v8i16:
505 ; AVX-NEXT: vpminsw %xmm1, %xmm0, %xmm2
506 ; AVX-NEXT: vpmaxsw %xmm1, %xmm0, %xmm0
507 ; AVX-NEXT: vpsubw %xmm2, %xmm0, %xmm0
509 %cmp = icmp sge <8 x i16> %a, %b
510 %ab = sub <8 x i16> %a, %b
511 %ba = sub <8 x i16> %b, %a
512 %sel = select <8 x i1> %cmp, <8 x i16> %ab, <8 x i16> %ba
516 define <4 x i32> @abd_cmp_v4i32(<4 x i32> %a, <4 x i32> %b) nounwind {
517 ; SSE2-LABEL: abd_cmp_v4i32:
519 ; SSE2-NEXT: movdqa %xmm0, %xmm2
520 ; SSE2-NEXT: pcmpgtd %xmm1, %xmm2
521 ; SSE2-NEXT: psubd %xmm1, %xmm0
522 ; SSE2-NEXT: pxor %xmm2, %xmm0
523 ; SSE2-NEXT: psubd %xmm0, %xmm2
524 ; SSE2-NEXT: movdqa %xmm2, %xmm0
527 ; SSE42-LABEL: abd_cmp_v4i32:
529 ; SSE42-NEXT: movdqa %xmm0, %xmm2
530 ; SSE42-NEXT: pminsd %xmm1, %xmm2
531 ; SSE42-NEXT: pmaxsd %xmm1, %xmm0
532 ; SSE42-NEXT: psubd %xmm2, %xmm0
535 ; AVX-LABEL: abd_cmp_v4i32:
537 ; AVX-NEXT: vpminsd %xmm1, %xmm0, %xmm2
538 ; AVX-NEXT: vpmaxsd %xmm1, %xmm0, %xmm0
539 ; AVX-NEXT: vpsubd %xmm2, %xmm0, %xmm0
541 %cmp = icmp slt <4 x i32> %a, %b
542 %ab = sub <4 x i32> %a, %b
543 %ba = sub <4 x i32> %b, %a
544 %sel = select <4 x i1> %cmp, <4 x i32> %ba, <4 x i32> %ab
548 define <2 x i64> @abd_cmp_v2i64(<2 x i64> %a, <2 x i64> %b) nounwind {
549 ; SSE2-LABEL: abd_cmp_v2i64:
551 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648]
552 ; SSE2-NEXT: movdqa %xmm1, %xmm3
553 ; SSE2-NEXT: pxor %xmm2, %xmm3
554 ; SSE2-NEXT: pxor %xmm0, %xmm2
555 ; SSE2-NEXT: movdqa %xmm2, %xmm4
556 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm4
557 ; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
558 ; SSE2-NEXT: pcmpeqd %xmm3, %xmm2
559 ; SSE2-NEXT: pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
560 ; SSE2-NEXT: pand %xmm5, %xmm3
561 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm4[1,1,3,3]
562 ; SSE2-NEXT: por %xmm3, %xmm2
563 ; SSE2-NEXT: psubq %xmm1, %xmm0
564 ; SSE2-NEXT: pxor %xmm2, %xmm0
565 ; SSE2-NEXT: psubq %xmm0, %xmm2
566 ; SSE2-NEXT: movdqa %xmm2, %xmm0
569 ; SSE42-LABEL: abd_cmp_v2i64:
571 ; SSE42-NEXT: movdqa %xmm0, %xmm2
572 ; SSE42-NEXT: pcmpgtq %xmm1, %xmm2
573 ; SSE42-NEXT: psubq %xmm1, %xmm0
574 ; SSE42-NEXT: pxor %xmm2, %xmm0
575 ; SSE42-NEXT: psubq %xmm0, %xmm2
576 ; SSE42-NEXT: movdqa %xmm2, %xmm0
579 ; AVX1-LABEL: abd_cmp_v2i64:
581 ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm2
582 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0
583 ; AVX1-NEXT: vpxor %xmm2, %xmm0, %xmm0
584 ; AVX1-NEXT: vpsubq %xmm0, %xmm2, %xmm0
587 ; AVX2-LABEL: abd_cmp_v2i64:
589 ; AVX2-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm2
590 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm0
591 ; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm0
592 ; AVX2-NEXT: vpsubq %xmm0, %xmm2, %xmm0
595 ; AVX512-LABEL: abd_cmp_v2i64:
597 ; AVX512-NEXT: vpminsq %xmm1, %xmm0, %xmm2
598 ; AVX512-NEXT: vpmaxsq %xmm1, %xmm0, %xmm0
599 ; AVX512-NEXT: vpsubq %xmm2, %xmm0, %xmm0
601 %cmp = icmp sge <2 x i64> %a, %b
602 %ab = sub <2 x i64> %a, %b
603 %ba = sub <2 x i64> %b, %a
604 %sel = select <2 x i1> %cmp, <2 x i64> %ab, <2 x i64> %ba
609 ; abs(sub_nsw(x, y)) -> abds(a,b)
612 define <16 x i8> @abd_subnsw_v16i8(<16 x i8> %a, <16 x i8> %b) nounwind {
613 ; SSE2-LABEL: abd_subnsw_v16i8:
615 ; SSE2-NEXT: psubb %xmm1, %xmm0
616 ; SSE2-NEXT: pxor %xmm1, %xmm1
617 ; SSE2-NEXT: psubb %xmm0, %xmm1
618 ; SSE2-NEXT: pminub %xmm1, %xmm0
621 ; SSE42-LABEL: abd_subnsw_v16i8:
623 ; SSE42-NEXT: psubb %xmm1, %xmm0
624 ; SSE42-NEXT: pabsb %xmm0, %xmm0
627 ; AVX-LABEL: abd_subnsw_v16i8:
629 ; AVX-NEXT: vpsubb %xmm1, %xmm0, %xmm0
630 ; AVX-NEXT: vpabsb %xmm0, %xmm0
632 %sub = sub nsw <16 x i8> %a, %b
633 %abs = call <16 x i8> @llvm.abs.v16i8(<16 x i8> %sub, i1 false)
637 define <8 x i16> @abd_subnsw_v8i16(<8 x i16> %a, <8 x i16> %b) nounwind {
638 ; SSE2-LABEL: abd_subnsw_v8i16:
640 ; SSE2-NEXT: psubw %xmm1, %xmm0
641 ; SSE2-NEXT: pxor %xmm1, %xmm1
642 ; SSE2-NEXT: psubw %xmm0, %xmm1
643 ; SSE2-NEXT: pmaxsw %xmm1, %xmm0
646 ; SSE42-LABEL: abd_subnsw_v8i16:
648 ; SSE42-NEXT: psubw %xmm1, %xmm0
649 ; SSE42-NEXT: pabsw %xmm0, %xmm0
652 ; AVX-LABEL: abd_subnsw_v8i16:
654 ; AVX-NEXT: vpsubw %xmm1, %xmm0, %xmm0
655 ; AVX-NEXT: vpabsw %xmm0, %xmm0
657 %sub = sub nsw <8 x i16> %a, %b
658 %abs = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %sub, i1 false)
662 define <4 x i32> @abd_subnsw_v4i32(<4 x i32> %a, <4 x i32> %b) nounwind {
663 ; SSE2-LABEL: abd_subnsw_v4i32:
665 ; SSE2-NEXT: psubd %xmm1, %xmm0
666 ; SSE2-NEXT: movdqa %xmm0, %xmm1
667 ; SSE2-NEXT: psrad $31, %xmm1
668 ; SSE2-NEXT: pxor %xmm1, %xmm0
669 ; SSE2-NEXT: psubd %xmm1, %xmm0
672 ; SSE42-LABEL: abd_subnsw_v4i32:
674 ; SSE42-NEXT: psubd %xmm1, %xmm0
675 ; SSE42-NEXT: pabsd %xmm0, %xmm0
678 ; AVX-LABEL: abd_subnsw_v4i32:
680 ; AVX-NEXT: vpsubd %xmm1, %xmm0, %xmm0
681 ; AVX-NEXT: vpabsd %xmm0, %xmm0
683 %sub = sub nsw <4 x i32> %a, %b
684 %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %sub, i1 false)
688 define <2 x i64> @abd_subnsw_v2i64(<2 x i64> %a, <2 x i64> %b) nounwind {
689 ; SSE2-LABEL: abd_subnsw_v2i64:
691 ; SSE2-NEXT: psubq %xmm1, %xmm0
692 ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]
693 ; SSE2-NEXT: psrad $31, %xmm1
694 ; SSE2-NEXT: pxor %xmm1, %xmm0
695 ; SSE2-NEXT: psubq %xmm1, %xmm0
698 ; SSE42-LABEL: abd_subnsw_v2i64:
700 ; SSE42-NEXT: psubq %xmm1, %xmm0
701 ; SSE42-NEXT: pxor %xmm1, %xmm1
702 ; SSE42-NEXT: psubq %xmm0, %xmm1
703 ; SSE42-NEXT: blendvpd %xmm0, %xmm1, %xmm0
706 ; AVX1-LABEL: abd_subnsw_v2i64:
708 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0
709 ; AVX1-NEXT: vpxor %xmm1, %xmm1, %xmm1
710 ; AVX1-NEXT: vpsubq %xmm0, %xmm1, %xmm1
711 ; AVX1-NEXT: vblendvpd %xmm0, %xmm1, %xmm0, %xmm0
714 ; AVX2-LABEL: abd_subnsw_v2i64:
716 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm0
717 ; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
718 ; AVX2-NEXT: vpsubq %xmm0, %xmm1, %xmm1
719 ; AVX2-NEXT: vblendvpd %xmm0, %xmm1, %xmm0, %xmm0
722 ; AVX512-LABEL: abd_subnsw_v2i64:
724 ; AVX512-NEXT: vpsubq %xmm1, %xmm0, %xmm0
725 ; AVX512-NEXT: vpabsq %xmm0, %xmm0
727 %sub = sub nsw <2 x i64> %a, %b
728 %abs = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %sub, i1 false)
736 define <2 x i64> @abd_cmp_v2i64_multiuse_cmp(<2 x i64> %a, <2 x i64> %b) nounwind {
737 ; SSE2-LABEL: abd_cmp_v2i64_multiuse_cmp:
739 ; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [2147483648,2147483648]
740 ; SSE2-NEXT: movdqa %xmm1, %xmm3
741 ; SSE2-NEXT: pxor %xmm2, %xmm3
742 ; SSE2-NEXT: pxor %xmm0, %xmm2
743 ; SSE2-NEXT: movdqa %xmm2, %xmm4
744 ; SSE2-NEXT: pcmpgtd %xmm3, %xmm4
745 ; SSE2-NEXT: pshufd {{.*#+}} xmm5 = xmm4[0,0,2,2]
746 ; SSE2-NEXT: movdqa %xmm2, %xmm6
747 ; SSE2-NEXT: pcmpeqd %xmm3, %xmm6
748 ; SSE2-NEXT: pshufd {{.*#+}} xmm6 = xmm6[1,1,3,3]
749 ; SSE2-NEXT: pand %xmm6, %xmm5
750 ; SSE2-NEXT: pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
751 ; SSE2-NEXT: por %xmm5, %xmm4
752 ; SSE2-NEXT: psubq %xmm1, %xmm0
753 ; SSE2-NEXT: pxor %xmm4, %xmm0
754 ; SSE2-NEXT: psubq %xmm0, %xmm4
755 ; SSE2-NEXT: pcmpgtd %xmm2, %xmm3
756 ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[0,0,2,2]
757 ; SSE2-NEXT: pand %xmm6, %xmm0
758 ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm3[1,1,3,3]
759 ; SSE2-NEXT: por %xmm0, %xmm1
760 ; SSE2-NEXT: pcmpeqd %xmm0, %xmm0
761 ; SSE2-NEXT: pxor %xmm1, %xmm0
762 ; SSE2-NEXT: paddq %xmm4, %xmm0
765 ; SSE42-LABEL: abd_cmp_v2i64_multiuse_cmp:
767 ; SSE42-NEXT: movdqa %xmm0, %xmm2
768 ; SSE42-NEXT: pcmpgtq %xmm1, %xmm2
769 ; SSE42-NEXT: movdqa %xmm0, %xmm3
770 ; SSE42-NEXT: psubq %xmm1, %xmm3
771 ; SSE42-NEXT: pxor %xmm2, %xmm3
772 ; SSE42-NEXT: psubq %xmm3, %xmm2
773 ; SSE42-NEXT: pcmpgtq %xmm0, %xmm1
774 ; SSE42-NEXT: pcmpeqd %xmm0, %xmm0
775 ; SSE42-NEXT: pxor %xmm1, %xmm0
776 ; SSE42-NEXT: paddq %xmm2, %xmm0
779 ; AVX1-LABEL: abd_cmp_v2i64_multiuse_cmp:
781 ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm2
782 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm3
783 ; AVX1-NEXT: vpxor %xmm2, %xmm3, %xmm3
784 ; AVX1-NEXT: vpsubq %xmm3, %xmm2, %xmm2
785 ; AVX1-NEXT: vpcmpgtq %xmm0, %xmm1, %xmm0
786 ; AVX1-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
787 ; AVX1-NEXT: vpxor %xmm1, %xmm0, %xmm0
788 ; AVX1-NEXT: vpaddq %xmm2, %xmm0, %xmm0
791 ; AVX2-LABEL: abd_cmp_v2i64_multiuse_cmp:
793 ; AVX2-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm2
794 ; AVX2-NEXT: vpsubq %xmm1, %xmm0, %xmm3
795 ; AVX2-NEXT: vpxor %xmm2, %xmm3, %xmm3
796 ; AVX2-NEXT: vpsubq %xmm3, %xmm2, %xmm2
797 ; AVX2-NEXT: vpcmpgtq %xmm0, %xmm1, %xmm0
798 ; AVX2-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
799 ; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0
800 ; AVX2-NEXT: vpaddq %xmm2, %xmm0, %xmm0
803 ; AVX512-LABEL: abd_cmp_v2i64_multiuse_cmp:
805 ; AVX512-NEXT: vpminsq %xmm1, %xmm0, %xmm2
806 ; AVX512-NEXT: vpmaxsq %xmm1, %xmm0, %xmm3
807 ; AVX512-NEXT: vpsubq %xmm2, %xmm3, %xmm2
808 ; AVX512-NEXT: vpcmpgtq %xmm0, %xmm1, %xmm0
809 ; AVX512-NEXT: vpternlogq $15, %xmm0, %xmm0, %xmm0
810 ; AVX512-NEXT: vpaddq %xmm2, %xmm0, %xmm0
812 %cmp = icmp sge <2 x i64> %a, %b
813 %ab = sub <2 x i64> %a, %b
814 %ba = sub <2 x i64> %b, %a
815 %sel = select <2 x i1> %cmp, <2 x i64> %ab, <2 x i64> %ba
816 %ext = sext <2 x i1> %cmp to <2 x i64>
817 %res = add <2 x i64> %ext, %sel
821 define <8 x i16> @abd_cmp_v8i16_multiuse_sub(<8 x i16> %a, <8 x i16> %b) nounwind {
822 ; SSE-LABEL: abd_cmp_v8i16_multiuse_sub:
824 ; SSE-NEXT: movdqa %xmm0, %xmm2
825 ; SSE-NEXT: psubw %xmm1, %xmm2
826 ; SSE-NEXT: movdqa %xmm0, %xmm3
827 ; SSE-NEXT: pminsw %xmm1, %xmm3
828 ; SSE-NEXT: pmaxsw %xmm1, %xmm0
829 ; SSE-NEXT: psubw %xmm3, %xmm0
830 ; SSE-NEXT: paddw %xmm2, %xmm0
833 ; AVX-LABEL: abd_cmp_v8i16_multiuse_sub:
835 ; AVX-NEXT: vpsubw %xmm1, %xmm0, %xmm2
836 ; AVX-NEXT: vpminsw %xmm1, %xmm0, %xmm3
837 ; AVX-NEXT: vpmaxsw %xmm1, %xmm0, %xmm0
838 ; AVX-NEXT: vpsubw %xmm3, %xmm0, %xmm0
839 ; AVX-NEXT: vpaddw %xmm0, %xmm2, %xmm0
841 %cmp = icmp sgt <8 x i16> %a, %b
842 %ab = sub <8 x i16> %a, %b
843 %ba = sub <8 x i16> %b, %a
844 %sel = select <8 x i1> %cmp, <8 x i16> %ab, <8 x i16> %ba
845 %res = add <8 x i16> %ab, %sel
849 declare <16 x i8> @llvm.abs.v16i8(<16 x i8>, i1)
850 declare <8 x i16> @llvm.abs.v8i16(<8 x i16>, i1)
851 declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1)
852 declare <2 x i64> @llvm.abs.v2i64(<2 x i64>, i1)
853 declare <4 x i64> @llvm.abs.v4i64(<4 x i64>, i1)
854 declare <8 x i64> @llvm.abs.v8i64(<8 x i64>, i1)
855 declare <16 x i64> @llvm.abs.v16i64(<16 x i64>, i1)
856 declare <2 x i128> @llvm.abs.v2i128(<2 x i128>, i1)
858 declare <16 x i8> @llvm.smax.v16i8(<16 x i8>, <16 x i8>)
859 declare <8 x i16> @llvm.smax.v8i16(<8 x i16>, <8 x i16>)
860 declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>)
861 declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>)
863 declare <16 x i8> @llvm.smin.v16i8(<16 x i8>, <16 x i8>)
864 declare <8 x i16> @llvm.smin.v8i16(<8 x i16>, <8 x i16>)
865 declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>)
866 declare <2 x i64> @llvm.smin.v2i64(<2 x i64>, <2 x i64>)