Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ CODEGENOPT(InstrumentForProfiling , 1, 0, Benign) ///< Set when -pg is enabled.
CODEGENOPT(CallFEntry , 1, 0, Benign) ///< Set when -mfentry is enabled.
CODEGENOPT(MNopMCount , 1, 0, Benign) ///< Set when -mnop-mcount is enabled.
CODEGENOPT(RecordMCount , 1, 0, Benign) ///< Set when -mrecord-mcount is enabled.
CODEGENOPT(StackProtectorGuardRecord, 1, 0, Benign) ///< Set when -mstack-protector-guard-record is enabled.
CODEGENOPT(PackedStack , 1, 0, Benign) ///< Set when -mpacked-stack is enabled.
CODEGENOPT(LessPreciseFPMAD , 1, 0, Benign) ///< Enable less precise MAD instructions to
///< be generated.
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -5728,6 +5728,13 @@ def mstack_protector_guard_reg_EQ : Joined<["-"], "mstack-protector-guard-reg=">
Visibility<[ClangOption, CC1Option]>,
HelpText<"Use the given reg for addressing the stack-protector guard">,
MarshallingInfoString<CodeGenOpts<"StackProtectorGuardReg">>;
def mstackprotector_guard_record
: Flag<["-"], "mstack-protector-guard-record">,
HelpText<"Generate a __stackprotector_loc section entry for each load of "
"the stackguard address.">,
Visibility<[ClangOption, CC1Option]>,
Group<m_Group>,
MarshallingInfoFlag<CodeGenOpts<"StackProtectorGuardRecord">>;
def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86/SystemZ only)">,
Visibility<[ClangOption, CC1Option]>, Group<m_Group>,
MarshallingInfoFlag<CodeGenOpts<"CallFEntry">>;
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,14 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
}
}

if (CGM.getCodeGenOpts().StackProtectorGuardRecord) {
if (CGM.getCodeGenOpts().StackProtectorGuard != "global")
CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)
<< "-mstack-protector-guard-record"
<< "-mstack-protector-guard=global";
Fn->addFnAttr("mstackprotector-guard-record");
}

if (CGM.getCodeGenOpts().PackedStack) {
if (getContext().getTargetInfo().getTriple().getArch() !=
llvm::Triple::systemz)
Expand Down
9 changes: 7 additions & 2 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3433,11 +3433,12 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC() &&
!EffectiveTriple.isSystemZ())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
EffectiveTriple.isThumb()) &&
EffectiveTriple.isThumb() || EffectiveTriple.isSystemZ()) &&
Value != "tls" && Value != "global") {
D.Diag(diag::err_drv_invalid_value_with_suggestion)
<< A->getOption().getName() << Value << "tls global";
Expand Down Expand Up @@ -3553,6 +3554,10 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
}
A->render(Args, CmdArgs);
}

if (Arg *A = Args.getLastArg(options::OPT_mstackprotector_guard_record)) {
A->render(Args, CmdArgs);
}
}

static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args,
Expand Down
13 changes: 13 additions & 0 deletions clang/test/CodeGen/SystemZ/stack-guard-pseudos.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %clang_cc1 -S -mllvm -stop-after=systemz-isel -stack-protector 1 -triple=s390x-ibm-linux < %s -o - | FileCheck %s

// CHECK: bb.0.entry:
// CHECK: MOVE_STACK_GUARD %stack.0.StackGuardSlot, 0
// CHECK: COMPARE_STACK_GUARD %stack.0.StackGuardSlot, implicit-def $cc

extern char *strcpy (char * D, const char * S);
int main(int argc, char *argv[])
{
char Buffer[8] = {0};
strcpy(Buffer, argv[1]);
return 0;
}
26 changes: 26 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
Expand Down Expand Up @@ -740,6 +741,31 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
case SystemZ::EH_SjLj_Setup:
return;

