Index: llvm/include/llvm/CodeGen/AsmPrinter.h =================================================================== --- llvm/include/llvm/CodeGen/AsmPrinter.h +++ llvm/include/llvm/CodeGen/AsmPrinter.h @@ -210,6 +210,16 @@ /// CFISection type the module needs i.e. either .eh_frame or .debug_frame. CFISection ModuleCFISection = CFISection::None; + /// True if the module contains split-stack functions. This is used to + /// emit .note.GNU-split-stack section as required by the linker for + /// special handling split-stack function calling no-split-stack function. + bool HasSplitStack = false; + + /// True if the module contains no-split-stack functions. This is used to + /// emit .note.GNU-no-split-stack section when it also contains split-stack + /// functions. + bool HasNoSplitStack = false; + protected: explicit AsmPrinter(TargetMachine &TM, std::unique_ptr Streamer); Index: llvm/include/llvm/CodeGen/MachineModuleInfo.h =================================================================== --- llvm/include/llvm/CodeGen/MachineModuleInfo.h +++ llvm/include/llvm/CodeGen/MachineModuleInfo.h @@ -125,16 +125,6 @@ /// comments in lib/Target/X86/X86FrameLowering.cpp for more details. bool UsesMorestackAddr; - /// True if the module contains split-stack functions. This is used to - /// emit .note.GNU-split-stack section as required by the linker for - /// special handling split-stack function calling no-split-stack function. - bool HasSplitStack; - - /// True if the module contains no-split-stack functions. This is used to - /// emit .note.GNU-no-split-stack section when it also contains split-stack - /// functions. - bool HasNosplitStack; - /// Maps IR Functions to their corresponding MachineFunctions. DenseMap> MachineFunctions; /// Next unique number available for a MachineFunction. @@ -206,22 +196,6 @@ UsesMorestackAddr = b; } - bool hasSplitStack() const { - return HasSplitStack; - } - - void setHasSplitStack(bool b) { - HasSplitStack = b; - } - - bool hasNosplitStack() const { - return HasNosplitStack; - } - - void setHasNosplitStack(bool b) { - HasNosplitStack = b; - } - /// Return the symbol to be used for the specified basic block when its /// address is taken. This cannot be its normal LBB label because the block /// may be accessed outside its containing function. Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -262,6 +262,8 @@ bool AsmPrinter::doInitialization(Module &M) { auto *MMIWP = getAnalysisIfAvailable(); MMI = MMIWP ? &MMIWP->getMMI() : nullptr; + HasSplitStack = false; + HasNoSplitStack = false; // Initialize TargetLoweringObjectFile. const_cast(getObjFileLowering()) @@ -1929,10 +1931,10 @@ // Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if // split-stack is used. - if (TM.getTargetTriple().isOSBinFormatELF() && MMI->hasSplitStack()) { + if (TM.getTargetTriple().isOSBinFormatELF() && HasSplitStack) { OutStreamer->SwitchSection( OutContext.getELFSection(".note.GNU-split-stack", ELF::SHT_PROGBITS, 0)); - if (MMI->hasNosplitStack()) + if (HasNoSplitStack) OutStreamer->SwitchSection( OutContext.getELFSection(".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0)); } @@ -1999,6 +2001,23 @@ this->MF = &MF; const Function &F = MF.getFunction(); + // Record that there are split-stack functions, so we will emit a special + // section to tell the linker. + if (MF.shouldSplitStack()) { + HasSplitStack = true; + + // For non-leaf functions we have to allow for the possibility that the call + // is to a non-split function, as in PR37807. This function could also take + // the address of a non-split function. When the linker tries to adjust its + // non-existent prologue, it would fail with an error. Mark the object file + // so that such failures are not errors. See this Go language bug-report + // https://go-review.googlesource.com/c/go/+/148819/ + const MachineFrameInfo &MFI = MF.getFrameInfo(); + if (MFI.getStackSize() == 0 && !MFI.hasTailCall()) + HasNoSplitStack = true; + } else + HasNoSplitStack = true; + // Get the function symbol. if (!MAI->needsFunctionDescriptors()) { CurrentFnSym = getSymbol(&MF.getFunction()); Index: llvm/lib/CodeGen/MachineModuleInfo.cpp =================================================================== --- llvm/lib/CodeGen/MachineModuleInfo.cpp +++ llvm/lib/CodeGen/MachineModuleInfo.cpp @@ -194,7 +194,6 @@ CurCallSite = 0; NextFnNum = 0; UsesMorestackAddr = false; - HasSplitStack = HasNosplitStack = false; AddrLabelSymbols = nullptr; } @@ -221,8 +220,6 @@ ObjFileMMI = MMI.ObjFileMMI; CurCallSite = MMI.CurCallSite; UsesMorestackAddr = MMI.UsesMorestackAddr; - HasSplitStack = MMI.HasSplitStack; - HasNosplitStack = MMI.HasNosplitStack; AddrLabelSymbols = MMI.AddrLabelSymbols; ExternalContext = MMI.ExternalContext; TheModule = MMI.TheModule; Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp =================================================================== --- llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -1144,11 +1144,7 @@ if (MF.shouldSplitStack()) { for (MachineBasicBlock *SaveBlock : SaveBlocks) TFI.adjustForSegmentedStacks(MF, *SaveBlock); - // Record that there are split-stack functions, so we will emit a - // special section to tell the linker. - MF.getMMI().setHasSplitStack(true); - } else - MF.getMMI().setHasNosplitStack(true); + } // Emit additional code that is required to explicitly handle the stack in // HiPE native code (if needed) when loaded in the Erlang/OTP runtime. The Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/BinaryFormat/COFF.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" Index: llvm/lib/Target/ARM/ARMFrameLowering.cpp =================================================================== --- llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -2515,10 +2515,8 @@ // its non-existent prologue, it would fail with an error. Mark the object // file so that such failures are not errors. See this Go language bug-report // https://go-review.googlesource.com/c/go/+/148819/ - if (StackSize == 0 && !MFI.hasTailCall()) { - MF.getMMI().setHasNosplitStack(true); + if (StackSize == 0 && !MFI.hasTailCall()) return; - } // Use R4 and R5 as scratch registers. // We save R4 and R5 before use and restore them before leaving the function. Index: llvm/lib/Target/X86/X86FrameLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86FrameLowering.cpp +++ llvm/lib/Target/X86/X86FrameLowering.cpp @@ -2951,10 +2951,8 @@ // its non-existent prologue, it would fail with an error. Mark the object // file so that such failures are not errors. See this Go language bug-report // https://go-review.googlesource.com/c/go/+/148819/ - if (StackSize == 0 && !MFI.hasTailCall()) { - MF.getMMI().setHasNosplitStack(true); + if (StackSize == 0 && !MFI.hasTailCall()) return; - } MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock(); MachineBasicBlock *checkMBB = MF.CreateMachineBasicBlock();