forked from OSchip/llvm-project
262 lines
7.8 KiB
ArmAsm
262 lines
7.8 KiB
ArmAsm
# This test reproduces the case where C++ exception handling is used and split
|
|
# function optimization is enabled. In particular, function foo is splitted
|
|
# to two fragments:
|
|
# foo: contains 2 try blocks, which invokes bar to throw exception
|
|
# foo.cold.1: contains 2 corresponding catch blocks (landing pad)
|
|
#
|
|
# Similar to split jump table, split landing pad target to different fragment.
|
|
# This test is written to ensure BOLT safely handle these targets, e.g., by
|
|
# marking them as non-simple.
|
|
#
|
|
# Steps to write this test:
|
|
# - Create a copy of Inputs/src/unreachable.cpp
|
|
# - Simplify bar(), focus on throw an exception
|
|
# - Create the second switch case in foo() to have multiple landing pads
|
|
# - Compile with clang++ to .s
|
|
# - Move landing pad code from foo to foo.cold.1
|
|
# - Ensure that all landing pads can be reached normally
|
|
#
|
|
# Additional details:
|
|
# .gcc_except_table specify the landing pads for try blocks
|
|
# LPStart = 255 (omit), which means LPStart = foo start
|
|
# Landing pads .Ltmp2 and .Ltmp5 in call site record are offset to foo start.
|
|
|
|
|
|
# REQUIRES: system-linux
|
|
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
|
|
# RUN: %clang++ %cxxflags %t.o -o %t.exe -Wl,-q
|
|
# RUN: llvm-bolt -v=3 %t.exe -o %t.out 2>&1 | FileCheck %s
|
|
|
|
# CHECK: BOLT-WARNING: Ignoring foo
|
|
# CHECK: BOLT-WARNING: Ignoring foo.cold.1
|
|
# CHECK: BOLT-WARNING: skipped 2 functions due to cold fragments
|
|
|
|
.text
|
|
.globl bar # -- Begin function bar
|
|
.p2align 4, 0x90
|
|
.type bar,@function
|
|
bar: # @bar
|
|
.cfi_startproc
|
|
# %bb.0: # %entry
|
|
pushq %rbp
|
|
.cfi_def_cfa_offset 16
|
|
.cfi_offset %rbp, -16
|
|
movq %rsp, %rbp
|
|
.cfi_def_cfa_register %rbp
|
|
subq $16, %rsp
|
|
movq %rdi, -8(%rbp)
|
|
cmpq $34, -8(%rbp)
|
|
jne .LBB0_2
|
|
# %bb.1: # %if.then
|
|
movl $4, %edi
|
|
callq __cxa_allocate_exception@PLT
|
|
movq %rax, %rdi
|
|
movl $0, (%rdi)
|
|
movq _ZTIi@GOTPCREL(%rip), %rsi
|
|
xorl %eax, %eax
|
|
movl %eax, %edx
|
|
callq __cxa_throw@PLT
|
|
.LBB0_2: # %if.else
|
|
movl $8, %edi
|
|
callq __cxa_allocate_exception@PLT
|
|
movq %rax, %rdi
|
|
movq $0, (%rdi)
|
|
movq _ZTIDn@GOTPCREL(%rip), %rsi
|
|
xorl %eax, %eax
|
|
movl %eax, %edx
|
|
callq __cxa_throw@PLT
|
|
.Lfunc_end0:
|
|
.size bar, .Lfunc_end0-bar
|
|
.cfi_endproc
|
|
# -- End function
|
|
.globl foo # -- Begin function foo
|
|
.p2align 4, 0x90
|
|
.type foo,@function
|
|
foo: # @foo
|
|
.Lfunc_begin0:
|
|
.cfi_startproc
|
|
.cfi_personality 155, DW.ref.__gxx_personality_v0
|
|
.cfi_lsda 27, .Lexception0
|
|
# %bb.0: # %entry
|
|
pushq %rbp
|
|
.cfi_def_cfa_offset 16
|
|
.cfi_offset %rbp, -16
|
|
movq %rsp, %rbp
|
|
.cfi_def_cfa_register %rbp
|
|
subq $48, %rsp
|
|
movq %rdi, -16(%rbp)
|
|
movq -16(%rbp), %rdi
|
|
.Ltmp0:
|
|
callq bar
|
|
.Ltmp1:
|
|
jmp .LBB1_1
|
|
.LBB1_1: # %invoke.cont
|
|
jmp .LBB1_5
|
|
.LBB1_5: # %try.cont
|
|
movq -16(%rbp), %rdi
|
|
addq $34, %rdi
|
|
.Ltmp3:
|
|
callq bar
|
|
.Ltmp4:
|
|
jmp .LBB1_6
|
|
.LBB1_6: # %invoke.cont2
|
|
jmp .LBB1_10
|
|
.LBB1_10: # %try.cont8
|
|
movq $0, -8(%rbp)
|
|
.LBB1_11: # %return
|
|
movq -8(%rbp), %rax
|
|
addq $48, %rsp
|
|
popq %rbp
|
|
.cfi_def_cfa %rsp, 8
|
|
retq
|
|
.LBB1_12: # %eh.resume
|
|
.cfi_def_cfa %rbp, 16
|
|
movq -24(%rbp), %rdi
|
|
callq _Unwind_Resume@PLT
|
|
.Lfunc_end1:
|
|
.size foo, .Lfunc_end1-foo
|
|
.cfi_endproc
|
|
.section .gcc_except_table,"a",@progbits
|
|
.p2align 2
|
|
GCC_except_table1:
|
|
.Lexception0:
|
|
.byte 255 # @LPStart Encoding = omit
|
|
.byte 155 # @TType Encoding = indirect pcrel sdata4
|
|
.uleb128 .Lttbase0-.Lttbaseref0
|
|
.Lttbaseref0:
|
|
.byte 1 # Call site Encoding = uleb128
|
|
.uleb128 .Lcst_end0-.Lcst_begin0
|
|
.Lcst_begin0:
|
|
.uleb128 .Ltmp0-.Lfunc_begin0 # >> Call Site 1 <<
|
|
.uleb128 .Ltmp1-.Ltmp0 # Call between .Ltmp0 and .Ltmp1
|
|
.uleb128 .Ltmp2-.Lfunc_begin0 # jumps to .Ltmp2
|
|
.byte 1 # On action: 1
|
|
.uleb128 .Ltmp1-.Lfunc_begin0 # >> Call Site 2 <<
|
|
.uleb128 .Ltmp3-.Ltmp1 # Call between .Ltmp1 and .Ltmp3
|
|
.byte 0 # has no landing pad
|
|
.byte 0 # On action: cleanup
|
|
.uleb128 .Ltmp3-.Lfunc_begin0 # >> Call Site 3 <<
|
|
.uleb128 .Ltmp4-.Ltmp3 # Call between .Ltmp3 and .Ltmp4
|
|
.uleb128 .Ltmp5-.Lfunc_begin0 # jumps to .Ltmp5
|
|
.byte 1 # On action: 1
|
|
.uleb128 .Ltmp4-.Lfunc_begin0 # >> Call Site 4 <<
|
|
.uleb128 .Lfunc_end1-.Ltmp4 # Call between .Ltmp4 and .Lfunc_end1
|
|
.byte 0 # has no landing pad
|
|
.byte 0 # On action: cleanup
|
|
.Lcst_end0:
|
|
.byte 1 # >> Action Record 1 <<
|
|
# Catch TypeInfo 1
|
|
.byte 0 # No further actions
|
|
.p2align 2
|
|
# >> Catch TypeInfos <<
|
|
.Ltmp6: # TypeInfo 1
|
|
.long .L_ZTIi.DW.stub-.Ltmp6
|
|
.Lttbase0:
|
|
.p2align 2
|
|
# -- End function
|
|
|
|
|
|
.text
|
|
.globl foo.cold.1 # -- Begin function foo.cold.1
|
|
.p2align 4, 0x90
|
|
.type foo.cold.1,@function
|
|
foo.cold.1: # @foo.cold.1
|
|
.Lfunc_begin3:
|
|
.cfi_startproc
|
|
.Ltmp2:
|
|
movq %rax, %rcx
|
|
movl %edx, %eax
|
|
movq %rcx, -24(%rbp)
|
|
movl %eax, -28(%rbp)
|
|
# %bb.3: # %catch.dispatch
|
|
movl -28(%rbp), %eax
|
|
movl $1, %ecx
|
|
cmpl %ecx, %eax
|
|
jne .LBB1_12
|
|
# %bb.4: # %catch
|
|
movq -24(%rbp), %rdi
|
|
callq __cxa_begin_catch@PLT
|
|
movl (%rax), %eax
|
|
movl %eax, -32(%rbp)
|
|
movq $0, -8(%rbp)
|
|
callq __cxa_end_catch@PLT
|
|
jmp .LBB1_11
|
|
.Ltmp5:
|
|
movq %rax, %rcx
|
|
movl %edx, %eax
|
|
movq %rcx, -24(%rbp)
|
|
movl %eax, -28(%rbp)
|
|
# %bb.8: # %catch.dispatch3
|
|
movl -28(%rbp), %eax
|
|
movl $1, %ecx
|
|
cmpl %ecx, %eax
|
|
jne .LBB1_12
|
|
# %bb.9: # %catch6
|
|
movq -24(%rbp), %rdi
|
|
callq __cxa_begin_catch@PLT
|
|
movl (%rax), %eax
|
|
movl %eax, -36(%rbp)
|
|
movq $0, -8(%rbp)
|
|
callq __cxa_end_catch@PLT
|
|
jmp .LBB1_11
|
|
.Lfunc_end3:
|
|
.size foo.cold.1, .Lfunc_end3-foo.cold.1
|
|
.cfi_endproc
|
|
|
|
|
|
.text
|
|
.globl main # -- Begin function main
|
|
.p2align 4, 0x90
|
|
.type main,@function
|
|
main: # @main
|
|
.cfi_startproc
|
|
# %bb.0: # %entry
|
|
pushq %rbp
|
|
.cfi_def_cfa_offset 16
|
|
.cfi_offset %rbp, -16
|
|
movq %rsp, %rbp
|
|
.cfi_def_cfa_register %rbp
|
|
subq $16, %rsp
|
|
movl $0, -4(%rbp)
|
|
movl %edi, -8(%rbp)
|
|
movq %rsi, -16(%rbp)
|
|
xorl %eax, %eax
|
|
movl %eax, %edi
|
|
callq foo
|
|
# kill: def $eax killed $eax killed $rax
|
|
addq $16, %rsp
|
|
popq %rbp
|
|
.cfi_def_cfa %rsp, 8
|
|
retq
|
|
.Lfunc_end2:
|
|
.size main, .Lfunc_end2-main
|
|
.cfi_endproc
|
|
# -- End function
|
|
.data
|
|
.p2align 3
|
|
.L_ZTIi.DW.stub:
|
|
.quad _ZTIi
|
|
.hidden DW.ref.__gxx_personality_v0
|
|
.weak DW.ref.__gxx_personality_v0
|
|
.section .data.DW.ref.__gxx_personality_v0,"aGw",@progbits,DW.ref.__gxx_personality_v0,comdat
|
|
.p2align 3
|
|
.type DW.ref.__gxx_personality_v0,@object
|
|
.size DW.ref.__gxx_personality_v0, 8
|
|
DW.ref.__gxx_personality_v0:
|
|
.quad __gxx_personality_v0
|
|
.section ".note.GNU-stack","",@progbits
|
|
.addrsig
|
|
.addrsig_sym bar
|
|
.addrsig_sym __cxa_allocate_exception
|
|
.addrsig_sym __cxa_throw
|
|
.addrsig_sym foo
|
|
.addrsig_sym __gxx_personality_v0
|
|
.addrsig_sym __cxa_begin_catch
|
|
.addrsig_sym __cxa_end_catch
|
|
.addrsig_sym _Unwind_Resume
|
|
.addrsig_sym _ZTIi
|
|
.addrsig_sym _ZTIDn
|
|
.addrsig_sym foo.cold.1
|
|
.addrsig_sym __cxa_begin_catch
|
|
.addrsig_sym __cxa_end_catch
|