//===-- NumericalStabilitySanitizer.cpp -----------------------------------===//
//
// 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 file contains the instrumentation pass for the numerical sanitizer.
// Conceptually the pass injects shadow computations using higher precision
// types and inserts consistency checks. For details see the paper
// https://arxiv.org/abs/2102.12782.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Instrumentation/NumericalStabilitySanitizer.h"

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Instrumentation.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

#include <cstdint>

using namespace llvm;

#define DEBUG_TYPE "nsan"

STATISTIC(NumInstrumentedFTLoads,
          "Number of instrumented floating-point loads");

STATISTIC(NumInstrumentedFTCalls,
          "Number of instrumented floating-point calls");
STATISTIC(NumInstrumentedFTRets,
          "Number of instrumented floating-point returns");
STATISTIC(NumInstrumentedFTStores,
          "Number of instrumented floating-point stores");
STATISTIC(NumInstrumentedNonFTStores,
          "Number of instrumented non floating-point stores");
STATISTIC(
    NumInstrumentedNonFTMemcpyStores,
    "Number of instrumented non floating-point stores with memcpy semantics");
STATISTIC(NumInstrumentedFCmp, "Number of instrumented fcmps");

// Using smaller shadow types types can help improve speed. For example, `dlq`
// is 3x slower to 5x faster in opt mode and 2-6x faster in dbg mode compared to
// `dqq`.
static cl::opt<std::string> ClShadowMapping(
    "nsan-shadow-type-mapping", cl::init("dqq"),
    cl::desc("One shadow type id for each of `float`, `double`, `long double`. "
             "`d`,`l`,`q`,`e` mean double, x86_fp80, fp128 (quad) and "
             "ppc_fp128 (extended double) respectively. The default is to "
             "shadow `float` as `double`, and `double` and `x86_fp80` as "
             "`fp128`"),
    cl::Hidden);

static cl::opt<bool>
    ClInstrumentFCmp("nsan-instrument-fcmp", cl::init(true),
                     cl::desc("Instrument floating-point comparisons"),
                     cl::Hidden);

static cl::opt<std::string> ClCheckFunctionsFilter(
    "check-functions-filter",
    cl::desc("Only emit checks for arguments of functions "
             "whose names match the given regular expression"),
    cl::value_desc("regex"));

static cl::opt<bool> ClTruncateFCmpEq(
    "nsan-truncate-fcmp-eq", cl::init(true),
    cl::desc(
        "This flag controls the behaviour of fcmp equality comparisons."
        "For equality comparisons such as `x == 0.0f`, we can perform the "
        "shadow check in the shadow (`x_shadow == 0.0) == (x == 0.0f)`) or app "
        " domain (`(trunc(x_shadow) == 0.0f) == (x == 0.0f)`). This helps "
        "catch the case when `x_shadow` is accurate enough (and therefore "
        "close enough to zero) so that `trunc(x_shadow)` is zero even though "
        "both `x` and `x_shadow` are not"),
    cl::Hidden);

// When there is external, uninstrumented code writing to memory, the shadow
// memory can get out of sync with the application memory. Enabling this flag
// emits consistency checks for loads to catch this situation.
// When everything is instrumented, this is not strictly necessary because any
// load should have a corresponding store, but can help debug cases when the
// framework did a bad job at tracking shadow memory modifications by failing on
// load rather than store.
// TODO: provide a way to resume computations from the FT value when the load
// is inconsistent. This ensures that further computations are not polluted.
static cl::opt<bool> ClCheckLoads("nsan-check-loads",
                                  cl::desc("Check floating-point load"),
                                  cl::Hidden);

static cl::opt<bool> ClCheckStores("nsan-check-stores", cl::init(true),
                                   cl::desc("Check floating-point stores"),
                                   cl::Hidden);

static cl::opt<bool> ClCheckRet("nsan-check-ret", cl::init(true),
                                cl::desc("Check floating-point return values"),
                                cl::Hidden);

// LLVM may store constant floats as bitcasted ints.
// It's not really necessary to shadow such stores,
// if the shadow value is unknown the framework will re-extend it on load
// anyway. Moreover, because of size collisions (e.g. bf16 vs f16) it is
// impossible to determine the floating-point type based on the size.
// However, for debugging purposes it can be useful to model such stores.
static cl::opt<bool> ClPropagateNonFTConstStoresAsFT(
    "nsan-propagate-non-ft-const-stores-as-ft",
    cl::desc(
        "Propagate non floating-point const stores as floating point values."
        "For debugging purposes only"),
    cl::Hidden);

constexpr StringLiteral kNsanModuleCtorName("nsan.module_ctor");
constexpr StringLiteral kNsanInitName("__nsan_init");

// The following values must be kept in sync with the runtime.
constexpr int kShadowScale = 2;
constexpr int kMaxVectorWidth = 8;
constexpr int kMaxNumArgs = 128;
constexpr int kMaxShadowTypeSizeBytes = 16; // fp128

namespace {

// Defines the characteristics (type id, type, and floating-point semantics)
// attached for all possible shadow types.
class ShadowTypeConfig {
public:
  static std::unique_ptr<ShadowTypeConfig> fromNsanTypeId(char TypeId);

  // The LLVM Type corresponding to the shadow type.
  virtual Type *getType(LLVMContext &Context) const = 0;

  // The nsan type id of the shadow type (`d`, `l`, `q`, ...).
  virtual char getNsanTypeId() const = 0;

  virtual ~ShadowTypeConfig() = default;
};

template <char NsanTypeId>
class ShadowTypeConfigImpl : public ShadowTypeConfig {
public:
  char getNsanTypeId() const override { return NsanTypeId; }
  static constexpr const char kNsanTypeId = NsanTypeId;
};

// `double` (`d`) shadow type.
class F64ShadowConfig : public ShadowTypeConfigImpl<'d'> {
  Type *getType(LLVMContext &Context) const override {
    return Type::getDoubleTy(Context);
  }
};

// `x86_fp80` (`l`) shadow type: X86 long double.
class F80ShadowConfig : public ShadowTypeConfigImpl<'l'> {
  Type *getType(LLVMContext &Context) const override {
    return Type::getX86_FP80Ty(Context);
  }
};

// `fp128` (`q`) shadow type.
class F128ShadowConfig : public ShadowTypeConfigImpl<'q'> {
  Type *getType(LLVMContext &Context) const override {
    return Type::getFP128Ty(Context);
  }
};

// `ppc_fp128` (`e`) shadow type: IBM extended double with 106 bits of mantissa.
class PPC128ShadowConfig : public ShadowTypeConfigImpl<'e'> {
  Type *getType(LLVMContext &Context) const override {
    return Type::getPPC_FP128Ty(Context);
  }
};

// Creates a ShadowTypeConfig given its type id.
std::unique_ptr<ShadowTypeConfig>
ShadowTypeConfig::fromNsanTypeId(const char TypeId) {
  switch (TypeId) {
  case F64ShadowConfig::kNsanTypeId:
    return std::make_unique<F64ShadowConfig>();
  case F80ShadowConfig::kNsanTypeId:
    return std::make_unique<F80ShadowConfig>();
  case F128ShadowConfig::kNsanTypeId:
    return std::make_unique<F128ShadowConfig>();
  case PPC128ShadowConfig::kNsanTypeId:
    return std::make_unique<PPC128ShadowConfig>();
  }
  report_fatal_error("nsan: invalid shadow type id '" + Twine(TypeId) + "'");
}

// An enum corresponding to shadow value types. Used as indices in arrays, so
// not an `enum class`.
enum FTValueType { kFloat, kDouble, kLongDouble, kNumValueTypes };

// If `FT` corresponds to a primitive FTValueType, return it.
static std::optional<FTValueType> ftValueTypeFromType(Type *FT) {
  if (FT->isFloatTy())
    return kFloat;
  if (FT->isDoubleTy())
    return kDouble;
  if (FT->isX86_FP80Ty())
    return kLongDouble;
  return {};
}

// Returns the LLVM type for an FTValueType.
static Type *typeFromFTValueType(FTValueType VT, LLVMContext &Context) {
  switch (VT) {
  case kFloat:
    return Type::getFloatTy(Context);
  case kDouble:
    return Type::getDoubleTy(Context);
  case kLongDouble:
    return Type::getX86_FP80Ty(Context);
  case kNumValueTypes:
    return nullptr;
  }
  llvm_unreachable("Unhandled FTValueType enum");
}

// Returns the type name for an FTValueType.
static const char *typeNameFromFTValueType(FTValueType VT) {
  switch (VT) {
  case kFloat:
    return "float";
  case kDouble:
    return "double";
  case kLongDouble:
    return "longdouble";
  case kNumValueTypes:
    return nullptr;
  }
  llvm_unreachable("Unhandled FTValueType enum");
}

// A specific mapping configuration of application type to shadow type for nsan
// (see -nsan-shadow-mapping flag).
class MappingConfig {
public:
  explicit MappingConfig(LLVMContext &C) : Context(C) {
    if (ClShadowMapping.size() != 3)
      report_fatal_error("Invalid nsan mapping: " + Twine(ClShadowMapping));
    unsigned ShadowTypeSizeBits[kNumValueTypes];
    for (int VT = 0; VT < kNumValueTypes; ++VT) {
      auto Config = ShadowTypeConfig::fromNsanTypeId(ClShadowMapping[VT]);
      if (!Config)
        report_fatal_error("Failed to get ShadowTypeConfig for " +
                           Twine(ClShadowMapping[VT]));
      const unsigned AppTypeSize =
          typeFromFTValueType(static_cast<FTValueType>(VT), Context)
              ->getScalarSizeInBits();
      const unsigned ShadowTypeSize =
          Config->getType(Context)->getScalarSizeInBits();
      // Check that the shadow type size is at most kShadowScale times the
      // application type size, so that shadow memory compoutations are valid.
      if (ShadowTypeSize > kShadowScale * AppTypeSize)
        report_fatal_error("Invalid nsan mapping f" + Twine(AppTypeSize) +
                           "->f" + Twine(ShadowTypeSize) +
                           ": The shadow type size should be at most " +
                           Twine(kShadowScale) +
                           " times the application type size");
      ShadowTypeSizeBits[VT] = ShadowTypeSize;
      Configs[VT] = std::move(Config);
    }

    // Check that the mapping is monotonous. This is required because if one
    // does an fpextend of `float->long double` in application code, nsan is
    // going to do an fpextend of `shadow(float) -> shadow(long double)` in
    // shadow code. This will fail in `qql` mode, since nsan would be
    // fpextending `f128->long`, which is invalid.
    // TODO: Relax this.
    if (ShadowTypeSizeBits[kFloat] > ShadowTypeSizeBits[kDouble] ||
        ShadowTypeSizeBits[kDouble] > ShadowTypeSizeBits[kLongDouble])
      report_fatal_error("Invalid nsan mapping: { float->f" +
                         Twine(ShadowTypeSizeBits[kFloat]) + "; double->f" +
                         Twine(ShadowTypeSizeBits[kDouble]) +
                         "; long double->f" +
                         Twine(ShadowTypeSizeBits[kLongDouble]) + " }");
  }

  const ShadowTypeConfig &byValueType(FTValueType VT) const {
    assert(VT < FTValueType::kNumValueTypes && "invalid value type");
    return *Configs[VT];
  }

  // Returns the extended shadow type for a given application type.
  Type *getExtendedFPType(Type *FT) const {
    if (const auto VT = ftValueTypeFromType(FT))
      return Configs[*VT]->getType(Context);
    if (FT->isVectorTy()) {
      auto *VecTy = cast<VectorType>(FT);
      // TODO: add support for scalable vector types.
      if (VecTy->isScalableTy())
        return nullptr;
      Type *ExtendedScalar = getExtendedFPType(VecTy->getElementType());
      return ExtendedScalar
                 ? VectorType::get(ExtendedScalar, VecTy->getElementCount())
                 : nullptr;
    }
    return nullptr;
  }

private:
  LLVMContext &Context;
  std::unique_ptr<ShadowTypeConfig> Configs[FTValueType::kNumValueTypes];
};

// The memory extents of a type specifies how many elements of a given
// FTValueType needs to be stored when storing this type.
struct MemoryExtents {
  FTValueType ValueType;
  uint64_t NumElts;
};

static MemoryExtents getMemoryExtentsOrDie(Type *FT) {
  if (const auto VT = ftValueTypeFromType(FT))
    return {*VT, 1};
  if (auto *VecTy = dyn_cast<VectorType>(FT)) {
    const auto ScalarExtents = getMemoryExtentsOrDie(VecTy->getElementType());
    return {ScalarExtents.ValueType,
            ScalarExtents.NumElts * VecTy->getElementCount().getFixedValue()};
  }
  llvm_unreachable("invalid value type");
}

// The location of a check. Passed as parameters to runtime checking functions.
class CheckLoc {
public:
  // Creates a location that references an application memory location.
  static CheckLoc makeStore(Value *Address) {
    CheckLoc Result(kStore);
    Result.Address = Address;
    return Result;
  }
  static CheckLoc makeLoad(Value *Address) {
    CheckLoc Result(kLoad);
    Result.Address = Address;
    return Result;
  }

