diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -633,6 +633,10 @@ return Scale == 1; } + /// If the target has a standard location for the stack protector cookie, + /// returns the address of that location. Otherwise, returns nullptr. + Value *getIRStackGuard(IRBuilderBase &IRB) const override; + private: /// RISCVCCAssignFn - This target-specific function extends the default /// CCValAssign with additional information used to lower RISC-V calling diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -14221,6 +14221,25 @@ return true; } +static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) { + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + Function *ThreadPointerFunc = + Intrinsic::getDeclaration(M, Intrinsic::thread_pointer); + return IRB.CreatePointerCast( + IRB.CreateConstGEP1_32(IRB.getInt8Ty(), + IRB.CreateCall(ThreadPointerFunc), Offset), + IRB.getInt8PtrTy()->getPointerTo(0)); +} + +Value *RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const { + // Fuchsia provides a fixed TLS slot for the stack cookie. + // defines ZX_TLS_STACK_GUARD_OFFSET with this value. + if (Subtarget.isTargetFuchsia()) + return useTpOffset(IRB, -0x10); + + return TargetLowering::getIRStackGuard(IRB); +} + #define GET_REGISTER_MATCHER #include "RISCVGenAsmMatcher.inc" diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -163,6 +163,9 @@ std::unique_ptr Legalizer; std::unique_ptr RegBankInfo; + /// TargetTriple - What processor and OS we're targeting. + Triple TargetTriple; + // Return the known range for the bit length of RVV data registers as set // at the command line. A value of 0 means nothing is known about that particular // limit beyond what's implied by the architecture. @@ -175,6 +178,9 @@ InstructionSelector *getInstructionSelector() const override; const LegalizerInfo *getLegalizerInfo() const override; const RegisterBankInfo *getRegBankInfo() const override; + const Triple &getTargetTriple() const { return TargetTriple; } + + bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); } bool useConstantPoolForLargeInts() const; diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp --- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp @@ -82,7 +82,8 @@ RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax), FrameLowering( initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)), - InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) { + InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this), + TargetTriple(TT) { CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering())); Legalizer.reset(new RISCVLegalizerInfo(*this)); diff --git a/llvm/test/CodeGen/RISCV/stack-protector-target.ll b/llvm/test/CodeGen/RISCV/stack-protector-target.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/stack-protector-target.ll @@ -0,0 +1,18 @@ +; Test target-specific stack cookie location. +; +; RUN: llc -mtriple=riscv64-fuchsia < %s -o - | FileCheck --check-prefixes=FUCHSIA-RISCV64 %s + +define void @_Z1fv() sspreq { +entry: + %x = alloca i32, align 4 + call void @_Z7CapturePi(ptr nonnull %x) + ret void +} + +declare void @_Z7CapturePi(ptr) + +; FUCHSIA-RISCV64: ld [[A:.*]], -16(tp) +; FUCHSIA-RISCV64: sd [[A]], [[B:[-0-9]+]](sp) +; FUCHSIA-RISCV64: ld [[C:.*]], -16(tp) +; FUCHSIA-RISCV64: ld [[D:.*]], [[B]](sp) +; FUCHSIA-RISCV64: bne [[C]], [[D]],