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
52 ; On Win64 we can't adjust the stack unless there's a frame pointer.
53 ; CHECKWIN64-LABEL: one32_minsize:
54 ; CHECKWIN64: movl $1, %eax
55 ; CHECKWIN64-NEXT: retq
58 define i32 @pr26023() minsize {
60 %x = alloca [120 x i8]
61 %0 = getelementptr inbounds [120 x i8], [120 x i8]* %x, i64 0, i64 0
62 call void asm sideeffect "", "imr,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %0)
63 %arrayidx = getelementptr inbounds [120 x i8], [120 x i8]* %x, i64 0, i64 119
64 store volatile i8 -2, i8* %arrayidx
65 call void asm sideeffect "", "r,~{dirflag},~{fpsr},~{flags}"(i32 5)
66 %1 = load volatile i8, i8* %arrayidx
67 %conv = sext i8 %1 to i32
70 ; The function writes to the redzone, so push/pop cannot be used.
71 ; CHECK64-LABEL: pr26023:
72 ; CHECK64: movl $5, %ecx
75 ; 32-bit X86 doesn't have a redzone.
76 ; CHECK32-LABEL: pr26023:
83 define i64 @one64_minsize() minsize {
86 ; On 64-bit we don't do xor-inc yet, so push-pop it is.
87 ; CHECK64-LABEL: one64_minsize:
89 ; CHECK64: .cfi_adjust_cfa_offset 8
91 ; CHECK64: .cfi_adjust_cfa_offset -8
94 ; On Win64 we can't adjust the stack unless there's a frame pointer.
95 ; CHECKWIN64-LABEL: one64_minsize:
96 ; CHECKWIN64: movl $1, %eax
97 ; CHECKWIN64-NEXT: retq
100 define i32 @minus_one32() optsize {
104 ; CHECK32-LABEL: minus_one32:
105 ; CHECK32: xorl %eax, %eax
106 ; CHECK32-NEXT: decl %eax
110 define i32 @minus_one32_minsize() minsize {
114 ; xor-dec is preferred over push-pop.
115 ; CHECK32-LABEL: minus_one32_minsize:
116 ; CHECK32: xorl %eax, %eax
117 ; CHECK32-NEXT: decl %eax
121 define i16 @one16() optsize {
125 ; CHECK32-LABEL: one16:
126 ; CHECK32: xorl %eax, %eax
127 ; CHECK32-NEXT: incl %eax
128 ; CHECK32-NEXT: # kill
132 define i16 @minus_one16() optsize {
136 ; CHECK32-LABEL: minus_one16:
137 ; CHECK32: xorl %eax, %eax
138 ; CHECK32-NEXT: decl %eax
139 ; CHECK32-NEXT: # kill
143 define i32 @minus_five32() minsize {
147 ; CHECK32-LABEL: minus_five32:
153 define i64 @minus_five64() minsize {
157 ; CHECK64-LABEL: minus_five64:
159 ; CHECK64: .cfi_adjust_cfa_offset 8
161 ; CHECK64: .cfi_adjust_cfa_offset -8
165 define i32 @rematerialize_minus_one() optsize {
167 ; Materialize -1 (thiscall forces it into %ecx).
168 tail call x86_thiscallcc void @f(i32 -1)
170 ; Clobber all registers except %esp, leaving nowhere to store the -1 besides
171 ; spilling it to the stack.
172 tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()
174 ; -1 should be re-materialized here instead of getting spilled above.
177 ; CHECK32-LABEL: rematerialize_minus_one
178 ; CHECK32: xorl %ecx, %ecx
179 ; CHECK32-NEXT: decl %ecx
181 ; CHECK32: xorl %eax, %eax
182 ; CHECK32-NEXT: decl %eax
187 define i32 @rematerialize_minus_one_eflags(i32 %x) optsize {
189 ; Materialize -1 (thiscall forces it into %ecx).
190 tail call x86_thiscallcc void @f(i32 -1)
192 ; Clobber all registers except %esp, leaving nowhere to store the -1 besides
193 ; spilling it to the stack.
194 tail call void asm sideeffect "", "~{eax},~{ebx},~{ecx},~{edx},~{edi},~{esi},~{ebp},~{dirflag},~{fpsr},~{flags}"()
197 %a = icmp ne i32 %x, 123
198 %b = zext i1 %a to i32
199 ; Cause -1 to be rematerialized right in front of the cmov, which needs eflags.
200 ; It must therefore not use the xor-dec lowering.
201 %c = select i1 %a, i32 %b, i32 -1
204 ; CHECK32-LABEL: rematerialize_minus_one_eflags
205 ; CHECK32: xorl %ecx, %ecx
206 ; CHECK32-NEXT: decl %ecx
216 declare x86_thiscallcc void @f(i32)