47#define DEBUG_TYPE "nsan"
50 "Number of instrumented floating-point loads");
53 "Number of instrumented floating-point calls");
55 "Number of instrumented floating-point returns");
57 "Number of instrumented floating-point stores");
59 "Number of instrumented non floating-point stores");
61 NumInstrumentedNonFTMemcpyStores,
62 "Number of instrumented non floating-point stores with memcpy semantics");
63STATISTIC(NumInstrumentedFCmp,
"Number of instrumented fcmps");
78class ShadowTypeConfig {
80 static std::unique_ptr<ShadowTypeConfig> fromNsanTypeId(
char TypeId);
86 virtual char getNsanTypeId()
const = 0;
88 virtual ~ShadowTypeConfig() =
default;
91template <
char NsanTypeId>
92class ShadowTypeConfigImpl :
public ShadowTypeConfig {
94 char getNsanTypeId()
const override {
return NsanTypeId; }
95 static constexpr char kNsanTypeId = NsanTypeId;
99class F64ShadowConfig :
public ShadowTypeConfigImpl<'d'> {
106class F80ShadowConfig :
public ShadowTypeConfigImpl<'l'> {
113class F128ShadowConfig :
public ShadowTypeConfigImpl<'q'> {
120class PPC128ShadowConfig :
public ShadowTypeConfigImpl<'e'> {
127std::unique_ptr<ShadowTypeConfig>
128ShadowTypeConfig::fromNsanTypeId(
const char TypeId) {
130 case F64ShadowConfig::kNsanTypeId:
131 return std::make_unique<F64ShadowConfig>();
132 case F80ShadowConfig::kNsanTypeId:
133 return std::make_unique<F80ShadowConfig>();
134 case F128ShadowConfig::kNsanTypeId:
135 return std::make_unique<F128ShadowConfig>();
136 case PPC128ShadowConfig::kNsanTypeId:
137 return std::make_unique<PPC128ShadowConfig>();
144enum FTValueType { kFloat, kDouble, kLongDouble, kNumValueTypes };
147static std::optional<FTValueType> ftValueTypeFromType(
Type *FT) {
158static Type *typeFromFTValueType(FTValueType VT,
LLVMContext &Context) {
173static const char *typeNameFromFTValueType(FTValueType VT) {
191 MappingConfig(
const InstrumentationOptions &Opts,
LLVMContext &
C)
193 if (Opts.nsan_shadow_type_mapping.size() != 3)
195 Twine(Opts.nsan_shadow_type_mapping));
196 unsigned ShadowTypeSizeBits[kNumValueTypes];
197 for (
int VT = 0; VT < kNumValueTypes; ++VT) {
199 ShadowTypeConfig::fromNsanTypeId(Opts.nsan_shadow_type_mapping[VT]);
202 Twine(Opts.nsan_shadow_type_mapping[VT]));
203 const unsigned AppTypeSize =
204 typeFromFTValueType(
static_cast<FTValueType
>(VT), Context)
205 ->getScalarSizeInBits();
206 const unsigned ShadowTypeSize =
207 Config->getType(Context)->getScalarSizeInBits();
212 "->f" +
Twine(ShadowTypeSize) +
213 ": The shadow type size should be at most " +
215 " times the application type size");
216 ShadowTypeSizeBits[VT] = ShadowTypeSize;
217 Configs[VT] = std::move(Config);
226 if (ShadowTypeSizeBits[kFloat] > ShadowTypeSizeBits[kDouble] ||
227 ShadowTypeSizeBits[kDouble] > ShadowTypeSizeBits[kLongDouble])
229 Twine(ShadowTypeSizeBits[kFloat]) +
"; double->f" +
230 Twine(ShadowTypeSizeBits[kDouble]) +
232 Twine(ShadowTypeSizeBits[kLongDouble]) +
" }");
235 const ShadowTypeConfig &byValueType(FTValueType VT)
const {
236 assert(VT < FTValueType::kNumValueTypes &&
"invalid value type");
241 Type *getExtendedFPType(
Type *FT)
const {
242 if (
const auto VT = ftValueTypeFromType(FT))
243 return Configs[*VT]->getType(Context);
247 if (VecTy->isScalableTy())
249 Type *ExtendedScalar = getExtendedFPType(VecTy->getElementType());
250 return ExtendedScalar
259 std::unique_ptr<ShadowTypeConfig> Configs[FTValueType::kNumValueTypes];
264struct MemoryExtents {
269static MemoryExtents getMemoryExtentsOrDie(
Type *FT) {
270 if (
const auto VT = ftValueTypeFromType(FT))
273 const auto ScalarExtents = getMemoryExtentsOrDie(VecTy->getElementType());
274 return {ScalarExtents.ValueType,
275 ScalarExtents.NumElts * VecTy->getElementCount().getFixedValue()};
284 static CheckLoc makeStore(
Value *Address) {
285 CheckLoc Result(kStore);
286 Result.Address = Address;
289 static CheckLoc makeLoad(
Value *Address) {
290 CheckLoc Result(kLoad);
291 Result.Address = Address;
296 static CheckLoc makeArg(
int ArgId) {
297 CheckLoc Result(kArg);
298 Result.ArgId = ArgId;
303 static CheckLoc makeRet() {
return CheckLoc(kRet); }
306 static CheckLoc makeInsert() {
return CheckLoc(kInsert); }
323 return ConstantInt::get(IntptrTy, 0);
325 return ConstantInt::get(IntptrTy, ArgId);
328 return Builder.CreatePtrToInt(Address, IntptrTy);
344 explicit CheckLoc(
CheckType CheckTy) : CheckTy(CheckTy) {}
346 Value *Address =
nullptr;
352class ValueToShadowMap {
354 explicit ValueToShadowMap(
const MappingConfig &Config) : Config(Config) {}
356 ValueToShadowMap(
const ValueToShadowMap &) =
delete;
357 ValueToShadowMap &operator=(
const ValueToShadowMap &) =
delete;
362 [[maybe_unused]]
const bool Inserted = Map.
try_emplace(&V, &Shadow).second;
366 errs() <<
I->getFunction()->getName() <<
": ";
367 errs() <<
"duplicate shadow (" << &V <<
"): ";
371 assert(Inserted &&
"duplicate shadow");
382 return getShadowConstant(
C);
383 return Map.
find(V)->second;
386 bool empty()
const {
return Map.
empty(); }
391 bool LosesInfo =
false;
403 Type *Ty = Config.getExtendedFPType(CFP->getType());
404 return ConstantFP::get(
405 Ty, extendConstantFP(CFP->getValueAPF(),
406 Ty->getScalarType()->getFltSemantics()));
409 if (
C->getType()->isVectorTy()) {
415 Elements.push_back(getShadowConstant(
C->getAggregateElement(
I)));
421 const MappingConfig &Config;
434 size_t NumSizedFuncs;
441 Attr = Attr.addFnAttribute(Ctx, Attribute::NoUnwind);
444 IntegerType *IntptrTy = M.getDataLayout().getIntPtrType(Ctx);
447 NumSizedFuncs = Sized.
size();
452 M.getOrInsertFunction(
Fallback, Attr, VoidTy, PtrTy, PtrTy, IntptrTy));
454 }
else if (NumArgs == 2) {
456 M.getOrInsertFunction(
Fallback, Attr, VoidTy, PtrTy, IntptrTy));
462 for (
size_t i = 0; i < NumSizedFuncs; ++i)
463 Funcs.push_back(M.getOrInsertFunction(Sized[i], SizedFnTy, Attr));
469 assert(NumSizedFuncs >= 3 &&
"Unexpected number of sized functions");
472 MemOpSize == 4 ? 1 : (MemOpSize == 8 ? 2 : (MemOpSize == 16 ? 3 : 0));
477FunctionCallee NsanMemOpFn::getFallback()
const {
return Funcs[0]; }
483class NumericalStabilitySanitizer {
485 NumericalStabilitySanitizer(
const InstrumentationOptions &Opts,
Module &M);
490 void maybeAddSuffixForNsanInterface(
CallBase *CI);
491 bool addrPointsToConstantData(
Value *Addr);
493 ValueToShadowMap &Map);
496 const ValueToShadowMap &Map);
499 ValueToShadowMap &Map);
502 const ValueToShadowMap &Map);
505 const ValueToShadowMap &Map);
510 void emitFCmpCheck(
FCmpInst &FCmp,
const ValueToShadowMap &Map);
516 const ValueToShadowMap &Map,
IRBuilder<> &Builder);
519 const ValueToShadowMap &Map,
522 const ValueToShadowMap &Map,
IRBuilder<> &Builder);
524 const ValueToShadowMap &Map,
IRBuilder<> &Builder);
528 const ValueToShadowMap &Map);
530 const ValueToShadowMap &Map);
532 const InstrumentationOptions &Opts;
535 MappingConfig Config;
539 FunctionCallee NsanGetShadowPtrForStore[FTValueType::kNumValueTypes] = {};
540 FunctionCallee NsanGetShadowPtrForLoad[FTValueType::kNumValueTypes] = {};
544 NsanMemOpFn NsanCopyFns;
545 NsanMemOpFn NsanSetUnknownFns;
551 Type *NsanShadowRetType =
nullptr;
556 Type *NsanShadowArgsType =
nullptr;
559 std::optional<Regex> CheckFunctionsFilter;
572 NumericalStabilitySanitizer Nsan(InstrumentationOptions::Global, M);
581 return M.getOrInsertGlobal(Name, Ty, [&M, Ty, Name] {
583 nullptr, Name,
nullptr,
588NumericalStabilitySanitizer::NumericalStabilitySanitizer(
589 const InstrumentationOptions &Opts,
Module &M)
592 NsanCopyFns(
M, {
"__nsan_copy_4",
"__nsan_copy_8",
"__nsan_copy_16"},
593 "__nsan_copy_values", 3),
595 {
"__nsan_set_value_unknown_4",
596 "__nsan_set_value_unknown_8",
597 "__nsan_set_value_unknown_16"},
598 "__nsan_set_value_unknown", 2) {
599 IntptrTy =
DL.getIntPtrType(Context);
606 Attr = Attr.addFnAttribute(Context, Attribute::NoUnwind);
608 for (
int I = 0;
I < kNumValueTypes; ++
I) {
609 const FTValueType VT =
static_cast<FTValueType
>(
I);
610 const char *VTName = typeNameFromFTValueType(VT);
611 Type *VTTy = typeFromFTValueType(VT, Context);
614 const std::string GetterPrefix =
615 std::string(
"__nsan_get_shadow_ptr_for_") + VTName;
616 NsanGetShadowPtrForStore[VT] = M.getOrInsertFunction(
617 GetterPrefix +
"_store", Attr, PtrTy, PtrTy, IntptrTy);
618 NsanGetShadowPtrForLoad[VT] = M.getOrInsertFunction(
619 GetterPrefix +
"_load", Attr, PtrTy, PtrTy, IntptrTy);
622 const auto &ShadowConfig = Config.byValueType(VT);
623 Type *ShadowTy = ShadowConfig.getType(Context);
625 M.getOrInsertFunction(std::string(
"__nsan_internal_check_") + VTName +
626 "_" + ShadowConfig.getNsanTypeId(),
627 Attr, Int32Ty, VTTy, ShadowTy, Int32Ty, IntptrTy);
628 NsanFCmpFail[VT] = M.getOrInsertFunction(
629 std::string(
"__nsan_fcmp_fail_") + VTName +
"_" +
630 ShadowConfig.getNsanTypeId(),
631 Attr, VoidTy, VTTy, VTTy, ShadowTy, ShadowTy, Int32Ty, Int1Ty, Int1Ty);
635 NsanGetRawShadowTypePtr = M.getOrInsertFunction(
636 "__nsan_internal_get_raw_shadow_type_ptr", Attr, PtrTy, PtrTy);
637 NsanGetRawShadowPtr = M.getOrInsertFunction(
638 "__nsan_internal_get_raw_shadow_ptr", Attr, PtrTy, PtrTy);
657 if (!Opts.check_functions_filter.empty()) {
659 std::string RegexError;
661 CheckFunctionsFilter = std::move(R);
667bool NumericalStabilitySanitizer::addrPointsToConstantData(
Value *Addr) {
670 Addr =
GEP->getPointerOperand();
673 return GV->isConstant();
689void NumericalStabilitySanitizer::createShadowArguments(
690 Function &
F,
const TargetLibraryInfo &TLI, ValueToShadowMap &Map) {
691 assert(!
F.getIntrinsicID() &&
"found a definition of an intrinsic");
694 if (
all_of(
F.args(), [
this](
const Argument &Arg) {
695 return Config.getExtendedFPType(Arg.getType()) == nullptr;
699 IRBuilder<> Builder(
F.getEntryBlock().getFirstNonPHIIt());
702 Value *HasShadowArgs = Builder.CreateICmpEQ(
703 Builder.CreateLoad(IntptrTy, NsanShadowArgsTag,
false),
704 Builder.CreatePtrToInt(&
F, IntptrTy));
706 unsigned ShadowArgsOffsetBytes = 0;
707 for (Argument &Arg :
F.args()) {
709 Type *ExtendedVT = Config.getExtendedFPType(VT);
710 if (ExtendedVT ==
nullptr)
712 Value *
L = Builder.CreateAlignedLoad(
714 Builder.CreateConstGEP2_64(NsanShadowArgsType, NsanShadowArgsPtr, 0,
715 ShadowArgsOffsetBytes),
717 Value *Shadow = Builder.CreateSelect(HasShadowArgs, L,
718 Builder.CreateFPExt(&Arg, ExtendedVT));
719 Map.setShadow(Arg, *Shadow);
720 TypeSize SlotSize =
DL.getTypeStoreSize(ExtendedVT);
722 ShadowArgsOffsetBytes += SlotSize;
724 Builder.CreateStore(ConstantInt::get(IntptrTy, 0), NsanShadowArgsTag);
730 const std::optional<Regex> &CheckFunctionsFilter) {
734 if (CheckFunctionsFilter) {
738 if (CheckFunctionsFilter->match(Fn->
getName()))
759 if (ID == Intrinsic::fabs || LFunc == LibFunc_fabsf ||
760 LFunc == LibFunc_fabs || LFunc == LibFunc_fabsl)
761 for (
const auto &U : CI.
users())
770void NumericalStabilitySanitizer::populateShadowStack(
771 CallBase &CI,
const TargetLibraryInfo &TLI,
const ValueToShadowMap &Map) {
778 return Config.getExtendedFPType(Arg->getType()) == nullptr;
783 SmallVector<Value *, 8> ArgShadows;
784 const bool ShouldCheckArgs =
shouldCheckArgs(CI, TLI, CheckFunctionsFilter);
786 if (Config.getExtendedFPType(Arg->
getType()) ==
nullptr)
788 Value *ArgShadow =
Map.getShadow(Arg);
789 ArgShadows.
push_back(ShouldCheckArgs ? emitCheck(Arg, ArgShadow, Builder,
790 CheckLoc::makeArg(ArgIdx))
796 if (Fn->isIntrinsic() || TLI.
getLibFunc(*Fn) != NotLibFunc)
804 unsigned ShadowArgId = 0;
807 Type *ExtendedVT = Config.getExtendedFPType(VT);
808 if (ExtendedVT ==
nullptr)
810 Builder.CreateAlignedStore(
811 ArgShadows[ShadowArgId++],
812 Builder.CreateConstGEP2_64(NsanShadowArgsType, NsanShadowArgsPtr, 0,
813 ShadowArgsOffsetBytes),
815 TypeSize SlotSize =
DL.getTypeStoreSize(ExtendedVT);
817 ShadowArgsOffsetBytes += SlotSize;
829Value *NumericalStabilitySanitizer::emitCheckInternal(
Value *V,
Value *ShadowV,
834 return ConstantInt::get(
838 Type *Ty =
V->getType();
839 if (
const auto VT = ftValueTypeFromType(Ty))
842 {
V, ShadowV, Loc.getType(
Context), Loc.getValue(IntptrTy, Builder)});
848 assert(!VecTy->isScalableTy() &&
849 "Scalable vector types are not supported yet");
850 Value *CheckResult =
nullptr;
851 for (
int I = 0,
E = VecTy->getElementCount().getFixedValue();
I <
E; ++
I) {
857 Value *ComponentCheckResult =
858 emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc);
859 CheckResult = CheckResult
860 ? Builder.
CreateOr(CheckResult, ComponentCheckResult)
861 : ComponentCheckResult;
866 Value *CheckResult =
nullptr;
870 Value *ComponentCheckResult =
871 emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc);
872 CheckResult = CheckResult
873 ? Builder.
CreateOr(CheckResult, ComponentCheckResult)
874 : ComponentCheckResult;
879 Value *CheckResult =
nullptr;
885 Value *ComponentCheckResult =
886 emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc);
887 CheckResult = CheckResult
888 ? Builder.
CreateOr(CheckResult, ComponentCheckResult)
889 : ComponentCheckResult;
892 return ConstantInt::get(
916 if (CheckFunctionsFilter && !CheckFunctionsFilter->match(
F->getName())) {
921 Value *CheckResult = emitCheckInternal(V, ShadowV, Builder, Loc);
927 ICmpEQ, Builder.
CreateFPExt(V, Config.getExtendedFPType(
V->getType())),
933void NumericalStabilitySanitizer::emitFCmpCheck(FCmpInst &FCmp,
934 const ValueToShadowMap &Map) {
935 if (!Opts.nsan_instrument_fcmp)
939 if (CheckFunctionsFilter && !CheckFunctionsFilter->match(
F->getName()))
943 if (Config.getExtendedFPType(
LHS->
getType()) ==
nullptr)
958 FCmpBuilder.SetCurrentDebugLocation(FCmp.
getDebugLoc());
962 if (FCmp.
isEquality() && Opts.nsan_truncate_fcmp_eq) {
964 ShadowLHS = FCmpBuilder.CreateFPExt(
965 FCmpBuilder.CreateFPTrunc(ShadowLHS,
LHS->
getType()), Ty);
966 ShadowRHS = FCmpBuilder.CreateFPExt(
967 FCmpBuilder.CreateFPTrunc(ShadowRHS,
RHS->
getType()), Ty);
970 FCmpBuilder.CreateFCmp(FCmp.
getPredicate(), ShadowLHS, ShadowRHS);
971 Value *OriginalAndShadowFcmpMatch =
972 FCmpBuilder.CreateICmpEQ(&FCmp, ShadowFCmp);
978 OriginalAndShadowFcmpMatch =
979 FCmpBuilder.CreateAndReduce(OriginalAndShadowFcmpMatch);
984 FCmpBuilder.CreateCondBr(OriginalAndShadowFcmpMatch, NextBB, FailBB,
985 MDBuilder(
Context).createLikelyBranchWeights());
989 FailBuilder.SetCurrentDebugLocation(FCmp.
getDebugLoc());
991 const auto EmitFailCall = [
this, &FCmp, &FCmpBuilder,
994 Value *ShadowResult) {
995 Type *FT =
L->getType();
996 FunctionCallee *
Callee =
nullptr;
998 Callee = &(NsanFCmpFail[kFloat]);
1000 Callee = &(NsanFCmpFail[kDouble]);
1003 Callee = &(NsanFCmpFail[kDouble]);
1004 L = FailBuilder.CreateFPTrunc(L, Type::getDoubleTy(
Context));
1005 R = FailBuilder.CreateFPTrunc(L, Type::getDoubleTy(
Context));
1009 FailBuilder.CreateCall(*Callee, {
L,
R, ShadowL, ShadowR,
1010 ConstantInt::get(FCmpBuilder.getInt32Ty(),
1019 Value *ExtractLHS = FailBuilder.CreateExtractElement(
LHS,
I);
1020 Value *ExtractRHS = FailBuilder.CreateExtractElement(
RHS,
I);
1021 Value *ExtractShaodwLHS = FailBuilder.CreateExtractElement(ShadowLHS,
I);
1022 Value *ExtractShaodwRHS = FailBuilder.CreateExtractElement(ShadowRHS,
I);
1023 Value *ExtractFCmp = FailBuilder.CreateExtractElement(&FCmp,
I);
1024 Value *ExtractShadowFCmp =
1025 FailBuilder.CreateExtractElement(ShadowFCmp,
I);
1026 EmitFailCall(ExtractLHS, ExtractRHS, ExtractShaodwLHS, ExtractShaodwRHS,
1027 ExtractFCmp, ExtractShadowFCmp);
1030 EmitFailCall(
LHS,
RHS, ShadowLHS, ShadowRHS, &FCmp, ShadowFCmp);
1032 FailBuilder.CreateBr(NextBB);
1034 ++NumInstrumentedFCmp;
1038PHINode *NumericalStabilitySanitizer::maybeCreateShadowPhi(
1039 PHINode &Phi,
const TargetLibraryInfo &TLI) {
1041 Type *ExtendedVT = Config.getExtendedFPType(VT);
1042 if (ExtendedVT ==
nullptr)
1052Value *NumericalStabilitySanitizer::handleLoad(LoadInst &
Load,
Type *VT,
1056 if (addrPointsToConstantData(
Load.getPointerOperand())) {
1076 const auto Extents = getMemoryExtentsOrDie(VT);
1078 NsanGetShadowPtrForLoad[Extents.ValueType],
1079 {Load.getPointerOperand(), ConstantInt::get(IntptrTy, Extents.NumElts)});
1080 ++NumInstrumentedFTLoads;
1096 LoadBBBuilder.SetCurrentDebugLocation(
Load.getDebugLoc());
1097 LoadBBBuilder.CreateCondBr(LoadBBBuilder.CreateIsNull(ShadowPtr), FExtBB,
1103 ShadowLoadBBBuilder.SetCurrentDebugLocation(
Load.getDebugLoc());
1104 Value *ShadowLoad = ShadowLoadBBBuilder.CreateAlignedLoad(
1105 ExtendedVT, ShadowPtr,
Align(1),
Load.isVolatile());
1106 if (Opts.nsan_check_loads) {
1107 ShadowLoad = emitCheck(&
Load, ShadowLoad, ShadowLoadBBBuilder,
1108 CheckLoc::makeLoad(
Load.getPointerOperand()));
1110 ShadowLoadBBBuilder.CreateBr(NextBB);
1114 FExtBBBuilder.SetCurrentDebugLocation(
Load.getDebugLoc());
1115 Value *FExt = FExtBBBuilder.CreateFPExt(&
Load, ExtendedVT);
1116 FExtBBBuilder.CreateBr(NextBB);
1120 NextBBBuilder.SetCurrentDebugLocation(
Load.getDebugLoc());
1121 PHINode *ShadowPhi = NextBBBuilder.CreatePHI(ExtendedVT, 2);
1127Value *NumericalStabilitySanitizer::handleTrunc(
const FPTruncInst &Trunc,
1129 const ValueToShadowMap &Map,
1133 Type *ExtendedSourceTy = Config.getExtendedFPType(OrigSourceTy);
1166 Value *
Source = ExtendedSourceTy ?
Map.getShadow(OrigSource) : OrigSource;
1167 Type *SourceTy = ExtendedSourceTy ? ExtendedSourceTy : OrigSourceTy;
1169 if (SourceTy == ExtendedVT)
1175Value *NumericalStabilitySanitizer::handleExt(
const FPExtInst &Ext,
Type *VT,
1177 const ValueToShadowMap &Map,
1181 Type *ExtendedSourceTy = Config.getExtendedFPType(OrigSourceTy);
1213 Value *
Source = ExtendedSourceTy ?
Map.getShadow(OrigSource) : OrigSource;
1214 Type *SourceTy = ExtendedSourceTy ? ExtendedSourceTy : OrigSourceTy;
1216 if (SourceTy == ExtendedVT)
1224struct KnownIntrinsic {
1225 struct WidenedIntrinsic {
1226 const char *NarrowName;
1228 using FnTypeFactory = FunctionType *(*)(LLVMContext &);
1229 FnTypeFactory MakeFnTy;
1232 static const char *
get(LibFunc LFunc);
1239 static const WidenedIntrinsic *widen(StringRef Name);
1244 const char *IntrinsicName;
1246 static const LFEntry kLibfuncIntrinsics[];
1248 static const WidenedIntrinsic kWidenedIntrinsics[];
1297const KnownIntrinsic::WidenedIntrinsic KnownIntrinsic::kWidenedIntrinsics[] = {
1386const KnownIntrinsic::LFEntry KnownIntrinsic::kLibfuncIntrinsics[] = {
1387 {LibFunc_sqrtf,
"llvm.sqrt.f32"},
1388 {LibFunc_sqrt,
"llvm.sqrt.f64"},
1389 {LibFunc_sqrtl,
"llvm.sqrt.f80"},
1390 {LibFunc_sinf,
"llvm.sin.f32"},
1391 {LibFunc_sin,
"llvm.sin.f64"},
1392 {LibFunc_sinl,
"llvm.sin.f80"},
1393 {LibFunc_cosf,
"llvm.cos.f32"},
1394 {LibFunc_cos,
"llvm.cos.f64"},
1395 {LibFunc_cosl,
"llvm.cos.f80"},
1396 {LibFunc_powf,
"llvm.pow.f32"},
1397 {LibFunc_pow,
"llvm.pow.f64"},
1398 {LibFunc_powl,
"llvm.pow.f80"},
1399 {LibFunc_expf,
"llvm.exp.f32"},
1400 {LibFunc_exp,
"llvm.exp.f64"},
1401 {LibFunc_expl,
"llvm.exp.f80"},
1402 {LibFunc_exp2f,
"llvm.exp2.f32"},
1403 {LibFunc_exp2,
"llvm.exp2.f64"},
1404 {LibFunc_exp2l,
"llvm.exp2.f80"},
1405 {LibFunc_logf,
"llvm.log.f32"},
1406 {LibFunc_log,
"llvm.log.f64"},
1407 {LibFunc_logl,
"llvm.log.f80"},
1408 {LibFunc_log10f,
"llvm.log10.f32"},
1409 {LibFunc_log10,
"llvm.log10.f64"},
1410 {LibFunc_log10l,
"llvm.log10.f80"},
1411 {LibFunc_log2f,
"llvm.log2.f32"},
1412 {LibFunc_log2,
"llvm.log2.f64"},
1413 {LibFunc_log2l,
"llvm.log2.f80"},
1414 {LibFunc_fabsf,
"llvm.fabs.f32"},
1415 {LibFunc_fabs,
"llvm.fabs.f64"},
1416 {LibFunc_fabsl,
"llvm.fabs.f80"},
1417 {LibFunc_copysignf,
"llvm.copysign.f32"},
1418 {LibFunc_copysign,
"llvm.copysign.f64"},
1419 {LibFunc_copysignl,
"llvm.copysign.f80"},
1420 {LibFunc_floorf,
"llvm.floor.f32"},
1421 {LibFunc_floor,
"llvm.floor.f64"},
1422 {LibFunc_floorl,
"llvm.floor.f80"},
1423 {LibFunc_fmaxf,
"llvm.maxnum.f32"},
1424 {LibFunc_fmax,
"llvm.maxnum.f64"},
1425 {LibFunc_fmaxl,
"llvm.maxnum.f80"},
1426 {LibFunc_fminf,
"llvm.minnum.f32"},
1427 {LibFunc_fmin,
"llvm.minnum.f64"},
1428 {LibFunc_fminl,
"llvm.minnum.f80"},
1429 {LibFunc_fmaximum_numf,
"llvm.maximumnum.f32"},
1430 {LibFunc_fmaximum_num,
"llvm.maximumnum.f64"},
1431 {LibFunc_fmaximum_numl,
"llvm.maximumnum.f80"},
1432 {LibFunc_fminimum_numf,
"llvm.minimumnum.f32"},
1433 {LibFunc_fminimum_num,
"llvm.minimumnum.f64"},
1434 {LibFunc_fminimum_numl,
"llvm.minimumnum.f80"},
1435 {LibFunc_ceilf,
"llvm.ceil.f32"},
1436 {LibFunc_ceil,
"llvm.ceil.f64"},
1437 {LibFunc_ceill,
"llvm.ceil.f80"},
1438 {LibFunc_truncf,
"llvm.trunc.f32"},
1439 {LibFunc_trunc,
"llvm.trunc.f64"},
1440 {LibFunc_truncl,
"llvm.trunc.f80"},
1441 {LibFunc_rintf,
"llvm.rint.f32"},
1442 {LibFunc_rint,
"llvm.rint.f64"},
1443 {LibFunc_rintl,
"llvm.rint.f80"},
1444 {LibFunc_nearbyintf,
"llvm.nearbyint.f32"},
1445 {LibFunc_nearbyint,
"llvm.nearbyint.f64"},
1446 {LibFunc_nearbyintl,
"llvm.nearbyint.f80"},
1447 {LibFunc_roundf,
"llvm.round.f32"},
1448 {LibFunc_round,
"llvm.round.f64"},
1449 {LibFunc_roundl,
"llvm.round.f80"},
1452const char *KnownIntrinsic::get(LibFunc LFunc) {
1453 for (
const auto &
E : kLibfuncIntrinsics) {
1454 if (
E.LFunc == LFunc)
1455 return E.IntrinsicName;
1460const KnownIntrinsic::WidenedIntrinsic *KnownIntrinsic::widen(StringRef Name) {
1461 for (
const auto &
E : kWidenedIntrinsics) {
1462 if (
E.NarrowName == Name)
1472 if (LFunc == NotLibFunc)
1475 if (
const char *Name = KnownIntrinsic::get(LFunc))
1483Value *NumericalStabilitySanitizer::maybeHandleKnownCallBase(
1484 CallBase &
Call,
Type *VT,
Type *ExtendedVT,
const TargetLibraryInfo &TLI,
1485 const ValueToShadowMap &Map,
IRBuilder<> &Builder) {
1491 FunctionType *WidenedFnTy =
nullptr;
1493 const auto *Widened = KnownIntrinsic::widen(Fn->
getName());
1495 WidenedId = Widened->ID;
1496 WidenedFnTy = Widened->MakeFnTy(
Context);
1507 const auto *Widened = KnownIntrinsic::widen(Name);
1508 assert(Widened &&
"make sure KnownIntrinsic entries are consistent");
1509 WidenedId = Widened->ID;
1510 WidenedFnTy = Widened->MakeFnTy(
Context);
1518 [[maybe_unused]]
bool IsValid =
1520 assert(IsValid &&
"invalid widened intrinsic");
1523 SmallVector<Value *, 4>
Args;
1528 Type *IntrinsicArgTy = WidenedFnTy->getParamType(
I);
1529 if (OrigArgTy == IntrinsicArgTy) {
1530 Args.push_back(Arg);
1533 Type *ShadowArgTy = Config.getExtendedFPType(Arg->
getType());
1535 "don't know how to get the shadow value for a non-FT");
1536 Value *Shadow =
Map.getShadow(Arg);
1537 if (ShadowArgTy == IntrinsicArgTy) {
1540 Args.push_back(Shadow);
1547 return WidenedFnTy->getReturnType() == ExtendedVT
1554Value *NumericalStabilitySanitizer::handleCallBase(CallBase &
Call,
Type *VT,
1556 const TargetLibraryInfo &TLI,
1557 const ValueToShadowMap &Map,
1567 maybeHandleKnownCallBase(
Call, VT, ExtendedVT, TLI, Map, Builder))
1573 Builder.
CreateLoad(IntptrTy, NsanShadowRetTag,
false);
1583 ++NumInstrumentedFTCalls;
1589Value *NumericalStabilitySanitizer::createShadowValueWithOperandsAvailable(
1590 Instruction &Inst,
const TargetLibraryInfo &TLI,
1591 const ValueToShadowMap &Map) {
1593 Type *ExtendedVT = Config.getExtendedFPType(VT);
1594 assert(ExtendedVT !=
nullptr &&
"trying to create a shadow for a non-FT");
1597 return handleLoad(*
Load, VT, ExtendedVT);
1604 return handleCallBase(*
Call, VT, ExtendedVT, TLI, Map, Builder);
1611 BasicBlock *NextBB = Invoke->getNormalDest();
1618 Value *Shadow = handleCallBase(*Invoke, VT, ExtendedVT, TLI, Map, Builder);
1628 return handleTrunc(*Trunc, VT, ExtendedVT, Map, Builder);
1630 return handleExt(*Ext, VT, ExtendedVT, Map, Builder);
1633 return Builder.
CreateUnOp(UnaryOp->getOpcode(),
1634 Map.getShadow(UnaryOp->getOperand(0)));
1638 Map.getShadow(BinOp->getOperand(0)),
1639 Map.getShadow(BinOp->getOperand(1)));
1643 return Builder.
CreateCast(Cast->getOpcode(), Cast->getOperand(0),
1649 Map.getShadow(S->getTrueValue()),
1650 Map.getShadow(S->getFalseValue()));
1657 Map.getShadow(Extract->getVectorOperand()), Extract->getIndexOperand());
1666 Map.getShadow(Shuffle->getOperand(1)),
1667 Shuffle->getShuffleMask());
1684void NumericalStabilitySanitizer::maybeCreateShadowValue(
1685 Instruction &Root,
const TargetLibraryInfo &TLI, ValueToShadowMap &Map) {
1687 Type *ExtendedVT = Config.getExtendedFPType(VT);
1688 if (ExtendedVT ==
nullptr)
1691 if (
Map.hasShadow(&Root))
1696 std::vector<Instruction *> DfsStack(1, &Root);
1697 while (!DfsStack.empty()) {
1703 if (
Map.hasShadow(
I)) {
1704 DfsStack.pop_back();
1708 bool MissingShadow =
false;
1710 Type *VT =
Op->getType();
1711 if (!Config.getExtendedFPType(VT))
1713 if (
Map.hasShadow(
Op))
1715 MissingShadow =
true;
1722 Value *Shadow = createShadowValueWithOperandsAvailable(*
I, TLI, Map);
1723 Map.setShadow(*
I, *Shadow);
1724 DfsStack.pop_back();
1729void NumericalStabilitySanitizer::propagateFTStore(
1730 StoreInst &
Store,
Type *VT,
Type *ExtendedVT,
const ValueToShadowMap &Map) {
1731 Value *StoredValue =
Store.getValueOperand();
1734 const auto Extents = getMemoryExtentsOrDie(VT);
1736 NsanGetShadowPtrForStore[Extents.ValueType],
1737 {Store.getPointerOperand(), ConstantInt::get(IntptrTy, Extents.NumElts)});
1739 Value *StoredShadow =
Map.getShadow(StoredValue);
1740 if (!
Store.getParent()->getParent()->hasOptNone()) {
1743 if (Opts.nsan_check_stores) {
1744 StoredShadow = emitCheck(StoredValue, StoredShadow, Builder,
1745 CheckLoc::makeStore(
Store.getPointerOperand()));
1746 ++NumInstrumentedFTStores;
1751 Store.isVolatile());
1762void NumericalStabilitySanitizer::propagateNonFTStore(
1763 StoreInst &
Store,
Type *VT,
const ValueToShadowMap &Map) {
1768 TypeSize SlotSize =
DL.getTypeStoreSize(VT);
1774 ++NumInstrumentedNonFTStores;
1775 Value *StoredValue =
Store.getValueOperand();
1782 Type *ShadowTypeIntTy = Type::getIntNTy(
Context, 8 * LoadSizeBytes);
1783 Type *ShadowValueIntTy =
1787 Value *LoadSrc =
Load->getPointerOperand();
1793 Value *RawShadowType = LoadBuilder.CreateAlignedLoad(
1795 LoadBuilder.CreateCall(NsanGetRawShadowTypePtr, {LoadSrc}),
Align(1),
1797 Value *RawShadowValue = LoadBuilder.CreateAlignedLoad(
1799 LoadBuilder.CreateCall(NsanGetRawShadowPtr, {LoadSrc}),
Align(1),
1804 RawShadowType, Builder.
CreateCall(NsanGetRawShadowTypePtr, {Dst}),
1808 Builder.
CreateCall(NsanGetRawShadowPtr, {Dst}),
1812 ++NumInstrumentedNonFTMemcpyStores;
1815 if (Constant *
C; Opts.nsan_propagate_non_ft_const_stores_as_ft &&
1819 Type *BitcastTy =
nullptr;
1821 switch (
C->getType()->getScalarSizeInBits()) {
1823 BitcastTy = Type::getFloatTy(
Context);
1826 BitcastTy = Type::getDoubleTy(
Context);
1829 BitcastTy = Type::getX86_FP80Ty(
Context);
1837 BitcastTy = VectorType::get(BitcastTy, VectorTy->getElementCount());
1840 const MemoryExtents Extents = getMemoryExtentsOrDie(BitcastTy);
1842 NsanGetShadowPtrForStore[Extents.ValueType],
1843 {PtrOp, ConstantInt::get(IntptrTy, Extents.NumElts)});
1845 Type *ExtVT = Config.getExtendedFPType(BitcastTy);
1849 Store.isVolatile());
1854 Builder.
CreateCall(NsanSetUnknownFns.getFallback(), {Dst, ValueSize});
1857void NumericalStabilitySanitizer::propagateShadowValues(
1858 Instruction &Inst,
const TargetLibraryInfo &TLI,
1859 const ValueToShadowMap &Map) {
1861 Value *StoredValue =
Store->getValueOperand();
1863 Type *ExtendedVT = Config.getExtendedFPType(VT);
1864 if (ExtendedVT ==
nullptr)
1865 return propagateNonFTStore(*
Store, VT, Map);
1866 return propagateFTStore(*
Store, VT, ExtendedVT, Map);
1870 emitFCmpCheck(*FCmp, Map);
1875 maybeAddSuffixForNsanInterface(CB);
1879 instrumentMemIntrinsic(
MI);
1882 populateShadowStack(*CB, TLI, Map);
1887 if (!Opts.nsan_check_ret)
1890 Value *RV = RetInst->getReturnValue();
1894 Type *ExtendedVT = Config.getExtendedFPType(VT);
1895 if (ExtendedVT ==
nullptr)
1897 Value *RVShadow =
Map.getShadow(RV);
1900 RVShadow = emitCheck(RV, RVShadow, Builder, CheckLoc::makeRet());
1901 ++NumInstrumentedFTRets;
1907 Value *ShadowRetValPtr =
1915 Type *VT =
V->getType();
1916 Type *ExtendedVT = Config.getExtendedFPType(VT);
1917 if (ExtendedVT ==
nullptr)
1920 emitCheck(V,
Map.getShadow(V), Builder, CheckLoc::makeInsert());
1929 std::vector<Instruction *> &Instructions) {
1931#define MOVE_FLAG(attr, setter) \
1932 if (F.getFnAttribute(attr).getValueAsString() == "true") { \
1933 F.removeFnAttr(attr); \
1934 FMF.set##setter(); \
1936 MOVE_FLAG(
"no-signed-zeros-fp-math", NoSignedZeros)
1941 I->setFastMathFlags(FMF);
1944bool NumericalStabilitySanitizer::sanitizeFunction(
1945 Function &
F,
const TargetLibraryInfo &TLI) {
1946 if (!
F.hasFnAttribute(Attribute::SanitizeNumericalStability) ||
2043 std::vector<Instruction *> OriginalInstructions;
2044 for (BasicBlock &BB :
F)
2045 for (Instruction &Inst : BB)
2046 OriginalInstructions.emplace_back(&Inst);
2049 ValueToShadowMap ValueToShadow(Config);
2054 std::vector<PHINode *> OriginalPhis;
2055 createShadowArguments(
F, TLI, ValueToShadow);
2056 for (Instruction *
I : OriginalInstructions) {
2058 if (PHINode *Shadow = maybeCreateShadowPhi(*Phi, TLI)) {
2059 OriginalPhis.push_back(Phi);
2060 ValueToShadow.setShadow(*Phi, *Shadow);
2066 for (Instruction *
I : OriginalInstructions)
2067 maybeCreateShadowValue(*
I, TLI, ValueToShadow);
2070 for (Instruction *
I : OriginalInstructions)
2071 propagateShadowValues(*
I, TLI, ValueToShadow);
2074 for (PHINode *Phi : OriginalPhis) {
2075 PHINode *ShadowPhi =
cast<PHINode>(ValueToShadow.getShadow(Phi));
2076 for (
unsigned I :
seq(
Phi->getNumOperands())) {
2078 Value *Shadow = ValueToShadow.getShadow(V);
2090 return !ValueToShadow.empty();
2097 if (CInt && CInt->getValue().getBitWidth() <= 64)
2098 OpSize = CInt->getValue().getZExtValue();
2106bool NumericalStabilitySanitizer::instrumentMemIntrinsic(MemIntrinsic *
MI) {
2109 FunctionCallee SetUnknownFn =
2110 NsanSetUnknownFns.getFunctionFor(
GetMemOpSize(
M->getArgOperand(2)));
2112 Builder.
CreateCall(SetUnknownFn, {
M->getArgOperand(0)});
2115 {
M->getArgOperand(0),
2120 FunctionCallee CopyFn =
2121 NsanCopyFns.getFunctionFor(
GetMemOpSize(
M->getArgOperand(2)));
2125 M->getArgOperand(1)});
2128 M->getArgOperand(1),
2136void NumericalStabilitySanitizer::maybeAddSuffixForNsanInterface(CallBase *CI) {
2144 if (Fn->
getName() ==
"__nsan_dump_shadow_mem") {
2146 "invalid prototype for __nsan_dump_shadow_mem");
2151 const uint64_t shadow_value_type_ids =
2152 (
static_cast<size_t>(Config.byValueType(kLongDouble).getNsanTypeId())
2154 (
static_cast<size_t>(Config.byValueType(kDouble).getNsanTypeId())
2156 static_cast<size_t>(Config.byValueType(kFloat).getNsanTypeId());
2157 CI->
setArgOperand(3, ConstantInt::get(IntptrTy, shadow_value_type_ids));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
Module.h This file contains the declarations for the Module class.
static constexpr Value * getValue(Ty &ValueOrUse)
Machine Check Debug Module
static GlobalValue * createThreadLocalGV(const char *Name, Module &M, Type *Ty)
static FunctionType * makeDoubleDouble(LLVMContext &C)
constexpr int kMaxVectorWidth
static bool shouldCheckArgs(CallBase &CI, const TargetLibraryInfo &TLI, const std::optional< Regex > &CheckFunctionsFilter)
static FunctionType * makeX86FP80X86FP80(LLVMContext &C)
#define MOVE_FLAG(attr, setter)
static FunctionType * makeX86FP80X86FP80I32(LLVMContext &C)
constexpr int kMaxNumArgs
constexpr int kMaxShadowTypeSizeBytes
static const char * getIntrinsicFromLibfunc(Function &Fn, Type *VT, const TargetLibraryInfo &TLI)
static FunctionType * makeX86FP80X86FP80X86FP80(LLVMContext &C)
static FunctionType * makeX86FP80X86FP80X86FP80X86FP80(LLVMContext &C)
static uint64_t GetMemOpSize(Value *V)
constexpr StringLiteral kNsanInitName("__nsan_init")
static FunctionType * makeDoubleDoubleDouble(LLVMContext &C)
constexpr int kShadowScale
constexpr StringLiteral kNsanModuleCtorName("nsan.module_ctor")
static FunctionType * makeDoubleDoubleDoubleDouble(LLVMContext &C)
static FunctionType * makeDoubleDoubleI32(LLVMContext &C)
static void moveFastMathFlags(Function &F, std::vector< Instruction * > &Instructions)
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static SymbolRef::Type getType(const Symbol *Sym)
static constexpr roundingMode rmTowardZero
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM_ABI void replaceSuccessorsPhiUsesWith(BasicBlock *Old, BasicBlock *New)
Update all phi nodes in this basic block's successors to refer to basic block New instead of basic bl...
iterator begin()
Instruction iterator methods.
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & back() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
InstListType::iterator iterator
Instruction iterators...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getCalledOperand() const
void setArgOperand(unsigned i, Value *v)
unsigned arg_size() const
Predicate getPredicate() const
Return the predicate for this instruction.
ConstantFP - Floating Point Values [float, double].
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
A parsed version of the target data layout string in and methods for querying it.
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
This instruction compares its operands according to the predicate given to the constructor.
static bool isEquality(Predicate Pred)
This class represents an extension of floating point types.
This class represents a truncation of floating point types.
Convenience struct for specifying and reasoning about fast-math flags.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
FunctionType * getFunctionType()
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
@ ExternalLinkage
Externally visible function.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Value * CreateFPTrunc(Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateConstGEP2_64(Type *Ty, Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name="")
BasicBlock::iterator GetInsertPoint() const
Value * CreateFreeze(Value *V, const Twine &Name="")
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr, FMFSource FMFSource={})
Value * CreateUnOp(Instruction::UnaryOps Opc, Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
UncondBrInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Value * CreateFPExt(Value *V, Type *DestTy, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI void replaceSuccessorWith(BasicBlock *OldBB, BasicBlock *NewBB)
Replace specified successor OldBB to point at the provided block.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
iterator_range< user_iterator > users()
const char * getOpcodeName() const
LLVM_ABI void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
This is the common base class for memset/memcpy/memmove.
A Module instance is used to store all the information related to an LLVM module.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
StringRef getName(LibFunc F) const
LibFunc getLibFunc(StringRef funcName) const
Searches for a particular function name.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI Type * getStructElementType(unsigned N) const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isX86_FP80Ty() const
Return true if this is x86 long double.
bool isArrayTy() const
True if this is an instance of ArrayType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
static LLVM_ABI Type * getPPC_FP128Ty(LLVMContext &C)
static LLVM_ABI Type * getFP128Ty(LLVMContext &C)
LLVM_ABI unsigned getStructNumElements() const
LLVM_ABI uint64_t getArrayNumElements() const
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
bool isStructTy() const
True if this is an instance of StructType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getX86_FP80Ty(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
'undef' values are things that do not have specified contents.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
const ParentTy * getParent() const
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ BasicBlock
Various leaf nodes.
LLVM_ABI bool isSignatureValid(Intrinsic::ID ID, FunctionType *FT, SmallVectorImpl< Type * > &OverloadTys, raw_ostream &OS=nulls())
Returns true if FT is a valid function type for intrinsic ID.
NodeAddr< PhiNode * > Phi
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function lazily.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)