//===- StackProtector.cpp - Stack Protector Insertion ---------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This pass inserts stack protectors into functions which need them. A variable
// with a random value in it is stored onto the stack before the local variables
// are allocated. Upon exiting the block, the stored value is checked. If it's
// changed, then there was some sort of violation and the program aborts.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/StackProtector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/EHPersonalities.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <optional>
#include <utility>

using namespace llvm;

#define DEBUG_TYPE "stack-protector"

STATISTIC(NumFunProtected, "Number of functions protected");
STATISTIC(NumAddrTaken, "Number of local variables that have their address"
                        " taken.");

static cl::opt<bool> EnableSelectionDAGSP("enable-selectiondag-sp",
                                          cl::init(true), cl::Hidden);
static cl::opt<bool> DisableCheckNoReturn("disable-check-noreturn-call",
                                          cl::init(false), cl::Hidden);

/// InsertStackProtectors - Insert code into the prologue and epilogue of the
/// function.
///
///  - The prologue code loads and stores the stack guard onto the stack.
///  - The epilogue checks the value stored in the prologue against the original
///    value. It calls __stack_chk_fail if they differ.
static bool InsertStackProtectors(const TargetMachine *TM, Function *F,
                                  DomTreeUpdater *DTU, bool &HasPrologue,
                                  bool &HasIRCheck);

/// CreateFailBB - Create a basic block to jump to when the stack protector
/// check fails.
static BasicBlock *CreateFailBB(Function *F, const Triple &Trip);

bool SSPLayoutInfo::shouldEmitSDCheck(const BasicBlock &BB) const {
  return HasPrologue && !HasIRCheck && isa<ReturnInst>(BB.getTerminator());
}

void SSPLayoutInfo::copyToMachineFrameInfo(MachineFrameInfo &MFI) const {
  if (Layout.empty())
    return;

  for (int I = 0, E = MFI.getObjectIndexEnd(); I != E; ++I) {
    if (MFI.isDeadObjectIndex(I))
      continue;

    const AllocaInst *AI = MFI.getObjectAllocation(I);
    if (!AI)
      continue;

    SSPLayoutMap::const_iterator LI = Layout.find(AI);
    if (LI == Layout.end())
      continue;

    MFI.setObjectSSPLayout(I, LI->second);
  }
}

SSPLayoutInfo SSPLayoutAnalysis::run(Function &F,
                                     FunctionAnalysisManager &FAM) {

  SSPLayoutInfo Info;
  Info.RequireStackProtector =
      SSPLayoutAnalysis::requiresStackProtector(&F, &Info.Layout);
  Info.SSPBufferSize = F.getFnAttributeAsParsedInteger(
      "stack-protector-buffer-size", SSPLayoutInfo::DefaultSSPBufferSize);
  return Info;
}

AnalysisKey SSPLayoutAnalysis::Key;

PreservedAnalyses StackProtectorPass::run(Function &F,
                                          FunctionAnalysisManager &FAM) {
  auto &Info = FAM.getResult<SSPLayoutAnalysis>(F);
  auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);

  if (!Info.RequireStackProtector)
    return PreservedAnalyses::all();

  // TODO(etienneb): Functions with funclets are not correctly supported now.
  // Do nothing if this is funclet-based personality.
  if (F.hasPersonalityFn()) {
    EHPersonality Personality = classifyEHPersonality(F.getPersonalityFn());
    if (isFuncletEHPersonality(Personality))
      return PreservedAnalyses::all();
  }

  ++NumFunProtected;
  bool Changed = InsertStackProtectors(TM, &F, DT ? &DTU : nullptr,
                                       Info.HasPrologue, Info.HasIRCheck);
#ifdef EXPENSIVE_CHECKS
  assert((!DT ||
          DTU.getDomTree().verify(DominatorTree::VerificationLevel::Full)) &&
         "Failed to maintain validity of domtree!");
