[llvm] [AArch64][PAC] Combine signing with address materialization (PR #130809)
Anatoly Trosinenko via llvm-commits
llvm-commits at lists.llvm.org
Wed May 21 12:46:16 PDT 2025
https://github.com/atrosinenko updated https://github.com/llvm/llvm-project/pull/130809
>From e10b8cb46c1d2a55c5acbc2ab8a95838804e744c Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Mon, 10 Mar 2025 15:14:55 +0300
Subject: [PATCH 1/5] [AArch64][PAC] Precommit tests on merging
MOVaddr/LOADgotAUTH with PAC*
---
.../GlobalISel/ptrauth-constant-in-code.ll | 74 +++++++++++++++++++
.../AArch64/ptrauth-constant-in-code.ll | 69 +++++++++++++++++
2 files changed, 143 insertions(+)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
index 12a3448111fcb..b7c52fc72c418 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
@@ -78,6 +78,80 @@ define ptr @foo() {
ret ptr ptrauth (ptr @g, i32 0)
}
+;--- finalize-isel.ll
+
+; RUN: llc < finalize-isel.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=1 \
+; RUN: -verify-machineinstrs -global-isel-abort=1 -stop-after=finalize-isel | \
+; RUN: FileCheck --check-prefixes=ISEL,ISEL-ELF %s
+; RUN: llc < finalize-isel.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=1 \
+; RUN: -verify-machineinstrs -global-isel-abort=1 -stop-after=finalize-isel | \
+; RUN: FileCheck --check-prefixes=ISEL %s
+
+ at const_table_local = dso_local constant [3 x ptr] [ptr null, ptr null, ptr null]
+ at const_table_got = constant [3 x ptr] [ptr null, ptr null, ptr null]
+
+define void @store_signed_const_local(ptr %dest) {
+; ISEL-LABEL: name: store_signed_const_local
+; ISEL: body:
+; ISEL: %0:gpr64common = COPY $x0
+; ISEL-NEXT: %10:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
+; ISEL-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-NEXT: %4:gpr64 = PACDA %10, %2
+; ISEL-NEXT: %14:gpr64 = COPY %4
+; ISEL-NEXT: STRXui %14, %0, 0 :: (store (p0) into %ir.dest)
+; ISEL-NEXT: RET_ReallyLR
+ %dest.i = ptrtoint ptr %dest to i64
+ %discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
+ %signed.i = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr ([2 x ptr], ptr @const_table_local, i32 0, i32 1) to i64), i32 2, i64 %discr)
+ %signed.ptr = inttoptr i64 %signed.i to ptr
+ store ptr %signed.ptr, ptr %dest
+ ret void
+}
+
+define void @store_signed_const_got(ptr %dest) {
+; ISEL-ELF-LABEL: name: store_signed_const_got
+; ISEL-ELF: body:
+; ISEL-ELF: %0:gpr64common = COPY $x0
+; ISEL-ELF-NEXT: %7:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got
+; ISEL-ELF-NEXT: %6:gpr64common = ADDXri %7, 8, 0
+; ISEL-ELF-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-ELF-NEXT: %4:gpr64 = PACDA %6, %2
+; ISEL-ELF-NEXT: %10:gpr64 = COPY %4
+; ISEL-ELF-NEXT: STRXui %10, %0, 0 :: (store (p0) into %ir.dest)
+; ISEL-ELF-NEXT: RET_ReallyLR
+ %dest.i = ptrtoint ptr %dest to i64
+ %discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
+ %signed.i = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr ([2 x ptr], ptr @const_table_got, i32 0, i32 1) to i64), i32 2, i64 %discr)
+ %signed.ptr = inttoptr i64 %signed.i to ptr
+ store ptr %signed.ptr, ptr %dest
+ ret void
+}
+
+define void @store_signed_arg(ptr %dest, ptr %p) {
+; ISEL-LABEL: name: store_signed_arg
+; ISEL: body:
+; ISEL: %0:gpr64common = COPY $x0
+; ISEL-NEXT: %1:gpr64common = COPY $x1
+; ISEL-NEXT: %3:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-NEXT: %6:gpr64common = ADDXri %1, 8, 0
+; Check that no implicit defs are added to PACDA instruction.
+; ISEL-NEXT: %8:gpr64 = PACDA %6, %3{{$}}
+; ISEL-NEXT: %10:gpr64 = COPY %8
+; ISEL-NEXT: STRXui %10, %0, 0 :: (store (p0) into %ir.dest)
+; ISEL-NEXT: RET_ReallyLR
+ %dest.i = ptrtoint ptr %dest to i64
+ %discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
+ %p.offset = getelementptr [2 x ptr], ptr %p, i32 0, i32 1
+ %p.offset.i = ptrtoint ptr %p.offset to i64
+ %signed.i = call i64 @llvm.ptrauth.sign(i64 %p.offset.i, i32 2, i64 %discr)
+ %signed.ptr = inttoptr i64 %signed.i to ptr
+ store ptr %signed.ptr, ptr %dest
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
+
;--- ok.ll
; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=1 \
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
index 76339a7cc5791..182e8f3d016e9 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
@@ -69,6 +69,75 @@ define ptr @foo() {
ret ptr ptrauth (ptr @g, i32 0)
}
+;--- finalize-isel.ll
+
+; RUN: llc < finalize-isel.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=0 \
+; RUN: -verify-machineinstrs -stop-after=finalize-isel | FileCheck --check-prefixes=ISEL,ISEL-ELF %s
+; RUN: llc < finalize-isel.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=0 \
+; RUN: -verify-machineinstrs -stop-after=finalize-isel | FileCheck --check-prefixes=ISEL %s
+
+ at const_table_local = dso_local constant [3 x ptr] [ptr null, ptr null, ptr null]
+ at const_table_got = constant [3 x ptr] [ptr null, ptr null, ptr null]
+
+define void @store_signed_const_local(ptr %dest) {
+; ISEL-LABEL: name: store_signed_const_local
+; ISEL: body:
+; ISEL: %0:gpr64common = COPY $x0
+; ISEL-NEXT: %1:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-NEXT: %2:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
+; ISEL-NEXT: %3:gpr64 = PACDA %2, killed %1
+; ISEL-NEXT: STRXui killed %3, %0, 0 :: (store (s64) into %ir.dest)
+; ISEL-NEXT: RET_ReallyLR
+ %dest.i = ptrtoint ptr %dest to i64
+ %discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
+ %signed.i = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr ([2 x ptr], ptr @const_table_local, i32 0, i32 1) to i64), i32 2, i64 %discr)
+ %signed.ptr = inttoptr i64 %signed.i to ptr
+ store ptr %signed.ptr, ptr %dest
+ ret void
+}
+
+define void @store_signed_const_got(ptr %dest) {
+; ISEL-ELF-LABEL: name: store_signed_const_got
+; ISEL-ELF: body:
+; ISEL-ELF: %0:gpr64common = COPY $x0
+; ISEL-ELF-NEXT: %1:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-ELF-NEXT: %2:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got, implicit-def dead $x16, implicit-def dead $x17, implicit-def dead $nzcv
+; ISEL-ELF-NEXT: %3:gpr64common = ADDXri killed %2, 8, 0
+; ISEL-ELF-NEXT: %4:gpr64 = PACDA %3, killed %1
+; ISEL-ELF-NEXT: STRXui killed %4, %0, 0 :: (store (s64) into %ir.dest)
+; ISEL-ELF-NEXT: RET_ReallyLR
+ %dest.i = ptrtoint ptr %dest to i64
+ %discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
+ %signed.i = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr ([2 x ptr], ptr @const_table_got, i32 0, i32 1) to i64), i32 2, i64 %discr)
+ %signed.ptr = inttoptr i64 %signed.i to ptr
+ store ptr %signed.ptr, ptr %dest
+ ret void
+}
+
+define void @store_signed_arg(ptr %dest, ptr %p) {
+; ISEL-LABEL: name: store_signed_arg
+; ISEL: body:
+; ISEL: %1:gpr64common = COPY $x1
+; ISEL-NEXT: %0:gpr64common = COPY $x0
+; ISEL-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-NEXT: %3:gpr64common = ADDXri %1, 8, 0
+; Check that no implicit defs are added to PACDA instruction.
+; ISEL-NEXT: %4:gpr64 = PACDA %3, killed %2{{$}}
+; ISEL-NEXT: STRXui killed %4, %0, 0 :: (store (s64) into %ir.dest)
+; ISEL-NEXT: RET_ReallyLR
+ %dest.i = ptrtoint ptr %dest to i64
+ %discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
+ %p.offset = getelementptr [2 x ptr], ptr %p, i32 0, i32 1
+ %p.offset.i = ptrtoint ptr %p.offset to i64
+ %signed.i = call i64 @llvm.ptrauth.sign(i64 %p.offset.i, i32 2, i64 %discr)
+ %signed.ptr = inttoptr i64 %signed.i to ptr
+ store ptr %signed.ptr, ptr %dest
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
+
;--- ok.ll
; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=0 \
>From 08a382ef2137a98b7fd72b6c98b7882e4cfcc0cc Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Mon, 10 Mar 2025 15:14:55 +0300
Subject: [PATCH 2/5] [AArch64][PAC] Combine signing with address
materialization
In pauthtest ABI, it is common to store a pointer signed with address
diversity to a heap-allocated object (namely, storing a signed pointer
to VTable as part of new object construction). This patch tries to
prevent introducing a signing oracle by combining pointer
materialization and its (re)signing into a single pseudo instruction
which is not expanded until AsmPrinter, if possible.
One of the typical patterns is materializing an unsigned pointer with
`MOVaddr` pseudo and then signing it with `PAC[ID][AB]` instruction,
which can be moved far away from `MOVaddr` by one of the passes in the
machine pipeline. As the storage address is not a `Constant` value, one
cannot simply emit a `ptrauth` constant in the frontend, which would be
selected into `MOVaddrPAC` pseudo.
Another pattern is fetching a pointer to VTable from a signed GOT entry
using `LOADgotAUTH` pseudo, authenticating and checking it, and then
re-signing after adding an offset.
This commit adds an instruction insertion hook for `PAC[ID][AB]` which
detects the above patterns and replaces it either with `MOVaddrPAC` or
`LOADgotPAC` instruction.
---
.../Target/AArch64/AArch64ISelLowering.cpp | 82 +++++++++++++++++++
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 2 +
llvm/lib/Target/AArch64/AArch64InstrInfo.h | 33 ++++++++
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 2 +
.../GlobalISel/ptrauth-constant-in-code.ll | 8 +-
.../AArch64/ptrauth-constant-in-code.ll | 8 +-
6 files changed, 131 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index c7858e4106358..e6f81dd4585da 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3349,6 +3349,78 @@ AArch64TargetLowering::EmitGetSMESaveSize(MachineInstr &MI,
MI.getOperand(0).getReg())
.addReg(AArch64::XZR);
BB->remove_instr(&MI);
+
+ return BB;
+}
+
+MachineBasicBlock *
+AArch64TargetLowering::tryRewritingPAC(MachineInstr &MI,
+ MachineBasicBlock *BB) const {
+ const TargetInstrInfo *TII = Subtarget->getInstrInfo();
+ MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
+ const DebugLoc &DL = MI.getDebugLoc();
+
+ MachineInstr *AddrInstr = nullptr;
+ int64_t Offset = 0;
+ // Try to find the address-setting instruction, accumulating the offset
+ // along the way. If any unknown pattern is found, keep everything as-is.
+ MachineOperand *CurOp = &MI.getOperand(1);
+ while (CurOp) {
+ MachineOperand *Def = MRI.getOneDef(CurOp->getReg());
+ if (!Def)
+ return BB;
+ MachineInstr *DefMI = Def->getParent();
+ assert(DefMI != nullptr);
+
+ switch (DefMI->getOpcode()) {
+ case AArch64::COPY:
+ CurOp = &DefMI->getOperand(1);
+ break;
+ case AArch64::ADDXri:
+ if (DefMI->getOperand(3).getImm() != 0) // shifts are not handled
+ return BB;
+ CurOp = &DefMI->getOperand(1);
+ Offset += DefMI->getOperand(2).getImm();
+ break;
+ case AArch64::MOVaddr:
+ case AArch64::LOADgotAUTH:
+ AddrInstr = DefMI;
+ CurOp = nullptr;
+ break;
+ default:
+ return BB;
+ }
+ }
+
+ unsigned NewOpcode = AddrInstr->getOpcode() == AArch64::LOADgotAUTH
+ ? AArch64::LOADgotPAC
+ : AArch64::MOVaddrPAC;
+ MachineOperand &AddrOp = AddrInstr->getOperand(1);
+ unsigned TargetFlags = AddrOp.getTargetFlags() & ~AArch64II::MO_PAGE;
+ Offset += AddrOp.getOffset();
+
+ // MOVaddrPAC and LOADgotPAC pseudos are expanded so that they use X16/X17
+ // internally, thus their restrictions on the register class of $AddrDisc
+ // operand are stricter than those of real PAC* instructions.
+ // If the original instruction accepts a discriminator operand, make sure
+ // it is moved out of X16/X17.
+ Register DiscReg = AArch64::XZR;
+ if (!isPACWithZeroDisc(MI.getOpcode())) {
+ DiscReg = MRI.createVirtualRegister(&AArch64::GPR64noipRegClass);
+ BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), DiscReg)
+ .addReg(MI.getOperand(2).getReg());
+ }
+
+ BuildMI(*BB, MI, DL, TII->get(NewOpcode))
+ .addGlobalAddress(AddrOp.getGlobal(), Offset, TargetFlags)
+ .addImm(getKeyForPACOpcode(MI.getOpcode()))
+ .addReg(DiscReg)
+ .addImm(0);
+
+ BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), MI.getOperand(0).getReg())
+ .addReg(AArch64::X16);
+
+ MI.removeFromParent();
return BB;
}
@@ -3450,6 +3522,16 @@ MachineBasicBlock *AArch64TargetLowering::EmitInstrWithCustomInserter(
return EmitZTInstr(MI, BB, AArch64::ZERO_T, /*Op0IsDef=*/true);
case AArch64::MOVT_TIZ_PSEUDO:
return EmitZTInstr(MI, BB, AArch64::MOVT_TIZ, /*Op0IsDef=*/true);
+
+ case AArch64::PACDA:
+ case AArch64::PACDB:
+ case AArch64::PACIA:
+ case AArch64::PACIB:
+ case AArch64::PACDZA:
+ case AArch64::PACDZB:
+ case AArch64::PACIZA:
+ case AArch64::PACIZB:
+ return tryRewritingPAC(MI, BB);
}
}
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index c1e6d70099fa5..54cff853bfae2 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -679,6 +679,8 @@ class AArch64TargetLowering : public TargetLowering {
MachineBasicBlock *BB) const;
MachineBasicBlock *EmitGetSMESaveSize(MachineInstr &MI,
MachineBasicBlock *BB) const;
+ MachineBasicBlock *tryRewritingPAC(MachineInstr &MI,
+ MachineBasicBlock *BB) const;
MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr &MI,
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
index 0ffaca9af4006..763b792bb7b7d 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h
@@ -790,6 +790,39 @@ static inline unsigned getPACOpcodeForKey(AArch64PACKey::ID K, bool Zero) {
llvm_unreachable("Unhandled AArch64PACKey::ID enum");
}
+static inline AArch64PACKey::ID getKeyForPACOpcode(unsigned Opcode) {
+ switch (Opcode) {
+ case AArch64::PACDA:
+ case AArch64::PACDZA:
+ return AArch64PACKey::DA;
+ case AArch64::PACDB:
+ case AArch64::PACDZB:
+ return AArch64PACKey::DB;
+ case AArch64::PACIA:
+ case AArch64::PACIZA:
+ return AArch64PACKey::IA;
+ case AArch64::PACIB:
+ case AArch64::PACIZB:
+ return AArch64PACKey::IB;
+ }
+ llvm_unreachable("Unhandled PAC opcode");
+}
+
+static inline bool isPACWithZeroDisc(unsigned Opcode) {
+ switch (Opcode) {
+ case AArch64::PACDA:
+ case AArch64::PACDB:
+ case AArch64::PACIA:
+ case AArch64::PACIB:
+ return false;
+ case AArch64::PACDZA:
+ case AArch64::PACDZB:
+ case AArch64::PACIZA:
+ case AArch64::PACIZB:
+ return true;
+ }
+ llvm_unreachable("Unhandled PAC opcode");
+}
// struct TSFlags {
#define TSFLAG_ELEMENT_SIZE_TYPE(X) (X) // 3-bits
#define TSFLAG_DESTRUCTIVE_INST_TYPE(X) ((X) << 3) // 4-bits
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 010c7c391527f..37cc9c3ec2b5d 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1845,7 +1845,9 @@ let Predicates = [HasPAuth] in {
def DZB : SignAuthZero<prefix_z, 0b11, !strconcat(asm, "dzb"), op>;
}
+ let usesCustomInserter = true in
defm PAC : SignAuth<0b000, 0b010, "pac", int_ptrauth_sign>;
+
defm AUT : SignAuth<0b001, 0b011, "aut", null_frag>;
def XPACI : ClearAuth<0, "xpaci">;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
index b7c52fc72c418..4ef5cc7981924 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
@@ -96,7 +96,9 @@ define void @store_signed_const_local(ptr %dest) {
; ISEL: %0:gpr64common = COPY $x0
; ISEL-NEXT: %10:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
; ISEL-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
-; ISEL-NEXT: %4:gpr64 = PACDA %10, %2
+; ISEL-NEXT: %15:gpr64noip = COPY %2
+; ISEL-NEXT: MOVaddrPAC @const_table_local + 8, 2, %15, 0, implicit-def $x16, implicit-def $x17
+; ISEL-NEXT: %4:gpr64 = COPY $x16
; ISEL-NEXT: %14:gpr64 = COPY %4
; ISEL-NEXT: STRXui %14, %0, 0 :: (store (p0) into %ir.dest)
; ISEL-NEXT: RET_ReallyLR
@@ -115,7 +117,9 @@ define void @store_signed_const_got(ptr %dest) {
; ISEL-ELF-NEXT: %7:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got
; ISEL-ELF-NEXT: %6:gpr64common = ADDXri %7, 8, 0
; ISEL-ELF-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
-; ISEL-ELF-NEXT: %4:gpr64 = PACDA %6, %2
+; ISEL-ELF-NEXT: %12:gpr64noip = COPY %2
+; ISEL-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %12, 0, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
+; ISEL-ELF-NEXT: %4:gpr64 = COPY $x16
; ISEL-ELF-NEXT: %10:gpr64 = COPY %4
; ISEL-ELF-NEXT: STRXui %10, %0, 0 :: (store (p0) into %ir.dest)
; ISEL-ELF-NEXT: RET_ReallyLR
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
index 182e8f3d016e9..e59f7925b7e02 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
@@ -85,7 +85,9 @@ define void @store_signed_const_local(ptr %dest) {
; ISEL: %0:gpr64common = COPY $x0
; ISEL-NEXT: %1:gpr64common = PAUTH_BLEND %0, 1234
; ISEL-NEXT: %2:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
-; ISEL-NEXT: %3:gpr64 = PACDA %2, killed %1
+; ISEL-NEXT: %4:gpr64noip = COPY %1
+; ISEL-NEXT: MOVaddrPAC @const_table_local + 8, 2, %4, 0, implicit-def $x16, implicit-def $x17
+; ISEL-NEXT: %3:gpr64 = COPY $x16
; ISEL-NEXT: STRXui killed %3, %0, 0 :: (store (s64) into %ir.dest)
; ISEL-NEXT: RET_ReallyLR
%dest.i = ptrtoint ptr %dest to i64
@@ -103,7 +105,9 @@ define void @store_signed_const_got(ptr %dest) {
; ISEL-ELF-NEXT: %1:gpr64common = PAUTH_BLEND %0, 1234
; ISEL-ELF-NEXT: %2:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got, implicit-def dead $x16, implicit-def dead $x17, implicit-def dead $nzcv
; ISEL-ELF-NEXT: %3:gpr64common = ADDXri killed %2, 8, 0
-; ISEL-ELF-NEXT: %4:gpr64 = PACDA %3, killed %1
+; ISEL-ELF-NEXT: %5:gpr64noip = COPY %1
+; ISEL-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %5, 0, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
+; ISEL-ELF-NEXT: %4:gpr64 = COPY $x16
; ISEL-ELF-NEXT: STRXui killed %4, %0, 0 :: (store (s64) into %ir.dest)
; ISEL-ELF-NEXT: RET_ReallyLR
%dest.i = ptrtoint ptr %dest to i64
>From fa4f9233850d2eb22f561636ed2db40e9ba1bb1e Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Thu, 27 Mar 2025 16:45:34 +0300
Subject: [PATCH 3/5] Test generated asm, remove dead LOADgotAUTH
---
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 2 +
.../GlobalISel/ptrauth-constant-in-code.ll | 117 ++++++++++++------
.../AArch64/ptrauth-constant-in-code.ll | 109 +++++++++++-----
.../CodeGen/AArch64/ptrauth-tiny-model-pic.ll | 4 +-
.../AArch64/ptrauth-tiny-model-static.ll | 4 +-
5 files changed, 165 insertions(+), 71 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 37cc9c3ec2b5d..d44e5f3a33fd5 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1995,6 +1995,8 @@ let Predicates = [HasPAuth] in {
def LOADgotAUTH : Pseudo<(outs GPR64common:$dst), (ins i64imm:$addr), []>,
Sched<[WriteI, ReadI]> {
+ // Make it possible to eliminate dead instruction after folding it into LOADgotPAC.
+ let hasSideEffects = 0;
let Defs = [X16,X17,NZCV];
let Size = 44;
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
index 4ef5cc7981924..a92179a3f3fe8 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
@@ -82,26 +82,45 @@ define ptr @foo() {
; RUN: llc < finalize-isel.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=1 \
; RUN: -verify-machineinstrs -global-isel-abort=1 -stop-after=finalize-isel | \
-; RUN: FileCheck --check-prefixes=ISEL,ISEL-ELF %s
+; RUN: FileCheck --check-prefixes=ISEL-MIR,ISEL-MIR-ELF %s
; RUN: llc < finalize-isel.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=1 \
; RUN: -verify-machineinstrs -global-isel-abort=1 -stop-after=finalize-isel | \
-; RUN: FileCheck --check-prefixes=ISEL %s
+; RUN: FileCheck --check-prefixes=ISEL-MIR %s
+; RUN: llc < finalize-isel.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=1 \
+; RUN: -verify-machineinstrs -global-isel-abort=1 -asm-verbose=0 | \
+; RUN: FileCheck --check-prefixes=ISEL-ASM,ISEL-ASM-ELF %s
+; RUN: llc < finalize-isel.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=1 \
+; RUN: -verify-machineinstrs -global-isel-abort=1 -asm-verbose=0 | \
+; RUN: FileCheck --check-prefixes=ISEL-ASM,ISEL-ASM-MACHO %s
@const_table_local = dso_local constant [3 x ptr] [ptr null, ptr null, ptr null]
@const_table_got = constant [3 x ptr] [ptr null, ptr null, ptr null]
define void @store_signed_const_local(ptr %dest) {
-; ISEL-LABEL: name: store_signed_const_local
-; ISEL: body:
-; ISEL: %0:gpr64common = COPY $x0
-; ISEL-NEXT: %10:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
-; ISEL-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
-; ISEL-NEXT: %15:gpr64noip = COPY %2
-; ISEL-NEXT: MOVaddrPAC @const_table_local + 8, 2, %15, 0, implicit-def $x16, implicit-def $x17
-; ISEL-NEXT: %4:gpr64 = COPY $x16
-; ISEL-NEXT: %14:gpr64 = COPY %4
-; ISEL-NEXT: STRXui %14, %0, 0 :: (store (p0) into %ir.dest)
-; ISEL-NEXT: RET_ReallyLR
+; ISEL-MIR-LABEL: name: store_signed_const_local
+; ISEL-MIR: body:
+; ISEL-MIR: %0:gpr64common = COPY $x0
+; ISEL-MIR-NEXT: %10:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
+; ISEL-MIR-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-NEXT: %15:gpr64noip = COPY %2
+; ISEL-MIR-NEXT: MOVaddrPAC @const_table_local + 8, 2, %15, 0, implicit-def $x16, implicit-def $x17
+; ISEL-MIR-NEXT: %4:gpr64 = COPY $x16
+; ISEL-MIR-NEXT: %14:gpr64 = COPY %4
+; ISEL-MIR-NEXT: STRXui %14, %0, 0 :: (store (p0) into %ir.dest)
+; ISEL-MIR-NEXT: RET_ReallyLR
+;
+; ISEL-ASM-LABEL: store_signed_const_local:
+; ISEL-ASM-NEXT: .cfi_startproc
+; ISEL-ASM-NEXT: mov x8, x0
+; ISEL-ASM-NEXT: movk x8, #1234, lsl #48
+; ISEL-ASM-ELF-NEXT: adrp x16, const_table_local
+; ISEL-ASM-ELF-NEXT: add x16, x16, :lo12:const_table_local
+; ISEL-ASM-MACHO-NEXT: adrp x16, _const_table_local at PAGE
+; ISEL-ASM-MACHO-NEXT: add x16, x16, _const_table_local at PAGEOFF
+; ISEL-ASM-NEXT: add x16, x16, #8
+; ISEL-ASM-NEXT: pacda x16, x8
+; ISEL-ASM-NEXT: str x16, [x0]
+; ISEL-ASM-NEXT: ret
%dest.i = ptrtoint ptr %dest to i64
%discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
%signed.i = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr ([2 x ptr], ptr @const_table_local, i32 0, i32 1) to i64), i32 2, i64 %discr)
@@ -111,18 +130,37 @@ define void @store_signed_const_local(ptr %dest) {
}
define void @store_signed_const_got(ptr %dest) {
-; ISEL-ELF-LABEL: name: store_signed_const_got
-; ISEL-ELF: body:
-; ISEL-ELF: %0:gpr64common = COPY $x0
-; ISEL-ELF-NEXT: %7:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got
-; ISEL-ELF-NEXT: %6:gpr64common = ADDXri %7, 8, 0
-; ISEL-ELF-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
-; ISEL-ELF-NEXT: %12:gpr64noip = COPY %2
-; ISEL-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %12, 0, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
-; ISEL-ELF-NEXT: %4:gpr64 = COPY $x16
-; ISEL-ELF-NEXT: %10:gpr64 = COPY %4
-; ISEL-ELF-NEXT: STRXui %10, %0, 0 :: (store (p0) into %ir.dest)
-; ISEL-ELF-NEXT: RET_ReallyLR
+; ISEL-MIR-ELF-LABEL: name: store_signed_const_got
+; ISEL-MIR-ELF: body:
+; ISEL-MIR-ELF: %0:gpr64common = COPY $x0
+; ISEL-MIR-ELF-NEXT: %7:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got
+; ISEL-MIR-ELF-NEXT: %6:gpr64common = ADDXri %7, 8, 0
+; ISEL-MIR-ELF-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-ELF-NEXT: %12:gpr64noip = COPY %2
+; ISEL-MIR-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %12, 0, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
+; ISEL-MIR-ELF-NEXT: %4:gpr64 = COPY $x16
+; ISEL-MIR-ELF-NEXT: %10:gpr64 = COPY %4
+; ISEL-MIR-ELF-NEXT: STRXui %10, %0, 0 :: (store (p0) into %ir.dest)
+; ISEL-MIR-ELF-NEXT: RET_ReallyLR
+;
+; ISEL-ASM-ELF-LABEL: store_signed_const_got:
+; ISEL-ASM-ELF-NEXT: .cfi_startproc
+; ISEL-ASM-ELF-NEXT: mov x8, x0
+; ISEL-ASM-ELF-NEXT: movk x8, #1234, lsl #48
+; ISEL-ASM-ELF-NEXT: adrp x17, :got_auth:const_table_got
+; ISEL-ASM-ELF-NEXT: add x17, x17, :got_auth_lo12:const_table_got
+; ISEL-ASM-ELF-NEXT: ldr x16, [x17]
+; ISEL-ASM-ELF-NEXT: autda x16, x17
+; ISEL-ASM-ELF-NEXT: mov x17, x16
+; ISEL-ASM-ELF-NEXT: xpacd x17
+; ISEL-ASM-ELF-NEXT: cmp x16, x17
+; ISEL-ASM-ELF-NEXT: b.eq .Lauth_success_0
+; ISEL-ASM-ELF-NEXT: brk #0xc472
+; ISEL-ASM-ELF-NEXT: .Lauth_success_0:
+; ISEL-ASM-ELF-NEXT: add x16, x16, #8
+; ISEL-ASM-ELF-NEXT: pacda x16, x8
+; ISEL-ASM-ELF-NEXT: str x16, [x0]
+; ISEL-ASM-ELF-NEXT: ret
%dest.i = ptrtoint ptr %dest to i64
%discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
%signed.i = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr ([2 x ptr], ptr @const_table_got, i32 0, i32 1) to i64), i32 2, i64 %discr)
@@ -132,17 +170,26 @@ define void @store_signed_const_got(ptr %dest) {
}
define void @store_signed_arg(ptr %dest, ptr %p) {
-; ISEL-LABEL: name: store_signed_arg
-; ISEL: body:
-; ISEL: %0:gpr64common = COPY $x0
-; ISEL-NEXT: %1:gpr64common = COPY $x1
-; ISEL-NEXT: %3:gpr64common = PAUTH_BLEND %0, 1234
-; ISEL-NEXT: %6:gpr64common = ADDXri %1, 8, 0
+; ISEL-MIR-LABEL: name: store_signed_arg
+; ISEL-MIR: body:
+; ISEL-MIR: %0:gpr64common = COPY $x0
+; ISEL-MIR-NEXT: %1:gpr64common = COPY $x1
+; ISEL-MIR-NEXT: %3:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-NEXT: %6:gpr64common = ADDXri %1, 8, 0
; Check that no implicit defs are added to PACDA instruction.
-; ISEL-NEXT: %8:gpr64 = PACDA %6, %3{{$}}
-; ISEL-NEXT: %10:gpr64 = COPY %8
-; ISEL-NEXT: STRXui %10, %0, 0 :: (store (p0) into %ir.dest)
-; ISEL-NEXT: RET_ReallyLR
+; ISEL-MIR-NEXT: %8:gpr64 = PACDA %6, %3{{$}}
+; ISEL-MIR-NEXT: %10:gpr64 = COPY %8
+; ISEL-MIR-NEXT: STRXui %10, %0, 0 :: (store (p0) into %ir.dest)
+; ISEL-MIR-NEXT: RET_ReallyLR
+;
+; ISEL-ASM-LABEL: store_signed_arg:
+; ISEL-ASM-NEXT: .cfi_startproc
+; ISEL-ASM-NEXT: mov x8, x0
+; ISEL-ASM-NEXT: movk x8, #1234, lsl #48
+; ISEL-ASM-NEXT: add x9, x1, #8
+; ISEL-ASM-NEXT: pacda x9, x8
+; ISEL-ASM-NEXT: str x9, [x0]
+; ISEL-ASM-NEXT: ret
%dest.i = ptrtoint ptr %dest to i64
%discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
%p.offset = getelementptr [2 x ptr], ptr %p, i32 0, i32 1
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
index e59f7925b7e02..64ddd9f262233 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
@@ -72,24 +72,41 @@ define ptr @foo() {
;--- finalize-isel.ll
; RUN: llc < finalize-isel.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=0 \
-; RUN: -verify-machineinstrs -stop-after=finalize-isel | FileCheck --check-prefixes=ISEL,ISEL-ELF %s
+; RUN: -verify-machineinstrs -stop-after=finalize-isel | FileCheck --check-prefixes=ISEL-MIR,ISEL-MIR-ELF %s
; RUN: llc < finalize-isel.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=0 \
-; RUN: -verify-machineinstrs -stop-after=finalize-isel | FileCheck --check-prefixes=ISEL %s
+; RUN: -verify-machineinstrs -stop-after=finalize-isel | FileCheck --check-prefixes=ISEL-MIR %s
+; RUN: llc < finalize-isel.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=0 \
+; RUN: -verify-machineinstrs -asm-verbose=0 | FileCheck --check-prefixes=ISEL-ASM,ISEL-ASM-ELF %s
+; RUN: llc < finalize-isel.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=0 \
+; RUN: -verify-machineinstrs -asm-verbose=0 | FileCheck --check-prefixes=ISEL-ASM,ISEL-ASM-MACHO %s
@const_table_local = dso_local constant [3 x ptr] [ptr null, ptr null, ptr null]
@const_table_got = constant [3 x ptr] [ptr null, ptr null, ptr null]
define void @store_signed_const_local(ptr %dest) {
-; ISEL-LABEL: name: store_signed_const_local
-; ISEL: body:
-; ISEL: %0:gpr64common = COPY $x0
-; ISEL-NEXT: %1:gpr64common = PAUTH_BLEND %0, 1234
-; ISEL-NEXT: %2:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
-; ISEL-NEXT: %4:gpr64noip = COPY %1
-; ISEL-NEXT: MOVaddrPAC @const_table_local + 8, 2, %4, 0, implicit-def $x16, implicit-def $x17
-; ISEL-NEXT: %3:gpr64 = COPY $x16
-; ISEL-NEXT: STRXui killed %3, %0, 0 :: (store (s64) into %ir.dest)
-; ISEL-NEXT: RET_ReallyLR
+; ISEL-MIR-LABEL: name: store_signed_const_local
+; ISEL-MIR: body:
+; ISEL-MIR: %0:gpr64common = COPY $x0
+; ISEL-MIR-NEXT: %1:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-NEXT: %2:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
+; ISEL-MIR-NEXT: %4:gpr64noip = COPY %1
+; ISEL-MIR-NEXT: MOVaddrPAC @const_table_local + 8, 2, %4, 0, implicit-def $x16, implicit-def $x17
+; ISEL-MIR-NEXT: %3:gpr64 = COPY $x16
+; ISEL-MIR-NEXT: STRXui killed %3, %0, 0 :: (store (s64) into %ir.dest)
+; ISEL-MIR-NEXT: RET_ReallyLR
+;
+; ISEL-ASM-LABEL: store_signed_const_local:
+; ISEL-ASM-NEXT: .cfi_startproc
+; ISEL-ASM-NEXT: mov x8, x0
+; ISEL-ASM-NEXT: movk x8, #1234, lsl #48
+; ISEL-ASM-ELF-NEXT: adrp x16, const_table_local
+; ISEL-ASM-ELF-NEXT: add x16, x16, :lo12:const_table_local
+; ISEL-ASM-MACHO-NEXT: adrp x16, _const_table_local at PAGE
+; ISEL-ASM-MACHO-NEXT: add x16, x16, _const_table_local at PAGEOFF
+; ISEL-ASM-NEXT: add x16, x16, #8
+; ISEL-ASM-NEXT: pacda x16, x8
+; ISEL-ASM-NEXT: str x16, [x0]
+; ISEL-ASM-NEXT: ret
%dest.i = ptrtoint ptr %dest to i64
%discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
%signed.i = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr ([2 x ptr], ptr @const_table_local, i32 0, i32 1) to i64), i32 2, i64 %discr)
@@ -99,17 +116,36 @@ define void @store_signed_const_local(ptr %dest) {
}
define void @store_signed_const_got(ptr %dest) {
-; ISEL-ELF-LABEL: name: store_signed_const_got
-; ISEL-ELF: body:
-; ISEL-ELF: %0:gpr64common = COPY $x0
-; ISEL-ELF-NEXT: %1:gpr64common = PAUTH_BLEND %0, 1234
-; ISEL-ELF-NEXT: %2:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got, implicit-def dead $x16, implicit-def dead $x17, implicit-def dead $nzcv
-; ISEL-ELF-NEXT: %3:gpr64common = ADDXri killed %2, 8, 0
-; ISEL-ELF-NEXT: %5:gpr64noip = COPY %1
-; ISEL-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %5, 0, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
-; ISEL-ELF-NEXT: %4:gpr64 = COPY $x16
-; ISEL-ELF-NEXT: STRXui killed %4, %0, 0 :: (store (s64) into %ir.dest)
-; ISEL-ELF-NEXT: RET_ReallyLR
+; ISEL-MIR-ELF-LABEL: name: store_signed_const_got
+; ISEL-MIR-ELF: body:
+; ISEL-MIR-ELF: %0:gpr64common = COPY $x0
+; ISEL-MIR-ELF-NEXT: %1:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-ELF-NEXT: %2:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got, implicit-def dead $x16, implicit-def dead $x17, implicit-def dead $nzcv
+; ISEL-MIR-ELF-NEXT: %3:gpr64common = ADDXri killed %2, 8, 0
+; ISEL-MIR-ELF-NEXT: %5:gpr64noip = COPY %1
+; ISEL-MIR-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %5, 0, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
+; ISEL-MIR-ELF-NEXT: %4:gpr64 = COPY $x16
+; ISEL-MIR-ELF-NEXT: STRXui killed %4, %0, 0 :: (store (s64) into %ir.dest)
+; ISEL-MIR-ELF-NEXT: RET_ReallyLR
+;
+; ISEL-ASM-ELF-LABEL: store_signed_const_got:
+; ISEL-ASM-ELF-NEXT: .cfi_startproc
+; ISEL-ASM-ELF-NEXT: mov x8, x0
+; ISEL-ASM-ELF-NEXT: movk x8, #1234, lsl #48
+; ISEL-ASM-ELF-NEXT: adrp x17, :got_auth:const_table_got
+; ISEL-ASM-ELF-NEXT: add x17, x17, :got_auth_lo12:const_table_got
+; ISEL-ASM-ELF-NEXT: ldr x16, [x17]
+; ISEL-ASM-ELF-NEXT: autda x16, x17
+; ISEL-ASM-ELF-NEXT: mov x17, x16
+; ISEL-ASM-ELF-NEXT: xpacd x17
+; ISEL-ASM-ELF-NEXT: cmp x16, x17
+; ISEL-ASM-ELF-NEXT: b.eq .Lauth_success_0
+; ISEL-ASM-ELF-NEXT: brk #0xc472
+; ISEL-ASM-ELF-NEXT: .Lauth_success_0:
+; ISEL-ASM-ELF-NEXT: add x16, x16, #8
+; ISEL-ASM-ELF-NEXT: pacda x16, x8
+; ISEL-ASM-ELF-NEXT: str x16, [x0]
+; ISEL-ASM-ELF-NEXT: ret
%dest.i = ptrtoint ptr %dest to i64
%discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
%signed.i = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr ([2 x ptr], ptr @const_table_got, i32 0, i32 1) to i64), i32 2, i64 %discr)
@@ -119,16 +155,25 @@ define void @store_signed_const_got(ptr %dest) {
}
define void @store_signed_arg(ptr %dest, ptr %p) {
-; ISEL-LABEL: name: store_signed_arg
-; ISEL: body:
-; ISEL: %1:gpr64common = COPY $x1
-; ISEL-NEXT: %0:gpr64common = COPY $x0
-; ISEL-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
-; ISEL-NEXT: %3:gpr64common = ADDXri %1, 8, 0
+; ISEL-MIR-LABEL: name: store_signed_arg
+; ISEL-MIR: body:
+; ISEL-MIR: %1:gpr64common = COPY $x1
+; ISEL-MIR-NEXT: %0:gpr64common = COPY $x0
+; ISEL-MIR-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-NEXT: %3:gpr64common = ADDXri %1, 8, 0
; Check that no implicit defs are added to PACDA instruction.
-; ISEL-NEXT: %4:gpr64 = PACDA %3, killed %2{{$}}
-; ISEL-NEXT: STRXui killed %4, %0, 0 :: (store (s64) into %ir.dest)
-; ISEL-NEXT: RET_ReallyLR
+; ISEL-MIR-NEXT: %4:gpr64 = PACDA %3, killed %2{{$}}
+; ISEL-MIR-NEXT: STRXui killed %4, %0, 0 :: (store (s64) into %ir.dest)
+; ISEL-MIR-NEXT: RET_ReallyLR
+;
+; ISEL-ASM-LABEL: store_signed_arg:
+; ISEL-ASM-NEXT: .cfi_startproc
+; ISEL-ASM-NEXT: mov x8, x0
+; ISEL-ASM-NEXT: movk x8, #1234, lsl #48
+; ISEL-ASM-NEXT: add x9, x1, #8
+; ISEL-ASM-NEXT: pacda x9, x8
+; ISEL-ASM-NEXT: str x9, [x0]
+; ISEL-ASM-NEXT: ret
%dest.i = ptrtoint ptr %dest to i64
%discr = call i64 @llvm.ptrauth.blend(i64 %dest.i, i64 1234)
%p.offset = getelementptr [2 x ptr], ptr %p, i32 0, i32 1
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll
index 9d13714bbefe3..cb8f1f4021eea 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll
@@ -34,7 +34,6 @@ define dso_preemptable void @foo1() {
; TRAP-NEXT: brk #0xc472
; TRAP-NEXT: .Lauth_success_0:
; TRAP-NEXT: mov x8, x16
-; CHECK-NEXT: ldrb w8, [x8]
; CHECK-NEXT: adr x17, :got_auth:dst
; NOTRAP-NEXT: ldr x9, [x17]
; NOTRAP-NEXT: autda x9, x17
@@ -47,6 +46,7 @@ define dso_preemptable void @foo1() {
; TRAP-NEXT: brk #0xc472
; TRAP-NEXT: .Lauth_success_1:
; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: ldrb w8, [x8]
; CHECK-NEXT: strb w8, [x9]
; CHECK-NEXT: ret
@@ -106,7 +106,6 @@ define dso_preemptable void @foo3() {
; TRAP-NEXT: brk #0xc472
; TRAP-NEXT: .Lauth_success_4:
; TRAP-NEXT: mov x8, x16
-; CHECK-NEXT: ldrb w8, [x8]
; CHECK-NEXT: adr x17, :got_auth:ptr
; NOTRAP-NEXT: ldr x9, [x17]
; NOTRAP-NEXT: autda x9, x17
@@ -119,6 +118,7 @@ define dso_preemptable void @foo3() {
; TRAP-NEXT: brk #0xc472
; TRAP-NEXT: .Lauth_success_5:
; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: ldrb w8, [x8]
; CHECK-NEXT: ldr x9, [x9]
; CHECK-NEXT: strb w8, [x9]
; CHECK-NEXT: ret
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll
index 2d098b70acccc..0bf54ab49381e 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll
@@ -34,7 +34,6 @@ define dso_local void @foo1() {
; TRAP-NEXT: brk #0xc472
; TRAP-NEXT: .Lauth_success_0:
; TRAP-NEXT: mov x8, x16
-; CHECK-NEXT: ldrb w8, [x8]
; CHECK-NEXT: adr x17, :got_auth:dst
; NOTRAP-NEXT: ldr x9, [x17]
; NOTRAP-NEXT: autda x9, x17
@@ -47,6 +46,7 @@ define dso_local void @foo1() {
; TRAP-NEXT: brk #0xc472
; TRAP-NEXT: .Lauth_success_1:
; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: ldrb w8, [x8]
; CHECK-NEXT: strb w8, [x9]
; CHECK-NEXT: ret
@@ -106,7 +106,6 @@ define dso_local void @foo3() {
; TRAP-NEXT: brk #0xc472
; TRAP-NEXT: .Lauth_success_4:
; TRAP-NEXT: mov x8, x16
-; CHECK-NEXT: ldrb w8, [x8]
; CHECK-NEXT: adr x17, :got_auth:ptr
; NOTRAP-NEXT: ldr x9, [x17]
; NOTRAP-NEXT: autda x9, x17
@@ -119,6 +118,7 @@ define dso_local void @foo3() {
; TRAP-NEXT: brk #0xc472
; TRAP-NEXT: .Lauth_success_5:
; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: ldrb w8, [x8]
; CHECK-NEXT: ldr x9, [x9]
; CHECK-NEXT: strb w8, [x9]
; CHECK-NEXT: ret
>From 29c91c84cb3e842b5e01246dc55fe9ff9a7ca54c Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Wed, 21 May 2025 21:52:51 +0300
Subject: [PATCH 4/5] Fix tests after rebase
---
.../AArch64/GlobalISel/ptrauth-constant-in-code.ll | 8 ++++----
llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
index a92179a3f3fe8..ca637224014ad 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
@@ -101,7 +101,7 @@ define void @store_signed_const_local(ptr %dest) {
; ISEL-MIR: body:
; ISEL-MIR: %0:gpr64common = COPY $x0
; ISEL-MIR-NEXT: %10:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
-; ISEL-MIR-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-NEXT: %2:gpr64common = MOVKXi %0, 1234, 48
; ISEL-MIR-NEXT: %15:gpr64noip = COPY %2
; ISEL-MIR-NEXT: MOVaddrPAC @const_table_local + 8, 2, %15, 0, implicit-def $x16, implicit-def $x17
; ISEL-MIR-NEXT: %4:gpr64 = COPY $x16
@@ -135,7 +135,7 @@ define void @store_signed_const_got(ptr %dest) {
; ISEL-MIR-ELF: %0:gpr64common = COPY $x0
; ISEL-MIR-ELF-NEXT: %7:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got
; ISEL-MIR-ELF-NEXT: %6:gpr64common = ADDXri %7, 8, 0
-; ISEL-MIR-ELF-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-ELF-NEXT: %2:gpr64common = MOVKXi %0, 1234, 48
; ISEL-MIR-ELF-NEXT: %12:gpr64noip = COPY %2
; ISEL-MIR-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %12, 0, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
; ISEL-MIR-ELF-NEXT: %4:gpr64 = COPY $x16
@@ -174,7 +174,7 @@ define void @store_signed_arg(ptr %dest, ptr %p) {
; ISEL-MIR: body:
; ISEL-MIR: %0:gpr64common = COPY $x0
; ISEL-MIR-NEXT: %1:gpr64common = COPY $x1
-; ISEL-MIR-NEXT: %3:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-NEXT: %3:gpr64common = MOVKXi %0, 1234, 48
; ISEL-MIR-NEXT: %6:gpr64common = ADDXri %1, 8, 0
; Check that no implicit defs are added to PACDA instruction.
; ISEL-MIR-NEXT: %8:gpr64 = PACDA %6, %3{{$}}
@@ -185,8 +185,8 @@ define void @store_signed_arg(ptr %dest, ptr %p) {
; ISEL-ASM-LABEL: store_signed_arg:
; ISEL-ASM-NEXT: .cfi_startproc
; ISEL-ASM-NEXT: mov x8, x0
-; ISEL-ASM-NEXT: movk x8, #1234, lsl #48
; ISEL-ASM-NEXT: add x9, x1, #8
+; ISEL-ASM-NEXT: movk x8, #1234, lsl #48
; ISEL-ASM-NEXT: pacda x9, x8
; ISEL-ASM-NEXT: str x9, [x0]
; ISEL-ASM-NEXT: ret
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
index 64ddd9f262233..cfded6aa53b4b 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
@@ -87,7 +87,7 @@ define void @store_signed_const_local(ptr %dest) {
; ISEL-MIR-LABEL: name: store_signed_const_local
; ISEL-MIR: body:
; ISEL-MIR: %0:gpr64common = COPY $x0
-; ISEL-MIR-NEXT: %1:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-NEXT: %1:gpr64common = MOVKXi %0, 1234, 48
; ISEL-MIR-NEXT: %2:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
; ISEL-MIR-NEXT: %4:gpr64noip = COPY %1
; ISEL-MIR-NEXT: MOVaddrPAC @const_table_local + 8, 2, %4, 0, implicit-def $x16, implicit-def $x17
@@ -119,7 +119,7 @@ define void @store_signed_const_got(ptr %dest) {
; ISEL-MIR-ELF-LABEL: name: store_signed_const_got
; ISEL-MIR-ELF: body:
; ISEL-MIR-ELF: %0:gpr64common = COPY $x0
-; ISEL-MIR-ELF-NEXT: %1:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-ELF-NEXT: %1:gpr64common = MOVKXi %0, 1234, 48
; ISEL-MIR-ELF-NEXT: %2:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got, implicit-def dead $x16, implicit-def dead $x17, implicit-def dead $nzcv
; ISEL-MIR-ELF-NEXT: %3:gpr64common = ADDXri killed %2, 8, 0
; ISEL-MIR-ELF-NEXT: %5:gpr64noip = COPY %1
@@ -159,7 +159,7 @@ define void @store_signed_arg(ptr %dest, ptr %p) {
; ISEL-MIR: body:
; ISEL-MIR: %1:gpr64common = COPY $x1
; ISEL-MIR-NEXT: %0:gpr64common = COPY $x0
-; ISEL-MIR-NEXT: %2:gpr64common = PAUTH_BLEND %0, 1234
+; ISEL-MIR-NEXT: %2:gpr64common = MOVKXi %0, 1234, 48
; ISEL-MIR-NEXT: %3:gpr64common = ADDXri %1, 8, 0
; Check that no implicit defs are added to PACDA instruction.
; ISEL-MIR-NEXT: %4:gpr64 = PACDA %3, killed %2{{$}}
@@ -169,8 +169,8 @@ define void @store_signed_arg(ptr %dest, ptr %p) {
; ISEL-ASM-LABEL: store_signed_arg:
; ISEL-ASM-NEXT: .cfi_startproc
; ISEL-ASM-NEXT: mov x8, x0
-; ISEL-ASM-NEXT: movk x8, #1234, lsl #48
; ISEL-ASM-NEXT: add x9, x1, #8
+; ISEL-ASM-NEXT: movk x8, #1234, lsl #48
; ISEL-ASM-NEXT: pacda x9, x8
; ISEL-ASM-NEXT: str x9, [x0]
; ISEL-ASM-NEXT: ret
>From 7af97c844809e6cbc7c17249c6832e9c6a7d7dfa Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Wed, 21 May 2025 22:31:55 +0300
Subject: [PATCH 5/5] Prevent immediate modifier substitution
---
.../Target/AArch64/AArch64ISelLowering.cpp | 108 ++++++++++--------
.../GlobalISel/ptrauth-constant-in-code.ll | 25 ++--
.../AArch64/ptrauth-constant-in-code.ll | 25 ++--
3 files changed, 93 insertions(+), 65 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index e6f81dd4585da..7e73d08e57f81 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3360,62 +3360,80 @@ AArch64TargetLowering::tryRewritingPAC(MachineInstr &MI,
MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
const DebugLoc &DL = MI.getDebugLoc();
- MachineInstr *AddrInstr = nullptr;
- int64_t Offset = 0;
- // Try to find the address-setting instruction, accumulating the offset
- // along the way. If any unknown pattern is found, keep everything as-is.
- MachineOperand *CurOp = &MI.getOperand(1);
- while (CurOp) {
- MachineOperand *Def = MRI.getOneDef(CurOp->getReg());
- if (!Def)
- return BB;
- MachineInstr *DefMI = Def->getParent();
- assert(DefMI != nullptr);
-
- switch (DefMI->getOpcode()) {
- case AArch64::COPY:
- CurOp = &DefMI->getOperand(1);
- break;
- case AArch64::ADDXri:
- if (DefMI->getOperand(3).getImm() != 0) // shifts are not handled
- return BB;
- CurOp = &DefMI->getOperand(1);
- Offset += DefMI->getOperand(2).getImm();
- break;
- case AArch64::MOVaddr:
- case AArch64::LOADgotAUTH:
- AddrInstr = DefMI;
- CurOp = nullptr;
- break;
- default:
- return BB;
+ // Find the unique register definition, skipping copies.
+ auto GetUniqueDef = [&MRI](Register Reg) {
+ for (;;) {
+ MachineInstr *Def = MRI.getUniqueVRegDef(Reg);
+ if (!Def || Def->getOpcode() != AArch64::COPY)
+ return Def;
+
+ Reg = Def->getOperand(1).getReg();
}
- }
+ };
+ // Find the unique register definition, skipping copies and increments.
+ auto GetUniqueDefPlusOffset =
+ [GetUniqueDef](Register Reg, int64_t &Offset) -> MachineInstr * {
+ for (;;) {
+ MachineInstr *Def = GetUniqueDef(Reg);
+ if (!Def || Def->getOpcode() != AArch64::ADDXri)
+ return Def;
+
+ if (Def->getOperand(3).getImm() != 0)
+ return nullptr; // shifted immediates are not handled
+ Reg = Def->getOperand(1).getReg();
+ Offset += Def->getOperand(2).getImm();
+ }
+ };
+
+ // Try to find a known address-setting instruction, accumulating the offset
+ // along the way. If no known pattern is found, keep everything as-is.
+
+ int64_t AddrOffset = 0;
+ MachineInstr *AddrDefInstr =
+ GetUniqueDefPlusOffset(MI.getOperand(1).getReg(), AddrOffset);
+ if (!AddrDefInstr)
+ return BB;
- unsigned NewOpcode = AddrInstr->getOpcode() == AArch64::LOADgotAUTH
- ? AArch64::LOADgotPAC
- : AArch64::MOVaddrPAC;
- MachineOperand &AddrOp = AddrInstr->getOperand(1);
+ unsigned NewOpcode;
+ if (AddrDefInstr->getOpcode() == AArch64::LOADgotAUTH)
+ NewOpcode = AArch64::LOADgotPAC;
+ else if (AddrDefInstr->getOpcode() == AArch64::MOVaddr)
+ NewOpcode = AArch64::MOVaddrPAC;
+ else
+ return BB; // Unknown opcode.
+
+ MachineOperand &AddrOp = AddrDefInstr->getOperand(1);
unsigned TargetFlags = AddrOp.getTargetFlags() & ~AArch64II::MO_PAGE;
- Offset += AddrOp.getOffset();
+ const GlobalValue *GV = AddrOp.getGlobal();
+ AddrOffset += AddrOp.getOffset();
+
+ // Detect discriminator blend computation, if any.
+ Register RegDisc = isPACWithZeroDisc(MI.getOpcode())
+ ? AArch64::XZR
+ : MI.getOperand(2).getReg();
+ unsigned IntDisc = 0;
+ MachineInstr *MaybeBlendDef =
+ RegDisc == AArch64::XZR ? nullptr : GetUniqueDef(RegDisc);
+ if (MaybeBlendDef && MaybeBlendDef->getOpcode() == AArch64::MOVKXi &&
+ MaybeBlendDef->getOperand(3).getImm() == 48) {
+ RegDisc = MaybeBlendDef->getOperand(1).getReg();
+ IntDisc = MaybeBlendDef->getOperand(2).getImm();
+ }
// MOVaddrPAC and LOADgotPAC pseudos are expanded so that they use X16/X17
// internally, thus their restrictions on the register class of $AddrDisc
// operand are stricter than those of real PAC* instructions.
- // If the original instruction accepts a discriminator operand, make sure
- // it is moved out of X16/X17.
- Register DiscReg = AArch64::XZR;
- if (!isPACWithZeroDisc(MI.getOpcode())) {
- DiscReg = MRI.createVirtualRegister(&AArch64::GPR64noipRegClass);
- BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), DiscReg)
- .addReg(MI.getOperand(2).getReg());
+ if (RegDisc != AArch64::XZR) {
+ Register TmpReg = MRI.createVirtualRegister(&AArch64::GPR64noipRegClass);
+ BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), TmpReg).addReg(RegDisc);
+ RegDisc = TmpReg;
}
BuildMI(*BB, MI, DL, TII->get(NewOpcode))
- .addGlobalAddress(AddrOp.getGlobal(), Offset, TargetFlags)
+ .addGlobalAddress(GV, AddrOffset, TargetFlags)
.addImm(getKeyForPACOpcode(MI.getOpcode()))
- .addReg(DiscReg)
- .addImm(0);
+ .addReg(RegDisc)
+ .addImm(IntDisc);
BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), MI.getOperand(0).getReg())
.addReg(AArch64::X16);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
index ca637224014ad..2640ed7400722 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll
@@ -96,14 +96,19 @@ define ptr @foo() {
@const_table_local = dso_local constant [3 x ptr] [ptr null, ptr null, ptr null]
@const_table_got = constant [3 x ptr] [ptr null, ptr null, ptr null]
+; Test that after post-processing in finalize-isel, MOVaddrPAC (or LOADgotPAC,
+; respectively) has both $AddrDisc and $Disc operands set. MOVaddr (or LOADgotAUTH,
+; respectively) and MOVKXi are not used anymore and are dead-code-eliminated
+; by the later passes.
+
define void @store_signed_const_local(ptr %dest) {
; ISEL-MIR-LABEL: name: store_signed_const_local
; ISEL-MIR: body:
; ISEL-MIR: %0:gpr64common = COPY $x0
; ISEL-MIR-NEXT: %10:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
; ISEL-MIR-NEXT: %2:gpr64common = MOVKXi %0, 1234, 48
-; ISEL-MIR-NEXT: %15:gpr64noip = COPY %2
-; ISEL-MIR-NEXT: MOVaddrPAC @const_table_local + 8, 2, %15, 0, implicit-def $x16, implicit-def $x17
+; ISEL-MIR-NEXT: %15:gpr64noip = COPY %0
+; ISEL-MIR-NEXT: MOVaddrPAC @const_table_local + 8, 2, %15, 1234, implicit-def $x16, implicit-def $x17
; ISEL-MIR-NEXT: %4:gpr64 = COPY $x16
; ISEL-MIR-NEXT: %14:gpr64 = COPY %4
; ISEL-MIR-NEXT: STRXui %14, %0, 0 :: (store (p0) into %ir.dest)
@@ -111,14 +116,14 @@ define void @store_signed_const_local(ptr %dest) {
;
; ISEL-ASM-LABEL: store_signed_const_local:
; ISEL-ASM-NEXT: .cfi_startproc
-; ISEL-ASM-NEXT: mov x8, x0
-; ISEL-ASM-NEXT: movk x8, #1234, lsl #48
; ISEL-ASM-ELF-NEXT: adrp x16, const_table_local
; ISEL-ASM-ELF-NEXT: add x16, x16, :lo12:const_table_local
; ISEL-ASM-MACHO-NEXT: adrp x16, _const_table_local at PAGE
; ISEL-ASM-MACHO-NEXT: add x16, x16, _const_table_local at PAGEOFF
; ISEL-ASM-NEXT: add x16, x16, #8
-; ISEL-ASM-NEXT: pacda x16, x8
+; ISEL-ASM-NEXT: mov x17, x0
+; ISEL-ASM-NEXT: movk x17, #1234, lsl #48
+; ISEL-ASM-NEXT: pacda x16, x17
; ISEL-ASM-NEXT: str x16, [x0]
; ISEL-ASM-NEXT: ret
%dest.i = ptrtoint ptr %dest to i64
@@ -136,8 +141,8 @@ define void @store_signed_const_got(ptr %dest) {
; ISEL-MIR-ELF-NEXT: %7:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got
; ISEL-MIR-ELF-NEXT: %6:gpr64common = ADDXri %7, 8, 0
; ISEL-MIR-ELF-NEXT: %2:gpr64common = MOVKXi %0, 1234, 48
-; ISEL-MIR-ELF-NEXT: %12:gpr64noip = COPY %2
-; ISEL-MIR-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %12, 0, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
+; ISEL-MIR-ELF-NEXT: %12:gpr64noip = COPY %0
+; ISEL-MIR-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %12, 1234, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
; ISEL-MIR-ELF-NEXT: %4:gpr64 = COPY $x16
; ISEL-MIR-ELF-NEXT: %10:gpr64 = COPY %4
; ISEL-MIR-ELF-NEXT: STRXui %10, %0, 0 :: (store (p0) into %ir.dest)
@@ -145,8 +150,6 @@ define void @store_signed_const_got(ptr %dest) {
;
; ISEL-ASM-ELF-LABEL: store_signed_const_got:
; ISEL-ASM-ELF-NEXT: .cfi_startproc
-; ISEL-ASM-ELF-NEXT: mov x8, x0
-; ISEL-ASM-ELF-NEXT: movk x8, #1234, lsl #48
; ISEL-ASM-ELF-NEXT: adrp x17, :got_auth:const_table_got
; ISEL-ASM-ELF-NEXT: add x17, x17, :got_auth_lo12:const_table_got
; ISEL-ASM-ELF-NEXT: ldr x16, [x17]
@@ -158,7 +161,9 @@ define void @store_signed_const_got(ptr %dest) {
; ISEL-ASM-ELF-NEXT: brk #0xc472
; ISEL-ASM-ELF-NEXT: .Lauth_success_0:
; ISEL-ASM-ELF-NEXT: add x16, x16, #8
-; ISEL-ASM-ELF-NEXT: pacda x16, x8
+; ISEL-ASM-ELF-NEXT: mov x17, x0
+; ISEL-ASM-ELF-NEXT: movk x17, #1234, lsl #48
+; ISEL-ASM-ELF-NEXT: pacda x16, x17
; ISEL-ASM-ELF-NEXT: str x16, [x0]
; ISEL-ASM-ELF-NEXT: ret
%dest.i = ptrtoint ptr %dest to i64
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
index cfded6aa53b4b..4c61de8ee6d86 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll
@@ -83,28 +83,33 @@ define ptr @foo() {
@const_table_local = dso_local constant [3 x ptr] [ptr null, ptr null, ptr null]
@const_table_got = constant [3 x ptr] [ptr null, ptr null, ptr null]
+; Test that after post-processing in finalize-isel, MOVaddrPAC (or LOADgotPAC,
+; respectively) has both $AddrDisc and $Disc operands set. MOVaddr (or LOADgotAUTH,
+; respectively) and MOVKXi are not used anymore and are dead-code-eliminated
+; by the later passes.
+
define void @store_signed_const_local(ptr %dest) {
; ISEL-MIR-LABEL: name: store_signed_const_local
; ISEL-MIR: body:
; ISEL-MIR: %0:gpr64common = COPY $x0
; ISEL-MIR-NEXT: %1:gpr64common = MOVKXi %0, 1234, 48
; ISEL-MIR-NEXT: %2:gpr64common = MOVaddr target-flags(aarch64-page) @const_table_local + 8, target-flags(aarch64-pageoff, aarch64-nc) @const_table_local + 8
-; ISEL-MIR-NEXT: %4:gpr64noip = COPY %1
-; ISEL-MIR-NEXT: MOVaddrPAC @const_table_local + 8, 2, %4, 0, implicit-def $x16, implicit-def $x17
+; ISEL-MIR-NEXT: %4:gpr64noip = COPY %0
+; ISEL-MIR-NEXT: MOVaddrPAC @const_table_local + 8, 2, %4, 1234, implicit-def $x16, implicit-def $x17
; ISEL-MIR-NEXT: %3:gpr64 = COPY $x16
; ISEL-MIR-NEXT: STRXui killed %3, %0, 0 :: (store (s64) into %ir.dest)
; ISEL-MIR-NEXT: RET_ReallyLR
;
; ISEL-ASM-LABEL: store_signed_const_local:
; ISEL-ASM-NEXT: .cfi_startproc
-; ISEL-ASM-NEXT: mov x8, x0
-; ISEL-ASM-NEXT: movk x8, #1234, lsl #48
; ISEL-ASM-ELF-NEXT: adrp x16, const_table_local
; ISEL-ASM-ELF-NEXT: add x16, x16, :lo12:const_table_local
; ISEL-ASM-MACHO-NEXT: adrp x16, _const_table_local at PAGE
; ISEL-ASM-MACHO-NEXT: add x16, x16, _const_table_local at PAGEOFF
; ISEL-ASM-NEXT: add x16, x16, #8
-; ISEL-ASM-NEXT: pacda x16, x8
+; ISEL-ASM-NEXT: mov x17, x0
+; ISEL-ASM-NEXT: movk x17, #1234, lsl #48
+; ISEL-ASM-NEXT: pacda x16, x17
; ISEL-ASM-NEXT: str x16, [x0]
; ISEL-ASM-NEXT: ret
%dest.i = ptrtoint ptr %dest to i64
@@ -122,16 +127,14 @@ define void @store_signed_const_got(ptr %dest) {
; ISEL-MIR-ELF-NEXT: %1:gpr64common = MOVKXi %0, 1234, 48
; ISEL-MIR-ELF-NEXT: %2:gpr64common = LOADgotAUTH target-flags(aarch64-got) @const_table_got, implicit-def dead $x16, implicit-def dead $x17, implicit-def dead $nzcv
; ISEL-MIR-ELF-NEXT: %3:gpr64common = ADDXri killed %2, 8, 0
-; ISEL-MIR-ELF-NEXT: %5:gpr64noip = COPY %1
-; ISEL-MIR-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %5, 0, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
+; ISEL-MIR-ELF-NEXT: %5:gpr64noip = COPY %0
+; ISEL-MIR-ELF-NEXT: LOADgotPAC target-flags(aarch64-got) @const_table_got + 8, 2, %5, 1234, implicit-def $x16, implicit-def $x17, implicit-def $nzcv
; ISEL-MIR-ELF-NEXT: %4:gpr64 = COPY $x16
; ISEL-MIR-ELF-NEXT: STRXui killed %4, %0, 0 :: (store (s64) into %ir.dest)
; ISEL-MIR-ELF-NEXT: RET_ReallyLR
;
; ISEL-ASM-ELF-LABEL: store_signed_const_got:
; ISEL-ASM-ELF-NEXT: .cfi_startproc
-; ISEL-ASM-ELF-NEXT: mov x8, x0
-; ISEL-ASM-ELF-NEXT: movk x8, #1234, lsl #48
; ISEL-ASM-ELF-NEXT: adrp x17, :got_auth:const_table_got
; ISEL-ASM-ELF-NEXT: add x17, x17, :got_auth_lo12:const_table_got
; ISEL-ASM-ELF-NEXT: ldr x16, [x17]
@@ -143,7 +146,9 @@ define void @store_signed_const_got(ptr %dest) {
; ISEL-ASM-ELF-NEXT: brk #0xc472
; ISEL-ASM-ELF-NEXT: .Lauth_success_0:
; ISEL-ASM-ELF-NEXT: add x16, x16, #8
-; ISEL-ASM-ELF-NEXT: pacda x16, x8
+; ISEL-ASM-ELF-NEXT: mov x17, x0
+; ISEL-ASM-ELF-NEXT: movk x17, #1234, lsl #48
+; ISEL-ASM-ELF-NEXT: pacda x16, x17
; ISEL-ASM-ELF-NEXT: str x16, [x0]
; ISEL-ASM-ELF-NEXT: ret
%dest.i = ptrtoint ptr %dest to i64
More information about the llvm-commits
mailing list