[WinEH] Find root frame correctly in CLR funclets
[oota-llvm.git] / test / CodeGen / WinEH / wineh-coreclr.ll
index 56675fefae748c6d1c87c55836e920f11bee8894..079993f74dbbcdd71dceec0b05ee146db172264d 100644 (file)
@@ -1,7 +1,9 @@
-; RUN: llc -mtriple=x86_64-pc-windows-coreclr < %s | FileCheck %s
+; RUN: llc -mtriple=x86_64-pc-windows-coreclr -verify-machineinstrs < %s | FileCheck %s
 
 declare void @ProcessCLRException()
 declare void @f(i32)
+declare void @g(i8 addrspace(1)*)
+declare i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token)
 
 ; Simplified IR for pseudo-C# like the following:
 ; void test1() {
@@ -30,7 +32,9 @@ declare void @f(i32)
 define void @test1() personality i8* bitcast (void ()* @ProcessCLRException to i8*) {
 entry:
 ; CHECK: # %entry
+; CHECK: leaq [[FPOffset:[0-9]+]](%rsp), %rbp
 ; CHECK: .seh_endprologue
+; CHECK: movq %rsp, [[PSPSymOffset:[0-9]+]](%rsp)
 ; CHECK: [[L_before_f1:.+]]:
 ; CHECK-NEXT: movl $1, %ecx
 ; CHECK-NEXT: callq f
@@ -50,7 +54,18 @@ catch1.pad:
   %catch1 = catchpad [i32 1]
     to label %catch1.body unwind label %catch2.pad
 catch1.body:
+; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
+;                        ^ all funclets use the same frame size
+; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
+;                              ^ establisher frame pointer passed in rcx
+; CHECK: movq %rcx, [[PSPSymOffset]](%rsp)
+; CHECK: leaq [[FPOffset]](%rcx), %rbp
 ; CHECK: .seh_endprologue
+; CHECK: movq %rdx, %rcx
+;             ^ exception pointer passed in rdx
+; CHECK-NEXT: callq g
+  %exn1 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch1)
+  call void @g(i8 addrspace(1)* %exn1)
 ; CHECK: [[L_before_f3:.+]]:
 ; CHECK-NEXT: movl $3, %ecx
 ; CHECK-NEXT: callq f
@@ -64,7 +79,18 @@ catch2.pad:
   %catch2 = catchpad [i32 2]
     to label %catch2.body unwind label %catch.end
 catch2.body:
+; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
+;                        ^ all funclets use the same frame size
+; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
+;                              ^ establisher frame pointer passed in rcx
+; CHECK: movq %rcx, [[PSPSymOffset]](%rsp)
+; CHECK: leaq [[FPOffset]](%rcx), %rbp
 ; CHECK: .seh_endprologue
+; CHECK: movq %rdx, %rcx
+;             ^ exception pointer passed in rdx
+; CHECK-NEXT: callq g
+  %exn2 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch2)
+  call void @g(i8 addrspace(1)* %exn2)
 ; CHECK: [[L_before_f4:.+]]:
 ; CHECK-NEXT: movl $4, %ecx
 ; CHECK-NEXT: callq f
@@ -82,6 +108,12 @@ try_in_catch:
 fault.pad:
 ; CHECK: .seh_proc [[L_fault:[^ ]+]]
   %fault = cleanuppad [i32 undef]
+; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
+;                        ^ all funclets use the same frame size
+; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
+;                              ^ establisher frame pointer passed in rcx
+; CHECK: movq %rcx, [[PSPSymOffset]](%rsp)
+; CHECK: leaq [[FPOffset]](%rcx), %rbp
 ; CHECK: .seh_endprologue
 ; CHECK: [[L_before_f6:.+]]:
 ; CHECK-NEXT: movl $6, %ecx
@@ -103,6 +135,12 @@ finally.clone:
 finally.pad:
 ; CHECK: .seh_proc [[L_finally:[^ ]+]]
   %finally = cleanuppad []
+; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
+;                        ^ all funclets use the same frame size
+; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
+;                              ^ establisher frame pointer passed in rcx
+; CHECK: movq %rcx, [[PSPSymOffset]](%rsp)
+; CHECK: leaq [[FPOffset]](%rcx), %rbp
 ; CHECK: .seh_endprologue
 ; CHECK: [[L_before_f7:.+]]:
 ; CHECK-NEXT: movl $7, %ecx