1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-22 20:43:44 +02:00
llvm-mirror/test/CodeGen/X86/win-funclet-cfi.ll
David Majnemer ccf132c096 [WinEH] Create a separate MBB for funclet prologues
Our current emission strategy is to emit the funclet prologue in the
CatchPad's normal destination.  This is problematic because
intra-funclet control flow to the normal destination is not erroneous
and results in us reevaluating the prologue if said control flow is
taken.

Instead, use the CatchPad's location for the funclet prologue.  This
correctly models our desire to have unwind edges evaluate the prologue
but edges to the normal destination result in typical control flow.

Differential Revision: http://reviews.llvm.org/D13424

llvm-svn: 249483
2015-10-06 23:31:59 +00:00

99 lines
2.5 KiB
LLVM

; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
define void @"\01?f@@YAXXZ"(i1 %B) personality i32 (...)* @__CxxFrameHandler3 {
entry:
invoke void @g()
to label %unreachable unwind label %cleanupblock
cleanupblock:
%cleanp = cleanuppad []
call void @g()
cleanupret %cleanp unwind label %catch.dispatch
catch.dispatch:
%cp = catchpad [i8* null, i32 64, i8* null]
to label %catch unwind label %catchendblock
catch:
call void @g()
catchret %cp to label %try.cont
try.cont:
ret void
catchendblock:
catchendpad unwind to caller
unreachable:
unreachable
}
declare void @g()
declare i32 @__CxxFrameHandler3(...)
; Destructors need CFI but they shouldn't use the .seh_handler directive.
; CHECK: "?dtor$[[cleanup:[0-9]+]]@?0??f@@YAXXZ@4HA":
; CHECK: .seh_proc "?dtor$[[cleanup]]@?0??f@@YAXXZ@4HA"
; CHECK-NOT: .seh_handler __CxxFrameHandler3
; CHECK: LBB0_[[cleanup]]: # %cleanupblock{{$}}
; Emit CFI for pushing RBP.
; CHECK: movq %rdx, 16(%rsp)
; CHECK: pushq %rbp
; CHECK: .seh_pushreg 5
; Emit CFI for allocating from the stack pointer.
; CHECK: subq $32, %rsp
; CHECK: .seh_stackalloc 32
; CHECK: leaq 48(%rdx), %rbp
; CHECK-NOT: .seh_setframe
; Prologue is done, emit the .seh_endprologue directive.
; CHECK: .seh_endprologue
; Make sure there is a nop after a call if the call precedes the epilogue.
; CHECK: callq g
; CHECK-NEXT: nop
; Don't emit a reference to the LSDA.
; CHECK: .seh_handlerdata
; CHECK-NOT: .long ("$cppxdata$?f@@YAXXZ")@IMGREL
; CHECK-NEXT: .text
; CHECK: .seh_endproc
; CHECK: "?catch$[[catch:[0-9]+]]@?0??f@@YAXXZ@4HA":
; CHECK: .seh_proc "?catch$[[catch]]@?0??f@@YAXXZ@4HA"
; CHECK-NEXT: .seh_handler __CxxFrameHandler3, @unwind, @except
; CHECK: LBB0_[[catch]]: # %catch.dispatch{{$}}
; Emit CFI for pushing RBP.
; CHECK: movq %rdx, 16(%rsp)
; CHECK: pushq %rbp
; CHECK: .seh_pushreg 5
; Emit CFI for allocating from the stack pointer.
; CHECK: subq $32, %rsp
; CHECK: .seh_stackalloc 32
; CHECK: leaq 48(%rdx), %rbp
; CHECK-NOT: .seh_setframe
; Prologue is done, emit the .seh_endprologue directive.
; CHECK: .seh_endprologue
; Make sure there is at least one instruction after a call before the epilogue.
; CHECK: callq g
; CHECK-NEXT: leaq .LBB0_{{[0-9]+}}(%rip), %rax
; Emit a reference to the LSDA.
; CHECK: .seh_handlerdata
; CHECK-NEXT: .long ("$cppxdata$?f@@YAXXZ")@IMGREL
; CHECK-NEXT: .text
; CHECK: .seh_endproc