Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / X86 / push-cfi.ll
blob7bbd5142e7391e53b713dc883f39a2963573d813
1 ; 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
3 ; RUN: llc < %s -mtriple=i686-pc-linux -stop-after=prologepilog | FileCheck %s --check-prefix=PEI
5 declare i32 @__gxx_personality_v0(...)
6 declare void @good(i32 %a, i32 %b, i32 %c, i32 %d)
7 declare void @large(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f)
8 declare void @empty()
10 ; When we use an invoke, we expect a .cfi_escape GNU_ARGS_SIZE
11 ; with size 16 before the invocation. Without FP, we also expect
12 ; .cfi_adjust_cfa_offset after each push.
13 ; Darwin should not generate pushes in either circumstance.
14 ; CHECK-LABEL: test1_nofp:
15 ; LINUX: .cfi_escape 0x2e, 0x10
16 ; LINUX-NEXT: pushl   $4
17 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
18 ; LINUX-NEXT: pushl   $3
19 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
20 ; LINUX-NEXT: pushl   $2
21 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
22 ; LINUX-NEXT: pushl   $1
23 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
24 ; LINUX-NEXT: call
25 ; LINUX-NEXT: addl $16, %esp
26 ; LINUX: .cfi_adjust_cfa_offset -16
27 ; DARWIN-NOT: .cfi_escape
28 ; DARWIN-NOT: pushl
30 ; PEI-LABEL: name: test1_nofp
31 ; PEI:         $esp = frame-setup SUB32ri $esp, 12, implicit-def dead $eflags
32 ; PEI-NEXT:    frame-setup CFI_INSTRUCTION def_cfa_offset 16
33 ; PEI-NOT:     frame-setup CFI_INSTRUCTION
34 ; PEI:         ...
35 define void @test1_nofp() #0 personality ptr @__gxx_personality_v0 {
36 entry:
37   invoke void @good(i32 1, i32 2, i32 3, i32 4)
38           to label %continue unwind label %cleanup
39 continue:
40   ret void
41 cleanup:  
42   landingpad { ptr, i32 }
43      cleanup
44   ret void
47 ; CHECK-LABEL: test1_fp:
48 ; LINUX: .cfi_escape 0x2e, 0x10
49 ; LINUX-NEXT: pushl   $4
50 ; LINUX-NEXT: pushl   $3
51 ; LINUX-NEXT: pushl   $2
52 ; LINUX-NEXT: pushl   $1
53 ; LINUX-NEXT: call
54 ; LINUX-NEXT: addl $16, %esp
55 ; DARWIN: pushl %ebp
56 ; DARWIN-NOT: .cfi_escape
57 ; DARWIN-NOT: pushl
58 define void @test1_fp() #1 personality ptr @__gxx_personality_v0 {
59 entry:
60   invoke void @good(i32 1, i32 2, i32 3, i32 4)
61           to label %continue unwind label %cleanup
62 continue:
63   ret void
64 cleanup:  
65   landingpad { ptr, i32 }
66      cleanup
67   ret void
70 ; If the function has no handlers, we don't need to generate GNU_ARGS_SIZE,
71 ; even if it has an unwind table. Without FP, we still need cfi_adjust_cfa_offset,
72 ; so darwin should not generate pushes.
73 ; CHECK-LABEL: test2_nofp:
74 ; LINUX-NOT: .cfi_escape
75 ; LINUX: pushl   $4
76 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
77 ; LINUX-NEXT: pushl   $3
78 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
79 ; LINUX-NEXT: pushl   $2
80 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
81 ; LINUX-NEXT: pushl   $1
82 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
83 ; LINUX-NEXT: call
84 ; LINUX-NEXT: addl $28, %esp
85 ; LINUX: .cfi_adjust_cfa_offset -28
86 ; DARWIN-NOT: .cfi_escape
87 ; DARWIN-NOT: pushl
88 define void @test2_nofp() #0 personality ptr @__gxx_personality_v0 {
89 entry:
90   call void @good(i32 1, i32 2, i32 3, i32 4)
91   ret void
94 ; CHECK-LABEL: test2_fp:
95 ; CHECK-NOT: .cfi_escape
96 ; CHECK-NOT: .cfi_adjust_cfa_offset
97 ; CHECK: pushl   $4
98 ; CHECK-NEXT: pushl   $3
99 ; CHECK-NEXT: pushl   $2
100 ; CHECK-NEXT: pushl   $1
101 ; CHECK-NEXT: call
102 ; CHECK-NEXT: addl $24, %esp
103 define void @test2_fp() #1 personality ptr @__gxx_personality_v0 {
104 entry:
105   call void @good(i32 1, i32 2, i32 3, i32 4)
106   ret void
109 ; If we did not end up using any pushes, no need for GNU_ARGS_SIZE or
110 ; cfi_adjust_cfa_offset.
111 ; CHECK-LABEL: test3_nofp:
112 ; LINUX-NOT: .cfi_escape
113 ; LINUX-NOT: .cfi_adjust_cfa_offset
114 ; LINUX-NOT: pushl
115 ; LINUX: retl
116 define void @test3_nofp() #0 personality ptr @__gxx_personality_v0 {
117 entry:
118   invoke void @empty()
119           to label %continue unwind label %cleanup
120 continue:
121   ret void
122 cleanup:  
123   landingpad { ptr, i32 }
124      cleanup
125   ret void
128 ; If we did not end up using any pushes, no need for GNU_ARGS_SIZE or
129 ; cfi_adjust_cfa_offset.
130 ; CHECK-LABEL: test3_fp:
131 ; LINUX: pushl %ebp
132 ; LINUX-NOT: .cfi_escape
133 ; LINUX-NOT: .cfi_adjust_cfa_offset
134 ; LINUX-NOT: pushl
135 ; LINUX: retl
136 define void @test3_fp() #1 personality ptr @__gxx_personality_v0 {
137 entry:
138   invoke void @empty()
139           to label %continue unwind label %cleanup
140 continue:
141   ret void
142 cleanup:  
143   landingpad { ptr, i32 }
144      cleanup
145   ret void
148 ; Different sized stacks need different GNU_ARGS_SIZEs
149 ; CHECK-LABEL: test4:
150 ; LINUX: .cfi_escape 0x2e, 0x10
151 ; LINUX-NEXT: pushl   $4
152 ; LINUX-NEXT: pushl   $3
153 ; LINUX-NEXT: pushl   $2
154 ; LINUX-NEXT: pushl   $1
155 ; LINUX-NEXT: call
156 ; LINUX-NEXT: addl $16, %esp
157 ; LINUX: .cfi_escape 0x2e, 0x20
158 ; LINUX: subl    $8, %esp
159 ; LINUX-NEXT: pushl   $11
160 ; LINUX-NEXT: pushl   $10
161 ; LINUX-NEXT: pushl   $9
162 ; LINUX-NEXT: pushl   $8
163 ; LINUX-NEXT: pushl   $7
164 ; LINUX-NEXT: pushl   $6
165 ; LINUX-NEXT: calll   large
166 ; LINUX-NEXT: addl $32, %esp
167 define void @test4() #1 personality ptr @__gxx_personality_v0 {
168 entry:
169   invoke void @good(i32 1, i32 2, i32 3, i32 4)
170           to label %continue1 unwind label %cleanup
171 continue1:
172   invoke void @large(i32 6, i32 7, i32 8, i32 9, i32 10, i32 11)
173           to label %continue2 unwind label %cleanup
174 continue2:
175   ret void          
176 cleanup:  
177   landingpad { ptr, i32 }
178      cleanup
179   ret void
182 ; If we did use pushes, we need to reset GNU_ARGS_SIZE before a call
183 ; without parameters, but don't need to adjust the cfa offset
184 ; CHECK-LABEL: test5_nofp:
185 ; LINUX: .cfi_escape 0x2e, 0x10
186 ; LINUX-NEXT: pushl   $4
187 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
188 ; LINUX-NEXT: pushl   $3
189 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
190 ; LINUX-NEXT: pushl   $2
191 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
192 ; LINUX-NEXT: pushl   $1
193 ; LINUX-NEXT: .cfi_adjust_cfa_offset 4
194 ; LINUX-NEXT: call
195 ; LINUX-NEXT: addl $16, %esp
196 ; LINUX: .cfi_adjust_cfa_offset -16
197 ; LINUX-NOT: .cfi_adjust_cfa_offset
198 ; LINUX: .cfi_escape 0x2e, 0x00
199 ; LINUX-NOT: .cfi_adjust_cfa_offset
200 ; LINUX: call
201 define void @test5_nofp() #0 personality ptr @__gxx_personality_v0 {
202 entry:
203   invoke void @good(i32 1, i32 2, i32 3, i32 4)
204           to label %continue1 unwind label %cleanup
205 continue1:
206   invoke void @empty()
207           to label %continue2 unwind label %cleanup
208 continue2:
209   ret void          
210 cleanup:  
211   landingpad { ptr, i32 }
212      cleanup
213   ret void
216 ; CHECK-LABEL: test5_fp:
217 ; LINUX: .cfi_escape 0x2e, 0x10
218 ; LINUX-NEXT: pushl   $4
219 ; LINUX-NEXT: pushl   $3
220 ; LINUX-NEXT: pushl   $2
221 ; LINUX-NEXT: pushl   $1
222 ; LINUX-NEXT: call
223 ; LINUX-NEXT: addl $16, %esp
224 ; LINUX: .cfi_escape 0x2e, 0x00
225 ; LINUX-NOT: .cfi_adjust_cfa_offset
226 ; LINUX: call
227 define void @test5_fp() #1 personality ptr @__gxx_personality_v0 {
228 entry:
229   invoke void @good(i32 1, i32 2, i32 3, i32 4)
230           to label %continue1 unwind label %cleanup
231 continue1:
232   invoke void @empty()
233           to label %continue2 unwind label %cleanup
234 continue2:
235   ret void          
236 cleanup:  
237   landingpad { ptr, i32 }
238      cleanup
239   ret void
242 ; FIXME: This is actually inefficient - we don't need to repeat the .cfi_escape twice.
243 ; CHECK-LABEL: test6:
244 ; LINUX: .cfi_escape 0x2e, 0x10
245 ; LINUX: call
246 ; LINUX: .cfi_escape 0x2e, 0x10
247 ; LINUX: call
248 define void @test6() #1 personality ptr @__gxx_personality_v0 {
249 entry:
250   invoke void @good(i32 1, i32 2, i32 3, i32 4)
251           to label %continue1 unwind label %cleanup
252 continue1:
253   invoke void @good(i32 5, i32 6, i32 7, i32 8)
254           to label %continue2 unwind label %cleanup
255 continue2:
256   ret void          
257 cleanup:  
258   landingpad { ptr, i32 }
259      cleanup
260   ret void
263 ; Darwin should generate pushes in the presense of FP and an unwind table,
264 ; but not FP and invoke.
265 ; CHECK-LABEL: test7:
266 ; DARWIN: pushl %ebp
267 ; DARWIN: movl %esp, %ebp
268 ; DARWIN: .cfi_def_cfa_register %ebp
269 ; DARWIN-NOT: .cfi_adjust_cfa_offset
270 ; DARWIN: pushl   $4
271 ; DARWIN-NEXT: pushl   $3
272 ; DARWIN-NEXT: pushl   $2
273 ; DARWIN-NEXT: pushl   $1
274 ; DARWIN-NEXT: call
275 define void @test7() #1 personality ptr @__gxx_personality_v0 {
276 entry:
277   call void @good(i32 1, i32 2, i32 3, i32 4)
278   ret void
281 ; CHECK-LABEL: test8:
282 ; DARWIN: pushl %ebp
283 ; DARWIN: movl %esp, %ebp
284 ; DARWIN-NOT: .cfi_adjust_cfa_offset
285 ; DARWIN-NOT: pushl
286 define void @test8() #1 personality ptr @__gxx_personality_v0 {
287 entry:
288   invoke void @good(i32 1, i32 2, i32 3, i32 4)
289           to label %continue unwind label %cleanup
290 continue:
291   ret void
292 cleanup:  
293   landingpad { ptr, i32 }
294      cleanup
295   ret void
298 attributes #0 = { optsize }
299 attributes #1 = { optsize "frame-pointer"="all" }