case SystemZ::LARL:
case SystemZ::LGRL: {
// If "-mstackprotector-guard-record" was supplied on the command line,
// we need special handling for LARL/LGRL.
if (MF->getFunction().hasFnAttribute("mstackprotector-guard-record")) {
// Obtain the name of the stack guard, and determine if that
// is what we are loading here.
const MachineOperand &Op = MI->getOperand(1);
if (Op.isGlobal() && (Op.getGlobal()->getName() == "__stack_chk_guard")) {
// If so, drop into the __stack_protector_loc section and record
// this locaytion.
MCSymbol *Sym = OutContext.createTempSymbol();
OutStreamer->pushSection();
OutStreamer->switchSection(OutContext.getELFSection(
"__stack_protector_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC));
OutStreamer->emitSymbolValue(Sym, getDataLayout().getPointerSize());
OutStreamer->popSection();
OutStreamer->emitLabel(Sym);
}
}
// Otherwise, keep the MI as it is.
Lower.lower(MI, LoweredMI);
break;
}

default:
Lower.lower(MI, LoweredMI);
break;
Expand Down
11 changes: 9 additions & 2 deletions llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
//
//===----------------------------------------------------------------------===//

#include "SystemZTargetMachine.h"
#include "MCTargetDesc/SystemZMCTargetDesc.h"
#include "SystemZISelLowering.h"
#include "SystemZTargetMachine.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
Expand Down Expand Up @@ -369,7 +372,11 @@ class SystemZDAGToDAGISel : public SelectionDAGISel {
if (F.hasFnAttribute("mrecord-mcount"))
report_fatal_error("mrecord-mcount only supported with fentry-call");
}

if (F.getParent()->getStackProtectorGuard() != "global") {
if (F.hasFnAttribute("mstack-protector-guard-record"))
report_fatal_error("mstack-protector-guard-record only supported with "
"mstack-protector-guard=global");
}
Subtarget = &MF.getSubtarget<SystemZSubtarget>();
return SelectionDAGISel::runOnMachineFunction(MF);
}
Expand Down
153 changes: 153 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,29 @@
//===----------------------------------------------------------------------===//

#include "SystemZISelLowering.h"
#include "MCTargetDesc/SystemZMCTargetDesc.h"
#include "SystemZCallingConv.h"
#include "SystemZConstantPoolValue.h"
#include "SystemZMachineFunctionInfo.h"
#include "SystemZRegisterInfo.h"
#include "SystemZTargetMachine.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsS390.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
Expand Down Expand Up @@ -8177,6 +8185,23 @@ SDValue SystemZTargetLowering::combineSTORE(
SN->getMemOperand());
}
}

// combine STORE (LOAD_STACK_GUARD) into MOVE_STACK_GUARD
if (Op1->isMachineOpcode() &&
(Op1->getMachineOpcode() == SystemZ::LOAD_STACK_GUARD)) {
// If so, create a MOVE_STACK_GUARD node to subsume the LOAD_STACK_GUARD,
// Store sequence.
int FI = cast<FrameIndexSDNode>(SN->getOperand(2))->getIndex();
// Dummy Register, FrameIndex, Dummy Displacement
SDValue Ops[] = {DAG.getTargetFrameIndex(FI, MVT::i64),
DAG.getTargetConstant(0, SDLoc(SN), MVT::i64),
SN->getChain()};
MachineSDNode *Move = DAG.getMachineNode(SystemZ::MOVE_STACK_GUARD,
SDLoc(SN), MVT::Other, Ops);

return SDValue(Move, 0);
}

