llvm/llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2

; PauthLR is controlled via a combination of -mbranch-protection and +pauth-lr.
; -mbranch-protection=+pc enables branch protection. If the feature +pauth-lr
; is available (v9.5a onwards) then non-NOP instructions are used; otherwise
; NOP instructions are used.

; There are 6 cases to cover:

; feature \ -mbranch-protection= |    none    | pac-ret |   pac-ret+pc
; ------------------------------------------------------------------------
; without +pauth-lr              | no codegen | old pac |     NOP pauth-lr
;    with +pauth-lr              | no codegen | old pac | non-NOP pauth-lr

; sign-return-address.ll tests combinations of -mbranch-protection=none/pac-ret
; and whether +pauth-lr is present or not.

; sign-return-address-pauth-lr.ll is identical, with the addition of the function
; attribute, which enables -mbranch-protection=pac-ret+pc, and therefore tests
; the remaining parameter combinations in the table:

; RUN: llc -mtriple=aarch64              < %s | FileCheck --check-prefixes=CHECK,COMPAT %s
; RUN: llc -mtriple=aarch64 -mattr=v8.3a < %s | FileCheck --check-prefixes=CHECK,V83A %s
; RUN: llc -mtriple=aarch64 -mattr=v9a -mattr=pauth-lr < %s | FileCheck --check-prefixes=PAUTHLR %s

define i32 @leaf(i32 %x) "branch-protection-pauth-lr" {
; CHECK-LABEL: leaf:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ret
;
; PAUTHLR-LABEL: leaf:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:    ret
  ret i32 %x
}

define i32 @leaf_sign_none(i32 %x) "branch-protection-pauth-lr"   {
; CHECK-LABEL: leaf_sign_none:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ret
;
; PAUTHLR-LABEL: leaf_sign_none:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:    ret
  ret i32 %x
}

define i32 @leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="non-leaf"  {
; CHECK-LABEL: leaf_sign_non_leaf:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ret
;
; PAUTHLR-LABEL: leaf_sign_non_leaf:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:    ret
  ret i32 %x
}

define i32 @leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" {
; COMPAT-LABEL: leaf_sign_all:
; COMPAT:       // %bb.0:
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:  .Ltmp0:
; COMPAT-NEXT:    hint #25
; COMPAT-NEXT:    .cfi_negate_ra_state
; COMPAT-NEXT:    adr x16, .Ltmp0
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:    hint #29
; COMPAT-NEXT:    ret
;
; V83A-LABEL: leaf_sign_all:
; V83A:       // %bb.0:
; V83A-NEXT:    hint #39
; V83A-NEXT:  .Ltmp0:
; V83A-NEXT:    paciasp
; V83A-NEXT:    .cfi_negate_ra_state
; V83A-NEXT:    adr x16, .Ltmp0
; V83A-NEXT:    hint #39
; V83A-NEXT:    retaa
;
; PAUTHLR-LABEL: leaf_sign_all:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:  .Ltmp0:
; PAUTHLR-NEXT:    paciasppc
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    retaasppc .Ltmp0
  ret i32 %x
}

define i64 @leaf_clobbers_lr(i64 %x) "branch-protection-pauth-lr" "sign-return-address"="non-leaf"  {
; COMPAT-LABEL: leaf_clobbers_lr:
; COMPAT:       // %bb.0:
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:  .Ltmp1:
; COMPAT-NEXT:    hint #25
; COMPAT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT:    .cfi_negate_ra_state
; COMPAT-NEXT:    .cfi_def_cfa_offset 16
; COMPAT-NEXT:    .cfi_offset w30, -16
; COMPAT-NEXT:    //APP
; COMPAT-NEXT:    mov x30, x0
; COMPAT-NEXT:    //NO_APP
; COMPAT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; COMPAT-NEXT:    adr x16, .Ltmp1
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:    hint #29
; COMPAT-NEXT:    ret
;
; V83A-LABEL: leaf_clobbers_lr:
; V83A:       // %bb.0:
; V83A-NEXT:    hint #39
; V83A-NEXT:  .Ltmp1:
; V83A-NEXT:    paciasp
; V83A-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT:    .cfi_negate_ra_state
; V83A-NEXT:    .cfi_def_cfa_offset 16
; V83A-NEXT:    .cfi_offset w30, -16
; V83A-NEXT:    //APP
; V83A-NEXT:    mov x30, x0
; V83A-NEXT:    //NO_APP
; V83A-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; V83A-NEXT:    adr x16, .Ltmp1
; V83A-NEXT:    hint #39
; V83A-NEXT:    retaa
;
; PAUTHLR-LABEL: leaf_clobbers_lr:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:  .Ltmp1:
; PAUTHLR-NEXT:    paciasppc
; PAUTHLR-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    .cfi_def_cfa_offset 16
; PAUTHLR-NEXT:    .cfi_offset w30, -16
; PAUTHLR-NEXT:    //APP
; PAUTHLR-NEXT:    mov x30, x0
; PAUTHLR-NEXT:    //NO_APP
; PAUTHLR-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; PAUTHLR-NEXT:    retaasppc .Ltmp1
  call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1
  ret i64 %x
}

