1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx | FileCheck %s --check-prefixes=AVX1
3 ; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx2 | FileCheck %s --check-prefixes=AVX2
4 ; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx512vl | FileCheck %s --check-prefixes=AVX512
7 ; trunc(abs(sub(sext(a),sext(b)))) -> abds(a,b)
10 define <32 x i8> @abd_ext_v32i8(<32 x i8> %a, <32 x i8> %b) nounwind {
11 ; AVX1-LABEL: abd_ext_v32i8:
13 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
14 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
15 ; AVX1-NEXT: vpminsb %xmm2, %xmm3, %xmm4
16 ; AVX1-NEXT: vpmaxsb %xmm2, %xmm3, %xmm2
17 ; AVX1-NEXT: vpsubb %xmm4, %xmm2, %xmm2
18 ; AVX1-NEXT: vpminsb %xmm1, %xmm0, %xmm3
19 ; AVX1-NEXT: vpmaxsb %xmm1, %xmm0, %xmm0
20 ; AVX1-NEXT: vpsubb %xmm3, %xmm0, %xmm0
21 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
24 ; AVX2-LABEL: abd_ext_v32i8:
26 ; AVX2-NEXT: vpminsb %ymm1, %ymm0, %ymm2
27 ; AVX2-NEXT: vpmaxsb %ymm1, %ymm0, %ymm0
28 ; AVX2-NEXT: vpsubb %ymm2, %ymm0, %ymm0
31 ; AVX512-LABEL: abd_ext_v32i8:
33 ; AVX512-NEXT: vpminsb %ymm1, %ymm0, %ymm2
34 ; AVX512-NEXT: vpmaxsb %ymm1, %ymm0, %ymm0
35 ; AVX512-NEXT: vpsubb %ymm2, %ymm0, %ymm0
37 %aext = sext <32 x i8> %a to <32 x i64>
38 %bext = sext <32 x i8> %b to <32 x i64>
39 %sub = sub <32 x i64> %aext, %bext
40 %abs = call <32 x i64> @llvm.abs.v32i64(<32 x i64> %sub, i1 false)
41 %trunc = trunc <32 x i64> %abs to <32 x i8>
45 define <32 x i8> @abd_ext_v32i8_undef(<32 x i8> %a, <32 x i8> %b) nounwind {
46 ; AVX1-LABEL: abd_ext_v32i8_undef:
48 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
49 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
50 ; AVX1-NEXT: vpminsb %xmm2, %xmm3, %xmm4
51 ; AVX1-NEXT: vpmaxsb %xmm2, %xmm3, %xmm2
52 ; AVX1-NEXT: vpsubb %xmm4, %xmm2, %xmm2
53 ; AVX1-NEXT: vpminsb %xmm1, %xmm0, %xmm3
54 ; AVX1-NEXT: vpmaxsb %xmm1, %xmm0, %xmm0
55 ; AVX1-NEXT: vpsubb %xmm3, %xmm0, %xmm0
56 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
59 ; AVX2-LABEL: abd_ext_v32i8_undef:
61 ; AVX2-NEXT: vpminsb %ymm1, %ymm0, %ymm2
62 ; AVX2-NEXT: vpmaxsb %ymm1, %ymm0, %ymm0
63 ; AVX2-NEXT: vpsubb %ymm2, %ymm0, %ymm0
66 ; AVX512-LABEL: abd_ext_v32i8_undef:
68 ; AVX512-NEXT: vpminsb %ymm1, %ymm0, %ymm2
69 ; AVX512-NEXT: vpmaxsb %ymm1, %ymm0, %ymm0
70 ; AVX512-NEXT: vpsubb %ymm2, %ymm0, %ymm0
72 %aext = sext <32 x i8> %a to <32 x i64>
73 %bext = sext <32 x i8> %b to <32 x i64>
74 %sub = sub <32 x i64> %aext, %bext
75 %abs = call <32 x i64> @llvm.abs.v32i64(<32 x i64> %sub, i1 true)
76 %trunc = trunc <32 x i64> %abs to <32 x i8>
80 define <16 x i16> @abd_ext_v16i16(<16 x i16> %a, <16 x i16> %b) nounwind {
81 ; AVX1-LABEL: abd_ext_v16i16:
83 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
84 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
85 ; AVX1-NEXT: vpminsw %xmm2, %xmm3, %xmm4
86 ; AVX1-NEXT: vpmaxsw %xmm2, %xmm3, %xmm2
87 ; AVX1-NEXT: vpsubw %xmm4, %xmm2, %xmm2
88 ; AVX1-NEXT: vpminsw %xmm1, %xmm0, %xmm3
89 ; AVX1-NEXT: vpmaxsw %xmm1, %xmm0, %xmm0
90 ; AVX1-NEXT: vpsubw %xmm3, %xmm0, %xmm0
91 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
94 ; AVX2-LABEL: abd_ext_v16i16:
96 ; AVX2-NEXT: vpminsw %ymm1, %ymm0, %ymm2
97 ; AVX2-NEXT: vpmaxsw %ymm1, %ymm0, %ymm0
98 ; AVX2-NEXT: vpsubw %ymm2, %ymm0, %ymm0
101 ; AVX512-LABEL: abd_ext_v16i16:
103 ; AVX512-NEXT: vpminsw %ymm1, %ymm0, %ymm2
104 ; AVX512-NEXT: vpmaxsw %ymm1, %ymm0, %ymm0
105 ; AVX512-NEXT: vpsubw %ymm2, %ymm0, %ymm0
107 %aext = sext <16 x i16> %a to <16 x i64>
108 %bext = sext <16 x i16> %b to <16 x i64>
109 %sub = sub <16 x i64> %aext, %bext
110 %abs = call <16 x i64> @llvm.abs.v16i64(<16 x i64> %sub, i1 false)
111 %trunc = trunc <16 x i64> %abs to <16 x i16>
112 ret <16 x i16> %trunc
115 define <16 x i16> @abd_ext_v16i16_undef(<16 x i16> %a, <16 x i16> %b) nounwind {
116 ; AVX1-LABEL: abd_ext_v16i16_undef:
118 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
119 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
120 ; AVX1-NEXT: vpminsw %xmm2, %xmm3, %xmm4
121 ; AVX1-NEXT: vpmaxsw %xmm2, %xmm3, %xmm2
122 ; AVX1-NEXT: vpsubw %xmm4, %xmm2, %xmm2
123 ; AVX1-NEXT: vpminsw %xmm1, %xmm0, %xmm3
124 ; AVX1-NEXT: vpmaxsw %xmm1, %xmm0, %xmm0
125 ; AVX1-NEXT: vpsubw %xmm3, %xmm0, %xmm0
126 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
129 ; AVX2-LABEL: abd_ext_v16i16_undef:
131 ; AVX2-NEXT: vpminsw %ymm1, %ymm0, %ymm2
132 ; AVX2-NEXT: vpmaxsw %ymm1, %ymm0, %ymm0
133 ; AVX2-NEXT: vpsubw %ymm2, %ymm0, %ymm0
136 ; AVX512-LABEL: abd_ext_v16i16_undef:
138 ; AVX512-NEXT: vpminsw %ymm1, %ymm0, %ymm2
139 ; AVX512-NEXT: vpmaxsw %ymm1, %ymm0, %ymm0
140 ; AVX512-NEXT: vpsubw %ymm2, %ymm0, %ymm0
142 %aext = sext <16 x i16> %a to <16 x i64>
143 %bext = sext <16 x i16> %b to <16 x i64>
144 %sub = sub <16 x i64> %aext, %bext
145 %abs = call <16 x i64> @llvm.abs.v16i64(<16 x i64> %sub, i1 true)
146 %trunc = trunc <16 x i64> %abs to <16 x i16>
147 ret <16 x i16> %trunc
150 define <8 x i32> @abd_ext_v8i32(<8 x i32> %a, <8 x i32> %b) nounwind {
151 ; AVX1-LABEL: abd_ext_v8i32:
153 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
154 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
155 ; AVX1-NEXT: vpminsd %xmm2, %xmm3, %xmm4
156 ; AVX1-NEXT: vpmaxsd %xmm2, %xmm3, %xmm2
157 ; AVX1-NEXT: vpsubd %xmm4, %xmm2, %xmm2
158 ; AVX1-NEXT: vpminsd %xmm1, %xmm0, %xmm3
159 ; AVX1-NEXT: vpmaxsd %xmm1, %xmm0, %xmm0
160 ; AVX1-NEXT: vpsubd %xmm3, %xmm0, %xmm0
161 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
164 ; AVX2-LABEL: abd_ext_v8i32:
166 ; AVX2-NEXT: vpminsd %ymm1, %ymm0, %ymm2
167 ; AVX2-NEXT: vpmaxsd %ymm1, %ymm0, %ymm0
168 ; AVX2-NEXT: vpsubd %ymm2, %ymm0, %ymm0
171 ; AVX512-LABEL: abd_ext_v8i32:
173 ; AVX512-NEXT: vpminsd %ymm1, %ymm0, %ymm2
174 ; AVX512-NEXT: vpmaxsd %ymm1, %ymm0, %ymm0
175 ; AVX512-NEXT: vpsubd %ymm2, %ymm0, %ymm0
177 %aext = sext <8 x i32> %a to <8 x i64>
178 %bext = sext <8 x i32> %b to <8 x i64>
179 %sub = sub <8 x i64> %aext, %bext
180 %abs = call <8 x i64> @llvm.abs.v8i64(<8 x i64> %sub, i1 false)
181 %trunc = trunc <8 x i64> %abs to <8 x i32>
185 define <8 x i32> @abd_ext_v8i32_undef(<8 x i32> %a, <8 x i32> %b) nounwind {
186 ; AVX1-LABEL: abd_ext_v8i32_undef:
188 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
189 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
190 ; AVX1-NEXT: vpminsd %xmm2, %xmm3, %xmm4
191 ; AVX1-NEXT: vpmaxsd %xmm2, %xmm3, %xmm2
192 ; AVX1-NEXT: vpsubd %xmm4, %xmm2, %xmm2
193 ; AVX1-NEXT: vpminsd %xmm1, %xmm0, %xmm3
194 ; AVX1-NEXT: vpmaxsd %xmm1, %xmm0, %xmm0
195 ; AVX1-NEXT: vpsubd %xmm3, %xmm0, %xmm0
196 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
199 ; AVX2-LABEL: abd_ext_v8i32_undef:
201 ; AVX2-NEXT: vpminsd %ymm1, %ymm0, %ymm2
202 ; AVX2-NEXT: vpmaxsd %ymm1, %ymm0, %ymm0
203 ; AVX2-NEXT: vpsubd %ymm2, %ymm0, %ymm0
206 ; AVX512-LABEL: abd_ext_v8i32_undef:
208 ; AVX512-NEXT: vpminsd %ymm1, %ymm0, %ymm2
209 ; AVX512-NEXT: vpmaxsd %ymm1, %ymm0, %ymm0
210 ; AVX512-NEXT: vpsubd %ymm2, %ymm0, %ymm0
212 %aext = sext <8 x i32> %a to <8 x i64>
213 %bext = sext <8 x i32> %b to <8 x i64>
214 %sub = sub <8 x i64> %aext, %bext
215 %abs = call <8 x i64> @llvm.abs.v8i64(<8 x i64> %sub, i1 true)
216 %trunc = trunc <8 x i64> %abs to <8 x i32>
220 define <4 x i64> @abd_ext_v4i64(<4 x i64> %a, <4 x i64> %b) nounwind {
221 ; AVX1-LABEL: abd_ext_v4i64:
223 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
224 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
225 ; AVX1-NEXT: vpcmpgtq %xmm2, %xmm3, %xmm4
226 ; AVX1-NEXT: vpsubq %xmm2, %xmm3, %xmm2
227 ; AVX1-NEXT: vpxor %xmm4, %xmm2, %xmm2
228 ; AVX1-NEXT: vpsubq %xmm2, %xmm4, %xmm2
229 ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm3
230 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0
231 ; AVX1-NEXT: vpxor %xmm3, %xmm0, %xmm0
232 ; AVX1-NEXT: vpsubq %xmm0, %xmm3, %xmm0
233 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
236 ; AVX2-LABEL: abd_ext_v4i64:
238 ; AVX2-NEXT: vpcmpgtq %ymm1, %ymm0, %ymm2
239 ; AVX2-NEXT: vpsubq %ymm1, %ymm0, %ymm0
240 ; AVX2-NEXT: vpxor %ymm2, %ymm0, %ymm0
241 ; AVX2-NEXT: vpsubq %ymm0, %ymm2, %ymm0
244 ; AVX512-LABEL: abd_ext_v4i64:
246 ; AVX512-NEXT: vpminsq %ymm1, %ymm0, %ymm2
247 ; AVX512-NEXT: vpmaxsq %ymm1, %ymm0, %ymm0
248 ; AVX512-NEXT: vpsubq %ymm2, %ymm0, %ymm0
250 %aext = sext <4 x i64> %a to <4 x i128>
251 %bext = sext <4 x i64> %b to <4 x i128>
252 %sub = sub <4 x i128> %aext, %bext
253 %abs = call <4 x i128> @llvm.abs.v4i128(<4 x i128> %sub, i1 false)
254 %trunc = trunc <4 x i128> %abs to <4 x i64>
258 define <4 x i64> @abd_ext_v4i64_undef(<4 x i64> %a, <4 x i64> %b) nounwind {
259 ; AVX1-LABEL: abd_ext_v4i64_undef:
261 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
262 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
263 ; AVX1-NEXT: vpcmpgtq %xmm2, %xmm3, %xmm4
264 ; AVX1-NEXT: vpsubq %xmm2, %xmm3, %xmm2
265 ; AVX1-NEXT: vpxor %xmm4, %xmm2, %xmm2
266 ; AVX1-NEXT: vpsubq %xmm2, %xmm4, %xmm2
267 ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm3
268 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0
269 ; AVX1-NEXT: vpxor %xmm3, %xmm0, %xmm0
270 ; AVX1-NEXT: vpsubq %xmm0, %xmm3, %xmm0
271 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
274 ; AVX2-LABEL: abd_ext_v4i64_undef:
276 ; AVX2-NEXT: vpcmpgtq %ymm1, %ymm0, %ymm2
277 ; AVX2-NEXT: vpsubq %ymm1, %ymm0, %ymm0
278 ; AVX2-NEXT: vpxor %ymm2, %ymm0, %ymm0
279 ; AVX2-NEXT: vpsubq %ymm0, %ymm2, %ymm0
282 ; AVX512-LABEL: abd_ext_v4i64_undef:
284 ; AVX512-NEXT: vpminsq %ymm1, %ymm0, %ymm2
285 ; AVX512-NEXT: vpmaxsq %ymm1, %ymm0, %ymm0
286 ; AVX512-NEXT: vpsubq %ymm2, %ymm0, %ymm0
288 %aext = sext <4 x i64> %a to <4 x i128>
289 %bext = sext <4 x i64> %b to <4 x i128>
290 %sub = sub <4 x i128> %aext, %bext
291 %abs = call <4 x i128> @llvm.abs.v4i128(<4 x i128> %sub, i1 true)
292 %trunc = trunc <4 x i128> %abs to <4 x i64>
297 ; sub(smax(a,b),smin(a,b)) -> abds(a,b)
300 define <32 x i8> @abd_minmax_v32i8(<32 x i8> %a, <32 x i8> %b) nounwind {
301 ; AVX1-LABEL: abd_minmax_v32i8:
303 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
304 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
305 ; AVX1-NEXT: vpminsb %xmm2, %xmm3, %xmm4
306 ; AVX1-NEXT: vpmaxsb %xmm2, %xmm3, %xmm2
307 ; AVX1-NEXT: vpsubb %xmm4, %xmm2, %xmm2
308 ; AVX1-NEXT: vpminsb %xmm1, %xmm0, %xmm3
309 ; AVX1-NEXT: vpmaxsb %xmm1, %xmm0, %xmm0
310 ; AVX1-NEXT: vpsubb %xmm3, %xmm0, %xmm0
311 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
314 ; AVX2-LABEL: abd_minmax_v32i8:
316 ; AVX2-NEXT: vpminsb %ymm1, %ymm0, %ymm2
317 ; AVX2-NEXT: vpmaxsb %ymm1, %ymm0, %ymm0
318 ; AVX2-NEXT: vpsubb %ymm2, %ymm0, %ymm0
321 ; AVX512-LABEL: abd_minmax_v32i8:
323 ; AVX512-NEXT: vpminsb %ymm1, %ymm0, %ymm2
324 ; AVX512-NEXT: vpmaxsb %ymm1, %ymm0, %ymm0
325 ; AVX512-NEXT: vpsubb %ymm2, %ymm0, %ymm0
327 %min = call <32 x i8> @llvm.smin.v32i8(<32 x i8> %a, <32 x i8> %b)
328 %max = call <32 x i8> @llvm.smax.v32i8(<32 x i8> %a, <32 x i8> %b)
329 %sub = sub <32 x i8> %max, %min
333 define <16 x i16> @abd_minmax_v16i16(<16 x i16> %a, <16 x i16> %b) nounwind {
334 ; AVX1-LABEL: abd_minmax_v16i16:
336 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
337 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
338 ; AVX1-NEXT: vpminsw %xmm2, %xmm3, %xmm4
339 ; AVX1-NEXT: vpmaxsw %xmm2, %xmm3, %xmm2
340 ; AVX1-NEXT: vpsubw %xmm4, %xmm2, %xmm2
341 ; AVX1-NEXT: vpminsw %xmm1, %xmm0, %xmm3
342 ; AVX1-NEXT: vpmaxsw %xmm1, %xmm0, %xmm0
343 ; AVX1-NEXT: vpsubw %xmm3, %xmm0, %xmm0
344 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
347 ; AVX2-LABEL: abd_minmax_v16i16:
349 ; AVX2-NEXT: vpminsw %ymm1, %ymm0, %ymm2
350 ; AVX2-NEXT: vpmaxsw %ymm1, %ymm0, %ymm0
351 ; AVX2-NEXT: vpsubw %ymm2, %ymm0, %ymm0
354 ; AVX512-LABEL: abd_minmax_v16i16:
356 ; AVX512-NEXT: vpminsw %ymm1, %ymm0, %ymm2
357 ; AVX512-NEXT: vpmaxsw %ymm1, %ymm0, %ymm0
358 ; AVX512-NEXT: vpsubw %ymm2, %ymm0, %ymm0
360 %min = call <16 x i16> @llvm.smin.v16i16(<16 x i16> %a, <16 x i16> %b)
361 %max = call <16 x i16> @llvm.smax.v16i16(<16 x i16> %a, <16 x i16> %b)
362 %sub = sub <16 x i16> %max, %min
366 define <8 x i32> @abd_minmax_v8i32(<8 x i32> %a, <8 x i32> %b) nounwind {
367 ; AVX1-LABEL: abd_minmax_v8i32:
369 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
370 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
371 ; AVX1-NEXT: vpminsd %xmm2, %xmm3, %xmm4
372 ; AVX1-NEXT: vpmaxsd %xmm2, %xmm3, %xmm2
373 ; AVX1-NEXT: vpsubd %xmm4, %xmm2, %xmm2
374 ; AVX1-NEXT: vpminsd %xmm1, %xmm0, %xmm3
375 ; AVX1-NEXT: vpmaxsd %xmm1, %xmm0, %xmm0
376 ; AVX1-NEXT: vpsubd %xmm3, %xmm0, %xmm0
377 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
380 ; AVX2-LABEL: abd_minmax_v8i32:
382 ; AVX2-NEXT: vpminsd %ymm1, %ymm0, %ymm2
383 ; AVX2-NEXT: vpmaxsd %ymm1, %ymm0, %ymm0
384 ; AVX2-NEXT: vpsubd %ymm2, %ymm0, %ymm0
387 ; AVX512-LABEL: abd_minmax_v8i32:
389 ; AVX512-NEXT: vpminsd %ymm1, %ymm0, %ymm2
390 ; AVX512-NEXT: vpmaxsd %ymm1, %ymm0, %ymm0
391 ; AVX512-NEXT: vpsubd %ymm2, %ymm0, %ymm0
393 %min = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %a, <8 x i32> %b)
394 %max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %a, <8 x i32> %b)
395 %sub = sub <8 x i32> %max, %min
399 define <4 x i64> @abd_minmax_v4i64(<4 x i64> %a, <4 x i64> %b) nounwind {
400 ; AVX1-LABEL: abd_minmax_v4i64:
402 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
403 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
404 ; AVX1-NEXT: vpcmpgtq %xmm2, %xmm3, %xmm4
405 ; AVX1-NEXT: vpsubq %xmm2, %xmm3, %xmm2
406 ; AVX1-NEXT: vpxor %xmm4, %xmm2, %xmm2
407 ; AVX1-NEXT: vpsubq %xmm2, %xmm4, %xmm2
408 ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm3
409 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0
410 ; AVX1-NEXT: vpxor %xmm3, %xmm0, %xmm0
411 ; AVX1-NEXT: vpsubq %xmm0, %xmm3, %xmm0
412 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
415 ; AVX2-LABEL: abd_minmax_v4i64:
417 ; AVX2-NEXT: vpcmpgtq %ymm1, %ymm0, %ymm2
418 ; AVX2-NEXT: vpsubq %ymm1, %ymm0, %ymm0
419 ; AVX2-NEXT: vpxor %ymm2, %ymm0, %ymm0
420 ; AVX2-NEXT: vpsubq %ymm0, %ymm2, %ymm0
423 ; AVX512-LABEL: abd_minmax_v4i64:
425 ; AVX512-NEXT: vpminsq %ymm1, %ymm0, %ymm2
426 ; AVX512-NEXT: vpmaxsq %ymm1, %ymm0, %ymm0
427 ; AVX512-NEXT: vpsubq %ymm2, %ymm0, %ymm0
429 %min = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %a, <4 x i64> %b)
430 %max = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %a, <4 x i64> %b)
431 %sub = sub <4 x i64> %max, %min
436 ; select(icmp(a,b),sub(a,b),sub(b,a)) -> abds(a,b)
439 define <32 x i8> @abd_cmp_v32i8(<32 x i8> %a, <32 x i8> %b) nounwind {
440 ; AVX1-LABEL: abd_cmp_v32i8:
442 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
443 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
444 ; AVX1-NEXT: vpminsb %xmm2, %xmm3, %xmm4
445 ; AVX1-NEXT: vpmaxsb %xmm2, %xmm3, %xmm2
446 ; AVX1-NEXT: vpsubb %xmm4, %xmm2, %xmm2
447 ; AVX1-NEXT: vpminsb %xmm1, %xmm0, %xmm3
448 ; AVX1-NEXT: vpmaxsb %xmm1, %xmm0, %xmm0
449 ; AVX1-NEXT: vpsubb %xmm3, %xmm0, %xmm0
450 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
453 ; AVX2-LABEL: abd_cmp_v32i8:
455 ; AVX2-NEXT: vpminsb %ymm1, %ymm0, %ymm2
456 ; AVX2-NEXT: vpmaxsb %ymm1, %ymm0, %ymm0
457 ; AVX2-NEXT: vpsubb %ymm2, %ymm0, %ymm0
460 ; AVX512-LABEL: abd_cmp_v32i8:
462 ; AVX512-NEXT: vpminsb %ymm1, %ymm0, %ymm2
463 ; AVX512-NEXT: vpmaxsb %ymm1, %ymm0, %ymm0
464 ; AVX512-NEXT: vpsubb %ymm2, %ymm0, %ymm0
466 %cmp = icmp sgt <32 x i8> %a, %b
467 %ab = sub <32 x i8> %a, %b
468 %ba = sub <32 x i8> %b, %a
469 %sel = select <32 x i1> %cmp, <32 x i8> %ab, <32 x i8> %ba
473 define <16 x i16> @abd_cmp_v16i16(<16 x i16> %a, <16 x i16> %b) nounwind {
474 ; AVX1-LABEL: abd_cmp_v16i16:
476 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
477 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
478 ; AVX1-NEXT: vpminsw %xmm2, %xmm3, %xmm4
479 ; AVX1-NEXT: vpmaxsw %xmm2, %xmm3, %xmm2
480 ; AVX1-NEXT: vpsubw %xmm4, %xmm2, %xmm2
481 ; AVX1-NEXT: vpminsw %xmm1, %xmm0, %xmm3
482 ; AVX1-NEXT: vpmaxsw %xmm1, %xmm0, %xmm0
483 ; AVX1-NEXT: vpsubw %xmm3, %xmm0, %xmm0
484 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
487 ; AVX2-LABEL: abd_cmp_v16i16:
489 ; AVX2-NEXT: vpminsw %ymm1, %ymm0, %ymm2
490 ; AVX2-NEXT: vpmaxsw %ymm1, %ymm0, %ymm0
491 ; AVX2-NEXT: vpsubw %ymm2, %ymm0, %ymm0
494 ; AVX512-LABEL: abd_cmp_v16i16:
496 ; AVX512-NEXT: vpminsw %ymm1, %ymm0, %ymm2
497 ; AVX512-NEXT: vpmaxsw %ymm1, %ymm0, %ymm0
498 ; AVX512-NEXT: vpsubw %ymm2, %ymm0, %ymm0
500 %cmp = icmp sge <16 x i16> %a, %b
501 %ab = sub <16 x i16> %a, %b
502 %ba = sub <16 x i16> %b, %a
503 %sel = select <16 x i1> %cmp, <16 x i16> %ab, <16 x i16> %ba
507 define <8 x i32> @abd_cmp_v8i32(<8 x i32> %a, <8 x i32> %b) nounwind {
508 ; AVX1-LABEL: abd_cmp_v8i32:
510 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
511 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
512 ; AVX1-NEXT: vpminsd %xmm2, %xmm3, %xmm4
513 ; AVX1-NEXT: vpmaxsd %xmm2, %xmm3, %xmm2
514 ; AVX1-NEXT: vpsubd %xmm4, %xmm2, %xmm2
515 ; AVX1-NEXT: vpminsd %xmm1, %xmm0, %xmm3
516 ; AVX1-NEXT: vpmaxsd %xmm1, %xmm0, %xmm0
517 ; AVX1-NEXT: vpsubd %xmm3, %xmm0, %xmm0
518 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
521 ; AVX2-LABEL: abd_cmp_v8i32:
523 ; AVX2-NEXT: vpminsd %ymm1, %ymm0, %ymm2
524 ; AVX2-NEXT: vpmaxsd %ymm1, %ymm0, %ymm0
525 ; AVX2-NEXT: vpsubd %ymm2, %ymm0, %ymm0
528 ; AVX512-LABEL: abd_cmp_v8i32:
530 ; AVX512-NEXT: vpminsd %ymm1, %ymm0, %ymm2
531 ; AVX512-NEXT: vpmaxsd %ymm1, %ymm0, %ymm0
532 ; AVX512-NEXT: vpsubd %ymm2, %ymm0, %ymm0
534 %cmp = icmp slt <8 x i32> %a, %b
535 %ab = sub <8 x i32> %a, %b
536 %ba = sub <8 x i32> %b, %a
537 %sel = select <8 x i1> %cmp, <8 x i32> %ba, <8 x i32> %ab
541 define <4 x i64> @abd_cmp_v4i64(<4 x i64> %a, <4 x i64> %b) nounwind {
542 ; AVX1-LABEL: abd_cmp_v4i64:
544 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
545 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
546 ; AVX1-NEXT: vpcmpgtq %xmm2, %xmm3, %xmm4
547 ; AVX1-NEXT: vpsubq %xmm2, %xmm3, %xmm2
548 ; AVX1-NEXT: vpxor %xmm4, %xmm2, %xmm2
549 ; AVX1-NEXT: vpsubq %xmm2, %xmm4, %xmm2
550 ; AVX1-NEXT: vpcmpgtq %xmm1, %xmm0, %xmm3
551 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0
552 ; AVX1-NEXT: vpxor %xmm3, %xmm0, %xmm0
553 ; AVX1-NEXT: vpsubq %xmm0, %xmm3, %xmm0
554 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
557 ; AVX2-LABEL: abd_cmp_v4i64:
559 ; AVX2-NEXT: vpcmpgtq %ymm1, %ymm0, %ymm2
560 ; AVX2-NEXT: vpsubq %ymm1, %ymm0, %ymm0
561 ; AVX2-NEXT: vpxor %ymm2, %ymm0, %ymm0
562 ; AVX2-NEXT: vpsubq %ymm0, %ymm2, %ymm0
565 ; AVX512-LABEL: abd_cmp_v4i64:
567 ; AVX512-NEXT: vpminsq %ymm1, %ymm0, %ymm2
568 ; AVX512-NEXT: vpmaxsq %ymm1, %ymm0, %ymm0
569 ; AVX512-NEXT: vpsubq %ymm2, %ymm0, %ymm0
571 %cmp = icmp sge <4 x i64> %a, %b
572 %ab = sub <4 x i64> %a, %b
573 %ba = sub <4 x i64> %b, %a
574 %sel = select <4 x i1> %cmp, <4 x i64> %ab, <4 x i64> %ba
579 ; abs(sub_nsw(x, y)) -> abds(a,b)
582 define <32 x i8> @abd_subnsw_v32i8(<32 x i8> %a, <32 x i8> %b) nounwind {
583 ; AVX1-LABEL: abd_subnsw_v32i8:
585 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
586 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
587 ; AVX1-NEXT: vpsubb %xmm2, %xmm3, %xmm2
588 ; AVX1-NEXT: vpsubb %xmm1, %xmm0, %xmm0
589 ; AVX1-NEXT: vpabsb %xmm0, %xmm0
590 ; AVX1-NEXT: vpabsb %xmm2, %xmm1
591 ; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
594 ; AVX2-LABEL: abd_subnsw_v32i8:
596 ; AVX2-NEXT: vpsubb %ymm1, %ymm0, %ymm0
597 ; AVX2-NEXT: vpabsb %ymm0, %ymm0
600 ; AVX512-LABEL: abd_subnsw_v32i8:
602 ; AVX512-NEXT: vpsubb %ymm1, %ymm0, %ymm0
603 ; AVX512-NEXT: vpabsb %ymm0, %ymm0
605 %sub = sub nsw <32 x i8> %a, %b
606 %abs = call <32 x i8> @llvm.abs.v32i8(<32 x i8> %sub, i1 false)
610 define <16 x i16> @abd_subnsw_v16i16(<16 x i16> %a, <16 x i16> %b) nounwind {
611 ; AVX1-LABEL: abd_subnsw_v16i16:
613 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
614 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
615 ; AVX1-NEXT: vpsubw %xmm2, %xmm3, %xmm2
616 ; AVX1-NEXT: vpsubw %xmm1, %xmm0, %xmm0
617 ; AVX1-NEXT: vpabsw %xmm0, %xmm0
618 ; AVX1-NEXT: vpabsw %xmm2, %xmm1
619 ; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
622 ; AVX2-LABEL: abd_subnsw_v16i16:
624 ; AVX2-NEXT: vpsubw %ymm1, %ymm0, %ymm0
625 ; AVX2-NEXT: vpabsw %ymm0, %ymm0
628 ; AVX512-LABEL: abd_subnsw_v16i16:
630 ; AVX512-NEXT: vpsubw %ymm1, %ymm0, %ymm0
631 ; AVX512-NEXT: vpabsw %ymm0, %ymm0
633 %sub = sub nsw <16 x i16> %a, %b
634 %abs = call <16 x i16> @llvm.abs.v16i16(<16 x i16> %sub, i1 false)
638 define <8 x i32> @abd_subnsw_v8i32(<8 x i32> %a, <8 x i32> %b) nounwind {
639 ; AVX1-LABEL: abd_subnsw_v8i32:
641 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
642 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
643 ; AVX1-NEXT: vpsubd %xmm2, %xmm3, %xmm2
644 ; AVX1-NEXT: vpsubd %xmm1, %xmm0, %xmm0
645 ; AVX1-NEXT: vpabsd %xmm0, %xmm0
646 ; AVX1-NEXT: vpabsd %xmm2, %xmm1
647 ; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0
650 ; AVX2-LABEL: abd_subnsw_v8i32:
652 ; AVX2-NEXT: vpsubd %ymm1, %ymm0, %ymm0
653 ; AVX2-NEXT: vpabsd %ymm0, %ymm0
656 ; AVX512-LABEL: abd_subnsw_v8i32:
658 ; AVX512-NEXT: vpsubd %ymm1, %ymm0, %ymm0
659 ; AVX512-NEXT: vpabsd %ymm0, %ymm0
661 %sub = sub nsw <8 x i32> %a, %b
662 %abs = call <8 x i32> @llvm.abs.v8i32(<8 x i32> %sub, i1 false)
666 define <4 x i64> @abd_subnsw_v4i64(<4 x i64> %a, <4 x i64> %b) nounwind {
667 ; AVX1-LABEL: abd_subnsw_v4i64:
669 ; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2
670 ; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3
671 ; AVX1-NEXT: vpsubq %xmm2, %xmm3, %xmm2
672 ; AVX1-NEXT: vpsubq %xmm1, %xmm0, %xmm0
673 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm1
674 ; AVX1-NEXT: vpxor %xmm3, %xmm3, %xmm3
675 ; AVX1-NEXT: vpsubq %xmm2, %xmm3, %xmm2
676 ; AVX1-NEXT: vpsubq %xmm0, %xmm3, %xmm0
677 ; AVX1-NEXT: vinsertf128 $1, %xmm2, %ymm0, %ymm0
678 ; AVX1-NEXT: vblendvpd %ymm1, %ymm0, %ymm1, %ymm0
681 ; AVX2-LABEL: abd_subnsw_v4i64:
683 ; AVX2-NEXT: vpsubq %ymm1, %ymm0, %ymm0
684 ; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
685 ; AVX2-NEXT: vpsubq %ymm0, %ymm1, %ymm1
686 ; AVX2-NEXT: vblendvpd %ymm0, %ymm1, %ymm0, %ymm0
689 ; AVX512-LABEL: abd_subnsw_v4i64:
691 ; AVX512-NEXT: vpsubq %ymm1, %ymm0, %ymm0
692 ; AVX512-NEXT: vpabsq %ymm0, %ymm0
694 %sub = sub nsw <4 x i64> %a, %b
695 %abs = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %sub, i1 false)
699 declare <32 x i8> @llvm.abs.v32i8(<32 x i8>, i1)
700 declare <16 x i16> @llvm.abs.v16i16(<16 x i16>, i1)
701 declare <8 x i32> @llvm.abs.v8i32(<8 x i32>, i1)
702 declare <4 x i64> @llvm.abs.v4i64(<4 x i64>, i1)
703 declare <8 x i64> @llvm.abs.v8i64(<8 x i64>, i1)
704 declare <16 x i64> @llvm.abs.v16i64(<16 x i64>, i1)
705 declare <32 x i64> @llvm.abs.v32i64(<32 x i64>, i1)
706 declare <4 x i128> @llvm.abs.v4i128(<4 x i128>, i1)
708 declare <32 x i8> @llvm.smax.v32i8(<32 x i8>, <32 x i8>)
709 declare <16 x i16> @llvm.smax.v16i16(<16 x i16>, <16 x i16>)
710 declare <8 x i32> @llvm.smax.v8i32(<8 x i32>, <8 x i32>)
711 declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>)
713 declare <32 x i8> @llvm.smin.v32i8(<32 x i8>, <32 x i8>)
714 declare <16 x i16> @llvm.smin.v16i16(<16 x i16>, <16 x i16>)
715 declare <8 x i32> @llvm.smin.v8i32(<8 x i32>, <8 x i32>)
716 declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>)