xref: /llvm-project/llvm/test/CodeGen/X86/stack-align-memcpy.ll (revision 2f448bf509432c1a19ec46ab8cbc7353c03c6280)
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
3
4%struct.foo = type { [88 x i8] }
5
6declare void @bar(ptr nocapture, ptr align 4 byval(%struct.foo)) nounwind
7declare void @baz(ptr) nounwind
8
9; PR15249
10; We can't use rep;movsl here because it clobbers the base pointer in %esi.
11define void @test1(ptr nocapture %x, i32 %y) nounwind {
12; CHECK-LABEL: test1:
13; CHECK:       ## %bb.0:
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), %edi
31; CHECK-NEXT:    movl 80(%ecx), %ebx
32; CHECK-NEXT:    movl 76(%ecx), %edx
33; CHECK-NEXT:    movl %edx, 68(%esi) ## 4-byte Spill
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 %edi
72; CHECK-NEXT:    pushl %ebx
73; CHECK-NEXT:    pushl 68(%esi) ## 4-byte Folded Reload
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
100; CHECK-NEXT:    retl
101  %dynalloc = alloca i8, i32 %y, align 1
102  call void @bar(ptr %dynalloc, ptr align 4 byval(%struct.foo) %x)
103  ret void
104}
105
106; PR19012
107; Also don't clobber %esi if the dynamic alloca comes after the memcpy.
108define void @test2(ptr nocapture %x, i32 %y, ptr %z) nounwind {
109; CHECK-LABEL: test2:
110; CHECK:       ## %bb.0:
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), %edx
123; CHECK-NEXT:    movl 80(%eax), %ebx
124; CHECK-NEXT:    movl 76(%eax), %ecx
125; CHECK-NEXT:    movl %ecx, 68(%esi) ## 4-byte Spill
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 %edx
164; CHECK-NEXT:    pushl %ebx
165; CHECK-NEXT:    pushl 68(%esi) ## 4-byte Folded Reload
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
201; CHECK-NEXT:    retl
202  call void @bar(ptr %z, ptr align 4 byval(%struct.foo) %x)
203  %dynalloc = alloca i8, i32 %y, align 1
204  call void @baz(ptr %dynalloc)
205  ret void
206}
207
208; Check that we do use rep movs if we make the alloca static.
209define void @test3(ptr nocapture %x, i32 %y, ptr %z) nounwind {
210; CHECK-LABEL: test3:
211; CHECK:       ## %bb.0:
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
232; CHECK-NEXT:    retl
233  call void @bar(ptr %z, ptr align 4 byval(%struct.foo) %x)
234  %statalloc = alloca i8, i32 8, align 1
235  call void @baz(ptr %statalloc)
236  ret void
237}
238