  // Creates a location that references an argument, given by id.
  static CheckLoc makeArg(int ArgId) {
    CheckLoc Result(kArg);
    Result.ArgId = ArgId;
    return Result;
  }

  // Creates a location that references the return value of a function.
  static CheckLoc makeRet() { return CheckLoc(kRet); }

  // Creates a location that references a vector insert.
  static CheckLoc makeInsert() { return CheckLoc(kInsert); }

  // Returns the CheckType of location this refers to, as an integer-typed LLVM
  // IR value.
  Value *getType(LLVMContext &C) const {
    return ConstantInt::get(Type::getInt32Ty(C), static_cast<int>(CheckTy));
  }

  // Returns a CheckType-specific value representing details of the location
  // (e.g. application address for loads or stores), as an `IntptrTy`-typed LLVM
  // IR value.
  Value *getValue(Type *IntptrTy, IRBuilder<> &Builder) const {
    switch (CheckTy) {
    case kUnknown:
      llvm_unreachable("unknown type");
    case kRet:
    case kInsert:
      return ConstantInt::get(IntptrTy, 0);
    case kArg:
      return ConstantInt::get(IntptrTy, ArgId);
    case kLoad:
    case kStore:
      return Builder.CreatePtrToInt(Address, IntptrTy);
    }
    llvm_unreachable("Unhandled CheckType enum");
  }

private:
  // Must be kept in sync with the runtime,
  // see compiler-rt/lib/nsan/nsan_stats.h
  enum CheckType {
    kUnknown = 0,
    kRet,
    kArg,
    kLoad,
    kStore,
    kInsert,
  };
  explicit CheckLoc(CheckType CheckTy) : CheckTy(CheckTy) {}

  Value *Address = nullptr;
  const CheckType CheckTy;
  int ArgId = -1;
};

// A map of LLVM IR values to shadow LLVM IR values.
class ValueToShadowMap {
public:
  explicit ValueToShadowMap(const MappingConfig &Config) : Config(Config) {}

  ValueToShadowMap(const ValueToShadowMap &) = delete;
  ValueToShadowMap &operator=(const ValueToShadowMap &) = delete;

  // Sets the shadow value for a value. Asserts that the value does not already
  // have a value.
  void setShadow(Value &V, Value &Shadow) {
    [[maybe_unused]] const bool Inserted = Map.try_emplace(&V, &Shadow).second;
    LLVM_DEBUG({
      if (!Inserted) {
        if (auto *I = dyn_cast<Instruction>(&V))
          errs() << I->getFunction()->getName() << ": ";
        errs() << "duplicate shadow (" << &V << "): ";
        V.dump();
      }
    });
    assert(Inserted && "duplicate shadow");
  }

  // Returns true if the value already has a shadow (including if the value is a
  // constant). If true, calling getShadow() is valid.
  bool hasShadow(Value *V) const { return isa<Constant>(V) || Map.contains(V); }

  // Returns the shadow value for a given value. Asserts that the value has
  // a shadow value. Lazily creates shadows for constant values.
  Value *getShadow(Value *V) const {
    if (Constant *C = dyn_cast<Constant>(V))
      return getShadowConstant(C);
    return Map.find(V)->second;
  }

  bool empty() const { return Map.empty(); }

private:
  // Extends a constant application value to its shadow counterpart.
  APFloat extendConstantFP(APFloat CV, const fltSemantics &To) const {
    bool LosesInfo = false;
    CV.convert(To, APFloatBase::rmTowardZero, &LosesInfo);
    return CV;
  }

  // Returns the shadow constant for the given application constant.
  Constant *getShadowConstant(Constant *C) const {
    if (UndefValue *U = dyn_cast<UndefValue>(C)) {
      return UndefValue::get(Config.getExtendedFPType(U->getType()));
    }
    if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
      // Floating-point constants.
      Type *Ty = Config.getExtendedFPType(CFP->getType());
      return ConstantFP::get(
          Ty, extendConstantFP(CFP->getValueAPF(), Ty->getFltSemantics()));
    }
    // Vector, array, or aggregate constants.
    if (C->getType()->isVectorTy()) {
      SmallVector<Constant *, 8> Elements;
      for (int I = 0, E = cast<VectorType>(C->getType())
                              ->getElementCount()
                              .getFixedValue();
           I < E; ++I)
        Elements.push_back(getShadowConstant(C->getAggregateElement(I)));
      return ConstantVector::get(Elements);
    }
    llvm_unreachable("unimplemented");
  }

  const MappingConfig &Config;
  DenseMap<Value *, Value *> Map;
};

class NsanMemOpFn {
public:
  NsanMemOpFn(Module &M, ArrayRef<StringRef> Sized, StringRef Fallback,
              size_t NumArgs);
  FunctionCallee getFunctionFor(uint64_t MemOpSize) const;
  FunctionCallee getFallback() const;

private:
  SmallVector<FunctionCallee> Funcs;
  size_t NumSizedFuncs;
};

NsanMemOpFn::NsanMemOpFn(Module &M, ArrayRef<StringRef> Sized,
                         StringRef Fallback, size_t NumArgs) {
  LLVMContext &Ctx = M.getContext();
  AttributeList Attr;
  Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
  Type *PtrTy = PointerType::getUnqual(Ctx);
  Type *VoidTy = Type::getVoidTy(Ctx);
  IntegerType *IntptrTy = M.getDataLayout().getIntPtrType(Ctx);
  FunctionType *SizedFnTy = nullptr;

  NumSizedFuncs = Sized.size();

  // First entry is fallback function
  if (NumArgs == 3) {
    Funcs.push_back(
        M.getOrInsertFunction(Fallback, Attr, VoidTy, PtrTy, PtrTy, IntptrTy));
    SizedFnTy = FunctionType::get(VoidTy, {PtrTy, PtrTy}, false);
  } else if (NumArgs == 2) {
    Funcs.push_back(
        M.getOrInsertFunction(Fallback, Attr, VoidTy, PtrTy, IntptrTy));
    SizedFnTy = FunctionType::get(VoidTy, {PtrTy}, false);
  } else {
    llvm_unreachable("Unexpected value of sized functions arguments");
  }

  for (size_t i = 0; i < NumSizedFuncs; ++i)
    Funcs.push_back(M.getOrInsertFunction(Sized[i], SizedFnTy, Attr));
}

FunctionCallee NsanMemOpFn::getFunctionFor(uint64_t MemOpSize) const {
  // Now `getFunctionFor` operates on `Funcs` of size 4 (at least) and the
  // following code assumes that the number of functions in `Func` is sufficient
  assert(NumSizedFuncs >= 3 && "Unexpected number of sized functions");

  size_t Idx =
      MemOpSize == 4 ? 1 : (MemOpSize == 8 ? 2 : (MemOpSize == 16 ? 3 : 0));

  return Funcs[Idx];
}

FunctionCallee NsanMemOpFn::getFallback() const { return Funcs[0]; }

/// Instantiating NumericalStabilitySanitizer inserts the nsan runtime library
/// API function declarations into the module if they don't exist already.
/// Instantiating ensures the __nsan_init function is in the list of global
/// constructors for the module.
class NumericalStabilitySanitizer {
public:
  NumericalStabilitySanitizer(Module &M);
  bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI);

private:
  bool instrumentMemIntrinsic(MemIntrinsic *MI);
  void maybeAddSuffixForNsanInterface(CallBase *CI);
  bool addrPointsToConstantData(Value *Addr);
  void maybeCreateShadowValue(Instruction &Root, const TargetLibraryInfo &TLI,
                              ValueToShadowMap &Map);
  Value *createShadowValueWithOperandsAvailable(Instruction &Inst,
                                                const TargetLibraryInfo &TLI,
                                                const ValueToShadowMap &Map);
  PHINode *maybeCreateShadowPhi(PHINode &Phi, const TargetLibraryInfo &TLI);
  void createShadowArguments(Function &F, const TargetLibraryInfo &TLI,
                             ValueToShadowMap &Map);

  void populateShadowStack(CallBase &CI, const TargetLibraryInfo &TLI,
                           const ValueToShadowMap &Map);

  void propagateShadowValues(Instruction &Inst, const TargetLibraryInfo &TLI,
                             const ValueToShadowMap &Map);
  Value *emitCheck(Value *V, Value *ShadowV, IRBuilder<> &Builder,
                   CheckLoc Loc);
  Value *emitCheckInternal(Value *V, Value *ShadowV, IRBuilder<> &Builder,
                           CheckLoc Loc);
  void emitFCmpCheck(FCmpInst &FCmp, const ValueToShadowMap &Map);

  // Value creation handlers.
  Value *handleLoad(LoadInst &Load, Type *VT, Type *ExtendedVT);
  Value *handleCallBase(CallBase &Call, Type *VT, Type *ExtendedVT,
                        const TargetLibraryInfo &TLI,
                        const ValueToShadowMap &Map, IRBuilder<> &Builder);
  Value *maybeHandleKnownCallBase(CallBase &Call, Type *VT, Type *ExtendedVT,
                                  const TargetLibraryInfo &TLI,
                                  const ValueToShadowMap &Map,
                                  IRBuilder<> &Builder);
  Value *handleTrunc(const FPTruncInst &Trunc, Type *VT, Type *ExtendedVT,
                     const ValueToShadowMap &Map, IRBuilder<> &Builder);
  Value *handleExt(const FPExtInst &Ext, Type *VT, Type *ExtendedVT,
                   const ValueToShadowMap &Map, IRBuilder<> &Builder);

  // Value propagation handlers.
  void propagateFTStore(StoreInst &Store, Type *VT, Type *ExtendedVT,
                        const ValueToShadowMap &Map);
  void propagateNonFTStore(StoreInst &Store, Type *VT,
                           const ValueToShadowMap &Map);

  const DataLayout &DL;
  LLVMContext &Context;
  MappingConfig Config;
  IntegerType *IntptrTy = nullptr;

  // TODO: Use std::array instead?
  FunctionCallee NsanGetShadowPtrForStore[FTValueType::kNumValueTypes] = {};
  FunctionCallee NsanGetShadowPtrForLoad[FTValueType::kNumValueTypes] = {};
  FunctionCallee NsanCheckValue[FTValueType::kNumValueTypes] = {};
  FunctionCallee NsanFCmpFail[FTValueType::kNumValueTypes] = {};

  NsanMemOpFn NsanCopyFns;
  NsanMemOpFn NsanSetUnknownFns;

  FunctionCallee NsanGetRawShadowTypePtr;
  FunctionCallee NsanGetRawShadowPtr;
  GlobalValue *NsanShadowRetTag = nullptr;

  Type *NsanShadowRetType = nullptr;
  GlobalValue *NsanShadowRetPtr = nullptr;

  GlobalValue *NsanShadowArgsTag = nullptr;

  Type *NsanShadowArgsType = nullptr;
  GlobalValue *NsanShadowArgsPtr = nullptr;

  std::optional<Regex> CheckFunctionsFilter;
};
} // end anonymous namespace

PreservedAnalyses
NumericalStabilitySanitizerPass::run(Module &M, ModuleAnalysisManager &MAM) {
  getOrCreateSanitizerCtorAndInitFunctions(
      M, kNsanModuleCtorName, kNsanInitName, /*InitArgTypes=*/{},
      /*InitArgs=*/{},
      // This callback is invoked when the functions are created the first
      // time. Hook them into the global ctors list in that case:
      [&](Function *Ctor, FunctionCallee) { appendToGlobalCtors(M, Ctor, 0); });

  NumericalStabilitySanitizer Nsan(M);
  auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
  for (Function &F : M)
    Nsan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));

  return PreservedAnalyses::none();
}

static GlobalValue *createThreadLocalGV(const char *Name, Module &M, Type *Ty) {
  return M.getOrInsertGlobal(Name, Ty, [&M, Ty, Name] {
    return new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
                              nullptr, Name, nullptr,
                              GlobalVariable::InitialExecTLSModel);
  });
}