declare i32 @foo(i32)

define i32 @non_leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" {
; COMPAT-LABEL: non_leaf_sign_all:
; COMPAT:       // %bb.0:
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:  .Ltmp2:
; COMPAT-NEXT:    hint #25
; COMPAT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT:    .cfi_negate_ra_state
; COMPAT-NEXT:    .cfi_def_cfa_offset 16
; COMPAT-NEXT:    .cfi_offset w30, -16
; COMPAT-NEXT:    bl foo
; COMPAT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; COMPAT-NEXT:    adr x16, .Ltmp2
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:    hint #29
; COMPAT-NEXT:    ret
;
; V83A-LABEL: non_leaf_sign_all:
; V83A:       // %bb.0:
; V83A-NEXT:    hint #39
; V83A-NEXT:  .Ltmp2:
; V83A-NEXT:    paciasp
; V83A-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT:    .cfi_negate_ra_state
; V83A-NEXT:    .cfi_def_cfa_offset 16
; V83A-NEXT:    .cfi_offset w30, -16
; V83A-NEXT:    bl foo
; V83A-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; V83A-NEXT:    adr x16, .Ltmp2
; V83A-NEXT:    hint #39
; V83A-NEXT:    retaa
;
; PAUTHLR-LABEL: non_leaf_sign_all:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:  .Ltmp2:
; PAUTHLR-NEXT:    paciasppc
; PAUTHLR-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    .cfi_def_cfa_offset 16
; PAUTHLR-NEXT:    .cfi_offset w30, -16
; PAUTHLR-NEXT:    bl foo
; PAUTHLR-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; PAUTHLR-NEXT:    retaasppc .Ltmp2
  %call = call i32 @foo(i32 %x)
  ret i32 %call
}

define i32 @non_leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="non-leaf"  {
; COMPAT-LABEL: non_leaf_sign_non_leaf:
; COMPAT:       // %bb.0:
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:  .Ltmp3:
; COMPAT-NEXT:    hint #25
; COMPAT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT:    .cfi_negate_ra_state
; COMPAT-NEXT:    .cfi_def_cfa_offset 16
; COMPAT-NEXT:    .cfi_offset w30, -16
; COMPAT-NEXT:    bl foo
; COMPAT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; COMPAT-NEXT:    adr x16, .Ltmp3
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:    hint #29
; COMPAT-NEXT:    ret
;
; V83A-LABEL: non_leaf_sign_non_leaf:
; V83A:       // %bb.0:
; V83A-NEXT:    hint #39
; V83A-NEXT:  .Ltmp3:
; V83A-NEXT:    paciasp
; V83A-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT:    .cfi_negate_ra_state
; V83A-NEXT:    .cfi_def_cfa_offset 16
; V83A-NEXT:    .cfi_offset w30, -16
; V83A-NEXT:    bl foo
; V83A-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; V83A-NEXT:    adr x16, .Ltmp3
; V83A-NEXT:    hint #39
; V83A-NEXT:    retaa
;
; PAUTHLR-LABEL: non_leaf_sign_non_leaf:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:  .Ltmp3:
; PAUTHLR-NEXT:    paciasppc
; PAUTHLR-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    .cfi_def_cfa_offset 16
; PAUTHLR-NEXT:    .cfi_offset w30, -16
; PAUTHLR-NEXT:    bl foo
; PAUTHLR-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; PAUTHLR-NEXT:    retaasppc .Ltmp3
  %call = call i32 @foo(i32 %x)
  ret i32 %call
}

