xref: /llvm-project/llvm/test/CodeGen/X86/abdu.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(zext(a),zext(b)))) -> abdu(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:    movzbl {{[0-9]+}}(%esp), %eax
13; X86-NEXT:    movzbl {{[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:    cmovbl %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:    movzbl %sil, %eax
24; X64-NEXT:    movzbl %dil, %ecx
25; X64-NEXT:    movl %ecx, %edx
26; X64-NEXT:    subl %eax, %edx
27; X64-NEXT:    subl %ecx, %eax
28; X64-NEXT:    cmovbl %edx, %eax
29; X64-NEXT:    # kill: def $al killed $al killed $eax
30; X64-NEXT:    retq
31  %aext = zext i8 %a to i64
32  %bext = zext i8 %b to i64
33  %sub = sub i64 %aext, %bext
34  %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
35  %trunc = trunc i64 %abs to i8
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:    movzwl {{[0-9]+}}(%esp), %eax
43; X86-NEXT:    movzbl {{[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:    cmovbl %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:    movzbl %dil, %ecx
54; X64-NEXT:    subl %esi, %edi
55; X64-NEXT:    movzwl %si, %eax
56; X64-NEXT:    subl %ecx, %eax
57; X64-NEXT:    cmovbl %edi, %eax
58; X64-NEXT:    # kill: def $al killed $al killed $eax
59; X64-NEXT:    retq
60  %aext = zext i8 %a to i64
61  %bext = zext 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:    movzbl {{[0-9]+}}(%esp), %eax
72; X86-NEXT:    movzbl {{[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:    cmovbl %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:    movzbl %sil, %eax
83; X64-NEXT:    movzbl %dil, %ecx
84; X64-NEXT:    movl %ecx, %edx
85; X64-NEXT:    subl %eax, %edx
86; X64-NEXT:    subl %ecx, %eax
87; X64-NEXT:    cmovbl %edx, %eax
88; X64-NEXT:    # kill: def $al killed $al killed $eax
89; X64-NEXT:    retq
90  %aext = zext i8 %a to i64
91  %bext = zext 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:    movzwl {{[0-9]+}}(%esp), %eax
102; X86-NEXT:    movzwl {{[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:    cmovbl %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:    movzwl %si, %eax
113; X64-NEXT:    movzwl %di, %ecx
114; X64-NEXT:    movl %ecx, %edx
115; X64-NEXT:    subl %eax, %edx
116; X64-NEXT:    subl %ecx, %eax
117; X64-NEXT:    cmovbl %edx, %eax
118; X64-NEXT:    # kill: def $ax killed $ax killed $eax
119; X64-NEXT:    retq
120  %aext = zext i16 %a to i64
121  %bext = zext 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:    movzwl {{[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:    cmovbl %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:    movzwl %di, %ecx
143; X64-NEXT:    movl %edi, %eax
144; X64-NEXT:    subl %esi, %eax
145; X64-NEXT:    subl %ecx, %esi
146; X64-NEXT:    cmovael %esi, %eax
147; X64-NEXT:    # kill: def $ax killed $ax killed $eax
148; X64-NEXT:    retq
149  %aext = zext i16 %a to i64
150  %bext = zext 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:    movzwl {{[0-9]+}}(%esp), %eax
161; X86-NEXT:    movzwl {{[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:    cmovbl %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:    movzwl %si, %eax
172; X64-NEXT:    movzwl %di, %ecx
173; X64-NEXT:    movl %ecx, %edx
174; X64-NEXT:    subl %eax, %edx
175; X64-NEXT:    subl %ecx, %eax
176; X64-NEXT:    cmovbl %edx, %eax
177; X64-NEXT:    # kill: def $ax killed $ax killed $eax
178; X64-NEXT:    retq
179  %aext = zext i16 %a to i64
180  %bext = zext 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:    cmovbl %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:    cmovael %esi, %eax
204; X64-NEXT:    retq
205  %aext = zext i32 %a to i64
206  %bext = zext 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:    movzwl {{[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:    cmovbl %edx, %eax
222; X86-NEXT:    retl
223;
224; X64-LABEL: abd_ext_i32_i16:
225; X64:       # %bb.0:
226; X64-NEXT:    movzwl %si, %eax
227; X64-NEXT:    movl %edi, %ecx
228; X64-NEXT:    subl %eax, %ecx
229; X64-NEXT:    subl %edi, %eax
230; X64-NEXT:    cmovbl %ecx, %eax
231; X64-NEXT:    retq
232  %aext = zext i32 %a to i64
233  %bext = zext 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:    cmovbl %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:    cmovael %esi, %eax
257; X64-NEXT:    retq
258  %aext = zext i32 %a to i64
259  %bext = zext 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:    movl {{[0-9]+}}(%esp), %eax
270; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
271; X86-NEXT:    xorl %ecx, %ecx
272; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
273; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
274; X86-NEXT:    sbbl %ecx, %ecx
275; X86-NEXT:    xorl %ecx, %edx
276; X86-NEXT:    xorl %ecx, %eax
277; X86-NEXT:    subl %ecx, %eax
278; X86-NEXT:    sbbl %ecx, %edx
279; X86-NEXT:    retl
280;
281; X64-LABEL: abd_ext_i64:
282; X64:       # %bb.0:
283; X64-NEXT:    movq %rdi, %rax
284; X64-NEXT:    subq %rsi, %rax
285; X64-NEXT:    subq %rdi, %rsi
286; X64-NEXT:    cmovaeq %rsi, %rax
287; X64-NEXT:    retq
288  %aext = zext i64 %a to i128
289  %bext = zext i64 %b to i128
290  %sub = sub i128 %aext, %bext
291  %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)
292  %trunc = trunc i128 %abs to i64
293  ret i64 %trunc
294}
295
296define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind {
297; X86-LABEL: abd_ext_i64_undef:
298; X86:       # %bb.0:
299; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
300; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
301; X86-NEXT:    xorl %ecx, %ecx
302; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
303; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
304; X86-NEXT:    sbbl %ecx, %ecx
305; X86-NEXT:    xorl %ecx, %edx
306; X86-NEXT:    xorl %ecx, %eax
307; X86-NEXT:    subl %ecx, %eax
308; X86-NEXT:    sbbl %ecx, %edx
309; X86-NEXT:    retl
310;
311; X64-LABEL: abd_ext_i64_undef:
312; X64:       # %bb.0:
313; X64-NEXT:    movq %rdi, %rax
314; X64-NEXT:    subq %rsi, %rax
315; X64-NEXT:    subq %rdi, %rsi
316; X64-NEXT:    cmovaeq %rsi, %rax
317; X64-NEXT:    retq
318  %aext = zext i64 %a to i128
319  %bext = zext i64 %b to i128
320  %sub = sub i128 %aext, %bext
321  %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)
322  %trunc = trunc i128 %abs to i64
323  ret i64 %trunc
324}
325
326define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {
327; X86-LABEL: abd_ext_i128:
328; X86:       # %bb.0:
329; X86-NEXT:    pushl %ebx
330; X86-NEXT:    pushl %edi
331; X86-NEXT:    pushl %esi
332; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
333; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
334; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
335; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
336; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
337; X86-NEXT:    xorl %ebx, %ebx
338; X86-NEXT:    subl {{[0-9]+}}(%esp), %edi
339; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
340; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
341; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
342; X86-NEXT:    sbbl %ebx, %ebx
343; X86-NEXT:    xorl %ebx, %ecx
344; X86-NEXT:    xorl %ebx, %edx
345; X86-NEXT:    xorl %ebx, %esi
346; X86-NEXT:    xorl %ebx, %edi
347; X86-NEXT:    subl %ebx, %edi
348; X86-NEXT:    sbbl %ebx, %esi
349; X86-NEXT:    sbbl %ebx, %edx
350; X86-NEXT:    sbbl %ebx, %ecx
351; X86-NEXT:    movl %edi, (%eax)
352; X86-NEXT:    movl %esi, 4(%eax)
353; X86-NEXT:    movl %edx, 8(%eax)
354; X86-NEXT:    movl %ecx, 12(%eax)
355; X86-NEXT:    popl %esi
356; X86-NEXT:    popl %edi
357; X86-NEXT:    popl %ebx
358; X86-NEXT:    retl $4
359;
360; X64-LABEL: abd_ext_i128:
361; X64:       # %bb.0:
362; X64-NEXT:    movq %rdi, %rax
363; X64-NEXT:    xorl %edi, %edi
364; X64-NEXT:    subq %rdx, %rax
365; X64-NEXT:    sbbq %rcx, %rsi
366; X64-NEXT:    sbbq %rdi, %rdi
367; X64-NEXT:    xorq %rdi, %rsi
368; X64-NEXT:    xorq %rdi, %rax
369; X64-NEXT:    subq %rdi, %rax
370; X64-NEXT:    sbbq %rdi, %rsi
371; X64-NEXT:    movq %rsi, %rdx
372; X64-NEXT:    retq
373  %aext = zext i128 %a to i256
374  %bext = zext i128 %b to i256
375  %sub = sub i256 %aext, %bext
376  %abs = call i256 @llvm.abs.i256(i256 %sub, i1 false)
377  %trunc = trunc i256 %abs to i128
378  ret i128 %trunc
379}
380
381define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {
382; X86-LABEL: abd_ext_i128_undef:
383; X86:       # %bb.0:
384; X86-NEXT:    pushl %ebx
385; X86-NEXT:    pushl %edi
386; X86-NEXT:    pushl %esi
387; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
388; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
389; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
390; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
391; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
392; X86-NEXT:    xorl %ebx, %ebx
393; X86-NEXT:    subl {{[0-9]+}}(%esp), %edi
394; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
395; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
396; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
397; X86-NEXT:    sbbl %ebx, %ebx
398; X86-NEXT:    xorl %ebx, %ecx
399; X86-NEXT:    xorl %ebx, %edx
400; X86-NEXT:    xorl %ebx, %esi
401; X86-NEXT:    xorl %ebx, %edi
402; X86-NEXT:    subl %ebx, %edi
403; X86-NEXT:    sbbl %ebx, %esi
404; X86-NEXT:    sbbl %ebx, %edx
405; X86-NEXT:    sbbl %ebx, %ecx
406; X86-NEXT:    movl %edi, (%eax)
407; X86-NEXT:    movl %esi, 4(%eax)
408; X86-NEXT:    movl %edx, 8(%eax)
409; X86-NEXT:    movl %ecx, 12(%eax)
410; X86-NEXT:    popl %esi
411; X86-NEXT:    popl %edi
412; X86-NEXT:    popl %ebx
413; X86-NEXT:    retl $4
414;
415; X64-LABEL: abd_ext_i128_undef:
416; X64:       # %bb.0:
417; X64-NEXT:    movq %rdi, %rax
418; X64-NEXT:    xorl %edi, %edi
419; X64-NEXT:    subq %rdx, %rax
420; X64-NEXT:    sbbq %rcx, %rsi
421; X64-NEXT:    sbbq %rdi, %rdi
422; X64-NEXT:    xorq %rdi, %rsi
423; X64-NEXT:    xorq %rdi, %rax
424; X64-NEXT:    subq %rdi, %rax
425; X64-NEXT:    sbbq %rdi, %rsi
426; X64-NEXT:    movq %rsi, %rdx
427; X64-NEXT:    retq
428  %aext = zext i128 %a to i256
429  %bext = zext i128 %b to i256
430  %sub = sub i256 %aext, %bext
431  %abs = call i256 @llvm.abs.i256(i256 %sub, i1 true)
432  %trunc = trunc i256 %abs to i128
433  ret i128 %trunc
434}
435
436;
437; sub(umax(a,b),umin(a,b)) -> abdu(a,b)
438;
439
440define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind {
441; X86-LABEL: abd_minmax_i8:
442; X86:       # %bb.0:
443; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
444; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
445; X86-NEXT:    movl %ecx, %edx
446; X86-NEXT:    subl %eax, %edx
447; X86-NEXT:    subl %ecx, %eax
448; X86-NEXT:    cmovbl %edx, %eax
449; X86-NEXT:    # kill: def $al killed $al killed $eax
450; X86-NEXT:    retl
451;
452; X64-LABEL: abd_minmax_i8:
453; X64:       # %bb.0:
454; X64-NEXT:    movzbl %sil, %eax
455; X64-NEXT:    movzbl %dil, %ecx
456; X64-NEXT:    movl %ecx, %edx
457; X64-NEXT:    subl %eax, %edx
458; X64-NEXT:    subl %ecx, %eax
459; X64-NEXT:    cmovbl %edx, %eax
460; X64-NEXT:    # kill: def $al killed $al killed $eax
461; X64-NEXT:    retq
462  %min = call i8 @llvm.umin.i8(i8 %a, i8 %b)
463  %max = call i8 @llvm.umax.i8(i8 %a, i8 %b)
464  %sub = sub i8 %max, %min
465  ret i8 %sub
466}
467
468define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind {
469; X86-LABEL: abd_minmax_i16:
470; X86:       # %bb.0:
471; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
472; X86-NEXT:    movzwl {{[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:    cmovbl %edx, %eax
477; X86-NEXT:    # kill: def $ax killed $ax killed $eax
478; X86-NEXT:    retl
479;
480; X64-LABEL: abd_minmax_i16:
481; X64:       # %bb.0:
482; X64-NEXT:    movzwl %si, %eax
483; X64-NEXT:    movzwl %di, %ecx
484; X64-NEXT:    movl %ecx, %edx
485; X64-NEXT:    subl %eax, %edx
486; X64-NEXT:    subl %ecx, %eax
487; X64-NEXT:    cmovbl %edx, %eax
488; X64-NEXT:    # kill: def $ax killed $ax killed $eax
489; X64-NEXT:    retq
490  %min = call i16 @llvm.umin.i16(i16 %a, i16 %b)
491  %max = call i16 @llvm.umax.i16(i16 %a, i16 %b)
492  %sub = sub i16 %max, %min
493  ret i16 %sub
494}
495
496define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind {
497; X86-LABEL: abd_minmax_i32:
498; X86:       # %bb.0:
499; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
500; X86-NEXT:    movl {{[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:    cmovbl %edx, %eax
505; X86-NEXT:    retl
506;
507; X64-LABEL: abd_minmax_i32:
508; X64:       # %bb.0:
509; X64-NEXT:    movl %edi, %eax
510; X64-NEXT:    subl %esi, %eax
511; X64-NEXT:    subl %edi, %esi
512; X64-NEXT:    cmovael %esi, %eax
513; X64-NEXT:    retq
514  %min = call i32 @llvm.umin.i32(i32 %a, i32 %b)
515  %max = call i32 @llvm.umax.i32(i32 %a, i32 %b)
516  %sub = sub i32 %max, %min
517  ret i32 %sub
518}
519
520define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind {
521; X86-LABEL: abd_minmax_i64:
522; X86:       # %bb.0:
523; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
524; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
525; X86-NEXT:    xorl %ecx, %ecx
526; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
527; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
528; X86-NEXT:    sbbl %ecx, %ecx
529; X86-NEXT:    xorl %ecx, %edx
530; X86-NEXT:    xorl %ecx, %eax
531; X86-NEXT:    subl %ecx, %eax
532; X86-NEXT:    sbbl %ecx, %edx
533; X86-NEXT:    retl
534;
535; X64-LABEL: abd_minmax_i64:
536; X64:       # %bb.0:
537; X64-NEXT:    movq %rdi, %rax
538; X64-NEXT:    subq %rsi, %rax
539; X64-NEXT:    subq %rdi, %rsi
540; X64-NEXT:    cmovaeq %rsi, %rax
541; X64-NEXT:    retq
542  %min = call i64 @llvm.umin.i64(i64 %a, i64 %b)
543  %max = call i64 @llvm.umax.i64(i64 %a, i64 %b)
544  %sub = sub i64 %max, %min
545  ret i64 %sub
546}
547
548define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind {
549; X86-LABEL: abd_minmax_i128:
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), %edx
555; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
556; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
557; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
558; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
559; X86-NEXT:    xorl %ebx, %ebx
560; X86-NEXT:    subl {{[0-9]+}}(%esp), %edi
561; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
562; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
563; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
564; X86-NEXT:    sbbl %ebx, %ebx
565; X86-NEXT:    xorl %ebx, %ecx
566; X86-NEXT:    xorl %ebx, %edx
567; X86-NEXT:    xorl %ebx, %esi
568; X86-NEXT:    xorl %ebx, %edi
569; X86-NEXT:    subl %ebx, %edi
570; X86-NEXT:    sbbl %ebx, %esi
571; X86-NEXT:    sbbl %ebx, %edx
572; X86-NEXT:    sbbl %ebx, %ecx
573; X86-NEXT:    movl %edi, (%eax)
574; X86-NEXT:    movl %esi, 4(%eax)
575; X86-NEXT:    movl %edx, 8(%eax)
576; X86-NEXT:    movl %ecx, 12(%eax)
577; X86-NEXT:    popl %esi
578; X86-NEXT:    popl %edi
579; X86-NEXT:    popl %ebx
580; X86-NEXT:    retl $4
581;
582; X64-LABEL: abd_minmax_i128:
583; X64:       # %bb.0:
584; X64-NEXT:    movq %rdi, %rax
585; X64-NEXT:    xorl %edi, %edi
586; X64-NEXT:    subq %rdx, %rax
587; X64-NEXT:    sbbq %rcx, %rsi
588; X64-NEXT:    sbbq %rdi, %rdi
589; X64-NEXT:    xorq %rdi, %rsi
590; X64-NEXT:    xorq %rdi, %rax
591; X64-NEXT:    subq %rdi, %rax
592; X64-NEXT:    sbbq %rdi, %rsi
593; X64-NEXT:    movq %rsi, %rdx
594; X64-NEXT:    retq
595  %min = call i128 @llvm.umin.i128(i128 %a, i128 %b)
596  %max = call i128 @llvm.umax.i128(i128 %a, i128 %b)
597  %sub = sub i128 %max, %min
598  ret i128 %sub
599}
600
601;
602; select(icmp(a,b),sub(a,b),sub(b,a)) -> abdu(a,b)
603;
604
605define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind {
606; X86-LABEL: abd_cmp_i8:
607; X86:       # %bb.0:
608; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
609; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
610; X86-NEXT:    movl %ecx, %edx
611; X86-NEXT:    subl %eax, %edx
612; X86-NEXT:    subl %ecx, %eax
613; X86-NEXT:    cmovbl %edx, %eax
614; X86-NEXT:    # kill: def $al killed $al killed $eax
615; X86-NEXT:    retl
616;
617; X64-LABEL: abd_cmp_i8:
618; X64:       # %bb.0:
619; X64-NEXT:    movzbl %dil, %eax
620; X64-NEXT:    movzbl %sil, %ecx
621; X64-NEXT:    movl %ecx, %edx
622; X64-NEXT:    subl %eax, %edx
623; X64-NEXT:    subl %ecx, %eax
624; X64-NEXT:    cmovbl %edx, %eax
625; X64-NEXT:    # kill: def $al killed $al killed $eax
626; X64-NEXT:    retq
627  %cmp = icmp ugt i8 %a, %b
628  %ab = sub i8 %a, %b
629  %ba = sub i8 %b, %a
630  %sel = select i1 %cmp, i8 %ab, i8 %ba
631  ret i8 %sel
632}
633
634define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind {
635; X86-LABEL: abd_cmp_i16:
636; X86:       # %bb.0:
637; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
638; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
639; X86-NEXT:    movl %ecx, %edx
640; X86-NEXT:    subl %eax, %edx
641; X86-NEXT:    subl %ecx, %eax
642; X86-NEXT:    cmovbl %edx, %eax
643; X86-NEXT:    # kill: def $ax killed $ax killed $eax
644; X86-NEXT:    retl
645;
646; X64-LABEL: abd_cmp_i16:
647; X64:       # %bb.0:
648; X64-NEXT:    movzwl %si, %eax
649; X64-NEXT:    movzwl %di, %ecx
650; X64-NEXT:    movl %ecx, %edx
651; X64-NEXT:    subl %eax, %edx
652; X64-NEXT:    subl %ecx, %eax
653; X64-NEXT:    cmovbl %edx, %eax
654; X64-NEXT:    # kill: def $ax killed $ax killed $eax
655; X64-NEXT:    retq
656  %cmp = icmp uge i16 %a, %b
657  %ab = sub i16 %a, %b
658  %ba = sub i16 %b, %a
659  %sel = select i1 %cmp, i16 %ab, i16 %ba
660  ret i16 %sel
661}
662
663define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind {
664; X86-LABEL: abd_cmp_i32:
665; X86:       # %bb.0:
666; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
667; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
668; X86-NEXT:    movl %ecx, %edx
669; X86-NEXT:    subl %eax, %edx
670; X86-NEXT:    subl %ecx, %eax
671; X86-NEXT:    cmovbl %edx, %eax
672; X86-NEXT:    retl
673;
674; X64-LABEL: abd_cmp_i32:
675; X64:       # %bb.0:
676; X64-NEXT:    movl %edi, %eax
677; X64-NEXT:    subl %esi, %eax
678; X64-NEXT:    subl %edi, %esi
679; X64-NEXT:    cmovael %esi, %eax
680; X64-NEXT:    retq
681  %cmp = icmp ult i32 %a, %b
682  %ab = sub i32 %a, %b
683  %ba = sub i32 %b, %a
684  %sel = select i1 %cmp, i32 %ba, i32 %ab
685  ret i32 %sel
686}
687
688define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind {
689; X86-LABEL: abd_cmp_i64:
690; X86:       # %bb.0:
691; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
692; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
693; X86-NEXT:    xorl %ecx, %ecx
694; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
695; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
696; X86-NEXT:    sbbl %ecx, %ecx
697; X86-NEXT:    xorl %ecx, %edx
698; X86-NEXT:    xorl %ecx, %eax
699; X86-NEXT:    subl %ecx, %eax
700; X86-NEXT:    sbbl %ecx, %edx
701; X86-NEXT:    retl
702;
703; X64-LABEL: abd_cmp_i64:
704; X64:       # %bb.0:
705; X64-NEXT:    movq %rdi, %rax
706; X64-NEXT:    subq %rsi, %rax
707; X64-NEXT:    subq %rdi, %rsi
708; X64-NEXT:    cmovaeq %rsi, %rax
709; X64-NEXT:    retq
710  %cmp = icmp uge i64 %a, %b
711  %ab = sub i64 %a, %b
712  %ba = sub i64 %b, %a
713  %sel = select i1 %cmp, i64 %ab, i64 %ba
714  ret i64 %sel
715}
716
717define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind {
718; X86-LABEL: abd_cmp_i128:
719; X86:       # %bb.0:
720; X86-NEXT:    pushl %ebx
721; X86-NEXT:    pushl %edi
722; X86-NEXT:    pushl %esi
723; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
724; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
725; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
726; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
727; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
728; X86-NEXT:    xorl %ebx, %ebx
729; X86-NEXT:    subl {{[0-9]+}}(%esp), %edi
730; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
731; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
732; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
733; X86-NEXT:    sbbl %ebx, %ebx
734; X86-NEXT:    xorl %ebx, %ecx
735; X86-NEXT:    xorl %ebx, %edx
736; X86-NEXT:    xorl %ebx, %esi
737; X86-NEXT:    xorl %ebx, %edi
738; X86-NEXT:    subl %ebx, %edi
739; X86-NEXT:    sbbl %ebx, %esi
740; X86-NEXT:    sbbl %ebx, %edx
741; X86-NEXT:    sbbl %ebx, %ecx
742; X86-NEXT:    movl %edi, (%eax)
743; X86-NEXT:    movl %esi, 4(%eax)
744; X86-NEXT:    movl %edx, 8(%eax)
745; X86-NEXT:    movl %ecx, 12(%eax)
746; X86-NEXT:    popl %esi
747; X86-NEXT:    popl %edi
748; X86-NEXT:    popl %ebx
749; X86-NEXT:    retl $4
750;
751; X64-LABEL: abd_cmp_i128:
752; X64:       # %bb.0:
753; X64-NEXT:    movq %rdi, %rax
754; X64-NEXT:    xorl %edi, %edi
755; X64-NEXT:    subq %rdx, %rax
756; X64-NEXT:    sbbq %rcx, %rsi
757; X64-NEXT:    sbbq %rdi, %rdi
758; X64-NEXT:    xorq %rdi, %rsi
759; X64-NEXT:    xorq %rdi, %rax
760; X64-NEXT:    subq %rdi, %rax
761; X64-NEXT:    sbbq %rdi, %rsi
762; X64-NEXT:    movq %rsi, %rdx
763; X64-NEXT:    retq
764  %cmp = icmp uge i128 %a, %b
765  %ab = sub i128 %a, %b
766  %ba = sub i128 %b, %a
767  %sel = select i1 %cmp, i128 %ab, i128 %ba
768  ret i128 %sel
769}
770
771;
772; sub(select(icmp(a,b),a,b),select(icmp(a,b),b,a)) -> abdu(a,b)
773;
774
775define i8 @abd_select_i8(i8 %a, i8 %b) nounwind {
776; X86-LABEL: abd_select_i8:
777; X86:       # %bb.0:
778; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
779; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
780; X86-NEXT:    movl %ecx, %edx
781; X86-NEXT:    subl %eax, %edx
782; X86-NEXT:    subl %ecx, %eax
783; X86-NEXT:    cmovbl %edx, %eax
784; X86-NEXT:    # kill: def $al killed $al killed $eax
785; X86-NEXT:    retl
786;
787; X64-LABEL: abd_select_i8:
788; X64:       # %bb.0:
789; X64-NEXT:    movzbl %sil, %eax
790; X64-NEXT:    movzbl %dil, %ecx
791; X64-NEXT:    movl %ecx, %edx
792; X64-NEXT:    subl %eax, %edx
793; X64-NEXT:    subl %ecx, %eax
794; X64-NEXT:    cmovbl %edx, %eax
795; X64-NEXT:    # kill: def $al killed $al killed $eax
796; X64-NEXT:    retq
797  %cmp = icmp ult i8 %a, %b
798  %ab = select i1 %cmp, i8 %a, i8 %b
799  %ba = select i1 %cmp, i8 %b, i8 %a
800  %sub = sub i8 %ba, %ab
801  ret i8 %sub
802}
803
804define i16 @abd_select_i16(i16 %a, i16 %b) nounwind {
805; X86-LABEL: abd_select_i16:
806; X86:       # %bb.0:
807; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
808; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
809; X86-NEXT:    movl %ecx, %edx
810; X86-NEXT:    subl %eax, %edx
811; X86-NEXT:    subl %ecx, %eax
812; X86-NEXT:    cmovbl %edx, %eax
813; X86-NEXT:    # kill: def $ax killed $ax killed $eax
814; X86-NEXT:    retl
815;
816; X64-LABEL: abd_select_i16:
817; X64:       # %bb.0:
818; X64-NEXT:    movzwl %si, %eax
819; X64-NEXT:    movzwl %di, %ecx
820; X64-NEXT:    movl %ecx, %edx
821; X64-NEXT:    subl %eax, %edx
822; X64-NEXT:    subl %ecx, %eax
823; X64-NEXT:    cmovbl %edx, %eax
824; X64-NEXT:    # kill: def $ax killed $ax killed $eax
825; X64-NEXT:    retq
826  %cmp = icmp ule i16 %a, %b
827  %ab = select i1 %cmp, i16 %a, i16 %b
828  %ba = select i1 %cmp, i16 %b, i16 %a
829  %sub = sub i16 %ba, %ab
830  ret i16 %sub
831}
832
833define i32 @abd_select_i32(i32 %a, i32 %b) nounwind {
834; X86-LABEL: abd_select_i32:
835; X86:       # %bb.0:
836; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
837; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
838; X86-NEXT:    movl %ecx, %edx
839; X86-NEXT:    subl %eax, %edx
840; X86-NEXT:    subl %ecx, %eax
841; X86-NEXT:    cmovbl %edx, %eax
842; X86-NEXT:    retl
843;
844; X64-LABEL: abd_select_i32:
845; X64:       # %bb.0:
846; X64-NEXT:    movl %edi, %eax
847; X64-NEXT:    subl %esi, %eax
848; X64-NEXT:    subl %edi, %esi
849; X64-NEXT:    cmovael %esi, %eax
850; X64-NEXT:    retq
851  %cmp = icmp ugt i32 %a, %b
852  %ab = select i1 %cmp, i32 %a, i32 %b
853  %ba = select i1 %cmp, i32 %b, i32 %a
854  %sub = sub i32 %ab, %ba
855  ret i32 %sub
856}
857
858define i64 @abd_select_i64(i64 %a, i64 %b) nounwind {
859; X86-LABEL: abd_select_i64:
860; X86:       # %bb.0:
861; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
862; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
863; X86-NEXT:    xorl %ecx, %ecx
864; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
865; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
866; X86-NEXT:    sbbl %ecx, %ecx
867; X86-NEXT:    xorl %ecx, %edx
868; X86-NEXT:    xorl %ecx, %eax
869; X86-NEXT:    subl %ecx, %eax
870; X86-NEXT:    sbbl %ecx, %edx
871; X86-NEXT:    retl
872;
873; X64-LABEL: abd_select_i64:
874; X64:       # %bb.0:
875; X64-NEXT:    movq %rdi, %rax
876; X64-NEXT:    subq %rsi, %rax
877; X64-NEXT:    subq %rdi, %rsi
878; X64-NEXT:    cmovaeq %rsi, %rax
879; X64-NEXT:    retq
880  %cmp = icmp uge i64 %a, %b
881  %ab = select i1 %cmp, i64 %a, i64 %b
882  %ba = select i1 %cmp, i64 %b, i64 %a
883  %sub = sub i64 %ab, %ba
884  ret i64 %sub
885}
886
887define i128 @abd_select_i128(i128 %a, i128 %b) nounwind {
888; X86-LABEL: abd_select_i128:
889; X86:       # %bb.0:
890; X86-NEXT:    pushl %ebx
891; X86-NEXT:    pushl %edi
892; X86-NEXT:    pushl %esi
893; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
894; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
895; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
896; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
897; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
898; X86-NEXT:    xorl %ebx, %ebx
899; X86-NEXT:    subl {{[0-9]+}}(%esp), %edi
900; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
901; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %edx
902; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
903; X86-NEXT:    sbbl %ebx, %ebx
904; X86-NEXT:    xorl %ebx, %ecx
905; X86-NEXT:    xorl %ebx, %edx
906; X86-NEXT:    xorl %ebx, %esi
907; X86-NEXT:    xorl %ebx, %edi
908; X86-NEXT:    subl %ebx, %edi
909; X86-NEXT:    sbbl %ebx, %esi
910; X86-NEXT:    sbbl %ebx, %edx
911; X86-NEXT:    sbbl %ebx, %ecx
912; X86-NEXT:    movl %edi, (%eax)
913; X86-NEXT:    movl %esi, 4(%eax)
914; X86-NEXT:    movl %edx, 8(%eax)
915; X86-NEXT:    movl %ecx, 12(%eax)
916; X86-NEXT:    popl %esi
917; X86-NEXT:    popl %edi
918; X86-NEXT:    popl %ebx
919; X86-NEXT:    retl $4
920;
921; X64-LABEL: abd_select_i128:
922; X64:       # %bb.0:
923; X64-NEXT:    movq %rdi, %rax
924; X64-NEXT:    xorl %edi, %edi
925; X64-NEXT:    subq %rdx, %rax
926; X64-NEXT:    sbbq %rcx, %rsi
927; X64-NEXT:    sbbq %rdi, %rdi
928; X64-NEXT:    xorq %rdi, %rsi
929; X64-NEXT:    xorq %rdi, %rax
930; X64-NEXT:    subq %rdi, %rax
931; X64-NEXT:    sbbq %rdi, %rsi
932; X64-NEXT:    movq %rsi, %rdx
933; X64-NEXT:    retq
934  %cmp = icmp ult i128 %a, %b
935  %ab = select i1 %cmp, i128 %a, i128 %b
936  %ba = select i1 %cmp, i128 %b, i128 %a
937  %sub = sub i128 %ba, %ab
938  ret i128 %sub
939}
940
941declare i8 @llvm.abs.i8(i8, i1)
942declare i16 @llvm.abs.i16(i16, i1)
943declare i32 @llvm.abs.i32(i32, i1)
944declare i64 @llvm.abs.i64(i64, i1)
945declare i128 @llvm.abs.i128(i128, i1)
946
947declare i8 @llvm.umax.i8(i8, i8)
948declare i16 @llvm.umax.i16(i16, i16)
949declare i32 @llvm.umax.i32(i32, i32)
950declare i64 @llvm.umax.i64(i64, i64)
951
952declare i8 @llvm.umin.i8(i8, i8)
953declare i16 @llvm.umin.i16(i16, i16)
954declare i32 @llvm.umin.i32(i32, i32)
955declare i64 @llvm.umin.i64(i64, i64)
956