NumericalStabilitySanitizer::NumericalStabilitySanitizer(Module &M)
    : DL(M.getDataLayout()), Context(M.getContext()), Config(Context),
      NsanCopyFns(M, {"__nsan_copy_4", "__nsan_copy_8", "__nsan_copy_16"},
                  "__nsan_copy_values", /*NumArgs=*/3),
      NsanSetUnknownFns(M,
                        {"__nsan_set_value_unknown_4",
                         "__nsan_set_value_unknown_8",
                         "__nsan_set_value_unknown_16"},
                        "__nsan_set_value_unknown", /*NumArgs=*/2) {
  IntptrTy = DL.getIntPtrType(Context);
  Type *PtrTy = PointerType::getUnqual(Context);
  Type *Int32Ty = Type::getInt32Ty(Context);
  Type *Int1Ty = Type::getInt1Ty(Context);
  Type *VoidTy = Type::getVoidTy(Context);

  AttributeList Attr;
  Attr = Attr.addFnAttribute(Context, Attribute::NoUnwind);
  // Initialize the runtime values (functions and global variables).
  for (int I = 0; I < kNumValueTypes; ++I) {
    const FTValueType VT = static_cast<FTValueType>(I);
    const char *VTName = typeNameFromFTValueType(VT);
    Type *VTTy = typeFromFTValueType(VT, Context);

    // Load/store.
    const std::string GetterPrefix =
        std::string("__nsan_get_shadow_ptr_for_") + VTName;
    NsanGetShadowPtrForStore[VT] = M.getOrInsertFunction(
        GetterPrefix + "_store", Attr, PtrTy, PtrTy, IntptrTy);
    NsanGetShadowPtrForLoad[VT] = M.getOrInsertFunction(
        GetterPrefix + "_load", Attr, PtrTy, PtrTy, IntptrTy);

    // Check.
    const auto &ShadowConfig = Config.byValueType(VT);
    Type *ShadowTy = ShadowConfig.getType(Context);
    NsanCheckValue[VT] =
        M.getOrInsertFunction(std::string("__nsan_internal_check_") + VTName +
                                  "_" + ShadowConfig.getNsanTypeId(),
                              Attr, Int32Ty, VTTy, ShadowTy, Int32Ty, IntptrTy);
    NsanFCmpFail[VT] = M.getOrInsertFunction(
        std::string("__nsan_fcmp_fail_") + VTName + "_" +
            ShadowConfig.getNsanTypeId(),
        Attr, VoidTy, VTTy, VTTy, ShadowTy, ShadowTy, Int32Ty, Int1Ty, Int1Ty);
  }

  // TODO: Add attributes nofree, nosync, readnone, readonly,
  NsanGetRawShadowTypePtr = M.getOrInsertFunction(
      "__nsan_internal_get_raw_shadow_type_ptr", Attr, PtrTy, PtrTy);
  NsanGetRawShadowPtr = M.getOrInsertFunction(
      "__nsan_internal_get_raw_shadow_ptr", Attr, PtrTy, PtrTy);

  NsanShadowRetTag = createThreadLocalGV("__nsan_shadow_ret_tag", M, IntptrTy);

  NsanShadowRetType = ArrayType::get(Type::getInt8Ty(Context),
                                     kMaxVectorWidth * kMaxShadowTypeSizeBytes);
  NsanShadowRetPtr =
      createThreadLocalGV("__nsan_shadow_ret_ptr", M, NsanShadowRetType);

  NsanShadowArgsTag =
      createThreadLocalGV("__nsan_shadow_args_tag", M, IntptrTy);

  NsanShadowArgsType =
      ArrayType::get(Type::getInt8Ty(Context),
                     kMaxVectorWidth * kMaxNumArgs * kMaxShadowTypeSizeBytes);

  NsanShadowArgsPtr =
      createThreadLocalGV("__nsan_shadow_args_ptr", M, NsanShadowArgsType);

  if (!ClCheckFunctionsFilter.empty()) {
    Regex R = Regex(ClCheckFunctionsFilter);
    std::string RegexError;
    assert(R.isValid(RegexError));
    CheckFunctionsFilter = std::move(R);
  }
}

// Returns true if the given LLVM Value points to constant data (typically, a
// global variable reference).
bool NumericalStabilitySanitizer::addrPointsToConstantData(Value *Addr) {
  // If this is a GEP, just analyze its pointer operand.
  if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Addr))
    Addr = GEP->getPointerOperand();

  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr))
    return GV->isConstant();
  return false;
}

// This instruments the function entry to create shadow arguments.
// Pseudocode:
//   if (this_fn_ptr == __nsan_shadow_args_tag) {
//     s(arg0) = LOAD<sizeof(arg0)>(__nsan_shadow_args);
//     s(arg1) = LOAD<sizeof(arg1)>(__nsan_shadow_args + sizeof(arg0));
//     ...
//     __nsan_shadow_args_tag = 0;
//   } else {
//     s(arg0) = fext(arg0);
//     s(arg1) = fext(arg1);
//     ...
//   }
void NumericalStabilitySanitizer::createShadowArguments(
    Function &F, const TargetLibraryInfo &TLI, ValueToShadowMap &Map) {
  assert(!F.getIntrinsicID() && "found a definition of an intrinsic");

  // Do not bother if there are no FP args.
  if (all_of(F.args(), [this](const Argument &Arg) {
        return Config.getExtendedFPType(Arg.getType()) == nullptr;
      }))
    return;

  IRBuilder<> Builder(&F.getEntryBlock(), F.getEntryBlock().getFirstNonPHIIt());
  // The function has shadow args if the shadow args tag matches the function
  // address.
  Value *HasShadowArgs = Builder.CreateICmpEQ(
      Builder.CreateLoad(IntptrTy, NsanShadowArgsTag, /*isVolatile=*/false),
      Builder.CreatePtrToInt(&F, IntptrTy));

  unsigned ShadowArgsOffsetBytes = 0;
  for (Argument &Arg : F.args()) {
    Type *VT = Arg.getType();
    Type *ExtendedVT = Config.getExtendedFPType(VT);
    if (ExtendedVT == nullptr)
      continue; // Not an FT value.
    Value *L = Builder.CreateAlignedLoad(
        ExtendedVT,
        Builder.CreateConstGEP2_64(NsanShadowArgsType, NsanShadowArgsPtr, 0,
                                   ShadowArgsOffsetBytes),
        Align(1), /*isVolatile=*/false);
    Value *Shadow = Builder.CreateSelect(HasShadowArgs, L,
                                         Builder.CreateFPExt(&Arg, ExtendedVT));
    Map.setShadow(Arg, *Shadow);
    TypeSize SlotSize = DL.getTypeStoreSize(ExtendedVT);
    assert(!SlotSize.isScalable() && "unsupported");
    ShadowArgsOffsetBytes += SlotSize;
  }
  Builder.CreateStore(ConstantInt::get(IntptrTy, 0), NsanShadowArgsTag);
}

// Returns true if the instrumentation should emit code to check arguments
// before a function call.
static bool shouldCheckArgs(CallBase &CI, const TargetLibraryInfo &TLI,
                            const std::optional<Regex> &CheckFunctionsFilter) {

  Function *Fn = CI.getCalledFunction();

  if (CheckFunctionsFilter) {
    // Skip checking args of indirect calls.
    if (Fn == nullptr)
      return false;
    if (CheckFunctionsFilter->match(Fn->getName()))
      return true;
    return false;
  }

  if (Fn == nullptr)
    return true; // Always check args of indirect calls.

  // Never check nsan functions, the user called them for a reason.
  if (Fn->getName().starts_with("__nsan_"))
    return false;

  const auto ID = Fn->getIntrinsicID();
  LibFunc LFunc = LibFunc::NumLibFuncs;
  // Always check args of unknown functions.
  if (ID == Intrinsic::ID() && !TLI.getLibFunc(*Fn, LFunc))
    return true;

  // Do not check args of an `fabs` call that is used for a comparison.
  // This is typically used for `fabs(a-b) < tolerance`, where what matters is
  // the result of the comparison, which is already caught be the fcmp checks.
  if (ID == Intrinsic::fabs || LFunc == LibFunc_fabsf ||
      LFunc == LibFunc_fabs || LFunc == LibFunc_fabsl)
    for (const auto &U : CI.users())
      if (isa<CmpInst>(U))
        return false;

  return true; // Default is check.
}

// Populates the shadow call stack (which contains shadow values for every
// floating-point parameter to the function).
void NumericalStabilitySanitizer::populateShadowStack(
    CallBase &CI, const TargetLibraryInfo &TLI, const ValueToShadowMap &Map) {
  // Do not create a shadow stack for inline asm.
  if (CI.isInlineAsm())
    return;

  // Do not bother if there are no FP args.
  if (all_of(CI.operands(), [this](const Value *Arg) {
        return Config.getExtendedFPType(Arg->getType()) == nullptr;
      }))
    return;

  IRBuilder<> Builder(&CI);
  SmallVector<Value *, 8> ArgShadows;
  const bool ShouldCheckArgs = shouldCheckArgs(CI, TLI, CheckFunctionsFilter);
  for (auto [ArgIdx, Arg] : enumerate(CI.operands())) {
    if (Config.getExtendedFPType(Arg->getType()) == nullptr)
      continue; // Not an FT value.
    Value *ArgShadow = Map.getShadow(Arg);
    ArgShadows.push_back(ShouldCheckArgs ? emitCheck(Arg, ArgShadow, Builder,
                                                     CheckLoc::makeArg(ArgIdx))
                                         : ArgShadow);
  }

  // Do not create shadow stacks for intrinsics/known lib funcs.
  if (Function *Fn = CI.getCalledFunction()) {
    LibFunc LFunc;
    if (Fn->isIntrinsic() || TLI.getLibFunc(*Fn, LFunc))
      return;
  }

  // Set the shadow stack tag.
  Builder.CreateStore(CI.getCalledOperand(), NsanShadowArgsTag);
  TypeSize ShadowArgsOffsetBytes = TypeSize::getFixed(0);

  unsigned ShadowArgId = 0;
  for (const Value *Arg : CI.operands()) {
    Type *VT = Arg->getType();
    Type *ExtendedVT = Config.getExtendedFPType(VT);
    if (ExtendedVT == nullptr)
      continue; // Not an FT value.
    Builder.CreateAlignedStore(
        ArgShadows[ShadowArgId++],
        Builder.CreateConstGEP2_64(NsanShadowArgsType, NsanShadowArgsPtr, 0,
                                   ShadowArgsOffsetBytes),
        Align(1), /*isVolatile=*/false);
    TypeSize SlotSize = DL.getTypeStoreSize(ExtendedVT);
    assert(!SlotSize.isScalable() && "unsupported");
    ShadowArgsOffsetBytes += SlotSize;
  }
}

// Internal part of emitCheck(). Returns a value that indicates whether
// computation should continue with the shadow or resume by re-fextending the
// value.
enum class ContinuationType { // Keep in sync with runtime.
  ContinueWithShadow = 0,
  ResumeFromValue = 1,
};

Value *NumericalStabilitySanitizer::emitCheckInternal(Value *V, Value *ShadowV,
                                                      IRBuilder<> &Builder,
                                                      CheckLoc Loc) {
  // Do not emit checks for constant values, this is redundant.
  if (isa<Constant>(V))
    return ConstantInt::get(
        Builder.getInt32Ty(),
        static_cast<int>(ContinuationType::ContinueWithShadow));

  Type *Ty = V->getType();
  if (const auto VT = ftValueTypeFromType(Ty))
    return Builder.CreateCall(
        NsanCheckValue[*VT],
        {V, ShadowV, Loc.getType(Context), Loc.getValue(IntptrTy, Builder)});

  if (Ty->isVectorTy()) {
    auto *VecTy = cast<VectorType>(Ty);
    // We currently skip scalable vector types in MappingConfig,
    // thus we should not encounter any such types here.
    assert(!VecTy->isScalableTy() &&
           "Scalable vector types are not supported yet");
    Value *CheckResult = nullptr;
    for (int I = 0, E = VecTy->getElementCount().getFixedValue(); I < E; ++I) {
      // We resume if any element resumes. Another option would be to create a
      // vector shuffle with the array of ContinueWithShadow, but that is too
      // complex.
      Value *ExtractV = Builder.CreateExtractElement(V, I);
      Value *ExtractShadowV = Builder.CreateExtractElement(ShadowV, I);
      Value *ComponentCheckResult =
          emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc);
      CheckResult = CheckResult
                        ? Builder.CreateOr(CheckResult, ComponentCheckResult)
                        : ComponentCheckResult;
    }
    return CheckResult;
  }
  if (Ty->isArrayTy()) {
    Value *CheckResult = nullptr;
    for (auto I : seq(Ty->getArrayNumElements())) {
      Value *ExtractV = Builder.CreateExtractElement(V, I);
      Value *ExtractShadowV = Builder.CreateExtractElement(ShadowV, I);
      Value *ComponentCheckResult =
          emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc);
      CheckResult = CheckResult
                        ? Builder.CreateOr(CheckResult, ComponentCheckResult)
                        : ComponentCheckResult;
    }
    return CheckResult;
  }
  if (Ty->isStructTy()) {
    Value *CheckResult = nullptr;
    for (auto I : seq(Ty->getStructNumElements())) {
      if (Config.getExtendedFPType(Ty->getStructElementType(I)) == nullptr)
        continue; // Only check FT values.
      Value *ExtractV = Builder.CreateExtractValue(V, I);
      Value *ExtractShadowV = Builder.CreateExtractElement(ShadowV, I);
      Value *ComponentCheckResult =
          emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc);
      CheckResult = CheckResult
                        ? Builder.CreateOr(CheckResult, ComponentCheckResult)
                        : ComponentCheckResult;
    }
    if (!CheckResult)
      return ConstantInt::get(
          Builder.getInt32Ty(),
          static_cast<int>(ContinuationType::ContinueWithShadow));
    return CheckResult;
  }

  llvm_unreachable("not implemented");
}