; Should not use the RETAA instruction.
define i32 @non_leaf_scs(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="non-leaf" shadowcallstack "target-features"="+v8.3a,+reserve-x18"  {
; CHECK-LABEL: non_leaf_scs:
; CHECK:       // %bb.0:
; CHECK-NEXT:    str x30, [x18], #8
; CHECK-NEXT:    .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
; CHECK-NEXT:    hint #39
; CHECK-NEXT:  .Ltmp4:
; CHECK-NEXT:    paciasp
; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-NEXT:    .cfi_negate_ra_state
; CHECK-NEXT:    .cfi_def_cfa_offset 16
; CHECK-NEXT:    .cfi_offset w30, -16
; CHECK-NEXT:    bl foo
; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT:    adr x16, .Ltmp4
; CHECK-NEXT:    hint #39
; CHECK-NEXT:    autiasp
; CHECK-NEXT:    ldr x30, [x18, #-8]!
; CHECK-NEXT:    ret
;
; PAUTHLR-LABEL: non_leaf_scs:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:    str x30, [x18], #8
; PAUTHLR-NEXT:    .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 //
; PAUTHLR-NEXT:  .Ltmp4:
; PAUTHLR-NEXT:    paciasppc
; PAUTHLR-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    .cfi_def_cfa_offset 16
; PAUTHLR-NEXT:    .cfi_offset w30, -16
; PAUTHLR-NEXT:    bl foo
; PAUTHLR-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; PAUTHLR-NEXT:    autiasppc .Ltmp4
; PAUTHLR-NEXT:    ldr x30, [x18, #-8]!
; PAUTHLR-NEXT:    ret
  %call = call i32 @foo(i32 %x)
  ret i32 %call
}

define i32 @leaf_sign_all_v83(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "target-features"="+v8.3a" {
; CHECK-LABEL: leaf_sign_all_v83:
; CHECK:       // %bb.0:
; CHECK-NEXT:    hint #39
; CHECK-NEXT:  .Ltmp5:
; CHECK-NEXT:    paciasp
; CHECK-NEXT:    .cfi_negate_ra_state
; CHECK-NEXT:    adr x16, .Ltmp5
; CHECK-NEXT:    hint #39
; CHECK-NEXT:    retaa
;
; PAUTHLR-LABEL: leaf_sign_all_v83:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:  .Ltmp5:
; PAUTHLR-NEXT:    paciasppc
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    retaasppc .Ltmp5
  ret i32 %x
}

declare fastcc i64 @bar(i64)

define fastcc void @spill_lr_and_tail_call(i64 %x) "branch-protection-pauth-lr" "sign-return-address"="all" {
; COMPAT-LABEL: spill_lr_and_tail_call:
; COMPAT:       // %bb.0:
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:  .Ltmp6:
; COMPAT-NEXT:    hint #25
; COMPAT-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; COMPAT-NEXT:    .cfi_negate_ra_state
; COMPAT-NEXT:    .cfi_def_cfa_offset 16
; COMPAT-NEXT:    .cfi_offset w30, -16
; COMPAT-NEXT:    //APP
; COMPAT-NEXT:    mov x30, x0
; COMPAT-NEXT:    //NO_APP
; COMPAT-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; COMPAT-NEXT:    adr x16, .Ltmp6
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:    hint #29
; COMPAT-NEXT:    b bar
;
; V83A-LABEL: spill_lr_and_tail_call:
; V83A:       // %bb.0:
; V83A-NEXT:    hint #39
; V83A-NEXT:  .Ltmp6:
; V83A-NEXT:    paciasp
; V83A-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; V83A-NEXT:    .cfi_negate_ra_state
; V83A-NEXT:    .cfi_def_cfa_offset 16
; V83A-NEXT:    .cfi_offset w30, -16
; V83A-NEXT:    //APP
; V83A-NEXT:    mov x30, x0
; V83A-NEXT:    //NO_APP
; V83A-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; V83A-NEXT:    adr x16, .Ltmp6
; V83A-NEXT:    hint #39
; V83A-NEXT:    autiasp
; V83A-NEXT:    b bar
;
; PAUTHLR-LABEL: spill_lr_and_tail_call:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:  .Ltmp6:
; PAUTHLR-NEXT:    paciasppc
; PAUTHLR-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    .cfi_def_cfa_offset 16
; PAUTHLR-NEXT:    .cfi_offset w30, -16
; PAUTHLR-NEXT:    //APP
; PAUTHLR-NEXT:    mov x30, x0
; PAUTHLR-NEXT:    //NO_APP
; PAUTHLR-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
; PAUTHLR-NEXT:    autiasppc .Ltmp6
; PAUTHLR-NEXT:    b bar
  call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1
  tail call fastcc i64 @bar(i64 %x)
  ret void
}

define i32 @leaf_sign_all_a_key(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "sign-return-address-key"="a_key" {
; COMPAT-LABEL: leaf_sign_all_a_key:
; COMPAT:       // %bb.0:
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:  .Ltmp7:
; COMPAT-NEXT:    hint #25
; COMPAT-NEXT:    .cfi_negate_ra_state
; COMPAT-NEXT:    adr x16, .Ltmp7
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:    hint #29
; COMPAT-NEXT:    ret
;
; V83A-LABEL: leaf_sign_all_a_key:
; V83A:       // %bb.0:
; V83A-NEXT:    hint #39
; V83A-NEXT:  .Ltmp7:
; V83A-NEXT:    paciasp
; V83A-NEXT:    .cfi_negate_ra_state
; V83A-NEXT:    adr x16, .Ltmp7
; V83A-NEXT:    hint #39
; V83A-NEXT:    retaa
;
; PAUTHLR-LABEL: leaf_sign_all_a_key:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:  .Ltmp7:
; PAUTHLR-NEXT:    paciasppc
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    retaasppc .Ltmp7
  ret i32 %x
}

define i32 @leaf_sign_all_b_key(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "sign-return-address-key"="b_key" {
; COMPAT-LABEL: leaf_sign_all_b_key:
; COMPAT:       // %bb.0:
; COMPAT-NEXT:    .cfi_b_key_frame
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:  .Ltmp8:
; COMPAT-NEXT:    hint #27
; COMPAT-NEXT:    .cfi_negate_ra_state
; COMPAT-NEXT:    adr x16, .Ltmp8
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:    hint #31
; COMPAT-NEXT:    ret
;
; V83A-LABEL: leaf_sign_all_b_key:
; V83A:       // %bb.0:
; V83A-NEXT:    .cfi_b_key_frame
; V83A-NEXT:    hint #39
; V83A-NEXT:  .Ltmp8:
; V83A-NEXT:    pacibsp
; V83A-NEXT:    .cfi_negate_ra_state
; V83A-NEXT:    adr x16, .Ltmp8
; V83A-NEXT:    hint #39
; V83A-NEXT:    retab
;
; PAUTHLR-LABEL: leaf_sign_all_b_key:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:    .cfi_b_key_frame
; PAUTHLR-NEXT:  .Ltmp8:
; PAUTHLR-NEXT:    pacibsppc
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    retabsppc .Ltmp8
  ret i32 %x
}

define i32 @leaf_sign_all_v83_b_key(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" {
; CHECK-LABEL: leaf_sign_all_v83_b_key:
; CHECK:       // %bb.0:
; CHECK-NEXT:    .cfi_b_key_frame
; CHECK-NEXT:    hint #39
; CHECK-NEXT:  .Ltmp9:
; CHECK-NEXT:    pacibsp
; CHECK-NEXT:    .cfi_negate_ra_state
; CHECK-NEXT:    adr x16, .Ltmp9
; CHECK-NEXT:    hint #39
; CHECK-NEXT:    retab
;
; PAUTHLR-LABEL: leaf_sign_all_v83_b_key:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:    .cfi_b_key_frame
; PAUTHLR-NEXT:  .Ltmp9:
; PAUTHLR-NEXT:    pacibsppc
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    retabsppc .Ltmp9
  ret i32 %x
}

; Note that BTI instruction is not needed before PACIASP.
define i32 @leaf_sign_all_a_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "sign-return-address-key"="a_key" "branch-target-enforcement" {
; COMPAT-LABEL: leaf_sign_all_a_key_bti:
; COMPAT:       // %bb.0:
; COMPAT-NEXT:    hint #34
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:  .Ltmp10:
; COMPAT-NEXT:    hint #25
; COMPAT-NEXT:    .cfi_negate_ra_state
; COMPAT-NEXT:    adr x16, .Ltmp10
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:    hint #29
; COMPAT-NEXT:    ret
;
; V83A-LABEL: leaf_sign_all_a_key_bti:
; V83A:       // %bb.0:
; V83A-NEXT:    hint #34
; V83A-NEXT:    hint #39
; V83A-NEXT:  .Ltmp10:
; V83A-NEXT:    paciasp
; V83A-NEXT:    .cfi_negate_ra_state
; V83A-NEXT:    adr x16, .Ltmp10
; V83A-NEXT:    hint #39
; V83A-NEXT:    retaa
;
; PAUTHLR-LABEL: leaf_sign_all_a_key_bti:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:    bti c
; PAUTHLR-NEXT:  .Ltmp10:
; PAUTHLR-NEXT:    paciasppc
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    retaasppc .Ltmp10
  ret i32 %x
}

; Note that BTI instruction is not needed before PACIBSP.
define i32 @leaf_sign_all_b_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "sign-return-address-key"="b_key" "branch-target-enforcement" {
; COMPAT-LABEL: leaf_sign_all_b_key_bti:
; COMPAT:       // %bb.0:
; COMPAT-NEXT:    hint #34
; COMPAT-NEXT:    .cfi_b_key_frame
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:  .Ltmp11:
; COMPAT-NEXT:    hint #27
; COMPAT-NEXT:    .cfi_negate_ra_state
; COMPAT-NEXT:    adr x16, .Ltmp11
; COMPAT-NEXT:    hint #39
; COMPAT-NEXT:    hint #31
; COMPAT-NEXT:    ret
;
; V83A-LABEL: leaf_sign_all_b_key_bti:
; V83A:       // %bb.0:
; V83A-NEXT:    hint #34
; V83A-NEXT:    .cfi_b_key_frame
; V83A-NEXT:    hint #39
; V83A-NEXT:  .Ltmp11:
; V83A-NEXT:    pacibsp
; V83A-NEXT:    .cfi_negate_ra_state
; V83A-NEXT:    adr x16, .Ltmp11
; V83A-NEXT:    hint #39
; V83A-NEXT:    retab
;
; PAUTHLR-LABEL: leaf_sign_all_b_key_bti:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:    bti c
; PAUTHLR-NEXT:    .cfi_b_key_frame
; PAUTHLR-NEXT:  .Ltmp11:
; PAUTHLR-NEXT:    pacibsppc
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    retabsppc .Ltmp11
  ret i32 %x
}

; Note that BTI instruction is not needed before PACIBSP.
define i32 @leaf_sign_all_v83_b_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" "branch-target-enforcement" {
; CHECK-LABEL: leaf_sign_all_v83_b_key_bti:
; CHECK:       // %bb.0:
; CHECK-NEXT:    hint #34
; CHECK-NEXT:    .cfi_b_key_frame
; CHECK-NEXT:    hint #39
; CHECK-NEXT:  .Ltmp12:
; CHECK-NEXT:    pacibsp
; CHECK-NEXT:    .cfi_negate_ra_state
; CHECK-NEXT:    adr x16, .Ltmp12
; CHECK-NEXT:    hint #39
; CHECK-NEXT:    retab
;
; PAUTHLR-LABEL: leaf_sign_all_v83_b_key_bti:
; PAUTHLR:       // %bb.0:
; PAUTHLR-NEXT:    bti c
; PAUTHLR-NEXT:    .cfi_b_key_frame
; PAUTHLR-NEXT:  .Ltmp12:
; PAUTHLR-NEXT:    pacibsppc
; PAUTHLR-NEXT:    .cfi_negate_ra_state
; PAUTHLR-NEXT:    retabsppc .Ltmp12
  ret i32 %x
}