#endif

  if (!Changed)
    return PreservedAnalyses::all();
  PreservedAnalyses PA;
  PA.preserve<SSPLayoutAnalysis>();
  PA.preserve<DominatorTreeAnalysis>();
  return PA;
}

char StackProtector::ID = 0;

StackProtector::StackProtector() : FunctionPass(ID) {
  initializeStackProtectorPass(*PassRegistry::getPassRegistry());
}

INITIALIZE_PASS_BEGIN(StackProtector, DEBUG_TYPE,
                      "Insert stack protectors", false, true)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(StackProtector, DEBUG_TYPE,
                    "Insert stack protectors", false, true)

FunctionPass *llvm::createStackProtectorPass() { return new StackProtector(); }

void StackProtector::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<TargetPassConfig>();
  AU.addPreserved<DominatorTreeWrapperPass>();
}

bool StackProtector::runOnFunction(Function &Fn) {
  F = &Fn;
  M = F->getParent();
  if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
    DTU.emplace(DTWP->getDomTree(), DomTreeUpdater::UpdateStrategy::Lazy);
  TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
  LayoutInfo.HasPrologue = false;
  LayoutInfo.HasIRCheck = false;

  LayoutInfo.SSPBufferSize = Fn.getFnAttributeAsParsedInteger(
      "stack-protector-buffer-size", SSPLayoutInfo::DefaultSSPBufferSize);
  if (!requiresStackProtector(F, &LayoutInfo.Layout))
    return false;

  // TODO(etienneb): Functions with funclets are not correctly supported now.
  // Do nothing if this is funclet-based personality.
  if (Fn.hasPersonalityFn()) {
    EHPersonality Personality = classifyEHPersonality(Fn.getPersonalityFn());
    if (isFuncletEHPersonality(Personality))
      return false;
  }

  ++NumFunProtected;
  bool Changed =
      InsertStackProtectors(TM, F, DTU ? &*DTU : nullptr,
                            LayoutInfo.HasPrologue, LayoutInfo.HasIRCheck);
#ifdef EXPENSIVE_CHECKS
  assert((!DTU ||
          DTU->getDomTree().verify(DominatorTree::VerificationLevel::Full)) &&
         "Failed to maintain validity of domtree!");
#endif
  DTU.reset();
  return Changed;
}

/// \param [out] IsLarge is set to true if a protectable array is found and
/// it is "large" ( >= ssp-buffer-size).  In the case of a structure with
/// multiple arrays, this gets set if any of them is large.
static bool ContainsProtectableArray(Type *Ty, Module *M, unsigned SSPBufferSize,
                                     bool &IsLarge, bool Strong,
                                     bool InStruct) {
  if (!Ty)
    return false;
  if (ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
    if (!AT->getElementType()->isIntegerTy(8)) {
      // If we're on a non-Darwin platform or we're inside of a structure, don't
      // add stack protectors unless the array is a character array.
      // However, in strong mode any array, regardless of type and size,
      // triggers a protector.
      if (!Strong && (InStruct || !M->getTargetTriple().isOSDarwin()))
        return false;
    }

    // If an array has more than SSPBufferSize bytes of allocated space, then we
    // emit stack protectors.
    if (SSPBufferSize <= M->getDataLayout().getTypeAllocSize(AT)) {
      IsLarge = true;
      return true;
    }

    if (Strong)
      // Require a protector for all arrays in strong mode
      return true;
  }

  const StructType *ST = dyn_cast<StructType>(Ty);
  if (!ST)
    return false;

  bool NeedsProtector = false;
  for (Type *ET : ST->elements())
    if (ContainsProtectableArray(ET, M, SSPBufferSize, IsLarge, Strong, true)) {
      // If the element is a protectable array and is large (>= SSPBufferSize)
      // then we are done.  If the protectable array is not large, then
      // keep looking in case a subsequent element is a large array.
      if (IsLarge)
        return true;
      NeedsProtector = true;
    }

  return NeedsProtector;
}

