https://github.com/pkova updated 
https://github.com/llvm/llvm-project/pull/186843

>From c05ddfc5dfccb732f0bcf36cca15d9d87878068e Mon Sep 17 00:00:00 2001
From: pkova <[email protected]>
Date: Mon, 16 Mar 2026 18:42:17 +0200
Subject: [PATCH] Delegate __builtin_setjmp FP save to backend on windows CFI
 targets

---
 clang/lib/CodeGen/CGBuiltin.cpp         | 22 ++++++++++++++++------
 llvm/lib/Target/X86/X86ISelLowering.cpp | 21 ++++++++++++++++++++-
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index df03e84ce9f81..0af1c957d86bb 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4927,12 +4927,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
       return RValue::get(Builder.CreateCall(F, Buf.emitRawPointer(*this)));
     }
 
-    // Store the frame pointer to the setjmp buffer.
-    Value *FrameAddr = Builder.CreateCall(
-        CGM.getIntrinsic(Intrinsic::frameaddress, AllocaInt8PtrTy),
-        ConstantInt::get(Int32Ty, 0));
-    Builder.CreateStore(FrameAddr, Buf);
-
     // Store the stack pointer to the setjmp buffer.
     Value *StackAddr = Builder.CreateStackSave();
     assert(Buf.emitRawPointer(*this)->getType() == StackAddr->getType());
@@ -4940,6 +4934,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
     Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Buf, 2);
     Builder.CreateStore(StackAddr, StackSaveSlot);
 
+    if (getTarget().getTriple().getArch() == llvm::Triple::x86_64 &&
+        (getTarget().getTriple().isOSWindows() ||
+         getTarget().getTriple().isUEFI())) {
+      // On WindowsCFI targets, @llvm.frameaddress returns an SEH-adjusted
+      // address rather than the raw register value that __builtin_longjmp
+      // needs. We delegate the store to the llvm backend in these cases.
+      Function *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
+      return RValue::get(Builder.CreateCall(F, Buf.emitRawPointer(*this)));
+    }
+
+    // Store the frame pointer to the setjmp buffer.
+    Value *FrameAddr = Builder.CreateCall(
+        CGM.getIntrinsic(Intrinsic::frameaddress, AllocaInt8PtrTy),
+        ConstantInt::get(Int32Ty, 0));
+    Builder.CreateStore(FrameAddr, Buf);
+
     // Call LLVM's EH setjmp, which is lightweight.
     Function *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
     return RValue::get(Builder.CreateCall(F, Buf.emitRawPointer(*this)));
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp 
b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 1e9d7aecd41a2..b96fddc9c9e4c 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -37557,6 +37557,26 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
     MIB.addMBB(restoreMBB);
   MIB.setMemRefs(MMOs);
 
+  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
+
+  // On WindowsCFI targets, @llvm.frameaddress returns an SEH-adjusted address
+  // rather than the raw register value that __builtin_longjmp needs. The
+  // frontend skips the @llvm.frameaddress store on these targets, so we store
+  // the raw FP register value here.
+  if (MF->getTarget().getMCAsmInfo()->usesWindowsCFI()) {
+    unsigned RegStoreOpc = (PVT == MVT::i64) ? X86::MOV64mr : X86::MOV32mr;
+
+    bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
+    if (HasFP) {
+      // Store FP to jmp_buf[0].
+      MIB = BuildMI(*thisMBB, MI, MIMD, TII->get(RegStoreOpc));
+      for (unsigned i = 0; i < X86::AddrNumOperands; ++i)
+        MIB.add(MI.getOperand(MemOpndSlot + i));
+      MIB.addReg(RegInfo->getFrameRegister(*MF));
+      MIB.setMemRefs(MMOs);
+    }
+  }
+
   if (MF->getFunction().getParent()->getModuleFlag("cf-protection-return")) {
     emitSetJmpShadowStackFix(MI, thisMBB);
   }
@@ -37565,7 +37585,6 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
   MIB = BuildMI(*thisMBB, MI, MIMD, TII->get(X86::EH_SjLj_Setup))
           .addMBB(restoreMBB);
 
-  const X86RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
   MIB.addRegMask(RegInfo->getNoPreservedMask());
   thisMBB->addSuccessor(mainMBB);
   thisMBB->addSuccessor(restoreMBB);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to