4db1372f9487d922e4123c999f245d6b73c6e88c
[oota-llvm.git] / test / CodeGen / X86 / movtopush.ll
1 ; RUN: llc < %s -mtriple=i686-windows | FileCheck %s -check-prefix=NORMAL\r
2 ; RUN: llc < %s -mtriple=i686-windows -force-align-stack -stack-alignment=32 | FileCheck %s -check-prefix=ALIGNED \r
3 declare void @good(i32 %a, i32 %b, i32 %c, i32 %d)\r
4 declare void @inreg(i32 %a, i32 inreg %b, i32 %c, i32 %d)\r
5 \r
6 ; Here, we should have a reserved frame, so we don't expect pushes\r
7 ; NORMAL-LABEL: test1\r
8 ; NORMAL: subl    $16, %esp\r
9 ; NORMAL-NEXT: movl    $4, 12(%esp)\r
10 ; NORMAL-NEXT: movl    $3, 8(%esp)\r
11 ; NORMAL-NEXT: movl    $2, 4(%esp)\r
12 ; NORMAL-NEXT: movl    $1, (%esp)\r
13 ; NORMAL-NEXT: call\r
14 define void @test1() {\r
15 entry:\r
16   call void @good(i32 1, i32 2, i32 3, i32 4)\r
17   ret void\r
18 }\r
19 \r
20 ; Here, we expect a sequence of 4 immediate pushes\r
21 ; NORMAL-LABEL: test2\r
22 ; NORMAL-NOT: subl {{.*}} %esp\r
23 ; NORMAL: pushl   $4\r
24 ; NORMAL-NEXT: pushl   $3\r
25 ; NORMAL-NEXT: pushl   $2\r
26 ; NORMAL-NEXT: pushl   $1\r
27 ; NORMAL-NEXT: call\r
28 define void @test2(i32 %k) {\r
29 entry:\r
30   %a = alloca i32, i32 %k\r
31   call void @good(i32 1, i32 2, i32 3, i32 4)\r
32   ret void\r
33 }\r
34 \r
35 ; Again, we expect a sequence of 4 immediate pushes\r
36 ; Checks that we generate the right pushes for >8bit immediates\r
37 ; NORMAL-LABEL: test2b\r
38 ; NORMAL-NOT: subl {{.*}} %esp\r
39 ; NORMAL: pushl   $4096\r
40 ; NORMAL-NEXT: pushl   $3072\r
41 ; NORMAL-NEXT: pushl   $2048\r
42 ; NORMAL-NEXT: pushl   $1024\r
43 ; NORMAL-NEXT: call\r
44 define void @test2b(i32 %k) {\r
45 entry:\r
46   %a = alloca i32, i32 %k\r
47   call void @good(i32 1024, i32 2048, i32 3072, i32 4096)\r
48   ret void\r
49 }\r
50 \r
51 ; The first push should push a register\r
52 ; NORMAL-LABEL: test3\r
53 ; NORMAL-NOT: subl {{.*}} %esp\r
54 ; NORMAL: pushl   $4\r
55 ; NORMAL-NEXT: pushl   $3\r
56 ; NORMAL-NEXT: pushl   $2\r
57 ; NORMAL-NEXT: pushl   %e{{..}}\r
58 ; NORMAL-NEXT: call\r
59 define void @test3(i32 %k) {\r
60 entry:\r
61   %a = alloca i32, i32 %k\r
62   call void @good(i32 %k, i32 2, i32 3, i32 4)\r
63   ret void\r
64 }\r
65 \r
66 ; We don't support weird calling conventions\r
67 ; NORMAL-LABEL: test4\r
68 ; NORMAL: subl    $12, %esp\r
69 ; NORMAL-NEXT: movl    $4, 8(%esp)\r
70 ; NORMAL-NEXT: movl    $3, 4(%esp)\r
71 ; NORMAL-NEXT: movl    $1, (%esp)\r
72 ; NORMAL-NEXT: movl    $2, %eax\r
73 ; NORMAL-NEXT: call\r
74 define void @test4(i32 %k) {\r
75 entry:\r
76   %a = alloca i32, i32 %k\r
77   call void @inreg(i32 1, i32 2, i32 3, i32 4)\r
78   ret void\r
79 }\r
80 \r
81 ; Check that additional alignment is added when the pushes\r
82 ; don't add up to the required alignment.\r
83 ; ALIGNED-LABEL: test5\r
84 ; ALIGNED: subl    $16, %esp\r
85 ; ALIGNED-NEXT: pushl   $4\r
86 ; ALIGNED-NEXT: pushl   $3\r
87 ; ALIGNED-NEXT: pushl   $2\r
88 ; ALIGNED-NEXT: pushl   $1\r
89 ; ALIGNED-NEXT: call\r
90 define void @test5(i32 %k) {\r
91 entry:\r
92   %a = alloca i32, i32 %k\r
93   call void @good(i32 1, i32 2, i32 3, i32 4)\r
94   ret void\r
95 }\r
96 \r
97 ; Check that pushing the addresses of globals (Or generally, things that \r
98 ; aren't exactly immediates) isn't broken.\r
99 ; Fixes PR21878.\r
100 ; NORMAL-LABEL: test6\r
101 ; NORMAL: pushl    $_ext\r
102 ; NORMAL-NEXT: call\r
103 declare void @f(i8*)\r
104 @ext = external constant i8\r
105 \r
106 define void @test6() {\r
107   call void @f(i8* @ext)\r
108   br label %bb\r
109 bb:\r
110   alloca i32\r
111   ret void\r
112 }