// Combine STORE (BSWAP) into STRVH/STRV/STRVG/VSTBR
if (!SN->isTruncatingStore() &&
Op1.getOpcode() == ISD::BSWAP &&
Expand Down Expand Up @@ -9106,6 +9131,41 @@ SDValue SystemZTargetLowering::combineSELECT_CCMASK(
return SDValue();
}

SDValue SystemZTargetLowering::combineICMP(SDNode *N,
DAGCombinerInfo &DCI) const {
SelectionDAG &DAG = DCI.DAG;
SDLoc DL(N);

// Combine icmp (load fi, LOAD_STACK_GUARD) into COMPARE_STACK_GUARD.

const SDValue &LHS = N->getOperand(0);
const SDValue &RHS = N->getOperand(1);

if (!ISD::isNormalLoad(RHS.getNode()) ||
!(LHS.isMachineOpcode() &&
(LHS->getMachineOpcode() == SystemZ::LOAD_STACK_GUARD)))
return SDValue();

auto const *StackLoad = cast<LoadSDNode>(RHS.getNode());

// The StackLoad will have an outgoing chain that needs to be redirected.
SDValue InChain = StackLoad->getChain();
SDValue OutChain = SDValue(const_cast<LoadSDNode *>(StackLoad), 1);
DAG.ReplaceAllUsesOfValueWith(OutChain, InChain);

int FI = cast<FrameIndexSDNode>(StackLoad->getOperand(1))->getIndex();

// Now, create a COMPARE_STACK_GUARD node to subsume the
// LoadFI, LOAD_STACK_GUARD, Compare sequence.
// Operands are the FrameIndex where the stackguard is stored, and the input
// chain.
SDValue Ops[] = {DAG.getTargetFrameIndex(FI, MVT::i64), InChain};
MachineSDNode *Move =
DAG.getMachineNode(SystemZ::COMPARE_STACK_GUARD, DL, MVT::i32, Ops);

return SDValue(Move, 0);
}

SDValue SystemZTargetLowering::combineGET_CCMASK(
SDNode *N, DAGCombinerInfo &DCI) const {

Expand Down Expand Up @@ -9420,6 +9480,8 @@ SDValue SystemZTargetLowering::PerformDAGCombine(SDNode *N,
case SystemZISD::BR_CCMASK: return combineBR_CCMASK(N, DCI);
case SystemZISD::SELECT_CCMASK: return combineSELECT_CCMASK(N, DCI);
case SystemZISD::GET_CCMASK: return combineGET_CCMASK(N, DCI);
case SystemZISD::ICMP:
return combineICMP(N, DCI);
case ISD::SRL:
case ISD::SRA: return combineShiftToMulAddHigh(N, DCI);
case ISD::MUL: return combineMUL(N, DCI);
Expand Down Expand Up @@ -11088,6 +11150,91 @@ getBackchainAddress(SDValue SP, SelectionDAG &DAG) const {
DAG.getIntPtrConstant(TFL->getBackchainOffset(MF), DL));
}

namespace {
// The custom inserters for MOVE_STACK_GUARD and COMPARE_STACK_GUARD both
// need to load the address of the stack guard. This function enables that.
Register emitLoadStackGuard(MachineInstr &MI, MachineBasicBlock *MBB) {
MachineFunction &MF = *MBB->getParent();
auto *II = MF.getTarget().getMCInstrInfo();
const Register AddrReg =
MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass);

Module *M = MF.getFunction().getParent();
StringRef GuardType = M->getStackProtectorGuard();

if (GuardType.empty() || (GuardType == "tls")) {
// TLS-based stack guard loading will be emitted post RA.
// This is so we can more easily guarantee the ear, sllg, ear, load
// sequence.
BuildMI(*MBB, MI, MI.getDebugLoc(), II->get(TargetOpcode::LOAD_STACK_GUARD),
AddrReg);

} else if (GuardType == "global") {
// Obtain the global value.
const GlobalValue *GV = M->getOrInsertGlobal(
"__stack_chk_guard", PointerType::getUnqual(M->getContext()));
// Emit the move.
if (M->getPICLevel() == PICLevel::NotPIC) {
BuildMI(*MBB, MI, MI.getDebugLoc(), II->get(SystemZ::LARL), AddrReg)
.addGlobalAddress(GV);
} else {
BuildMI(*MBB, MI, MI.getDebugLoc(), II->get(SystemZ::LGRL), AddrReg)
.addGlobalAddress(GV);
}
} else {
llvm_unreachable(
(Twine("Unknown stack protector type \"") + GuardType + "\"")
.str()
.c_str());
}
return AddrReg;
}
} // namespace

// Custom Inserter for MOVE_STACK_GUARD. Loads the address of the stack guard,
// then inserts an MVC.
MachineBasicBlock *
SystemZTargetLowering::emitMoveStackGuard(MachineInstr &MI,
MachineBasicBlock *MBB) const {
MachineOperand &FI = MI.getOperand(0);
auto *II = MBB->getParent()->getTarget().getMCInstrInfo();
Register AddrReg = emitLoadStackGuard(MI, MBB);

assert(FI.isFI() && "Operand 0 of MOVE_STACK_GUARD is not a frame index.");

BuildMI(*MBB, MI, MI.getDebugLoc(), II->get(SystemZ::MVC))
.addFrameIndex(FI.getIndex())
.addImm(0)
.addImm(8)
.addReg(AddrReg)
.addImm(0);
MI.removeFromParent();

return MBB;
}

// Custom Inserter for COMPARE_STACK_GUARD. Loads the address of the stack
// guard, then inserts a CLC.
MachineBasicBlock *
SystemZTargetLowering::emitCompareStackGuard(MachineInstr &MI,
MachineBasicBlock *MBB) const {
MachineOperand &FI = MI.getOperand(0);
auto *II = MBB->getParent()->getTarget().getMCInstrInfo();
Register AddrReg = emitLoadStackGuard(MI, MBB);

assert(FI.isFI() && "Operand 0 of COMPARE_STACK_GUARD is not a frame index.");

BuildMI(*MBB, MI, MI.getDebugLoc(), II->get(SystemZ::CLC))
.addFrameIndex(FI.getIndex())
.addImm(0)
.addImm(8)
.addReg(AddrReg)
.addImm(0);
MI.removeFromParent();

return MBB;
}

MachineBasicBlock *SystemZTargetLowering::EmitInstrWithCustomInserter(
MachineInstr &MI, MachineBasicBlock *MBB) const {
switch (MI.getOpcode()) {
Expand Down Expand Up @@ -11241,6 +11388,12 @@ MachineBasicBlock *SystemZTargetLowering::EmitInstrWithCustomInserter(
case SystemZ::EH_SjLj_LongJmp:
return emitEHSjLjLongJmp(MI, MBB);

case SystemZ::MOVE_STACK_GUARD:
return emitMoveStackGuard(MI, MBB);

case SystemZ::COMPARE_STACK_GUARD:
return emitCompareStackGuard(MI, MBB);

case TargetOpcode::STACKMAP:
case TargetOpcode::PATCHPOINT:
return emitPatchPoint(MI, MBB);
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@ class SystemZTargetLowering : public TargetLowering {
SDValue combineBSWAP(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineSETCC(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineBR_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineICMP(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineSELECT_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineGET_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineShiftToMulAddHigh(SDNode *N, DAGCombinerInfo &DCI) const;
Expand Down Expand Up @@ -851,6 +852,10 @@ class SystemZTargetLowering : public TargetLowering {
unsigned Opcode) const;
MachineBasicBlock *emitProbedAlloca(MachineInstr &MI,
MachineBasicBlock *MBB) const;
MachineBasicBlock *emitMoveStackGuard(MachineInstr &MI,
MachineBasicBlock *MBB) const;
MachineBasicBlock *emitCompareStackGuard(MachineInstr &MI,
MachineBasicBlock *MBB) const;

SDValue getBackchainAddress(SDValue SP, SelectionDAG &DAG) const;

Expand Down
Loading