Merging r261039:
[oota-llvm.git] / test / CodeGen / X86 / movtopush.ll
1 ; RUN: llc < %s -mtriple=i686-windows | FileCheck %s -check-prefix=NORMAL
2 ; RUN: llc < %s -mtriple=x86_64-windows | FileCheck %s -check-prefix=X64
3 ; RUN: llc < %s -mtriple=i686-windows -stackrealign -stack-alignment=32 | FileCheck %s -check-prefix=ALIGNED
4
5 %class.Class = type { i32 }
6 %struct.s = type { i64 }
7
8 declare void @good(i32 %a, i32 %b, i32 %c, i32 %d)
9 declare void @inreg(i32 %a, i32 inreg %b, i32 %c, i32 %d)
10 declare x86_thiscallcc void @thiscall(%class.Class* %class, i32 %a, i32 %b, i32 %c, i32 %d)
11 declare void @oneparam(i32 %a)
12 declare void @eightparams(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h)
13 declare void @struct(%struct.s* byval %a, i32 %b, i32 %c, i32 %d)
14
15 ; Here, we should have a reserved frame, so we don't expect pushes
16 ; NORMAL-LABEL: test1:
17 ; NORMAL: subl    $16, %esp
18 ; NORMAL-NEXT: movl    $4, 12(%esp)
19 ; NORMAL-NEXT: movl    $3, 8(%esp)
20 ; NORMAL-NEXT: movl    $2, 4(%esp)
21 ; NORMAL-NEXT: movl    $1, (%esp)
22 ; NORMAL-NEXT: call
23 ; NORMAL-NEXT: addl $16, %esp
24 define void @test1() {
25 entry:
26   call void @good(i32 1, i32 2, i32 3, i32 4)
27   ret void
28 }
29
30 ; We're optimizing for code size, so we should get pushes for x86,
31 ; even though there is a reserved call frame.
32 ; Make sure we don't touch x86-64
33 ; NORMAL-LABEL: test1b:
34 ; NORMAL-NOT: subl {{.*}} %esp
35 ; NORMAL: pushl   $4
36 ; NORMAL-NEXT: pushl   $3
37 ; NORMAL-NEXT: pushl   $2
38 ; NORMAL-NEXT: pushl   $1
39 ; NORMAL-NEXT: call
40 ; NORMAL-NEXT: addl $16, %esp
41 ; X64-LABEL: test1b:
42 ; X64: movl    $1, %ecx
43 ; X64-NEXT: movl    $2, %edx
44 ; X64-NEXT: movl    $3, %r8d
45 ; X64-NEXT: movl    $4, %r9d
46 ; X64-NEXT: callq   good
47 define void @test1b() optsize {
48 entry:
49   call void @good(i32 1, i32 2, i32 3, i32 4)
50   ret void
51 }
52
53 ; Same as above, but for minsize
54 ; NORMAL-LABEL: test1c:
55 ; NORMAL-NOT: subl {{.*}} %esp
56 ; NORMAL: pushl   $4
57 ; NORMAL-NEXT: pushl   $3
58 ; NORMAL-NEXT: pushl   $2
59 ; NORMAL-NEXT: pushl   $1
60 ; NORMAL-NEXT: call
61 ; NORMAL-NEXT: addl $16, %esp
62 define void @test1c() minsize {
63 entry:
64   call void @good(i32 1, i32 2, i32 3, i32 4)
65   ret void
66 }
67
68 ; If we have a reserved frame, we should have pushes
69 ; NORMAL-LABEL: test2:
70 ; NORMAL-NOT: subl {{.*}} %esp
71 ; NORMAL: pushl   $4
72 ; NORMAL-NEXT: pushl   $3
73 ; NORMAL-NEXT: pushl   $2
74 ; NORMAL-NEXT: pushl   $1
75 ; NORMAL-NEXT: call
76 define void @test2(i32 %k) {
77 entry:
78   %a = alloca i32, i32 %k
79   call void @good(i32 1, i32 2, i32 3, i32 4)
80   ret void
81 }
82
83 ; Again, we expect a sequence of 4 immediate pushes
84 ; Checks that we generate the right pushes for >8bit immediates
85 ; NORMAL-LABEL: test2b:
86 ; NORMAL-NOT: subl {{.*}} %esp
87 ; NORMAL: pushl   $4096
88 ; NORMAL-NEXT: pushl   $3072
89 ; NORMAL-NEXT: pushl   $2048
90 ; NORMAL-NEXT: pushl   $1024
91 ; NORMAL-NEXT: call
92 ; NORMAL-NEXT: addl $16, %esp
93 define void @test2b() optsize {
94 entry:
95   call void @good(i32 1024, i32 2048, i32 3072, i32 4096)
96   ret void
97 }
98
99 ; The first push should push a register
100 ; NORMAL-LABEL: test3:
101 ; NORMAL-NOT: subl {{.*}} %esp
102 ; NORMAL: pushl   $4
103 ; NORMAL-NEXT: pushl   $3
104 ; NORMAL-NEXT: pushl   $2
105 ; NORMAL-NEXT: pushl   %e{{..}}
106 ; NORMAL-NEXT: call
107 ; NORMAL-NEXT: addl $16, %esp
108 define void @test3(i32 %k) optsize {
109 entry:
110   %f = add i32 %k, 1
111   call void @good(i32 %f, i32 2, i32 3, i32 4)
112   ret void
113 }
114
115 ; We support weird calling conventions
116 ; NORMAL-LABEL: test4:
117 ; NORMAL: movl    $2, %eax
118 ; NORMAL-NEXT: pushl   $4
119 ; NORMAL-NEXT: pushl   $3
120 ; NORMAL-NEXT: pushl   $1
121 ; NORMAL-NEXT: call
122 ; NORMAL-NEXT: addl $12, %esp
123 define void @test4() optsize {
124 entry:
125   call void @inreg(i32 1, i32 2, i32 3, i32 4)
126   ret void
127 }
128
129 ; NORMAL-LABEL: test4b:
130 ; NORMAL: movl 4(%esp), %ecx
131 ; NORMAL-NEXT: pushl   $4
132 ; NORMAL-NEXT: pushl   $3
133 ; NORMAL-NEXT: pushl   $2
134 ; NORMAL-NEXT: pushl   $1
135 ; NORMAL-NEXT: call
136 ; NORMAL-NEXT: ret
137 define void @test4b(%class.Class* %f) optsize {
138 entry:
139   call x86_thiscallcc void @thiscall(%class.Class* %f, i32 1, i32 2, i32 3, i32 4)
140   ret void
141 }
142
143 ; When there is no reserved call frame, check that additional alignment
144 ; is added when the pushes don't add up to the required alignment.
145 ; ALIGNED-LABEL: test5:
146 ; ALIGNED: subl    $16, %esp
147 ; ALIGNED-NEXT: pushl   $4
148 ; ALIGNED-NEXT: pushl   $3
149 ; ALIGNED-NEXT: pushl   $2
150 ; ALIGNED-NEXT: pushl   $1
151 ; ALIGNED-NEXT: call
152 define void @test5(i32 %k) {
153 entry:
154   %a = alloca i32, i32 %k
155   call void @good(i32 1, i32 2, i32 3, i32 4)
156   ret void
157 }
158
159 ; When the alignment adds up, do the transformation
160 ; ALIGNED-LABEL: test5b:
161 ; ALIGNED: pushl   $8
162 ; ALIGNED-NEXT: pushl   $7
163 ; ALIGNED-NEXT: pushl   $6
164 ; ALIGNED-NEXT: pushl   $5
165 ; ALIGNED-NEXT: pushl   $4
166 ; ALIGNED-NEXT: pushl   $3
167 ; ALIGNED-NEXT: pushl   $2
168 ; ALIGNED-NEXT: pushl   $1
169 ; ALIGNED-NEXT: call
170 define void @test5b() optsize {
171 entry:
172   call void @eightparams(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8)
173   ret void
174 }
175
176 ; When having to compensate for the alignment isn't worth it,
177 ; don't use pushes.
178 ; ALIGNED-LABEL: test5c:
179 ; ALIGNED: movl $1, (%esp)
180 ; ALIGNED-NEXT: call
181 define void @test5c() optsize {
182 entry:
183   call void @oneparam(i32 1)
184   ret void
185 }
186
187 ; Check that pushing the addresses of globals (Or generally, things that 
188 ; aren't exactly immediates) isn't broken.
189 ; Fixes PR21878.
190 ; NORMAL-LABEL: test6:
191 ; NORMAL: pushl    $_ext
192 ; NORMAL-NEXT: call
193 declare void @f(i8*)
194 @ext = external constant i8
195
196 define void @test6() {
197   call void @f(i8* @ext)
198   br label %bb
199 bb:
200   alloca i32
201   ret void
202 }
203
204 ; Check that we fold simple cases into the push
205 ; NORMAL-LABEL: test7:
206 ; NORMAL-NOT: subl {{.*}} %esp
207 ; NORMAL: movl 4(%esp), [[EAX:%e..]]
208 ; NORMAL-NEXT: pushl   $4
209 ; NORMAL-NEXT: pushl   ([[EAX]])
210 ; NORMAL-NEXT: pushl   $2
211 ; NORMAL-NEXT: pushl   $1
212 ; NORMAL-NEXT: call
213 ; NORMAL-NEXT: addl $16, %esp
214 define void @test7(i32* %ptr) optsize {
215 entry:
216   %val = load i32, i32* %ptr
217   call void @good(i32 1, i32 2, i32 %val, i32 4)
218   ret void
219 }
220
221 ; Fold stack-relative loads into the push, with correct offset
222 ; In particular, at the second push, %b was at 12(%esp) and
223 ; %a wast at 8(%esp), but the second push bumped %esp, so %a
224 ; is now it at 12(%esp)
225 ; NORMAL-LABEL: test8:
226 ; NORMAL: pushl   $4
227 ; NORMAL-NEXT: pushl   12(%esp)
228 ; NORMAL-NEXT: pushl   12(%esp)
229 ; NORMAL-NEXT: pushl   $1
230 ; NORMAL-NEXT: call
231 ; NORMAL-NEXT: addl $16, %esp
232 define void @test8(i32 %a, i32 %b) optsize {
233 entry:
234   call void @good(i32 1, i32 %a, i32 %b, i32 4)
235   ret void
236 }
237
238 ; If one function is using push instructions, and the other isn't
239 ; (because it has frame-index references), then we must resolve
240 ; these references correctly.
241 ; NORMAL-LABEL: test9:
242 ; NORMAL-NOT: leal (%esp), 
243 ; NORMAL: pushl $4
244 ; NORMAL-NEXT: pushl $3
245 ; NORMAL-NEXT: pushl $2
246 ; NORMAL-NEXT: pushl $1
247 ; NORMAL-NEXT: call
248 ; NORMAL-NEXT: addl $16, %esp
249 ; NORMAL-NEXT: subl $20, %esp
250 ; NORMAL-NEXT: movl 20(%esp), [[E1:%e..]]
251 ; NORMAL-NEXT: movl 24(%esp), [[E2:%e..]]
252 ; NORMAL-NEXT: movl    [[E2]], 4(%esp)
253 ; NORMAL-NEXT: movl    [[E1]], (%esp)
254 ; NORMAL-NEXT: leal 32(%esp), [[E3:%e..]]
255 ; NORMAL-NEXT: movl    [[E3]], 16(%esp)
256 ; NORMAL-NEXT: leal 28(%esp), [[E4:%e..]]
257 ; NORMAL-NEXT: movl    [[E4]], 12(%esp)
258 ; NORMAL-NEXT: movl    $6, 8(%esp)
259 ; NORMAL-NEXT: call
260 ; NORMAL-NEXT: addl $20, %esp
261 define void @test9() optsize {
262 entry:
263   %p = alloca i32, align 4
264   %q = alloca i32, align 4
265   %s = alloca %struct.s, align 4  
266   call void @good(i32 1, i32 2, i32 3, i32 4)
267   %pv = ptrtoint i32* %p to i32
268   %qv = ptrtoint i32* %q to i32
269   call void @struct(%struct.s* byval %s, i32 6, i32 %qv, i32 %pv)
270   ret void
271 }
272
273 ; We can end up with an indirect call which gets reloaded on the spot.
274 ; Make sure we reference the correct stack slot - we spill into (%esp)
275 ; and reload from 16(%esp) due to the pushes.
276 ; NORMAL-LABEL: test10:
277 ; NORMAL: movl $_good, [[ALLOC:.*]]
278 ; NORMAL-NEXT: movl [[ALLOC]], [[EAX:%e..]]
279 ; NORMAL-NEXT: movl [[EAX]], (%esp) # 4-byte Spill
280 ; NORMAL: nop
281 ; NORMAL: pushl $4
282 ; NORMAL-NEXT: pushl $3
283 ; NORMAL-NEXT: pushl $2
284 ; NORMAL-NEXT: pushl $1
285 ; NORMAL-NEXT: calll *16(%esp)
286 ; NORMAL-NEXT: addl $16, %esp
287 define void @test10() optsize {
288   %stack_fptr = alloca void (i32, i32, i32, i32)*
289   store void (i32, i32, i32, i32)* @good, void (i32, i32, i32, i32)** %stack_fptr
290   %good_ptr = load volatile void (i32, i32, i32, i32)*, void (i32, i32, i32, i32)** %stack_fptr
291   call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di}"()
292   call void (i32, i32, i32, i32) %good_ptr(i32 1, i32 2, i32 3, i32 4)
293   ret void
294 }
295
296 ; We can't fold the load from the global into the push because of 
297 ; interference from the store
298 ; NORMAL-LABEL: test11:
299 ; NORMAL: movl    _the_global, [[EAX:%e..]]
300 ; NORMAL-NEXT: movl    $42, _the_global
301 ; NORMAL-NEXT: pushl $4
302 ; NORMAL-NEXT: pushl $3
303 ; NORMAL-NEXT: pushl $2
304 ; NORMAL-NEXT: pushl [[EAX]]
305 ; NORMAL-NEXT: call
306 ; NORMAL-NEXT: addl $16, %esp
307 @the_global = external global i32
308 define void @test11() optsize {
309   %myload = load i32, i32* @the_global
310   store i32 42, i32* @the_global
311   call void @good(i32 %myload, i32 2, i32 3, i32 4)
312   ret void
313 }
314
315 ; Converting one mov into a push isn't worth it when 
316 ; doing so forces too much overhead for other calls.
317 ; NORMAL-LABEL: test12:
318 ; NORMAL: movl    $8, 12(%esp)
319 ; NORMAL-NEXT: movl    $7, 8(%esp)
320 ; NORMAL-NEXT: movl    $6, 4(%esp)
321 ; NORMAL-NEXT: movl    $5, (%esp)
322 ; NORMAL-NEXT: calll _good
323 define void @test12() optsize {
324 entry:
325   %s = alloca %struct.s, align 4  
326   call void @struct(%struct.s* %s, i32 2, i32 3, i32 4)
327   call void @good(i32 5, i32 6, i32 7, i32 8)
328   call void @struct(%struct.s* %s, i32 10, i32 11, i32 12)
329   ret void
330 }
331
332 ; But if the gains outweigh the overhead, we should do it
333 ; NORMAL-LABEL: test12b:
334 ; NORMAL: pushl    $4
335 ; NORMAL-NEXT: pushl    $3
336 ; NORMAL-NEXT: pushl    $2
337 ; NORMAL-NEXT: pushl    $1
338 ; NORMAL-NEXT: calll _good
339 ; NORMAL-NEXT: addl    $16, %esp
340 ; NORMAL-NEXT: subl    $20, %esp
341 ; NORMAL: movl    $8, 16(%esp)
342 ; NORMAL-NEXT: movl    $7, 12(%esp)
343 ; NORMAL-NEXT: movl    $6, 8(%esp)
344 ; NORMAL-NEXT: calll _struct
345 ; NORMAL-NEXT: addl    $20, %esp
346 ; NORMAL-NEXT: pushl    $12
347 ; NORMAL-NEXT: pushl    $11
348 ; NORMAL-NEXT: pushl    $10
349 ; NORMAL-NEXT: pushl    $9
350 ; NORMAL-NEXT: calll _good
351 ; NORMAL-NEXT: addl $16, %esp
352 define void @test12b() optsize {
353 entry:
354   %s = alloca %struct.s, align 4  
355   call void @good(i32 1, i32 2, i32 3, i32 4)  
356   call void @struct(%struct.s* %s, i32 6, i32 7, i32 8)
357   call void @good(i32 9, i32 10, i32 11, i32 12)
358   ret void
359 }
360
361 ; Make sure the add does not prevent folding loads into pushes.
362 ; val1 and val2 will not be folded into pushes since they have
363 ; an additional use, but val3 should be.
364 ; NORMAL-LABEL: test13:
365 ; NORMAL: movl ([[P1:%e..]]), [[V1:%e..]]
366 ; NORMAL-NEXT: movl ([[P2:%e..]]), [[V2:%e..]]
367 ; NORMAL-NEXT: , [[ADD:%e..]]
368 ; NORMAL-NEXT: pushl [[ADD]]
369 ; NORMAL-NEXT: pushl ([[P3:%e..]])
370 ; NORMAL-NEXT: pushl [[V2]]
371 ; NORMAL-NEXT: pushl [[V1]]
372 ; NORMAL-NEXT: calll _good
373 ; NORMAL: movl [[P3]], %eax
374 define i32* @test13(i32* inreg %ptr1, i32* inreg %ptr2, i32* inreg %ptr3) optsize {
375 entry:
376   %val1 = load i32, i32* %ptr1
377   %val2 = load i32, i32* %ptr2
378   %val3 = load i32, i32* %ptr3
379   %add = add i32 %val1, %val2
380   call void @good(i32 %val1, i32 %val2, i32 %val3, i32 %add)
381   ret i32* %ptr3
382 }