// Inserts a runtime check of V against its shadow value ShadowV.
// We check values whenever they escape: on return, call, stores, and
// insertvalue.
// Returns the shadow value that should be used to continue the computations,
// depending on the answer from the runtime.
// TODO: Should we check on select ? phi ?
Value *NumericalStabilitySanitizer::emitCheck(Value *V, Value *ShadowV,
                                              IRBuilder<> &Builder,
                                              CheckLoc Loc) {
  // Do not emit checks for constant values, this is redundant.
  if (isa<Constant>(V))
    return ShadowV;

  if (Instruction *Inst = dyn_cast<Instruction>(V)) {
    Function *F = Inst->getFunction();
    if (CheckFunctionsFilter && !CheckFunctionsFilter->match(F->getName())) {
      return ShadowV;
    }
  }

  Value *CheckResult = emitCheckInternal(V, ShadowV, Builder, Loc);
  Value *ICmpEQ = Builder.CreateICmpEQ(
      CheckResult,
      ConstantInt::get(Builder.getInt32Ty(),
                       static_cast<int>(ContinuationType::ResumeFromValue)));
  return Builder.CreateSelect(
      ICmpEQ, Builder.CreateFPExt(V, Config.getExtendedFPType(V->getType())),
      ShadowV);
}

// Inserts a check that fcmp on shadow values are consistent with that on base
// values.
void NumericalStabilitySanitizer::emitFCmpCheck(FCmpInst &FCmp,
                                                const ValueToShadowMap &Map) {
  if (!ClInstrumentFCmp)
    return;

  Function *F = FCmp.getFunction();
  if (CheckFunctionsFilter && !CheckFunctionsFilter->match(F->getName()))
    return;

  Value *LHS = FCmp.getOperand(0);
  if (Config.getExtendedFPType(LHS->getType()) == nullptr)
    return;
  Value *RHS = FCmp.getOperand(1);

  // Split the basic block. On mismatch, we'll jump to the new basic block with
  // a call to the runtime for error reporting.
  BasicBlock *FCmpBB = FCmp.getParent();
  BasicBlock *NextBB = FCmpBB->splitBasicBlock(FCmp.getNextNode());
  // Remove the newly created terminator unconditional branch.
  FCmpBB->back().eraseFromParent();
  BasicBlock *FailBB =
      BasicBlock::Create(Context, "", FCmpBB->getParent(), NextBB);

  // Create the shadow fcmp and comparison between the fcmps.
  IRBuilder<> FCmpBuilder(FCmpBB);
  FCmpBuilder.SetCurrentDebugLocation(FCmp.getDebugLoc());
  Value *ShadowLHS = Map.getShadow(LHS);
  Value *ShadowRHS = Map.getShadow(RHS);
  // See comment on ClTruncateFCmpEq.
  if (FCmp.isEquality() && ClTruncateFCmpEq) {
    Type *Ty = ShadowLHS->getType();
    ShadowLHS = FCmpBuilder.CreateFPExt(
        FCmpBuilder.CreateFPTrunc(ShadowLHS, LHS->getType()), Ty);
    ShadowRHS = FCmpBuilder.CreateFPExt(
        FCmpBuilder.CreateFPTrunc(ShadowRHS, RHS->getType()), Ty);
  }
  Value *ShadowFCmp =
      FCmpBuilder.CreateFCmp(FCmp.getPredicate(), ShadowLHS, ShadowRHS);
  Value *OriginalAndShadowFcmpMatch =
      FCmpBuilder.CreateICmpEQ(&FCmp, ShadowFCmp);

  if (OriginalAndShadowFcmpMatch->getType()->isVectorTy()) {
    // If we have a vector type, `OriginalAndShadowFcmpMatch` is a vector of i1,
    // where an element is true if the corresponding elements in original and
    // shadow are the same. We want all elements to be 1.
    OriginalAndShadowFcmpMatch =
        FCmpBuilder.CreateAndReduce(OriginalAndShadowFcmpMatch);
  }

  // Use MDBuilder(*C).createLikelyBranchWeights() because "match" is the common
  // case.
  FCmpBuilder.CreateCondBr(OriginalAndShadowFcmpMatch, NextBB, FailBB,
                           MDBuilder(Context).createLikelyBranchWeights());

  // Fill in FailBB.
  IRBuilder<> FailBuilder(FailBB);
  FailBuilder.SetCurrentDebugLocation(FCmp.getDebugLoc());

  const auto EmitFailCall = [this, &FCmp, &FCmpBuilder,
                             &FailBuilder](Value *L, Value *R, Value *ShadowL,
                                           Value *ShadowR, Value *Result,
                                           Value *ShadowResult) {
    Type *FT = L->getType();
    FunctionCallee *Callee = nullptr;
    if (FT->isFloatTy()) {
      Callee = &(NsanFCmpFail[kFloat]);
    } else if (FT->isDoubleTy()) {
      Callee = &(NsanFCmpFail[kDouble]);
    } else if (FT->isX86_FP80Ty()) {
      // TODO: make NsanFCmpFailLongDouble work.
      Callee = &(NsanFCmpFail[kDouble]);
      L = FailBuilder.CreateFPTrunc(L, Type::getDoubleTy(Context));
      R = FailBuilder.CreateFPTrunc(L, Type::getDoubleTy(Context));
    } else {
      llvm_unreachable("not implemented");
    }
    FailBuilder.CreateCall(*Callee, {L, R, ShadowL, ShadowR,
                                     ConstantInt::get(FCmpBuilder.getInt32Ty(),
                                                      FCmp.getPredicate()),
                                     Result, ShadowResult});
  };
  if (LHS->getType()->isVectorTy()) {
    for (int I = 0, E = cast<VectorType>(LHS->getType())
                            ->getElementCount()
                            .getFixedValue();
         I < E; ++I) {
      Value *ExtractLHS = FailBuilder.CreateExtractElement(LHS, I);
      Value *ExtractRHS = FailBuilder.CreateExtractElement(RHS, I);
      Value *ExtractShaodwLHS = FailBuilder.CreateExtractElement(ShadowLHS, I);
      Value *ExtractShaodwRHS = FailBuilder.CreateExtractElement(ShadowRHS, I);
      Value *ExtractFCmp = FailBuilder.CreateExtractElement(&FCmp, I);
      Value *ExtractShadowFCmp =
          FailBuilder.CreateExtractElement(ShadowFCmp, I);
      EmitFailCall(ExtractLHS, ExtractRHS, ExtractShaodwLHS, ExtractShaodwRHS,
                   ExtractFCmp, ExtractShadowFCmp);
    }
  } else {
    EmitFailCall(LHS, RHS, ShadowLHS, ShadowRHS, &FCmp, ShadowFCmp);
  }
  FailBuilder.CreateBr(NextBB);

  ++NumInstrumentedFCmp;
}

// Creates a shadow phi value for any phi that defines a value of FT type.
PHINode *NumericalStabilitySanitizer::maybeCreateShadowPhi(
    PHINode &Phi, const TargetLibraryInfo &TLI) {
  Type *VT = Phi.getType();
  Type *ExtendedVT = Config.getExtendedFPType(VT);
  if (ExtendedVT == nullptr)
    return nullptr; // Not an FT value.
  // The phi operands are shadow values and are not available when the phi is
  // created. They will be populated in a final phase, once all shadow values
  // have been created.
  PHINode *Shadow = PHINode::Create(ExtendedVT, Phi.getNumIncomingValues());
  Shadow->insertAfter(Phi.getIterator());
  return Shadow;
}

Value *NumericalStabilitySanitizer::handleLoad(LoadInst &Load, Type *VT,
                                               Type *ExtendedVT) {
  IRBuilder<> Builder(Load.getNextNode());
  Builder.SetCurrentDebugLocation(Load.getDebugLoc());
  if (addrPointsToConstantData(Load.getPointerOperand())) {
    // No need to look into the shadow memory, the value is a constant. Just
    // convert from FT to 2FT.
    return Builder.CreateFPExt(&Load, ExtendedVT);
  }

  // if (%shadowptr == &)
  //    %shadow = fpext %v
  // else
  //    %shadow = load (ptrcast %shadow_ptr))
  // Considered options here:
  //  - Have `NsanGetShadowPtrForLoad` return a fixed address
  //    &__nsan_unknown_value_shadow_address that is valid to load from, and
  //    use a select. This has the advantage that the generated IR is simpler.
  //  - Have `NsanGetShadowPtrForLoad` return nullptr.  Because `select` does
  //    not short-circuit, dereferencing the returned pointer is no longer an
  //    option, have to split and create a separate basic block. This has the
  //    advantage of being easier to debug because it crashes if we ever mess
  //    up.

  const auto Extents = getMemoryExtentsOrDie(VT);
  Value *ShadowPtr = Builder.CreateCall(
      NsanGetShadowPtrForLoad[Extents.ValueType],
      {Load.getPointerOperand(), ConstantInt::get(IntptrTy, Extents.NumElts)});
  ++NumInstrumentedFTLoads;

  // Split the basic block.
  BasicBlock *LoadBB = Load.getParent();
  BasicBlock *NextBB = LoadBB->splitBasicBlock(Builder.GetInsertPoint());
  // Create the two options for creating the shadow value.
  BasicBlock *ShadowLoadBB =
      BasicBlock::Create(Context, "", LoadBB->getParent(), NextBB);
  BasicBlock *FExtBB =
      BasicBlock::Create(Context, "", LoadBB->getParent(), NextBB);

  // Replace the newly created terminator unconditional branch by a conditional
  // branch to one of the options.
  {
    LoadBB->back().eraseFromParent();
    IRBuilder<> LoadBBBuilder(LoadBB); // The old builder has been invalidated.
    LoadBBBuilder.SetCurrentDebugLocation(Load.getDebugLoc());
    LoadBBBuilder.CreateCondBr(LoadBBBuilder.CreateIsNull(ShadowPtr), FExtBB,
                               ShadowLoadBB);
  }

  // Fill in ShadowLoadBB.
  IRBuilder<> ShadowLoadBBBuilder(ShadowLoadBB);
  ShadowLoadBBBuilder.SetCurrentDebugLocation(Load.getDebugLoc());
  Value *ShadowLoad = ShadowLoadBBBuilder.CreateAlignedLoad(
      ExtendedVT, ShadowPtr, Align(1), Load.isVolatile());
  if (ClCheckLoads) {
    ShadowLoad = emitCheck(&Load, ShadowLoad, ShadowLoadBBBuilder,
                           CheckLoc::makeLoad(Load.getPointerOperand()));
  }
  ShadowLoadBBBuilder.CreateBr(NextBB);

  // Fill in FExtBB.
  IRBuilder<> FExtBBBuilder(FExtBB);
  FExtBBBuilder.SetCurrentDebugLocation(Load.getDebugLoc());
  Value *FExt = FExtBBBuilder.CreateFPExt(&Load, ExtendedVT);
  FExtBBBuilder.CreateBr(NextBB);

  // The shadow value come from any of the options.
  IRBuilder<> NextBBBuilder(&*NextBB->begin());
  NextBBBuilder.SetCurrentDebugLocation(Load.getDebugLoc());
  PHINode *ShadowPhi = NextBBBuilder.CreatePHI(ExtendedVT, 2);
  ShadowPhi->addIncoming(ShadowLoad, ShadowLoadBB);
  ShadowPhi->addIncoming(FExt, FExtBB);
  return ShadowPhi;
}

