1 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK32
2 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECK64
3 ; RUN: llc -mtriple=x86_64-pc-win32 -mattr=+cmov %s -o - | FileCheck %s --check-prefix=CHECKWIN64
5 define i32 @one32_nooptsize() {
9 ; When not optimizing for size, use mov.
10 ; CHECK32-LABEL: one32_nooptsize:
11 ; CHECK32: movl $1, %eax
13 ; CHECK64-LABEL: one32_nooptsize:
14 ; CHECK64: movl $1, %eax
18 define i32 @one32() optsize {
22 ; CHECK32-LABEL: one32:
23 ; CHECK32: xorl %eax, %eax
24 ; CHECK32-NEXT: incl %eax
27 ; FIXME: Figure out the best approach in 64-bit mode.
28 ; CHECK64-LABEL: one32:
29 ; CHECK64: movl $1, %eax
33 define i32 @one32_minsize() minsize {
37 ; On 32-bit, xor-inc is preferred over push-pop.
38 ; CHECK32-LABEL: one32_minsize:
39 ; CHECK32: xorl %eax, %eax
40 ; CHECK32-NEXT: incl %eax
43 ; On 64-bit we don't do xor-inc yet, so push-pop it is. Note that we have to
44 ; pop into a 64-bit register even when we just need 32 bits.
45 ; CHECK64-LABEL: one32_minsize:
47 ; CHECK64: .cfi_adjust_cfa_offset 8
49 ; CHECK64: .cfi_adjust_cfa_offset -8
53 define i64 @one64_minsize() minsize {
56 ; On 64-bit we don't do xor-inc yet, so push-pop it is.
57 ; CHECK64-LABEL: one64_minsize:
59 ; CHECK64: .cfi_adjust_cfa_offset 8
61 ; CHECK64: .cfi_adjust_cfa_offset -8
64 ; On Win64 we can't adjust the stack unless there's a frame pointer.
65 ; CHECKWIN64-LABEL: one64_minsize:
66 ; CHECKWIN64: movl $1, %eax
67 ; CHECKWIN64-NEXT: retq
70 define i32 @minus_one32() optsize {
74 ; CHECK32-LABEL: minus_one32:
75 ; CHECK32: xorl %eax, %eax
76 ; CHECK32-NEXT: decl %eax
80 define i32 @minus_one32_minsize() minsize {
84 ; xor-dec is preferred over push-pop.
85 ; CHECK32-LABEL: minus_one32_minsize:
86 ; CHECK32: xorl %eax, %eax
87 ; CHECK32-NEXT: decl %eax
91 define i16 @one16() optsize {
95 ; CHECK32-LABEL: one16:
96 ; CHECK32: xorl %eax, %eax
97 ; CHECK32-NEXT: incl %eax
101 define i16 @minus_one16() optsize {
105 ; CHECK32-LABEL: minus_one16:
106 ; CHECK32: xorl %eax, %eax
107 ; CHECK32-NEXT: decl %eax
111 define i32 @minus_five32() minsize {
115 ; CHECK32-LABEL: minus_five32:
121 define i64 @minus_five64() minsize {
125 ; CHECK64-LABEL: minus_five64:
127 ; CHECK64: .cfi_adjust_cfa_offset 8
129 ; CHECK64: .cfi_adjust_cfa_offset -8
133 define i32 @rematerialize_minus_one() optsize {
135 ; Materialize -1 (thiscall forces it into %ecx).
136 tail call x86_thiscallcc void @f(i32 -1)
138 ; Clobber all registers except %esp, leaving nowhere to store the -1 besides
139 ; spilling it to the stack.
140 tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()
142 ; -1 should be re-materialized here instead of getting spilled above.
145 ; CHECK32-LABEL: rematerialize_minus_one
146 ; CHECK32: xorl %ecx, %ecx
147 ; CHECK32-NEXT: decl %ecx
149 ; CHECK32: xorl %eax, %eax
150 ; CHECK32-NEXT: decl %eax
155 define i32 @rematerialize_minus_one_eflags(i32 %x) optsize {
157 ; Materialize -1 (thiscall forces it into %ecx).
158 tail call x86_thiscallcc void @f(i32 -1)
160 ; Clobber all registers except %esp, leaving nowhere to store the -1 besides
161 ; spilling it to the stack.
162 tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()
165 %a = icmp ne i32 %x, 123
166 %b = zext i1 %a to i32
167 ; Cause -1 to be rematerialized right in front of the cmov, which needs eflags.
168 ; It must therefore not use the xor-dec lowering.
169 %c = select i1 %a, i32 %b, i32 -1
172 ; CHECK32-LABEL: rematerialize_minus_one_eflags
173 ; CHECK32: xorl %ecx, %ecx
174 ; CHECK32-NEXT: decl %ecx
184 declare x86_thiscallcc void @f(i32)