1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 2; RUN: llc -mtriple=aarch64 < %s | FileCheck --check-prefixes=CHECK,COMPAT %s 3; RUN: llc -mtriple=aarch64 -mattr=v8.3a < %s | FileCheck --check-prefixes=CHECK,V83A %s 4 5; v9.5-A is not expected to change codegen without -mbranch-protection=+pc, so reuse V83A. 6; RUN: llc -mtriple=aarch64 -mattr=v9.5a < %s | FileCheck --check-prefixes=CHECK,V83A %s 7 8define i32 @leaf(i32 %x) { 9; CHECK-LABEL: leaf: 10; CHECK: // %bb.0: 11; CHECK-NEXT: ret 12 ret i32 %x 13} 14 15define i32 @leaf_sign_none(i32 %x) { 16; CHECK-LABEL: leaf_sign_none: 17; CHECK: // %bb.0: 18; CHECK-NEXT: ret 19 ret i32 %x 20} 21 22define i32 @leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" { 23; CHECK-LABEL: leaf_sign_non_leaf: 24; CHECK: // %bb.0: 25; CHECK-NEXT: ret 26 ret i32 %x 27} 28 29define i32 @leaf_sign_all(i32 %x) "sign-return-address"="all" { 30; COMPAT-LABEL: leaf_sign_all: 31; COMPAT: // %bb.0: 32; COMPAT-NEXT: .cfi_negate_ra_state 33; COMPAT-NEXT: hint #25 34; COMPAT-NEXT: hint #29 35; COMPAT-NEXT: ret 36; 37; V83A-LABEL: leaf_sign_all: 38; V83A: // %bb.0: 39; V83A-NEXT: .cfi_negate_ra_state 40; V83A-NEXT: paciasp 41; V83A-NEXT: retaa 42 ret i32 %x 43} 44 45define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf" { 46; COMPAT-LABEL: leaf_clobbers_lr: 47; COMPAT: // %bb.0: 48; COMPAT-NEXT: .cfi_negate_ra_state 49; COMPAT-NEXT: hint #25 50; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 51; COMPAT-NEXT: .cfi_def_cfa_offset 16 52; COMPAT-NEXT: .cfi_offset w30, -16 53; COMPAT-NEXT: //APP 54; COMPAT-NEXT: mov x30, x0 55; COMPAT-NEXT: //NO_APP 56; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 57; COMPAT-NEXT: hint #29 58; COMPAT-NEXT: ret 59; 60; V83A-LABEL: leaf_clobbers_lr: 61; V83A: // %bb.0: 62; V83A-NEXT: .cfi_negate_ra_state 63; V83A-NEXT: paciasp 64; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 65; V83A-NEXT: .cfi_def_cfa_offset 16 66; V83A-NEXT: .cfi_offset w30, -16 67; V83A-NEXT: //APP 68; V83A-NEXT: mov x30, x0 69; V83A-NEXT: //NO_APP 70; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 71; V83A-NEXT: retaa 72 call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1 73 ret i64 %x 74} 75 76declare i32 @foo(i32) 77 78define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" { 79; COMPAT-LABEL: non_leaf_sign_all: 80; COMPAT: // %bb.0: 81; COMPAT-NEXT: .cfi_negate_ra_state 82; COMPAT-NEXT: hint #25 83; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 84; COMPAT-NEXT: .cfi_def_cfa_offset 16 85; COMPAT-NEXT: .cfi_offset w30, -16 86; COMPAT-NEXT: bl foo 87; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 88; COMPAT-NEXT: hint #29 89; COMPAT-NEXT: ret 90; 91; V83A-LABEL: non_leaf_sign_all: 92; V83A: // %bb.0: 93; V83A-NEXT: .cfi_negate_ra_state 94; V83A-NEXT: paciasp 95; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 96; V83A-NEXT: .cfi_def_cfa_offset 16 97; V83A-NEXT: .cfi_offset w30, -16 98; V83A-NEXT: bl foo 99; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 100; V83A-NEXT: retaa 101 %call = call i32 @foo(i32 %x) 102 ret i32 %call 103} 104 105define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" { 106; COMPAT-LABEL: non_leaf_sign_non_leaf: 107; COMPAT: // %bb.0: 108; COMPAT-NEXT: .cfi_negate_ra_state 109; COMPAT-NEXT: hint #25 110; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 111; COMPAT-NEXT: .cfi_def_cfa_offset 16 112; COMPAT-NEXT: .cfi_offset w30, -16 113; COMPAT-NEXT: bl foo 114; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 115; COMPAT-NEXT: hint #29 116; COMPAT-NEXT: ret 117; 118; V83A-LABEL: non_leaf_sign_non_leaf: 119; V83A: // %bb.0: 120; V83A-NEXT: .cfi_negate_ra_state 121; V83A-NEXT: paciasp 122; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 123; V83A-NEXT: .cfi_def_cfa_offset 16 124; V83A-NEXT: .cfi_offset w30, -16 125; V83A-NEXT: bl foo 126; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 127; V83A-NEXT: retaa 128 %call = call i32 @foo(i32 %x) 129 ret i32 %call 130} 131 132; Should not use the RETAA instruction. 133define i32 @non_leaf_scs(i32 %x) "sign-return-address"="non-leaf" shadowcallstack "target-features"="+v8.3a,+reserve-x18" { 134; CHECK-LABEL: non_leaf_scs: 135; CHECK: // %bb.0: 136; CHECK-NEXT: str x30, [x18], #8 137; CHECK-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 // 138; CHECK-NEXT: .cfi_negate_ra_state 139; CHECK-NEXT: paciasp 140; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 141; CHECK-NEXT: .cfi_def_cfa_offset 16 142; CHECK-NEXT: .cfi_offset w30, -16 143; CHECK-NEXT: bl foo 144; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 145; CHECK-NEXT: autiasp 146; CHECK-NEXT: ldr x30, [x18, #-8]! 147; CHECK-NEXT: ret 148 %call = call i32 @foo(i32 %x) 149 ret i32 %call 150} 151 152define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" { 153; CHECK-LABEL: leaf_sign_all_v83: 154; CHECK: // %bb.0: 155; CHECK-NEXT: .cfi_negate_ra_state 156; CHECK-NEXT: paciasp 157; CHECK-NEXT: retaa 158 ret i32 %x 159} 160 161declare fastcc i64 @bar(i64) 162 163define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" { 164; COMPAT-LABEL: spill_lr_and_tail_call: 165; COMPAT: // %bb.0: 166; COMPAT-NEXT: .cfi_negate_ra_state 167; COMPAT-NEXT: hint #25 168; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 169; COMPAT-NEXT: .cfi_def_cfa_offset 16 170; COMPAT-NEXT: .cfi_offset w30, -16 171; COMPAT-NEXT: //APP 172; COMPAT-NEXT: mov x30, x0 173; COMPAT-NEXT: //NO_APP 174; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 175; COMPAT-NEXT: hint #29 176; COMPAT-NEXT: b bar 177; 178; V83A-LABEL: spill_lr_and_tail_call: 179; V83A: // %bb.0: 180; V83A-NEXT: .cfi_negate_ra_state 181; V83A-NEXT: paciasp 182; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 183; V83A-NEXT: .cfi_def_cfa_offset 16 184; V83A-NEXT: .cfi_offset w30, -16 185; V83A-NEXT: //APP 186; V83A-NEXT: mov x30, x0 187; V83A-NEXT: //NO_APP 188; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 189; V83A-NEXT: autiasp 190; V83A-NEXT: b bar 191 call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1 192 tail call fastcc i64 @bar(i64 %x) 193 ret void 194} 195 196define i32 @leaf_sign_all_a_key(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" { 197; COMPAT-LABEL: leaf_sign_all_a_key: 198; COMPAT: // %bb.0: 199; COMPAT-NEXT: .cfi_negate_ra_state 200; COMPAT-NEXT: hint #25 201; COMPAT-NEXT: hint #29 202; COMPAT-NEXT: ret 203; 204; V83A-LABEL: leaf_sign_all_a_key: 205; V83A: // %bb.0: 206; V83A-NEXT: .cfi_negate_ra_state 207; V83A-NEXT: paciasp 208; V83A-NEXT: retaa 209 ret i32 %x 210} 211 212define i32 @leaf_sign_all_b_key(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" { 213; COMPAT-LABEL: leaf_sign_all_b_key: 214; COMPAT: // %bb.0: 215; COMPAT-NEXT: .cfi_b_key_frame 216; COMPAT-NEXT: .cfi_negate_ra_state 217; COMPAT-NEXT: hint #27 218; COMPAT-NEXT: hint #31 219; COMPAT-NEXT: ret 220; 221; V83A-LABEL: leaf_sign_all_b_key: 222; V83A: // %bb.0: 223; V83A-NEXT: .cfi_b_key_frame 224; V83A-NEXT: .cfi_negate_ra_state 225; V83A-NEXT: pacibsp 226; V83A-NEXT: retab 227 ret i32 %x 228} 229 230define i32 @leaf_sign_all_v83_b_key(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" { 231; CHECK-LABEL: leaf_sign_all_v83_b_key: 232; CHECK: // %bb.0: 233; CHECK-NEXT: .cfi_b_key_frame 234; CHECK-NEXT: .cfi_negate_ra_state 235; CHECK-NEXT: pacibsp 236; CHECK-NEXT: retab 237 ret i32 %x 238} 239 240; Note that BTI instruction is not needed before PACIASP. 241define i32 @leaf_sign_all_a_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" "branch-target-enforcement"{ 242; COMPAT-LABEL: leaf_sign_all_a_key_bti: 243; COMPAT: // %bb.0: 244; COMPAT-NEXT: .cfi_negate_ra_state 245; COMPAT-NEXT: hint #25 246; COMPAT-NEXT: hint #29 247; COMPAT-NEXT: ret 248; 249; V83A-LABEL: leaf_sign_all_a_key_bti: 250; V83A: // %bb.0: 251; V83A-NEXT: .cfi_negate_ra_state 252; V83A-NEXT: paciasp 253; V83A-NEXT: retaa 254 ret i32 %x 255} 256 257; Note that BTI instruction is not needed before PACIBSP. 258define i32 @leaf_sign_all_b_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" "branch-target-enforcement"{ 259; COMPAT-LABEL: leaf_sign_all_b_key_bti: 260; COMPAT: // %bb.0: 261; COMPAT-NEXT: .cfi_b_key_frame 262; COMPAT-NEXT: .cfi_negate_ra_state 263; COMPAT-NEXT: hint #27 264; COMPAT-NEXT: hint #31 265; COMPAT-NEXT: ret 266; 267; V83A-LABEL: leaf_sign_all_b_key_bti: 268; V83A: // %bb.0: 269; V83A-NEXT: .cfi_b_key_frame 270; V83A-NEXT: .cfi_negate_ra_state 271; V83A-NEXT: pacibsp 272; V83A-NEXT: retab 273 ret i32 %x 274} 275 276; Note that BTI instruction is not needed before PACIBSP. 277define 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" { 278; CHECK-LABEL: leaf_sign_all_v83_b_key_bti: 279; CHECK: // %bb.0: 280; CHECK-NEXT: .cfi_b_key_frame 281; CHECK-NEXT: .cfi_negate_ra_state 282; CHECK-NEXT: pacibsp 283; CHECK-NEXT: retab 284 ret i32 %x 285} 286