Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / bolt / test / X86 / split-landing-pad.s
blobdda27891443f2f9e092a0da0066ff774179fa4ad
1 # This test reproduces the case where C++ exception handling is used and split
2 # function optimization is enabled. In particular, function foo is splitted
3 # to two fragments:
4 # foo: contains 2 try blocks, which invokes bar to throw exception
5 # foo.cold.1: contains 2 corresponding catch blocks (landing pad)
7 # Similar to split jump table, split landing pad target to different fragment.
8 # This test is written to ensure BOLT safely handle these targets, e.g., by
9 # marking them as non-simple.
11 # Steps to write this test:
12 # - Create a copy of Inputs/src/unreachable.cpp
13 # - Simplify bar(), focus on throw an exception
14 # - Create the second switch case in foo() to have multiple landing pads
15 # - Compile with clang++ to .s
16 # - Move landing pad code from foo to foo.cold.1
17 # - Ensure that all landing pads can be reached normally
19 # Additional details:
20 # .gcc_except_table specify the landing pads for try blocks
21 # LPStart = 255 (omit), which means LPStart = foo start
22 # Landing pads .Ltmp2 and .Ltmp5 in call site record are offset to foo start.
25 # REQUIRES: system-linux
26 # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
27 # RUN: %clang++ %cxxflags %t.o -o %t.exe -Wl,-q
28 # RUN: llvm-bolt -v=3 %t.exe -o %t.out 2>&1 | FileCheck %s
30 # CHECK: BOLT-WARNING: Ignoring foo
31 # CHECK: BOLT-WARNING: Ignoring foo.cold.1
32 # CHECK: BOLT-WARNING: skipped 2 functions due to cold fragments
34 .text
35 .globl bar # -- Begin function bar
36 .p2align 4, 0x90
37 .type bar,@function
38 bar: # @bar
39 .cfi_startproc
40 # %bb.0: # %entry
41 pushq %rbp
42 .cfi_def_cfa_offset 16
43 .cfi_offset %rbp, -16
44 movq %rsp, %rbp
45 .cfi_def_cfa_register %rbp
46 subq $16, %rsp
47 movq %rdi, -8(%rbp)
48 cmpq $34, -8(%rbp)
49 jne .LBB0_2
50 # %bb.1: # %if.then
51 movl $4, %edi
52 callq __cxa_allocate_exception@PLT
53 movq %rax, %rdi
54 movl $0, (%rdi)
55 movq _ZTIi@GOTPCREL(%rip), %rsi
56 xorl %eax, %eax
57 movl %eax, %edx
58 callq __cxa_throw@PLT
59 .LBB0_2: # %if.else
60 movl $8, %edi
61 callq __cxa_allocate_exception@PLT
62 movq %rax, %rdi
63 movq $0, (%rdi)
64 movq _ZTIDn@GOTPCREL(%rip), %rsi
65 xorl %eax, %eax
66 movl %eax, %edx
67 callq __cxa_throw@PLT
68 .Lfunc_end0:
69 .size bar, .Lfunc_end0-bar
70 .cfi_endproc
71 # -- End function
72 .globl foo # -- Begin function foo
73 .p2align 4, 0x90
74 .type foo,@function
75 foo: # @foo
76 .Lfunc_begin0:
77 .cfi_startproc
78 .cfi_personality 155, DW.ref.__gxx_personality_v0
79 .cfi_lsda 27, .Lexception0
80 # %bb.0: # %entry
81 pushq %rbp
82 .cfi_def_cfa_offset 16
83 .cfi_offset %rbp, -16
84 movq %rsp, %rbp
85 .cfi_def_cfa_register %rbp
86 subq $48, %rsp
87 movq %rdi, -16(%rbp)
88 movq -16(%rbp), %rdi
89 .Ltmp0:
90 callq bar
91 .Ltmp1:
92 jmp .LBB1_1
93 .LBB1_1: # %invoke.cont
94 jmp .LBB1_5
95 .LBB1_5: # %try.cont
96 movq -16(%rbp), %rdi
97 addq $34, %rdi
98 .Ltmp3:
99 callq bar
100 .Ltmp4:
101 jmp .LBB1_6
102 .LBB1_6: # %invoke.cont2
103 jmp .LBB1_10
104 .LBB1_10: # %try.cont8
105 movq $0, -8(%rbp)
106 .LBB1_11: # %return
107 movq -8(%rbp), %rax
108 addq $48, %rsp
109 popq %rbp
110 .cfi_def_cfa %rsp, 8
111 retq
112 .LBB1_12: # %eh.resume
113 .cfi_def_cfa %rbp, 16
114 movq -24(%rbp), %rdi
115 callq _Unwind_Resume@PLT
116 .Lfunc_end1:
117 .size foo, .Lfunc_end1-foo
118 .cfi_endproc
119 .section .gcc_except_table,"a",@progbits
120 .p2align 2
121 GCC_except_table1:
122 .Lexception0:
123 .byte 255 # @LPStart Encoding = omit
124 .byte 155 # @TType Encoding = indirect pcrel sdata4
125 .uleb128 .Lttbase0-.Lttbaseref0
126 .Lttbaseref0:
127 .byte 1 # Call site Encoding = uleb128
128 .uleb128 .Lcst_end0-.Lcst_begin0
129 .Lcst_begin0:
130 .uleb128 .Ltmp0-.Lfunc_begin0 # >> Call Site 1 <<
131 .uleb128 .Ltmp1-.Ltmp0 # Call between .Ltmp0 and .Ltmp1
132 .uleb128 .Ltmp2-.Lfunc_begin0 # jumps to .Ltmp2
133 .byte 1 # On action: 1
134 .uleb128 .Ltmp1-.Lfunc_begin0 # >> Call Site 2 <<
135 .uleb128 .Ltmp3-.Ltmp1 # Call between .Ltmp1 and .Ltmp3
136 .byte 0 # has no landing pad
137 .byte 0 # On action: cleanup
138 .uleb128 .Ltmp3-.Lfunc_begin0 # >> Call Site 3 <<
139 .uleb128 .Ltmp4-.Ltmp3 # Call between .Ltmp3 and .Ltmp4
140 .uleb128 .Ltmp5-.Lfunc_begin0 # jumps to .Ltmp5
141 .byte 1 # On action: 1
142 .uleb128 .Ltmp4-.Lfunc_begin0 # >> Call Site 4 <<
143 .uleb128 .Lfunc_end1-.Ltmp4 # Call between .Ltmp4 and .Lfunc_end1
144 .byte 0 # has no landing pad
145 .byte 0 # On action: cleanup
146 .Lcst_end0:
147 .byte 1 # >> Action Record 1 <<
148 # Catch TypeInfo 1
149 .byte 0 # No further actions
150 .p2align 2
151 # >> Catch TypeInfos <<
152 .Ltmp6: # TypeInfo 1
153 .long .L_ZTIi.DW.stub-.Ltmp6
154 .Lttbase0:
155 .p2align 2
156 # -- End function
159 .text
160 .globl foo.cold.1 # -- Begin function foo.cold.1
161 .p2align 4, 0x90
162 .type foo.cold.1,@function
163 foo.cold.1: # @foo.cold.1
164 .Lfunc_begin3:
165 .cfi_startproc
166 .Ltmp2:
167 movq %rax, %rcx
168 movl %edx, %eax
169 movq %rcx, -24(%rbp)
170 movl %eax, -28(%rbp)
171 # %bb.3: # %catch.dispatch
172 movl -28(%rbp), %eax
173 movl $1, %ecx
174 cmpl %ecx, %eax
175 jne .LBB1_12
176 # %bb.4: # %catch
177 movq -24(%rbp), %rdi
178 callq __cxa_begin_catch@PLT
179 movl (%rax), %eax
180 movl %eax, -32(%rbp)
181 movq $0, -8(%rbp)
182 callq __cxa_end_catch@PLT
183 jmp .LBB1_11
184 .Ltmp5:
185 movq %rax, %rcx
186 movl %edx, %eax
187 movq %rcx, -24(%rbp)
188 movl %eax, -28(%rbp)
189 # %bb.8: # %catch.dispatch3
190 movl -28(%rbp), %eax
191 movl $1, %ecx
192 cmpl %ecx, %eax
193 jne .LBB1_12
194 # %bb.9: # %catch6
195 movq -24(%rbp), %rdi
196 callq __cxa_begin_catch@PLT
197 movl (%rax), %eax
198 movl %eax, -36(%rbp)
199 movq $0, -8(%rbp)
200 callq __cxa_end_catch@PLT
201 jmp .LBB1_11
202 .Lfunc_end3:
203 .size foo.cold.1, .Lfunc_end3-foo.cold.1
204 .cfi_endproc
207 .text
208 .globl main # -- Begin function main
209 .p2align 4, 0x90
210 .type main,@function
211 main: # @main
212 .cfi_startproc
213 # %bb.0: # %entry
214 pushq %rbp
215 .cfi_def_cfa_offset 16
216 .cfi_offset %rbp, -16
217 movq %rsp, %rbp
218 .cfi_def_cfa_register %rbp
219 subq $16, %rsp
220 movl $0, -4(%rbp)
221 movl %edi, -8(%rbp)
222 movq %rsi, -16(%rbp)
223 xorl %eax, %eax
224 movl %eax, %edi
225 callq foo
226 # kill: def $eax killed $eax killed $rax
227 addq $16, %rsp
228 popq %rbp
229 .cfi_def_cfa %rsp, 8
230 retq
231 .Lfunc_end2:
232 .size main, .Lfunc_end2-main
233 .cfi_endproc
234 # -- End function
235 .data
236 .p2align 3
237 .L_ZTIi.DW.stub:
238 .quad _ZTIi
239 .hidden DW.ref.__gxx_personality_v0
240 .weak DW.ref.__gxx_personality_v0
241 .section .data.DW.ref.__gxx_personality_v0,"aGw",@progbits,DW.ref.__gxx_personality_v0,comdat
242 .p2align 3
243 .type DW.ref.__gxx_personality_v0,@object
244 .size DW.ref.__gxx_personality_v0, 8
245 DW.ref.__gxx_personality_v0:
246 .quad __gxx_personality_v0
247 .section ".note.GNU-stack","",@progbits
248 .addrsig
249 .addrsig_sym bar
250 .addrsig_sym __cxa_allocate_exception
251 .addrsig_sym __cxa_throw
252 .addrsig_sym foo
253 .addrsig_sym __gxx_personality_v0
254 .addrsig_sym __cxa_begin_catch
255 .addrsig_sym __cxa_end_catch
256 .addrsig_sym _Unwind_Resume
257 .addrsig_sym _ZTIi
258 .addrsig_sym _ZTIDn
259 .addrsig_sym foo.cold.1
260 .addrsig_sym __cxa_begin_catch
261 .addrsig_sym __cxa_end_catch