diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1719,7 +1719,8 @@ // The AUTIASP instruction assembles to a hint instruction before v8.3a so // this instruction can safely used for any v8a architecture. // From v8.3a onwards there are optimised authenticate LR and return - // instructions, namely RETA{A,B}, that can be used instead. + // instructions, namely RETA{A,B}, that can be used instead. In this case the + // DW_CFA_AARCH64_negate_ra_state can't be emitted. if (Subtarget.hasPAuth() && MBBI != MBB.end() && MBBI->getOpcode() == AArch64::RET_ReallyLR) { BuildMI(MBB, MBBI, DL, @@ -1731,6 +1732,12 @@ MBB, MBBI, DL, TII->get(MFI.shouldSignWithBKey() ? AArch64::AUTIBSP : AArch64::AUTIASP)) .setMIFlag(MachineInstr::FrameDestroy); + + unsigned CFIIndex = + MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); + BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlags(MachineInstr::FrameDestroy); } } diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -7596,7 +7596,8 @@ } // If v8.3a features are available we can replace a RET instruction by - // RETAA or RETAB and omit the AUT instructions + // RETAA or RETAB and omit the AUT instructions. In this case the + // DW_CFA_AARCH64_negate_ra_state can't be emitted. if (Subtarget.hasPAuth() && MBBAUT != MBB.end() && MBBAUT->getOpcode() == AArch64::RET) { BuildMI(MBB, MBBAUT, DL, @@ -7609,6 +7610,11 @@ TII->get(ShouldSignReturnAddrWithAKey ? AArch64::AUTIASP : AArch64::AUTIBSP)) .setMIFlag(MachineInstr::FrameDestroy); + unsigned CFIIndexAuth = + MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); + BuildMI(MBB, MBBAUT, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndexAuth) + .setMIFlags(MachineInstr::FrameDestroy); } } } diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-cfi.ll b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-cfi.ll --- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-cfi.ll +++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-cfi.ll @@ -28,7 +28,8 @@ ; CHECK-NOT: bl OUTLINED_FUNCTION_{{[0-9]+}} ; V8A: hint #31 ; V83A: autibsp -; CHECK-NEXT: ret +; V8A-NEXT, V83A-NEXT: .cfi_negate_ra_state +; V8A-NEXT, V83A-NEXT: ret ret void } diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir --- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir @@ -32,6 +32,7 @@ # CHECK: BL @[[OUTLINED_FUNCTION]] # CHECK: bb.5: # CHECK: frame-destroy AUTIBSP +# CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state # CHECK-NEXT: RET name: foo tracksRegLiveness: true diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir --- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir @@ -81,6 +81,7 @@ STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) $sp = frame-destroy ADDXri $sp, 16, 0 frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp + frame-destroy CFI_INSTRUCTION negate_ra_sign_state RET undef $lr # CHECK-LABEL: name: legal0 @@ -91,6 +92,7 @@ # CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state # CHECK: BL @[[OUTLINED_FUNC:OUTLINED_FUNCTION_[0-9]+]] # CHECK: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state # CHECK-NEXT: RET undef $lr ... @@ -114,6 +116,7 @@ STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) $sp = frame-destroy ADDXri $sp, 16, 0 frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp + frame-destroy CFI_INSTRUCTION negate_ra_sign_state RET undef $lr # CHECK-LABEL: name: legal1 @@ -124,6 +127,7 @@ # CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state # CHECK: BL @[[OUTLINED_FUNC]] # CHECK: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state # CHECK-NEXT: RET undef $lr ... @@ -147,6 +151,7 @@ STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) $sp = frame-destroy ADDXri $sp, 12, 0 frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp + frame-destroy CFI_INSTRUCTION negate_ra_sign_state RET undef $lr ... @@ -170,6 +175,7 @@ STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) $sp = frame-destroy ADDXri $sp, 12, 0 frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp + frame-destroy CFI_INSTRUCTION negate_ra_sign_state RET undef $lr # CHECK-LABEL: name: illegal0 @@ -180,6 +186,7 @@ # CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state # CHECK-NOT: BL @OUTLINED_FUNCTION_{{.*}} # CHECK: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state # CHECK-NEXT: RET undef $lr # CHECK-LABEL: name: illegal1 @@ -190,6 +197,7 @@ # CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state # CHECK-NOT: BL @OUTLINED_FUNCTION_{{.*}} # CHECK: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state # CHECK-NEXT: RET undef $lr # Outlined function that contains only legal sp modifications @@ -203,4 +211,5 @@ # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0 # CHECK: $sp = frame-destroy ADDXri $sp, 16, 0 # CHECK-NEXT: frame-destroy AUTIASP implicit-def $lr, implicit $lr, implicit $sp +# CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state # CHECK-NEXT: RET $lr diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-thunk.ll b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-thunk.ll --- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-thunk.ll +++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-thunk.ll @@ -11,8 +11,10 @@ ; CHECK: // %bb.0: // %entry ; V8A-NEXT: hint #25 ; V83A-NEXT: paciasp +; CHECK-NEXT: .cfi_negate_ra_state ; V8A: hint #29 ; V83A: autiasp +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK-NEXT: ret entry: %call = tail call i32 @thunk_called_fn(i32 1, i32 2, i32 3, i32 4) @@ -28,6 +30,7 @@ ; CHECK-NEXT: .cfi_negate_ra_state ; V8A: hint #29 ; V83A: autiasp +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK-NEXT: ret entry: %call = tail call i32 @thunk_called_fn(i32 1, i32 2, i32 3, i32 4) @@ -43,6 +46,7 @@ ; CHECK-NEXT: .cfi_negate_ra_state ; V8A: hint #29 ; V83A: autiasp +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK-NEXT: ret entry: %call = tail call i32 %fptr(i32 1, i32 2, i32 3, i32 4) @@ -58,6 +62,7 @@ ; CHECK-NEXT: .cfi_negate_ra_state ; V8A: hint #29 ; V83A: autiasp +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK-NEXT: ret entry: %call = tail call i32 %fptr(i32 1, i32 2, i32 3, i32 4) diff --git a/llvm/test/CodeGen/AArch64/sign-return-address.ll b/llvm/test/CodeGen/AArch64/sign-return-address.ll --- a/llvm/test/CodeGen/AArch64/sign-return-address.ll +++ b/llvm/test/CodeGen/AArch64/sign-return-address.ll @@ -24,7 +24,9 @@ ; CHECK-LABEL: @leaf_sign_all ; CHECK: hint #25 +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK: hint #29 +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK: ret ; CHECK-V83A: pacia x30, sp ; CHECK-V83A: retaa @@ -34,10 +36,12 @@ ; CHECK: @leaf_clobbers_lr ; CHECK: hint #25 +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK-V83A: pacia x30, sp ; CHECK, CHECK-V83A: str x30, [sp, #-16]! ; CHECK, CHECK-V83A: ldr x30, [sp], #16 ; CHECK: hint #29 +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK: ret ; CHECK-V32A-NEXT: retaa define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf" { @@ -49,7 +53,9 @@ ; CHECK: @non_leaf_sign_all ; CHECK: hint #25 +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK: hint #29 +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK: ret ; CHECK-V83A: pacia x30, sp ; CHECK-V83A: retaa @@ -60,10 +66,12 @@ ; CHECK: @non_leaf_sign_non_leaf ; CHECK: hint #25 +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK-V83A: pacia x30, sp ; CHECK, CHECK-V83A: str x30, [sp, #-16]! ; CHECK, CHECK-V83A: ldr x30, [sp], #16 ; CHECK: hint #29 +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK: ret ; CHECK-V83A: retaa define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" { @@ -72,10 +80,11 @@ } ; CHECK-LABEL: @leaf_sign_all_v83 -; CHECK: pacia x30, sp -; CHECK-NOT: ret -; CHECK: retaa -; CHECK-NOT: ret +; CHECK: pacia x30, sp +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK-NOT: ret +; CHECK: retaa +; CHECK-NOT: ret define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" { ret i32 %x } @@ -84,11 +93,14 @@ ; CHECK-LABEL: @spill_lr_and_tail_call ; CHECK: hint #25 +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK-V83A: pacia x30, sp +; CHECK-V83A-NEXT: .cfi_negate_ra_state ; CHECK, CHECK-V83A: str x30, [sp, #-16]! ; CHECK, CHECK-V83A: ldr x30, [sp], #16 ; CHECK-V83A: autiasp ; CHECK: hint #29 +; CHECK-NEXT: .cfi_negate_ra_state ; CHECK: b bar define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" { call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1 @@ -97,57 +109,71 @@ } ; CHECK-LABEL: @leaf_sign_all_a_key -; CHECK: hint #25 -; CHECK: hint #29 -; CHECK-V83A: pacia x30, sp -; CHECK-V83A: retaa +; CHECK: hint #25 +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK: hint #29 +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK-V83A: pacia x30, sp +; CHECK-V83A-NEXT: .cfi_negate_ra_state +; CHECK-V83A: retaa define i32 @leaf_sign_all_a_key(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" { ret i32 %x } ; CHECK-LABEL: @leaf_sign_all_b_key -; CHECK: hint #27 -; CHECK: hint #31 -; CHECK-V83A: pacib x30, sp -; CHECK-V83A: retab +; CHECK: hint #27 +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK: hint #31 +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK-V83A: pacib x30, sp +; CHECK-V83A-NEXT: .cfi_negate_ra_state +; CHECK-V83A: retab define i32 @leaf_sign_all_b_key(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" { ret i32 %x } ; CHECK-LABEL: @leaf_sign_all_v83_b_key -; CHECK: pacib x30, sp -; CHECK-NOT: ret -; CHECK: retab -; CHECK-NOT: ret +; CHECK: pacib x30, sp +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK-NOT: ret +; CHECK: retab +; CHECK-NOT: ret define i32 @leaf_sign_all_v83_b_key(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" { ret i32 %x } ; CHECK-LABEL: @leaf_sign_all_a_key_bti -; CHECK-NOT: hint #34 -; CHECK: hint #25 -; CHECK: hint #29 -; CHECK-V83A: pacia x30, sp -; CHECK-V83A: retaa +; CHECK-NOT: hint #34 +; CHECK: hint #25 +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK: hint #29 +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK-V83A: pacia x30, sp +; CHECK-V83A-NEXT: .cfi_negate_ra_state +; CHECK-V83A: retaa define i32 @leaf_sign_all_a_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" "branch-target-enforcement"="true"{ ret i32 %x } ; CHECK-LABEL: @leaf_sign_all_b_key_bti -; CHECK-NOT: hint #34 -; CHECK: hint #27 -; CHECK: hint #31 -; CHECK-V83A: pacib x30, sp -; CHECK-V83A: retab +; CHECK-NOT: hint #34 +; CHECK: hint #27 +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK: hint #31 +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK-V83A: pacib x30, sp +; CHECK-V83A-NEXT: .cfi_negate_ra_state +; CHECK-V83A: retab define i32 @leaf_sign_all_b_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" "branch-target-enforcement"="true"{ ret i32 %x } ; CHECK-LABEL: @leaf_sign_all_v83_b_key_bti ; CHECK: pacib x30, sp -; CHECK-NOT: ret -; CHECK: retab -; CHECK-NOT: ret +; CHECK-NEXT: .cfi_negate_ra_state +; CHECK-NOT: ret +; CHECK: retab +; CHECK-NOT: ret 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"="true" { ret i32 %x }