1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -stackrealign -mtriple i386-apple-darwin -mcpu=i486 | FileCheck %s
4 %struct.foo = type { [88 x i8] }
6 declare void @bar(i8* nocapture, %struct.foo* align 4 byval) nounwind
7 declare void @baz(i8*) nounwind
10 ; We can't use rep;movsl here because it clobbers the base pointer in %esi.
11 define void @test1(%struct.foo* nocapture %x, i32 %y) nounwind {
14 ; CHECK-NEXT: pushl %ebp
15 ; CHECK-NEXT: movl %esp, %ebp
16 ; CHECK-NEXT: pushl %ebx
17 ; CHECK-NEXT: pushl %edi
18 ; CHECK-NEXT: pushl %esi
19 ; CHECK-NEXT: andl $-16, %esp
20 ; CHECK-NEXT: subl $80, %esp
21 ; CHECK-NEXT: movl %esp, %esi
22 ; CHECK-NEXT: movl 8(%ebp), %ecx
23 ; CHECK-NEXT: movl 12(%ebp), %edx
24 ; CHECK-NEXT: movl %esp, %eax
25 ; CHECK-NEXT: addl $15, %edx
26 ; CHECK-NEXT: andl $-16, %edx
27 ; CHECK-NEXT: subl %edx, %eax
28 ; CHECK-NEXT: movl %eax, %esp
29 ; CHECK-NEXT: subl $4, %esp
30 ; CHECK-NEXT: movl 84(%ecx), %edx
31 ; CHECK-NEXT: movl %edx, 68(%esi) ## 4-byte Spill
32 ; CHECK-NEXT: movl 80(%ecx), %edi
33 ; CHECK-NEXT: movl 76(%ecx), %ebx
34 ; CHECK-NEXT: movl 72(%ecx), %edx
35 ; CHECK-NEXT: movl %edx, 64(%esi) ## 4-byte Spill
36 ; CHECK-NEXT: movl 68(%ecx), %edx
37 ; CHECK-NEXT: movl %edx, 60(%esi) ## 4-byte Spill
38 ; CHECK-NEXT: movl 64(%ecx), %edx
39 ; CHECK-NEXT: movl %edx, 56(%esi) ## 4-byte Spill
40 ; CHECK-NEXT: movl 60(%ecx), %edx
41 ; CHECK-NEXT: movl %edx, 52(%esi) ## 4-byte Spill
42 ; CHECK-NEXT: movl 56(%ecx), %edx
43 ; CHECK-NEXT: movl %edx, 48(%esi) ## 4-byte Spill
44 ; CHECK-NEXT: movl 52(%ecx), %edx
45 ; CHECK-NEXT: movl %edx, 44(%esi) ## 4-byte Spill
46 ; CHECK-NEXT: movl 48(%ecx), %edx
47 ; CHECK-NEXT: movl %edx, 40(%esi) ## 4-byte Spill
48 ; CHECK-NEXT: movl 44(%ecx), %edx
49 ; CHECK-NEXT: movl %edx, 36(%esi) ## 4-byte Spill
50 ; CHECK-NEXT: movl 40(%ecx), %edx
51 ; CHECK-NEXT: movl %edx, 32(%esi) ## 4-byte Spill
52 ; CHECK-NEXT: movl 36(%ecx), %edx
53 ; CHECK-NEXT: movl %edx, 28(%esi) ## 4-byte Spill
54 ; CHECK-NEXT: movl 32(%ecx), %edx
55 ; CHECK-NEXT: movl %edx, 24(%esi) ## 4-byte Spill
56 ; CHECK-NEXT: movl 28(%ecx), %edx
57 ; CHECK-NEXT: movl %edx, 20(%esi) ## 4-byte Spill
58 ; CHECK-NEXT: movl 24(%ecx), %edx
59 ; CHECK-NEXT: movl %edx, 16(%esi) ## 4-byte Spill
60 ; CHECK-NEXT: movl 20(%ecx), %edx
61 ; CHECK-NEXT: movl %edx, 12(%esi) ## 4-byte Spill
62 ; CHECK-NEXT: movl 16(%ecx), %edx
63 ; CHECK-NEXT: movl %edx, 8(%esi) ## 4-byte Spill
64 ; CHECK-NEXT: movl 12(%ecx), %edx
65 ; CHECK-NEXT: movl %edx, 4(%esi) ## 4-byte Spill
66 ; CHECK-NEXT: movl 8(%ecx), %edx
67 ; CHECK-NEXT: movl %edx, (%esi) ## 4-byte Spill
68 ; CHECK-NEXT: movl (%ecx), %edx
69 ; CHECK-NEXT: movl %edx, 72(%esi) ## 4-byte Spill
70 ; CHECK-NEXT: movl 4(%ecx), %ecx
71 ; CHECK-NEXT: pushl 68(%esi) ## 4-byte Folded Reload
72 ; CHECK-NEXT: pushl %edi
73 ; CHECK-NEXT: pushl %ebx
74 ; CHECK-NEXT: pushl 64(%esi) ## 4-byte Folded Reload
75 ; CHECK-NEXT: pushl 60(%esi) ## 4-byte Folded Reload
76 ; CHECK-NEXT: pushl 56(%esi) ## 4-byte Folded Reload
77 ; CHECK-NEXT: pushl 52(%esi) ## 4-byte Folded Reload
78 ; CHECK-NEXT: pushl 48(%esi) ## 4-byte Folded Reload
79 ; CHECK-NEXT: pushl 44(%esi) ## 4-byte Folded Reload
80 ; CHECK-NEXT: pushl 40(%esi) ## 4-byte Folded Reload
81 ; CHECK-NEXT: pushl 36(%esi) ## 4-byte Folded Reload
82 ; CHECK-NEXT: pushl 32(%esi) ## 4-byte Folded Reload
83 ; CHECK-NEXT: pushl 28(%esi) ## 4-byte Folded Reload
84 ; CHECK-NEXT: pushl 24(%esi) ## 4-byte Folded Reload
85 ; CHECK-NEXT: pushl 20(%esi) ## 4-byte Folded Reload
86 ; CHECK-NEXT: pushl 16(%esi) ## 4-byte Folded Reload
87 ; CHECK-NEXT: pushl 12(%esi) ## 4-byte Folded Reload
88 ; CHECK-NEXT: pushl 8(%esi) ## 4-byte Folded Reload
89 ; CHECK-NEXT: pushl 4(%esi) ## 4-byte Folded Reload
90 ; CHECK-NEXT: pushl (%esi) ## 4-byte Folded Reload
91 ; CHECK-NEXT: pushl %ecx
92 ; CHECK-NEXT: pushl 72(%esi) ## 4-byte Folded Reload
93 ; CHECK-NEXT: pushl %eax
94 ; CHECK-NEXT: calll _bar
95 ; CHECK-NEXT: leal -12(%ebp), %esp
96 ; CHECK-NEXT: popl %esi
97 ; CHECK-NEXT: popl %edi
98 ; CHECK-NEXT: popl %ebx
99 ; CHECK-NEXT: popl %ebp
101 %dynalloc = alloca i8, i32 %y, align 1
102 call void @bar(i8* %dynalloc, %struct.foo* align 4 byval %x)
107 ; Also don't clobber %esi if the dynamic alloca comes after the memcpy.
108 define void @test2(%struct.foo* nocapture %x, i32 %y, i8* %z) nounwind {
109 ; CHECK-LABEL: test2:
111 ; CHECK-NEXT: pushl %ebp
112 ; CHECK-NEXT: movl %esp, %ebp
113 ; CHECK-NEXT: pushl %ebx
114 ; CHECK-NEXT: pushl %edi
115 ; CHECK-NEXT: pushl %esi
116 ; CHECK-NEXT: andl $-16, %esp
117 ; CHECK-NEXT: subl $80, %esp
118 ; CHECK-NEXT: movl %esp, %esi
119 ; CHECK-NEXT: movl 12(%ebp), %edi
120 ; CHECK-NEXT: movl 8(%ebp), %eax
121 ; CHECK-NEXT: subl $4, %esp
122 ; CHECK-NEXT: movl 84(%eax), %ecx
123 ; CHECK-NEXT: movl %ecx, 68(%esi) ## 4-byte Spill
124 ; CHECK-NEXT: movl 80(%eax), %edx
125 ; CHECK-NEXT: movl 76(%eax), %ebx
126 ; CHECK-NEXT: movl 72(%eax), %ecx
127 ; CHECK-NEXT: movl %ecx, 64(%esi) ## 4-byte Spill
128 ; CHECK-NEXT: movl 68(%eax), %ecx
129 ; CHECK-NEXT: movl %ecx, 60(%esi) ## 4-byte Spill
130 ; CHECK-NEXT: movl 64(%eax), %ecx
131 ; CHECK-NEXT: movl %ecx, 56(%esi) ## 4-byte Spill
132 ; CHECK-NEXT: movl 60(%eax), %ecx
133 ; CHECK-NEXT: movl %ecx, 52(%esi) ## 4-byte Spill
134 ; CHECK-NEXT: movl 56(%eax), %ecx
135 ; CHECK-NEXT: movl %ecx, 48(%esi) ## 4-byte Spill
136 ; CHECK-NEXT: movl 52(%eax), %ecx
137 ; CHECK-NEXT: movl %ecx, 44(%esi) ## 4-byte Spill
138 ; CHECK-NEXT: movl 48(%eax), %ecx
139 ; CHECK-NEXT: movl %ecx, 40(%esi) ## 4-byte Spill
140 ; CHECK-NEXT: movl 44(%eax), %ecx
141 ; CHECK-NEXT: movl %ecx, 36(%esi) ## 4-byte Spill
142 ; CHECK-NEXT: movl 40(%eax), %ecx
143 ; CHECK-NEXT: movl %ecx, 32(%esi) ## 4-byte Spill
144 ; CHECK-NEXT: movl 36(%eax), %ecx
145 ; CHECK-NEXT: movl %ecx, 28(%esi) ## 4-byte Spill
146 ; CHECK-NEXT: movl 32(%eax), %ecx
147 ; CHECK-NEXT: movl %ecx, 24(%esi) ## 4-byte Spill
148 ; CHECK-NEXT: movl 28(%eax), %ecx
149 ; CHECK-NEXT: movl %ecx, 20(%esi) ## 4-byte Spill
150 ; CHECK-NEXT: movl 24(%eax), %ecx
151 ; CHECK-NEXT: movl %ecx, 16(%esi) ## 4-byte Spill
152 ; CHECK-NEXT: movl 20(%eax), %ecx
153 ; CHECK-NEXT: movl %ecx, 12(%esi) ## 4-byte Spill
154 ; CHECK-NEXT: movl 16(%eax), %ecx
155 ; CHECK-NEXT: movl %ecx, 8(%esi) ## 4-byte Spill
156 ; CHECK-NEXT: movl 12(%eax), %ecx
157 ; CHECK-NEXT: movl %ecx, 4(%esi) ## 4-byte Spill
158 ; CHECK-NEXT: movl 8(%eax), %ecx
159 ; CHECK-NEXT: movl %ecx, (%esi) ## 4-byte Spill
160 ; CHECK-NEXT: movl (%eax), %ecx
161 ; CHECK-NEXT: movl %ecx, 72(%esi) ## 4-byte Spill
162 ; CHECK-NEXT: movl 4(%eax), %eax
163 ; CHECK-NEXT: pushl 68(%esi) ## 4-byte Folded Reload
164 ; CHECK-NEXT: pushl %edx
165 ; CHECK-NEXT: pushl %ebx
166 ; CHECK-NEXT: pushl 64(%esi) ## 4-byte Folded Reload
167 ; CHECK-NEXT: pushl 60(%esi) ## 4-byte Folded Reload
168 ; CHECK-NEXT: pushl 56(%esi) ## 4-byte Folded Reload
169 ; CHECK-NEXT: pushl 52(%esi) ## 4-byte Folded Reload
170 ; CHECK-NEXT: pushl 48(%esi) ## 4-byte Folded Reload
171 ; CHECK-NEXT: pushl 44(%esi) ## 4-byte Folded Reload
172 ; CHECK-NEXT: pushl 40(%esi) ## 4-byte Folded Reload
173 ; CHECK-NEXT: pushl 36(%esi) ## 4-byte Folded Reload
174 ; CHECK-NEXT: pushl 32(%esi) ## 4-byte Folded Reload
175 ; CHECK-NEXT: pushl 28(%esi) ## 4-byte Folded Reload
176 ; CHECK-NEXT: pushl 24(%esi) ## 4-byte Folded Reload
177 ; CHECK-NEXT: pushl 20(%esi) ## 4-byte Folded Reload
178 ; CHECK-NEXT: pushl 16(%esi) ## 4-byte Folded Reload
179 ; CHECK-NEXT: pushl 12(%esi) ## 4-byte Folded Reload
180 ; CHECK-NEXT: pushl 8(%esi) ## 4-byte Folded Reload
181 ; CHECK-NEXT: pushl 4(%esi) ## 4-byte Folded Reload
182 ; CHECK-NEXT: pushl (%esi) ## 4-byte Folded Reload
183 ; CHECK-NEXT: pushl %eax
184 ; CHECK-NEXT: pushl 72(%esi) ## 4-byte Folded Reload
185 ; CHECK-NEXT: pushl 16(%ebp)
186 ; CHECK-NEXT: calll _bar
187 ; CHECK-NEXT: addl $96, %esp
188 ; CHECK-NEXT: movl %esp, %eax
189 ; CHECK-NEXT: addl $15, %edi
190 ; CHECK-NEXT: andl $-16, %edi
191 ; CHECK-NEXT: subl %edi, %eax
192 ; CHECK-NEXT: movl %eax, %esp
193 ; CHECK-NEXT: subl $12, %esp
194 ; CHECK-NEXT: pushl %eax
195 ; CHECK-NEXT: calll _baz
196 ; CHECK-NEXT: leal -12(%ebp), %esp
197 ; CHECK-NEXT: popl %esi
198 ; CHECK-NEXT: popl %edi
199 ; CHECK-NEXT: popl %ebx
200 ; CHECK-NEXT: popl %ebp
202 call void @bar(i8* %z, %struct.foo* align 4 byval %x)
203 %dynalloc = alloca i8, i32 %y, align 1
204 call void @baz(i8* %dynalloc)
208 ; Check that we do use rep movs if we make the alloca static.
209 define void @test3(%struct.foo* nocapture %x, i32 %y, i8* %z) nounwind {
210 ; CHECK-LABEL: test3:
212 ; CHECK-NEXT: pushl %ebp
213 ; CHECK-NEXT: movl %esp, %ebp
214 ; CHECK-NEXT: pushl %edi
215 ; CHECK-NEXT: pushl %esi
216 ; CHECK-NEXT: andl $-16, %esp
217 ; CHECK-NEXT: subl $112, %esp
218 ; CHECK-NEXT: movl 16(%ebp), %eax
219 ; CHECK-NEXT: movl 8(%ebp), %esi
220 ; CHECK-NEXT: leal {{[0-9]+}}(%esp), %edi
221 ; CHECK-NEXT: movl $22, %ecx
222 ; CHECK-NEXT: rep;movsl (%esi), %es:(%edi)
223 ; CHECK-NEXT: movl %eax, (%esp)
224 ; CHECK-NEXT: calll _bar
225 ; CHECK-NEXT: leal {{[0-9]+}}(%esp), %eax
226 ; CHECK-NEXT: movl %eax, (%esp)
227 ; CHECK-NEXT: calll _baz
228 ; CHECK-NEXT: leal -8(%ebp), %esp
229 ; CHECK-NEXT: popl %esi
230 ; CHECK-NEXT: popl %edi
231 ; CHECK-NEXT: popl %ebp
233 call void @bar(i8* %z, %struct.foo* align 4 byval %x)
234 %statalloc = alloca i8, i32 8, align 1
235 call void @baz(i8* %statalloc)