Re: objtool: undefined stack state in folio_zero_user()

From: Peter Zijlstra

Date: Tue Jun 30 2026 - 16:28:13 EST


On Tue, Jun 30, 2026 at 07:41:57PM +0200, Peter Zijlstra wrote:
> Also, there is always a 'free' register to store RSP, it is called: RSP
> :-)
>
> Now, clearly I don't actually know much of LLVM internals, but this is
> all quite insane.

I had Gemini talk me though trying to do this, and while I got the
modified llvm to build, I could not actually get it to 'work'. It builds
a kernel fine, but it still does the same stupid.

The idea was to explicitly allow rematerialization of RSP 'loads'. But
like said, it isn't actually helping.

FWIW...

---
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 86a5a631ce73..ebec3a7563ca 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -816,6 +816,13 @@ bool X86InstrInfo::isReMaterializableImpl(
case X86::PTILEZEROV:
return true;

+ case X86::MOV64rr: {
+ const MachineOperand &SrcOp = MI.getOperand(1);
+ if (SrcOp.isReg() && SrcOp.getReg() == X86::RSP)
+ return true;
+ break;
+ }
+
case X86::MOV8rm:
case X86::MOV8rm_NOREX:
case X86::MOV16rm:
@@ -964,6 +971,15 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
Register DestReg, unsigned SubIdx,
const MachineInstr &Orig,
LaneBitmask UsedLanes) const {
+ const DebugLoc &DL = Orig.getDebugLoc();
+ if (Orig.getOpcode() == X86::MOV64rr &&
+ Orig.getOperand(1).isReg() &&
+ Orig.getOperand(1).getReg() == X86::RSP) {
+ BuildMI(MBB, I, DL, get(X86::MOV64rr), DestReg)
+ .addReg(X86::RSP);
+ return;
+ }
+
bool ClobbersEFLAGS = Orig.modifiesRegister(X86::EFLAGS, &TRI);
if (ClobbersEFLAGS && MBB.computeRegisterLiveness(&TRI, X86::EFLAGS, I) !=
MachineBasicBlock::LQR_Dead) {
@@ -984,7 +1000,6 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
llvm_unreachable("Unexpected instruction!");
}

- const DebugLoc &DL = Orig.getDebugLoc();
BuildMI(MBB, I, DL, get(X86::MOV32ri))
.add(Orig.getOperand(0))
.addImm(Value);
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index c84e0f441a45..913c28740eef 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/LiveRegMatrix.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -1167,6 +1168,32 @@ bool X86RegisterInfo::getRegAllocationHints(Register VirtReg,
if (!VRM)
return BaseImplRetVal;

+ if (MachineInstr *DefMI = MRI->getVRegDef(VirtReg)) {
+ if (DefMI->getOpcode() == X86::MOV64rr &&
+ DefMI->getOperand(1).isReg() &&
+ DefMI->getOperand(1).getReg() == X86::RSP) {
+ bool IsKMSANTrackingBlock = false;
+ const MachineBasicBlock *MBB = DefMI->getParent();
+
+ for (const MachineInstr &MI : *MBB) {
+ if (MI.isCall() && MI.getOperand(0).isSymbol()) {
+ StringRef SymName(MI.getOperand(0).getSymbolName());
+ if (SymName == "__msan_chain_origin") {
+ IsKMSANTrackingBlock = true;
+ break;
+ }
+ }
+ }
+
+ if (IsKMSANTrackingBlock) {
+ if (llvm::is_contained(Order, X86::RSP)) {
+ Hints.insert(Hints.begin(), X86::RSP);
+ return true;
+ }
+ }
+ }
+ }
+
if (ID != X86::TILERegClassID) {
if (DisableRegAllocNDDHints || !ST.hasNDD() ||
!TRI.isGeneralPurposeRegisterClass(&RC))