xref: /llvm-project/llvm/test/CodeGen/X86/abdu-neg.ll (revision 1b0400eed8613108d9f293b9ddd3380e3241ac60)
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(nabs(sub(zext(a),zext(b)))) -> nabds(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:    negb %al
19; X86-NEXT:    # kill: def $al killed $al killed $eax
20; X86-NEXT:    retl
21;
22; X64-LABEL: abd_ext_i8:
23; X64:       # %bb.0:
24; X64-NEXT:    movzbl %sil, %eax
25; X64-NEXT:    movzbl %dil, %ecx
26; X64-NEXT:    movl %ecx, %edx
27; X64-NEXT:    subl %eax, %edx
28; X64-NEXT:    subl %ecx, %eax
29; X64-NEXT:    cmovbl %edx, %eax
30; X64-NEXT:    negb %al
31; X64-NEXT:    # kill: def $al killed $al killed $eax
32; X64-NEXT:    retq
33  %aext = zext i8 %a to i64
34  %bext = zext i8 %b to i64
35  %sub = sub i64 %aext, %bext
36  %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
37  %nabs = sub i64 0, %abs
38  %trunc = trunc i64 %nabs to i8
39  ret i8 %trunc
40}
41
42define i8 @abd_ext_i8_i16(i8 %a, i16 %b) nounwind {
43; X86-LABEL: abd_ext_i8_i16:
44; X86:       # %bb.0:
45; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
46; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
47; X86-NEXT:    movl %ecx, %edx
48; X86-NEXT:    subl %eax, %edx
49; X86-NEXT:    subl %ecx, %eax
50; X86-NEXT:    cmovbl %edx, %eax
51; X86-NEXT:    negb %al
52; X86-NEXT:    # kill: def $al killed $al killed $eax
53; X86-NEXT:    retl
54;
55; X64-LABEL: abd_ext_i8_i16:
56; X64:       # %bb.0:
57; X64-NEXT:    movzbl %dil, %ecx
58; X64-NEXT:    subl %esi, %edi
59; X64-NEXT:    movzwl %si, %eax
60; X64-NEXT:    subl %ecx, %eax
61; X64-NEXT:    cmovbl %edi, %eax
62; X64-NEXT:    negb %al
63; X64-NEXT:    # kill: def $al killed $al killed $eax
64; X64-NEXT:    retq
65  %aext = zext i8 %a to i64
66  %bext = zext i16 %b to i64
67  %sub = sub i64 %aext, %bext
68  %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
69  %nabs = sub i64 0, %abs
70  %trunc = trunc i64 %nabs to i8
71  ret i8 %trunc
72}
73
74define i8 @abd_ext_i8_undef(i8 %a, i8 %b) nounwind {
75; X86-LABEL: abd_ext_i8_undef:
76; X86:       # %bb.0:
77; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
78; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
79; X86-NEXT:    movl %ecx, %edx
80; X86-NEXT:    subl %eax, %edx
81; X86-NEXT:    subl %ecx, %eax
82; X86-NEXT:    cmovbl %edx, %eax
83; X86-NEXT:    negb %al
84; X86-NEXT:    # kill: def $al killed $al killed $eax
85; X86-NEXT:    retl
86;
87; X64-LABEL: abd_ext_i8_undef:
88; X64:       # %bb.0:
89; X64-NEXT:    movzbl %sil, %eax
90; X64-NEXT:    movzbl %dil, %ecx
91; X64-NEXT:    movl %ecx, %edx
92; X64-NEXT:    subl %eax, %edx
93; X64-NEXT:    subl %ecx, %eax
94; X64-NEXT:    cmovbl %edx, %eax
95; X64-NEXT:    negb %al
96; X64-NEXT:    # kill: def $al killed $al killed $eax
97; X64-NEXT:    retq
98  %aext = zext i8 %a to i64
99  %bext = zext i8 %b to i64
100  %sub = sub i64 %aext, %bext
101  %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
102  %nabs = sub i64 0, %abs
103  %trunc = trunc i64 %nabs to i8
104  ret i8 %trunc
105}
106
107define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind {
108; X86-LABEL: abd_ext_i16:
109; X86:       # %bb.0:
110; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
111; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
112; X86-NEXT:    movl %ecx, %edx
113; X86-NEXT:    subl %eax, %edx
114; X86-NEXT:    subl %ecx, %eax
115; X86-NEXT:    cmovael %edx, %eax
116; X86-NEXT:    # kill: def $ax killed $ax killed $eax
117; X86-NEXT:    retl
118;
119; X64-LABEL: abd_ext_i16:
120; X64:       # %bb.0:
121; X64-NEXT:    movzwl %di, %ecx
122; X64-NEXT:    subl %esi, %edi
123; X64-NEXT:    movzwl %si, %eax
124; X64-NEXT:    subl %ecx, %eax
125; X64-NEXT:    cmovbl %edi, %eax
126; X64-NEXT:    negl %eax
127; X64-NEXT:    # kill: def $ax killed $ax killed $eax
128; X64-NEXT:    retq
129  %aext = zext i16 %a to i64
130  %bext = zext i16 %b to i64
131  %sub = sub i64 %aext, %bext
132  %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
133  %nabs = sub i64 0, %abs
134  %trunc = trunc i64 %nabs to i16
135  ret i16 %trunc
136}
137
138define i16 @abd_ext_i16_i32(i16 %a, i32 %b) nounwind {
139; X86-LABEL: abd_ext_i16_i32:
140; X86:       # %bb.0:
141; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
142; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
143; X86-NEXT:    movl %ecx, %edx
144; X86-NEXT:    subl %eax, %edx
145; X86-NEXT:    subl %ecx, %eax
146; X86-NEXT:    cmovael %edx, %eax
147; X86-NEXT:    # kill: def $ax killed $ax killed $eax
148; X86-NEXT:    retl
149;
150; X64-LABEL: abd_ext_i16_i32:
151; X64:       # %bb.0:
152; X64-NEXT:    movzwl %di, %ecx
153; X64-NEXT:    movl %edi, %eax
154; X64-NEXT:    subl %esi, %eax
155; X64-NEXT:    subl %ecx, %esi
156; X64-NEXT:    cmovael %esi, %eax
157; X64-NEXT:    negl %eax
158; X64-NEXT:    # kill: def $ax killed $ax killed $eax
159; X64-NEXT:    retq
160  %aext = zext i16 %a to i64
161  %bext = zext i32 %b to i64
162  %sub = sub i64 %aext, %bext
163  %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
164  %nabs = sub i64 0, %abs
165  %trunc = trunc i64 %nabs to i16
166  ret i16 %trunc
167}
168
169define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind {
170; X86-LABEL: abd_ext_i16_undef:
171; X86:       # %bb.0:
172; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
173; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
174; X86-NEXT:    movl %ecx, %edx
175; X86-NEXT:    subl %eax, %edx
176; X86-NEXT:    subl %ecx, %eax
177; X86-NEXT:    cmovael %edx, %eax
178; X86-NEXT:    # kill: def $ax killed $ax killed $eax
179; X86-NEXT:    retl
180;
181; X64-LABEL: abd_ext_i16_undef:
182; X64:       # %bb.0:
183; X64-NEXT:    movzwl %di, %ecx
184; X64-NEXT:    subl %esi, %edi
185; X64-NEXT:    movzwl %si, %eax
186; X64-NEXT:    subl %ecx, %eax
187; X64-NEXT:    cmovbl %edi, %eax
188; X64-NEXT:    negl %eax
189; X64-NEXT:    # kill: def $ax killed $ax killed $eax
190; X64-NEXT:    retq
191  %aext = zext i16 %a to i64
192  %bext = zext i16 %b to i64
193  %sub = sub i64 %aext, %bext
194  %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
195  %nabs = sub i64 0, %abs
196  %trunc = trunc i64 %nabs to i16
197  ret i16 %trunc
198}
199
200define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind {
201; X86-LABEL: abd_ext_i32:
202; X86:       # %bb.0:
203; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
204; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
205; X86-NEXT:    movl %ecx, %edx
206; X86-NEXT:    subl %eax, %edx
207; X86-NEXT:    subl %ecx, %eax
208; X86-NEXT:    cmovael %edx, %eax
209; X86-NEXT:    retl
210;
211; X64-LABEL: abd_ext_i32:
212; X64:       # %bb.0:
213; X64-NEXT:    movl %edi, %eax
214; X64-NEXT:    subl %esi, %eax
215; X64-NEXT:    subl %edi, %esi
216; X64-NEXT:    cmovbl %esi, %eax
217; X64-NEXT:    retq
218  %aext = zext i32 %a to i64
219  %bext = zext i32 %b to i64
220  %sub = sub i64 %aext, %bext
221  %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
222  %nabs = sub i64 0, %abs
223  %trunc = trunc i64 %nabs to i32
224  ret i32 %trunc
225}
226
227define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind {
228; X86-LABEL: abd_ext_i32_i16:
229; X86:       # %bb.0:
230; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
231; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
232; X86-NEXT:    movl %ecx, %edx
233; X86-NEXT:    subl %eax, %edx
234; X86-NEXT:    subl %ecx, %eax
235; X86-NEXT:    cmovael %edx, %eax
236; X86-NEXT:    retl
237;
238; X64-LABEL: abd_ext_i32_i16:
239; X64:       # %bb.0:
240; X64-NEXT:    movzwl %si, %eax
241; X64-NEXT:    movl %edi, %ecx
242; X64-NEXT:    subl %eax, %ecx
243; X64-NEXT:    subl %edi, %eax
244; X64-NEXT:    cmovael %ecx, %eax
245; X64-NEXT:    retq
246  %aext = zext i32 %a to i64
247  %bext = zext i16 %b to i64
248  %sub = sub i64 %aext, %bext
249  %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)
250  %nabs = sub i64 0, %abs
251  %trunc = trunc i64 %nabs to i32
252  ret i32 %trunc
253}
254
255define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind {
256; X86-LABEL: abd_ext_i32_undef:
257; X86:       # %bb.0:
258; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
259; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
260; X86-NEXT:    movl %ecx, %edx
261; X86-NEXT:    subl %eax, %edx
262; X86-NEXT:    subl %ecx, %eax
263; X86-NEXT:    cmovael %edx, %eax
264; X86-NEXT:    retl
265;
266; X64-LABEL: abd_ext_i32_undef:
267; X64:       # %bb.0:
268; X64-NEXT:    movl %edi, %eax
269; X64-NEXT:    subl %esi, %eax
270; X64-NEXT:    subl %edi, %esi
271; X64-NEXT:    cmovbl %esi, %eax
272; X64-NEXT:    retq
273  %aext = zext i32 %a to i64
274  %bext = zext i32 %b to i64
275  %sub = sub i64 %aext, %bext
276  %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)
277  %nabs = sub i64 0, %abs
278  %trunc = trunc i64 %nabs to i32
279  ret i32 %trunc
280}
281
282define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind {
283; X86-LABEL: abd_ext_i64:
284; X86:       # %bb.0:
285; X86-NEXT:    pushl %esi
286; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
287; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
288; X86-NEXT:    xorl %edx, %edx
289; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
290; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
291; X86-NEXT:    movl $0, %esi
292; X86-NEXT:    sbbl %esi, %esi
293; X86-NEXT:    xorl %esi, %ecx
294; X86-NEXT:    xorl %esi, %eax
295; X86-NEXT:    subl %esi, %eax
296; X86-NEXT:    sbbl %esi, %ecx
297; X86-NEXT:    negl %eax
298; X86-NEXT:    sbbl %ecx, %edx
299; X86-NEXT:    popl %esi
300; X86-NEXT:    retl
301;
302; X64-LABEL: abd_ext_i64:
303; X64:       # %bb.0:
304; X64-NEXT:    movq %rdi, %rax
305; X64-NEXT:    subq %rsi, %rax
306; X64-NEXT:    subq %rdi, %rsi
307; X64-NEXT:    cmovbq %rsi, %rax
308; X64-NEXT:    retq
309  %aext = zext i64 %a to i128
310  %bext = zext i64 %b to i128
311  %sub = sub i128 %aext, %bext
312  %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)
313  %nabs = sub i128 0, %abs
314  %trunc = trunc i128 %nabs to i64
315  ret i64 %trunc
316}
317
318define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind {
319; X86-LABEL: abd_ext_i64_undef:
320; X86:       # %bb.0:
321; X86-NEXT:    pushl %esi
322; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
323; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
324; X86-NEXT:    xorl %edx, %edx
325; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
326; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
327; X86-NEXT:    movl $0, %esi
328; X86-NEXT:    sbbl %esi, %esi
329; X86-NEXT:    xorl %esi, %ecx
330; X86-NEXT:    xorl %esi, %eax
331; X86-NEXT:    subl %esi, %eax
332; X86-NEXT:    sbbl %esi, %ecx
333; X86-NEXT:    negl %eax
334; X86-NEXT:    sbbl %ecx, %edx
335; X86-NEXT:    popl %esi
336; X86-NEXT:    retl
337;
338; X64-LABEL: abd_ext_i64_undef:
339; X64:       # %bb.0:
340; X64-NEXT:    movq %rdi, %rax
341; X64-NEXT:    subq %rsi, %rax
342; X64-NEXT:    subq %rdi, %rsi
343; X64-NEXT:    cmovbq %rsi, %rax
344; X64-NEXT:    retq
345  %aext = zext i64 %a to i128
346  %bext = zext i64 %b to i128
347  %sub = sub i128 %aext, %bext
348  %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)
349  %nabs = sub i128 0, %abs
350  %trunc = trunc i128 %nabs to i64
351  ret i64 %trunc
352}
353
354define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {
355; X86-LABEL: abd_ext_i128:
356; X86:       # %bb.0:
357; X86-NEXT:    pushl %ebp
358; X86-NEXT:    pushl %ebx
359; X86-NEXT:    pushl %edi
360; X86-NEXT:    pushl %esi
361; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
362; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
363; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
364; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
365; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
366; X86-NEXT:    xorl %edi, %edi
367; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
368; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ebx
369; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
370; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
371; X86-NEXT:    movl $0, %ebp
372; X86-NEXT:    sbbl %ebp, %ebp
373; X86-NEXT:    xorl %ebp, %ecx
374; X86-NEXT:    xorl %ebp, %esi
375; X86-NEXT:    xorl %ebp, %ebx
376; X86-NEXT:    xorl %ebp, %edx
377; X86-NEXT:    subl %ebp, %edx
378; X86-NEXT:    sbbl %ebp, %ebx
379; X86-NEXT:    sbbl %ebp, %esi
380; X86-NEXT:    sbbl %ebp, %ecx
381; X86-NEXT:    negl %edx
382; X86-NEXT:    movl $0, %ebp
383; X86-NEXT:    sbbl %ebx, %ebp
384; X86-NEXT:    movl $0, %ebx
385; X86-NEXT:    sbbl %esi, %ebx
386; X86-NEXT:    sbbl %ecx, %edi
387; X86-NEXT:    movl %edx, (%eax)
388; X86-NEXT:    movl %ebp, 4(%eax)
389; X86-NEXT:    movl %ebx, 8(%eax)
390; X86-NEXT:    movl %edi, 12(%eax)
391; X86-NEXT:    popl %esi
392; X86-NEXT:    popl %edi
393; X86-NEXT:    popl %ebx
394; X86-NEXT:    popl %ebp
395; X86-NEXT:    retl $4
396;
397; X64-LABEL: abd_ext_i128:
398; X64:       # %bb.0:
399; X64-NEXT:    movq %rdi, %rax
400; X64-NEXT:    xorl %edi, %edi
401; X64-NEXT:    subq %rdx, %rax
402; X64-NEXT:    sbbq %rcx, %rsi
403; X64-NEXT:    movl $0, %ecx
404; X64-NEXT:    sbbq %rcx, %rcx
405; X64-NEXT:    xorq %rcx, %rsi
406; X64-NEXT:    xorq %rcx, %rax
407; X64-NEXT:    subq %rcx, %rax
408; X64-NEXT:    sbbq %rcx, %rsi
409; X64-NEXT:    negq %rax
410; X64-NEXT:    sbbq %rsi, %rdi
411; X64-NEXT:    movq %rdi, %rdx
412; X64-NEXT:    retq
413  %aext = zext i128 %a to i256
414  %bext = zext i128 %b to i256
415  %sub = sub i256 %aext, %bext
416  %abs = call i256 @llvm.abs.i256(i256 %sub, i1 false)
417  %nabs = sub i256 0, %abs
418  %trunc = trunc i256 %nabs to i128
419  ret i128 %trunc
420}
421
422define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {
423; X86-LABEL: abd_ext_i128_undef:
424; X86:       # %bb.0:
425; X86-NEXT:    pushl %ebp
426; X86-NEXT:    pushl %ebx
427; X86-NEXT:    pushl %edi
428; X86-NEXT:    pushl %esi
429; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
430; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
431; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
432; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
433; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
434; X86-NEXT:    xorl %edi, %edi
435; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
436; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ebx
437; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
438; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
439; X86-NEXT:    movl $0, %ebp
440; X86-NEXT:    sbbl %ebp, %ebp
441; X86-NEXT:    xorl %ebp, %ecx
442; X86-NEXT:    xorl %ebp, %esi
443; X86-NEXT:    xorl %ebp, %ebx
444; X86-NEXT:    xorl %ebp, %edx
445; X86-NEXT:    subl %ebp, %edx
446; X86-NEXT:    sbbl %ebp, %ebx
447; X86-NEXT:    sbbl %ebp, %esi
448; X86-NEXT:    sbbl %ebp, %ecx
449; X86-NEXT:    negl %edx
450; X86-NEXT:    movl $0, %ebp
451; X86-NEXT:    sbbl %ebx, %ebp
452; X86-NEXT:    movl $0, %ebx
453; X86-NEXT:    sbbl %esi, %ebx
454; X86-NEXT:    sbbl %ecx, %edi
455; X86-NEXT:    movl %edx, (%eax)
456; X86-NEXT:    movl %ebp, 4(%eax)
457; X86-NEXT:    movl %ebx, 8(%eax)
458; X86-NEXT:    movl %edi, 12(%eax)
459; X86-NEXT:    popl %esi
460; X86-NEXT:    popl %edi
461; X86-NEXT:    popl %ebx
462; X86-NEXT:    popl %ebp
463; X86-NEXT:    retl $4
464;
465; X64-LABEL: abd_ext_i128_undef:
466; X64:       # %bb.0:
467; X64-NEXT:    movq %rdi, %rax
468; X64-NEXT:    xorl %edi, %edi
469; X64-NEXT:    subq %rdx, %rax
470; X64-NEXT:    sbbq %rcx, %rsi
471; X64-NEXT:    movl $0, %ecx
472; X64-NEXT:    sbbq %rcx, %rcx
473; X64-NEXT:    xorq %rcx, %rsi
474; X64-NEXT:    xorq %rcx, %rax
475; X64-NEXT:    subq %rcx, %rax
476; X64-NEXT:    sbbq %rcx, %rsi
477; X64-NEXT:    negq %rax
478; X64-NEXT:    sbbq %rsi, %rdi
479; X64-NEXT:    movq %rdi, %rdx
480; X64-NEXT:    retq
481  %aext = zext i128 %a to i256
482  %bext = zext i128 %b to i256
483  %sub = sub i256 %aext, %bext
484  %abs = call i256 @llvm.abs.i256(i256 %sub, i1 true)
485  %nabs = sub i256 0, %abs
486  %trunc = trunc i256 %nabs to i128
487  ret i128 %trunc
488}
489
490;
491; sub(umin(a,b),umax(a,b)) -> nabds(a,b)
492;
493
494define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind {
495; X86-LABEL: abd_minmax_i8:
496; X86:       # %bb.0:
497; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
498; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
499; X86-NEXT:    movl %ecx, %edx
500; X86-NEXT:    subl %eax, %edx
501; X86-NEXT:    subl %ecx, %eax
502; X86-NEXT:    cmovbl %edx, %eax
503; X86-NEXT:    negb %al
504; X86-NEXT:    # kill: def $al killed $al killed $eax
505; X86-NEXT:    retl
506;
507; X64-LABEL: abd_minmax_i8:
508; X64:       # %bb.0:
509; X64-NEXT:    movzbl %sil, %eax
510; X64-NEXT:    movzbl %dil, %ecx
511; X64-NEXT:    movl %ecx, %edx
512; X64-NEXT:    subl %eax, %edx
513; X64-NEXT:    subl %ecx, %eax
514; X64-NEXT:    cmovbl %edx, %eax
515; X64-NEXT:    negb %al
516; X64-NEXT:    # kill: def $al killed $al killed $eax
517; X64-NEXT:    retq
518  %min = call i8 @llvm.umin.i8(i8 %a, i8 %b)
519  %max = call i8 @llvm.umax.i8(i8 %a, i8 %b)
520  %sub = sub i8 %min, %max
521  ret i8 %sub
522}
523
524define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind {
525; X86-LABEL: abd_minmax_i16:
526; X86:       # %bb.0:
527; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
528; X86-NEXT:    movzwl {{[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:    cmovael %edx, %eax
533; X86-NEXT:    # kill: def $ax killed $ax killed $eax
534; X86-NEXT:    retl
535;
536; X64-LABEL: abd_minmax_i16:
537; X64:       # %bb.0:
538; X64-NEXT:    movzwl %di, %ecx
539; X64-NEXT:    subl %esi, %edi
540; X64-NEXT:    movzwl %si, %eax
541; X64-NEXT:    subl %ecx, %eax
542; X64-NEXT:    cmovbl %edi, %eax
543; X64-NEXT:    negl %eax
544; X64-NEXT:    # kill: def $ax killed $ax killed $eax
545; X64-NEXT:    retq
546  %min = call i16 @llvm.umin.i16(i16 %a, i16 %b)
547  %max = call i16 @llvm.umax.i16(i16 %a, i16 %b)
548  %sub = sub i16 %min, %max
549  ret i16 %sub
550}
551
552define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind {
553; X86-LABEL: abd_minmax_i32:
554; X86:       # %bb.0:
555; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
556; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
557; X86-NEXT:    movl %ecx, %edx
558; X86-NEXT:    subl %eax, %edx
559; X86-NEXT:    subl %ecx, %eax
560; X86-NEXT:    cmovael %edx, %eax
561; X86-NEXT:    retl
562;
563; X64-LABEL: abd_minmax_i32:
564; X64:       # %bb.0:
565; X64-NEXT:    movl %edi, %eax
566; X64-NEXT:    subl %esi, %eax
567; X64-NEXT:    subl %edi, %esi
568; X64-NEXT:    cmovbl %esi, %eax
569; X64-NEXT:    retq
570  %min = call i32 @llvm.umin.i32(i32 %a, i32 %b)
571  %max = call i32 @llvm.umax.i32(i32 %a, i32 %b)
572  %sub = sub i32 %min, %max
573  ret i32 %sub
574}
575
576define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind {
577; X86-LABEL: abd_minmax_i64:
578; X86:       # %bb.0:
579; X86-NEXT:    pushl %ebp
580; X86-NEXT:    pushl %ebx
581; X86-NEXT:    pushl %edi
582; X86-NEXT:    pushl %esi
583; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
584; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
585; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
586; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
587; X86-NEXT:    cmpl %esi, %edi
588; X86-NEXT:    movl %ebx, %eax
589; X86-NEXT:    sbbl %ecx, %eax
590; X86-NEXT:    movl %ecx, %edx
591; X86-NEXT:    cmovbl %ebx, %edx
592; X86-NEXT:    movl %esi, %eax
593; X86-NEXT:    cmovbl %edi, %eax
594; X86-NEXT:    cmpl %edi, %esi
595; X86-NEXT:    movl %ecx, %ebp
596; X86-NEXT:    sbbl %ebx, %ebp
597; X86-NEXT:    cmovbl %ebx, %ecx
598; X86-NEXT:    cmovbl %edi, %esi
599; X86-NEXT:    subl %esi, %eax
600; X86-NEXT:    sbbl %ecx, %edx
601; X86-NEXT:    popl %esi
602; X86-NEXT:    popl %edi
603; X86-NEXT:    popl %ebx
604; X86-NEXT:    popl %ebp
605; X86-NEXT:    retl
606;
607; X64-LABEL: abd_minmax_i64:
608; X64:       # %bb.0:
609; X64-NEXT:    movq %rdi, %rax
610; X64-NEXT:    subq %rsi, %rax
611; X64-NEXT:    subq %rdi, %rsi
612; X64-NEXT:    cmovbq %rsi, %rax
613; X64-NEXT:    retq
614  %min = call i64 @llvm.umin.i64(i64 %a, i64 %b)
615  %max = call i64 @llvm.umax.i64(i64 %a, i64 %b)
616  %sub = sub i64 %min, %max
617  ret i64 %sub
618}
619
620define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind {
621; X86-LABEL: abd_minmax_i128:
622; X86:       # %bb.0:
623; X86-NEXT:    pushl %ebp
624; X86-NEXT:    pushl %ebx
625; X86-NEXT:    pushl %edi
626; X86-NEXT:    pushl %esi
627; X86-NEXT:    pushl %eax
628; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebp
629; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
630; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
631; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
632; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
633; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
634; X86-NEXT:    cmpl %eax, %esi
635; X86-NEXT:    sbbl %ebx, %ecx
636; X86-NEXT:    movl %edx, %ecx
637; X86-NEXT:    sbbl %ebp, %ecx
638; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
639; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
640; X86-NEXT:    movl %edx, %ecx
641; X86-NEXT:    sbbl %edi, %ecx
642; X86-NEXT:    movl %edi, %ecx
643; X86-NEXT:    cmovbl %edx, %ecx
644; X86-NEXT:    movl %ecx, (%esp) # 4-byte Spill
645; X86-NEXT:    cmovbl {{[0-9]+}}(%esp), %ebp
646; X86-NEXT:    movl %ebx, %ecx
647; X86-NEXT:    cmovbl {{[0-9]+}}(%esp), %ecx
648; X86-NEXT:    movl %eax, %edx
649; X86-NEXT:    cmovbl %esi, %edx
650; X86-NEXT:    cmpl %esi, %eax
651; X86-NEXT:    movl %ebx, %esi
652; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
653; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
654; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
655; X86-NEXT:    movl %edi, %esi
656; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
657; X86-NEXT:    cmovbl {{[0-9]+}}(%esp), %edi
658; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
659; X86-NEXT:    cmovbl {{[0-9]+}}(%esp), %esi
660; X86-NEXT:    cmovbl {{[0-9]+}}(%esp), %ebx
661; X86-NEXT:    cmovbl {{[0-9]+}}(%esp), %eax
662; X86-NEXT:    subl %eax, %edx
663; X86-NEXT:    sbbl %ebx, %ecx
664; X86-NEXT:    sbbl %esi, %ebp
665; X86-NEXT:    movl (%esp), %esi # 4-byte Reload
666; X86-NEXT:    sbbl %edi, %esi
667; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
668; X86-NEXT:    movl %edx, (%eax)
669; X86-NEXT:    movl %ecx, 4(%eax)
670; X86-NEXT:    movl %ebp, 8(%eax)
671; X86-NEXT:    movl %esi, 12(%eax)
672; X86-NEXT:    addl $4, %esp
673; X86-NEXT:    popl %esi
674; X86-NEXT:    popl %edi
675; X86-NEXT:    popl %ebx
676; X86-NEXT:    popl %ebp
677; X86-NEXT:    retl $4
678;
679; X64-LABEL: abd_minmax_i128:
680; X64:       # %bb.0:
681; X64-NEXT:    cmpq %rdx, %rdi
682; X64-NEXT:    movq %rsi, %rax
683; X64-NEXT:    sbbq %rcx, %rax
684; X64-NEXT:    movq %rcx, %r8
685; X64-NEXT:    cmovbq %rsi, %r8
686; X64-NEXT:    movq %rdx, %rax
687; X64-NEXT:    cmovbq %rdi, %rax
688; X64-NEXT:    cmpq %rdi, %rdx
689; X64-NEXT:    movq %rcx, %r9
690; X64-NEXT:    sbbq %rsi, %r9
691; X64-NEXT:    cmovbq %rsi, %rcx
692; X64-NEXT:    cmovbq %rdi, %rdx
693; X64-NEXT:    subq %rdx, %rax
694; X64-NEXT:    sbbq %rcx, %r8
695; X64-NEXT:    movq %r8, %rdx
696; X64-NEXT:    retq
697  %min = call i128 @llvm.umin.i128(i128 %a, i128 %b)
698  %max = call i128 @llvm.umax.i128(i128 %a, i128 %b)
699  %sub = sub i128 %min, %max
700  ret i128 %sub
701}
702
703;
704; select(icmp(a,b),sub(a,b),sub(b,a)) -> nabds(a,b)
705;
706
707define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind {
708; X86-LABEL: abd_cmp_i8:
709; X86:       # %bb.0:
710; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
711; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
712; X86-NEXT:    movl %ecx, %edx
713; X86-NEXT:    subl %eax, %edx
714; X86-NEXT:    subl %ecx, %eax
715; X86-NEXT:    cmovbl %edx, %eax
716; X86-NEXT:    negb %al
717; X86-NEXT:    # kill: def $al killed $al killed $eax
718; X86-NEXT:    retl
719;
720; X64-LABEL: abd_cmp_i8:
721; X64:       # %bb.0:
722; X64-NEXT:    movzbl %sil, %eax
723; X64-NEXT:    movzbl %dil, %ecx
724; X64-NEXT:    movl %ecx, %edx
725; X64-NEXT:    subl %eax, %edx
726; X64-NEXT:    subl %ecx, %eax
727; X64-NEXT:    cmovbl %edx, %eax
728; X64-NEXT:    negb %al
729; X64-NEXT:    # kill: def $al killed $al killed $eax
730; X64-NEXT:    retq
731  %cmp = icmp ule i8 %a, %b
732  %ab = sub i8 %a, %b
733  %ba = sub i8 %b, %a
734  %sel = select i1 %cmp, i8 %ab, i8 %ba
735  ret i8 %sel
736}
737
738define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind {
739; X86-LABEL: abd_cmp_i16:
740; X86:       # %bb.0:
741; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
742; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
743; X86-NEXT:    movl %ecx, %edx
744; X86-NEXT:    subl %eax, %edx
745; X86-NEXT:    subl %ecx, %eax
746; X86-NEXT:    cmovael %edx, %eax
747; X86-NEXT:    # kill: def $ax killed $ax killed $eax
748; X86-NEXT:    retl
749;
750; X64-LABEL: abd_cmp_i16:
751; X64:       # %bb.0:
752; X64-NEXT:    movzwl %di, %ecx
753; X64-NEXT:    subl %esi, %edi
754; X64-NEXT:    movzwl %si, %eax
755; X64-NEXT:    subl %ecx, %eax
756; X64-NEXT:    cmovbl %edi, %eax
757; X64-NEXT:    negl %eax
758; X64-NEXT:    # kill: def $ax killed $ax killed $eax
759; X64-NEXT:    retq
760  %cmp = icmp ult i16 %a, %b
761  %ab = sub i16 %a, %b
762  %ba = sub i16 %b, %a
763  %sel = select i1 %cmp, i16 %ab, i16 %ba
764  ret i16 %sel
765}
766
767define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind {
768; X86-LABEL: abd_cmp_i32:
769; X86:       # %bb.0:
770; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
771; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
772; X86-NEXT:    movl %ecx, %edx
773; X86-NEXT:    subl %eax, %edx
774; X86-NEXT:    subl %ecx, %eax
775; X86-NEXT:    cmovael %edx, %eax
776; X86-NEXT:    retl
777;
778; X64-LABEL: abd_cmp_i32:
779; X64:       # %bb.0:
780; X64-NEXT:    movl %edi, %eax
781; X64-NEXT:    subl %esi, %eax
782; X64-NEXT:    subl %edi, %esi
783; X64-NEXT:    cmovbl %esi, %eax
784; X64-NEXT:    retq
785  %cmp = icmp uge i32 %a, %b
786  %ab = sub i32 %a, %b
787  %ba = sub i32 %b, %a
788  %sel = select i1 %cmp, i32 %ba, i32 %ab
789  ret i32 %sel
790}
791
792define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind {
793; X86-LABEL: abd_cmp_i64:
794; X86:       # %bb.0:
795; X86-NEXT:    pushl %esi
796; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
797; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
798; X86-NEXT:    xorl %edx, %edx
799; X86-NEXT:    subl {{[0-9]+}}(%esp), %eax
800; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
801; X86-NEXT:    movl $0, %esi
802; X86-NEXT:    sbbl %esi, %esi
803; X86-NEXT:    xorl %esi, %ecx
804; X86-NEXT:    xorl %esi, %eax
805; X86-NEXT:    subl %esi, %eax
806; X86-NEXT:    sbbl %esi, %ecx
807; X86-NEXT:    negl %eax
808; X86-NEXT:    sbbl %ecx, %edx
809; X86-NEXT:    popl %esi
810; X86-NEXT:    retl
811;
812; X64-LABEL: abd_cmp_i64:
813; X64:       # %bb.0:
814; X64-NEXT:    movq %rdi, %rax
815; X64-NEXT:    subq %rsi, %rax
816; X64-NEXT:    subq %rdi, %rsi
817; X64-NEXT:    cmovbq %rsi, %rax
818; X64-NEXT:    retq
819  %cmp = icmp ult i64 %a, %b
820  %ab = sub i64 %a, %b
821  %ba = sub i64 %b, %a
822  %sel = select i1 %cmp, i64 %ab, i64 %ba
823  ret i64 %sel
824}
825
826define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind {
827; X86-LABEL: abd_cmp_i128:
828; X86:       # %bb.0:
829; X86-NEXT:    pushl %ebp
830; X86-NEXT:    pushl %ebx
831; X86-NEXT:    pushl %edi
832; X86-NEXT:    pushl %esi
833; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
834; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
835; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
836; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
837; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
838; X86-NEXT:    xorl %edi, %edi
839; X86-NEXT:    subl {{[0-9]+}}(%esp), %edx
840; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ebx
841; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %esi
842; X86-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx
843; X86-NEXT:    movl $0, %ebp
844; X86-NEXT:    sbbl %ebp, %ebp
845; X86-NEXT:    xorl %ebp, %ecx
846; X86-NEXT:    xorl %ebp, %esi
847; X86-NEXT:    xorl %ebp, %ebx
848; X86-NEXT:    xorl %ebp, %edx
849; X86-NEXT:    subl %ebp, %edx
850; X86-NEXT:    sbbl %ebp, %ebx
851; X86-NEXT:    sbbl %ebp, %esi
852; X86-NEXT:    sbbl %ebp, %ecx
853; X86-NEXT:    negl %edx
854; X86-NEXT:    movl $0, %ebp
855; X86-NEXT:    sbbl %ebx, %ebp
856; X86-NEXT:    movl $0, %ebx
857; X86-NEXT:    sbbl %esi, %ebx
858; X86-NEXT:    sbbl %ecx, %edi
859; X86-NEXT:    movl %edx, (%eax)
860; X86-NEXT:    movl %ebp, 4(%eax)
861; X86-NEXT:    movl %ebx, 8(%eax)
862; X86-NEXT:    movl %edi, 12(%eax)
863; X86-NEXT:    popl %esi
864; X86-NEXT:    popl %edi
865; X86-NEXT:    popl %ebx
866; X86-NEXT:    popl %ebp
867; X86-NEXT:    retl $4
868;
869; X64-LABEL: abd_cmp_i128:
870; X64:       # %bb.0:
871; X64-NEXT:    movq %rdi, %rax
872; X64-NEXT:    xorl %edi, %edi
873; X64-NEXT:    subq %rdx, %rax
874; X64-NEXT:    sbbq %rcx, %rsi
875; X64-NEXT:    movl $0, %ecx
876; X64-NEXT:    sbbq %rcx, %rcx
877; X64-NEXT:    xorq %rcx, %rsi
878; X64-NEXT:    xorq %rcx, %rax
879; X64-NEXT:    subq %rcx, %rax
880; X64-NEXT:    sbbq %rcx, %rsi
881; X64-NEXT:    negq %rax
882; X64-NEXT:    sbbq %rsi, %rdi
883; X64-NEXT:    movq %rdi, %rdx
884; X64-NEXT:    retq
885  %cmp = icmp ult i128 %a, %b
886  %ab = sub i128 %a, %b
887  %ba = sub i128 %b, %a
888  %sel = select i1 %cmp, i128 %ab, i128 %ba
889  ret i128 %sel
890}
891
892declare i8 @llvm.abs.i8(i8, i1)
893declare i16 @llvm.abs.i16(i16, i1)
894declare i32 @llvm.abs.i32(i32, i1)
895declare i64 @llvm.abs.i64(i64, i1)
896declare i128 @llvm.abs.i128(i128, i1)
897
898declare i8 @llvm.umax.i8(i8, i8)
899declare i16 @llvm.umax.i16(i16, i16)
900declare i32 @llvm.umax.i32(i32, i32)
901declare i64 @llvm.umax.i64(i64, i64)
902
903declare i8 @llvm.umin.i8(i8, i8)
904declare i16 @llvm.umin.i16(i16, i16)
905declare i32 @llvm.umin.i32(i32, i32)
906declare i64 @llvm.umin.i64(i64, i64)
907