From 0d9179874a30c098ca344e926993d1aa5937fa4e Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Sun, 3 Aug 2025 10:16:46 +0900 Subject: [PATCH 1/2] RuntimeLibcalls: Add entries for stack probe functions Stop hardcoding different variants of __chkstk and query the name through RuntimeLibcalls. --- llvm/include/llvm/IR/RuntimeLibcalls.td | 37 ++++++++++++++++++- .../Target/AArch64/AArch64ISelLowering.cpp | 8 +++- .../AArch64/AArch64PrologueEpilogue.cpp | 7 +++- llvm/lib/Target/AArch64/AArch64Subtarget.h | 6 --- llvm/lib/Target/ARM/ARMFrameLowering.cpp | 12 ++++-- llvm/lib/Target/ARM/ARMISelLowering.cpp | 9 ++++- llvm/lib/Target/X86/X86ISelLowering.cpp | 7 ++-- 7 files changed, 67 insertions(+), 19 deletions(-) diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td index ee80606ed0dbf..48d443acd1a2c 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.td +++ b/llvm/include/llvm/IR/RuntimeLibcalls.td @@ -406,6 +406,7 @@ def STACK_SMASH_HANDLER : RuntimeLibcall; // Safe stack def SAFESTACK_POINTER_ADDRESS : RuntimeLibcall; +def STACK_PROBE : RuntimeLibcall; def SECURITY_CHECK_COOKIE : RuntimeLibcall; // Deoptimization @@ -1084,6 +1085,15 @@ def __stack_smash_handler : RuntimeLibcallImpl; def __riscv_flush_icache : RuntimeLibcallImpl; +def _chkstk : RuntimeLibcallImpl; +def _alloca : RuntimeLibcallImpl; + +def __chkstk : RuntimeLibcallImpl; +def ___chkstk_ms : RuntimeLibcallImpl; + +def __chkstk_ms : RuntimeLibcallImpl; +def __chkstk_arm64ec : RuntimeLibcallImpl; + def __security_check_cookie : RuntimeLibcallImpl; def __security_check_cookie_arm64ec : RuntimeLibcallImpl; @@ -1260,6 +1270,9 @@ defvar SecurityCheckCookieIfWinMSVC = LibcallImpls<(add __security_check_cookie, __security_cookie), isWindowsMSVCOrItaniumEnvironment>; +defvar __chkstk_IfWinMSVC = + LibcallImpls<(add __chkstk), isWindowsMSVCEnvironment>; + defvar LibmHasSinCosF32 = LibcallImpls<(add sincosf), hasSinCos>; defvar LibmHasSinCosF64 = LibcallImpls<(add sincos), hasSinCos>; defvar LibmHasSinCosF80 = LibcallImpls<(add sincosl_f80), hasSinCos>; @@ -1418,6 +1431,7 @@ def AArch64SystemLibrary : SystemRuntimeLibrary< DefaultLibmExp10, DefaultStackProtector, SecurityCheckCookieIfWinMSVC, + __chkstk_IfWinMSVC, SMEABI_LibCalls_PreserveMost_From_X0, SMEABI_LibCalls_PreserveMost_From_X1, SMEABI_LibCalls_PreserveMost_From_X2) @@ -1465,6 +1479,7 @@ def WindowsARM64ECSystemLibrary LibcallImpls<(add __security_check_cookie_arm64ec, __security_cookie), isWindowsMSVCEnvironment>, + __chkstk_arm64ec, ExceptionModelCallsArm64EC)>; //===----------------------------------------------------------------------===// @@ -1882,6 +1897,7 @@ def ARMSystemLibrary WindowARMDivRemCalls, WindowARMFPIntCasts, SecurityCheckCookieIfWinMSVC, + LibcallImpls<(add __chkstk), isOSWindows>, AEABIDivRemCalls, DarwinSinCosStret, DarwinExp10, LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128, @@ -2552,6 +2568,19 @@ def isX86_32 : RuntimeLibcallPredicate<"TT.getArch() == Triple::x86">; def isX86_64 : RuntimeLibcallPredicate<"TT.getArch() == Triple::x86_64">; def isX86 : RuntimeLibcallPredicate<"TT.isX86()">; +def isCygwinMinGW64 : RuntimeLibcallPredicate< + [{TT.isOSCygMing() && TT.getArch() == Triple::x86_64}]>; +def isCygwinMinGW32 : RuntimeLibcallPredicate< + [{TT.isOSCygMing() && TT.getArch() == Triple::x86}]>; + +def isWin32NotCygMing : RuntimeLibcallPredicate< + [{TT.getArch() == Triple::x86 && + (TT.isOSWindows() || TT.isUEFI()) && !TT.isOSCygMing()}]>; +def isWin64NotCygMing : RuntimeLibcallPredicate< + [{TT.getArch() == Triple::x86_64 && + (TT.isOSWindows() || TT.isUEFI()) && !TT.isOSCygMing()}]>; + + // Some darwins have an optimized __bzero/bzero function. def darwinHas__bzero : RuntimeLibcallPredicate<"TT.isMacOSX() && !TT.isMacOSXVersionLT(10, 6)">; @@ -2581,8 +2610,12 @@ defvar X86CommonLibcalls = // FIXME: MSVCRT doesn't have powi. The f128 case is added as a // hack for one test relying on it. __powitf2_f128, - DefaultStackProtector - ); + DefaultStackProtector, + LibcallImpls<(add ___chkstk_ms), isCygwinMinGW64>, + LibcallImpls<(add __chkstk), isWin64NotCygMing>, + LibcallImpls<(add _alloca), isCygwinMinGW32>, + LibcallImpls<(add _chkstk), isWin32NotCygMing> +); defvar Windows32DivRemMulCalls = LibcallsWithCC<(add WindowsDivRemMulLibcalls), X86_STDCALL, diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 3c6679f3c1fa7..4cb89a18062c5 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -16857,11 +16857,15 @@ AArch64TargetLowering::LowerWindowsDYNAMIC_STACKALLOC(SDValue Op, return DAG.getMergeValues(Ops, DL); } + RTLIB::LibcallImpl ChkStkImpl = getLibcallImpl(RTLIB::STACK_PROBE); + if (ChkStkImpl == RTLIB::Unsupported) + return SDValue(); + Chain = DAG.getCALLSEQ_START(Chain, 0, 0, DL); EVT PtrVT = getPointerTy(DAG.getDataLayout()); - SDValue Callee = DAG.getTargetExternalSymbol(Subtarget->getChkStkName(), - PtrVT, 0); + SDValue Callee = DAG.getTargetExternalSymbol( + getLibcallImplName(ChkStkImpl).data(), PtrVT, 0); const AArch64RegisterInfo *TRI = Subtarget->getRegisterInfo(); const uint32_t *Mask = TRI->getWindowsStackProbePreservedMask(); diff --git a/llvm/lib/Target/AArch64/AArch64PrologueEpilogue.cpp b/llvm/lib/Target/AArch64/AArch64PrologueEpilogue.cpp index 965585f40571b..dcddcb50bd91e 100644 --- a/llvm/lib/Target/AArch64/AArch64PrologueEpilogue.cpp +++ b/llvm/lib/Target/AArch64/AArch64PrologueEpilogue.cpp @@ -1135,7 +1135,12 @@ void AArch64PrologueEmitter::emitWindowsStackProbe( .setMIFlags(MachineInstr::FrameSetup); } - const char *ChkStk = Subtarget.getChkStkName(); + const AArch64TargetLowering *TLI = Subtarget.getTargetLowering(); + RTLIB::LibcallImpl ChkStkLibcall = TLI->getLibcallImpl(RTLIB::STACK_PROBE); + if (ChkStkLibcall == RTLIB::Unsupported) + reportFatalUsageError("no available implementation of __chkstk"); + + const char *ChkStk = TLI->getLibcallImplName(ChkStkLibcall).data(); switch (MF.getTarget().getCodeModel()) { case CodeModel::Tiny: case CodeModel::Small: diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h index ab4004e30f629..8fc35bfeb01f9 100644 --- a/llvm/lib/Target/AArch64/AArch64Subtarget.h +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h @@ -450,12 +450,6 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo { /// add + cnt instructions. bool useScalarIncVL() const; - const char* getChkStkName() const { - if (isWindowsArm64EC()) - return "#__chkstk_arm64ec"; - return "__chkstk"; - } - /// Choose a method of checking LR before performing a tail call. AArch64PAuth::AuthCheckMethod getAuthenticatedLRCheckMethod(const MachineFunction &MF) const; diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index 21a113572ce93..db5674ca721cc 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -1138,6 +1138,12 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, .add(predOps(ARMCC::AL)); } + const ARMTargetLowering *TLI = STI.getTargetLowering(); + RTLIB::LibcallImpl ChkStkLibcall = TLI->getLibcallImpl(RTLIB::STACK_PROBE); + if (ChkStkLibcall == RTLIB::Unsupported) + reportFatalUsageError("no available implementation of __chkstk"); + const char *ChkStk = TLI->getLibcallImplName(ChkStkLibcall).data(); + switch (TM.getCodeModel()) { case CodeModel::Tiny: llvm_unreachable("Tiny code model not available on ARM."); @@ -1146,14 +1152,14 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, case CodeModel::Kernel: BuildMI(MBB, MBBI, dl, TII.get(ARM::tBL)) .add(predOps(ARMCC::AL)) - .addExternalSymbol("__chkstk") + .addExternalSymbol(ChkStk) .addReg(ARM::R4, RegState::Implicit) .setMIFlags(MachineInstr::FrameSetup); break; case CodeModel::Large: BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), ARM::R12) - .addExternalSymbol("__chkstk") - .setMIFlags(MachineInstr::FrameSetup); + .addExternalSymbol(ChkStk) + .setMIFlags(MachineInstr::FrameSetup); BuildMI(MBB, MBBI, dl, TII.get(ARM::tBLXr)) .add(predOps(ARMCC::AL)) diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 92fae71121a81..220cf16589679 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -11727,6 +11727,11 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI, // -mcmodel=large, alleviating the need for the trampoline which may clobber // IP. + RTLIB::LibcallImpl ChkStkLibcall = getLibcallImpl(RTLIB::STACK_PROBE); + if (ChkStkLibcall == RTLIB::Unsupported) + reportFatalUsageError("no available implementation of __chkstk"); + + const char *ChkStk = getLibcallImplName(ChkStkLibcall).data(); switch (TM.getCodeModel()) { case CodeModel::Tiny: llvm_unreachable("Tiny code model not available on ARM."); @@ -11735,7 +11740,7 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI, case CodeModel::Kernel: BuildMI(*MBB, MI, DL, TII.get(ARM::tBL)) .add(predOps(ARMCC::AL)) - .addExternalSymbol("__chkstk") + .addExternalSymbol(ChkStk) .addReg(ARM::R4, RegState::Implicit | RegState::Kill) .addReg(ARM::R4, RegState::Implicit | RegState::Define) .addReg(ARM::R12, @@ -11748,7 +11753,7 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI, Register Reg = MRI.createVirtualRegister(&ARM::rGPRRegClass); BuildMI(*MBB, MI, DL, TII.get(ARM::t2MOVi32imm), Reg) - .addExternalSymbol("__chkstk"); + .addExternalSymbol(ChkStk); BuildMI(*MBB, MI, DL, TII.get(gettBLXrOpcode(*MBB->getParent()))) .add(predOps(ARMCC::AL)) .addReg(Reg, RegState::Kill) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index fa3dce256046f..2f3192cbd06a5 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -62436,9 +62436,10 @@ X86TargetLowering::getStackProbeSymbolName(const MachineFunction &MF) const { // We need a stack probe to conform to the Windows ABI. Choose the right // symbol. - if (Subtarget.is64Bit()) - return Subtarget.isTargetCygMing() ? "___chkstk_ms" : "__chkstk"; - return Subtarget.isTargetCygMing() ? "_alloca" : "_chkstk"; + RTLIB::LibcallImpl StackProbeImpl = getLibcallImpl(RTLIB::STACK_PROBE); + if (StackProbeImpl == RTLIB::Unsupported) + return ""; + return getLibcallImplName(StackProbeImpl); } unsigned From cd2660d0559ad5f34e4fc9413ce0d02665412219 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 11 Nov 2025 14:52:40 -0800 Subject: [PATCH 2/2] Remove __chkstk_ms --- llvm/include/llvm/IR/RuntimeLibcalls.td | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td index 48d443acd1a2c..3931e0869123b 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.td +++ b/llvm/include/llvm/IR/RuntimeLibcalls.td @@ -1090,8 +1090,6 @@ def _alloca : RuntimeLibcallImpl; def __chkstk : RuntimeLibcallImpl; def ___chkstk_ms : RuntimeLibcallImpl; - -def __chkstk_ms : RuntimeLibcallImpl; def __chkstk_arm64ec : RuntimeLibcallImpl; def __security_check_cookie : RuntimeLibcallImpl;