[llvm] [LivePhysRegs][AArch64] Remove XZR from live registers (PR #176324)

Benjamin Lerman via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 19 09:23:38 PST 2026


https://github.com/qsr updated https://github.com/llvm/llvm-project/pull/176324

>From 20e25aa03231bcc45672e7e7e5057f20e9723e0a Mon Sep 17 00:00:00 2001
From: Benjamin Lerman <qsr at google.com>
Date: Fri, 16 Jan 2026 09:49:45 +0100
Subject: [PATCH] [AArch64] Remove constant registers from live registers

Constant registers are never live.

This fixes an issue where LXR was considered being clobbered by the
stack probing code.

A test have been added to check that this issue is fixed.
---
 llvm/include/llvm/CodeGen/LivePhysRegs.h     |  3 ++
 llvm/test/CodeGen/AArch64/no-xzr-liveins.mir | 30 ++++++++++++++++++++
 2 files changed, 33 insertions(+)
 create mode 100644 llvm/test/CodeGen/AArch64/no-xzr-liveins.mir

diff --git a/llvm/include/llvm/CodeGen/LivePhysRegs.h b/llvm/include/llvm/CodeGen/LivePhysRegs.h
index a76b7f95d9b93..6a9949ddfde1b 100644
--- a/llvm/include/llvm/CodeGen/LivePhysRegs.h
+++ b/llvm/include/llvm/CodeGen/LivePhysRegs.h
@@ -83,6 +83,9 @@ class LivePhysRegs {
   void addReg(MCRegister Reg) {
     assert(TRI && "LivePhysRegs is not initialized.");
     assert(Reg < TRI->getNumRegs() && "Expected a physical register.");
+    // Constant registers are never considered live.
+    if (TRI->isConstantPhysReg(Reg))
+      return;
     for (MCPhysReg SubReg : TRI->subregs_inclusive(Reg))
       LiveRegs.insert(SubReg);
   }
diff --git a/llvm/test/CodeGen/AArch64/no-xzr-liveins.mir b/llvm/test/CodeGen/AArch64/no-xzr-liveins.mir
new file mode 100644
index 0000000000000..ef774b7de23d1
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/no-xzr-liveins.mir
@@ -0,0 +1,30 @@
+# RUN: llc -mtriple=aarch64-unknown-fuchsia -run-pass=prologepilog %s -o - | FileCheck %s
+
+# This test ensures that constant registers like XZR are not considered live
+# even if they are in the liveins list. This prevents the stack probe from
+# incorrectly thinking it needs to preserve XZR if it's used as a temporary
+# register.
+
+--- |
+  define void @func() #0 {
+    ret void
+  }
+  attributes #0 = { "probe-stack"="inline-asm" "stack-probe-size"="4096" }
+...
+---
+name:            func
+tracksRegLiveness: true
+frameInfo:
+  stackSize:       4096
+  maxAlignment:    8
+  localFrameSize:  4096
+stack:
+  - { id: 0, size: 4096, alignment: 8 }
+  - { id: 1, type: variable-sized }
+body:             |
+  bb.0:
+    liveins: $xzr
+    ; CHECK-LABEL: name: func
+    ; CHECK: $xzr = frame-setup LDRXui $sp, 0
+    $x0 = COPY $xzr
+    RET_ReallyLR



More information about the llvm-commits mailing list