/// Maximum remaining allocation size observed for a phi node, and how often
/// the allocation size has already been decreased. We only allow a limited
/// number of decreases.
struct PhiInfo {
  TypeSize AllocSize;
  unsigned NumDecreased = 0;
  static constexpr unsigned MaxNumDecreased = 3;
  PhiInfo(TypeSize AllocSize) : AllocSize(AllocSize) {}
};
using PhiMap = SmallDenseMap<const PHINode *, PhiInfo, 16>;

/// Check whether a stack allocation has its address taken.
static bool HasAddressTaken(const Instruction *AI, TypeSize AllocSize,
                            Module *M,
                            PhiMap &VisitedPHIs) {
  const DataLayout &DL = M->getDataLayout();
  for (const User *U : AI->users()) {
    const auto *I = cast<Instruction>(U);
    // If this instruction accesses memory make sure it doesn't access beyond
    // the bounds of the allocated object.
    std::optional<MemoryLocation> MemLoc = MemoryLocation::getOrNone(I);
    if (MemLoc && MemLoc->Size.hasValue() &&
        !TypeSize::isKnownGE(AllocSize, MemLoc->Size.getValue()))
      return true;
    switch (I->getOpcode()) {
    case Instruction::Store:
      if (AI == cast<StoreInst>(I)->getValueOperand())
        return true;
      break;
    case Instruction::AtomicCmpXchg:
      // cmpxchg conceptually includes both a load and store from the same
      // location. So, like store, the value being stored is what matters.
      if (AI == cast<AtomicCmpXchgInst>(I)->getNewValOperand())
        return true;
      break;
    case Instruction::AtomicRMW:
      if (AI == cast<AtomicRMWInst>(I)->getValOperand())
        return true;
      break;
    case Instruction::PtrToInt:
      if (AI == cast<PtrToIntInst>(I)->getOperand(0))
        return true;
      break;
    case Instruction::Call: {
      // Ignore intrinsics that do not become real instructions.
      // TODO: Narrow this to intrinsics that have store-like effects.
      const auto *CI = cast<CallInst>(I);
      if (!CI->isDebugOrPseudoInst() && !CI->isLifetimeStartOrEnd())
        return true;
      break;
    }
    case Instruction::Invoke:
      return true;
    case Instruction::GetElementPtr: {
      // If the GEP offset is out-of-bounds, or is non-constant and so has to be
      // assumed to be potentially out-of-bounds, then any memory access that
      // would use it could also be out-of-bounds meaning stack protection is
      // required.
      const GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
      unsigned IndexSize = DL.getIndexTypeSizeInBits(I->getType());
      APInt Offset(IndexSize, 0);
      if (!GEP->accumulateConstantOffset(DL, Offset))
        return true;
      TypeSize OffsetSize = TypeSize::getFixed(Offset.getLimitedValue());
      if (!TypeSize::isKnownGT(AllocSize, OffsetSize))
        return true;
      // Adjust AllocSize to be the space remaining after this offset.
      // We can't subtract a fixed size from a scalable one, so in that case
      // assume the scalable value is of minimum size.
      TypeSize NewAllocSize =
          TypeSize::getFixed(AllocSize.getKnownMinValue()) - OffsetSize;
      if (HasAddressTaken(I, NewAllocSize, M, VisitedPHIs))
        return true;
      break;
    }
    case Instruction::BitCast:
    case Instruction::Select:
    case Instruction::AddrSpaceCast:
      if (HasAddressTaken(I, AllocSize, M, VisitedPHIs))
        return true;
      break;
    case Instruction::PHI: {
      // Keep track of what PHI nodes we have already visited to ensure
      // they are only visited once.
      const auto *PN = cast<PHINode>(I);
      auto [It, Inserted] = VisitedPHIs.try_emplace(PN, AllocSize);
      if (!Inserted) {
        if (TypeSize::isKnownGE(AllocSize, It->second.AllocSize))
          break;

        // Check again with smaller size.
        if (It->second.NumDecreased == PhiInfo::MaxNumDecreased)
          return true;

        It->second.AllocSize = AllocSize;
        ++It->second.NumDecreased;
      }
      if (HasAddressTaken(PN, AllocSize, M, VisitedPHIs))
        return true;
      break;
    }
    case Instruction::Load:
    case Instruction::Ret:
      // These instructions take an address operand, but have load-like or
      // other innocuous behavior that should not trigger a stack protector.
      break;
    default:
      // Conservatively return true for any instruction that takes an address
      // operand, but is not handled above.
      return true;
    }
  }
  return false;
}

