| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 |
| ; 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 |
| |
| ; v9.5-A is not expected to change codegen without -mbranch-protection=+pc, so reuse V83A. |
| ; RUN: llc -mtriple=aarch64 -mattr=v9.5a < %s | FileCheck --check-prefixes=CHECK,V83A %s |
| |
| define i32 @leaf(i32 %x) { |
| ; CHECK-LABEL: leaf: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ret |
| ret i32 %x |
| } |
| |
| define i32 @leaf_sign_none(i32 %x) { |
| ; CHECK-LABEL: leaf_sign_none: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ret |
| ret i32 %x |
| } |
| |
| define i32 @leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" { |
| ; CHECK-LABEL: leaf_sign_non_leaf: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: ret |
| ret i32 %x |
| } |
| |
| define i32 @leaf_sign_all(i32 %x) "sign-return-address"="all" { |
| ; COMPAT-LABEL: leaf_sign_all: |
| ; COMPAT: // %bb.0: |
| ; COMPAT-NEXT: .cfi_negate_ra_state |
| ; COMPAT-NEXT: hint #25 |
| ; COMPAT-NEXT: hint #29 |
| ; COMPAT-NEXT: ret |
| ; |
| ; V83A-LABEL: leaf_sign_all: |
| ; V83A: // %bb.0: |
| ; V83A-NEXT: .cfi_negate_ra_state |
| ; V83A-NEXT: paciasp |
| ; V83A-NEXT: retaa |
| ret i32 %x |
| } |
| |
| define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf" { |
| ; COMPAT-LABEL: leaf_clobbers_lr: |
| ; COMPAT: // %bb.0: |
| ; COMPAT-NEXT: .cfi_negate_ra_state |
| ; COMPAT-NEXT: hint #25 |
| ; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill |
| ; 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: hint #29 |
| ; COMPAT-NEXT: ret |
| ; |
| ; V83A-LABEL: leaf_clobbers_lr: |
| ; V83A: // %bb.0: |
| ; V83A-NEXT: .cfi_negate_ra_state |
| ; V83A-NEXT: paciasp |
| ; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill |
| ; 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: retaa |
| 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) "sign-return-address"="all" { |
| ; COMPAT-LABEL: non_leaf_sign_all: |
| ; COMPAT: // %bb.0: |
| ; COMPAT-NEXT: .cfi_negate_ra_state |
| ; COMPAT-NEXT: hint #25 |
| ; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill |
| ; 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: hint #29 |
| ; COMPAT-NEXT: ret |
| ; |
| ; V83A-LABEL: non_leaf_sign_all: |
| ; V83A: // %bb.0: |
| ; V83A-NEXT: .cfi_negate_ra_state |
| ; V83A-NEXT: paciasp |
| ; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill |
| ; 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: retaa |
| %call = call i32 @foo(i32 %x) |
| ret i32 %call |
| } |
| |
| define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" { |
| ; COMPAT-LABEL: non_leaf_sign_non_leaf: |
| ; COMPAT: // %bb.0: |
| ; COMPAT-NEXT: .cfi_negate_ra_state |
| ; COMPAT-NEXT: hint #25 |
| ; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill |
| ; 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: hint #29 |
| ; COMPAT-NEXT: ret |
| ; |
| ; V83A-LABEL: non_leaf_sign_non_leaf: |
| ; V83A: // %bb.0: |
| ; V83A-NEXT: .cfi_negate_ra_state |
| ; V83A-NEXT: paciasp |
| ; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill |
| ; 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: retaa |
| %call = call i32 @foo(i32 %x) |
| ret i32 %call |
| } |
| |
| ; Should not use the RETAA instruction. |
| define i32 @non_leaf_scs(i32 %x) "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: .cfi_negate_ra_state |
| ; CHECK-NEXT: paciasp |
| ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill |
| ; 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: autiasp |
| ; CHECK-NEXT: ldr x30, [x18, #-8]! |
| ; CHECK-NEXT: ret |
| %call = call i32 @foo(i32 %x) |
| ret i32 %call |
| } |
| |
| define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" { |
| ; CHECK-LABEL: leaf_sign_all_v83: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: .cfi_negate_ra_state |
| ; CHECK-NEXT: paciasp |
| ; CHECK-NEXT: retaa |
| ret i32 %x |
| } |
| |
| declare fastcc i64 @bar(i64) |
| |
| define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" { |
| ; COMPAT-LABEL: spill_lr_and_tail_call: |
| ; COMPAT: // %bb.0: |
| ; COMPAT-NEXT: .cfi_negate_ra_state |
| ; COMPAT-NEXT: hint #25 |
| ; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill |
| ; 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: hint #29 |
| ; COMPAT-NEXT: b bar |
| ; |
| ; V83A-LABEL: spill_lr_and_tail_call: |
| ; V83A: // %bb.0: |
| ; V83A-NEXT: .cfi_negate_ra_state |
| ; V83A-NEXT: paciasp |
| ; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill |
| ; 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: autiasp |
| ; V83A-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) "sign-return-address"="all" "sign-return-address-key"="a_key" { |
| ; COMPAT-LABEL: leaf_sign_all_a_key: |
| ; COMPAT: // %bb.0: |
| ; COMPAT-NEXT: .cfi_negate_ra_state |
| ; COMPAT-NEXT: hint #25 |
| ; COMPAT-NEXT: hint #29 |
| ; COMPAT-NEXT: ret |
| ; |
| ; V83A-LABEL: leaf_sign_all_a_key: |
| ; V83A: // %bb.0: |
| ; V83A-NEXT: .cfi_negate_ra_state |
| ; V83A-NEXT: paciasp |
| ; V83A-NEXT: retaa |
| ret i32 %x |
| } |
| |
| define i32 @leaf_sign_all_b_key(i32 %x) "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: .cfi_negate_ra_state |
| ; COMPAT-NEXT: hint #27 |
| ; 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: .cfi_negate_ra_state |
| ; V83A-NEXT: pacibsp |
| ; V83A-NEXT: retab |
| ret i32 %x |
| } |
| |
| define i32 @leaf_sign_all_v83_b_key(i32 %x) "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: .cfi_negate_ra_state |
| ; CHECK-NEXT: pacibsp |
| ; CHECK-NEXT: retab |
| ret i32 %x |
| } |
| |
| ; Note that BTI instruction is not needed before PACIASP. |
| define i32 @leaf_sign_all_a_key_bti(i32 %x) "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: .cfi_negate_ra_state |
| ; COMPAT-NEXT: hint #25 |
| ; COMPAT-NEXT: hint #29 |
| ; COMPAT-NEXT: ret |
| ; |
| ; V83A-LABEL: leaf_sign_all_a_key_bti: |
| ; V83A: // %bb.0: |
| ; V83A-NEXT: .cfi_negate_ra_state |
| ; V83A-NEXT: paciasp |
| ; V83A-NEXT: retaa |
| ret i32 %x |
| } |
| |
| ; Note that BTI instruction is not needed before PACIBSP. |
| define i32 @leaf_sign_all_b_key_bti(i32 %x) "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: .cfi_b_key_frame |
| ; COMPAT-NEXT: .cfi_negate_ra_state |
| ; COMPAT-NEXT: hint #27 |
| ; COMPAT-NEXT: hint #31 |
| ; COMPAT-NEXT: ret |
| ; |
| ; V83A-LABEL: leaf_sign_all_b_key_bti: |
| ; V83A: // %bb.0: |
| ; V83A-NEXT: .cfi_b_key_frame |
| ; V83A-NEXT: .cfi_negate_ra_state |
| ; V83A-NEXT: pacibsp |
| ; V83A-NEXT: retab |
| ret i32 %x |
| } |
| |
| ; Note that BTI instruction is not needed before PACIBSP. |
| define i32 @leaf_sign_all_v83_b_key_bti(i32 %x) "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: .cfi_b_key_frame |
| ; CHECK-NEXT: .cfi_negate_ra_state |
| ; CHECK-NEXT: pacibsp |
| ; CHECK-NEXT: retab |
| ret i32 %x |
| } |