Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / MC / AArch64 / seh-large-func-multi-epilog.s
blobc2d7f94f7b11f4ffbb756427e7e7fd029bad71dd
1 // This test checks that we emit unwind info correctly for epilogs that:
2 // 1. mirror the prolog; or
3 // 2. are subsequence at the end of the prolog; or
4 // 3. neither of above two.
5 // in the same segment.
6 // RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s -o %t.o
7 // RUN: llvm-readobj -S -r -u %t.o | FileCheck %s
9 // CHECK: Section {
10 // CHECK: Number: 4
11 // CHECK-NEXT: Name: .xdata (2E 78 64 61 74 61 00 00)
12 // CHECK-NEXT: VirtualSize: 0x0
13 // CHECK-NEXT: VirtualAddress: 0x0
14 // CHECK-NEXT: RawDataSize: 80
15 // CHECK-NEXT: PointerToRawData: 0x1251AC
16 // CHECK-NEXT: PointerToRelocations: 0x0
17 // CHECK-NEXT: PointerToLineNumbers: 0x0
18 // CHECK-NEXT: RelocationCount: 0
19 // CHECK-NEXT: LineNumberCount: 0
20 // CHECK-NEXT: Characteristics [ (0x40300040)
21 // CHECK-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
22 // CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
23 // CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
24 // CHECK-NEXT: ]
25 // CHECK-NEXT: }
26 // CHECK-NEXT: Section {
27 // CHECK-NEXT: Number: 5
28 // CHECK-NEXT: Name: .pdata (2E 70 64 61 74 61 00 00)
29 // CHECK-NEXT: VirtualSize: 0x0
30 // CHECK-NEXT: VirtualAddress: 0x0
31 // CHECK-NEXT: RawDataSize: 16
32 // CHECK-NEXT: PointerToRawData: 0x1251FC
33 // CHECK-NEXT: PointerToRelocations: 0x12520C
34 // CHECK-NEXT: PointerToLineNumbers: 0x0
35 // CHECK-NEXT: RelocationCount: 4
36 // CHECK-NEXT: LineNumberCount: 0
37 // CHECK-NEXT: Characteristics [ (0x40300040)
38 // CHECK-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
39 // CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
40 // CHECK-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
41 // CHECK-NEXT: ]
42 // CHECK-NEXT: }
43 // CHECK-NEXT:]
44 // CHECK-LABEL:Relocations [
45 // CHECK-NEXT: Section (1) .text {
46 // CHECK-NEXT: 0x94 IMAGE_REL_ARM64_BRANCH26 foo (12)
47 // CHECK-NEXT: 0x125068 IMAGE_REL_ARM64_BRANCH26 foo (12)
48 // CHECK-NEXT: }
49 // CHECK-NEXT: Section (5) .pdata {
50 // CHECK-NEXT: 0x0 IMAGE_REL_ARM64_ADDR32NB .text (0)
51 // CHECK-NEXT: 0x4 IMAGE_REL_ARM64_ADDR32NB .xdata (7)
52 // CHECK-NEXT: 0x8 IMAGE_REL_ARM64_ADDR32NB .text (0)
53 // CHECK-NEXT: 0xC IMAGE_REL_ARM64_ADDR32NB .xdata (7)
54 // CHECK-NEXT: }
55 // CHECK-NEXT:]
56 // CHECK-LABEL:UnwindInformation [
57 // CHECK-NEXT: RuntimeFunction {
58 // CHECK-NEXT: Function: multi_epilog (0x0)
59 // CHECK-NEXT: ExceptionRecord: .xdata (0x0)
60 // CHECK-NEXT: ExceptionData {
61 // CHECK-NEXT: FunctionLength: 1048572
62 // CHECK-NEXT: Version: 0
63 // CHECK-NEXT: ExceptionData: No
64 // CHECK-NEXT: EpiloguePacked: No
65 // CHECK-NEXT: EpilogueScopes: 3
66 // CHECK-NEXT: ByteCodeLength: 24
67 // CHECK-NEXT: Prologue [
68 // CHECK-NEXT: 0xe1 ; mov fp, sp
69 // CHECK-NEXT: 0xca16 ; stp x27, x28, [sp, #176]
70 // CHECK-NEXT: 0xc998 ; stp x25, x26, [sp, #192]
71 // CHECK-NEXT: 0xc91a ; stp x23, x24, [sp, #208]
72 // CHECK-NEXT: 0xc89c ; stp x21, x22, [sp, #224]
73 // CHECK-NEXT: 0xc81e ; stp x19, x20, [sp, #240]
74 // CHECK-NEXT: 0x9f ; stp x29, x30, [sp, #-256]!
75 // CHECK-NEXT: 0xe4 ; end
76 // CHECK-NEXT: ]
77 // CHECK-NEXT: EpilogueScopes [
78 // CHECK-NEXT: EpilogueScope {
79 // CHECK-NEXT: StartOffset: 38
80 // CHECK-NEXT: EpilogueStartIndex: 0
81 // CHECK-NEXT: Opcodes [
82 // CHECK-NEXT: 0xe1 ; mov sp, fp
83 // CHECK-NEXT: 0xca16 ; ldp x27, x28, [sp, #176]
84 // CHECK-NEXT: 0xc998 ; ldp x25, x26, [sp, #192]
85 // CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]
86 // CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]
87 // CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]
88 // CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256
89 // CHECK-NEXT: 0xe4 ; end
90 // CHECK-NEXT: ]
91 // CHECK-NEXT: }
92 // CHECK-NEXT: EpilogueScope {
93 // CHECK-NEXT: StartOffset: 46
94 // CHECK-NEXT: EpilogueStartIndex: 3
95 // CHECK-NEXT: Opcodes [
96 // CHECK-NEXT: 0xc998 ; ldp x25, x26, [sp, #192]
97 // CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]
98 // CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]
99 // CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]
100 // CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256
101 // CHECK-NEXT: 0xe4 ; end
102 // CHECK-NEXT: ]
103 // CHECK-NEXT: }
104 // CHECK-NEXT: EpilogueScope {
105 // CHECK-NEXT: StartOffset: 52
106 // CHECK-NEXT: EpilogueStartIndex: 13
107 // CHECK-NEXT: Opcodes [
108 // CHECK-NEXT: 0xe1 ; mov sp, fp
109 // CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]
110 // CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]
111 // CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]
112 // CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256
113 // CHECK-NEXT: 0xe4 ; end
114 // CHECK-NEXT: ]
115 // CHECK-NEXT: }
116 // CHECK-NEXT: ]
117 // CHECK-NEXT: }
118 // CHECK-NEXT: }
119 // CHECK-NEXT: RuntimeFunction {
120 // CHECK-NEXT: Function: multi_epilog +0xFFFFC (0xFFFFC)
121 // CHECK-NEXT: ExceptionRecord: .xdata +0x28 (0x28)
122 // CHECK-NEXT: ExceptionData {
123 // CHECK-NEXT: FunctionLength: 151744
124 // CHECK-NEXT: Version: 0
125 // CHECK-NEXT: ExceptionData: No
126 // CHECK-NEXT: EpiloguePacked: No
127 // CHECK-NEXT: EpilogueScopes: 3
128 // CHECK-NEXT: ByteCodeLength: 24
129 // CHECK-NEXT: Prologue [
130 // CHECK-NEXT: 0xe5 ; end_c
131 // CHECK-NEXT: 0xe1 ; mov fp, sp
132 // CHECK-NEXT: 0xca16 ; stp x27, x28, [sp, #176]
133 // CHECK-NEXT: 0xc998 ; stp x25, x26, [sp, #192]
134 // CHECK-NEXT: 0xc91a ; stp x23, x24, [sp, #208]
135 // CHECK-NEXT: 0xc89c ; stp x21, x22, [sp, #224]
136 // CHECK-NEXT: 0xc81e ; stp x19, x20, [sp, #240]
137 // CHECK-NEXT: 0x9f ; stp x29, x30, [sp, #-256]!
138 // CHECK-NEXT: 0xe4 ; end
139 // CHECK-NEXT: ]
140 // CHECK-NEXT: EpilogueScopes [
141 // CHECK-NEXT: EpilogueScope {
142 // CHECK-NEXT: StartOffset: 37916
143 // CHECK-NEXT: EpilogueStartIndex: 1
144 // CHECK-NEXT: Opcodes [
145 // CHECK-NEXT: 0xe1 ; mov sp, fp
146 // CHECK-NEXT: 0xca16 ; ldp x27, x28, [sp, #176]
147 // CHECK-NEXT: 0xc998 ; ldp x25, x26, [sp, #192]
148 // CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]
149 // CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]
150 // CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]
151 // CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256
152 // CHECK-NEXT: 0xe4 ; end
153 // CHECK-NEXT: ]
154 // CHECK-NEXT: }
155 // CHECK-NEXT: EpilogueScope {
156 // CHECK-NEXT: StartOffset: 37924
157 // CHECK-NEXT: EpilogueStartIndex: 4
158 // CHECK-NEXT: Opcodes [
159 // CHECK-NEXT: 0xc998 ; ldp x25, x26, [sp, #192]
160 // CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]
161 // CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]
162 // CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]
163 // CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256
164 // CHECK-NEXT: 0xe4 ; end
165 // CHECK-NEXT: ]
166 // CHECK-NEXT: }
167 // CHECK-NEXT: EpilogueScope {
168 // CHECK-NEXT: StartOffset: 37930
169 // CHECK-NEXT: EpilogueStartIndex: 14
170 // CHECK-NEXT: Opcodes [
171 // CHECK-NEXT: 0xe1 ; mov sp, fp
172 // CHECK-NEXT: 0xc91a ; ldp x23, x24, [sp, #208]
173 // CHECK-NEXT: 0xc89c ; ldp x21, x22, [sp, #224]
174 // CHECK-NEXT: 0xc81e ; ldp x19, x20, [sp, #240]
175 // CHECK-NEXT: 0x9f ; ldp x29, x30, [sp], #256
176 // CHECK-NEXT: 0xe4 ; end
177 // CHECK-NEXT: ]
178 // CHECK-NEXT: }
179 // CHECK-NEXT: ]
180 // CHECK-NEXT: }
181 // CHECK-NEXT: }
182 // CHECK-NEXT:]
184 .text
185 .global multi_epilog
186 .p2align 2
187 .seh_proc multi_epilog
188 multi_epilog:
189 stp x29, lr, [sp, #-256]!
190 .seh_save_fplr_x 256
191 stp x19, x20, [sp, #240]
192 .seh_save_regp x19, 240
193 stp x21, x22, [sp, #224]
194 .seh_save_regp x21, 224
195 stp x23, x24, [sp, #208]
196 .seh_save_regp x23, 208
197 stp x25, x26, [sp, #192]
198 .seh_save_regp x25, 192
199 stp x27, x28, [sp, #176]
200 .seh_save_regp x27, 176
201 mov x29, fp
202 .seh_set_fp
203 .seh_endprologue
204 .rept 30
206 .endr
207 bl foo
208 // Epilogs 1, 2 and 3 are in the same segment as prolog.
209 // epilog1 - mirroring prolog
210 .seh_startepilogue
211 mov sp, x29
212 .seh_set_fp
213 stp x27, x28, [sp, #176]
214 .seh_save_regp x27, 176
215 stp x25, x26, [sp, #192]
216 .seh_save_regp x25, 192
217 stp x23, x24, [sp, #208]
218 .seh_save_regp x23, 208
219 stp x21, x22, [sp, #224]
220 .seh_save_regp x21, 224
221 ldp x19, x20, [sp, #240]
222 .seh_save_regp x19, 240
223 ldp x29, lr, [sp], #256
224 .seh_save_fplr_x 256
225 .seh_endepilogue
227 // epilog2 - a subsequence at the end of prolog, can use prolog's opcodes.
228 .seh_startepilogue
229 stp x25, x26, [sp, #192]
230 .seh_save_regp x25, 192
231 stp x23, x24, [sp, #208]
232 .seh_save_regp x23, 208
233 stp x21, x22, [sp, #224]
234 .seh_save_regp x21, 224
235 ldp x19, x20, [sp, #240]
236 .seh_save_regp x19, 240
237 ldp x29, lr, [sp], #256
238 .seh_save_fplr_x 256
239 .seh_endepilogue
241 // epilog3 - cannot use prolog's opcode.
242 .seh_startepilogue
243 mov sp, x29
244 .seh_set_fp
245 stp x23, x24, [sp, #208]
246 .seh_save_regp x23, 208
247 stp x21, x22, [sp, #224]
248 .seh_save_regp x21, 224
249 ldp x19, x20, [sp, #240]
250 .seh_save_regp x19, 240
251 ldp x29, lr, [sp], #256
252 .seh_save_fplr_x 256
253 .seh_endepilogue
255 .rept 300000
257 .endr
258 bl foo
259 // Epilogs below are in a segment without prolog
260 // epilog4 - mirroring prolog, its start index should be 1, counting the end_c.
261 .seh_startepilogue
262 mov sp, x29
263 .seh_set_fp
264 stp x27, x28, [sp, #176]
265 .seh_save_regp x27, 176
266 stp x25, x26, [sp, #192]
267 .seh_save_regp x25, 192
268 stp x23, x24, [sp, #208]
269 .seh_save_regp x23, 208
270 stp x21, x22, [sp, #224]
271 .seh_save_regp x21, 224
272 ldp x19, x20, [sp, #240]
273 .seh_save_regp x19, 240
274 ldp x29, lr, [sp], #256
275 .seh_save_fplr_x 256
276 .seh_endepilogue
278 // epilog5 - same as epilog2, its start index should be: 1 + epilog2's index.
279 .seh_startepilogue
280 stp x25, x26, [sp, #192]
281 .seh_save_regp x25, 192
282 stp x23, x24, [sp, #208]
283 .seh_save_regp x23, 208
284 stp x21, x22, [sp, #224]
285 .seh_save_regp x21, 224
286 ldp x19, x20, [sp, #240]
287 .seh_save_regp x19, 240
288 ldp x29, lr, [sp], #256
289 .seh_save_fplr_x 256
290 .seh_endepilogue
292 // epilog6 - same as epilog3, cannot use prolog's opcode. Again its start index
293 // should be: 1 + epilog3's index.
294 .seh_startepilogue
295 mov sp, x29
296 .seh_set_fp
297 stp x23, x24, [sp, #208]
298 .seh_save_regp x23, 208
299 stp x21, x22, [sp, #224]
300 .seh_save_regp x21, 224
301 ldp x19, x20, [sp, #240]
302 .seh_save_regp x19, 240
303 ldp x29, lr, [sp], #256
304 .seh_save_fplr_x 256
305 .seh_endepilogue
307 .seh_endfunclet
308 .seh_endproc