Value *NumericalStabilitySanitizer::handleTrunc(const FPTruncInst &Trunc,
                                                Type *VT, Type *ExtendedVT,
                                                const ValueToShadowMap &Map,
                                                IRBuilder<> &Builder) {
  Value *OrigSource = Trunc.getOperand(0);
  Type *OrigSourceTy = OrigSource->getType();
  Type *ExtendedSourceTy = Config.getExtendedFPType(OrigSourceTy);

  // When truncating:
  //  - (A) If the source has a shadow, we truncate from the shadow, else we
  //    truncate from the original source.
  //  - (B) If the shadow of the source is larger than the shadow of the dest,
  //    we still need a truncate. Else, the shadow of the source is the same
  //    type as the shadow of the dest (because mappings are non-decreasing), so
  //   we don't need to emit a truncate.
  // Examples,
  //   with a mapping of {f32->f64;f64->f80;f80->f128}
  //     fptrunc double   %1 to float     ->  fptrunc x86_fp80 s(%1) to double
  //     fptrunc x86_fp80 %1 to float     ->  fptrunc fp128    s(%1) to double
  //     fptrunc fp128    %1 to float     ->  fptrunc fp128    %1    to double
  //     fptrunc x86_fp80 %1 to double    ->  x86_fp80 s(%1)
  //     fptrunc fp128    %1 to double    ->  fptrunc fp128 %1 to x86_fp80
  //     fptrunc fp128    %1 to x86_fp80  ->  fp128 %1
  //   with a mapping of {f32->f64;f64->f128;f80->f128}
  //     fptrunc double   %1 to float     ->  fptrunc fp128    s(%1) to double
  //     fptrunc x86_fp80 %1 to float     ->  fptrunc fp128    s(%1) to double
  //     fptrunc fp128    %1 to float     ->  fptrunc fp128    %1    to double
  //     fptrunc x86_fp80 %1 to double    ->  fp128 %1
  //     fptrunc fp128    %1 to double    ->  fp128 %1
  //     fptrunc fp128    %1 to x86_fp80  ->  fp128 %1
  //   with a mapping of {f32->f32;f64->f32;f80->f64}
  //     fptrunc double   %1 to float     ->  float s(%1)
  //     fptrunc x86_fp80 %1 to float     ->  fptrunc double    s(%1) to float
  //     fptrunc fp128    %1 to float     ->  fptrunc fp128     %1    to float
  //     fptrunc x86_fp80 %1 to double    ->  fptrunc double    s(%1) to float
  //     fptrunc fp128    %1 to double    ->  fptrunc fp128     %1    to float
  //     fptrunc fp128    %1 to x86_fp80  ->  fptrunc fp128     %1    to double

  // See (A) above.
  Value *Source = ExtendedSourceTy ? Map.getShadow(OrigSource) : OrigSource;
  Type *SourceTy = ExtendedSourceTy ? ExtendedSourceTy : OrigSourceTy;
  // See (B) above.
  if (SourceTy == ExtendedVT)
    return Source;

  return Builder.CreateFPTrunc(Source, ExtendedVT);
}

Value *NumericalStabilitySanitizer::handleExt(const FPExtInst &Ext, Type *VT,
                                              Type *ExtendedVT,
                                              const ValueToShadowMap &Map,
                                              IRBuilder<> &Builder) {
  Value *OrigSource = Ext.getOperand(0);
  Type *OrigSourceTy = OrigSource->getType();
  Type *ExtendedSourceTy = Config.getExtendedFPType(OrigSourceTy);
  // When extending:
  //  - (A) If the source has a shadow, we extend from the shadow, else we
  //    extend from the original source.
  //  - (B) If the shadow of the dest is larger than the shadow of the source,
  //    we still need an extend. Else, the shadow of the source is the same
  //    type as the shadow of the dest (because mappings are non-decreasing), so
  //    we don't need to emit an extend.
  // Examples,
  //   with a mapping of {f32->f64;f64->f80;f80->f128}
  //     fpext half    %1 to float     ->  fpext half     %1    to double
  //     fpext half    %1 to double    ->  fpext half     %1    to x86_fp80
  //     fpext half    %1 to x86_fp80  ->  fpext half     %1    to fp128
  //     fpext float   %1 to double    ->  double s(%1)
  //     fpext float   %1 to x86_fp80  ->  fpext double   s(%1) to fp128
  //     fpext double  %1 to x86_fp80  ->  fpext x86_fp80 s(%1) to fp128
  //   with a mapping of {f32->f64;f64->f128;f80->f128}
  //     fpext half    %1 to float     ->  fpext half     %1    to double
  //     fpext half    %1 to double    ->  fpext half     %1    to fp128
  //     fpext half    %1 to x86_fp80  ->  fpext half     %1    to fp128
  //     fpext float   %1 to double    ->  fpext double   s(%1) to fp128
  //     fpext float   %1 to x86_fp80  ->  fpext double   s(%1) to fp128
  //     fpext double  %1 to x86_fp80  ->  fp128 s(%1)
  //   with a mapping of {f32->f32;f64->f32;f80->f64}
  //     fpext half    %1 to float     ->  fpext half     %1    to float
  //     fpext half    %1 to double    ->  fpext half     %1    to float
  //     fpext half    %1 to x86_fp80  ->  fpext half     %1    to double
  //     fpext float   %1 to double    ->  s(%1)
  //     fpext float   %1 to x86_fp80  ->  fpext float    s(%1) to double
  //     fpext double  %1 to x86_fp80  ->  fpext float    s(%1) to double

  // See (A) above.
  Value *Source = ExtendedSourceTy ? Map.getShadow(OrigSource) : OrigSource;
  Type *SourceTy = ExtendedSourceTy ? ExtendedSourceTy : OrigSourceTy;
  // See (B) above.
  if (SourceTy == ExtendedVT)
    return Source;

  return Builder.CreateFPExt(Source, ExtendedVT);
}

namespace {
// TODO: This should be tablegen-ed.
struct KnownIntrinsic {
  struct WidenedIntrinsic {
    const char *NarrowName;
    Intrinsic::ID ID; // wide id.
    using FnTypeFactory = FunctionType *(*)(LLVMContext &);
    FnTypeFactory MakeFnTy;
  };

  static const char *get(LibFunc LFunc);

  // Given an intrinsic with an `FT` argument, try to find a wider intrinsic
  // that applies the same operation on the shadow argument.
  // Options are:
  //  - pass in the ID and full function type,
  //  - pass in the name, which includes the function type through mangling.
  static const WidenedIntrinsic *widen(StringRef Name);

private:
  struct LFEntry {
    LibFunc LFunc;
    const char *IntrinsicName;
  };
  static const LFEntry kLibfuncIntrinsics[];

  static const WidenedIntrinsic kWidenedIntrinsics[];
};
} // namespace

static FunctionType *makeDoubleDouble(LLVMContext &C) {
  return FunctionType::get(Type::getDoubleTy(C), {Type::getDoubleTy(C)}, false);
}

static FunctionType *makeX86FP80X86FP80(LLVMContext &C) {
  return FunctionType::get(Type::getX86_FP80Ty(C), {Type::getX86_FP80Ty(C)},
                           false);
}

static FunctionType *makeDoubleDoubleI32(LLVMContext &C) {
  return FunctionType::get(Type::getDoubleTy(C),
                           {Type::getDoubleTy(C), Type::getInt32Ty(C)}, false);
}

static FunctionType *makeX86FP80X86FP80I32(LLVMContext &C) {
  return FunctionType::get(Type::getX86_FP80Ty(C),
                           {Type::getX86_FP80Ty(C), Type::getInt32Ty(C)},
                           false);
}

static FunctionType *makeDoubleDoubleDouble(LLVMContext &C) {
  return FunctionType::get(Type::getDoubleTy(C),
                           {Type::getDoubleTy(C), Type::getDoubleTy(C)}, false);
}

static FunctionType *makeX86FP80X86FP80X86FP80(LLVMContext &C) {
  return FunctionType::get(Type::getX86_FP80Ty(C),
                           {Type::getX86_FP80Ty(C), Type::getX86_FP80Ty(C)},
                           false);
}

static FunctionType *makeDoubleDoubleDoubleDouble(LLVMContext &C) {
  return FunctionType::get(
      Type::getDoubleTy(C),
      {Type::getDoubleTy(C), Type::getDoubleTy(C), Type::getDoubleTy(C)},
      false);
}

static FunctionType *makeX86FP80X86FP80X86FP80X86FP80(LLVMContext &C) {
  return FunctionType::get(
      Type::getX86_FP80Ty(C),
      {Type::getX86_FP80Ty(C), Type::getX86_FP80Ty(C), Type::getX86_FP80Ty(C)},
      false);
}

const KnownIntrinsic::WidenedIntrinsic KnownIntrinsic::kWidenedIntrinsics[] = {
    // TODO: Right now we ignore vector intrinsics.
    // This is hard because we have to model the semantics of the intrinsics,
    // e.g. llvm.x86.sse2.min.sd means extract first element, min, insert back.
    // Intrinsics that take any non-vector FT types:
    // NOTE: Right now because of
    // https://github.com/llvm/llvm-project/issues/44744
    // for f128 we need to use makeX86FP80X86FP80 (go to a lower precision and
    // come back).
    {"llvm.sqrt.f32", Intrinsic::sqrt, makeDoubleDouble},
    {"llvm.sqrt.f64", Intrinsic::sqrt, makeX86FP80X86FP80},
    {"llvm.sqrt.f80", Intrinsic::sqrt, makeX86FP80X86FP80},
    {"llvm.powi.f32", Intrinsic::powi, makeDoubleDoubleI32},
    {"llvm.powi.f64", Intrinsic::powi, makeX86FP80X86FP80I32},
    {"llvm.powi.f80", Intrinsic::powi, makeX86FP80X86FP80I32},
    {"llvm.sin.f32", Intrinsic::sin, makeDoubleDouble},
    {"llvm.sin.f64", Intrinsic::sin, makeX86FP80X86FP80},
    {"llvm.sin.f80", Intrinsic::sin, makeX86FP80X86FP80},
    {"llvm.cos.f32", Intrinsic::cos, makeDoubleDouble},
    {"llvm.cos.f64", Intrinsic::cos, makeX86FP80X86FP80},
    {"llvm.cos.f80", Intrinsic::cos, makeX86FP80X86FP80},
    {"llvm.pow.f32", Intrinsic::pow, makeDoubleDoubleDouble},
    {"llvm.pow.f64", Intrinsic::pow, makeX86FP80X86FP80X86FP80},
    {"llvm.pow.f80", Intrinsic::pow, makeX86FP80X86FP80X86FP80},
    {"llvm.exp.f32", Intrinsic::exp, makeDoubleDouble},
    {"llvm.exp.f64", Intrinsic::exp, makeX86FP80X86FP80},
    {"llvm.exp.f80", Intrinsic::exp, makeX86FP80X86FP80},
    {"llvm.exp2.f32", Intrinsic::exp2, makeDoubleDouble},
    {"llvm.exp2.f64", Intrinsic::exp2, makeX86FP80X86FP80},
    {"llvm.exp2.f80", Intrinsic::exp2, makeX86FP80X86FP80},
    {"llvm.log.f32", Intrinsic::log, makeDoubleDouble},
    {"llvm.log.f64", Intrinsic::log, makeX86FP80X86FP80},
    {"llvm.log.f80", Intrinsic::log, makeX86FP80X86FP80},
    {"llvm.log10.f32", Intrinsic::log10, makeDoubleDouble},
    {"llvm.log10.f64", Intrinsic::log10, makeX86FP80X86FP80},
    {"llvm.log10.f80", Intrinsic::log10, makeX86FP80X86FP80},
    {"llvm.log2.f32", Intrinsic::log2, makeDoubleDouble},
    {"llvm.log2.f64", Intrinsic::log2, makeX86FP80X86FP80},
    {"llvm.log2.f80", Intrinsic::log2, makeX86FP80X86FP80},
    {"llvm.fma.f32", Intrinsic::fma, makeDoubleDoubleDoubleDouble},

    {"llvm.fmuladd.f32", Intrinsic::fmuladd, makeDoubleDoubleDoubleDouble},

    {"llvm.fma.f64", Intrinsic::fma, makeX86FP80X86FP80X86FP80X86FP80},

    {"llvm.fmuladd.f64", Intrinsic::fma, makeX86FP80X86FP80X86FP80X86FP80},

    {"llvm.fma.f80", Intrinsic::fma, makeX86FP80X86FP80X86FP80X86FP80},
    {"llvm.fabs.f32", Intrinsic::fabs, makeDoubleDouble},
    {"llvm.fabs.f64", Intrinsic::fabs, makeX86FP80X86FP80},
    {"llvm.fabs.f80", Intrinsic::fabs, makeX86FP80X86FP80},
    {"llvm.minnum.f32", Intrinsic::minnum, makeDoubleDoubleDouble},
    {"llvm.minnum.f64", Intrinsic::minnum, makeX86FP80X86FP80X86FP80},
    {"llvm.minnum.f80", Intrinsic::minnum, makeX86FP80X86FP80X86FP80},
    {"llvm.maxnum.f32", Intrinsic::maxnum, makeDoubleDoubleDouble},
    {"llvm.maxnum.f64", Intrinsic::maxnum, makeX86FP80X86FP80X86FP80},
    {"llvm.maxnum.f80", Intrinsic::maxnum, makeX86FP80X86FP80X86FP80},
    {"llvm.minimum.f32", Intrinsic::minimum, makeDoubleDoubleDouble},
    {"llvm.minimum.f64", Intrinsic::minimum, makeX86FP80X86FP80X86FP80},
    {"llvm.minimum.f80", Intrinsic::minimum, makeX86FP80X86FP80X86FP80},
    {"llvm.maximum.f32", Intrinsic::maximum, makeDoubleDoubleDouble},
    {"llvm.maximum.f64", Intrinsic::maximum, makeX86FP80X86FP80X86FP80},
    {"llvm.maximum.f80", Intrinsic::maximum, makeX86FP80X86FP80X86FP80},
    {"llvm.copysign.f32", Intrinsic::copysign, makeDoubleDoubleDouble},
    {"llvm.copysign.f64", Intrinsic::copysign, makeX86FP80X86FP80X86FP80},
    {"llvm.copysign.f80", Intrinsic::copysign, makeX86FP80X86FP80X86FP80},
    {"llvm.floor.f32", Intrinsic::floor, makeDoubleDouble},
    {"llvm.floor.f64", Intrinsic::floor, makeX86FP80X86FP80},
    {"llvm.floor.f80", Intrinsic::floor, makeX86FP80X86FP80},
    {"llvm.ceil.f32", Intrinsic::ceil, makeDoubleDouble},
    {"llvm.ceil.f64", Intrinsic::ceil, makeX86FP80X86FP80},
    {"llvm.ceil.f80", Intrinsic::ceil, makeX86FP80X86FP80},
    {"llvm.trunc.f32", Intrinsic::trunc, makeDoubleDouble},
    {"llvm.trunc.f64", Intrinsic::trunc, makeX86FP80X86FP80},
    {"llvm.trunc.f80", Intrinsic::trunc, makeX86FP80X86FP80},
    {"llvm.rint.f32", Intrinsic::rint, makeDoubleDouble},
    {"llvm.rint.f64", Intrinsic::rint, makeX86FP80X86FP80},
    {"llvm.rint.f80", Intrinsic::rint, makeX86FP80X86FP80},
    {"llvm.nearbyint.f32", Intrinsic::nearbyint, makeDoubleDouble},
    {"llvm.nearbyint.f64", Intrinsic::nearbyint, makeX86FP80X86FP80},
    {"llvm.nearbyin80f64", Intrinsic::nearbyint, makeX86FP80X86FP80},
    {"llvm.round.f32", Intrinsic::round, makeDoubleDouble},
    {"llvm.round.f64", Intrinsic::round, makeX86FP80X86FP80},
    {"llvm.round.f80", Intrinsic::round, makeX86FP80X86FP80},
    {"llvm.lround.f32", Intrinsic::lround, makeDoubleDouble},
    {"llvm.lround.f64", Intrinsic::lround, makeX86FP80X86FP80},
    {"llvm.lround.f80", Intrinsic::lround, makeX86FP80X86FP80},
    {"llvm.llround.f32", Intrinsic::llround, makeDoubleDouble},
    {"llvm.llround.f64", Intrinsic::llround, makeX86FP80X86FP80},
    {"llvm.llround.f80", Intrinsic::llround, makeX86FP80X86FP80},
    {"llvm.lrint.f32", Intrinsic::lrint, makeDoubleDouble},
    {"llvm.lrint.f64", Intrinsic::lrint, makeX86FP80X86FP80},
    {"llvm.lrint.f80", Intrinsic::lrint, makeX86FP80X86FP80},
    {"llvm.llrint.f32", Intrinsic::llrint, makeDoubleDouble},
    {"llvm.llrint.f64", Intrinsic::llrint, makeX86FP80X86FP80},
    {"llvm.llrint.f80", Intrinsic::llrint, makeX86FP80X86FP80},
};

