[Alignment][NFC] Use Align with TargetLowering::setMinFunctionAlignment
[llvm-core.git] / test / CodeGen / X86 / materialize.ll
blob6e1264b4fd43e0e9ab856efd65cdd061a9699e82
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() {
6 entry:
7   ret i32 1
9 ; When not optimizing for size, use mov.
10 ; CHECK32-LABEL: one32_nooptsize:
11 ; CHECK32:       movl $1, %eax
12 ; CHECK32-NEXT:  retl
13 ; CHECK64-LABEL: one32_nooptsize:
14 ; CHECK64:       movl $1, %eax
15 ; CHECK64-NEXT:  retq
18 define i32 @one32() optsize {
19 entry:
20   ret i32 1
22 ; CHECK32-LABEL: one32:
23 ; CHECK32:       xorl %eax, %eax
24 ; CHECK32-NEXT:  incl %eax
25 ; CHECK32-NEXT:  retl
27 ; FIXME: Figure out the best approach in 64-bit mode.
28 ; CHECK64-LABEL: one32:
29 ; CHECK64:       movl $1, %eax
30 ; CHECK64-NEXT:  retq
33 define i32 @one32_minsize() minsize {
34 entry:
35   ret i32 1
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
41 ; CHECK32-NEXT:  retl
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:
46 ; CHECK64:       pushq $1
47 ; CHECK64:       .cfi_adjust_cfa_offset 8
48 ; CHECK64:       popq %rax
49 ; CHECK64:       .cfi_adjust_cfa_offset -8
50 ; CHECK64-NEXT:  retq
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 {
59 entry:
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
68   ret i32 %conv
70 ; The function writes to the redzone, so push/pop cannot be used.
71 ; CHECK64-LABEL: pr26023:
72 ; CHECK64:       movl $5, %ecx
73 ; CHECK64:       retq
75 ; 32-bit X86 doesn't have a redzone.
76 ; CHECK32-LABEL: pr26023:
77 ; CHECK32:       pushl $5
78 ; CHECK32:       popl %ecx
79 ; CHECK32:       retl
83 define i64 @one64_minsize() minsize {
84 entry:
85   ret i64 1
86 ; On 64-bit we don't do xor-inc yet, so push-pop it is.
87 ; CHECK64-LABEL: one64_minsize:
88 ; CHECK64:       pushq $1
89 ; CHECK64:       .cfi_adjust_cfa_offset 8
90 ; CHECK64:       popq %rax
91 ; CHECK64:       .cfi_adjust_cfa_offset -8
92 ; CHECK64-NEXT:  retq
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 {
101 entry:
102   ret i32 -1
104 ; CHECK32-LABEL: minus_one32:
105 ; CHECK32:       xorl %eax, %eax
106 ; CHECK32-NEXT:  decl %eax
107 ; CHECK32-NEXT:  retl
110 define i32 @minus_one32_minsize() minsize {
111 entry:
112   ret i32 -1
114 ; xor-dec is preferred over push-pop.
115 ; CHECK32-LABEL: minus_one32_minsize:
116 ; CHECK32:       xorl %eax, %eax
117 ; CHECK32-NEXT:  decl %eax
118 ; CHECK32-NEXT:  retl
121 define i16 @one16() optsize {
122 entry:
123   ret i16 1
125 ; CHECK32-LABEL: one16:
126 ; CHECK32:       xorl %eax, %eax
127 ; CHECK32-NEXT:  incl %eax
128 ; CHECK32-NEXT:  # kill
129 ; CHECK32-NEXT:  retl
132 define i16 @minus_one16() optsize {
133 entry:
134   ret i16 -1
136 ; CHECK32-LABEL: minus_one16:
137 ; CHECK32:       xorl %eax, %eax
138 ; CHECK32-NEXT:  decl %eax
139 ; CHECK32-NEXT:  # kill
140 ; CHECK32-NEXT:  retl
143 define i32 @minus_five32() minsize {
144 entry:
145   ret i32 -5
147 ; CHECK32-LABEL: minus_five32:
148 ; CHECK32: pushl $-5
149 ; CHECK32: popl %eax
150 ; CHECK32: retl
153 define i64 @minus_five64() minsize {
154 entry:
155   ret i64 -5
157 ; CHECK64-LABEL: minus_five64:
158 ; CHECK64: pushq $-5
159 ; CHECK64:       .cfi_adjust_cfa_offset 8
160 ; CHECK64: popq %rax
161 ; CHECK64:       .cfi_adjust_cfa_offset -8
162 ; CHECK64: retq
165 define i32 @rematerialize_minus_one() optsize {
166 entry:
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.
175   ret i32 -1
177 ; CHECK32-LABEL: rematerialize_minus_one
178 ; CHECK32:       xorl %ecx, %ecx
179 ; CHECK32-NEXT:  decl %ecx
180 ; CHECK32:       calll
181 ; CHECK32:       xorl %eax, %eax
182 ; CHECK32-NEXT:  decl %eax
183 ; CHECK32-NOT:   %eax
184 ; CHECK32:       retl
187 define i32 @rematerialize_minus_one_eflags(i32 %x) optsize {
188 entry:
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}"()
196   ; Define eflags.
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
202   ret i32 %c
204 ; CHECK32-LABEL: rematerialize_minus_one_eflags
205 ; CHECK32:       xorl %ecx, %ecx
206 ; CHECK32-NEXT:  decl %ecx
207 ; CHECK32:       calll
208 ; CHECK32:       cmpl
209 ; CHECK32:       setne
210 ; CHECK32-NOT:   xorl
211 ; CHECK32:       movl $-1
212 ; CHECK32:       cmov
213 ; CHECK32:       retl
216 declare x86_thiscallcc void @f(i32)