[llvm] [llvm][AArch64] Eliminate redundant mov's sandwiching aut's in tail calls (PR #211105)
Jon Roelofs via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 23 09:00:21 PDT 2026
https://github.com/jroelofs updated https://github.com/llvm/llvm-project/pull/211105
>From dbc4dbe6092aa9627ab629d52937792edf3efd82 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Tue, 21 Jul 2026 13:28:52 -0700
Subject: [PATCH 1/2] [llvm][AArch64] Eliminate redundant mov's sandwiching
aut's in tail calls
When the target has +pauth, we don't have to use the hint space compatible
encodings (auti[ab]1716), and instead can directly authenticate lr with
auti[ab].
---
.../lib/Target/AArch64/AArch64PointerAuth.cpp | 55 +++++++++++++++----
.../CodeGen/AArch64/arm64e-tail-call-autib.ll | 4 +-
.../AArch64/pauth-lr-tail-call-fpdiff.ll | 40 ++++++++++----
.../test/CodeGen/AArch64/swifttail-ptrauth.ll | 10 +++-
4 files changed, 79 insertions(+), 30 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
index 7165c3bfed422..94cade25c4ffe 100644
--- a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
+++ b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
@@ -269,13 +269,13 @@ void AArch64PointerAuthImpl::authenticateLR(
StackOffset::getFixed(-ArgumentStackToRestore), TII,
MachineInstr::FrameDestroy);
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::X17)
- .addReg(AArch64::XZR)
- .addReg(AArch64::LR)
- .addImm(0)
- .setMIFlag(MachineInstr::FrameDestroy);
-
if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::X17)
+ .addReg(AArch64::XZR)
+ .addReg(AArch64::LR)
+ .addImm(0)
+ .setMIFlag(MachineInstr::FrameDestroy);
+
assert(PACSym && "No PAC instruction to refer to");
emitEpiloguePACSymOffsetIntoReg(*TII, MBB, MBBI, DL, PACSym,
AArch64::X15);
@@ -284,7 +284,19 @@ void AArch64PointerAuthImpl::authenticateLR(
unsigned AutOpc = UseBKey ? AArch64::AUTIB171615 : AArch64::AUTIA171615;
BuildMI(MBB, MBBI, DL, TII->get(AutOpc))
.setMIFlag(MachineInstr::FrameDestroy);
+
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::LR)
+ .addReg(AArch64::XZR)
+ .addReg(AArch64::X17)
+ .addImm(0)
+ .setMIFlag(MachineInstr::FrameDestroy);
} else if (MFnI->branchProtectionPAuthLR()) {
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::X17)
+ .addReg(AArch64::XZR)
+ .addReg(AArch64::LR)
+ .addImm(0)
+ .setMIFlag(MachineInstr::FrameDestroy);
+
assert(PACSym && "No PAC instruction to refer to");
emitEpiloguePACSymOffsetIntoReg(*TII, MBB, MBBI, DL, PACSym,
AArch64::X15);
@@ -301,18 +313,37 @@ void AArch64PointerAuthImpl::authenticateLR(
unsigned AutOpc = UseBKey ? AArch64::AUTIB1716 : AArch64::AUTIA1716;
BuildMI(MBB, MBBI, DL, TII->get(AutOpc))
.setMIFlag(MachineInstr::FrameDestroy);
+
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::LR)
+ .addReg(AArch64::XZR)
+ .addReg(AArch64::X17)
+ .addImm(0)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ } else if (Subtarget->hasPAuth()) {
+ BuildMI(MBB, MBBI, DL,
+ TII->get(UseBKey ? AArch64::AUTIB : AArch64::AUTIA), AArch64::LR)
+ .addUse(AArch64::LR)
+ .addUse(AArch64::X16)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ emitAUTCFI(MBB, MBBI, EmitAsyncCFI);
} else {
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::X17)
+ .addReg(AArch64::XZR)
+ .addReg(AArch64::LR)
+ .addImm(0)
+ .setMIFlag(MachineInstr::FrameDestroy);
+
unsigned AutOpc = UseBKey ? AArch64::AUTIB1716 : AArch64::AUTIA1716;
BuildMI(MBB, MBBI, DL, TII->get(AutOpc))
.setMIFlag(MachineInstr::FrameDestroy);
emitAUTCFI(MBB, MBBI, EmitAsyncCFI);
- }
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::LR)
- .addReg(AArch64::XZR)
- .addReg(AArch64::X17)
- .addImm(0)
- .setMIFlag(MachineInstr::FrameDestroy);
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::LR)
+ .addReg(AArch64::XZR)
+ .addReg(AArch64::X17)
+ .addImm(0)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ }
return;
}
diff --git a/llvm/test/CodeGen/AArch64/arm64e-tail-call-autib.ll b/llvm/test/CodeGen/AArch64/arm64e-tail-call-autib.ll
index d8e22b0c3cb04..bb478b0358c40 100644
--- a/llvm/test/CodeGen/AArch64/arm64e-tail-call-autib.ll
+++ b/llvm/test/CodeGen/AArch64/arm64e-tail-call-autib.ll
@@ -39,9 +39,7 @@ define swifttailcc void @test_async_tail_call(ptr swiftasync %ctx) "ptrauth-retu
; CHECK-NEXT: and x29, x29, #0xefffffffffffffff
; CHECK-NEXT: add sp, sp, #32
; CHECK-NEXT: add x16, sp, #16
-; CHECK-NEXT: mov x17, x30
-; CHECK-NEXT: autib1716
-; CHECK-NEXT: mov x30, x17
+; CHECK-NEXT: autib x30, x16
; CHECK-NEXT: eor x16, x30, x30, lsl #1
; CHECK-NEXT: tbz x16, #62, Lauth_success_0
; CHECK-NEXT: brk #0xc471
diff --git a/llvm/test/CodeGen/AArch64/pauth-lr-tail-call-fpdiff.ll b/llvm/test/CodeGen/AArch64/pauth-lr-tail-call-fpdiff.ll
index fac71d5ec4a59..04e0585a50593 100644
--- a/llvm/test/CodeGen/AArch64/pauth-lr-tail-call-fpdiff.ll
+++ b/llvm/test/CodeGen/AArch64/pauth-lr-tail-call-fpdiff.ll
@@ -61,26 +61,30 @@ define swifttailcc void @tail_call_fpdiff_a_key(ptr swiftasync %ctx) "branch-pro
; CHECK-NEXT: .cfi_restore w30
; CHECK-NEXT: .cfi_restore w29
; CHECK-NEXT: add x16, sp, #16
-; CHECK-NEXT: mov x17, x30
+; COMPAT-NEXT: mov x17, x30
; COMPAT-NEXT: adrp x15, .Ltmp0
; COMPAT-NEXT: add x15, x15, :lo12:.Ltmp0
; COMPAT-NEXT: hint #39
; COMPAT-NEXT: hint #12
+; COMPAT-NEXT: mov x30, x17
+; V83A-NEXT: mov x17, x30
; V83A-NEXT: adrp x15, .Ltmp0
; V83A-NEXT: add x15, x15, :lo12:.Ltmp0
; V83A-NEXT: hint #39
; V83A-NEXT: autia1716
+; V83A-NEXT: mov x30, x17
+; V9A-NEXT: mov x17, x30
; V9A-NEXT: adrp x15, .Ltmp0
; V9A-NEXT: add x15, x15, :lo12:.Ltmp0
; V9A-NEXT: autia171615
+; V9A-NEXT: mov x30, x17
-; PAUTH-NEXT: autia1716
+; PAUTH-NEXT: autia x30, x16
; PAUTH-NEXT: .cfi_negate_ra_state
-; CHECK-NEXT: mov x30, x17
; CHECK-NEXT: b callee_stack_args
musttail call swifttailcc void @callee_stack_args(ptr swiftasync %ctx, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9)
ret void
@@ -136,26 +140,30 @@ define swifttailcc void @tail_call_fpdiff_b_key(ptr swiftasync %ctx) "branch-pro
; CHECK-NEXT: .cfi_restore w30
; CHECK-NEXT: .cfi_restore w29
; CHECK-NEXT: add x16, sp, #16
-; CHECK-NEXT: mov x17, x30
+; COMPAT-NEXT: mov x17, x30
; COMPAT-NEXT: adrp x15, .Ltmp1
; COMPAT-NEXT: add x15, x15, :lo12:.Ltmp1
; COMPAT-NEXT: hint #39
; COMPAT-NEXT: hint #14
+; COMPAT-NEXT: mov x30, x17
+; V83A-NEXT: mov x17, x30
; V83A-NEXT: adrp x15, .Ltmp1
; V83A-NEXT: add x15, x15, :lo12:.Ltmp1
; V83A-NEXT: hint #39
; V83A-NEXT: autib1716
+; V83A-NEXT: mov x30, x17
+; V9A-NEXT: mov x17, x30
; V9A-NEXT: adrp x15, .Ltmp1
; V9A-NEXT: add x15, x15, :lo12:.Ltmp1
; V9A-NEXT: autib171615
+; V9A-NEXT: mov x30, x17
-; PAUTH-NEXT: autib1716
+; PAUTH-NEXT: autib x30, x16
; PAUTH-NEXT: .cfi_negate_ra_state
-; CHECK-NEXT: mov x30, x17
; CHECK-NEXT: b callee_stack_args
musttail call swifttailcc void @callee_stack_args(ptr swiftasync %ctx, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9)
ret void
@@ -330,26 +338,30 @@ define swifttailcc void @indirect_tail_call_fpdiff_a_key(ptr swiftasync %ctx, pt
; CHECK-NEXT: .cfi_restore w30
; CHECK-NEXT: .cfi_restore w29
; CHECK-NEXT: add x16, sp, #16
-; CHECK-NEXT: mov x17, x30
+; COMPAT-NEXT: mov x17, x30
; COMPAT-NEXT: adrp x15, .Ltmp4
; COMPAT-NEXT: add x15, x15, :lo12:.Ltmp4
; COMPAT-NEXT: hint #39
; COMPAT-NEXT: hint #12
+; COMPAT-NEXT: mov x30, x17
+; V83A-NEXT: mov x17, x30
; V83A-NEXT: adrp x15, .Ltmp4
; V83A-NEXT: add x15, x15, :lo12:.Ltmp4
; V83A-NEXT: hint #39
; V83A-NEXT: autia1716
+; V83A-NEXT: mov x30, x17
+; V9A-NEXT: mov x17, x30
; V9A-NEXT: adrp x15, .Ltmp4
; V9A-NEXT: add x15, x15, :lo12:.Ltmp4
; V9A-NEXT: autia171615
+; V9A-NEXT: mov x30, x17
-; PAUTH-NEXT: autia1716
+; PAUTH-NEXT: autia x30, x16
; PAUTH-NEXT: .cfi_negate_ra_state
-; CHECK-NEXT: mov x30, x17
; CHECK-NEXT: br x8
musttail call swifttailcc void %callee(ptr swiftasync %ctx, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9)
ret void
@@ -406,26 +418,30 @@ define swifttailcc void @indirect_tail_call_fpdiff_b_key(ptr swiftasync %ctx, pt
; CHECK-NEXT: .cfi_restore w30
; CHECK-NEXT: .cfi_restore w29
; CHECK-NEXT: add x16, sp, #16
-; CHECK-NEXT: mov x17, x30
+; COMPAT-NEXT: mov x17, x30
; COMPAT-NEXT: adrp x15, .Ltmp5
; COMPAT-NEXT: add x15, x15, :lo12:.Ltmp5
; COMPAT-NEXT: hint #39
; COMPAT-NEXT: hint #14
+; COMPAT-NEXT: mov x30, x17
+; V83A-NEXT: mov x17, x30
; V83A-NEXT: adrp x15, .Ltmp5
; V83A-NEXT: add x15, x15, :lo12:.Ltmp5
; V83A-NEXT: hint #39
; V83A-NEXT: autib1716
+; V83A-NEXT: mov x30, x17
+; V9A-NEXT: mov x17, x30
; V9A-NEXT: adrp x15, .Ltmp5
; V9A-NEXT: add x15, x15, :lo12:.Ltmp5
; V9A-NEXT: autib171615
+; V9A-NEXT: mov x30, x17
-; PAUTH-NEXT: autib1716
+; PAUTH-NEXT: autib x30, x16
; PAUTH-NEXT: .cfi_negate_ra_state
-; CHECK-NEXT: mov x30, x17
; CHECK-NEXT: br x8
musttail call swifttailcc void %callee(ptr swiftasync %ctx, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9)
ret void
diff --git a/llvm/test/CodeGen/AArch64/swifttail-ptrauth.ll b/llvm/test/CodeGen/AArch64/swifttail-ptrauth.ll
index bf074c4966e4b..18466af6894e0 100644
--- a/llvm/test/CodeGen/AArch64/swifttail-ptrauth.ll
+++ b/llvm/test/CodeGen/AArch64/swifttail-ptrauth.ll
@@ -167,26 +167,30 @@ define swifttailcc void @caller_to8_from0() "branch-protection-pauth-lr" "sign-r
; CHECK-NEXT: .cfi_restore w30
; CHECK-NEXT: .cfi_restore w29
; CHECK-NEXT: add x16, sp, #16
-; CHECK-NEXT: mov x17, x30
+; COMPAT-NEXT: mov x17, x30
; COMPAT-NEXT: adrp x15, .Ltmp2
; COMPAT-NEXT: add x15, x15, :lo12:.Ltmp2
; COMPAT-NEXT: hint #39
; COMPAT-NEXT: hint #12
+; COMPAT-NEXT: mov x30, x17
+; V83A-NEXT: mov x17, x30
; V83A-NEXT: adrp x15, .Ltmp2
; V83A-NEXT: add x15, x15, :lo12:.Ltmp2
; V83A-NEXT: hint #39
; V83A-NEXT: autia1716
+; V83A-NEXT: mov x30, x17
+; V9A-NEXT: mov x17, x30
; V9A-NEXT: adrp x15, .Ltmp2
; V9A-NEXT: add x15, x15, :lo12:.Ltmp2
; V9A-NEXT: autia171615
+; V9A-NEXT: mov x30, x17
-; PAUTH-NEXT: autia1716
+; PAUTH-NEXT: autia x30, x16
; PAUTH-NEXT: .cfi_negate_ra_state
-; CHECK-NEXT: mov x30, x17
; CHECK-NEXT: b callee_stack8
tail call swifttailcc void @callee_stack8([8 x i64] poison, i64 42)
ret void
>From e95cea77d6c844be4ff92fd57215c17ef6b0e6c9 Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Thu, 23 Jul 2026 09:00:01 -0700
Subject: [PATCH 2/2] mov lambda
---
.../lib/Target/AArch64/AArch64PointerAuth.cpp | 40 ++++++-------------
1 file changed, 12 insertions(+), 28 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
index 94cade25c4ffe..a6dc926950d71 100644
--- a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
+++ b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp
@@ -269,12 +269,16 @@ void AArch64PointerAuthImpl::authenticateLR(
StackOffset::getFixed(-ArgumentStackToRestore), TII,
MachineInstr::FrameDestroy);
- if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::X17)
+ auto emitMOV = [&](Register Dst, Register Src) {
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), Dst)
.addReg(AArch64::XZR)
- .addReg(AArch64::LR)
+ .addReg(Src)
.addImm(0)
.setMIFlag(MachineInstr::FrameDestroy);
+ };
+
+ if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
+ emitMOV(AArch64::X17, AArch64::LR);
assert(PACSym && "No PAC instruction to refer to");
emitEpiloguePACSymOffsetIntoReg(*TII, MBB, MBBI, DL, PACSym,
@@ -285,17 +289,9 @@ void AArch64PointerAuthImpl::authenticateLR(
BuildMI(MBB, MBBI, DL, TII->get(AutOpc))
.setMIFlag(MachineInstr::FrameDestroy);
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::LR)
- .addReg(AArch64::XZR)
- .addReg(AArch64::X17)
- .addImm(0)
- .setMIFlag(MachineInstr::FrameDestroy);
+ emitMOV(AArch64::LR, AArch64::X17);
} else if (MFnI->branchProtectionPAuthLR()) {
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::X17)
- .addReg(AArch64::XZR)
- .addReg(AArch64::LR)
- .addImm(0)
- .setMIFlag(MachineInstr::FrameDestroy);
+ emitMOV(AArch64::X17, AArch64::LR);
assert(PACSym && "No PAC instruction to refer to");
emitEpiloguePACSymOffsetIntoReg(*TII, MBB, MBBI, DL, PACSym,
@@ -314,11 +310,7 @@ void AArch64PointerAuthImpl::authenticateLR(
BuildMI(MBB, MBBI, DL, TII->get(AutOpc))
.setMIFlag(MachineInstr::FrameDestroy);
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::LR)
- .addReg(AArch64::XZR)
- .addReg(AArch64::X17)
- .addImm(0)
- .setMIFlag(MachineInstr::FrameDestroy);
+ emitMOV(AArch64::LR, AArch64::X17);
} else if (Subtarget->hasPAuth()) {
BuildMI(MBB, MBBI, DL,
TII->get(UseBKey ? AArch64::AUTIB : AArch64::AUTIA), AArch64::LR)
@@ -327,22 +319,14 @@ void AArch64PointerAuthImpl::authenticateLR(
.setMIFlag(MachineInstr::FrameDestroy);
emitAUTCFI(MBB, MBBI, EmitAsyncCFI);
} else {
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::X17)
- .addReg(AArch64::XZR)
- .addReg(AArch64::LR)
- .addImm(0)
- .setMIFlag(MachineInstr::FrameDestroy);
+ emitMOV(AArch64::X17, AArch64::LR);
unsigned AutOpc = UseBKey ? AArch64::AUTIB1716 : AArch64::AUTIA1716;
BuildMI(MBB, MBBI, DL, TII->get(AutOpc))
.setMIFlag(MachineInstr::FrameDestroy);
emitAUTCFI(MBB, MBBI, EmitAsyncCFI);
- BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::LR)
- .addReg(AArch64::XZR)
- .addReg(AArch64::X17)
- .addImm(0)
- .setMIFlag(MachineInstr::FrameDestroy);
+ emitMOV(AArch64::LR, AArch64::X17);
}
return;
}
More information about the llvm-commits
mailing list