[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