1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686 -mattr=cmov | FileCheck %s --check-prefixes=X86
3 ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefixes=X64
6 ; trunc(abs(sub(zext(a),zext(b)))) -> abdu(a,b)
9 define i8 @abd_ext_i8(i8 %a, i8 %b) nounwind {
10 ; X86-LABEL: abd_ext_i8:
12 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
13 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
14 ; X86-NEXT: subl %eax, %ecx
15 ; X86-NEXT: movl %ecx, %eax
17 ; X86-NEXT: cmovsl %ecx, %eax
18 ; X86-NEXT: # kill: def $al killed $al killed $eax
21 ; X64-LABEL: abd_ext_i8:
23 ; X64-NEXT: movzbl %sil, %eax
24 ; X64-NEXT: movzbl %dil, %ecx
25 ; X64-NEXT: subl %eax, %ecx
26 ; X64-NEXT: movl %ecx, %eax
28 ; X64-NEXT: cmovsl %ecx, %eax
29 ; X64-NEXT: # kill: def $al killed $al killed $eax
31 %aext = zext i8 %a to i64
32 %bext = zext i8 %b to i64
33 %sub = sub i64 %aext, %bext
34 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
35 %trunc = trunc i64 %abs to i8
39 define i8 @abd_ext_i8_undef(i8 %a, i8 %b) nounwind {
40 ; X86-LABEL: abd_ext_i8_undef:
42 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
43 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
44 ; X86-NEXT: subl %eax, %ecx
45 ; X86-NEXT: movl %ecx, %eax
47 ; X86-NEXT: cmovsl %ecx, %eax
48 ; X86-NEXT: # kill: def $al killed $al killed $eax
51 ; X64-LABEL: abd_ext_i8_undef:
53 ; X64-NEXT: movzbl %sil, %eax
54 ; X64-NEXT: movzbl %dil, %ecx
55 ; X64-NEXT: subl %eax, %ecx
56 ; X64-NEXT: movl %ecx, %eax
58 ; X64-NEXT: cmovsl %ecx, %eax
59 ; X64-NEXT: # kill: def $al killed $al killed $eax
61 %aext = zext i8 %a to i64
62 %bext = zext i8 %b to i64
63 %sub = sub i64 %aext, %bext
64 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
65 %trunc = trunc i64 %abs to i8
69 define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind {
70 ; X86-LABEL: abd_ext_i16:
72 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
73 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
74 ; X86-NEXT: subl %eax, %ecx
75 ; X86-NEXT: movl %ecx, %eax
77 ; X86-NEXT: cmovsl %ecx, %eax
78 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
81 ; X64-LABEL: abd_ext_i16:
83 ; X64-NEXT: movzwl %si, %eax
84 ; X64-NEXT: movzwl %di, %ecx
85 ; X64-NEXT: subl %eax, %ecx
86 ; X64-NEXT: movl %ecx, %eax
88 ; X64-NEXT: cmovsl %ecx, %eax
89 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
91 %aext = zext i16 %a to i64
92 %bext = zext i16 %b to i64
93 %sub = sub i64 %aext, %bext
94 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
95 %trunc = trunc i64 %abs to i16
99 define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind {
100 ; X86-LABEL: abd_ext_i16_undef:
102 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
103 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
104 ; X86-NEXT: subl %eax, %ecx
105 ; X86-NEXT: movl %ecx, %eax
106 ; X86-NEXT: negl %eax
107 ; X86-NEXT: cmovsl %ecx, %eax
108 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
111 ; X64-LABEL: abd_ext_i16_undef:
113 ; X64-NEXT: movzwl %si, %eax
114 ; X64-NEXT: movzwl %di, %ecx
115 ; X64-NEXT: subl %eax, %ecx
116 ; X64-NEXT: movl %ecx, %eax
117 ; X64-NEXT: negl %eax
118 ; X64-NEXT: cmovsl %ecx, %eax
119 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
121 %aext = zext i16 %a to i64
122 %bext = zext i16 %b to i64
123 %sub = sub i64 %aext, %bext
124 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
125 %trunc = trunc i64 %abs to i16
129 define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind {
130 ; X86-LABEL: abd_ext_i32:
132 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
133 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
134 ; X86-NEXT: movl %eax, %edx
135 ; X86-NEXT: subl %ecx, %edx
136 ; X86-NEXT: negl %edx
137 ; X86-NEXT: subl %ecx, %eax
138 ; X86-NEXT: cmovbel %edx, %eax
141 ; X64-LABEL: abd_ext_i32:
143 ; X64-NEXT: movl %esi, %eax
144 ; X64-NEXT: movl %edi, %ecx
145 ; X64-NEXT: subq %rax, %rcx
146 ; X64-NEXT: movq %rcx, %rax
147 ; X64-NEXT: negq %rax
148 ; X64-NEXT: cmovsq %rcx, %rax
149 ; X64-NEXT: # kill: def $eax killed $eax killed $rax
151 %aext = zext i32 %a to i64
152 %bext = zext i32 %b to i64
153 %sub = sub i64 %aext, %bext
154 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
155 %trunc = trunc i64 %abs to i32
159 define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind {
160 ; X86-LABEL: abd_ext_i32_undef:
162 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
163 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
164 ; X86-NEXT: movl %eax, %edx
165 ; X86-NEXT: subl %ecx, %edx
166 ; X86-NEXT: negl %edx
167 ; X86-NEXT: subl %ecx, %eax
168 ; X86-NEXT: cmovbel %edx, %eax
171 ; X64-LABEL: abd_ext_i32_undef:
173 ; X64-NEXT: movl %esi, %eax
174 ; X64-NEXT: movl %edi, %ecx
175 ; X64-NEXT: subq %rax, %rcx
176 ; X64-NEXT: movq %rcx, %rax
177 ; X64-NEXT: negq %rax
178 ; X64-NEXT: cmovsq %rcx, %rax
179 ; X64-NEXT: # kill: def $eax killed $eax killed $rax
181 %aext = zext i32 %a to i64
182 %bext = zext i32 %b to i64
183 %sub = sub i64 %aext, %bext
184 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
185 %trunc = trunc i64 %abs to i32
189 define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind {
190 ; X86-LABEL: abd_ext_i64:
192 ; X86-NEXT: pushl %esi
193 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
194 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
195 ; X86-NEXT: xorl %ecx, %ecx
196 ; X86-NEXT: subl {{[0-9]+}}(%esp), %eax
197 ; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx
198 ; X86-NEXT: movl $0, %esi
199 ; X86-NEXT: sbbl %esi, %esi
200 ; X86-NEXT: sbbl %ecx, %ecx
201 ; X86-NEXT: sarl $31, %ecx
202 ; X86-NEXT: xorl %ecx, %edx
203 ; X86-NEXT: xorl %ecx, %eax
204 ; X86-NEXT: subl %ecx, %eax
205 ; X86-NEXT: sbbl %ecx, %edx
206 ; X86-NEXT: popl %esi
209 ; X64-LABEL: abd_ext_i64:
211 ; X64-NEXT: movq %rdi, %rax
212 ; X64-NEXT: subq %rsi, %rax
213 ; X64-NEXT: negq %rax
214 ; X64-NEXT: subq %rsi, %rdi
215 ; X64-NEXT: cmovaq %rdi, %rax
217 %aext = zext i64 %a to i128
218 %bext = zext i64 %b to i128
219 %sub = sub i128 %aext, %bext
220 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)
221 %trunc = trunc i128 %abs to i64
225 define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind {
226 ; X86-LABEL: abd_ext_i64_undef:
228 ; X86-NEXT: pushl %esi
229 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
230 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
231 ; X86-NEXT: xorl %ecx, %ecx
232 ; X86-NEXT: subl {{[0-9]+}}(%esp), %eax
233 ; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx
234 ; X86-NEXT: movl $0, %esi
235 ; X86-NEXT: sbbl %esi, %esi
236 ; X86-NEXT: sbbl %ecx, %ecx
237 ; X86-NEXT: sarl $31, %ecx
238 ; X86-NEXT: xorl %ecx, %edx
239 ; X86-NEXT: xorl %ecx, %eax
240 ; X86-NEXT: subl %ecx, %eax
241 ; X86-NEXT: sbbl %ecx, %edx
242 ; X86-NEXT: popl %esi
245 ; X64-LABEL: abd_ext_i64_undef:
247 ; X64-NEXT: movq %rdi, %rax
248 ; X64-NEXT: subq %rsi, %rax
249 ; X64-NEXT: negq %rax
250 ; X64-NEXT: subq %rsi, %rdi
251 ; X64-NEXT: cmovaq %rdi, %rax
253 %aext = zext i64 %a to i128
254 %bext = zext i64 %b to i128
255 %sub = sub i128 %aext, %bext
256 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)
257 %trunc = trunc i128 %abs to i64
262 ; sub(umax(a,b),umin(a,b)) -> abdu(a,b)
265 define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind {
266 ; X86-LABEL: abd_minmax_i8:
268 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
269 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
270 ; X86-NEXT: subl %eax, %ecx
271 ; X86-NEXT: movl %ecx, %eax
272 ; X86-NEXT: negl %eax
273 ; X86-NEXT: cmovsl %ecx, %eax
274 ; X86-NEXT: # kill: def $al killed $al killed $eax
277 ; X64-LABEL: abd_minmax_i8:
279 ; X64-NEXT: movzbl %sil, %eax
280 ; X64-NEXT: movzbl %dil, %ecx
281 ; X64-NEXT: subl %eax, %ecx
282 ; X64-NEXT: movl %ecx, %eax
283 ; X64-NEXT: negl %eax
284 ; X64-NEXT: cmovsl %ecx, %eax
285 ; X64-NEXT: # kill: def $al killed $al killed $eax
287 %min = call i8 @llvm.umin.i8(i8 %a, i8 %b)
288 %max = call i8 @llvm.umax.i8(i8 %a, i8 %b)
289 %sub = sub i8 %max, %min
293 define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind {
294 ; X86-LABEL: abd_minmax_i16:
296 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
297 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
298 ; X86-NEXT: subl %eax, %ecx
299 ; X86-NEXT: movl %ecx, %eax
300 ; X86-NEXT: negl %eax
301 ; X86-NEXT: cmovsl %ecx, %eax
302 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
305 ; X64-LABEL: abd_minmax_i16:
307 ; X64-NEXT: movzwl %si, %eax
308 ; X64-NEXT: movzwl %di, %ecx
309 ; X64-NEXT: subl %eax, %ecx
310 ; X64-NEXT: movl %ecx, %eax
311 ; X64-NEXT: negl %eax
312 ; X64-NEXT: cmovsl %ecx, %eax
313 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
315 %min = call i16 @llvm.umin.i16(i16 %a, i16 %b)
316 %max = call i16 @llvm.umax.i16(i16 %a, i16 %b)
317 %sub = sub i16 %max, %min
321 define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind {
322 ; X86-LABEL: abd_minmax_i32:
324 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
325 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
326 ; X86-NEXT: movl %eax, %edx
327 ; X86-NEXT: subl %ecx, %edx
328 ; X86-NEXT: negl %edx
329 ; X86-NEXT: subl %ecx, %eax
330 ; X86-NEXT: cmovbel %edx, %eax
333 ; X64-LABEL: abd_minmax_i32:
335 ; X64-NEXT: movl %esi, %eax
336 ; X64-NEXT: movl %edi, %ecx
337 ; X64-NEXT: subq %rax, %rcx
338 ; X64-NEXT: movq %rcx, %rax
339 ; X64-NEXT: negq %rax
340 ; X64-NEXT: cmovsq %rcx, %rax
341 ; X64-NEXT: # kill: def $eax killed $eax killed $rax
343 %min = call i32 @llvm.umin.i32(i32 %a, i32 %b)
344 %max = call i32 @llvm.umax.i32(i32 %a, i32 %b)
345 %sub = sub i32 %max, %min
349 define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind {
350 ; X86-LABEL: abd_minmax_i64:
352 ; X86-NEXT: pushl %ebp
353 ; X86-NEXT: pushl %ebx
354 ; X86-NEXT: pushl %edi
355 ; X86-NEXT: pushl %esi
356 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
357 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
358 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
359 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
360 ; X86-NEXT: cmpl %eax, %ecx
361 ; X86-NEXT: movl %esi, %edi
362 ; X86-NEXT: sbbl %edx, %edi
363 ; X86-NEXT: movl %edx, %edi
364 ; X86-NEXT: cmovbl %esi, %edi
365 ; X86-NEXT: movl %eax, %ebx
366 ; X86-NEXT: cmovbl %ecx, %ebx
367 ; X86-NEXT: cmpl %ecx, %eax
368 ; X86-NEXT: movl %edx, %ebp
369 ; X86-NEXT: sbbl %esi, %ebp
370 ; X86-NEXT: cmovbl %esi, %edx
371 ; X86-NEXT: cmovbl %ecx, %eax
372 ; X86-NEXT: subl %ebx, %eax
373 ; X86-NEXT: sbbl %edi, %edx
374 ; X86-NEXT: popl %esi
375 ; X86-NEXT: popl %edi
376 ; X86-NEXT: popl %ebx
377 ; X86-NEXT: popl %ebp
380 ; X64-LABEL: abd_minmax_i64:
382 ; X64-NEXT: movq %rdi, %rax
383 ; X64-NEXT: subq %rsi, %rax
384 ; X64-NEXT: negq %rax
385 ; X64-NEXT: subq %rsi, %rdi
386 ; X64-NEXT: cmovaq %rdi, %rax
388 %min = call i64 @llvm.umin.i64(i64 %a, i64 %b)
389 %max = call i64 @llvm.umax.i64(i64 %a, i64 %b)
390 %sub = sub i64 %max, %min
395 ; select(icmp(a,b),sub(a,b),sub(b,a)) -> abdu(a,b)
398 define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind {
399 ; X86-LABEL: abd_cmp_i8:
401 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
402 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
403 ; X86-NEXT: movl %eax, %edx
404 ; X86-NEXT: subb %cl, %dl
406 ; X86-NEXT: subb %cl, %al
407 ; X86-NEXT: movzbl %al, %ecx
408 ; X86-NEXT: movzbl %dl, %eax
409 ; X86-NEXT: cmovael %ecx, %eax
410 ; X86-NEXT: # kill: def $al killed $al killed $eax
413 ; X64-LABEL: abd_cmp_i8:
415 ; X64-NEXT: movl %esi, %eax
416 ; X64-NEXT: subb %dil, %al
418 ; X64-NEXT: subb %dil, %sil
419 ; X64-NEXT: movzbl %sil, %ecx
420 ; X64-NEXT: movzbl %al, %eax
421 ; X64-NEXT: cmovael %ecx, %eax
422 ; X64-NEXT: # kill: def $al killed $al killed $eax
424 %cmp = icmp ugt i8 %a, %b
427 %sel = select i1 %cmp, i8 %ab, i8 %ba
431 define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind {
432 ; X86-LABEL: abd_cmp_i16:
434 ; X86-NEXT: pushl %esi
435 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
436 ; X86-NEXT: movzwl {{[0-9]+}}(%esp), %edx
437 ; X86-NEXT: movl %ecx, %esi
438 ; X86-NEXT: subw %dx, %si
439 ; X86-NEXT: movl %esi, %eax
440 ; X86-NEXT: negl %eax
441 ; X86-NEXT: cmpw %dx, %cx
442 ; X86-NEXT: cmovael %esi, %eax
443 ; X86-NEXT: # kill: def $ax killed $ax killed $eax
444 ; X86-NEXT: popl %esi
447 ; X64-LABEL: abd_cmp_i16:
449 ; X64-NEXT: movl %edi, %ecx
450 ; X64-NEXT: subw %si, %cx
451 ; X64-NEXT: movl %ecx, %eax
452 ; X64-NEXT: negl %eax
453 ; X64-NEXT: cmpw %si, %di
454 ; X64-NEXT: cmovael %ecx, %eax
455 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
457 %cmp = icmp uge i16 %a, %b
460 %sel = select i1 %cmp, i16 %ab, i16 %ba
464 define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind {
465 ; X86-LABEL: abd_cmp_i32:
467 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
468 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
469 ; X86-NEXT: movl %eax, %edx
470 ; X86-NEXT: subl %ecx, %edx
471 ; X86-NEXT: negl %edx
472 ; X86-NEXT: subl %ecx, %eax
473 ; X86-NEXT: cmovbl %edx, %eax
476 ; X64-LABEL: abd_cmp_i32:
478 ; X64-NEXT: movl %edi, %eax
479 ; X64-NEXT: subl %esi, %eax
480 ; X64-NEXT: negl %eax
481 ; X64-NEXT: subl %esi, %edi
482 ; X64-NEXT: cmovael %edi, %eax
484 %cmp = icmp ult i32 %a, %b
487 %sel = select i1 %cmp, i32 %ba, i32 %ab
491 define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind {
492 ; X86-LABEL: abd_cmp_i64:
494 ; X86-NEXT: pushl %ebx
495 ; X86-NEXT: pushl %edi
496 ; X86-NEXT: pushl %esi
497 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
498 ; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
499 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
500 ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
501 ; X86-NEXT: movl %ecx, %edi
502 ; X86-NEXT: subl %eax, %edi
503 ; X86-NEXT: movl %esi, %ebx
504 ; X86-NEXT: sbbl %edx, %ebx
505 ; X86-NEXT: subl %ecx, %eax
506 ; X86-NEXT: sbbl %esi, %edx
507 ; X86-NEXT: cmovael %edi, %eax
508 ; X86-NEXT: cmovael %ebx, %edx
509 ; X86-NEXT: popl %esi
510 ; X86-NEXT: popl %edi
511 ; X86-NEXT: popl %ebx
514 ; X64-LABEL: abd_cmp_i64:
516 ; X64-NEXT: movq %rdi, %rax
517 ; X64-NEXT: subq %rsi, %rax
518 ; X64-NEXT: negq %rax
519 ; X64-NEXT: subq %rsi, %rdi
520 ; X64-NEXT: cmovbq %rdi, %rax
522 %cmp = icmp uge i64 %a, %b
525 %sel = select i1 %cmp, i64 %ba, i64 %ab
529 declare i8 @llvm.abs.i8(i8, i1)
530 declare i16 @llvm.abs.i16(i16, i1)
531 declare i32 @llvm.abs.i32(i32, i1)
532 declare i64 @llvm.abs.i64(i64, i1)
533 declare i128 @llvm.abs.i128(i128, i1)
535 declare i8 @llvm.umax.i8(i8, i8)
536 declare i16 @llvm.umax.i16(i16, i16)
537 declare i32 @llvm.umax.i32(i32, i32)
538 declare i64 @llvm.umax.i64(i64, i64)
540 declare i8 @llvm.umin.i8(i8, i8)
541 declare i16 @llvm.umin.i16(i16, i16)
542 declare i32 @llvm.umin.i32(i32, i32)
543 declare i64 @llvm.umin.i64(i64, i64)