const KnownIntrinsic::LFEntry KnownIntrinsic::kLibfuncIntrinsics[] = {
    {LibFunc_sqrtf, "llvm.sqrt.f32"},
    {LibFunc_sqrt, "llvm.sqrt.f64"},
    {LibFunc_sqrtl, "llvm.sqrt.f80"},
    {LibFunc_sinf, "llvm.sin.f32"},
    {LibFunc_sin, "llvm.sin.f64"},
    {LibFunc_sinl, "llvm.sin.f80"},
    {LibFunc_cosf, "llvm.cos.f32"},
    {LibFunc_cos, "llvm.cos.f64"},
    {LibFunc_cosl, "llvm.cos.f80"},
    {LibFunc_powf, "llvm.pow.f32"},
    {LibFunc_pow, "llvm.pow.f64"},
    {LibFunc_powl, "llvm.pow.f80"},
    {LibFunc_expf, "llvm.exp.f32"},
    {LibFunc_exp, "llvm.exp.f64"},
    {LibFunc_expl, "llvm.exp.f80"},
    {LibFunc_exp2f, "llvm.exp2.f32"},
    {LibFunc_exp2, "llvm.exp2.f64"},
    {LibFunc_exp2l, "llvm.exp2.f80"},
    {LibFunc_logf, "llvm.log.f32"},
    {LibFunc_log, "llvm.log.f64"},
    {LibFunc_logl, "llvm.log.f80"},
    {LibFunc_log10f, "llvm.log10.f32"},
    {LibFunc_log10, "llvm.log10.f64"},
    {LibFunc_log10l, "llvm.log10.f80"},
    {LibFunc_log2f, "llvm.log2.f32"},
    {LibFunc_log2, "llvm.log2.f64"},
    {LibFunc_log2l, "llvm.log2.f80"},
    {LibFunc_fabsf, "llvm.fabs.f32"},
    {LibFunc_fabs, "llvm.fabs.f64"},
    {LibFunc_fabsl, "llvm.fabs.f80"},
    {LibFunc_copysignf, "llvm.copysign.f32"},
    {LibFunc_copysign, "llvm.copysign.f64"},
    {LibFunc_copysignl, "llvm.copysign.f80"},
    {LibFunc_floorf, "llvm.floor.f32"},
    {LibFunc_floor, "llvm.floor.f64"},
    {LibFunc_floorl, "llvm.floor.f80"},
    {LibFunc_fmaxf, "llvm.maxnum.f32"},
    {LibFunc_fmax, "llvm.maxnum.f64"},
    {LibFunc_fmaxl, "llvm.maxnum.f80"},
    {LibFunc_fminf, "llvm.minnum.f32"},
    {LibFunc_fmin, "llvm.minnum.f64"},
    {LibFunc_fminl, "llvm.minnum.f80"},
    {LibFunc_ceilf, "llvm.ceil.f32"},
    {LibFunc_ceil, "llvm.ceil.f64"},
    {LibFunc_ceill, "llvm.ceil.f80"},
    {LibFunc_truncf, "llvm.trunc.f32"},
    {LibFunc_trunc, "llvm.trunc.f64"},
    {LibFunc_truncl, "llvm.trunc.f80"},
    {LibFunc_rintf, "llvm.rint.f32"},
    {LibFunc_rint, "llvm.rint.f64"},
    {LibFunc_rintl, "llvm.rint.f80"},
    {LibFunc_nearbyintf, "llvm.nearbyint.f32"},
    {LibFunc_nearbyint, "llvm.nearbyint.f64"},
    {LibFunc_nearbyintl, "llvm.nearbyint.f80"},
    {LibFunc_roundf, "llvm.round.f32"},
    {LibFunc_round, "llvm.round.f64"},
    {LibFunc_roundl, "llvm.round.f80"},
};

const char *KnownIntrinsic::get(LibFunc LFunc) {
  for (const auto &E : kLibfuncIntrinsics) {
    if (E.LFunc == LFunc)
      return E.IntrinsicName;
  }
  return nullptr;
}

const KnownIntrinsic::WidenedIntrinsic *KnownIntrinsic::widen(StringRef Name) {
  for (const auto &E : kWidenedIntrinsics) {
    if (E.NarrowName == Name)
      return &E;
  }
  return nullptr;
}

// Returns the name of the LLVM intrinsic corresponding to the given function.
static const char *getIntrinsicFromLibfunc(Function &Fn, Type *VT,
                                           const TargetLibraryInfo &TLI) {
  LibFunc LFunc;
  if (!TLI.getLibFunc(Fn, LFunc))
    return nullptr;

  if (const char *Name = KnownIntrinsic::get(LFunc))
    return Name;

  LLVM_DEBUG(errs() << "TODO: LibFunc: " << TLI.getName(LFunc) << "\n");
  return nullptr;
}

// Try to handle a known function call.
Value *NumericalStabilitySanitizer::maybeHandleKnownCallBase(
    CallBase &Call, Type *VT, Type *ExtendedVT, const TargetLibraryInfo &TLI,
    const ValueToShadowMap &Map, IRBuilder<> &Builder) {
  Function *Fn = Call.getCalledFunction();
  if (Fn == nullptr)
    return nullptr;

  Intrinsic::ID WidenedId = Intrinsic::ID();
  FunctionType *WidenedFnTy = nullptr;
  if (const auto ID = Fn->getIntrinsicID()) {
    const auto *Widened = KnownIntrinsic::widen(Fn->getName());
    if (Widened) {
      WidenedId = Widened->ID;
      WidenedFnTy = Widened->MakeFnTy(Context);
    } else {
      // If we don't know how to widen the intrinsic, we have no choice but to
      // call the non-wide version on a truncated shadow and extend again
      // afterwards.
      WidenedId = ID;
      WidenedFnTy = Fn->getFunctionType();
    }
  } else if (const char *Name = getIntrinsicFromLibfunc(*Fn, VT, TLI)) {
    // We might have a call to a library function that we can replace with a
    // wider Intrinsic.
    const auto *Widened = KnownIntrinsic::widen(Name);
    assert(Widened && "make sure KnownIntrinsic entries are consistent");
    WidenedId = Widened->ID;
    WidenedFnTy = Widened->MakeFnTy(Context);
  } else {
    // This is not a known library function or intrinsic.
    return nullptr;
  }

  // Check that the widened intrinsic is valid.
  SmallVector<Intrinsic::IITDescriptor, 8> Table;
  getIntrinsicInfoTableEntries(WidenedId, Table);
  SmallVector<Type *, 4> ArgTys;
  ArrayRef<Intrinsic::IITDescriptor> TableRef = Table;
  [[maybe_unused]] Intrinsic::MatchIntrinsicTypesResult MatchResult =
      Intrinsic::matchIntrinsicSignature(WidenedFnTy, TableRef, ArgTys);
  assert(MatchResult == Intrinsic::MatchIntrinsicTypes_Match &&
         "invalid widened intrinsic");
  // For known intrinsic functions, we create a second call to the same
  // intrinsic with a different type.
  SmallVector<Value *, 4> Args;
  // The last operand is the intrinsic itself, skip it.
  for (unsigned I = 0, E = Call.getNumOperands() - 1; I < E; ++I) {
    Value *Arg = Call.getOperand(I);
    Type *OrigArgTy = Arg->getType();
    Type *IntrinsicArgTy = WidenedFnTy->getParamType(I);
    if (OrigArgTy == IntrinsicArgTy) {
      Args.push_back(Arg); // The arg is passed as is.
      continue;
    }
    Type *ShadowArgTy = Config.getExtendedFPType(Arg->getType());
    assert(ShadowArgTy &&
           "don't know how to get the shadow value for a non-FT");
    Value *Shadow = Map.getShadow(Arg);
    if (ShadowArgTy == IntrinsicArgTy) {
      // The shadow is the right type for the intrinsic.
      assert(Shadow->getType() == ShadowArgTy);
      Args.push_back(Shadow);
      continue;
    }
    // There is no intrinsic with his level of precision, truncate the shadow.
    Args.push_back(Builder.CreateFPTrunc(Shadow, IntrinsicArgTy));
  }
  Value *IntrinsicCall = Builder.CreateIntrinsic(WidenedId, ArgTys, Args);
  return WidenedFnTy->getReturnType() == ExtendedVT
             ? IntrinsicCall
             : Builder.CreateFPExt(IntrinsicCall, ExtendedVT);
}

// Handle a CallBase, i.e. a function call, an inline asm sequence, or an
// invoke.
Value *NumericalStabilitySanitizer::handleCallBase(CallBase &Call, Type *VT,
                                                   Type *ExtendedVT,
                                                   const TargetLibraryInfo &TLI,
                                                   const ValueToShadowMap &Map,
                                                   IRBuilder<> &Builder) {
  // We cannot look inside inline asm, just expand the result again.
  if (Call.isInlineAsm())
    return Builder.CreateFPExt(&Call, ExtendedVT);

  // Intrinsics and library functions (e.g. sin, exp) are handled
  // specifically, because we know their semantics and can do better than
  // blindly calling them (e.g. compute the sinus in the actual shadow domain).
  if (Value *V =
          maybeHandleKnownCallBase(Call, VT, ExtendedVT, TLI, Map, Builder))
    return V;

  // If the return tag matches that of the called function, read the extended
  // return value from the shadow ret ptr. Else, just extend the return value.
  Value *L =
      Builder.CreateLoad(IntptrTy, NsanShadowRetTag, /*isVolatile=*/false);
  Value *HasShadowRet = Builder.CreateICmpEQ(
      L, Builder.CreatePtrToInt(Call.getCalledOperand(), IntptrTy));

  Value *ShadowRetVal = Builder.CreateLoad(
      ExtendedVT,
      Builder.CreateConstGEP2_64(NsanShadowRetType, NsanShadowRetPtr, 0, 0),
      /*isVolatile=*/false);
  Value *Shadow = Builder.CreateSelect(HasShadowRet, ShadowRetVal,
                                       Builder.CreateFPExt(&Call, ExtendedVT));
  ++NumInstrumentedFTCalls;
  return Shadow;
}

