summaryrefslogtreecommitdiff
path: root/llvm/test/CodeGen/AArch64/wineh-bti-funclet.ll
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/CodeGen/AArch64/wineh-bti-funclet.ll')
-rw-r--r--llvm/test/CodeGen/AArch64/wineh-bti-funclet.ll79
1 files changed, 79 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/AArch64/wineh-bti-funclet.ll b/llvm/test/CodeGen/AArch64/wineh-bti-funclet.ll
new file mode 100644
index 000000000000..4f4f984b8974
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/wineh-bti-funclet.ll
@@ -0,0 +1,79 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=aarch64-windows -mattr=+bti -o - %s | FileCheck %s
+
+declare i32 @__CxxFrameHandler3(...)
+declare void @may_throw()
+
+; Purpose: For WinEH funclets, entry is call-like: accept `bti c` / `hint #34` or a PAC prologue.
+
+define dso_local void @wineh_funclet() #0 personality ptr @__CxxFrameHandler3 {
+; CHECK-LABEL: wineh_funclet:
+; CHECK: .Lfunc_begin0:
+; CHECK-NEXT: .seh_proc wineh_funclet
+; CHECK-NEXT: .seh_handler __CxxFrameHandler3, @unwind, @except
+; CHECK-NEXT: // %bb.0: // %entry
+; CHECK-NEXT: bti c
+; CHECK-NEXT: .seh_nop
+; CHECK-NEXT: stp x29, x30, [sp, #-32]! // 16-byte Folded Spill
+; CHECK-NEXT: .seh_save_fplr_x 32
+; CHECK-NEXT: mov x29, sp
+; CHECK-NEXT: .seh_set_fp
+; CHECK-NEXT: .seh_endprologue
+; CHECK-NEXT: mov x0, #-2 // =0xfffffffffffffffe
+; CHECK-NEXT: stur x0, [x29, #16]
+; CHECK-NEXT: .Ltmp0: // EH_LABEL
+; CHECK-NEXT: bl may_throw
+; CHECK-NEXT: .Ltmp1: // EH_LABEL
+; CHECK-NEXT: .LBB0_1: // Block address taken
+; CHECK-NEXT: // %try.cont
+; CHECK-NEXT: $ehgcr_0_1:
+; CHECK-NEXT: bti j
+; CHECK-NEXT: .seh_startepilogue
+; CHECK-NEXT: ldp x29, x30, [sp], #32 // 16-byte Folded Reload
+; CHECK-NEXT: .seh_save_fplr_x 32
+; CHECK-NEXT: .seh_endepilogue
+; CHECK-NEXT: ret
+; CHECK-NEXT: .seh_endfunclet
+; CHECK-NEXT: .seh_handlerdata
+; CHECK-NEXT: .word $cppxdata$wineh_funclet@IMGREL
+; CHECK-NEXT: .text
+; CHECK-NEXT: .seh_endproc
+; CHECK-NEXT: .def "?catch$2@?0?wineh_funclet@4HA";
+; CHECK-NEXT: .scl 3;
+; CHECK-NEXT: .type 32;
+; CHECK-NEXT: .endef
+; CHECK-NEXT: .p2align 2
+; CHECK-NEXT: "?catch$2@?0?wineh_funclet@4HA":
+; CHECK-NEXT: .seh_proc "?catch$2@?0?wineh_funclet@4HA"
+; CHECK-NEXT: .seh_handler __CxxFrameHandler3, @unwind, @except
+; CHECK-NEXT: .LBB0_2: // %catch
+; CHECK-NEXT: bti c
+; CHECK-NEXT: .seh_nop
+; CHECK-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
+; CHECK-NEXT: .seh_save_fplr_x 16
+; CHECK-NEXT: .seh_endprologue
+; CHECK-NEXT: bl may_throw
+; CHECK-NEXT: adrp x0, .LBB0_1
+; CHECK-NEXT: add x0, x0, .LBB0_1
+; CHECK-NEXT: .seh_startepilogue
+; CHECK-NEXT: ldp x29, x30, [sp], #16 // 16-byte Folded Reload
+; CHECK-NEXT: .seh_save_fplr_x 16
+; CHECK-NEXT: .seh_endepilogue
+; CHECK-NEXT: ret
+entry:
+ invoke void @may_throw()
+ to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch:
+ %cs = catchswitch within none [label %catch] unwind to caller
+
+catch:
+ %cp = catchpad within %cs [ptr null, i32 0, ptr null]
+ call void @may_throw() ["funclet"(token %cp)]
+ catchret from %cp to label %try.cont
+
+try.cont:
+ ret void
+}
+
+attributes #0 = { noinline "branch-target-enforcement"="true" }