1; RUN: llc -o - %s -verify-machineinstrs -mtriple=aarch64-windows | FileCheck %s 2 3; Windows runtime passes the establisher frame as the second argument to the 4; termination handler. Check that we copy it into fp. 5 6; CHECK: ?dtor$3@?0?main@4HA": 7; CHECK: .seh_proc "?dtor$3@?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 12 13target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128" 14target triple = "aarch64-unknown-windows-msvc19.15.26732" 15 16; Function Attrs: noinline nounwind optnone uwtable 17define dso_local i32 @main() #0 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) { 18entry: 19 %retval = alloca i32, align 4 20 %Counter = alloca i32, align 4 21 %__exception_code = alloca i32, align 4 22 call void (...) @llvm.localescape(i32* %Counter) 23 store i32 0, i32* %retval, align 4 24 store i32 0, i32* %Counter, align 4 25 %call = invoke i32 bitcast (i32 (...)* @RaiseStatus to i32 (i32)*)(i32 -1073741675) #3 26 to label %invoke.cont unwind label %ehcleanup 27 28invoke.cont: ; preds = %entry 29 %0 = call i8* @llvm.localaddress() 30 invoke void @"?fin$0@0@main@@"(i8 0, i8* %0) #3 31 to label %invoke.cont1 unwind label %catch.dispatch 32 33invoke.cont1: ; preds = %invoke.cont 34 br label %__try.cont 35 36ehcleanup: ; preds = %entry 37 %1 = cleanuppad within none [] 38 %2 = call i8* @llvm.localaddress() 39 invoke void @"?fin$0@0@main@@"(i8 1, i8* %2) #3 [ "funclet"(token %1) ] 40 to label %invoke.cont2 unwind label %catch.dispatch 41 42invoke.cont2: ; preds = %ehcleanup 43 cleanupret from %1 unwind label %catch.dispatch 44 45catch.dispatch: ; preds = %invoke.cont2, %ehcleanup, %invoke.cont 46 %3 = catchswitch within none [label %__except] unwind to caller 47 48__except: ; preds = %catch.dispatch 49 %4 = catchpad within %3 [i8* null] 50 catchret from %4 to label %__except3 51 52__except3: ; preds = %__except 53 %5 = call i32 @llvm.eh.exceptioncode(token %4) 54 store i32 %5, i32* %__exception_code, align 4 55 %6 = load i32, i32* %Counter, align 4 56 %add = add nsw i32 %6, 5 57 store i32 %add, i32* %Counter, align 4 58 br label %__try.cont 59 60__try.cont: ; preds = %__except3, %invoke.cont1 61 %7 = load i32, i32* %retval, align 4 62 ret i32 %7 63} 64 65define internal void @"?fin$0@0@main@@"(i8 %abnormal_termination, i8* %frame_pointer) { 66entry: 67 %frame_pointer.addr = alloca i8*, align 8 68 %abnormal_termination.addr = alloca i8, align 1 69 %0 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @main to i8*), i8* %frame_pointer, i32 0) 70 %Counter = bitcast i8* %0 to i32* 71 store i8* %frame_pointer, i8** %frame_pointer.addr, align 8 72 store i8 %abnormal_termination, i8* %abnormal_termination.addr, align 1 73 store i32 3, i32* %Counter, align 4 74 call void @"?fin$1@0@main@@"(i8 0, i8* %frame_pointer) 75 %1 = load i32, i32* %Counter, align 4 76 %add = add nsw i32 %1, 2 77 store i32 %add, i32* %Counter, align 4 78 %call = call i32 bitcast (i32 (...)* @RaiseStatus to i32 (i32)*)(i32 -1073741675) 79 ret void 80} 81 82; Function Attrs: nounwind readnone 83declare i8* @llvm.localrecover(i8*, i8*, i32) #1 84 85define internal void @"?fin$1@0@main@@"(i8 %abnormal_termination, i8* %frame_pointer) { 86entry: 87 %frame_pointer.addr = alloca i8*, align 8 88 %abnormal_termination.addr = alloca i8, align 1 89 %0 = call i8* @llvm.localrecover(i8* bitcast (i32 ()* @main to i8*), i8* %frame_pointer, i32 0) 90 %Counter = bitcast i8* %0 to i32* 91 store i8* %frame_pointer, i8** %frame_pointer.addr, align 8 92 store i8 %abnormal_termination, i8* %abnormal_termination.addr, align 1 93 %1 = load i32, i32* %Counter, align 4 94 %cmp = icmp eq i32 %1, 3 95 br i1 %cmp, label %if.then, label %if.end 96 97if.then: ; preds = %entry 98 %2 = load i32, i32* %Counter, align 4 99 %add = add nsw i32 %2, 1 100 store i32 %add, i32* %Counter, align 4 101 br label %if.end 102 103if.end: ; preds = %if.then, %entry 104 ret void 105} 106 107declare dso_local i32 @RaiseStatus(...) 108 109declare dso_local i32 @__C_specific_handler(...) 110 111; Function Attrs: nounwind readnone 112declare i8* @llvm.localaddress() #1 113 114; Function Attrs: nounwind readnone 115declare i32 @llvm.eh.exceptioncode(token) #1 116 117; Function Attrs: nounwind 118declare void @llvm.localescape(...) #2 119 120attributes #0 = { noinline nounwind optnone uwtable } 121attributes #1 = { nounwind readnone } 122attributes #2 = { nounwind } 123attributes #3 = { noinline } 124