[llvm] [AArch64][PAC] Reset `killed` operand flags in outlined functions (PR #221041)
Anatoly Trosinenko via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 23 04:52:33 PDT 2026
https://github.com/atrosinenko updated https://github.com/llvm/llvm-project/pull/221041
>From 1947fd78bcf150e6a62a1f66a66daec75505fa9e Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Tue, 1 Sep 2026 21:38:40 +0300
Subject: [PATCH 1/2] [AArch64][PAC] Reset `killed` operand flags in outlined
functions
Presently, MachineOutliner does not take `killed` operand flags into
account when merging instruction sequences. While it sounds perfectly
reasonable not to inhibit merging of the instruction sequences that
only differ in `killed` flags (for N flags there is technically 2^N
valid ways to drop some subset of them), copying these flags from
an arbitrarily chosen representative instruction may result in
incorrect codegen of PAuth-related pseudo instructions on AArch64.
To keep `killed` flags conservatively correct as if `OUTLINED_FUNCTION`s
are virtually re-inserted at every call site, this patch takes the
simplest approach of resetting every `killed` flag inside the
outlined functions.
---
llvm/lib/CodeGen/MachineOutliner.cpp | 1 +
.../machine-outliner-operand-flags.mir | 82 +++++++++++++++++++
2 files changed, 83 insertions(+)
create mode 100644 llvm/test/CodeGen/AArch64/machine-outliner-operand-flags.mir
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index 171705f1d68d55..6bc7f0c432f19a 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -958,6 +958,7 @@ MachineFunction *MachineOutliner::createOutlinedFunction(
MachineInstr &NewMI = TII.duplicate(MBB, MBB.end(), MI);
NewMI.dropMemRefs(MF);
NewMI.setDebugLoc(DL);
+ NewMI.clearKillInfo();
// Also clear debug locations on any bundled instructions.
if (NewMI.isBundledWithSucc()) {
auto BundleEnd = getBundleEnd(NewMI.getIterator());
diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-operand-flags.mir b/llvm/test/CodeGen/AArch64/machine-outliner-operand-flags.mir
new file mode 100644
index 00000000000000..445778b1bd86d4
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/machine-outliner-operand-flags.mir
@@ -0,0 +1,82 @@
+# RUN: llc -mtriple=aarch64 -run-pass=machine-outliner -verify-machineinstrs -o - %s | FileCheck %s
+
+# Make sure "killed" operand flags would be correct if OUTLINED_FUNCTION is
+# virtually re-inserted at its call site. This is important for correct emission
+# of PAuth-related pseudo instructions by AArch64AsmPrinter.
+# Current implementation ensures this property by simply clearing all "killed"
+# flags on the operands of the instructions contained in `OUTLINED_FUNCTION`s.
+
+--- |
+ define void @test_pac_disc(ptr %p) #0 { ret void }
+ define void @test_not_exactly_cloned_flags(i64 %a, i64 %b) #0 { ret void }
+ attributes #0 = { noredzone optsize minsize }
+...
+---
+# Test PAC pseudo that may actually result in incorrect codegen if `killed` flag
+# is passed to AsmPrinter where it should not.
+
+name: test_pac_disc
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: test_pac_disc
+ ; CHECK: $x1 = ORRXrs $xzr, $x0, 0
+ ; CHECK-NEXT: BL @OUTLINED_FUNCTION_0
+ ; CHECK-NEXT: $x1 = ORRXrs $xzr, $x0, 0
+ ; CHECK-NEXT: BL @OUTLINED_FUNCTION_0
+ ; CHECK-NEXT: BL @OUTLINED_FUNCTION_0
+ ; CHECK-NEXT: RET undef $lr
+
+ liveins: $x0
+ $x1 = ORRXrs $xzr, $x0, 0
+ $x2 = LDRXui $x1, 0
+ $x2 = PAC $x2, 2, 12345, killed $x1, implicit-def dead $x16, implicit-def dead $x17
+ STRXui $x2, $x0, 0
+ $x1 = ORRXrs $xzr, $x0, 0
+ $x2 = LDRXui $x1, 0
+ $x2 = PAC $x2, 2, 12345, $x1, implicit-def dead $x16, implicit-def dead $x17
+ STRXui $x2, $x0, 0
+ $x2 = LDRXui $x1, 0
+ $x2 = PAC $x2, 2, 12345, killed $x1, implicit-def dead $x16, implicit-def dead $x17
+ STRXui $x2, $x0, 0
+ RET undef $lr
+...
+---
+# Make sure `killed` flags are intentionally reset: in the original function, there
+# is no such ADDXrs instruction that could have been cloned as-is (without clearing
+# the `killed` flags) to OUTLINED_FUNCTION_1.
+
+name: test_not_exactly_cloned_flags
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: test_not_exactly_cloned_flags
+ ; CHECK: BL @OUTLINED_FUNCTION_1,
+ ; CHECK-NEXT: BL @OUTLINED_FUNCTION_1,
+ ; CHECK-NEXT: BL @OUTLINED_FUNCTION_1,
+ ; CHECK-NEXT: RET undef $lr
+
+ liveins: $x0, $x1
+ $x2 = ORRXrs $xzr, $x0, 0
+ $x3 = ORRXrs $xzr, $x1, 0
+ $x4 = ADDXrs killed $x2, killed $x3, 0
+ $x2 = ORRXrs $xzr, $x0, 0
+ $x3 = ORRXrs $xzr, $x1, 0
+ $x4 = ADDXrs killed $x2, $x3, 0
+ $x2 = ORRXrs $xzr, $x0, 0
+ $x3 = ORRXrs $xzr, $x1, 0
+ $x4 = ADDXrs $x2, killed $x3, 0
+ RET undef $lr
+...
+
+# CHECK-LABEL: name: OUTLINED_FUNCTION_0
+# CHECK: $x2 = LDRXui $x1, 0
+# CHECK-NEXT: $x2 = PAC $x2, 2, 12345, $x1, implicit-def dead $x16, implicit-def dead $x17
+# CHECK-NEXT: STRXui $x2, $x0, 0
+# CHECK-NEXT: RET $lr
+
+# CHECK-LABEL: name: OUTLINED_FUNCTION_1
+# CHECK: $x2 = ORRXrs $xzr, $x0, 0
+# CHECK-NEXT: $x3 = ORRXrs $xzr, $x1, 0
+# CHECK-NEXT: $x4 = ADDXrs $x2, $x3, 0
+# CHECK-NEXT: RET $lr
>From 4cc9bdafe4816ea2c8ead53d7f2e0bdf3331fa2e Mon Sep 17 00:00:00 2001
From: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
Date: Wed, 23 Sep 2026 14:51:01 +0300
Subject: [PATCH 2/2] Update CodeGen/ARM/machine-outliner-stack-fixup-thumb.mir
---
llvm/test/CodeGen/ARM/machine-outliner-stack-fixup-thumb.mir | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/ARM/machine-outliner-stack-fixup-thumb.mir b/llvm/test/CodeGen/ARM/machine-outliner-stack-fixup-thumb.mir
index a31cf7ea035fec..a64791c9425441 100644
--- a/llvm/test/CodeGen/ARM/machine-outliner-stack-fixup-thumb.mir
+++ b/llvm/test/CodeGen/ARM/machine-outliner-stack-fixup-thumb.mir
@@ -207,5 +207,5 @@ body: |
;CHECK-NEXT: tBX_RET 14 /* CC::al */, $noreg
;CHECK: name: OUTLINED_FUNCTION_[[SHARED]]
- ;CHECK: $r0 = tMOVr killed $r1, 14 /* CC::al */, $noreg
+ ;CHECK: $r0 = tMOVr $r1, 14 /* CC::al */, $noreg
;CHECK-NEXT: tTAILJMPdND @foo, 14 /* CC::al */, $noreg, implicit $sp
More information about the llvm-commits
mailing list