xref: /llvm-project/bolt/test/X86/split-landing-pad.s (revision 11791ae7b0b05b8bd8d806331ff51da618912cf8)
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)
6##
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.
10##
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
18##
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.
23
24
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
29
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
33
34	.text
35	.globl	bar                             # -- Begin function bar
36	.p2align	4, 0x90
37	.type	bar,@function
38bar:                                    # @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
75foo:                                    # @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
121GCC_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
157
158
159        .text
160	.globl	foo.cold.1              # -- Begin function foo.cold.1
161	.p2align	4, 0x90
162	.type	foo.cold.1,@function
163foo.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
205
206
207	.text
208	.globl	main                            # -- Begin function main
209	.p2align	4, 0x90
210	.type	main,@function
211main:                                   # @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
245DW.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
262