Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / X86 / abds.ll
blobdaed1125e9deebbf7116e7f033fc5c0368c9904f
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(sext(a),sext(b)))) -> abds(a,b)
9 define i8 @abd_ext_i8(i8 %a, i8 %b) nounwind {
10 ; X86-LABEL: abd_ext_i8:
11 ; X86:       # %bb.0:
12 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
13 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %ecx
14 ; X86-NEXT:    subl %eax, %ecx
15 ; X86-NEXT:    movl %ecx, %eax
16 ; X86-NEXT:    negl %eax
17 ; X86-NEXT:    cmovsl %ecx, %eax
18 ; X86-NEXT:    # kill: def $al killed $al killed $eax
19 ; X86-NEXT:    retl
21 ; X64-LABEL: abd_ext_i8:
22 ; X64:       # %bb.0:
23 ; X64-NEXT:    movsbl %sil, %eax
24 ; X64-NEXT:    movsbl %dil, %ecx
25 ; X64-NEXT:    subl %eax, %ecx
26 ; X64-NEXT:    movl %ecx, %eax
27 ; X64-NEXT:    negl %eax
28 ; X64-NEXT:    cmovsl %ecx, %eax
29 ; X64-NEXT:    # kill: def $al killed $al killed $eax
30 ; X64-NEXT:    retq
31   %aext = sext i8 %a to i64
32   %bext = sext 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
36   ret i8 %trunc
39 define i8 @abd_ext_i8_undef(i8 %a, i8 %b) nounwind {
40 ; X86-LABEL: abd_ext_i8_undef:
41 ; X86:       # %bb.0:
42 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
43 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %ecx
44 ; X86-NEXT:    subl %eax, %ecx
45 ; X86-NEXT:    movl %ecx, %eax
46 ; X86-NEXT:    negl %eax
47 ; X86-NEXT:    cmovsl %ecx, %eax
48 ; X86-NEXT:    # kill: def $al killed $al killed $eax
49 ; X86-NEXT:    retl
51 ; X64-LABEL: abd_ext_i8_undef:
52 ; X64:       # %bb.0:
53 ; X64-NEXT:    movsbl %sil, %eax
54 ; X64-NEXT:    movsbl %dil, %ecx
55 ; X64-NEXT:    subl %eax, %ecx
56 ; X64-NEXT:    movl %ecx, %eax
57 ; X64-NEXT:    negl %eax
58 ; X64-NEXT:    cmovsl %ecx, %eax
59 ; X64-NEXT:    # kill: def $al killed $al killed $eax
60 ; X64-NEXT:    retq
61   %aext = sext i8 %a to i64
62   %bext = sext 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
66   ret i8 %trunc
69 define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind {
70 ; X86-LABEL: abd_ext_i16:
71 ; X86:       # %bb.0:
72 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
73 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
74 ; X86-NEXT:    subl %eax, %ecx
75 ; X86-NEXT:    movl %ecx, %eax
76 ; X86-NEXT:    negl %eax
77 ; X86-NEXT:    cmovsl %ecx, %eax
78 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
79 ; X86-NEXT:    retl
81 ; X64-LABEL: abd_ext_i16:
82 ; X64:       # %bb.0:
83 ; X64-NEXT:    movswl %si, %eax
84 ; X64-NEXT:    movswl %di, %ecx
85 ; X64-NEXT:    subl %eax, %ecx
86 ; X64-NEXT:    movl %ecx, %eax
87 ; X64-NEXT:    negl %eax
88 ; X64-NEXT:    cmovsl %ecx, %eax
89 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
90 ; X64-NEXT:    retq
91   %aext = sext i16 %a to i64
92   %bext = sext 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
96   ret i16 %trunc
99 define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind {
100 ; X86-LABEL: abd_ext_i16_undef:
101 ; X86:       # %bb.0:
102 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
103 ; X86-NEXT:    movswl {{[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
109 ; X86-NEXT:    retl
111 ; X64-LABEL: abd_ext_i16_undef:
112 ; X64:       # %bb.0:
113 ; X64-NEXT:    movswl %si, %eax
114 ; X64-NEXT:    movswl %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
120 ; X64-NEXT:    retq
121   %aext = sext i16 %a to i64
122   %bext = sext 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
126   ret i16 %trunc
129 define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind {
130 ; X86-LABEL: abd_ext_i32:
131 ; X86:       # %bb.0:
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:    cmovlel %edx, %eax
139 ; X86-NEXT:    retl
141 ; X64-LABEL: abd_ext_i32:
142 ; X64:       # %bb.0:
143 ; X64-NEXT:    movslq %esi, %rax
144 ; X64-NEXT:    movslq %edi, %rcx
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
150 ; X64-NEXT:    retq
151   %aext = sext i32 %a to i64
152   %bext = sext 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
156   ret i32 %trunc
159 define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind {
160 ; X86-LABEL: abd_ext_i32_undef:
161 ; X86:       # %bb.0:
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:    cmovlel %edx, %eax
169 ; X86-NEXT:    retl
171 ; X64-LABEL: abd_ext_i32_undef:
172 ; X64:       # %bb.0:
173 ; X64-NEXT:    movslq %esi, %rax
174 ; X64-NEXT:    movslq %edi, %rcx
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
180 ; X64-NEXT:    retq
181   %aext = sext i32 %a to i64
182   %bext = sext 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
186   ret i32 %trunc
189 define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind {
190 ; X86-LABEL: abd_ext_i64:
191 ; X86:       # %bb.0:
192 ; X86-NEXT:    pushl %edi
193 ; X86-NEXT:    pushl %esi
194 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
195 ; X86-NEXT:    movl %esi, %edi
196 ; X86-NEXT:    sarl $31, %edi
197 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
198 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
199 ; X86-NEXT:    movl %edx, %ecx
200 ; X86-NEXT:    sarl $31, %ecx
201 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
202 ; X86-NEXT:    sbbl %esi, %edx
203 ; X86-NEXT:    movl %ecx, %esi
204 ; X86-NEXT:    sbbl %edi, %esi
205 ; X86-NEXT:    sbbl %edi, %ecx
206 ; X86-NEXT:    sarl $31, %ecx
207 ; X86-NEXT:    xorl %ecx, %edx
208 ; X86-NEXT:    xorl %ecx, %eax
209 ; X86-NEXT:    subl %ecx, %eax
210 ; X86-NEXT:    sbbl %ecx, %edx
211 ; X86-NEXT:    popl %esi
212 ; X86-NEXT:    popl %edi
213 ; X86-NEXT:    retl
215 ; X64-LABEL: abd_ext_i64:
216 ; X64:       # %bb.0:
217 ; X64-NEXT:    movq %rdi, %rax
218 ; X64-NEXT:    subq %rsi, %rax
219 ; X64-NEXT:    negq %rax
220 ; X64-NEXT:    subq %rsi, %rdi
221 ; X64-NEXT:    cmovgq %rdi, %rax
222 ; X64-NEXT:    retq
223   %aext = sext i64 %a to i128
224   %bext = sext i64 %b to i128
225   %sub = sub i128 %aext, %bext
226   %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)
227   %trunc = trunc i128 %abs to i64
228   ret i64 %trunc
231 define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind {
232 ; X86-LABEL: abd_ext_i64_undef:
233 ; X86:       # %bb.0:
234 ; X86-NEXT:    pushl %edi
235 ; X86-NEXT:    pushl %esi
236 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
237 ; X86-NEXT:    movl %esi, %edi
238 ; X86-NEXT:    sarl $31, %edi
239 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
240 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
241 ; X86-NEXT:    movl %edx, %ecx
242 ; X86-NEXT:    sarl $31, %ecx
243 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
244 ; X86-NEXT:    sbbl %esi, %edx
245 ; X86-NEXT:    movl %ecx, %esi
246 ; X86-NEXT:    sbbl %edi, %esi
247 ; X86-NEXT:    sbbl %edi, %ecx
248 ; X86-NEXT:    sarl $31, %ecx
249 ; X86-NEXT:    xorl %ecx, %edx
250 ; X86-NEXT:    xorl %ecx, %eax
251 ; X86-NEXT:    subl %ecx, %eax
252 ; X86-NEXT:    sbbl %ecx, %edx
253 ; X86-NEXT:    popl %esi
254 ; X86-NEXT:    popl %edi
255 ; X86-NEXT:    retl
257 ; X64-LABEL: abd_ext_i64_undef:
258 ; X64:       # %bb.0:
259 ; X64-NEXT:    movq %rdi, %rax
260 ; X64-NEXT:    subq %rsi, %rax
261 ; X64-NEXT:    negq %rax
262 ; X64-NEXT:    subq %rsi, %rdi
263 ; X64-NEXT:    cmovgq %rdi, %rax
264 ; X64-NEXT:    retq
265   %aext = sext i64 %a to i128
266   %bext = sext i64 %b to i128
267   %sub = sub i128 %aext, %bext
268   %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)
269   %trunc = trunc i128 %abs to i64
270   ret i64 %trunc
274 ; sub(smax(a,b),smin(a,b)) -> abds(a,b)
277 define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind {
278 ; X86-LABEL: abd_minmax_i8:
279 ; X86:       # %bb.0:
280 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
281 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %ecx
282 ; X86-NEXT:    subl %eax, %ecx
283 ; X86-NEXT:    movl %ecx, %eax
284 ; X86-NEXT:    negl %eax
285 ; X86-NEXT:    cmovsl %ecx, %eax
286 ; X86-NEXT:    # kill: def $al killed $al killed $eax
287 ; X86-NEXT:    retl
289 ; X64-LABEL: abd_minmax_i8:
290 ; X64:       # %bb.0:
291 ; X64-NEXT:    movsbl %sil, %eax
292 ; X64-NEXT:    movsbl %dil, %ecx
293 ; X64-NEXT:    subl %eax, %ecx
294 ; X64-NEXT:    movl %ecx, %eax
295 ; X64-NEXT:    negl %eax
296 ; X64-NEXT:    cmovsl %ecx, %eax
297 ; X64-NEXT:    # kill: def $al killed $al killed $eax
298 ; X64-NEXT:    retq
299   %min = call i8 @llvm.smin.i8(i8 %a, i8 %b)
300   %max = call i8 @llvm.smax.i8(i8 %a, i8 %b)
301   %sub = sub i8 %max, %min
302   ret i8 %sub
305 define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind {
306 ; X86-LABEL: abd_minmax_i16:
307 ; X86:       # %bb.0:
308 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
309 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
310 ; X86-NEXT:    subl %eax, %ecx
311 ; X86-NEXT:    movl %ecx, %eax
312 ; X86-NEXT:    negl %eax
313 ; X86-NEXT:    cmovsl %ecx, %eax
314 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
315 ; X86-NEXT:    retl
317 ; X64-LABEL: abd_minmax_i16:
318 ; X64:       # %bb.0:
319 ; X64-NEXT:    movswl %si, %eax
320 ; X64-NEXT:    movswl %di, %ecx
321 ; X64-NEXT:    subl %eax, %ecx
322 ; X64-NEXT:    movl %ecx, %eax
323 ; X64-NEXT:    negl %eax
324 ; X64-NEXT:    cmovsl %ecx, %eax
325 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
326 ; X64-NEXT:    retq
327   %min = call i16 @llvm.smin.i16(i16 %a, i16 %b)
328   %max = call i16 @llvm.smax.i16(i16 %a, i16 %b)
329   %sub = sub i16 %max, %min
330   ret i16 %sub
333 define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind {
334 ; X86-LABEL: abd_minmax_i32:
335 ; X86:       # %bb.0:
336 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
337 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
338 ; X86-NEXT:    movl %eax, %edx
339 ; X86-NEXT:    subl %ecx, %edx
340 ; X86-NEXT:    negl %edx
341 ; X86-NEXT:    subl %ecx, %eax
342 ; X86-NEXT:    cmovlel %edx, %eax
343 ; X86-NEXT:    retl
345 ; X64-LABEL: abd_minmax_i32:
346 ; X64:       # %bb.0:
347 ; X64-NEXT:    movslq %esi, %rax
348 ; X64-NEXT:    movslq %edi, %rcx
349 ; X64-NEXT:    subq %rax, %rcx
350 ; X64-NEXT:    movq %rcx, %rax
351 ; X64-NEXT:    negq %rax
352 ; X64-NEXT:    cmovsq %rcx, %rax
353 ; X64-NEXT:    # kill: def $eax killed $eax killed $rax
354 ; X64-NEXT:    retq
355   %min = call i32 @llvm.smin.i32(i32 %a, i32 %b)
356   %max = call i32 @llvm.smax.i32(i32 %a, i32 %b)
357   %sub = sub i32 %max, %min
358   ret i32 %sub
361 define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind {
362 ; X86-LABEL: abd_minmax_i64:
363 ; X86:       # %bb.0:
364 ; X86-NEXT:    pushl %ebp
365 ; X86-NEXT:    pushl %ebx
366 ; X86-NEXT:    pushl %edi
367 ; X86-NEXT:    pushl %esi
368 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
369 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
370 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
371 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
372 ; X86-NEXT:    cmpl %eax, %ecx
373 ; X86-NEXT:    movl %esi, %edi
374 ; X86-NEXT:    sbbl %edx, %edi
375 ; X86-NEXT:    movl %edx, %edi
376 ; X86-NEXT:    cmovll %esi, %edi
377 ; X86-NEXT:    movl %eax, %ebx
378 ; X86-NEXT:    cmovll %ecx, %ebx
379 ; X86-NEXT:    cmpl %ecx, %eax
380 ; X86-NEXT:    movl %edx, %ebp
381 ; X86-NEXT:    sbbl %esi, %ebp
382 ; X86-NEXT:    cmovll %esi, %edx
383 ; X86-NEXT:    cmovll %ecx, %eax
384 ; X86-NEXT:    subl %ebx, %eax
385 ; X86-NEXT:    sbbl %edi, %edx
386 ; X86-NEXT:    popl %esi
387 ; X86-NEXT:    popl %edi
388 ; X86-NEXT:    popl %ebx
389 ; X86-NEXT:    popl %ebp
390 ; X86-NEXT:    retl
392 ; X64-LABEL: abd_minmax_i64:
393 ; X64:       # %bb.0:
394 ; X64-NEXT:    movq %rdi, %rax
395 ; X64-NEXT:    subq %rsi, %rax
396 ; X64-NEXT:    negq %rax
397 ; X64-NEXT:    subq %rsi, %rdi
398 ; X64-NEXT:    cmovgq %rdi, %rax
399 ; X64-NEXT:    retq
400   %min = call i64 @llvm.smin.i64(i64 %a, i64 %b)
401   %max = call i64 @llvm.smax.i64(i64 %a, i64 %b)
402   %sub = sub i64 %max, %min
403   ret i64 %sub
407 ; select(icmp(a,b),sub(a,b),sub(b,a)) -> abds(a,b)
410 define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind {
411 ; X86-LABEL: abd_cmp_i8:
412 ; X86:       # %bb.0:
413 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
414 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
415 ; X86-NEXT:    movl %eax, %edx
416 ; X86-NEXT:    subb %cl, %dl
417 ; X86-NEXT:    negb %dl
418 ; X86-NEXT:    subb %cl, %al
419 ; X86-NEXT:    movzbl %al, %ecx
420 ; X86-NEXT:    movzbl %dl, %eax
421 ; X86-NEXT:    cmovgl %ecx, %eax
422 ; X86-NEXT:    # kill: def $al killed $al killed $eax
423 ; X86-NEXT:    retl
425 ; X64-LABEL: abd_cmp_i8:
426 ; X64:       # %bb.0:
427 ; X64-NEXT:    movl %edi, %eax
428 ; X64-NEXT:    subb %sil, %al
429 ; X64-NEXT:    negb %al
430 ; X64-NEXT:    subb %sil, %dil
431 ; X64-NEXT:    movzbl %dil, %ecx
432 ; X64-NEXT:    movzbl %al, %eax
433 ; X64-NEXT:    cmovgl %ecx, %eax
434 ; X64-NEXT:    # kill: def $al killed $al killed $eax
435 ; X64-NEXT:    retq
436   %cmp = icmp sgt i8 %a, %b
437   %ab = sub i8 %a, %b
438   %ba = sub i8 %b, %a
439   %sel = select i1 %cmp, i8 %ab, i8 %ba
440   ret i8 %sel
443 define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind {
444 ; X86-LABEL: abd_cmp_i16:
445 ; X86:       # %bb.0:
446 ; X86-NEXT:    pushl %esi
447 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
448 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
449 ; X86-NEXT:    movl %ecx, %esi
450 ; X86-NEXT:    subw %dx, %si
451 ; X86-NEXT:    movl %esi, %eax
452 ; X86-NEXT:    negl %eax
453 ; X86-NEXT:    cmpw %dx, %cx
454 ; X86-NEXT:    cmovgel %esi, %eax
455 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
456 ; X86-NEXT:    popl %esi
457 ; X86-NEXT:    retl
459 ; X64-LABEL: abd_cmp_i16:
460 ; X64:       # %bb.0:
461 ; X64-NEXT:    movl %edi, %ecx
462 ; X64-NEXT:    subw %si, %cx
463 ; X64-NEXT:    movl %ecx, %eax
464 ; X64-NEXT:    negl %eax
465 ; X64-NEXT:    cmpw %si, %di
466 ; X64-NEXT:    cmovgel %ecx, %eax
467 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
468 ; X64-NEXT:    retq
469   %cmp = icmp sge i16 %a, %b
470   %ab = sub i16 %a, %b
471   %ba = sub i16 %b, %a
472   %sel = select i1 %cmp, i16 %ab, i16 %ba
473   ret i16 %sel
476 define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind {
477 ; X86-LABEL: abd_cmp_i32:
478 ; X86:       # %bb.0:
479 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
480 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
481 ; X86-NEXT:    movl %eax, %edx
482 ; X86-NEXT:    subl %ecx, %edx
483 ; X86-NEXT:    negl %edx
484 ; X86-NEXT:    subl %ecx, %eax
485 ; X86-NEXT:    cmovll %edx, %eax
486 ; X86-NEXT:    retl
488 ; X64-LABEL: abd_cmp_i32:
489 ; X64:       # %bb.0:
490 ; X64-NEXT:    movl %edi, %eax
491 ; X64-NEXT:    subl %esi, %eax
492 ; X64-NEXT:    negl %eax
493 ; X64-NEXT:    subl %esi, %edi
494 ; X64-NEXT:    cmovgel %edi, %eax
495 ; X64-NEXT:    retq
496   %cmp = icmp slt i32 %a, %b
497   %ab = sub i32 %a, %b
498   %ba = sub i32 %b, %a
499   %sel = select i1 %cmp, i32 %ba, i32 %ab
500   ret i32 %sel
503 define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind {
504 ; X86-LABEL: abd_cmp_i64:
505 ; X86:       # %bb.0:
506 ; X86-NEXT:    pushl %ebx
507 ; X86-NEXT:    pushl %edi
508 ; X86-NEXT:    pushl %esi
509 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
510 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
511 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
512 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
513 ; X86-NEXT:    movl %ecx, %edi
514 ; X86-NEXT:    subl %eax, %edi
515 ; X86-NEXT:    movl %esi, %ebx
516 ; X86-NEXT:    sbbl %edx, %ebx
517 ; X86-NEXT:    subl %ecx, %eax
518 ; X86-NEXT:    sbbl %esi, %edx
519 ; X86-NEXT:    cmovgel %edi, %eax
520 ; X86-NEXT:    cmovgel %ebx, %edx
521 ; X86-NEXT:    popl %esi
522 ; X86-NEXT:    popl %edi
523 ; X86-NEXT:    popl %ebx
524 ; X86-NEXT:    retl
526 ; X64-LABEL: abd_cmp_i64:
527 ; X64:       # %bb.0:
528 ; X64-NEXT:    movq %rdi, %rax
529 ; X64-NEXT:    subq %rsi, %rax
530 ; X64-NEXT:    negq %rax
531 ; X64-NEXT:    subq %rsi, %rdi
532 ; X64-NEXT:    cmovlq %rdi, %rax
533 ; X64-NEXT:    retq
534   %cmp = icmp sge i64 %a, %b
535   %ab = sub i64 %a, %b
536   %ba = sub i64 %b, %a
537   %sel = select i1 %cmp, i64 %ba, i64 %ab
538   ret i64 %sel
542 ; abs(sub_nsw(x, y)) -> abds(a,b)
545 define i8 @abd_subnsw_i8(i8 %a, i8 %b) nounwind {
546 ; X86-LABEL: abd_subnsw_i8:
547 ; X86:       # %bb.0:
548 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
549 ; X86-NEXT:    subb {{[0-9]+}}(%esp), %al
550 ; X86-NEXT:    movl %eax, %ecx
551 ; X86-NEXT:    sarb $7, %cl
552 ; X86-NEXT:    xorb %cl, %al
553 ; X86-NEXT:    subb %cl, %al
554 ; X86-NEXT:    retl
556 ; X64-LABEL: abd_subnsw_i8:
557 ; X64:       # %bb.0:
558 ; X64-NEXT:    movl %edi, %eax
559 ; X64-NEXT:    subb %sil, %al
560 ; X64-NEXT:    movl %eax, %ecx
561 ; X64-NEXT:    sarb $7, %cl
562 ; X64-NEXT:    xorb %cl, %al
563 ; X64-NEXT:    subb %cl, %al
564 ; X64-NEXT:    # kill: def $al killed $al killed $eax
565 ; X64-NEXT:    retq
566   %sub = sub nsw i8 %a, %b
567   %abs = call i8 @llvm.abs.i8(i8 %sub, i1 false)
568   ret i8 %abs
571 define i8 @abd_subnsw_i8_undef(i8 %a, i8 %b) nounwind {
572 ; X86-LABEL: abd_subnsw_i8_undef:
573 ; X86:       # %bb.0:
574 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
575 ; X86-NEXT:    subb {{[0-9]+}}(%esp), %al
576 ; X86-NEXT:    movl %eax, %ecx
577 ; X86-NEXT:    sarb $7, %cl
578 ; X86-NEXT:    xorb %cl, %al
579 ; X86-NEXT:    subb %cl, %al
580 ; X86-NEXT:    retl
582 ; X64-LABEL: abd_subnsw_i8_undef:
583 ; X64:       # %bb.0:
584 ; X64-NEXT:    movl %edi, %eax
585 ; X64-NEXT:    subb %sil, %al
586 ; X64-NEXT:    movl %eax, %ecx
587 ; X64-NEXT:    sarb $7, %cl
588 ; X64-NEXT:    xorb %cl, %al
589 ; X64-NEXT:    subb %cl, %al
590 ; X64-NEXT:    # kill: def $al killed $al killed $eax
591 ; X64-NEXT:    retq
592   %sub = sub nsw i8 %a, %b
593   %abs = call i8 @llvm.abs.i8(i8 %sub, i1 true)
594   ret i8 %abs
597 define i16 @abd_subnsw_i16(i16 %a, i16 %b) nounwind {
598 ; X86-LABEL: abd_subnsw_i16:
599 ; X86:       # %bb.0:
600 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
601 ; X86-NEXT:    subw {{[0-9]+}}(%esp), %cx
602 ; X86-NEXT:    movl %ecx, %eax
603 ; X86-NEXT:    negw %ax
604 ; X86-NEXT:    cmovsw %cx, %ax
605 ; X86-NEXT:    retl
607 ; X64-LABEL: abd_subnsw_i16:
608 ; X64:       # %bb.0:
609 ; X64-NEXT:    subl %esi, %edi
610 ; X64-NEXT:    movl %edi, %eax
611 ; X64-NEXT:    negw %ax
612 ; X64-NEXT:    cmovsw %di, %ax
613 ; X64-NEXT:    retq
614   %sub = sub nsw i16 %a, %b
615   %abs = call i16 @llvm.abs.i16(i16 %sub, i1 false)
616   ret i16 %abs
619 define i16 @abd_subnsw_i16_undef(i16 %a, i16 %b) nounwind {
620 ; X86-LABEL: abd_subnsw_i16_undef:
621 ; X86:       # %bb.0:
622 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
623 ; X86-NEXT:    subw {{[0-9]+}}(%esp), %cx
624 ; X86-NEXT:    movl %ecx, %eax
625 ; X86-NEXT:    negw %ax
626 ; X86-NEXT:    cmovsw %cx, %ax
627 ; X86-NEXT:    retl
629 ; X64-LABEL: abd_subnsw_i16_undef:
630 ; X64:       # %bb.0:
631 ; X64-NEXT:    subl %esi, %edi
632 ; X64-NEXT:    movl %edi, %eax
633 ; X64-NEXT:    negw %ax
634 ; X64-NEXT:    cmovsw %di, %ax
635 ; X64-NEXT:    retq
636   %sub = sub nsw i16 %a, %b
637   %abs = call i16 @llvm.abs.i16(i16 %sub, i1 true)
638   ret i16 %abs
641 define i32 @abd_subnsw_i32(i32 %a, i32 %b) nounwind {
642 ; X86-LABEL: abd_subnsw_i32:
643 ; X86:       # %bb.0:
644 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
645 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %ecx
646 ; X86-NEXT:    movl %ecx, %eax
647 ; X86-NEXT:    negl %eax
648 ; X86-NEXT:    cmovsl %ecx, %eax
649 ; X86-NEXT:    retl
651 ; X64-LABEL: abd_subnsw_i32:
652 ; X64:       # %bb.0:
653 ; X64-NEXT:    subl %esi, %edi
654 ; X64-NEXT:    movl %edi, %eax
655 ; X64-NEXT:    negl %eax
656 ; X64-NEXT:    cmovsl %edi, %eax
657 ; X64-NEXT:    retq
658   %sub = sub nsw i32 %a, %b
659   %abs = call i32 @llvm.abs.i32(i32 %sub, i1 false)
660   ret i32 %abs
663 define i32 @abd_subnsw_i32_undef(i32 %a, i32 %b) nounwind {
664 ; X86-LABEL: abd_subnsw_i32_undef:
665 ; X86:       # %bb.0:
666 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
667 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %ecx
668 ; X86-NEXT:    movl %ecx, %eax
669 ; X86-NEXT:    negl %eax
670 ; X86-NEXT:    cmovsl %ecx, %eax
671 ; X86-NEXT:    retl
673 ; X64-LABEL: abd_subnsw_i32_undef:
674 ; X64:       # %bb.0:
675 ; X64-NEXT:    subl %esi, %edi
676 ; X64-NEXT:    movl %edi, %eax
677 ; X64-NEXT:    negl %eax
678 ; X64-NEXT:    cmovsl %edi, %eax
679 ; X64-NEXT:    retq
680   %sub = sub nsw i32 %a, %b
681   %abs = call i32 @llvm.abs.i32(i32 %sub, i1 true)
682   ret i32 %abs
685 define i64 @abd_subnsw_i64(i64 %a, i64 %b) nounwind {
686 ; X86-LABEL: abd_subnsw_i64:
687 ; X86:       # %bb.0:
688 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
689 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
690 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
691 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
692 ; X86-NEXT:    movl %edx, %ecx
693 ; X86-NEXT:    sarl $31, %ecx
694 ; X86-NEXT:    xorl %ecx, %edx
695 ; X86-NEXT:    xorl %ecx, %eax
696 ; X86-NEXT:    subl %ecx, %eax
697 ; X86-NEXT:    sbbl %ecx, %edx
698 ; X86-NEXT:    retl
700 ; X64-LABEL: abd_subnsw_i64:
701 ; X64:       # %bb.0:
702 ; X64-NEXT:    subq %rsi, %rdi
703 ; X64-NEXT:    movq %rdi, %rax
704 ; X64-NEXT:    negq %rax
705 ; X64-NEXT:    cmovsq %rdi, %rax
706 ; X64-NEXT:    retq
707   %sub = sub nsw i64 %a, %b
708   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
709   ret i64 %abs
712 define i64 @abd_subnsw_i64_undef(i64 %a, i64 %b) nounwind {
713 ; X86-LABEL: abd_subnsw_i64_undef:
714 ; X86:       # %bb.0:
715 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
716 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
717 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
718 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
719 ; X86-NEXT:    movl %edx, %ecx
720 ; X86-NEXT:    sarl $31, %ecx
721 ; X86-NEXT:    xorl %ecx, %edx
722 ; X86-NEXT:    xorl %ecx, %eax
723 ; X86-NEXT:    subl %ecx, %eax
724 ; X86-NEXT:    sbbl %ecx, %edx
725 ; X86-NEXT:    retl
727 ; X64-LABEL: abd_subnsw_i64_undef:
728 ; X64:       # %bb.0:
729 ; X64-NEXT:    subq %rsi, %rdi
730 ; X64-NEXT:    movq %rdi, %rax
731 ; X64-NEXT:    negq %rax
732 ; X64-NEXT:    cmovsq %rdi, %rax
733 ; X64-NEXT:    retq
734   %sub = sub nsw i64 %a, %b
735   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
736   ret i64 %abs
740 ; negative tests
743 define i32 @abd_sub_i32(i32 %a, i32 %b) nounwind {
744 ; X86-LABEL: abd_sub_i32:
745 ; X86:       # %bb.0:
746 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
747 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %ecx
748 ; X86-NEXT:    movl %ecx, %eax
749 ; X86-NEXT:    negl %eax
750 ; X86-NEXT:    cmovsl %ecx, %eax
751 ; X86-NEXT:    retl
753 ; X64-LABEL: abd_sub_i32:
754 ; X64:       # %bb.0:
755 ; X64-NEXT:    subl %esi, %edi
756 ; X64-NEXT:    movl %edi, %eax
757 ; X64-NEXT:    negl %eax
758 ; X64-NEXT:    cmovsl %edi, %eax
759 ; X64-NEXT:    retq
760   %sub = sub i32 %a, %b
761   %abs = call i32 @llvm.abs.i32(i32 %sub, i1 false)
762   ret i32 %abs
766 declare i8 @llvm.abs.i8(i8, i1)
767 declare i16 @llvm.abs.i16(i16, i1)
768 declare i32 @llvm.abs.i32(i32, i1)
769 declare i64 @llvm.abs.i64(i64, i1)
770 declare i128 @llvm.abs.i128(i128, i1)
772 declare i8 @llvm.smax.i8(i8, i8)
773 declare i16 @llvm.smax.i16(i16, i16)
774 declare i32 @llvm.smax.i32(i32, i32)
775 declare i64 @llvm.smax.i64(i64, i64)
777 declare i8 @llvm.smin.i8(i8, i8)
778 declare i16 @llvm.smin.i16(i16, i16)
779 declare i32 @llvm.smin.i32(i32, i32)
780 declare i64 @llvm.smin.i64(i64, i64)