[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / test / CodeGen / X86 / abds.ll
blob0356c2702a4199c8320d6e0b9ca4a6d5bad4f4a8
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:    movl %ecx, %edx
15 ; X86-NEXT:    subl %eax, %edx
16 ; X86-NEXT:    subl %ecx, %eax
17 ; X86-NEXT:    cmovll %edx, %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:    movl %ecx, %edx
26 ; X64-NEXT:    subl %eax, %edx
27 ; X64-NEXT:    subl %ecx, %eax
28 ; X64-NEXT:    cmovll %edx, %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_i16(i8 %a, i16 %b) nounwind {
40 ; X86-LABEL: abd_ext_i8_i16:
41 ; X86:       # %bb.0:
42 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
43 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %ecx
44 ; X86-NEXT:    movl %ecx, %edx
45 ; X86-NEXT:    subl %eax, %edx
46 ; X86-NEXT:    subl %ecx, %eax
47 ; X86-NEXT:    cmovll %edx, %eax
48 ; X86-NEXT:    # kill: def $al killed $al killed $eax
49 ; X86-NEXT:    retl
51 ; X64-LABEL: abd_ext_i8_i16:
52 ; X64:       # %bb.0:
53 ; X64-NEXT:    movsbl %dil, %ecx
54 ; X64-NEXT:    subl %esi, %edi
55 ; X64-NEXT:    movswl %si, %eax
56 ; X64-NEXT:    subl %ecx, %eax
57 ; X64-NEXT:    cmovll %edi, %eax
58 ; X64-NEXT:    # kill: def $al killed $al killed $eax
59 ; X64-NEXT:    retq
60   %aext = sext i8 %a to i64
61   %bext = sext i16 %b to i64
62   %sub = sub i64 %aext, %bext
63   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
64   %trunc = trunc i64 %abs to i8
65   ret i8 %trunc
68 define i8 @abd_ext_i8_undef(i8 %a, i8 %b) nounwind {
69 ; X86-LABEL: abd_ext_i8_undef:
70 ; X86:       # %bb.0:
71 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
72 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %ecx
73 ; X86-NEXT:    movl %ecx, %edx
74 ; X86-NEXT:    subl %eax, %edx
75 ; X86-NEXT:    subl %ecx, %eax
76 ; X86-NEXT:    cmovll %edx, %eax
77 ; X86-NEXT:    # kill: def $al killed $al killed $eax
78 ; X86-NEXT:    retl
80 ; X64-LABEL: abd_ext_i8_undef:
81 ; X64:       # %bb.0:
82 ; X64-NEXT:    movsbl %sil, %eax
83 ; X64-NEXT:    movsbl %dil, %ecx
84 ; X64-NEXT:    movl %ecx, %edx
85 ; X64-NEXT:    subl %eax, %edx
86 ; X64-NEXT:    subl %ecx, %eax
87 ; X64-NEXT:    cmovll %edx, %eax
88 ; X64-NEXT:    # kill: def $al killed $al killed $eax
89 ; X64-NEXT:    retq
90   %aext = sext i8 %a to i64
91   %bext = sext i8 %b to i64
92   %sub = sub i64 %aext, %bext
93   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
94   %trunc = trunc i64 %abs to i8
95   ret i8 %trunc
98 define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind {
99 ; X86-LABEL: abd_ext_i16:
100 ; X86:       # %bb.0:
101 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
102 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
103 ; X86-NEXT:    movl %ecx, %edx
104 ; X86-NEXT:    subl %eax, %edx
105 ; X86-NEXT:    subl %ecx, %eax
106 ; X86-NEXT:    cmovll %edx, %eax
107 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
108 ; X86-NEXT:    retl
110 ; X64-LABEL: abd_ext_i16:
111 ; X64:       # %bb.0:
112 ; X64-NEXT:    movswl %si, %eax
113 ; X64-NEXT:    movswl %di, %ecx
114 ; X64-NEXT:    movl %ecx, %edx
115 ; X64-NEXT:    subl %eax, %edx
116 ; X64-NEXT:    subl %ecx, %eax
117 ; X64-NEXT:    cmovll %edx, %eax
118 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
119 ; X64-NEXT:    retq
120   %aext = sext i16 %a to i64
121   %bext = sext i16 %b to i64
122   %sub = sub i64 %aext, %bext
123   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
124   %trunc = trunc i64 %abs to i16
125   ret i16 %trunc
128 define i16 @abd_ext_i16_i32(i16 %a, i32 %b) nounwind {
129 ; X86-LABEL: abd_ext_i16_i32:
130 ; X86:       # %bb.0:
131 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
132 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
133 ; X86-NEXT:    movl %ecx, %edx
134 ; X86-NEXT:    subl %eax, %edx
135 ; X86-NEXT:    subl %ecx, %eax
136 ; X86-NEXT:    cmovll %edx, %eax
137 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
138 ; X86-NEXT:    retl
140 ; X64-LABEL: abd_ext_i16_i32:
141 ; X64:       # %bb.0:
142 ; X64-NEXT:    movswl %di, %ecx
143 ; X64-NEXT:    movl %edi, %eax
144 ; X64-NEXT:    subl %esi, %eax
145 ; X64-NEXT:    subl %ecx, %esi
146 ; X64-NEXT:    cmovgel %esi, %eax
147 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
148 ; X64-NEXT:    retq
149   %aext = sext i16 %a to i64
150   %bext = sext i32 %b to i64
151   %sub = sub i64 %aext, %bext
152   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
153   %trunc = trunc i64 %abs to i16
154   ret i16 %trunc
157 define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind {
158 ; X86-LABEL: abd_ext_i16_undef:
159 ; X86:       # %bb.0:
160 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
161 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
162 ; X86-NEXT:    movl %ecx, %edx
163 ; X86-NEXT:    subl %eax, %edx
164 ; X86-NEXT:    subl %ecx, %eax
165 ; X86-NEXT:    cmovll %edx, %eax
166 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
167 ; X86-NEXT:    retl
169 ; X64-LABEL: abd_ext_i16_undef:
170 ; X64:       # %bb.0:
171 ; X64-NEXT:    movswl %si, %eax
172 ; X64-NEXT:    movswl %di, %ecx
173 ; X64-NEXT:    movl %ecx, %edx
174 ; X64-NEXT:    subl %eax, %edx
175 ; X64-NEXT:    subl %ecx, %eax
176 ; X64-NEXT:    cmovll %edx, %eax
177 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
178 ; X64-NEXT:    retq
179   %aext = sext i16 %a to i64
180   %bext = sext i16 %b to i64
181   %sub = sub i64 %aext, %bext
182   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
183   %trunc = trunc i64 %abs to i16
184   ret i16 %trunc
187 define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind {
188 ; X86-LABEL: abd_ext_i32:
189 ; X86:       # %bb.0:
190 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
191 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
192 ; X86-NEXT:    movl %ecx, %edx
193 ; X86-NEXT:    subl %eax, %edx
194 ; X86-NEXT:    subl %ecx, %eax
195 ; X86-NEXT:    cmovll %edx, %eax
196 ; X86-NEXT:    retl
198 ; X64-LABEL: abd_ext_i32:
199 ; X64:       # %bb.0:
200 ; X64-NEXT:    movl %edi, %eax
201 ; X64-NEXT:    subl %esi, %eax
202 ; X64-NEXT:    subl %edi, %esi
203 ; X64-NEXT:    cmovgel %esi, %eax
204 ; X64-NEXT:    retq
205   %aext = sext i32 %a to i64
206   %bext = sext i32 %b to i64
207   %sub = sub i64 %aext, %bext
208   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
209   %trunc = trunc i64 %abs to i32
210   ret i32 %trunc
213 define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind {
214 ; X86-LABEL: abd_ext_i32_i16:
215 ; X86:       # %bb.0:
216 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
217 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
218 ; X86-NEXT:    movl %ecx, %edx
219 ; X86-NEXT:    subl %eax, %edx
220 ; X86-NEXT:    subl %ecx, %eax
221 ; X86-NEXT:    cmovll %edx, %eax
222 ; X86-NEXT:    retl
224 ; X64-LABEL: abd_ext_i32_i16:
225 ; X64:       # %bb.0:
226 ; X64-NEXT:    movswl %si, %eax
227 ; X64-NEXT:    movl %edi, %ecx
228 ; X64-NEXT:    subl %eax, %ecx
229 ; X64-NEXT:    subl %edi, %eax
230 ; X64-NEXT:    cmovll %ecx, %eax
231 ; X64-NEXT:    retq
232   %aext = sext i32 %a to i64
233   %bext = sext i16 %b to i64
234   %sub = sub i64 %aext, %bext
235   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
236   %trunc = trunc i64 %abs to i32
237   ret i32 %trunc
240 define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind {
241 ; X86-LABEL: abd_ext_i32_undef:
242 ; X86:       # %bb.0:
243 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
244 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
245 ; X86-NEXT:    movl %ecx, %edx
246 ; X86-NEXT:    subl %eax, %edx
247 ; X86-NEXT:    subl %ecx, %eax
248 ; X86-NEXT:    cmovll %edx, %eax
249 ; X86-NEXT:    retl
251 ; X64-LABEL: abd_ext_i32_undef:
252 ; X64:       # %bb.0:
253 ; X64-NEXT:    movl %edi, %eax
254 ; X64-NEXT:    subl %esi, %eax
255 ; X64-NEXT:    subl %edi, %esi
256 ; X64-NEXT:    cmovgel %esi, %eax
257 ; X64-NEXT:    retq
258   %aext = sext i32 %a to i64
259   %bext = sext i32 %b to i64
260   %sub = sub i64 %aext, %bext
261   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
262   %trunc = trunc i64 %abs to i32
263   ret i32 %trunc
266 define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind {
267 ; X86-LABEL: abd_ext_i64:
268 ; X86:       # %bb.0:
269 ; X86-NEXT:    pushl %ebx
270 ; X86-NEXT:    pushl %edi
271 ; X86-NEXT:    pushl %esi
272 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
273 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
274 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
275 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
276 ; X86-NEXT:    movl %ecx, %edi
277 ; X86-NEXT:    subl %eax, %edi
278 ; X86-NEXT:    movl %esi, %ebx
279 ; X86-NEXT:    sbbl %edx, %ebx
280 ; X86-NEXT:    subl %ecx, %eax
281 ; X86-NEXT:    sbbl %esi, %edx
282 ; X86-NEXT:    cmovll %edi, %eax
283 ; X86-NEXT:    cmovll %ebx, %edx
284 ; X86-NEXT:    popl %esi
285 ; X86-NEXT:    popl %edi
286 ; X86-NEXT:    popl %ebx
287 ; X86-NEXT:    retl
289 ; X64-LABEL: abd_ext_i64:
290 ; X64:       # %bb.0:
291 ; X64-NEXT:    movq %rdi, %rax
292 ; X64-NEXT:    subq %rsi, %rax
293 ; X64-NEXT:    subq %rdi, %rsi
294 ; X64-NEXT:    cmovgeq %rsi, %rax
295 ; X64-NEXT:    retq
296   %aext = sext i64 %a to i128
297   %bext = sext i64 %b to i128
298   %sub = sub i128 %aext, %bext
299   %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)
300   %trunc = trunc i128 %abs to i64
301   ret i64 %trunc
304 define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind {
305 ; X86-LABEL: abd_ext_i64_undef:
306 ; X86:       # %bb.0:
307 ; X86-NEXT:    pushl %ebx
308 ; X86-NEXT:    pushl %edi
309 ; X86-NEXT:    pushl %esi
310 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
311 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
312 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
313 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
314 ; X86-NEXT:    movl %ecx, %edi
315 ; X86-NEXT:    subl %eax, %edi
316 ; X86-NEXT:    movl %esi, %ebx
317 ; X86-NEXT:    sbbl %edx, %ebx
318 ; X86-NEXT:    subl %ecx, %eax
319 ; X86-NEXT:    sbbl %esi, %edx
320 ; X86-NEXT:    cmovll %edi, %eax
321 ; X86-NEXT:    cmovll %ebx, %edx
322 ; X86-NEXT:    popl %esi
323 ; X86-NEXT:    popl %edi
324 ; X86-NEXT:    popl %ebx
325 ; X86-NEXT:    retl
327 ; X64-LABEL: abd_ext_i64_undef:
328 ; X64:       # %bb.0:
329 ; X64-NEXT:    movq %rdi, %rax
330 ; X64-NEXT:    subq %rsi, %rax
331 ; X64-NEXT:    subq %rdi, %rsi
332 ; X64-NEXT:    cmovgeq %rsi, %rax
333 ; X64-NEXT:    retq
334   %aext = sext i64 %a to i128
335   %bext = sext i64 %b to i128
336   %sub = sub i128 %aext, %bext
337   %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)
338   %trunc = trunc i128 %abs to i64
339   ret i64 %trunc
342 define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {
343 ; X86-LABEL: abd_ext_i128:
344 ; X86:       # %bb.0:
345 ; X86-NEXT:    pushl %ebp
346 ; X86-NEXT:    pushl %ebx
347 ; X86-NEXT:    pushl %edi
348 ; X86-NEXT:    pushl %esi
349 ; X86-NEXT:    pushl %eax
350 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
351 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
352 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
353 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
354 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
355 ; X86-NEXT:    subl %edx, %eax
356 ; X86-NEXT:    movl %eax, (%esp) # 4-byte Spill
357 ; X86-NEXT:    sbbl %esi, %ebx
358 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebp
359 ; X86-NEXT:    sbbl %ecx, %ebp
360 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
361 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
362 ; X86-NEXT:    sbbl %edi, %eax
363 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
364 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
365 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
366 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edi
367 ; X86-NEXT:    cmovll (%esp), %edx # 4-byte Folded Reload
368 ; X86-NEXT:    cmovll %ebx, %esi
369 ; X86-NEXT:    cmovll %ebp, %ecx
370 ; X86-NEXT:    cmovll %eax, %edi
371 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
372 ; X86-NEXT:    movl %edi, 12(%eax)
373 ; X86-NEXT:    movl %ecx, 8(%eax)
374 ; X86-NEXT:    movl %esi, 4(%eax)
375 ; X86-NEXT:    movl %edx, (%eax)
376 ; X86-NEXT:    addl $4, %esp
377 ; X86-NEXT:    popl %esi
378 ; X86-NEXT:    popl %edi
379 ; X86-NEXT:    popl %ebx
380 ; X86-NEXT:    popl %ebp
381 ; X86-NEXT:    retl $4
383 ; X64-LABEL: abd_ext_i128:
384 ; X64:       # %bb.0:
385 ; X64-NEXT:    movq %rdi, %rax
386 ; X64-NEXT:    subq %rdx, %rax
387 ; X64-NEXT:    movq %rsi, %r8
388 ; X64-NEXT:    sbbq %rcx, %r8
389 ; X64-NEXT:    subq %rdi, %rdx
390 ; X64-NEXT:    sbbq %rsi, %rcx
391 ; X64-NEXT:    cmovgeq %rdx, %rax
392 ; X64-NEXT:    cmovgeq %rcx, %r8
393 ; X64-NEXT:    movq %r8, %rdx
394 ; X64-NEXT:    retq
395   %aext = sext i128 %a to i256
396   %bext = sext i128 %b to i256
397   %sub = sub i256 %aext, %bext
398   %abs = call i256 @llvm.abs.i256(i256 %sub, i1 false)
399   %trunc = trunc i256 %abs to i128
400   ret i128 %trunc
403 define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {
404 ; X86-LABEL: abd_ext_i128_undef:
405 ; X86:       # %bb.0:
406 ; X86-NEXT:    pushl %ebp
407 ; X86-NEXT:    pushl %ebx
408 ; X86-NEXT:    pushl %edi
409 ; X86-NEXT:    pushl %esi
410 ; X86-NEXT:    pushl %eax
411 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
412 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
413 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
414 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
415 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
416 ; X86-NEXT:    subl %edx, %eax
417 ; X86-NEXT:    movl %eax, (%esp) # 4-byte Spill
418 ; X86-NEXT:    sbbl %esi, %ebx
419 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebp
420 ; X86-NEXT:    sbbl %ecx, %ebp
421 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
422 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
423 ; X86-NEXT:    sbbl %edi, %eax
424 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
425 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
426 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
427 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edi
428 ; X86-NEXT:    cmovll (%esp), %edx # 4-byte Folded Reload
429 ; X86-NEXT:    cmovll %ebx, %esi
430 ; X86-NEXT:    cmovll %ebp, %ecx
431 ; X86-NEXT:    cmovll %eax, %edi
432 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
433 ; X86-NEXT:    movl %edi, 12(%eax)
434 ; X86-NEXT:    movl %ecx, 8(%eax)
435 ; X86-NEXT:    movl %esi, 4(%eax)
436 ; X86-NEXT:    movl %edx, (%eax)
437 ; X86-NEXT:    addl $4, %esp
438 ; X86-NEXT:    popl %esi
439 ; X86-NEXT:    popl %edi
440 ; X86-NEXT:    popl %ebx
441 ; X86-NEXT:    popl %ebp
442 ; X86-NEXT:    retl $4
444 ; X64-LABEL: abd_ext_i128_undef:
445 ; X64:       # %bb.0:
446 ; X64-NEXT:    movq %rdi, %rax
447 ; X64-NEXT:    subq %rdx, %rax
448 ; X64-NEXT:    movq %rsi, %r8
449 ; X64-NEXT:    sbbq %rcx, %r8
450 ; X64-NEXT:    subq %rdi, %rdx
451 ; X64-NEXT:    sbbq %rsi, %rcx
452 ; X64-NEXT:    cmovgeq %rdx, %rax
453 ; X64-NEXT:    cmovgeq %rcx, %r8
454 ; X64-NEXT:    movq %r8, %rdx
455 ; X64-NEXT:    retq
456   %aext = sext i128 %a to i256
457   %bext = sext i128 %b to i256
458   %sub = sub i256 %aext, %bext
459   %abs = call i256 @llvm.abs.i256(i256 %sub, i1 true)
460   %trunc = trunc i256 %abs to i128
461   ret i128 %trunc
465 ; sub(smax(a,b),smin(a,b)) -> abds(a,b)
468 define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind {
469 ; X86-LABEL: abd_minmax_i8:
470 ; X86:       # %bb.0:
471 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
472 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %ecx
473 ; X86-NEXT:    movl %ecx, %edx
474 ; X86-NEXT:    subl %eax, %edx
475 ; X86-NEXT:    subl %ecx, %eax
476 ; X86-NEXT:    cmovll %edx, %eax
477 ; X86-NEXT:    # kill: def $al killed $al killed $eax
478 ; X86-NEXT:    retl
480 ; X64-LABEL: abd_minmax_i8:
481 ; X64:       # %bb.0:
482 ; X64-NEXT:    movsbl %sil, %eax
483 ; X64-NEXT:    movsbl %dil, %ecx
484 ; X64-NEXT:    movl %ecx, %edx
485 ; X64-NEXT:    subl %eax, %edx
486 ; X64-NEXT:    subl %ecx, %eax
487 ; X64-NEXT:    cmovll %edx, %eax
488 ; X64-NEXT:    # kill: def $al killed $al killed $eax
489 ; X64-NEXT:    retq
490   %min = call i8 @llvm.smin.i8(i8 %a, i8 %b)
491   %max = call i8 @llvm.smax.i8(i8 %a, i8 %b)
492   %sub = sub i8 %max, %min
493   ret i8 %sub
496 define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind {
497 ; X86-LABEL: abd_minmax_i16:
498 ; X86:       # %bb.0:
499 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
500 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
501 ; X86-NEXT:    movl %ecx, %edx
502 ; X86-NEXT:    subl %eax, %edx
503 ; X86-NEXT:    subl %ecx, %eax
504 ; X86-NEXT:    cmovll %edx, %eax
505 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
506 ; X86-NEXT:    retl
508 ; X64-LABEL: abd_minmax_i16:
509 ; X64:       # %bb.0:
510 ; X64-NEXT:    movswl %si, %eax
511 ; X64-NEXT:    movswl %di, %ecx
512 ; X64-NEXT:    movl %ecx, %edx
513 ; X64-NEXT:    subl %eax, %edx
514 ; X64-NEXT:    subl %ecx, %eax
515 ; X64-NEXT:    cmovll %edx, %eax
516 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
517 ; X64-NEXT:    retq
518   %min = call i16 @llvm.smin.i16(i16 %a, i16 %b)
519   %max = call i16 @llvm.smax.i16(i16 %a, i16 %b)
520   %sub = sub i16 %max, %min
521   ret i16 %sub
524 define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind {
525 ; X86-LABEL: abd_minmax_i32:
526 ; X86:       # %bb.0:
527 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
528 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
529 ; X86-NEXT:    movl %ecx, %edx
530 ; X86-NEXT:    subl %eax, %edx
531 ; X86-NEXT:    subl %ecx, %eax
532 ; X86-NEXT:    cmovll %edx, %eax
533 ; X86-NEXT:    retl
535 ; X64-LABEL: abd_minmax_i32:
536 ; X64:       # %bb.0:
537 ; X64-NEXT:    movl %edi, %eax
538 ; X64-NEXT:    subl %esi, %eax
539 ; X64-NEXT:    subl %edi, %esi
540 ; X64-NEXT:    cmovgel %esi, %eax
541 ; X64-NEXT:    retq
542   %min = call i32 @llvm.smin.i32(i32 %a, i32 %b)
543   %max = call i32 @llvm.smax.i32(i32 %a, i32 %b)
544   %sub = sub i32 %max, %min
545   ret i32 %sub
548 define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind {
549 ; X86-LABEL: abd_minmax_i64:
550 ; X86:       # %bb.0:
551 ; X86-NEXT:    pushl %ebx
552 ; X86-NEXT:    pushl %edi
553 ; X86-NEXT:    pushl %esi
554 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
555 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
556 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
557 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
558 ; X86-NEXT:    movl %ecx, %edi
559 ; X86-NEXT:    subl %eax, %edi
560 ; X86-NEXT:    movl %esi, %ebx
561 ; X86-NEXT:    sbbl %edx, %ebx
562 ; X86-NEXT:    subl %ecx, %eax
563 ; X86-NEXT:    sbbl %esi, %edx
564 ; X86-NEXT:    cmovll %edi, %eax
565 ; X86-NEXT:    cmovll %ebx, %edx
566 ; X86-NEXT:    popl %esi
567 ; X86-NEXT:    popl %edi
568 ; X86-NEXT:    popl %ebx
569 ; X86-NEXT:    retl
571 ; X64-LABEL: abd_minmax_i64:
572 ; X64:       # %bb.0:
573 ; X64-NEXT:    movq %rdi, %rax
574 ; X64-NEXT:    subq %rsi, %rax
575 ; X64-NEXT:    subq %rdi, %rsi
576 ; X64-NEXT:    cmovgeq %rsi, %rax
577 ; X64-NEXT:    retq
578   %min = call i64 @llvm.smin.i64(i64 %a, i64 %b)
579   %max = call i64 @llvm.smax.i64(i64 %a, i64 %b)
580   %sub = sub i64 %max, %min
581   ret i64 %sub
584 define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind {
585 ; X86-LABEL: abd_minmax_i128:
586 ; X86:       # %bb.0:
587 ; X86-NEXT:    pushl %ebp
588 ; X86-NEXT:    pushl %ebx
589 ; X86-NEXT:    pushl %edi
590 ; X86-NEXT:    pushl %esi
591 ; X86-NEXT:    pushl %eax
592 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
593 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
594 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
595 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
596 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
597 ; X86-NEXT:    subl %edx, %eax
598 ; X86-NEXT:    movl %eax, (%esp) # 4-byte Spill
599 ; X86-NEXT:    sbbl %esi, %ebx
600 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebp
601 ; X86-NEXT:    sbbl %ecx, %ebp
602 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
603 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
604 ; X86-NEXT:    sbbl %edi, %eax
605 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
606 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
607 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
608 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edi
609 ; X86-NEXT:    cmovll (%esp), %edx # 4-byte Folded Reload
610 ; X86-NEXT:    cmovll %ebx, %esi
611 ; X86-NEXT:    cmovll %ebp, %ecx
612 ; X86-NEXT:    cmovll %eax, %edi
613 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
614 ; X86-NEXT:    movl %edi, 12(%eax)
615 ; X86-NEXT:    movl %ecx, 8(%eax)
616 ; X86-NEXT:    movl %esi, 4(%eax)
617 ; X86-NEXT:    movl %edx, (%eax)
618 ; X86-NEXT:    addl $4, %esp
619 ; X86-NEXT:    popl %esi
620 ; X86-NEXT:    popl %edi
621 ; X86-NEXT:    popl %ebx
622 ; X86-NEXT:    popl %ebp
623 ; X86-NEXT:    retl $4
625 ; X64-LABEL: abd_minmax_i128:
626 ; X64:       # %bb.0:
627 ; X64-NEXT:    movq %rdi, %rax
628 ; X64-NEXT:    subq %rdx, %rax
629 ; X64-NEXT:    movq %rsi, %r8
630 ; X64-NEXT:    sbbq %rcx, %r8
631 ; X64-NEXT:    subq %rdi, %rdx
632 ; X64-NEXT:    sbbq %rsi, %rcx
633 ; X64-NEXT:    cmovgeq %rdx, %rax
634 ; X64-NEXT:    cmovgeq %rcx, %r8
635 ; X64-NEXT:    movq %r8, %rdx
636 ; X64-NEXT:    retq
637   %min = call i128 @llvm.smin.i128(i128 %a, i128 %b)
638   %max = call i128 @llvm.smax.i128(i128 %a, i128 %b)
639   %sub = sub i128 %max, %min
640   ret i128 %sub
644 ; select(icmp(a,b),sub(a,b),sub(b,a)) -> abds(a,b)
647 define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind {
648 ; X86-LABEL: abd_cmp_i8:
649 ; X86:       # %bb.0:
650 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
651 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %ecx
652 ; X86-NEXT:    movl %ecx, %edx
653 ; X86-NEXT:    subl %eax, %edx
654 ; X86-NEXT:    subl %ecx, %eax
655 ; X86-NEXT:    cmovll %edx, %eax
656 ; X86-NEXT:    # kill: def $al killed $al killed $eax
657 ; X86-NEXT:    retl
659 ; X64-LABEL: abd_cmp_i8:
660 ; X64:       # %bb.0:
661 ; X64-NEXT:    movsbl %sil, %eax
662 ; X64-NEXT:    movsbl %dil, %ecx
663 ; X64-NEXT:    movl %ecx, %edx
664 ; X64-NEXT:    subl %eax, %edx
665 ; X64-NEXT:    subl %ecx, %eax
666 ; X64-NEXT:    cmovll %edx, %eax
667 ; X64-NEXT:    # kill: def $al killed $al killed $eax
668 ; X64-NEXT:    retq
669   %cmp = icmp sgt i8 %a, %b
670   %ab = sub i8 %a, %b
671   %ba = sub i8 %b, %a
672   %sel = select i1 %cmp, i8 %ab, i8 %ba
673   ret i8 %sel
676 define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind {
677 ; X86-LABEL: abd_cmp_i16:
678 ; X86:       # %bb.0:
679 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
680 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
681 ; X86-NEXT:    movl %ecx, %edx
682 ; X86-NEXT:    subl %eax, %edx
683 ; X86-NEXT:    subl %ecx, %eax
684 ; X86-NEXT:    cmovll %edx, %eax
685 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
686 ; X86-NEXT:    retl
688 ; X64-LABEL: abd_cmp_i16:
689 ; X64:       # %bb.0:
690 ; X64-NEXT:    movswl %si, %eax
691 ; X64-NEXT:    movswl %di, %ecx
692 ; X64-NEXT:    movl %ecx, %edx
693 ; X64-NEXT:    subl %eax, %edx
694 ; X64-NEXT:    subl %ecx, %eax
695 ; X64-NEXT:    cmovll %edx, %eax
696 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
697 ; X64-NEXT:    retq
698   %cmp = icmp sge i16 %a, %b
699   %ab = sub i16 %a, %b
700   %ba = sub i16 %b, %a
701   %sel = select i1 %cmp, i16 %ab, i16 %ba
702   ret i16 %sel
705 define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind {
706 ; X86-LABEL: abd_cmp_i32:
707 ; X86:       # %bb.0:
708 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
709 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
710 ; X86-NEXT:    movl %ecx, %edx
711 ; X86-NEXT:    subl %eax, %edx
712 ; X86-NEXT:    subl %ecx, %eax
713 ; X86-NEXT:    cmovll %edx, %eax
714 ; X86-NEXT:    retl
716 ; X64-LABEL: abd_cmp_i32:
717 ; X64:       # %bb.0:
718 ; X64-NEXT:    movl %edi, %eax
719 ; X64-NEXT:    subl %esi, %eax
720 ; X64-NEXT:    subl %edi, %esi
721 ; X64-NEXT:    cmovgel %esi, %eax
722 ; X64-NEXT:    retq
723   %cmp = icmp slt i32 %a, %b
724   %ab = sub i32 %a, %b
725   %ba = sub i32 %b, %a
726   %sel = select i1 %cmp, i32 %ba, i32 %ab
727   ret i32 %sel
730 define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind {
731 ; X86-LABEL: abd_cmp_i64:
732 ; X86:       # %bb.0:
733 ; X86-NEXT:    pushl %ebx
734 ; X86-NEXT:    pushl %edi
735 ; X86-NEXT:    pushl %esi
736 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
737 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
738 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
739 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
740 ; X86-NEXT:    movl %ecx, %edi
741 ; X86-NEXT:    subl %eax, %edi
742 ; X86-NEXT:    movl %esi, %ebx
743 ; X86-NEXT:    sbbl %edx, %ebx
744 ; X86-NEXT:    subl %ecx, %eax
745 ; X86-NEXT:    sbbl %esi, %edx
746 ; X86-NEXT:    cmovll %edi, %eax
747 ; X86-NEXT:    cmovll %ebx, %edx
748 ; X86-NEXT:    popl %esi
749 ; X86-NEXT:    popl %edi
750 ; X86-NEXT:    popl %ebx
751 ; X86-NEXT:    retl
753 ; X64-LABEL: abd_cmp_i64:
754 ; X64:       # %bb.0:
755 ; X64-NEXT:    movq %rdi, %rax
756 ; X64-NEXT:    subq %rsi, %rax
757 ; X64-NEXT:    subq %rdi, %rsi
758 ; X64-NEXT:    cmovgeq %rsi, %rax
759 ; X64-NEXT:    retq
760   %cmp = icmp sge i64 %a, %b
761   %ab = sub i64 %a, %b
762   %ba = sub i64 %b, %a
763   %sel = select i1 %cmp, i64 %ab, i64 %ba
764   ret i64 %sel
767 define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind {
768 ; X86-LABEL: abd_cmp_i128:
769 ; X86:       # %bb.0:
770 ; X86-NEXT:    pushl %ebp
771 ; X86-NEXT:    pushl %ebx
772 ; X86-NEXT:    pushl %edi
773 ; X86-NEXT:    pushl %esi
774 ; X86-NEXT:    pushl %eax
775 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
776 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
777 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
778 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
779 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
780 ; X86-NEXT:    subl %edx, %eax
781 ; X86-NEXT:    movl %eax, (%esp) # 4-byte Spill
782 ; X86-NEXT:    sbbl %esi, %ebx
783 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebp
784 ; X86-NEXT:    sbbl %ecx, %ebp
785 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
786 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
787 ; X86-NEXT:    sbbl %edi, %eax
788 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
789 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
790 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
791 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edi
792 ; X86-NEXT:    cmovll (%esp), %edx # 4-byte Folded Reload
793 ; X86-NEXT:    cmovll %ebx, %esi
794 ; X86-NEXT:    cmovll %ebp, %ecx
795 ; X86-NEXT:    cmovll %eax, %edi
796 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
797 ; X86-NEXT:    movl %edi, 12(%eax)
798 ; X86-NEXT:    movl %ecx, 8(%eax)
799 ; X86-NEXT:    movl %esi, 4(%eax)
800 ; X86-NEXT:    movl %edx, (%eax)
801 ; X86-NEXT:    addl $4, %esp
802 ; X86-NEXT:    popl %esi
803 ; X86-NEXT:    popl %edi
804 ; X86-NEXT:    popl %ebx
805 ; X86-NEXT:    popl %ebp
806 ; X86-NEXT:    retl $4
808 ; X64-LABEL: abd_cmp_i128:
809 ; X64:       # %bb.0:
810 ; X64-NEXT:    movq %rdi, %rax
811 ; X64-NEXT:    subq %rdx, %rax
812 ; X64-NEXT:    movq %rsi, %r8
813 ; X64-NEXT:    sbbq %rcx, %r8
814 ; X64-NEXT:    subq %rdi, %rdx
815 ; X64-NEXT:    sbbq %rsi, %rcx
816 ; X64-NEXT:    cmovgeq %rdx, %rax
817 ; X64-NEXT:    cmovgeq %rcx, %r8
818 ; X64-NEXT:    movq %r8, %rdx
819 ; X64-NEXT:    retq
820   %cmp = icmp sge i128 %a, %b
821   %ab = sub i128 %a, %b
822   %ba = sub i128 %b, %a
823   %sel = select i1 %cmp, i128 %ab, i128 %ba
824   ret i128 %sel
828 ; abs(sub_nsw(x, y)) -> abds(a,b)
831 define i8 @abd_subnsw_i8(i8 %a, i8 %b) nounwind {
832 ; X86-LABEL: abd_subnsw_i8:
833 ; X86:       # %bb.0:
834 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
835 ; X86-NEXT:    subb {{[0-9]+}}(%esp), %al
836 ; X86-NEXT:    movl %eax, %ecx
837 ; X86-NEXT:    sarb $7, %cl
838 ; X86-NEXT:    xorb %cl, %al
839 ; X86-NEXT:    subb %cl, %al
840 ; X86-NEXT:    retl
842 ; X64-LABEL: abd_subnsw_i8:
843 ; X64:       # %bb.0:
844 ; X64-NEXT:    movl %edi, %eax
845 ; X64-NEXT:    subb %sil, %al
846 ; X64-NEXT:    movl %eax, %ecx
847 ; X64-NEXT:    sarb $7, %cl
848 ; X64-NEXT:    xorb %cl, %al
849 ; X64-NEXT:    subb %cl, %al
850 ; X64-NEXT:    # kill: def $al killed $al killed $eax
851 ; X64-NEXT:    retq
852   %sub = sub nsw i8 %a, %b
853   %abs = call i8 @llvm.abs.i8(i8 %sub, i1 false)
854   ret i8 %abs
857 define i8 @abd_subnsw_i8_undef(i8 %a, i8 %b) nounwind {
858 ; X86-LABEL: abd_subnsw_i8_undef:
859 ; X86:       # %bb.0:
860 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
861 ; X86-NEXT:    subb {{[0-9]+}}(%esp), %al
862 ; X86-NEXT:    movl %eax, %ecx
863 ; X86-NEXT:    sarb $7, %cl
864 ; X86-NEXT:    xorb %cl, %al
865 ; X86-NEXT:    subb %cl, %al
866 ; X86-NEXT:    retl
868 ; X64-LABEL: abd_subnsw_i8_undef:
869 ; X64:       # %bb.0:
870 ; X64-NEXT:    movl %edi, %eax
871 ; X64-NEXT:    subb %sil, %al
872 ; X64-NEXT:    movl %eax, %ecx
873 ; X64-NEXT:    sarb $7, %cl
874 ; X64-NEXT:    xorb %cl, %al
875 ; X64-NEXT:    subb %cl, %al
876 ; X64-NEXT:    # kill: def $al killed $al killed $eax
877 ; X64-NEXT:    retq
878   %sub = sub nsw i8 %a, %b
879   %abs = call i8 @llvm.abs.i8(i8 %sub, i1 true)
880   ret i8 %abs
883 define i16 @abd_subnsw_i16(i16 %a, i16 %b) nounwind {
884 ; X86-LABEL: abd_subnsw_i16:
885 ; X86:       # %bb.0:
886 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
887 ; X86-NEXT:    subw {{[0-9]+}}(%esp), %cx
888 ; X86-NEXT:    movl %ecx, %eax
889 ; X86-NEXT:    negw %ax
890 ; X86-NEXT:    cmovsw %cx, %ax
891 ; X86-NEXT:    retl
893 ; X64-LABEL: abd_subnsw_i16:
894 ; X64:       # %bb.0:
895 ; X64-NEXT:    subl %esi, %edi
896 ; X64-NEXT:    movl %edi, %eax
897 ; X64-NEXT:    negw %ax
898 ; X64-NEXT:    cmovsw %di, %ax
899 ; X64-NEXT:    retq
900   %sub = sub nsw i16 %a, %b
901   %abs = call i16 @llvm.abs.i16(i16 %sub, i1 false)
902   ret i16 %abs
905 define i16 @abd_subnsw_i16_undef(i16 %a, i16 %b) nounwind {
906 ; X86-LABEL: abd_subnsw_i16_undef:
907 ; X86:       # %bb.0:
908 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
909 ; X86-NEXT:    subw {{[0-9]+}}(%esp), %cx
910 ; X86-NEXT:    movl %ecx, %eax
911 ; X86-NEXT:    negw %ax
912 ; X86-NEXT:    cmovsw %cx, %ax
913 ; X86-NEXT:    retl
915 ; X64-LABEL: abd_subnsw_i16_undef:
916 ; X64:       # %bb.0:
917 ; X64-NEXT:    subl %esi, %edi
918 ; X64-NEXT:    movl %edi, %eax
919 ; X64-NEXT:    negw %ax
920 ; X64-NEXT:    cmovsw %di, %ax
921 ; X64-NEXT:    retq
922   %sub = sub nsw i16 %a, %b
923   %abs = call i16 @llvm.abs.i16(i16 %sub, i1 true)
924   ret i16 %abs
927 define i32 @abd_subnsw_i32(i32 %a, i32 %b) nounwind {
928 ; X86-LABEL: abd_subnsw_i32:
929 ; X86:       # %bb.0:
930 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
931 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
932 ; X86-NEXT:    movl %ecx, %edx
933 ; X86-NEXT:    subl %eax, %edx
934 ; X86-NEXT:    subl %ecx, %eax
935 ; X86-NEXT:    cmovll %edx, %eax
936 ; X86-NEXT:    retl
938 ; X64-LABEL: abd_subnsw_i32:
939 ; X64:       # %bb.0:
940 ; X64-NEXT:    movl %edi, %eax
941 ; X64-NEXT:    subl %esi, %eax
942 ; X64-NEXT:    subl %edi, %esi
943 ; X64-NEXT:    cmovgel %esi, %eax
944 ; X64-NEXT:    retq
945   %sub = sub nsw i32 %a, %b
946   %abs = call i32 @llvm.abs.i32(i32 %sub, i1 false)
947   ret i32 %abs
950 define i32 @abd_subnsw_i32_undef(i32 %a, i32 %b) nounwind {
951 ; X86-LABEL: abd_subnsw_i32_undef:
952 ; X86:       # %bb.0:
953 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
954 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
955 ; X86-NEXT:    movl %ecx, %edx
956 ; X86-NEXT:    subl %eax, %edx
957 ; X86-NEXT:    subl %ecx, %eax
958 ; X86-NEXT:    cmovll %edx, %eax
959 ; X86-NEXT:    retl
961 ; X64-LABEL: abd_subnsw_i32_undef:
962 ; X64:       # %bb.0:
963 ; X64-NEXT:    movl %edi, %eax
964 ; X64-NEXT:    subl %esi, %eax
965 ; X64-NEXT:    subl %edi, %esi
966 ; X64-NEXT:    cmovgel %esi, %eax
967 ; X64-NEXT:    retq
968   %sub = sub nsw i32 %a, %b
969   %abs = call i32 @llvm.abs.i32(i32 %sub, i1 true)
970   ret i32 %abs
973 define i64 @abd_subnsw_i64(i64 %a, i64 %b) nounwind {
974 ; X86-LABEL: abd_subnsw_i64:
975 ; X86:       # %bb.0:
976 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
977 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
978 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
979 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
980 ; X86-NEXT:    movl %edx, %ecx
981 ; X86-NEXT:    sarl $31, %ecx
982 ; X86-NEXT:    xorl %ecx, %edx
983 ; X86-NEXT:    xorl %ecx, %eax
984 ; X86-NEXT:    subl %ecx, %eax
985 ; X86-NEXT:    sbbl %ecx, %edx
986 ; X86-NEXT:    retl
988 ; X64-LABEL: abd_subnsw_i64:
989 ; X64:       # %bb.0:
990 ; X64-NEXT:    movq %rdi, %rax
991 ; X64-NEXT:    subq %rsi, %rax
992 ; X64-NEXT:    subq %rdi, %rsi
993 ; X64-NEXT:    cmovgeq %rsi, %rax
994 ; X64-NEXT:    retq
995   %sub = sub nsw i64 %a, %b
996   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
997   ret i64 %abs
1000 define i64 @abd_subnsw_i64_undef(i64 %a, i64 %b) nounwind {
1001 ; X86-LABEL: abd_subnsw_i64_undef:
1002 ; X86:       # %bb.0:
1003 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1004 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1005 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
1006 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
1007 ; X86-NEXT:    movl %edx, %ecx
1008 ; X86-NEXT:    sarl $31, %ecx
1009 ; X86-NEXT:    xorl %ecx, %edx
1010 ; X86-NEXT:    xorl %ecx, %eax
1011 ; X86-NEXT:    subl %ecx, %eax
1012 ; X86-NEXT:    sbbl %ecx, %edx
1013 ; X86-NEXT:    retl
1015 ; X64-LABEL: abd_subnsw_i64_undef:
1016 ; X64:       # %bb.0:
1017 ; X64-NEXT:    movq %rdi, %rax
1018 ; X64-NEXT:    subq %rsi, %rax
1019 ; X64-NEXT:    subq %rdi, %rsi
1020 ; X64-NEXT:    cmovgeq %rsi, %rax
1021 ; X64-NEXT:    retq
1022   %sub = sub nsw i64 %a, %b
1023   %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
1024   ret i64 %abs
1027 define i128 @abd_subnsw_i128(i128 %a, i128 %b) nounwind {
1028 ; X86-LABEL: abd_subnsw_i128:
1029 ; X86:       # %bb.0:
1030 ; X86-NEXT:    pushl %ebx
1031 ; X86-NEXT:    pushl %edi
1032 ; X86-NEXT:    pushl %esi
1033 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1034 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1035 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1036 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
1037 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1038 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edi
1039 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
1040 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
1041 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
1042 ; X86-NEXT:    movl %ecx, %ebx
1043 ; X86-NEXT:    sarl $31, %ebx
1044 ; X86-NEXT:    xorl %ebx, %ecx
1045 ; X86-NEXT:    xorl %ebx, %edx
1046 ; X86-NEXT:    xorl %ebx, %esi
1047 ; X86-NEXT:    xorl %ebx, %edi
1048 ; X86-NEXT:    subl %ebx, %edi
1049 ; X86-NEXT:    sbbl %ebx, %esi
1050 ; X86-NEXT:    sbbl %ebx, %edx
1051 ; X86-NEXT:    sbbl %ebx, %ecx
1052 ; X86-NEXT:    movl %edi, (%eax)
1053 ; X86-NEXT:    movl %esi, 4(%eax)
1054 ; X86-NEXT:    movl %edx, 8(%eax)
1055 ; X86-NEXT:    movl %ecx, 12(%eax)
1056 ; X86-NEXT:    popl %esi
1057 ; X86-NEXT:    popl %edi
1058 ; X86-NEXT:    popl %ebx
1059 ; X86-NEXT:    retl $4
1061 ; X64-LABEL: abd_subnsw_i128:
1062 ; X64:       # %bb.0:
1063 ; X64-NEXT:    movq %rdi, %rax
1064 ; X64-NEXT:    subq %rdx, %rax
1065 ; X64-NEXT:    sbbq %rcx, %rsi
1066 ; X64-NEXT:    movq %rsi, %rcx
1067 ; X64-NEXT:    sarq $63, %rcx
1068 ; X64-NEXT:    xorq %rcx, %rsi
1069 ; X64-NEXT:    xorq %rcx, %rax
1070 ; X64-NEXT:    subq %rcx, %rax
1071 ; X64-NEXT:    sbbq %rcx, %rsi
1072 ; X64-NEXT:    movq %rsi, %rdx
1073 ; X64-NEXT:    retq
1074   %sub = sub nsw i128 %a, %b
1075   %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)
1076   ret i128 %abs
1079 define i128 @abd_subnsw_i128_undef(i128 %a, i128 %b) nounwind {
1080 ; X86-LABEL: abd_subnsw_i128_undef:
1081 ; X86:       # %bb.0:
1082 ; X86-NEXT:    pushl %ebx
1083 ; X86-NEXT:    pushl %edi
1084 ; X86-NEXT:    pushl %esi
1085 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1086 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1087 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1088 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
1089 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1090 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edi
1091 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
1092 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
1093 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
1094 ; X86-NEXT:    movl %ecx, %ebx
1095 ; X86-NEXT:    sarl $31, %ebx
1096 ; X86-NEXT:    xorl %ebx, %ecx
1097 ; X86-NEXT:    xorl %ebx, %edx
1098 ; X86-NEXT:    xorl %ebx, %esi
1099 ; X86-NEXT:    xorl %ebx, %edi
1100 ; X86-NEXT:    subl %ebx, %edi
1101 ; X86-NEXT:    sbbl %ebx, %esi
1102 ; X86-NEXT:    sbbl %ebx, %edx
1103 ; X86-NEXT:    sbbl %ebx, %ecx
1104 ; X86-NEXT:    movl %edi, (%eax)
1105 ; X86-NEXT:    movl %esi, 4(%eax)
1106 ; X86-NEXT:    movl %edx, 8(%eax)
1107 ; X86-NEXT:    movl %ecx, 12(%eax)
1108 ; X86-NEXT:    popl %esi
1109 ; X86-NEXT:    popl %edi
1110 ; X86-NEXT:    popl %ebx
1111 ; X86-NEXT:    retl $4
1113 ; X64-LABEL: abd_subnsw_i128_undef:
1114 ; X64:       # %bb.0:
1115 ; X64-NEXT:    movq %rdi, %rax
1116 ; X64-NEXT:    subq %rdx, %rax
1117 ; X64-NEXT:    sbbq %rcx, %rsi
1118 ; X64-NEXT:    movq %rsi, %rcx
1119 ; X64-NEXT:    sarq $63, %rcx
1120 ; X64-NEXT:    xorq %rcx, %rsi
1121 ; X64-NEXT:    xorq %rcx, %rax
1122 ; X64-NEXT:    subq %rcx, %rax
1123 ; X64-NEXT:    sbbq %rcx, %rsi
1124 ; X64-NEXT:    movq %rsi, %rdx
1125 ; X64-NEXT:    retq
1126   %sub = sub nsw i128 %a, %b
1127   %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)
1128   ret i128 %abs
1132 ; negative tests
1135 define i32 @abd_sub_i32(i32 %a, i32 %b) nounwind {
1136 ; X86-LABEL: abd_sub_i32:
1137 ; X86:       # %bb.0:
1138 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1139 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %ecx
1140 ; X86-NEXT:    movl %ecx, %eax
1141 ; X86-NEXT:    negl %eax
1142 ; X86-NEXT:    cmovsl %ecx, %eax
1143 ; X86-NEXT:    retl
1145 ; X64-LABEL: abd_sub_i32:
1146 ; X64:       # %bb.0:
1147 ; X64-NEXT:    subl %esi, %edi
1148 ; X64-NEXT:    movl %edi, %eax
1149 ; X64-NEXT:    negl %eax
1150 ; X64-NEXT:    cmovsl %edi, %eax
1151 ; X64-NEXT:    retq
1152   %sub = sub i32 %a, %b
1153   %abs = call i32 @llvm.abs.i32(i32 %sub, i1 false)
1154   ret i32 %abs
1158 ; sub(select(icmp(a,b),a,b),select(icmp(a,b),b,a)) -> abds(a,b)
1161 define i8 @abd_select_i8(i8 %a, i8 %b) nounwind {
1162 ; X86-LABEL: abd_select_i8:
1163 ; X86:       # %bb.0:
1164 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
1165 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %ecx
1166 ; X86-NEXT:    movl %ecx, %edx
1167 ; X86-NEXT:    subl %eax, %edx
1168 ; X86-NEXT:    subl %ecx, %eax
1169 ; X86-NEXT:    cmovll %edx, %eax
1170 ; X86-NEXT:    # kill: def $al killed $al killed $eax
1171 ; X86-NEXT:    retl
1173 ; X64-LABEL: abd_select_i8:
1174 ; X64:       # %bb.0:
1175 ; X64-NEXT:    movsbl %sil, %eax
1176 ; X64-NEXT:    movsbl %dil, %ecx
1177 ; X64-NEXT:    movl %ecx, %edx
1178 ; X64-NEXT:    subl %eax, %edx
1179 ; X64-NEXT:    subl %ecx, %eax
1180 ; X64-NEXT:    cmovll %edx, %eax
1181 ; X64-NEXT:    # kill: def $al killed $al killed $eax
1182 ; X64-NEXT:    retq
1183   %cmp = icmp slt i8 %a, %b
1184   %ab = select i1 %cmp, i8 %a, i8 %b
1185   %ba = select i1 %cmp, i8 %b, i8 %a
1186   %sub = sub i8 %ba, %ab
1187   ret i8 %sub
1190 define i16 @abd_select_i16(i16 %a, i16 %b) nounwind {
1191 ; X86-LABEL: abd_select_i16:
1192 ; X86:       # %bb.0:
1193 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %eax
1194 ; X86-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
1195 ; X86-NEXT:    movl %ecx, %edx
1196 ; X86-NEXT:    subl %eax, %edx
1197 ; X86-NEXT:    subl %ecx, %eax
1198 ; X86-NEXT:    cmovll %edx, %eax
1199 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1200 ; X86-NEXT:    retl
1202 ; X64-LABEL: abd_select_i16:
1203 ; X64:       # %bb.0:
1204 ; X64-NEXT:    movswl %si, %eax
1205 ; X64-NEXT:    movswl %di, %ecx
1206 ; X64-NEXT:    movl %ecx, %edx
1207 ; X64-NEXT:    subl %eax, %edx
1208 ; X64-NEXT:    subl %ecx, %eax
1209 ; X64-NEXT:    cmovll %edx, %eax
1210 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1211 ; X64-NEXT:    retq
1212   %cmp = icmp sle i16 %a, %b
1213   %ab = select i1 %cmp, i16 %a, i16 %b
1214   %ba = select i1 %cmp, i16 %b, i16 %a
1215   %sub = sub i16 %ba, %ab
1216   ret i16 %sub
1219 define i32 @abd_select_i32(i32 %a, i32 %b) nounwind {
1220 ; X86-LABEL: abd_select_i32:
1221 ; X86:       # %bb.0:
1222 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1223 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1224 ; X86-NEXT:    movl %ecx, %edx
1225 ; X86-NEXT:    subl %eax, %edx
1226 ; X86-NEXT:    subl %ecx, %eax
1227 ; X86-NEXT:    cmovll %edx, %eax
1228 ; X86-NEXT:    retl
1230 ; X64-LABEL: abd_select_i32:
1231 ; X64:       # %bb.0:
1232 ; X64-NEXT:    movl %edi, %eax
1233 ; X64-NEXT:    subl %esi, %eax
1234 ; X64-NEXT:    subl %edi, %esi
1235 ; X64-NEXT:    cmovgel %esi, %eax
1236 ; X64-NEXT:    retq
1237   %cmp = icmp sgt i32 %a, %b
1238   %ab = select i1 %cmp, i32 %a, i32 %b
1239   %ba = select i1 %cmp, i32 %b, i32 %a
1240   %sub = sub i32 %ab, %ba
1241   ret i32 %sub
1244 define i64 @abd_select_i64(i64 %a, i64 %b) nounwind {
1245 ; X86-LABEL: abd_select_i64:
1246 ; X86:       # %bb.0:
1247 ; X86-NEXT:    pushl %ebx
1248 ; X86-NEXT:    pushl %edi
1249 ; X86-NEXT:    pushl %esi
1250 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1251 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1252 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1253 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1254 ; X86-NEXT:    movl %ecx, %edi
1255 ; X86-NEXT:    subl %eax, %edi
1256 ; X86-NEXT:    movl %esi, %ebx
1257 ; X86-NEXT:    sbbl %edx, %ebx
1258 ; X86-NEXT:    subl %ecx, %eax
1259 ; X86-NEXT:    sbbl %esi, %edx
1260 ; X86-NEXT:    cmovll %edi, %eax
1261 ; X86-NEXT:    cmovll %ebx, %edx
1262 ; X86-NEXT:    popl %esi
1263 ; X86-NEXT:    popl %edi
1264 ; X86-NEXT:    popl %ebx
1265 ; X86-NEXT:    retl
1267 ; X64-LABEL: abd_select_i64:
1268 ; X64:       # %bb.0:
1269 ; X64-NEXT:    movq %rdi, %rax
1270 ; X64-NEXT:    subq %rsi, %rax
1271 ; X64-NEXT:    subq %rdi, %rsi
1272 ; X64-NEXT:    cmovgeq %rsi, %rax
1273 ; X64-NEXT:    retq
1274   %cmp = icmp sge i64 %a, %b
1275   %ab = select i1 %cmp, i64 %a, i64 %b
1276   %ba = select i1 %cmp, i64 %b, i64 %a
1277   %sub = sub i64 %ab, %ba
1278   ret i64 %sub
1281 define i128 @abd_select_i128(i128 %a, i128 %b) nounwind {
1282 ; X86-LABEL: abd_select_i128:
1283 ; X86:       # %bb.0:
1284 ; X86-NEXT:    pushl %ebp
1285 ; X86-NEXT:    pushl %ebx
1286 ; X86-NEXT:    pushl %edi
1287 ; X86-NEXT:    pushl %esi
1288 ; X86-NEXT:    pushl %eax
1289 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
1290 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1291 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1292 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1293 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
1294 ; X86-NEXT:    subl %edx, %eax
1295 ; X86-NEXT:    movl %eax, (%esp) # 4-byte Spill
1296 ; X86-NEXT:    sbbl %esi, %ebx
1297 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebp
1298 ; X86-NEXT:    sbbl %ecx, %ebp
1299 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
1300 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1301 ; X86-NEXT:    sbbl %edi, %eax
1302 ; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
1303 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
1304 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
1305 ; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edi
1306 ; X86-NEXT:    cmovll (%esp), %edx # 4-byte Folded Reload
1307 ; X86-NEXT:    cmovll %ebx, %esi
1308 ; X86-NEXT:    cmovll %ebp, %ecx
1309 ; X86-NEXT:    cmovll %eax, %edi
1310 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
1311 ; X86-NEXT:    movl %edi, 12(%eax)
1312 ; X86-NEXT:    movl %ecx, 8(%eax)
1313 ; X86-NEXT:    movl %esi, 4(%eax)
1314 ; X86-NEXT:    movl %edx, (%eax)
1315 ; X86-NEXT:    addl $4, %esp
1316 ; X86-NEXT:    popl %esi
1317 ; X86-NEXT:    popl %edi
1318 ; X86-NEXT:    popl %ebx
1319 ; X86-NEXT:    popl %ebp
1320 ; X86-NEXT:    retl $4
1322 ; X64-LABEL: abd_select_i128:
1323 ; X64:       # %bb.0:
1324 ; X64-NEXT:    movq %rdi, %rax
1325 ; X64-NEXT:    subq %rdx, %rax
1326 ; X64-NEXT:    movq %rsi, %r8
1327 ; X64-NEXT:    sbbq %rcx, %r8
1328 ; X64-NEXT:    subq %rdi, %rdx
1329 ; X64-NEXT:    sbbq %rsi, %rcx
1330 ; X64-NEXT:    cmovgeq %rdx, %rax
1331 ; X64-NEXT:    cmovgeq %rcx, %r8
1332 ; X64-NEXT:    movq %r8, %rdx
1333 ; X64-NEXT:    retq
1334   %cmp = icmp slt i128 %a, %b
1335   %ab = select i1 %cmp, i128 %a, i128 %b
1336   %ba = select i1 %cmp, i128 %b, i128 %a
1337   %sub = sub i128 %ba, %ab
1338   ret i128 %sub
1341 declare i8 @llvm.abs.i8(i8, i1)
1342 declare i16 @llvm.abs.i16(i16, i1)
1343 declare i32 @llvm.abs.i32(i32, i1)
1344 declare i64 @llvm.abs.i64(i64, i1)
1345 declare i128 @llvm.abs.i128(i128, i1)
1347 declare i8 @llvm.smax.i8(i8, i8)
1348 declare i16 @llvm.smax.i16(i16, i16)
1349 declare i32 @llvm.smax.i32(i32, i32)
1350 declare i64 @llvm.smax.i64(i64, i64)
1352 declare i8 @llvm.smin.i8(i8, i8)
1353 declare i16 @llvm.smin.i16(i16, i16)
1354 declare i32 @llvm.smin.i32(i32, i32)
1355 declare i64 @llvm.smin.i64(i64, i64)