xref: /llvm-project/llvm/test/CodeGen/X86/abds.ll (revision 854ded9b24ea41ae10e884294b19bf3f80ca49f6)
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
4
5;
6; trunc(abs(sub(sext(a),sext(b)))) -> abds(a,b)
7;
8
9define 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
20;
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
37}
38
39define 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
50;
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
66}
67
68define 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
79;
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
96}
97
98define 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
109;
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
126}
127
128define 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
139;
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
155}
156
157define 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
168;
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
185}
186
187define 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
197;
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
211}
212
213define 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
223;
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
238}
239
240define 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
250;
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
264}
265
266define 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
288;
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
302}
303
304define 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
326;
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
340}
341
342define 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
382;
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
401}
402
403define 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
443;
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
462}
463
464;
465; sub(smax(a,b),smin(a,b)) -> abds(a,b)
466;
467
468define 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
479;
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
494}
495
496define 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
507;
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
522}
523
524define 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
534;
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
546}
547
548define 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
570;
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
582}
583
584define 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
624;
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
641}
642
643;
644; select(icmp(a,b),sub(a,b),sub(b,a)) -> abds(a,b)
645;
646
647define 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
658;
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
674}
675
676define 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
687;
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
703}
704
705define 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
715;
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
728}
729
730define 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
752;
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
765}
766
767define 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
807;
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
825}
826
827;
828; abs(sub_nsw(x, y)) -> abds(a,b)
829;
830
831define 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
841;
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
855}
856
857define 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
867;
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
881}
882
883define 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
892;
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
903}
904
905define 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
914;
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
925}
926
927define 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
937;
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
948}
949
950define 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
960;
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
971}
972
973define 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
987;
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
998}
999
1000define 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
1014;
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
1025}
1026
1027define 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
1060;
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
1077}
1078
1079define 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
1112;
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
1129}
1130
1131;
1132; negative tests
1133;
1134
1135define 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
1144;
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
1155}
1156
1157;
1158; sub(select(icmp(a,b),a,b),select(icmp(a,b),b,a)) -> abds(a,b)
1159;
1160
1161define 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
1172;
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
1188}
1189
1190define 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
1201;
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
1217}
1218
1219define 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
1229;
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
1242}
1243
1244define 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
1266;
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
1279}
1280
1281define 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
1321;
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
1339}
1340
1341declare i8 @llvm.abs.i8(i8, i1)
1342declare i16 @llvm.abs.i16(i16, i1)
1343declare i32 @llvm.abs.i32(i32, i1)
1344declare i64 @llvm.abs.i64(i64, i1)
1345declare i128 @llvm.abs.i128(i128, i1)
1346
1347declare i8 @llvm.smax.i8(i8, i8)
1348declare i16 @llvm.smax.i16(i16, i16)
1349declare i32 @llvm.smax.i32(i32, i32)
1350declare i64 @llvm.smax.i64(i64, i64)
1351
1352declare i8 @llvm.smin.i8(i8, i8)
1353declare i16 @llvm.smin.i16(i16, i16)
1354declare i32 @llvm.smin.i32(i32, i32)
1355declare i64 @llvm.smin.i64(i64, i64)
1356