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
