Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2034,27 +2034,25 @@ MachineFrameInfo *MFI = ParentBB->getParent()->getFrameInfo(); int FI = MFI->getStackProtectorIndex(); - const Module &M = *ParentBB->getParent()->getFunction()->getParent(); - const Value *IRGuard = TLI.getSDStackGuard(M); - assert(IRGuard && "Currently there must be an IR guard in order to use " - "SelectionDAG SSP"); - SDValue GuardPtr = getValue(IRGuard); - SDValue StackSlotPtr = DAG.getFrameIndex(FI, PtrTy); - - unsigned Align = DL->getPrefTypeAlignment(IRGuard->getType()); - SDValue Guard; SDLoc dl = getCurSDLoc(); + SDValue StackSlotPtr = DAG.getFrameIndex(FI, PtrTy); + const Module &M = *ParentBB->getParent()->getFunction()->getParent(); + unsigned Align = DL->getPrefTypeAlignment(Type::getInt8PtrTy(M.getContext())); // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD. // Otherwise, emit a volatile load to retrieve the stack guard value. SDValue Chain = DAG.getEntryNode(); - if (TLI.useLoadStackGuardNode()) + if (TLI.useLoadStackGuardNode()) { Guard = getLoadStackGuard(DAG, dl, Chain); - else + } else { + const Value *IRGuard = TLI.getSDStackGuard(M); + SDValue GuardPtr = getValue(IRGuard); + Guard = DAG.getLoad(PtrTy, dl, Chain, GuardPtr, MachinePointerInfo(IRGuard, 0), true, false, false, Align); + } SDValue StackSlot = DAG.getLoad( PtrTy, dl, DAG.getEntryNode(), StackSlotPtr, Index: lib/Target/PowerPC/PPCISelLowering.h =================================================================== --- lib/Target/PowerPC/PPCISelLowering.h +++ lib/Target/PowerPC/PPCISelLowering.h @@ -688,6 +688,11 @@ unsigned getExceptionSelectorRegister(const Constant *PersonalityFn) const override; + /// Override to support customized stack guard loading. + bool useLoadStackGuardNode() const override; + void insertSSPDeclarations(Module &M) const override; + Value *getSDStackGuard(const Module &M) const override; + private: struct ReuseLoadInfo { SDValue Ptr; Index: lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCISelLowering.cpp +++ lib/Target/PowerPC/PPCISelLowering.cpp @@ -12013,3 +12013,23 @@ .addReg(NewVR); } } + +bool PPCTargetLowering::useLoadStackGuardNode() const { + if (!Subtarget.isTargetLinux()) { + return TargetLowering::useLoadStackGuardNode(); + } + return true; +} + +void PPCTargetLowering::insertSSPDeclarations(Module &M) const { + if (!Subtarget.isTargetLinux()) { + return TargetLowering::insertSSPDeclarations(M); + } +} + +Value *PPCTargetLowering::getSDStackGuard(const Module &M) const { + if (!Subtarget.isTargetLinux()) { + return TargetLowering::getSDStackGuard(M); + } + return nullptr; +} Index: lib/Target/PowerPC/PPCInstrInfo.h =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.h +++ lib/Target/PowerPC/PPCInstrInfo.h @@ -272,6 +272,8 @@ ArrayRef> getSerializableBitmaskMachineOperandTargetFlags() const override; + + bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override; }; } Index: lib/Target/PowerPC/PPCInstrInfo.cpp =================================================================== --- lib/Target/PowerPC/PPCInstrInfo.cpp +++ lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1857,3 +1857,17 @@ return makeArrayRef(TargetFlags); } +bool PPCInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { + switch (MI->getOpcode()) { + case TargetOpcode::LOAD_STACK_GUARD: { + const int64_t Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008; + const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2; + MI->setDesc(get(PPC::LD)); + MachineInstrBuilder(*MI->getParent()->getParent(), MI) + .addImm(Offset) + .addReg(Reg); + return true; + } + } + return false; +} Index: lib/Target/PowerPC/PPCSubtarget.h =================================================================== --- lib/Target/PowerPC/PPCSubtarget.h +++ lib/Target/PowerPC/PPCSubtarget.h @@ -286,6 +286,7 @@ bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } + bool isTargetLinux() const { return TargetTriple.isOSLinux(); } bool isDarwinABI() const { return isTargetMachO() || isDarwin(); } bool isSVR4ABI() const { return !isDarwinABI(); } Index: test/CodeGen/PowerPC/stack-protector.ll =================================================================== --- test/CodeGen/PowerPC/stack-protector.ll +++ test/CodeGen/PowerPC/stack-protector.ll @@ -1,6 +1,17 @@ -; RUN: llc -march=ppc32 -mtriple=ppc32-unknown-linux < %s | FileCheck %s -; CHECK: __stack_chk_guard -; CHECK: __stack_chk_fail +; RUN: llc -mtriple=powerpc-apple-darwin8 < %s | FileCheck -check-prefix=DARWIN32 %s +; RUN: llc -mtriple=powerpc64-apple-darwin < %s | FileCheck -check-prefix=DARWIN64 %s +; RUN: llc -mtriple=ppc32-unknown-linux < %s | FileCheck -check-prefix=LINUX32 %s +; RUN: llc -mtriple=powerpc64le-unknown-linux < %s | FileCheck -check-prefix=LINUX64 %s + +; DARWIN32: __stack_chk_guard +; DARWIN64: __stack_chk_guard +; LINUX32: ld {{[0-9]+}}, -28680(2) +; LINUX64: ld {{[0-9]+}}, -28688(13) + +; DARWIN32: __stack_chk_fail +; DARWIN64: __stack_chk_fail +; LINUX32: __stack_chk_fail +; LINUX64: __stack_chk_fail @"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]