1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X86 --check-prefix=X86-NO-CMOV
3; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+cmov | FileCheck %s --check-prefix=X86 --check-prefix=X86-CMOV
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64
5
6;; Integer absolute value, should produce something at least as good as:
7;;       movl   %edi, %eax
8;;       negl   %eax
9;;       cmovll %edi, %eax
10;;       ret
11; rdar://10695237
12define i8 @test_i8(i8 %a) nounwind {
13; X86-LABEL: test_i8:
14; X86:       # %bb.0:
15; X86-NEXT:    movb {{[0-9]+}}(%esp), %al
16; X86-NEXT:    movl %eax, %ecx
17; X86-NEXT:    sarb $7, %cl
18; X86-NEXT:    addb %cl, %al
19; X86-NEXT:    xorb %cl, %al
20; X86-NEXT:    retl
21;
22; X64-LABEL: test_i8:
23; X64:       # %bb.0:
24; X64-NEXT:    # kill: def $edi killed $edi def $rdi
25; X64-NEXT:    movl %edi, %ecx
26; X64-NEXT:    sarb $7, %cl
27; X64-NEXT:    leal (%rdi,%rcx), %eax
28; X64-NEXT:    xorb %cl, %al
29; X64-NEXT:    # kill: def $al killed $al killed $eax
30; X64-NEXT:    retq
31  %tmp1neg = sub i8 0, %a
32  %b = icmp sgt i8 %a, -1
33  %abs = select i1 %b, i8 %a, i8 %tmp1neg
34  ret i8 %abs
35}
36
37define i16 @test_i16(i16 %a) nounwind {
38; X86-NO-CMOV-LABEL: test_i16:
39; X86-NO-CMOV:       # %bb.0:
40; X86-NO-CMOV-NEXT:    movswl {{[0-9]+}}(%esp), %eax
41; X86-NO-CMOV-NEXT:    movl %eax, %ecx
42; X86-NO-CMOV-NEXT:    sarl $15, %ecx
43; X86-NO-CMOV-NEXT:    addl %ecx, %eax
44; X86-NO-CMOV-NEXT:    xorl %ecx, %eax
45; X86-NO-CMOV-NEXT:    # kill: def $ax killed $ax killed $eax
46; X86-NO-CMOV-NEXT:    retl
47;
48; X86-CMOV-LABEL: test_i16:
49; X86-CMOV:       # %bb.0:
50; X86-CMOV-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
51; X86-CMOV-NEXT:    movl %ecx, %eax
52; X86-CMOV-NEXT:    negw %ax
53; X86-CMOV-NEXT:    cmovlw %cx, %ax
54; X86-CMOV-NEXT:    retl
55;
56; X64-LABEL: test_i16:
57; X64:       # %bb.0:
58; X64-NEXT:    movl %edi, %eax
59; X64-NEXT:    negw %ax
60; X64-NEXT:    cmovlw %di, %ax
61; X64-NEXT:    retq
62  %tmp1neg = sub i16 0, %a
63  %b = icmp sgt i16 %a, -1
64  %abs = select i1 %b, i16 %a, i16 %tmp1neg
65  ret i16 %abs
66}
67
68define i32 @test_i32(i32 %a) nounwind {
69; X86-NO-CMOV-LABEL: test_i32:
70; X86-NO-CMOV:       # %bb.0:
71; X86-NO-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
72; X86-NO-CMOV-NEXT:    movl %eax, %ecx
73; X86-NO-CMOV-NEXT:    sarl $31, %ecx
74; X86-NO-CMOV-NEXT:    addl %ecx, %eax
75; X86-NO-CMOV-NEXT:    xorl %ecx, %eax
76; X86-NO-CMOV-NEXT:    retl
77;
78; X86-CMOV-LABEL: test_i32:
79; X86-CMOV:       # %bb.0:
80; X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
81; X86-CMOV-NEXT:    movl %ecx, %eax
82; X86-CMOV-NEXT:    negl %eax
83; X86-CMOV-NEXT:    cmovll %ecx, %eax
84; X86-CMOV-NEXT:    retl
85;
86; X64-LABEL: test_i32:
87; X64:       # %bb.0:
88; X64-NEXT:    movl %edi, %eax
89; X64-NEXT:    negl %eax
90; X64-NEXT:    cmovll %edi, %eax
91; X64-NEXT:    retq
92  %tmp1neg = sub i32 0, %a
93  %b = icmp sgt i32 %a, -1
94  %abs = select i1 %b, i32 %a, i32 %tmp1neg
95  ret i32 %abs
96}
97
98define i64 @test_i64(i64 %a) nounwind {
99; X86-LABEL: test_i64:
100; X86:       # %bb.0:
101; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
102; X86-NEXT:    movl %edx, %ecx
103; X86-NEXT:    sarl $31, %ecx
104; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
105; X86-NEXT:    addl %ecx, %eax
106; X86-NEXT:    adcl %ecx, %edx
107; X86-NEXT:    xorl %ecx, %edx
108; X86-NEXT:    xorl %ecx, %eax
109; X86-NEXT:    retl
110;
111; X64-LABEL: test_i64:
112; X64:       # %bb.0:
113; X64-NEXT:    movq %rdi, %rax
114; X64-NEXT:    negq %rax
115; X64-NEXT:    cmovlq %rdi, %rax
116; X64-NEXT:    retq
117  %tmp1neg = sub i64 0, %a
118  %b = icmp sgt i64 %a, -1
119  %abs = select i1 %b, i64 %a, i64 %tmp1neg
120  ret i64 %abs
121}
122
123define i128 @test_i128(i128 %a) nounwind {
124; X86-LABEL: test_i128:
125; X86:       # %bb.0:
126; X86-NEXT:    pushl %ebx
127; X86-NEXT:    pushl %edi
128; X86-NEXT:    pushl %esi
129; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
130; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
131; X86-NEXT:    movl %ecx, %edx
132; X86-NEXT:    sarl $31, %edx
133; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
134; X86-NEXT:    addl %edx, %esi
135; X86-NEXT:    movl {{[0-9]+}}(%esp), %edi
136; X86-NEXT:    adcl %edx, %edi
137; X86-NEXT:    movl {{[0-9]+}}(%esp), %ebx
138; X86-NEXT:    adcl %edx, %ebx
139; X86-NEXT:    adcl %edx, %ecx
140; X86-NEXT:    xorl %edx, %ecx
141; X86-NEXT:    xorl %edx, %ebx
142; X86-NEXT:    xorl %edx, %edi
143; X86-NEXT:    xorl %edx, %esi
144; X86-NEXT:    movl %esi, (%eax)
145; X86-NEXT:    movl %edi, 4(%eax)
146; X86-NEXT:    movl %ebx, 8(%eax)
147; X86-NEXT:    movl %ecx, 12(%eax)
148; X86-NEXT:    popl %esi
149; X86-NEXT:    popl %edi
150; X86-NEXT:    popl %ebx
151; X86-NEXT:    retl $4
152;
153; X64-LABEL: test_i128:
154; X64:       # %bb.0:
155; X64-NEXT:    movq %rsi, %rdx
156; X64-NEXT:    movq %rdi, %rax
157; X64-NEXT:    movq %rsi, %rcx
158; X64-NEXT:    sarq $63, %rcx
159; X64-NEXT:    addq %rcx, %rax
160; X64-NEXT:    adcq %rcx, %rdx
161; X64-NEXT:    xorq %rcx, %rax
162; X64-NEXT:    xorq %rcx, %rdx
163; X64-NEXT:    retq
164  %tmp1neg = sub i128 0, %a
165  %b = icmp sgt i128 %a, -1
166  %abs = select i1 %b, i128 %a, i128 %tmp1neg
167  ret i128 %abs
168}
169
170