summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-09-08 22:44:41 +0000
committerReid Kleckner <rnk@google.com>2015-09-08 22:44:41 +0000
commitdf1295173f244ce9d1c67ced33e05ba00042308d (patch)
treeb124401bb445e92c27bf597157be919fc293bfc1 /llvm/test
parent18203f763ccf8863f49cfc40f08253a7764ef657 (diff)
downloadbcm5719-llvm-df1295173f244ce9d1c67ced33e05ba00042308d.tar.gz
bcm5719-llvm-df1295173f244ce9d1c67ced33e05ba00042308d.zip
[WinEH] Emit prologues and epilogues for funclets
Summary: 32-bit funclets have short prologues that allocate enough stack for the largest call in the whole function. The runtime saves CSRs for the funclet. It doesn't restore CSRs after we finally transfer control back to the parent funciton via a CATCHRET, but that's a separate issue. 32-bit funclets also have to adjust the incoming EBP value, which is what llvm.x86.seh.recoverframe does in the old model. 64-bit funclets need to spill CSRs as normal. For simplicity, this just spills the same set of CSRs as the parent function, rather than trying to compute different CSR sets for the parent function and each funclet. 64-bit funclets also allocate enough stack space for the largest outgoing call frame, like 32-bit. Reviewers: majnemer Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D12546 llvm-svn: 247092
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/CodeGen/X86/win-catchpad-csrs.ll136
-rw-r--r--llvm/test/CodeGen/X86/win-catchpad.ll68
2 files changed, 190 insertions, 14 deletions
diff --git a/llvm/test/CodeGen/X86/win-catchpad-csrs.ll b/llvm/test/CodeGen/X86/win-catchpad-csrs.ll
new file mode 100644
index 00000000000..f765207d19d
--- /dev/null
+++ b/llvm/test/CodeGen/X86/win-catchpad-csrs.ll
@@ -0,0 +1,136 @@
+; RUN: llc -mtriple=i686-pc-windows-msvc < %s | FileCheck --check-prefix=X86 %s
+; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck --check-prefix=X64 %s
+
+%rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
+%eh.CatchableType = type { i32, i8*, i32, i32, i32, i32, i8* }
+%eh.CatchableTypeArray.1 = type { i32, [1 x %eh.CatchableType*] }
+%eh.ThrowInfo = type { i32, i8*, i8*, i8* }
+%eh.CatchHandlerType = type { i32, i8* }
+
+$"\01??_R0H@8" = comdat any
+
+@"\01??_7type_info@@6B@" = external constant i8*
+@"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
+
+@llvm.eh.handlertype.H.0 = private unnamed_addr constant %eh.CatchHandlerType { i32 0, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*) }, section "llvm.metadata"
+@llvm.eh.handlertype.H.1 = private unnamed_addr constant %eh.CatchHandlerType { i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*) }, section "llvm.metadata"
+
+declare i32 @getint()
+declare void @useints(...)
+declare void @f(i32 %p)
+declare i32 @__CxxFrameHandler3(...)
+
+define i32 @try_catch_catch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+entry:
+ %a = call i32 @getint()
+ %b = call i32 @getint()
+ %c = call i32 @getint()
+ %d = call i32 @getint()
+ call void (...) @useints(i32 %a, i32 %b, i32 %c, i32 %d)
+ invoke void @f(i32 1)
+ to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %0 = catchpad [%eh.CatchHandlerType* @llvm.eh.handlertype.H.0, i8* null]
+ to label %catch unwind label %catchendblock
+
+catch:
+ invoke void @f(i32 2)
+ to label %invoke.cont.2 unwind label %catchendblock
+
+invoke.cont.2: ; preds = %catch
+ catchret %0 to label %try.cont
+
+try.cont: ; preds = %entry, %invoke.cont.2, %invoke.cont.3
+ ret i32 0
+
+catchendblock: ; preds = %catch,
+ catchendpad unwind to caller
+}
+
+; X86-LABEL: _try_catch_catch:
+; X86: pushl %ebp
+; X86: movl %esp, %ebp
+; X86: pushl %ebx
+; X86: pushl %edi
+; X86: pushl %esi
+; X86: subl ${{[0-9]+}}, %esp
+; X86: calll _getint
+; X86: calll _getint
+; X86: calll _getint
+; X86: calll _getint
+; X86: calll _useints
+; X86: movl $0, -{{[0-9]+}}(%ebp)
+; X86: movl $1, (%esp)
+; X86: calll _f
+; X86: [[contbb:LBB0_[0-9]+]]:
+; X86: movl -{{[0-9]+}}(%ebp), %esp
+; X86: addl ${{[0-9]+}}, %esp
+; X86: popl %esi
+; X86: popl %edi
+; X86: popl %ebx
+; X86: popl %ebp
+; X86: retl
+
+; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
+; X86-NOT: pushl
+; X86: addl $12, %ebp
+; X86: subl $16, %esp
+; X86: movl $1, -{{[0-9]+}}(%ebp)
+; X86: movl $2, (%esp)
+; X86: calll _f
+; X86: movl $[[contbb]], %eax
+; X86-NEXT: addl $16, %esp
+; X86-NOT: popl
+; X86-NEXT: retl
+
+; X86: L__ehtable$try_catch_catch:
+; X86: $handlerMap$0$try_catch_catch:
+; X86: .long 0
+; X86: .long "??_R0H@8"
+; X86: .long 0
+; X86: .long [[catch1bb]]
+
+; X64-LABEL: try_catch_catch:
+; X64: pushq %rbp
+; X64: .seh_pushreg 5
+; X64: pushq %rsi
+; X64: .seh_pushreg 6
+; X64: pushq %rdi
+; X64: .seh_pushreg 7
+; X64: pushq %rbx
+; X64: .seh_pushreg 3
+; X64: subq $40, %rsp
+; X64: .seh_stackalloc 40
+; X64: leaq 32(%rsp), %rbp
+; X64: .seh_setframe 5, 32
+; X64: callq getint
+; X64: callq getint
+; X64: callq getint
+; X64: callq getint
+; X64: callq useints
+; X64: movl $1, %ecx
+; X64: callq f
+; X64: [[contbb:\.LBB0_[0-9]+]]:
+; X64: addq $40, %rsp
+; X64: popq %rbp
+; X64: retq
+
+; X64: [[catch1bb:\.LBB0_[0-9]+]]: # %catch{{$}}
+; X64: movq %rdx, 16(%rsp)
+; X64: pushq %rbp
+; X64: movq %rdx, %rbp
+; X64: subq $32, %rsp
+; X64: movl $2, %ecx
+; X64: callq f
+; X64: leaq [[contbb]](%rip), %rax
+; X64: addq $32, %rsp
+; X64: popq %rbp
+; X64: retq
+
+; X64: $handlerMap$0$try_catch_catch:
+; X64: .long 0
+; X64: .long "??_R0H@8"@IMGREL
+; X64: .long 0
+; X64: .long [[catch1bb]]@IMGREL
+; X64: .long 56
diff --git a/llvm/test/CodeGen/X86/win-catchpad.ll b/llvm/test/CodeGen/X86/win-catchpad.ll
index 607d948e3d1..7ab59ab7223 100644
--- a/llvm/test/CodeGen/X86/win-catchpad.ll
+++ b/llvm/test/CodeGen/X86/win-catchpad.ll
@@ -27,12 +27,14 @@ $"\01??_R0H@8" = comdat any
@llvm.eh.handlertype.H.0 = private unnamed_addr constant %eh.CatchHandlerType { i32 0, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*) }, section "llvm.metadata"
@llvm.eh.handlertype.H.1 = private unnamed_addr constant %eh.CatchHandlerType { i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*) }, section "llvm.metadata"
-declare void @f(i32 %p)
+declare void @f(i32 %p, i32* %l)
declare i32 @__CxxFrameHandler3(...)
+declare void @barrier()
define i32 @try_catch_catch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
entry:
- invoke void @f(i32 1)
+ %local = alloca i32
+ invoke void @f(i32 1, i32* %local)
to label %try.cont unwind label %catch.dispatch
catch.dispatch: ; preds = %entry
@@ -40,7 +42,11 @@ catch.dispatch: ; preds = %entry
to label %catch unwind label %catch.dispatch.2
catch: ; preds = %catch.dispatch
- invoke void @f(i32 2)
+ ; FIXME: Remove this barrier once we add more real register allocation barriers.
+ invoke void @barrier()
+ to label %barrier.split unwind label %catchendblock
+barrier.split:
+ invoke void @f(i32 2, i32* %local)
to label %invoke.cont.2 unwind label %catchendblock
invoke.cont.2: ; preds = %catch
@@ -51,7 +57,7 @@ catch.dispatch.2: ; preds = %catch.dispatch
to label %catch.2 unwind label %catchendblock
catch.2: ; preds = %catch.dispatch.2
- invoke void @f(i32 3)
+ invoke void @f(i32 3, i32* %local)
to label %invoke.cont.3 unwind label %catchendblock
invoke.cont.3: ; preds = %catch.2
@@ -66,24 +72,37 @@ catchendblock: ; preds = %catch, %catch.2, %c
; X86-LABEL: _try_catch_catch:
; X86: movl $0, -{{[0-9]+}}(%ebp)
-; X86: movl $1, (%esp)
+; X86: leal -[[local_offs:[0-9]+]](%ebp), %[[addr_reg:[a-z]+]]
+; X86-DAG: movl %[[addr_reg]], 4(%esp)
+; X86-DAG: movl $1, (%esp)
; X86: calll _f
; X86: [[contbb:LBB0_[0-9]+]]:
; X86: movl -{{[0-9]+}}(%ebp), %esp
; X86: retl
; X86: [[catch1bb:LBB0_[0-9]+]]: # %catch{{$}}
+; X86: addl $12, %ebp
+; X86: subl $8, %esp
+; X86: calll _barrier
; X86: movl $1, -{{[0-9]+}}(%ebp)
-; X86: movl $2, (%esp)
+; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
+; X86-DAG: movl %[[addr_reg]], 4(%esp)
+; X86-DAG: movl $2, (%esp)
; X86: calll _f
; X86: movl $[[contbb]], %eax
+; X86-NEXT: addl $8, %esp
; X86-NEXT: retl
; X86: [[catch2bb:LBB0_[0-9]+]]: # %catch.2{{$}}
+; X86: addl $12, %ebp
+; X86: subl $8, %esp
; X86: movl $1, -{{[0-9]+}}(%ebp)
-; X86: movl $3, (%esp)
+; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
+; X86-DAG: movl %[[addr_reg]], 4(%esp)
+; X86-DAG: movl $3, (%esp)
; X86: calll _f
; X86: movl $[[contbb]], %eax
+; X86-NEXT: addl $8, %esp
; X86-NEXT: retl
; X86: L__ehtable$try_catch_catch:
@@ -98,33 +117,54 @@ catchendblock: ; preds = %catch, %catch.2, %c
; X86: .long [[catch2bb]]
; X64-LABEL: try_catch_catch:
-; X64: movl $1, %ecx
+; X64: pushq %rbp
+; X64: .seh_pushreg 5
+; X64: subq $48, %rsp
+; X64: .seh_stackalloc 48
+; X64: leaq 48(%rsp), %rbp
+; X64: .seh_setframe 5, 48
+; X64-DAG: leaq -[[local_offs:[0-9]+]](%rbp), %rdx
+; X64-DAG: movl $1, %ecx
; X64: callq f
; X64: [[contbb:\.LBB0_[0-9]+]]:
+; X64: addq $48, %rsp
+; X64: popq %rbp
; X64: retq
; X64: [[catch1bb:\.LBB0_[0-9]+]]: # %catch{{$}}
-; X64: movl $2, %ecx
+; X64: movq %rdx, 16(%rsp)
+; X64: pushq %rbp
+; X64: movq %rdx, %rbp
+; X64: subq $32, %rsp
+; X64-DAG: leaq -[[local_offs]](%rbp), %rdx
+; X64-DAG: movl $2, %ecx
; X64: callq f
; X64: leaq [[contbb]](%rip), %rax
+; X64: addq $32, %rsp
+; X64: popq %rbp
; X64: retq
; X64: [[catch2bb:\.LBB0_[0-9]+]]: # %catch.2{{$}}
-; X64: movl $3, %ecx
+; X64: movq %rdx, 16(%rsp)
+; X64: pushq %rbp
+; X64: movq %rdx, %rbp
+; X64: subq $32, %rsp
+; X64-DAG: leaq -[[local_offs]](%rbp), %rdx
+; X64-DAG: movl $3, %ecx
; X64: callq f
; X64: leaq [[contbb]](%rip), %rax
+; X64: addq $32, %rsp
+; X64: popq %rbp
; X64: retq
-; FIXME: Get rid of these parent_frame_offset things below. They are leftover
-; from our IR outlining strategy.
; X64: $handlerMap$0$try_catch_catch:
; X64: .long 0
; X64: .long "??_R0H@8"@IMGREL
; X64: .long 0
; X64: .long [[catch1bb]]@IMGREL
-; X64 .long .Lcatch$parent_frame_offset
+; X64: .long 56
; X64: .long 0
; X64: .long "??_R0H@8"@IMGREL
; X64: .long 0
; X64: .long [[catch2bb]]@IMGREL
-; X64 .long .Lcatch.2$parent_frame_offset
+; X64: .long 56
OpenPOWER on IntegriCloud