Index: lib/Target/SystemZ/SystemZISelLowering.h =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.h +++ lib/Target/SystemZ/SystemZISelLowering.h @@ -452,6 +452,10 @@ SelectionDAG &DAG) const override; SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; + /// If the target has a standard location for the stack protector cookie, + /// returns the address of that location. Otherwise, returns nullptr. + Value *getIRStackGuard(IRBuilder<> &IRB) const override; + private: const SystemZSubtarget &Subtarget; Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp +++ lib/Target/SystemZ/SystemZISelLowering.cpp @@ -4942,6 +4942,16 @@ return SDValue(); } +Value *SystemZTargetLowering::getIRStackGuard(IRBuilder<> &IRB) const { + const unsigned TlsOffset = 0x28; + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + Function *ThreadPointerFunc = + Intrinsic::getDeclaration(M, Intrinsic::thread_pointer); + return IRB.CreatePointerCast( + IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), TlsOffset), + Type::getInt8PtrTy(IRB.getContext())->getPointerTo(0)); +} + //===----------------------------------------------------------------------===// // Custom insertion //===----------------------------------------------------------------------===// Index: test/CodeGen/SystemZ/stack-guard.ll =================================================================== --- /dev/null +++ test/CodeGen/SystemZ/stack-guard.ll @@ -0,0 +1,32 @@ +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +; CHECK-LABEL: @test_stack_guard +; CHECK: ear [[REG1:%r[0-9]*]], %a0 +; CHECK: sllg [[REG2:%r[0-9]*]], [[REG1]], 32 +; CHECK: ear [[REG2]], %a1 +; CHECK: lg [[REG3:%r[0-9]*]], 40([[REG2]]) +; CHECK: stg [[REG3]], {{[0-9]*}}(%r15) +; CHECK: brasl %r14, foo3@PLT +; CHECK: lg [[REG4:%r[0-9]*]], 40([[REG2]]) +; CHECK: cg [[REG4]], {{[0-9]*}}(%r15) + +define i32 @test_stack_guard() #0 { +entry: + %a1 = alloca [256 x i32], align 4 + %0 = bitcast [256 x i32]* %a1 to i8* + call void @llvm.lifetime.start(i64 1024, i8* %0) + %arraydecay = getelementptr inbounds [256 x i32], [256 x i32]* %a1, i64 0, i64 0 + call void @foo3(i32* %arraydecay) + call void @llvm.lifetime.end(i64 1024, i8* %0) + ret i32 0 +} + +; Function Attrs: nounwind +declare void @llvm.lifetime.start(i64, i8* nocapture) + +declare void @foo3(i32*) + +; Function Attrs: nounwind +declare void @llvm.lifetime.end(i64, i8* nocapture) + +attributes #0 = { sspstrong }