/// Search for the first call to the llvm.stackprotector intrinsic and return it
/// if present.
static const CallInst *findStackProtectorIntrinsic(Function &F) {
  for (const BasicBlock &BB : F)
    for (const Instruction &I : BB)
      if (const auto *II = dyn_cast<IntrinsicInst>(&I))
        if (II->getIntrinsicID() == Intrinsic::stackprotector)
          return II;
  return nullptr;
}

/// Check whether or not this function needs a stack protector based
/// upon the stack protector level.
///
/// We use two heuristics: a standard (ssp) and strong (sspstrong).
/// The standard heuristic which will add a guard variable to functions that
/// call alloca with a either a variable size or a size >= SSPBufferSize,
/// functions with character buffers larger than SSPBufferSize, and functions
/// with aggregates containing character buffers larger than SSPBufferSize. The
/// strong heuristic will add a guard variables to functions that call alloca
/// regardless of size, functions with any buffer regardless of type and size,
/// functions with aggregates that contain any buffer regardless of type and
/// size, and functions that contain stack-based variables that have had their
/// address taken.
bool SSPLayoutAnalysis::requiresStackProtector(Function *F,
                                               SSPLayoutMap *Layout) {
  Module *M = F->getParent();
  bool Strong = false;
  bool NeedsProtector = false;

  // The set of PHI nodes visited when determining if a variable's reference has
  // been taken.  This set is maintained to ensure we don't visit the same PHI
  // node multiple times.
  PhiMap VisitedPHIs;

  unsigned SSPBufferSize = F->getFnAttributeAsParsedInteger(
      "stack-protector-buffer-size", SSPLayoutInfo::DefaultSSPBufferSize);

  if (F->hasFnAttribute(Attribute::SafeStack))
    return false;

  // We are constructing the OptimizationRemarkEmitter on the fly rather than
  // using the analysis pass to avoid building DominatorTree and LoopInfo which
  // are not available this late in the IR pipeline.
  OptimizationRemarkEmitter ORE(F);

  if (F->hasFnAttribute(Attribute::StackProtectReq)) {
    if (!Layout)
      return true;
    ORE.emit([&]() {
      return OptimizationRemark(DEBUG_TYPE, "StackProtectorRequested", F)
             << "Stack protection applied to function "
             << ore::NV("Function", F)
             << " due to a function attribute or command-line switch";
    });
    NeedsProtector = true;
    Strong = true; // Use the same heuristic as strong to determine SSPLayout
  } else if (F->hasFnAttribute(Attribute::StackProtectStrong))
    Strong = true;
  else if (!F->hasFnAttribute(Attribute::StackProtect))
    return false;

  for (const BasicBlock &BB : *F) {
    for (const Instruction &I : BB) {
      if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
        if (AI->isArrayAllocation()) {
          auto RemarkBuilder = [&]() {
            return OptimizationRemark(DEBUG_TYPE, "StackProtectorAllocaOrArray",
                                      &I)
                   << "Stack protection applied to function "
                   << ore::NV("Function", F)
                   << " due to a call to alloca or use of a variable length "
                      "array";
          };
          if (const auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {
            if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
              // A call to alloca with size >= SSPBufferSize requires
              // stack protectors.
              if (!Layout)
                return true;
              Layout->insert(
                  std::make_pair(AI, MachineFrameInfo::SSPLK_LargeArray));
              ORE.emit(RemarkBuilder);
              NeedsProtector = true;
            } else if (Strong) {
              // Require protectors for all alloca calls in strong mode.
              if (!Layout)
                return true;
              Layout->insert(
                  std::make_pair(AI, MachineFrameInfo::SSPLK_SmallArray));
              ORE.emit(RemarkBuilder);
              NeedsProtector = true;
            }
          } else {
            // A call to alloca with a variable size requires protectors.
            if (!Layout)
              return true;
            Layout->insert(
                std::make_pair(AI, MachineFrameInfo::SSPLK_LargeArray));
            ORE.emit(RemarkBuilder);
            NeedsProtector = true;
          }
          continue;
        }

        bool IsLarge = false;
        if (ContainsProtectableArray(AI->getAllocatedType(), M, SSPBufferSize,
                                     IsLarge, Strong, false)) {
          if (!Layout)
            return true;
          Layout->insert(std::make_pair(
              AI, IsLarge ? MachineFrameInfo::SSPLK_LargeArray
                          : MachineFrameInfo::SSPLK_SmallArray));
          ORE.emit([&]() {
            return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I)
                   << "Stack protection applied to function "
                   << ore::NV("Function", F)
                   << " due to a stack allocated buffer or struct containing a "
                      "buffer";
          });
          NeedsProtector = true;
          continue;
        }

        if (Strong &&
            HasAddressTaken(
                AI, M->getDataLayout().getTypeAllocSize(AI->getAllocatedType()),
                M, VisitedPHIs)) {
          ++NumAddrTaken;
          if (!Layout)
            return true;
          Layout->insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf));
          ORE.emit([&]() {
            return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken",
                                      &I)
                   << "Stack protection applied to function "
                   << ore::NV("Function", F)
                   << " due to the address of a local variable being taken";
          });
          NeedsProtector = true;
        }
        // Clear any PHIs that we visited, to make sure we examine all uses of
        // any subsequent allocas that we look at.
        VisitedPHIs.clear();
      }
    }
  }

  return NeedsProtector;
}

