1 ; RUN: llc -o - %s -verify-machineinstrs -mtriple=aarch64-windows | FileCheck %s
3 ; Windows runtime passes the establisher frame as the second argument to the
4 ; termination handler. Check that we copy it into fp.
6 ; CHECK: ?dtor$6@?0?main@4HA":
7 ; CHECK: .seh_proc "?dtor$6@?0?main@4HA"
8 ; CHECK: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
9 ; CHECK-NEXT: .seh_save_fplr_x 16
10 ; CHECK-NEXT: .seh_endprologue
11 ; CHECK-NEXT: mov x29, x1
13 target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
14 target triple = "aarch64-unknown-windows-msvc19.15.26732"
16 ; Function Attrs: noinline nounwind optnone uwtable
17 define dso_local i32 @main() #0 personality ptr @__C_specific_handler {
19 %retval = alloca i32, align 4
20 %Counter = alloca i32, align 4
21 %__exception_code = alloca i32, align 4
22 call void (...) @llvm.localescape(ptr %Counter)
23 store i32 0, ptr %retval, align 4
24 store i32 0, ptr %Counter, align 4
25 %call = invoke i32 @RaiseStatus(i32 -1073741675) #3
26 to label %invoke.cont unwind label %ehcleanup
28 invoke.cont: ; preds = %entry
29 %0 = call ptr @llvm.localaddress()
30 invoke void @"?fin$0@0@main@@"(i8 0, ptr %0) #3
31 to label %invoke.cont1 unwind label %catch.dispatch
33 invoke.cont1: ; preds = %invoke.cont
36 ehcleanup: ; preds = %entry
37 %1 = cleanuppad within none []
38 %2 = call ptr @llvm.localaddress()
39 invoke void @"?fin$0@0@main@@"(i8 1, ptr %2) #3 [ "funclet"(token %1) ]
40 to label %invoke.cont2 unwind label %catch.dispatch
42 invoke.cont2: ; preds = %ehcleanup
43 cleanupret from %1 unwind label %catch.dispatch
45 catch.dispatch: ; preds = %invoke.cont2, %ehcleanup, %invoke.cont
46 %3 = catchswitch within none [label %__except] unwind to caller
48 __except: ; preds = %catch.dispatch
49 %4 = catchpad within %3 [ptr null]
50 catchret from %4 to label %__except3
52 __except3: ; preds = %__except
53 %5 = call i32 @llvm.eh.exceptioncode(token %4)
54 store i32 %5, ptr %__exception_code, align 4
55 %6 = load i32, ptr %Counter, align 4
56 %add = add nsw i32 %6, 5
57 store i32 %add, ptr %Counter, align 4
60 __try.cont: ; preds = %__except3, %invoke.cont1
61 %7 = load i32, ptr %retval, align 4
65 define internal void @"?fin$0@0@main@@"(i8 %abnormal_termination, ptr %frame_pointer) {
67 %frame_pointer.addr = alloca ptr, align 8
68 %abnormal_termination.addr = alloca i8, align 1
69 %0 = call ptr @llvm.localrecover(ptr @main, ptr %frame_pointer, i32 0)
70 store ptr %frame_pointer, ptr %frame_pointer.addr, align 8
71 store i8 %abnormal_termination, ptr %abnormal_termination.addr, align 1
72 store i32 3, ptr %0, align 4
73 call void @"?fin$1@0@main@@"(i8 0, ptr %frame_pointer)
74 %1 = load i32, ptr %0, align 4
75 %add = add nsw i32 %1, 2
76 store i32 %add, ptr %0, align 4
77 %call = call i32 @RaiseStatus(i32 -1073741675)
81 ; Function Attrs: nounwind readnone
82 declare ptr @llvm.localrecover(ptr, ptr, i32) #1
84 define internal void @"?fin$1@0@main@@"(i8 %abnormal_termination, ptr %frame_pointer) {
86 %frame_pointer.addr = alloca ptr, align 8
87 %abnormal_termination.addr = alloca i8, align 1
88 %0 = call ptr @llvm.localrecover(ptr @main, ptr %frame_pointer, i32 0)
89 store ptr %frame_pointer, ptr %frame_pointer.addr, align 8
90 store i8 %abnormal_termination, ptr %abnormal_termination.addr, align 1
91 %1 = load i32, ptr %0, align 4
92 %cmp = icmp eq i32 %1, 3
93 br i1 %cmp, label %if.then, label %if.end
95 if.then: ; preds = %entry
96 %2 = load i32, ptr %0, align 4
97 %add = add nsw i32 %2, 1
98 store i32 %add, ptr %0, align 4
101 if.end: ; preds = %if.then, %entry
105 declare dso_local i32 @RaiseStatus(...)
107 declare dso_local i32 @__C_specific_handler(...)
109 ; Function Attrs: nounwind readnone
110 declare ptr @llvm.localaddress() #1
112 ; Function Attrs: nounwind readnone
113 declare i32 @llvm.eh.exceptioncode(token) #1
115 ; Function Attrs: nounwind
116 declare void @llvm.localescape(...) #2
118 attributes #0 = { noinline nounwind optnone uwtable }
119 attributes #1 = { nounwind readnone }
120 attributes #2 = { nounwind }
121 attributes #3 = { noinline }