blob: 6389708f42ccc28fabbd808f2c30b2b177c09914 [file] [log] [blame]
Michael Kuperstein73dc8522015-11-03 08:17:25 +00001; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s -check-prefix=LINUX -check-prefix=CHECK
2; RUN: llc < %s -mtriple=i686-apple-darwin | FileCheck %s -check-prefix=DARWIN -check-prefix=CHECK
Michael Kuperstein259f1502015-10-07 07:01:31 +00003
4declare i32 @__gxx_personality_v0(...)
5declare void @good(i32 %a, i32 %b, i32 %c, i32 %d)
6declare void @large(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f)
7declare void @empty()
8
Michael Kuperstein77ce9d32015-12-06 13:06:20 +00009; When we use an invoke, we expect a .cfi_escape GNU_ARGS_SIZE
10; with size 16 before the invocation. Without FP, we also expect
11; .cfi_adjust_cfa_offset after each push.
12; Darwin should not generate pushes in either circumstance.
Michael Kuperstein73dc8522015-11-03 08:17:25 +000013; CHECK-LABEL: test1_nofp:
14; LINUX: .cfi_escape 0x2e, 0x10
Michael Kuperstein73dc8522015-11-03 08:17:25 +000015; LINUX-NEXT: pushl $4
Michael Kuperstein77ce9d32015-12-06 13:06:20 +000016; LINUX-NEXT: Ltmp{{[0-9]+}}:
17; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +000018; LINUX-NEXT: pushl $3
Michael Kuperstein77ce9d32015-12-06 13:06:20 +000019; LINUX-NEXT: Ltmp{{[0-9]+}}:
20; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +000021; LINUX-NEXT: pushl $2
Michael Kuperstein77ce9d32015-12-06 13:06:20 +000022; LINUX-NEXT: Ltmp{{[0-9]+}}:
23; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +000024; LINUX-NEXT: pushl $1
Michael Kuperstein77ce9d32015-12-06 13:06:20 +000025; LINUX-NEXT: Ltmp{{[0-9]+}}:
26; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +000027; LINUX-NEXT: call
28; LINUX-NEXT: addl $16, %esp
29; LINUX: .cfi_adjust_cfa_offset -16
30; DARWIN-NOT: .cfi_escape
31; DARWIN-NOT: pushl
32define void @test1_nofp() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
33entry:
34 invoke void @good(i32 1, i32 2, i32 3, i32 4)
35 to label %continue unwind label %cleanup
36continue:
37 ret void
38cleanup:
39 landingpad { i8*, i32 }
40 cleanup
41 ret void
42}
43
44; CHECK-LABEL: test1_fp:
45; LINUX: .cfi_escape 0x2e, 0x10
46; LINUX-NEXT: pushl $4
47; LINUX-NEXT: pushl $3
48; LINUX-NEXT: pushl $2
49; LINUX-NEXT: pushl $1
50; LINUX-NEXT: call
51; LINUX-NEXT: addl $16, %esp
52; DARWIN: pushl %ebp
53; DARWIN-NOT: .cfi_escape
54; DARWIN-NOT: pushl
55define void @test1_fp() #1 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
Michael Kuperstein259f1502015-10-07 07:01:31 +000056entry:
57 invoke void @good(i32 1, i32 2, i32 3, i32 4)
58 to label %continue unwind label %cleanup
59continue:
60 ret void
61cleanup:
62 landingpad { i8*, i32 }
63 cleanup
64 ret void
65}
66
67; If the function has no handlers, we don't need to generate GNU_ARGS_SIZE,
Michael Kuperstein73dc8522015-11-03 08:17:25 +000068; even if it has an unwind table. Without FP, we still need cfi_adjust_cfa_offset,
69; so darwin should not generate pushes.
70; CHECK-LABEL: test2_nofp:
71; LINUX-NOT: .cfi_escape
Michael Kuperstein77ce9d32015-12-06 13:06:20 +000072; LINUX: pushl $4
73; LINUX-NEXT: Ltmp{{[0-9]+}}:
74; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +000075; LINUX-NEXT: pushl $3
Michael Kuperstein77ce9d32015-12-06 13:06:20 +000076; LINUX-NEXT: Ltmp{{[0-9]+}}:
77; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +000078; LINUX-NEXT: pushl $2
Michael Kuperstein77ce9d32015-12-06 13:06:20 +000079; LINUX-NEXT: Ltmp{{[0-9]+}}:
80; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +000081; LINUX-NEXT: pushl $1
Michael Kuperstein77ce9d32015-12-06 13:06:20 +000082; LINUX-NEXT: Ltmp{{[0-9]+}}:
83; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +000084; LINUX-NEXT: call
Hans Wennborga7e396b2016-04-06 16:10:20 +000085; LINUX-NEXT: addl $16, %esp
86; LINUX: .cfi_adjust_cfa_offset -16
Michael Kuperstein73dc8522015-11-03 08:17:25 +000087; DARWIN-NOT: .cfi_escape
88; DARWIN-NOT: pushl
89define void @test2_nofp() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
Michael Kuperstein259f1502015-10-07 07:01:31 +000090entry:
91 call void @good(i32 1, i32 2, i32 3, i32 4)
92 ret void
93}
94
Michael Kuperstein73dc8522015-11-03 08:17:25 +000095; CHECK-LABEL: test2_fp:
Michael Kuperstein259f1502015-10-07 07:01:31 +000096; CHECK-NOT: .cfi_escape
Michael Kuperstein73dc8522015-11-03 08:17:25 +000097; CHECK-NOT: .cfi_adjust_cfa_offset
98; CHECK: pushl $4
99; CHECK-NEXT: pushl $3
100; CHECK-NEXT: pushl $2
101; CHECK-NEXT: pushl $1
102; CHECK-NEXT: call
103; CHECK-NEXT: addl $24, %esp
104define void @test2_fp() #1 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
105entry:
106 call void @good(i32 1, i32 2, i32 3, i32 4)
107 ret void
108}
109
110; If we did not end up using any pushes, no need for GNU_ARGS_SIZE or
111; cfi_adjust_cfa_offset.
112; CHECK-LABEL: test3_nofp:
113; LINUX-NOT: .cfi_escape
114; LINUX-NOT: .cfi_adjust_cfa_offset
115; LINUX-NOT: pushl
116; LINUX: retl
117define void @test3_nofp() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
118entry:
119 invoke void @empty()
120 to label %continue unwind label %cleanup
121continue:
122 ret void
123cleanup:
124 landingpad { i8*, i32 }
125 cleanup
126 ret void
127}
128
129; If we did not end up using any pushes, no need for GNU_ARGS_SIZE or
130; cfi_adjust_cfa_offset.
131; CHECK-LABEL: test3_fp:
132; LINUX: pushl %ebp
133; LINUX-NOT: .cfi_escape
134; LINUX-NOT: .cfi_adjust_cfa_offset
135; LINUX-NOT: pushl
136; LINUX: retl
137define void @test3_fp() #1 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
Michael Kuperstein259f1502015-10-07 07:01:31 +0000138entry:
139 invoke void @empty()
140 to label %continue unwind label %cleanup
141continue:
142 ret void
143cleanup:
144 landingpad { i8*, i32 }
145 cleanup
146 ret void
147}
148
149; Different sized stacks need different GNU_ARGS_SIZEs
150; CHECK-LABEL: test4:
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000151; LINUX: .cfi_escape 0x2e, 0x10
152; LINUX-NEXT: pushl $4
153; LINUX-NEXT: pushl $3
154; LINUX-NEXT: pushl $2
155; LINUX-NEXT: pushl $1
156; LINUX-NEXT: call
157; LINUX-NEXT: addl $16, %esp
158; LINUX: .cfi_escape 0x2e, 0x20
159; LINUX: subl $8, %esp
160; LINUX-NEXT: pushl $11
161; LINUX-NEXT: pushl $10
162; LINUX-NEXT: pushl $9
163; LINUX-NEXT: pushl $8
164; LINUX-NEXT: pushl $7
165; LINUX-NEXT: pushl $6
166; LINUX-NEXT: calll large
167; LINUX-NEXT: addl $32, %esp
168define void @test4() #1 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
Michael Kuperstein259f1502015-10-07 07:01:31 +0000169entry:
170 invoke void @good(i32 1, i32 2, i32 3, i32 4)
171 to label %continue1 unwind label %cleanup
172continue1:
173 invoke void @large(i32 6, i32 7, i32 8, i32 9, i32 10, i32 11)
174 to label %continue2 unwind label %cleanup
175continue2:
176 ret void
177cleanup:
178 landingpad { i8*, i32 }
179 cleanup
180 ret void
181}
182
183; If we did use pushes, we need to reset GNU_ARGS_SIZE before a call
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000184; without parameters, but don't need to adjust the cfa offset
185; CHECK-LABEL: test5_nofp:
186; LINUX: .cfi_escape 0x2e, 0x10
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000187; LINUX-NEXT: pushl $4
Michael Kuperstein77ce9d32015-12-06 13:06:20 +0000188; LINUX-NEXT: Ltmp{{[0-9]+}}:
189; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000190; LINUX-NEXT: pushl $3
Michael Kuperstein77ce9d32015-12-06 13:06:20 +0000191; LINUX-NEXT: Ltmp{{[0-9]+}}:
192; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000193; LINUX-NEXT: pushl $2
Michael Kuperstein77ce9d32015-12-06 13:06:20 +0000194; LINUX-NEXT: Ltmp{{[0-9]+}}:
195; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000196; LINUX-NEXT: pushl $1
Michael Kuperstein77ce9d32015-12-06 13:06:20 +0000197; LINUX-NEXT: Ltmp{{[0-9]+}}:
198; LINUX-NEXT: .cfi_adjust_cfa_offset 4
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000199; LINUX-NEXT: call
200; LINUX-NEXT: addl $16, %esp
201; LINUX: .cfi_adjust_cfa_offset -16
202; LINUX-NOT: .cfi_adjust_cfa_offset
203; LINUX: .cfi_escape 0x2e, 0x00
204; LINUX-NOT: .cfi_adjust_cfa_offset
205; LINUX: call
206define void @test5_nofp() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
Michael Kuperstein259f1502015-10-07 07:01:31 +0000207entry:
208 invoke void @good(i32 1, i32 2, i32 3, i32 4)
209 to label %continue1 unwind label %cleanup
210continue1:
211 invoke void @empty()
212 to label %continue2 unwind label %cleanup
213continue2:
214 ret void
215cleanup:
216 landingpad { i8*, i32 }
217 cleanup
218 ret void
219}
220
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000221; CHECK-LABEL: test5_fp:
222; LINUX: .cfi_escape 0x2e, 0x10
223; LINUX-NEXT: pushl $4
224; LINUX-NEXT: pushl $3
225; LINUX-NEXT: pushl $2
226; LINUX-NEXT: pushl $1
227; LINUX-NEXT: call
228; LINUX-NEXT: addl $16, %esp
229; LINUX: .cfi_escape 0x2e, 0x00
230; LINUX-NOT: .cfi_adjust_cfa_offset
231; LINUX: call
232define void @test5_fp() #1 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
233entry:
234 invoke void @good(i32 1, i32 2, i32 3, i32 4)
235 to label %continue1 unwind label %cleanup
236continue1:
237 invoke void @empty()
238 to label %continue2 unwind label %cleanup
239continue2:
240 ret void
241cleanup:
242 landingpad { i8*, i32 }
243 cleanup
244 ret void
245}
246
247; FIXME: This is actually inefficient - we don't need to repeat the .cfi_escape twice.
Michael Kuperstein259f1502015-10-07 07:01:31 +0000248; CHECK-LABEL: test6:
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000249; LINUX: .cfi_escape 0x2e, 0x10
250; LINUX: call
251; LINUX: .cfi_escape 0x2e, 0x10
252; LINUX: call
253define void @test6() #1 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
Michael Kuperstein259f1502015-10-07 07:01:31 +0000254entry:
255 invoke void @good(i32 1, i32 2, i32 3, i32 4)
256 to label %continue1 unwind label %cleanup
257continue1:
258 invoke void @good(i32 5, i32 6, i32 7, i32 8)
259 to label %continue2 unwind label %cleanup
260continue2:
261 ret void
262cleanup:
263 landingpad { i8*, i32 }
264 cleanup
265 ret void
266}
Michael Kuperstein73dc8522015-11-03 08:17:25 +0000267
268; Darwin should generate pushes in the presense of FP and an unwind table,
269; but not FP and invoke.
270; CHECK-LABEL: test7:
271; DARWIN: pushl %ebp
272; DARWIN: movl %esp, %ebp
273; DARWIN: .cfi_def_cfa_register %ebp
274; DARWIN-NOT: .cfi_adjust_cfa_offset
275; DARWIN: pushl $4
276; DARWIN-NEXT: pushl $3
277; DARWIN-NEXT: pushl $2
278; DARWIN-NEXT: pushl $1
279; DARWIN-NEXT: call
280define void @test7() #1 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
281entry:
282 call void @good(i32 1, i32 2, i32 3, i32 4)
283 ret void
284}
285
286; CHECK-LABEL: test8:
287; DARWIN: pushl %ebp
288; DARWIN: movl %esp, %ebp
289; DARWIN-NOT: .cfi_adjust_cfa_offset
290; DARWIN-NOT: pushl
291define void @test8() #1 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
292entry:
293 invoke void @good(i32 1, i32 2, i32 3, i32 4)
294 to label %continue unwind label %cleanup
295continue:
296 ret void
297cleanup:
298 landingpad { i8*, i32 }
299 cleanup
300 ret void
301}
302
303attributes #0 = { optsize }
304attributes #1 = { optsize "no-frame-pointer-elim"="true" }