/// Create a stack guard loading and populate whether SelectionDAG SSP is
/// supported.
static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,
                            IRBuilder<> &B,
                            bool *SupportsSelectionDAGSP = nullptr) {
  Value *Guard = TLI->getIRStackGuard(B);
  StringRef GuardMode = M->getStackProtectorGuard();
  if ((GuardMode == "tls" || GuardMode.empty()) && Guard)
    return B.CreateLoad(B.getPtrTy(), Guard, true, "StackGuard");

  // Use SelectionDAG SSP handling, since there isn't an IR guard.
  //
  // This is more or less weird, since we optionally output whether we
  // should perform a SelectionDAG SP here. The reason is that it's strictly
  // defined as !TLI->getIRStackGuard(B), where getIRStackGuard is also
  // mutating. There is no way to get this bit without mutating the IR, so
  // getting this bit has to happen in this right time.
  //
  // We could have define a new function TLI::supportsSelectionDAGSP(), but that
  // will put more burden on the backends' overriding work, especially when it
  // actually conveys the same information getIRStackGuard() already gives.
  if (SupportsSelectionDAGSP)
    *SupportsSelectionDAGSP = true;
  TLI->insertSSPDeclarations(*M);
  return B.CreateIntrinsic(Intrinsic::stackguard, {}, {});
}