// Creates a shadow value for the given FT value. At that point all operands are
// guaranteed to be available.
Value *NumericalStabilitySanitizer::createShadowValueWithOperandsAvailable(
    Instruction &Inst, const TargetLibraryInfo &TLI,
    const ValueToShadowMap &Map) {
  Type *VT = Inst.getType();
  Type *ExtendedVT = Config.getExtendedFPType(VT);
  assert(ExtendedVT != nullptr && "trying to create a shadow for a non-FT");

  if (auto *Load = dyn_cast<LoadInst>(&Inst))
    return handleLoad(*Load, VT, ExtendedVT);

  if (auto *Call = dyn_cast<CallInst>(&Inst)) {
    // Insert after the call.
    BasicBlock::iterator It(Inst);
    IRBuilder<> Builder(Call->getParent(), ++It);
    Builder.SetCurrentDebugLocation(Call->getDebugLoc());
    return handleCallBase(*Call, VT, ExtendedVT, TLI, Map, Builder);
  }

  if (auto *Invoke = dyn_cast<InvokeInst>(&Inst)) {
    // The Invoke terminates the basic block, create a new basic block in
    // between the successful invoke and the next block.
    BasicBlock *InvokeBB = Invoke->getParent();
    BasicBlock *NextBB = Invoke->getNormalDest();
    BasicBlock *NewBB =
        BasicBlock::Create(Context, "", NextBB->getParent(), NextBB);
    Inst.replaceSuccessorWith(NextBB, NewBB);

    IRBuilder<> Builder(NewBB);
    Builder.SetCurrentDebugLocation(Invoke->getDebugLoc());
    Value *Shadow = handleCallBase(*Invoke, VT, ExtendedVT, TLI, Map, Builder);
    Builder.CreateBr(NextBB);
    NewBB->replaceSuccessorsPhiUsesWith(InvokeBB, NewBB);
    return Shadow;
  }

  IRBuilder<> Builder(Inst.getNextNode());
  Builder.SetCurrentDebugLocation(Inst.getDebugLoc());

  if (auto *Trunc = dyn_cast<FPTruncInst>(&Inst))
    return handleTrunc(*Trunc, VT, ExtendedVT, Map, Builder);
  if (auto *Ext = dyn_cast<FPExtInst>(&Inst))
    return handleExt(*Ext, VT, ExtendedVT, Map, Builder);

  if (auto *UnaryOp = dyn_cast<UnaryOperator>(&Inst))
    return Builder.CreateUnOp(UnaryOp->getOpcode(),
                              Map.getShadow(UnaryOp->getOperand(0)));

  if (auto *BinOp = dyn_cast<BinaryOperator>(&Inst))
    return Builder.CreateBinOp(BinOp->getOpcode(),
                               Map.getShadow(BinOp->getOperand(0)),
                               Map.getShadow(BinOp->getOperand(1)));

  if (isa<UIToFPInst>(&Inst) || isa<SIToFPInst>(&Inst)) {
    auto *Cast = cast<CastInst>(&Inst);
    return Builder.CreateCast(Cast->getOpcode(), Cast->getOperand(0),
                              ExtendedVT);
  }

  if (auto *S = dyn_cast<SelectInst>(&Inst))
    return Builder.CreateSelect(S->getCondition(),
                                Map.getShadow(S->getTrueValue()),
                                Map.getShadow(S->getFalseValue()));

  if (auto *Freeze = dyn_cast<FreezeInst>(&Inst))
    return Builder.CreateFreeze(Map.getShadow(Freeze->getOperand(0)));

  if (auto *Extract = dyn_cast<ExtractElementInst>(&Inst))
    return Builder.CreateExtractElement(
        Map.getShadow(Extract->getVectorOperand()), Extract->getIndexOperand());

  if (auto *Insert = dyn_cast<InsertElementInst>(&Inst))
    return Builder.CreateInsertElement(Map.getShadow(Insert->getOperand(0)),
                                       Map.getShadow(Insert->getOperand(1)),
                                       Insert->getOperand(2));

  if (auto *Shuffle = dyn_cast<ShuffleVectorInst>(&Inst))
    return Builder.CreateShuffleVector(Map.getShadow(Shuffle->getOperand(0)),
                                       Map.getShadow(Shuffle->getOperand(1)),
                                       Shuffle->getShuffleMask());
  // TODO: We could make aggregate object first class citizens. For now we
  // just extend the extracted value.
  if (auto *Extract = dyn_cast<ExtractValueInst>(&Inst))
    return Builder.CreateFPExt(Extract, ExtendedVT);

  if (auto *BC = dyn_cast<BitCastInst>(&Inst))
    return Builder.CreateFPExt(BC, ExtendedVT);

  report_fatal_error("Unimplemented support for " +
                     Twine(Inst.getOpcodeName()));
}

// Creates a shadow value for an instruction that defines a value of FT type.
// FT operands that do not already have shadow values are created recursively.
// The DFS is guaranteed to not loop as phis and arguments already have
// shadows.
void NumericalStabilitySanitizer::maybeCreateShadowValue(
    Instruction &Root, const TargetLibraryInfo &TLI, ValueToShadowMap &Map) {
  Type *VT = Root.getType();
  Type *ExtendedVT = Config.getExtendedFPType(VT);
  if (ExtendedVT == nullptr)
    return; // Not an FT value.

  if (Map.hasShadow(&Root))
    return; // Shadow already exists.

  assert(!isa<PHINode>(Root) && "phi nodes should already have shadows");

  std::vector<Instruction *> DfsStack(1, &Root);
  while (!DfsStack.empty()) {
    // Ensure that all operands to the instruction have shadows before
    // proceeding.
    Instruction *I = DfsStack.back();
    // The shadow for the instruction might have been created deeper in the DFS,
    // see `forward_use_with_two_uses` test.
    if (Map.hasShadow(I)) {
      DfsStack.pop_back();
      continue;
    }

    bool MissingShadow = false;
    for (Value *Op : I->operands()) {
      Type *VT = Op->getType();
      if (!Config.getExtendedFPType(VT))
        continue; // Not an FT value.
      if (Map.hasShadow(Op))
        continue; // Shadow is already available.
      MissingShadow = true;
      DfsStack.push_back(cast<Instruction>(Op));
    }
    if (MissingShadow)
      continue; // Process operands and come back to this instruction later.

    // All operands have shadows. Create a shadow for the current value.
    Value *Shadow = createShadowValueWithOperandsAvailable(*I, TLI, Map);
    Map.setShadow(*I, *Shadow);
    DfsStack.pop_back();
  }
}

// A floating-point store needs its value and type written to shadow memory.
void NumericalStabilitySanitizer::propagateFTStore(
    StoreInst &Store, Type *VT, Type *ExtendedVT, const ValueToShadowMap &Map) {
  Value *StoredValue = Store.getValueOperand();
  IRBuilder<> Builder(&Store);
  Builder.SetCurrentDebugLocation(Store.getDebugLoc());
  const auto Extents = getMemoryExtentsOrDie(VT);
  Value *ShadowPtr = Builder.CreateCall(
      NsanGetShadowPtrForStore[Extents.ValueType],
      {Store.getPointerOperand(), ConstantInt::get(IntptrTy, Extents.NumElts)});

  Value *StoredShadow = Map.getShadow(StoredValue);
  if (!Store.getParent()->getParent()->hasOptNone()) {
    // Only check stores when optimizing, because non-optimized code generates
    // too many stores to the stack, creating false positives.
    if (ClCheckStores) {
      StoredShadow = emitCheck(StoredValue, StoredShadow, Builder,
                               CheckLoc::makeStore(Store.getPointerOperand()));
      ++NumInstrumentedFTStores;
    }
  }

  Builder.CreateAlignedStore(StoredShadow, ShadowPtr, Align(1),
                             Store.isVolatile());
}

// A non-ft store needs to invalidate shadow memory. Exceptions are:
//   - memory transfers of floating-point data through other pointer types (llvm
//     optimization passes transform `*(float*)a = *(float*)b` into
//     `*(i32*)a = *(i32*)b` ). These have the same semantics as memcpy.
//   - Writes of FT-sized constants. LLVM likes to do float stores as bitcasted
//     ints. Note that this is not really necessary because if the value is
//     unknown the framework will re-extend it on load anyway. It just felt
//     easier to debug tests with vectors of FTs.
void NumericalStabilitySanitizer::propagateNonFTStore(
    StoreInst &Store, Type *VT, const ValueToShadowMap &Map) {
  Value *PtrOp = Store.getPointerOperand();
  IRBuilder<> Builder(Store.getNextNode());
  Builder.SetCurrentDebugLocation(Store.getDebugLoc());
  Value *Dst = PtrOp;
  TypeSize SlotSize = DL.getTypeStoreSize(VT);
  assert(!SlotSize.isScalable() && "unsupported");
  const auto LoadSizeBytes = SlotSize.getFixedValue();
  Value *ValueSize = Constant::getIntegerValue(
      IntptrTy, APInt(IntptrTy->getPrimitiveSizeInBits(), LoadSizeBytes));

  ++NumInstrumentedNonFTStores;
  Value *StoredValue = Store.getValueOperand();
  if (LoadInst *Load = dyn_cast<LoadInst>(StoredValue)) {
    // TODO: Handle the case when the value is from a phi.
    // This is a memory transfer with memcpy semantics. Copy the type and
    // value from the source. Note that we cannot use __nsan_copy_values()
    // here, because that will not work when there is a write to memory in
    // between the load and the store, e.g. in the case of a swap.
    Type *ShadowTypeIntTy = Type::getIntNTy(Context, 8 * LoadSizeBytes);
    Type *ShadowValueIntTy =
        Type::getIntNTy(Context, 8 * kShadowScale * LoadSizeBytes);
    IRBuilder<> LoadBuilder(Load->getNextNode());
    Builder.SetCurrentDebugLocation(Store.getDebugLoc());
    Value *LoadSrc = Load->getPointerOperand();
    // Read the shadow type and value at load time. The type has the same size
    // as the FT value, the value has twice its size.
    // TODO: cache them to avoid re-creating them when a load is used by
    // several stores. Maybe create them like the FT shadows when a load is
    // encountered.
    Value *RawShadowType = LoadBuilder.CreateAlignedLoad(
        ShadowTypeIntTy,
        LoadBuilder.CreateCall(NsanGetRawShadowTypePtr, {LoadSrc}), Align(1),
        /*isVolatile=*/false);
    Value *RawShadowValue = LoadBuilder.CreateAlignedLoad(
        ShadowValueIntTy,
        LoadBuilder.CreateCall(NsanGetRawShadowPtr, {LoadSrc}), Align(1),
        /*isVolatile=*/false);

    // Write back the shadow type and value at store time.
    Builder.CreateAlignedStore(
        RawShadowType, Builder.CreateCall(NsanGetRawShadowTypePtr, {Dst}),
        Align(1),
        /*isVolatile=*/false);
    Builder.CreateAlignedStore(RawShadowValue,
                               Builder.CreateCall(NsanGetRawShadowPtr, {Dst}),
                               Align(1),
                               /*isVolatile=*/false);

    ++NumInstrumentedNonFTMemcpyStores;
    return;
  }
  // ClPropagateNonFTConstStoresAsFT is by default false.
  if (Constant *C; ClPropagateNonFTConstStoresAsFT &&
                   (C = dyn_cast<Constant>(StoredValue))) {
    // This might be a fp constant stored as an int. Bitcast and store if it has
    // appropriate size.
    Type *BitcastTy = nullptr; // The FT type to bitcast to.
    if (auto *CInt = dyn_cast<ConstantInt>(C)) {
      switch (CInt->getType()->getScalarSizeInBits()) {
      case 32:
        BitcastTy = Type::getFloatTy(Context);
        break;
      case 64:
        BitcastTy = Type::getDoubleTy(Context);
        break;
      case 80:
        BitcastTy = Type::getX86_FP80Ty(Context);
        break;
      default:
        break;
      }
    } else if (auto *CDV = dyn_cast<ConstantDataVector>(C)) {
      const int NumElements =
          cast<VectorType>(CDV->getType())->getElementCount().getFixedValue();
      switch (CDV->getType()->getScalarSizeInBits()) {
      case 32:
        BitcastTy =
            VectorType::get(Type::getFloatTy(Context), NumElements, false);
        break;
      case 64:
        BitcastTy =
            VectorType::get(Type::getDoubleTy(Context), NumElements, false);
        break;
      case 80:
        BitcastTy =
            VectorType::get(Type::getX86_FP80Ty(Context), NumElements, false);
        break;
      default:
        break;
      }
    }
    if (BitcastTy) {
      const MemoryExtents Extents = getMemoryExtentsOrDie(BitcastTy);
      Value *ShadowPtr = Builder.CreateCall(
          NsanGetShadowPtrForStore[Extents.ValueType],
          {PtrOp, ConstantInt::get(IntptrTy, Extents.NumElts)});
      // Bitcast the integer value to the appropriate FT type and extend to 2FT.
      Type *ExtVT = Config.getExtendedFPType(BitcastTy);
      Value *Shadow =
          Builder.CreateFPExt(Builder.CreateBitCast(C, BitcastTy), ExtVT);
      Builder.CreateAlignedStore(Shadow, ShadowPtr, Align(1),
                                 Store.isVolatile());
      return;
    }
  }
  // All other stores just reset the shadow value to unknown.
  Builder.CreateCall(NsanSetUnknownFns.getFallback(), {Dst, ValueSize});
}

