AMDGPU/SI: Consolidate FLAT patterns
[oota-llvm.git] / test / CodeGen / X86 / materialize.ll
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
4
5 define i32 @one32_nooptsize() {
6 entry:
7   ret i32 1
8
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
16 }
17
18 define i32 @one32() optsize {
19 entry:
20   ret i32 1
21
22 ; CHECK32-LABEL: one32:
23 ; CHECK32:       xorl %eax, %eax
24 ; CHECK32-NEXT:  incl %eax
25 ; CHECK32-NEXT:  retl
26
27 ; FIXME: Figure out the best approach in 64-bit mode.
28 ; CHECK64-LABEL: one32:
29 ; CHECK64:       movl $1, %eax
30 ; CHECK64-NEXT:  retq
31 }
32
33 define i32 @one32_minsize() minsize {
34 entry:
35   ret i32 1
36
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
42
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
51 }
52
53 define i64 @one64_minsize() minsize {
54 entry:
55   ret i64 1
56 ; On 64-bit we don't do xor-inc yet, so push-pop it is.
57 ; CHECK64-LABEL: one64_minsize:
58 ; CHECK64:       pushq $1
59 ; CHECK64:       .cfi_adjust_cfa_offset 8
60 ; CHECK64:       popq %rax
61 ; CHECK64:       .cfi_adjust_cfa_offset -8
62 ; CHECK64-NEXT:  retq
63
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
68 }
69
70 define i32 @minus_one32() optsize {
71 entry:
72   ret i32 -1
73
74 ; CHECK32-LABEL: minus_one32:
75 ; CHECK32:       xorl %eax, %eax
76 ; CHECK32-NEXT:  decl %eax
77 ; CHECK32-NEXT:  retl
78 }
79
80 define i32 @minus_one32_minsize() minsize {
81 entry:
82   ret i32 -1
83
84 ; xor-dec is preferred over push-pop.
85 ; CHECK32-LABEL: minus_one32_minsize:
86 ; CHECK32:       xorl %eax, %eax
87 ; CHECK32-NEXT:  decl %eax
88 ; CHECK32-NEXT:  retl
89 }
90
91 define i16 @one16() optsize {
92 entry:
93   ret i16 1
94
95 ; CHECK32-LABEL: one16:
96 ; CHECK32:       xorl %eax, %eax
97 ; CHECK32-NEXT:  incl %eax
98 ; CHECK32-NEXT:  retl
99 }
100
101 define i16 @minus_one16() optsize {
102 entry:
103   ret i16 -1
104
105 ; CHECK32-LABEL: minus_one16:
106 ; CHECK32:       xorl %eax, %eax
107 ; CHECK32-NEXT:  decl %eax
108 ; CHECK32-NEXT:  retl
109 }
110
111 define i32 @minus_five32() minsize {
112 entry:
113   ret i32 -5
114
115 ; CHECK32-LABEL: minus_five32:
116 ; CHECK32: pushl $-5
117 ; CHECK32: popl %eax
118 ; CHECK32: retl
119 }
120
121 define i64 @minus_five64() minsize {
122 entry:
123   ret i64 -5
124
125 ; CHECK64-LABEL: minus_five64:
126 ; CHECK64: pushq $-5
127 ; CHECK64:       .cfi_adjust_cfa_offset 8
128 ; CHECK64: popq %rax
129 ; CHECK64:       .cfi_adjust_cfa_offset -8
130 ; CHECK64: retq
131 }
132
133 define i32 @rematerialize_minus_one() optsize {
134 entry:
135   ; Materialize -1 (thiscall forces it into %ecx).
136   tail call x86_thiscallcc void @f(i32 -1)
137
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}"()
141
142   ; -1 should be re-materialized here instead of getting spilled above.
143   ret i32 -1
144
145 ; CHECK32-LABEL: rematerialize_minus_one
146 ; CHECK32:       xorl %ecx, %ecx
147 ; CHECK32-NEXT:  decl %ecx
148 ; CHECK32:       calll
149 ; CHECK32:       xorl %eax, %eax
150 ; CHECK32-NEXT:  decl %eax
151 ; CHECK32-NOT:   %eax
152 ; CHECK32:       retl
153 }
154
155 define i32 @rematerialize_minus_one_eflags(i32 %x) optsize {
156 entry:
157   ; Materialize -1 (thiscall forces it into %ecx).
158   tail call x86_thiscallcc void @f(i32 -1)
159
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}"()
163
164   ; Define eflags.
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
170   ret i32 %c
171
172 ; CHECK32-LABEL: rematerialize_minus_one_eflags
173 ; CHECK32:       xorl %ecx, %ecx
174 ; CHECK32-NEXT:  decl %ecx
175 ; CHECK32:       calll
176 ; CHECK32:       cmpl
177 ; CHECK32:       setne
178 ; CHECK32-NOT:   xorl
179 ; CHECK32:       movl $-1
180 ; CHECK32:       cmov
181 ; CHECK32:       retl
182 }
183
184 declare x86_thiscallcc void @f(i32)