/// Insert code into the entry block that stores the stack guard
/// variable onto the stack:
///
///   entry:
///     StackGuardSlot = alloca i8*
///     StackGuard = <stack guard>
///     call void @llvm.stackprotector(StackGuard, StackGuardSlot)
///
/// Returns true if the platform/triple supports the stackprotectorcreate pseudo
/// node.
static bool CreatePrologue(Function *F, Module *M, Instruction *CheckLoc,
                           const TargetLoweringBase *TLI, AllocaInst *&AI) {
  bool SupportsSelectionDAGSP = false;
  IRBuilder<> B(&F->getEntryBlock().front());
  PointerType *PtrTy = PointerType::getUnqual(CheckLoc->getContext());
  AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot");

  Value *GuardSlot = getStackGuard(TLI, M, B, &SupportsSelectionDAGSP);
  B.CreateIntrinsic(Intrinsic::stackprotector, {}, {GuardSlot, AI});
  return SupportsSelectionDAGSP;
}

bool InsertStackProtectors(const TargetMachine *TM, Function *F,
                           DomTreeUpdater *DTU, bool &HasPrologue,
                           bool &HasIRCheck) {
  auto *M = F->getParent();
  auto *TLI = TM->getSubtargetImpl(*F)->getTargetLowering();

  // If the target wants to XOR the frame pointer into the guard value, it's
  // impossible to emit the check in IR, so the target *must* support stack
  // protection in SDAG.
  bool SupportsSelectionDAGSP =
      TLI->useStackGuardXorFP() ||
      (EnableSelectionDAGSP && !TM->Options.EnableFastISel);
  AllocaInst *AI = nullptr; // Place on stack that stores the stack guard.
  BasicBlock *FailBB = nullptr;

  for (BasicBlock &BB : llvm::make_early_inc_range(*F)) {
    // This is stack protector auto generated check BB, skip it.
    if (&BB == FailBB)
      continue;
    Instruction *CheckLoc = dyn_cast<ReturnInst>(BB.getTerminator());
    if (!CheckLoc && !DisableCheckNoReturn)
      for (auto &Inst : BB)
        if (auto *CB = dyn_cast<CallBase>(&Inst))
          // Do stack check before noreturn calls that aren't nounwind (e.g:
          // __cxa_throw).
          if (CB->doesNotReturn() && !CB->doesNotThrow()) {
            CheckLoc = CB;
            break;
          }

    if (!CheckLoc)
      continue;

    // Generate prologue instrumentation if not already generated.
    if (!HasPrologue) {
      HasPrologue = true;
      SupportsSelectionDAGSP &= CreatePrologue(F, M, CheckLoc, TLI, AI);
    }

    // SelectionDAG based code generation. Nothing else needs to be done here.
    // The epilogue instrumentation is postponed to SelectionDAG.
    if (SupportsSelectionDAGSP)
      break;

    // Find the stack guard slot if the prologue was not created by this pass
    // itself via a previous call to CreatePrologue().
    if (!AI) {
      const CallInst *SPCall = findStackProtectorIntrinsic(*F);
      assert(SPCall && "Call to llvm.stackprotector is missing");
      AI = cast<AllocaInst>(SPCall->getArgOperand(1));
    }

    // Set HasIRCheck to true, so that SelectionDAG will not generate its own
    // version. SelectionDAG called 'shouldEmitSDCheck' to check whether
    // instrumentation has already been generated.
    HasIRCheck = true;

    // If we're instrumenting a block with a tail call, the check has to be
    // inserted before the call rather than between it and the return. The
    // verifier guarantees that a tail call is either directly before the
    // return or with a single correct bitcast of the return value in between so
    // we don't need to worry about many situations here.
    Instruction *Prev = CheckLoc->getPrevNonDebugInstruction();
    if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isTailCall())
      CheckLoc = Prev;
    else if (Prev) {
      Prev = Prev->getPrevNonDebugInstruction();
      if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isTailCall())
        CheckLoc = Prev;
    }

    // Generate epilogue instrumentation. The epilogue intrumentation can be
    // function-based or inlined depending on which mechanism the target is
    // providing.
    if (Function *GuardCheck = TLI->getSSPStackGuardCheck(*M)) {
      // Generate the function-based epilogue instrumentation.
      // The target provides a guard check function, generate a call to it.
      IRBuilder<> B(CheckLoc);
      LoadInst *Guard = B.CreateLoad(B.getPtrTy(), AI, true, "Guard");
      CallInst *Call = B.CreateCall(GuardCheck, {Guard});
      Call->setAttributes(GuardCheck->getAttributes());
      Call->setCallingConv(GuardCheck->getCallingConv());
    } else {
      // Generate the epilogue with inline instrumentation.
      // If we do not support SelectionDAG based calls, generate IR level
      // calls.
      //
      // For each block with a return instruction, convert this:
      //
      //   return:
      //     ...
      //     ret ...
      //
      // into this:
      //
      //   return:
      //     ...
      //     %1 = <stack guard>
      //     %2 = load StackGuardSlot
      //     %3 = icmp ne i1 %1, %2
      //     br i1 %3, label %CallStackCheckFailBlk, label %SP_return
      //
      //   SP_return:
      //     ret ...
      //
      //   CallStackCheckFailBlk:
      //     call void @__stack_chk_fail()
      //     unreachable

      // Create the FailBB. We duplicate the BB every time since the MI tail
      // merge pass will merge together all of the various BB into one including
      // fail BB generated by the stack protector pseudo instruction.
      if (!FailBB)
        FailBB = CreateFailBB(F, TM->getTargetTriple());

      IRBuilder<> B(CheckLoc);
      Value *Guard = getStackGuard(TLI, M, B);
      LoadInst *LI2 = B.CreateLoad(B.getPtrTy(), AI, true);
      auto *Cmp = cast<ICmpInst>(B.CreateICmpNE(Guard, LI2));
      auto SuccessProb =
          BranchProbabilityInfo::getBranchProbStackProtector(true);
      auto FailureProb =
          BranchProbabilityInfo::getBranchProbStackProtector(false);
      MDNode *Weights = MDBuilder(F->getContext())
                            .createBranchWeights(FailureProb.getNumerator(),
                                                 SuccessProb.getNumerator());

      SplitBlockAndInsertIfThen(Cmp, CheckLoc,
                                /*Unreachable=*/false, Weights, DTU,
                                /*LI=*/nullptr, /*ThenBlock=*/FailBB);

      auto *BI = cast<BranchInst>(Cmp->getParent()->getTerminator());
      BasicBlock *NewBB = BI->getSuccessor(1);
      NewBB->setName("SP_return");
      NewBB->moveAfter(&BB);

      Cmp->setPredicate(Cmp->getInversePredicate());
      BI->swapSuccessors();
    }
  }

  // Return if we didn't modify any basic blocks. i.e., there are no return
  // statements in the function.
  return HasPrologue;
}

BasicBlock *CreateFailBB(Function *F, const Triple &Trip) {
  auto *M = F->getParent();
  LLVMContext &Context = F->getContext();
  BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
  IRBuilder<> B(FailBB);
  if (F->getSubprogram())
    B.SetCurrentDebugLocation(
        DILocation::get(Context, 0, 0, F->getSubprogram()));
  FunctionCallee StackChkFail;
  SmallVector<Value *, 1> Args;
  if (Trip.isOSOpenBSD()) {
    StackChkFail = M->getOrInsertFunction("__stack_smash_handler",
                                          Type::getVoidTy(Context),
                                          PointerType::getUnqual(Context));
    Args.push_back(B.CreateGlobalString(F->getName(), "SSH"));
  } else {
    StackChkFail =
        M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context));
  }
  cast<Function>(StackChkFail.getCallee())->addFnAttr(Attribute::NoReturn);
  B.CreateCall(StackChkFail, Args);
  B.CreateUnreachable();
  return FailBB;
}