void NumericalStabilitySanitizer::propagateShadowValues(
    Instruction &Inst, const TargetLibraryInfo &TLI,
    const ValueToShadowMap &Map) {
  if (auto *Store = dyn_cast<StoreInst>(&Inst)) {
    Value *StoredValue = Store->getValueOperand();
    Type *VT = StoredValue->getType();
    Type *ExtendedVT = Config.getExtendedFPType(VT);
    if (ExtendedVT == nullptr)
      return propagateNonFTStore(*Store, VT, Map);
    return propagateFTStore(*Store, VT, ExtendedVT, Map);
  }

  if (auto *FCmp = dyn_cast<FCmpInst>(&Inst)) {
    emitFCmpCheck(*FCmp, Map);
    return;
  }

  if (auto *CB = dyn_cast<CallBase>(&Inst)) {
    maybeAddSuffixForNsanInterface(CB);
    if (CallInst *CI = dyn_cast<CallInst>(&Inst))
      maybeMarkSanitizerLibraryCallNoBuiltin(CI, &TLI);
    if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&Inst)) {
      instrumentMemIntrinsic(MI);
      return;
    }
    populateShadowStack(*CB, TLI, Map);
    return;
  }

  if (auto *RetInst = dyn_cast<ReturnInst>(&Inst)) {
    if (!ClCheckRet)
      return;

    Value *RV = RetInst->getReturnValue();
    if (RV == nullptr)
      return; // This is a `ret void`.
    Type *VT = RV->getType();
    Type *ExtendedVT = Config.getExtendedFPType(VT);
    if (ExtendedVT == nullptr)
      return; // Not an FT ret.
    Value *RVShadow = Map.getShadow(RV);
    IRBuilder<> Builder(RetInst);

    RVShadow = emitCheck(RV, RVShadow, Builder, CheckLoc::makeRet());
    ++NumInstrumentedFTRets;
    // Store tag.
    Value *FnAddr =
        Builder.CreatePtrToInt(Inst.getParent()->getParent(), IntptrTy);
    Builder.CreateStore(FnAddr, NsanShadowRetTag);
    // Store value.
    Value *ShadowRetValPtr =
        Builder.CreateConstGEP2_64(NsanShadowRetType, NsanShadowRetPtr, 0, 0);
    Builder.CreateStore(RVShadow, ShadowRetValPtr);
    return;
  }

  if (InsertValueInst *Insert = dyn_cast<InsertValueInst>(&Inst)) {
    Value *V = Insert->getOperand(1);
    Type *VT = V->getType();
    Type *ExtendedVT = Config.getExtendedFPType(VT);
    if (ExtendedVT == nullptr)
      return;
    IRBuilder<> Builder(Insert);
    emitCheck(V, Map.getShadow(V), Builder, CheckLoc::makeInsert());
    return;
  }
}

// Moves fast math flags from the function to individual instructions, and
// removes the attribute from the function.
// TODO: Make this controllable with a flag.
static void moveFastMathFlags(Function &F,
                              std::vector<Instruction *> &Instructions) {
  FastMathFlags FMF;
#define MOVE_FLAG(attr, setter)                                                \
  if (F.getFnAttribute(attr).getValueAsString() == "true") {                   \
    F.removeFnAttr(attr);                                                      \
    FMF.set##setter();                                                         \
  }
  MOVE_FLAG("unsafe-fp-math", Fast)
  MOVE_FLAG("no-infs-fp-math", NoInfs)
  MOVE_FLAG("no-nans-fp-math", NoNaNs)
  MOVE_FLAG("no-signed-zeros-fp-math", NoSignedZeros)
#undef MOVE_FLAG

  for (Instruction *I : Instructions)
    if (isa<FPMathOperator>(I))
      I->setFastMathFlags(FMF);
}

bool NumericalStabilitySanitizer::sanitizeFunction(
    Function &F, const TargetLibraryInfo &TLI) {
  if (!F.hasFnAttribute(Attribute::SanitizeNumericalStability) ||
      F.isDeclaration())
    return false;

  // This is required to prevent instrumenting call to __nsan_init from within
  // the module constructor.
  if (F.getName() == kNsanModuleCtorName)
    return false;

  // The instrumentation maintains:
  //  - for each IR value `v` of floating-point (or vector floating-point) type
  //    FT, a shadow IR value `s(v)` with twice the precision 2FT (e.g.
  //    double for float and f128 for double).
  //  - A shadow memory, which stores `s(v)` for any `v` that has been stored,
  //    along with a shadow memory tag, which stores whether the value in the
  //    corresponding shadow memory is valid. Note that this might be
  //    incorrect if a non-instrumented function stores to memory, or if
  //    memory is stored to through a char pointer.
  //  - A shadow stack, which holds `s(v)` for any floating-point argument `v`
  //    of a call to an instrumented function. This allows
  //    instrumented functions to retrieve the shadow values for their
  //    arguments.
  //    Because instrumented functions can be called from non-instrumented
  //    functions, the stack needs to include a tag so that the instrumented
  //    function knows whether shadow values are available for their
  //    parameters (i.e. whether is was called by an instrumented function).
  //    When shadow arguments are not available, they have to be recreated by
  //    extending the precision of the non-shadow arguments to the non-shadow
  //    value. Non-instrumented functions do not modify (or even know about) the
  //    shadow stack. The shadow stack pointer is __nsan_shadow_args. The shadow
  //    stack tag is __nsan_shadow_args_tag. The tag is any unique identifier
  //    for the function (we use the address of the function). Both variables
  //    are thread local.
  //    Example:
  //     calls                             shadow stack tag      shadow stack
  //     =======================================================================
  //     non_instrumented_1()              0                     0
  //             |
  //             v
  //     instrumented_2(float a)           0                     0
  //             |
  //             v
  //     instrumented_3(float b, double c) &instrumented_3       s(b),s(c)
  //             |
  //             v
  //     instrumented_4(float d)           &instrumented_4       s(d)
  //             |
  //             v
  //     non_instrumented_5(float e)       &non_instrumented_5   s(e)
  //             |
  //             v
  //     instrumented_6(float f)           &non_instrumented_5   s(e)
  //
  //   On entry, instrumented_2 checks whether the tag corresponds to its
  //   function ptr.
  //   Note that functions reset the tag to 0 after reading shadow parameters.
  //   This ensures that the function does not erroneously read invalid data if
  //   called twice in the same stack, once from an instrumented function and
  //   once from an uninstrumented one. For example, in the following example,
  //   resetting the tag in (A) ensures that (B) does not reuse the same the
  //   shadow arguments (which would be incorrect).
  //      instrumented_1(float a)
  //             |
  //             v
  //      instrumented_2(float b)  (A)
  //             |
  //             v
  //      non_instrumented_3()
  //             |
  //             v
  //      instrumented_2(float b)  (B)
  //
  //  - A shadow return slot. Any function that returns a floating-point value
  //    places a shadow return value in __nsan_shadow_ret_val. Again, because
  //    we might be calling non-instrumented functions, this value is guarded
  //    by __nsan_shadow_ret_tag marker indicating which instrumented function
  //    placed the value in __nsan_shadow_ret_val, so that the caller can check
  //    that this corresponds to the callee. Both variables are thread local.
  //
  //    For example, in the following example, the instrumentation in
  //    `instrumented_1` rejects the shadow return value from `instrumented_3`
  //    because is is not tagged as expected (`&instrumented_3` instead of
  //    `non_instrumented_2`):
  //
  //        instrumented_1()
  //            |
  //            v
  //        float non_instrumented_2()
  //            |
  //            v
  //        float instrumented_3()
  //
  // Calls of known math functions (sin, cos, exp, ...) are duplicated to call
  // their overload on the shadow type.

  // Collect all instructions before processing, as creating shadow values
  // creates new instructions inside the function.
  std::vector<Instruction *> OriginalInstructions;
  for (BasicBlock &BB : F)
    for (Instruction &Inst : BB)
      OriginalInstructions.emplace_back(&Inst);

  moveFastMathFlags(F, OriginalInstructions);
  ValueToShadowMap ValueToShadow(Config);

  // In the first pass, we create shadow values for all FT function arguments
  // and all phis. This ensures that the DFS of the next pass does not have
  // any loops.
  std::vector<PHINode *> OriginalPhis;
  createShadowArguments(F, TLI, ValueToShadow);
  for (Instruction *I : OriginalInstructions) {
    if (PHINode *Phi = dyn_cast<PHINode>(I)) {
      if (PHINode *Shadow = maybeCreateShadowPhi(*Phi, TLI)) {
        OriginalPhis.push_back(Phi);
        ValueToShadow.setShadow(*Phi, *Shadow);
      }
    }
  }

  // Create shadow values for all instructions creating FT values.
  for (Instruction *I : OriginalInstructions)
    maybeCreateShadowValue(*I, TLI, ValueToShadow);

  // Propagate shadow values across stores, calls and rets.
  for (Instruction *I : OriginalInstructions)
    propagateShadowValues(*I, TLI, ValueToShadow);

  // The last pass populates shadow phis with shadow values.
  for (PHINode *Phi : OriginalPhis) {
    PHINode *ShadowPhi = cast<PHINode>(ValueToShadow.getShadow(Phi));
    for (unsigned I : seq(Phi->getNumOperands())) {
      Value *V = Phi->getOperand(I);
      Value *Shadow = ValueToShadow.getShadow(V);
      BasicBlock *IncomingBB = Phi->getIncomingBlock(I);
      // For some instructions (e.g. invoke), we create the shadow in a separate
      // block, different from the block where the original value is created.
      // In that case, the shadow phi might need to refer to this block instead
      // of the original block.
      // Note that this can only happen for instructions as constant shadows are
      // always created in the same block.
      ShadowPhi->addIncoming(Shadow, IncomingBB);
    }
  }

  return !ValueToShadow.empty();
}

static uint64_t GetMemOpSize(Value *V) {
  uint64_t OpSize = 0;
  if (Constant *C = dyn_cast<Constant>(V)) {
    auto *CInt = dyn_cast<ConstantInt>(C);
    if (CInt && CInt->getValue().getBitWidth() <= 64)
      OpSize = CInt->getValue().getZExtValue();
  }

  return OpSize;
}

// Instrument the memory intrinsics so that they properly modify the shadow
// memory.
bool NumericalStabilitySanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
  IRBuilder<> Builder(MI);
  if (auto *M = dyn_cast<MemSetInst>(MI)) {
    FunctionCallee SetUnknownFn =
        NsanSetUnknownFns.getFunctionFor(GetMemOpSize(M->getArgOperand(2)));
    if (SetUnknownFn.getFunctionType()->getNumParams() == 1)
      Builder.CreateCall(SetUnknownFn, {/*Address=*/M->getArgOperand(0)});
    else
      Builder.CreateCall(SetUnknownFn,
                         {/*Address=*/M->getArgOperand(0),
                          /*Size=*/Builder.CreateIntCast(M->getArgOperand(2),
                                                         IntptrTy, false)});

  } else if (auto *M = dyn_cast<MemTransferInst>(MI)) {
    FunctionCallee CopyFn =
        NsanCopyFns.getFunctionFor(GetMemOpSize(M->getArgOperand(2)));

    if (CopyFn.getFunctionType()->getNumParams() == 2)
      Builder.CreateCall(CopyFn, {/*Destination=*/M->getArgOperand(0),
                                  /*Source=*/M->getArgOperand(1)});
    else
      Builder.CreateCall(CopyFn, {/*Destination=*/M->getArgOperand(0),
                                  /*Source=*/M->getArgOperand(1),
                                  /*Size=*/
                                  Builder.CreateIntCast(M->getArgOperand(2),
                                                        IntptrTy, false)});
  }
  return false;
}

void NumericalStabilitySanitizer::maybeAddSuffixForNsanInterface(CallBase *CI) {
  Function *Fn = CI->getCalledFunction();
  if (Fn == nullptr)
    return;

  if (!Fn->getName().starts_with("__nsan_"))
    return;

  if (Fn->getName() == "__nsan_dump_shadow_mem") {
    assert(CI->arg_size() == 4 &&
           "invalid prototype for __nsan_dump_shadow_mem");
    // __nsan_dump_shadow_mem requires an extra parameter with the dynamic
    // configuration:
    // (shadow_type_id_for_long_double << 16) | (shadow_type_id_for_double << 8)
    // | shadow_type_id_for_double
    const uint64_t shadow_value_type_ids =
        (static_cast<size_t>(Config.byValueType(kLongDouble).getNsanTypeId())
         << 16) |
        (static_cast<size_t>(Config.byValueType(kDouble).getNsanTypeId())
         << 8) |
        static_cast<size_t>(Config.byValueType(kFloat).getNsanTypeId());
    CI->setArgOperand(3, ConstantInt::get(IntptrTy, shadow_value_type_ids));
  }
}
