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;
573 NumericalStabilitySanitizer Nsan(Opts, M);
582 return M.getOrInsertGlobal(Name, Ty, [&M, Ty, Name] {
584 nullptr, Name,
nullptr,
589NumericalStabilitySanitizer::NumericalStabilitySanitizer(
590 const InstrumentationOptions &Opts,
Module &M)
593 NsanCopyFns(
M, {
"__nsan_copy_4",
"__nsan_copy_8",
"__nsan_copy_16"},
594 "__nsan_copy_values", 3),
596 {
"__nsan_set_value_unknown_4",
597 "__nsan_set_value_unknown_8",
598 "__nsan_set_value_unknown_16"},
599 "__nsan_set_value_unknown", 2) {
600 IntptrTy =
DL.getIntPtrType(Context);
607 Attr = Attr.addFnAttribute(Context, Attribute::NoUnwind);
611 TargetLibraryInfo::getExtAttrForI32Return(TT,
true);
613 TargetLibraryInfo::getExtAttrForI32Param(TT,
true);
618 for (
int I = 0;
I < kNumValueTypes; ++
I) {
619 const FTValueType VT =
static_cast<FTValueType
>(
I);
620 const char *VTName = typeNameFromFTValueType(VT);
621 Type *VTTy = typeFromFTValueType(VT, Context);
624 const std::string GetterPrefix =
625 std::string(
"__nsan_get_shadow_ptr_for_") + VTName;
626 NsanGetShadowPtrForStore[VT] = M.getOrInsertFunction(
627 GetterPrefix +
"_store", Attr, PtrTy, PtrTy, IntptrTy);
628 NsanGetShadowPtrForLoad[VT] = M.getOrInsertFunction(
629 GetterPrefix +
"_load", Attr, PtrTy, PtrTy, IntptrTy);
632 const auto &ShadowConfig = Config.byValueType(VT);
633 Type *ShadowTy = ShadowConfig.getType(Context);
636 AL =
AL.maybeAddRetAttribute(Context, I32RetExtAttr);
637 AL =
AL.maybeAddParamAttribute(Context, 2, I32ArgExtAttr);
639 M.getOrInsertFunction(std::string(
"__nsan_internal_check_") + VTName +
640 "_" + ShadowConfig.getNsanTypeId(),
641 AL, Int32Ty, VTTy, ShadowTy, Int32Ty, IntptrTy);
646 AL =
AL.maybeAddParamAttribute(Context, 4, I32ArgExtAttr);
647 AL =
AL.maybeAddParamAttribute(Context, 5, BoolExtAttr);
648 AL =
AL.maybeAddParamAttribute(Context, 6, BoolExtAttr);
649 NsanFCmpFail[VT] = M.getOrInsertFunction(
650 std::string(
"__nsan_fcmp_fail_") + VTName +
"_" +
651 ShadowConfig.getNsanTypeId(),
652 AL, VoidTy, VTTy, VTTy, ShadowTy, ShadowTy, Int32Ty, Int1Ty, Int1Ty);
657 NsanGetRawShadowTypePtr = M.getOrInsertFunction(
658 "__nsan_internal_get_raw_shadow_type_ptr", Attr, PtrTy, PtrTy);
659 NsanGetRawShadowPtr = M.getOrInsertFunction(
660 "__nsan_internal_get_raw_shadow_ptr", Attr, PtrTy, PtrTy);
679 if (!Opts.check_functions_filter.empty()) {
681 std::string RegexError;
683 CheckFunctionsFilter = std::move(R);
689bool NumericalStabilitySanitizer::addrPointsToConstantData(
Value *Addr) {
692 Addr =
GEP->getPointerOperand();
695 return GV->isConstant();
711void NumericalStabilitySanitizer::createShadowArguments(
712 Function &
F,
const TargetLibraryInfo &TLI, ValueToShadowMap &Map) {
713 assert(!
F.getIntrinsicID() &&
"found a definition of an intrinsic");
716 if (
all_of(
F.args(), [
this](
const Argument &Arg) {
717 return Config.getExtendedFPType(Arg.getType()) == nullptr;
721 IRBuilder<> Builder(
F.getEntryBlock().getFirstNonPHIIt());
724 Value *HasShadowArgs = Builder.CreateICmpEQ(
725 Builder.CreateLoad(IntptrTy, NsanShadowArgsTag,
false),
726 Builder.CreatePtrToInt(&
F, IntptrTy));
728 unsigned ShadowArgsOffsetBytes = 0;
729 for (Argument &Arg :
F.args()) {
731 Type *ExtendedVT = Config.getExtendedFPType(VT);
732 if (ExtendedVT ==
nullptr)
734 Value *
L = Builder.CreateAlignedLoad(
736 Builder.CreateConstGEP2_64(NsanShadowArgsType, NsanShadowArgsPtr, 0,
737 ShadowArgsOffsetBytes),
739 Value *Shadow = Builder.CreateSelect(HasShadowArgs, L,
740 Builder.CreateFPExt(&Arg, ExtendedVT));
741 Map.setShadow(Arg, *Shadow);
742 TypeSize SlotSize =
DL.getTypeStoreSize(ExtendedVT);
744 ShadowArgsOffsetBytes += SlotSize;
746 Builder.CreateStore(ConstantInt::get(IntptrTy, 0), NsanShadowArgsTag);
752 const std::optional<Regex> &CheckFunctionsFilter) {
756 if (CheckFunctionsFilter) {
760 if (CheckFunctionsFilter->match(Fn->
getName()))
781 if (ID == Intrinsic::fabs || LFunc == LibFunc_fabsf ||
782 LFunc == LibFunc_fabs || LFunc == LibFunc_fabsl)
783 for (
const auto &U : CI.
users())
792void NumericalStabilitySanitizer::populateShadowStack(
793 CallBase &CI,
const TargetLibraryInfo &TLI,
const ValueToShadowMap &Map) {
800 return Config.getExtendedFPType(Arg->getType()) == nullptr;
805 SmallVector<Value *, 8> ArgShadows;
806 const bool ShouldCheckArgs =
shouldCheckArgs(CI, TLI, CheckFunctionsFilter);
808 if (Config.getExtendedFPType(Arg->
getType()) ==
nullptr)
810 Value *ArgShadow =
Map.getShadow(Arg);
811 ArgShadows.
push_back(ShouldCheckArgs ? emitCheck(Arg, ArgShadow, Builder,
812 CheckLoc::makeArg(ArgIdx))
818 if (Fn->isIntrinsic() || TLI.
getLibFunc(*Fn) != NotLibFunc)
826 unsigned ShadowArgId = 0;
829 Type *ExtendedVT = Config.getExtendedFPType(VT);
830 if (ExtendedVT ==
nullptr)
832 Builder.CreateAlignedStore(
833 ArgShadows[ShadowArgId++],
834 Builder.CreateConstGEP2_64(NsanShadowArgsType, NsanShadowArgsPtr, 0,
835 ShadowArgsOffsetBytes),
837 TypeSize SlotSize =
DL.getTypeStoreSize(ExtendedVT);
839 ShadowArgsOffsetBytes += SlotSize;
851Value *NumericalStabilitySanitizer::emitCheckInternal(
Value *V,
Value *ShadowV,
856 return ConstantInt::get(
860 Type *Ty =
V->getType();
861 if (
const auto VT = ftValueTypeFromType(Ty))
864 {
V, ShadowV, Loc.getType(
Context), Loc.getValue(IntptrTy, Builder)});
870 assert(!VecTy->isScalableTy() &&
871 "Scalable vector types are not supported yet");
872 Value *CheckResult =
nullptr;
873 for (
int I = 0,
E = VecTy->getElementCount().getFixedValue();
I <
E; ++
I) {
879 Value *ComponentCheckResult =
880 emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc);
881 CheckResult = CheckResult
882 ? Builder.
CreateOr(CheckResult, ComponentCheckResult)
883 : ComponentCheckResult;
888 Value *CheckResult =
nullptr;
892 Value *ComponentCheckResult =
893 emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc);
894 CheckResult = CheckResult
895 ? Builder.
CreateOr(CheckResult, ComponentCheckResult)
896 : ComponentCheckResult;
901 Value *CheckResult =
nullptr;
907 Value *ComponentCheckResult =
908 emitCheckInternal(ExtractV, ExtractShadowV, Builder, Loc);
909 CheckResult = CheckResult
910 ? Builder.
CreateOr(CheckResult, ComponentCheckResult)
911 : ComponentCheckResult;
914 return ConstantInt::get(
938 if (CheckFunctionsFilter && !CheckFunctionsFilter->match(
F->getName())) {
943 Value *CheckResult = emitCheckInternal(V, ShadowV, Builder, Loc);
949 ICmpEQ, Builder.
CreateFPExt(V, Config.getExtendedFPType(
V->getType())),
955void NumericalStabilitySanitizer::emitFCmpCheck(FCmpInst &FCmp,
956 const ValueToShadowMap &Map) {
957 if (!Opts.nsan_instrument_fcmp)
961 if (CheckFunctionsFilter && !CheckFunctionsFilter->match(
F->getName()))
965 if (Config.getExtendedFPType(
LHS->
getType()) ==
nullptr)
980 FCmpBuilder.SetCurrentDebugLocation(FCmp.
getDebugLoc());
984 if (FCmp.
isEquality() && Opts.nsan_truncate_fcmp_eq) {
986 ShadowLHS = FCmpBuilder.CreateFPExt(
987 FCmpBuilder.CreateFPTrunc(ShadowLHS,
LHS->
getType()), Ty);
988 ShadowRHS = FCmpBuilder.CreateFPExt(
989 FCmpBuilder.CreateFPTrunc(ShadowRHS,
RHS->
getType()), Ty);
992 FCmpBuilder.CreateFCmp(FCmp.
getPredicate(), ShadowLHS, ShadowRHS);
993 Value *OriginalAndShadowFcmpMatch =
994 FCmpBuilder.CreateICmpEQ(&FCmp, ShadowFCmp);
1000 OriginalAndShadowFcmpMatch =
1001 FCmpBuilder.CreateAndReduce(OriginalAndShadowFcmpMatch);
1006 FCmpBuilder.CreateCondBr(OriginalAndShadowFcmpMatch, NextBB, FailBB,
1007 MDBuilder(
Context).createLikelyBranchWeights());
1011 FailBuilder.SetCurrentDebugLocation(FCmp.
getDebugLoc());
1013 const auto EmitFailCall = [
this, &FCmp, &FCmpBuilder,
1016 Value *ShadowResult) {
1017 Type *FT =
L->getType();
1018 FunctionCallee *
Callee =
nullptr;
1020 Callee = &(NsanFCmpFail[kFloat]);
1022 Callee = &(NsanFCmpFail[kDouble]);
1025 Callee = &(NsanFCmpFail[kDouble]);
1026 L = FailBuilder.CreateFPTrunc(L, Type::getDoubleTy(
Context));
1027 R = FailBuilder.CreateFPTrunc(L, Type::getDoubleTy(
Context));
1031 FailBuilder.CreateCall(*Callee, {
L,
R, ShadowL, ShadowR,
1032 ConstantInt::get(FCmpBuilder.getInt32Ty(),
1041 Value *ExtractLHS = FailBuilder.CreateExtractElement(
LHS,
I);
1042 Value *ExtractRHS = FailBuilder.CreateExtractElement(
RHS,
I);
1043 Value *ExtractShaodwLHS = FailBuilder.CreateExtractElement(ShadowLHS,
I);
1044 Value *ExtractShaodwRHS = FailBuilder.CreateExtractElement(ShadowRHS,
I);
1045 Value *ExtractFCmp = FailBuilder.CreateExtractElement(&FCmp,
I);
1046 Value *ExtractShadowFCmp =
1047 FailBuilder.CreateExtractElement(ShadowFCmp,
I);
1048 EmitFailCall(ExtractLHS, ExtractRHS, ExtractShaodwLHS, ExtractShaodwRHS,
1049 ExtractFCmp, ExtractShadowFCmp);
1052 EmitFailCall(
LHS,
RHS, ShadowLHS, ShadowRHS, &FCmp, ShadowFCmp);
1054 FailBuilder.CreateBr(NextBB);
1056 ++NumInstrumentedFCmp;
1060PHINode *NumericalStabilitySanitizer::maybeCreateShadowPhi(
1061 PHINode &Phi,
const TargetLibraryInfo &TLI) {
1063 Type *ExtendedVT = Config.getExtendedFPType(VT);
1064 if (ExtendedVT ==
nullptr)
1074Value *NumericalStabilitySanitizer::handleLoad(LoadInst &
Load,
Type *VT,
1078 if (addrPointsToConstantData(
Load.getPointerOperand())) {
1098 const auto Extents = getMemoryExtentsOrDie(VT);
1100 NsanGetShadowPtrForLoad[Extents.ValueType],
1101 {Load.getPointerOperand(), ConstantInt::get(IntptrTy, Extents.NumElts)});
1102 ++NumInstrumentedFTLoads;
1118 LoadBBBuilder.SetCurrentDebugLocation(
Load.getDebugLoc());
1119 LoadBBBuilder.CreateCondBr(LoadBBBuilder.CreateIsNull(ShadowPtr), FExtBB,
1125 ShadowLoadBBBuilder.SetCurrentDebugLocation(
Load.getDebugLoc());
1126 Value *ShadowLoad = ShadowLoadBBBuilder.CreateAlignedLoad(
1127 ExtendedVT, ShadowPtr,
Align(1),
Load.isVolatile());
1128 if (Opts.nsan_check_loads) {
1129 ShadowLoad = emitCheck(&
Load, ShadowLoad, ShadowLoadBBBuilder,
1130 CheckLoc::makeLoad(
Load.getPointerOperand()));
1132 ShadowLoadBBBuilder.CreateBr(NextBB);
1136 FExtBBBuilder.SetCurrentDebugLocation(
Load.getDebugLoc());
1137 Value *FExt = FExtBBBuilder.CreateFPExt(&
Load, ExtendedVT);
1138 FExtBBBuilder.CreateBr(NextBB);
1142 NextBBBuilder.SetCurrentDebugLocation(
Load.getDebugLoc());
1143 PHINode *ShadowPhi = NextBBBuilder.CreatePHI(ExtendedVT, 2);
1149Value *NumericalStabilitySanitizer::handleTrunc(
const FPTruncInst &Trunc,
1151 const ValueToShadowMap &Map,
1155 Type *ExtendedSourceTy = Config.getExtendedFPType(OrigSourceTy);
1188 Value *
Source = ExtendedSourceTy ?
Map.getShadow(OrigSource) : OrigSource;
1189 Type *SourceTy = ExtendedSourceTy ? ExtendedSourceTy : OrigSourceTy;
1191 if (SourceTy == ExtendedVT)
1197Value *NumericalStabilitySanitizer::handleExt(
const FPExtInst &Ext,
Type *VT,
1199 const ValueToShadowMap &Map,
1203 Type *ExtendedSourceTy = Config.getExtendedFPType(OrigSourceTy);
1235 Value *
Source = ExtendedSourceTy ?
Map.getShadow(OrigSource) : OrigSource;
1236 Type *SourceTy = ExtendedSourceTy ? ExtendedSourceTy : OrigSourceTy;
1238 if (SourceTy == ExtendedVT)
1246struct KnownIntrinsic {
1247 struct WidenedIntrinsic {
1248 const char *NarrowName;
1250 using FnTypeFactory = FunctionType *(*)(LLVMContext &);
1251 FnTypeFactory MakeFnTy;
1254 static const char *
get(LibFunc LFunc);
1261 static const WidenedIntrinsic *widen(StringRef Name);
1266 const char *IntrinsicName;
1268 static const LFEntry kLibfuncIntrinsics[];
1270 static const WidenedIntrinsic kWidenedIntrinsics[];
1319const KnownIntrinsic::WidenedIntrinsic KnownIntrinsic::kWidenedIntrinsics[] = {
1408const KnownIntrinsic::LFEntry KnownIntrinsic::kLibfuncIntrinsics[] = {
1409 {LibFunc_sqrtf,
"llvm.sqrt.f32"},
1410 {LibFunc_sqrt,
"llvm.sqrt.f64"},
1411 {LibFunc_sqrtl,
"llvm.sqrt.f80"},
1412 {LibFunc_sinf,
"llvm.sin.f32"},
1413 {LibFunc_sin,
"llvm.sin.f64"},
1414 {LibFunc_sinl,
"llvm.sin.f80"},
1415 {LibFunc_cosf,
"llvm.cos.f32"},
1416 {LibFunc_cos,
"llvm.cos.f64"},
1417 {LibFunc_cosl,
"llvm.cos.f80"},
1418 {LibFunc_powf,
"llvm.pow.f32"},
1419 {LibFunc_pow,
"llvm.pow.f64"},
1420 {LibFunc_powl,
"llvm.pow.f80"},
1421 {LibFunc_expf,
"llvm.exp.f32"},
1422 {LibFunc_exp,
"llvm.exp.f64"},
1423 {LibFunc_expl,
"llvm.exp.f80"},
1424 {LibFunc_exp2f,
"llvm.exp2.f32"},
1425 {LibFunc_exp2,
"llvm.exp2.f64"},
1426 {LibFunc_exp2l,
"llvm.exp2.f80"},
1427 {LibFunc_logf,
"llvm.log.f32"},
1428 {LibFunc_log,
"llvm.log.f64"},
1429 {LibFunc_logl,
"llvm.log.f80"},
1430 {LibFunc_log10f,
"llvm.log10.f32"},
1431 {LibFunc_log10,
"llvm.log10.f64"},
1432 {LibFunc_log10l,
"llvm.log10.f80"},
1433 {LibFunc_log2f,
"llvm.log2.f32"},
1434 {LibFunc_log2,
"llvm.log2.f64"},
1435 {LibFunc_log2l,
"llvm.log2.f80"},
1436 {LibFunc_fabsf,
"llvm.fabs.f32"},
1437 {LibFunc_fabs,
"llvm.fabs.f64"},
1438 {LibFunc_fabsl,
"llvm.fabs.f80"},
1439 {LibFunc_copysignf,
"llvm.copysign.f32"},
1440 {LibFunc_copysign,
"llvm.copysign.f64"},
1441 {LibFunc_copysignl,
"llvm.copysign.f80"},
1442 {LibFunc_floorf,
"llvm.floor.f32"},
1443 {LibFunc_floor,
"llvm.floor.f64"},
1444 {LibFunc_floorl,
"llvm.floor.f80"},
1445 {LibFunc_fmaxf,
"llvm.maxnum.f32"},
1446 {LibFunc_fmax,
"llvm.maxnum.f64"},
1447 {LibFunc_fmaxl,
"llvm.maxnum.f80"},
1448 {LibFunc_fminf,
"llvm.minnum.f32"},
1449 {LibFunc_fmin,
"llvm.minnum.f64"},
1450 {LibFunc_fminl,
"llvm.minnum.f80"},
1451 {LibFunc_fmaximum_numf,
"llvm.maximumnum.f32"},
1452 {LibFunc_fmaximum_num,
"llvm.maximumnum.f64"},
1453 {LibFunc_fmaximum_numl,
"llvm.maximumnum.f80"},
1454 {LibFunc_fminimum_numf,
"llvm.minimumnum.f32"},
1455 {LibFunc_fminimum_num,
"llvm.minimumnum.f64"},
1456 {LibFunc_fminimum_numl,
"llvm.minimumnum.f80"},
1457 {LibFunc_ceilf,
"llvm.ceil.f32"},
1458 {LibFunc_ceil,
"llvm.ceil.f64"},
1459 {LibFunc_ceill,
"llvm.ceil.f80"},
1460 {LibFunc_truncf,
"llvm.trunc.f32"},
1461 {LibFunc_trunc,
"llvm.trunc.f64"},
1462 {LibFunc_truncl,
"llvm.trunc.f80"},
1463 {LibFunc_rintf,
"llvm.rint.f32"},
1464 {LibFunc_rint,
"llvm.rint.f64"},
1465 {LibFunc_rintl,
"llvm.rint.f80"},
1466 {LibFunc_nearbyintf,
"llvm.nearbyint.f32"},
1467 {LibFunc_nearbyint,
"llvm.nearbyint.f64"},
1468 {LibFunc_nearbyintl,
"llvm.nearbyint.f80"},
1469 {LibFunc_roundf,
"llvm.round.f32"},
1470 {LibFunc_round,
"llvm.round.f64"},
1471 {LibFunc_roundl,
"llvm.round.f80"},
1474const char *KnownIntrinsic::get(LibFunc LFunc) {
1475 for (
const auto &
E : kLibfuncIntrinsics) {
1476 if (
E.LFunc == LFunc)
1477 return E.IntrinsicName;
1482const KnownIntrinsic::WidenedIntrinsic *KnownIntrinsic::widen(StringRef Name) {
1483 for (
const auto &
E : kWidenedIntrinsics) {
1484 if (
E.NarrowName == Name)
1494 if (LFunc == NotLibFunc)
1497 if (
const char *Name = KnownIntrinsic::get(LFunc))
1505Value *NumericalStabilitySanitizer::maybeHandleKnownCallBase(
1506 CallBase &
Call,
Type *VT,
Type *ExtendedVT,
const TargetLibraryInfo &TLI,
1507 const ValueToShadowMap &Map,
IRBuilder<> &Builder) {
1513 FunctionType *WidenedFnTy =
nullptr;
1515 const auto *Widened = KnownIntrinsic::widen(Fn->
getName());
1517 WidenedId = Widened->ID;
1518 WidenedFnTy = Widened->MakeFnTy(
Context);
1529 const auto *Widened = KnownIntrinsic::widen(Name);
1530 assert(Widened &&
"make sure KnownIntrinsic entries are consistent");
1531 WidenedId = Widened->ID;
1532 WidenedFnTy = Widened->MakeFnTy(
Context);
1540 [[maybe_unused]]
bool IsValid =
1542 assert(IsValid &&
"invalid widened intrinsic");
1545 SmallVector<Value *, 4>
Args;
1550 Type *IntrinsicArgTy = WidenedFnTy->getParamType(
I);
1551 if (OrigArgTy == IntrinsicArgTy) {
1552 Args.push_back(Arg);
1555 Type *ShadowArgTy = Config.getExtendedFPType(Arg->
getType());
1557 "don't know how to get the shadow value for a non-FT");
1558 Value *Shadow =
Map.getShadow(Arg);
1559 if (ShadowArgTy == IntrinsicArgTy) {
1562 Args.push_back(Shadow);
1569 return WidenedFnTy->getReturnType() == ExtendedVT
1576Value *NumericalStabilitySanitizer::handleCallBase(CallBase &
Call,
Type *VT,
1578 const TargetLibraryInfo &TLI,
1579 const ValueToShadowMap &Map,
1589 maybeHandleKnownCallBase(
Call, VT, ExtendedVT, TLI, Map, Builder))
1595 Builder.
CreateLoad(IntptrTy, NsanShadowRetTag,
false);
1605 ++NumInstrumentedFTCalls;
1611Value *NumericalStabilitySanitizer::createShadowValueWithOperandsAvailable(
1612 Instruction &Inst,
const TargetLibraryInfo &TLI,
1613 const ValueToShadowMap &Map) {
1615 Type *ExtendedVT = Config.getExtendedFPType(VT);
1616 assert(ExtendedVT !=
nullptr &&
"trying to create a shadow for a non-FT");
1619 return handleLoad(*
Load, VT, ExtendedVT);
1626 return handleCallBase(*
Call, VT, ExtendedVT, TLI, Map, Builder);
1633 BasicBlock *NextBB = Invoke->getNormalDest();
1640 Value *Shadow = handleCallBase(*Invoke, VT, ExtendedVT, TLI, Map, Builder);
1650 return handleTrunc(*Trunc, VT, ExtendedVT, Map, Builder);
1652 return handleExt(*Ext, VT, ExtendedVT, Map, Builder);
1655 return Builder.
CreateUnOp(UnaryOp->getOpcode(),
1656 Map.getShadow(UnaryOp->getOperand(0)));
1660 Map.getShadow(BinOp->getOperand(0)),
1661 Map.getShadow(BinOp->getOperand(1)));
1665 return Builder.
CreateCast(Cast->getOpcode(), Cast->getOperand(0),
1671 Map.getShadow(S->getTrueValue()),
1672 Map.getShadow(S->getFalseValue()));
1679 Map.getShadow(Extract->getVectorOperand()), Extract->getIndexOperand());
1688 Map.getShadow(Shuffle->getOperand(1)),
1689 Shuffle->getShuffleMask());
1706void NumericalStabilitySanitizer::maybeCreateShadowValue(
1707 Instruction &Root,
const TargetLibraryInfo &TLI, ValueToShadowMap &Map) {
1709 Type *ExtendedVT = Config.getExtendedFPType(VT);
1710 if (ExtendedVT ==
nullptr)
1713 if (
Map.hasShadow(&Root))
1718 std::vector<Instruction *> DfsStack(1, &Root);
1719 while (!DfsStack.empty()) {
1725 if (
Map.hasShadow(
I)) {
1726 DfsStack.pop_back();
1730 bool MissingShadow =
false;
1732 Type *VT =
Op->getType();
1733 if (!Config.getExtendedFPType(VT))
1735 if (
Map.hasShadow(
Op))
1737 MissingShadow =
true;
1744 Value *Shadow = createShadowValueWithOperandsAvailable(*
I, TLI, Map);
1745 Map.setShadow(*
I, *Shadow);
1746 DfsStack.pop_back();
1751void NumericalStabilitySanitizer::propagateFTStore(
1752 StoreInst &
Store,
Type *VT,
Type *ExtendedVT,
const ValueToShadowMap &Map) {
1753 Value *StoredValue =
Store.getValueOperand();
1756 const auto Extents = getMemoryExtentsOrDie(VT);
1758 NsanGetShadowPtrForStore[Extents.ValueType],
1759 {Store.getPointerOperand(), ConstantInt::get(IntptrTy, Extents.NumElts)});
1761 Value *StoredShadow =
Map.getShadow(StoredValue);
1762 if (!
Store.getParent()->getParent()->hasOptNone()) {
1765 if (Opts.nsan_check_stores) {
1766 StoredShadow = emitCheck(StoredValue, StoredShadow, Builder,
1767 CheckLoc::makeStore(
Store.getPointerOperand()));
1768 ++NumInstrumentedFTStores;
1773 Store.isVolatile());
1784void NumericalStabilitySanitizer::propagateNonFTStore(
1785 StoreInst &
Store,
Type *VT,
const ValueToShadowMap &Map) {
1790 TypeSize SlotSize =
DL.getTypeStoreSize(VT);
1796 ++NumInstrumentedNonFTStores;
1797 Value *StoredValue =
Store.getValueOperand();
1804 Type *ShadowTypeIntTy = Type::getIntNTy(
Context, 8 * LoadSizeBytes);
1805 Type *ShadowValueIntTy =
1809 Value *LoadSrc =
Load->getPointerOperand();
1815 Value *RawShadowType = LoadBuilder.CreateAlignedLoad(
1817 LoadBuilder.CreateCall(NsanGetRawShadowTypePtr, {LoadSrc}),
Align(1),
1819 Value *RawShadowValue = LoadBuilder.CreateAlignedLoad(
1821 LoadBuilder.CreateCall(NsanGetRawShadowPtr, {LoadSrc}),
Align(1),
1826 RawShadowType, Builder.
CreateCall(NsanGetRawShadowTypePtr, {Dst}),
1830 Builder.
CreateCall(NsanGetRawShadowPtr, {Dst}),
1834 ++NumInstrumentedNonFTMemcpyStores;
1837 if (Constant *
C; Opts.nsan_propagate_non_ft_const_stores_as_ft &&
1841 Type *BitcastTy =
nullptr;
1843 switch (
C->getType()->getScalarSizeInBits()) {
1845 BitcastTy = Type::getFloatTy(
Context);
1848 BitcastTy = Type::getDoubleTy(
Context);
1851 BitcastTy = Type::getX86_FP80Ty(
Context);
1859 BitcastTy = VectorType::get(BitcastTy, VectorTy->getElementCount());
1862 const MemoryExtents Extents = getMemoryExtentsOrDie(BitcastTy);
1864 NsanGetShadowPtrForStore[Extents.ValueType],
1865 {PtrOp, ConstantInt::get(IntptrTy, Extents.NumElts)});
1867 Type *ExtVT = Config.getExtendedFPType(BitcastTy);
1871 Store.isVolatile());
1876 Builder.
CreateCall(NsanSetUnknownFns.getFallback(), {Dst, ValueSize});
1879void NumericalStabilitySanitizer::propagateShadowValues(
1880 Instruction &Inst,
const TargetLibraryInfo &TLI,
1881 const ValueToShadowMap &Map) {
1883 Value *StoredValue =
Store->getValueOperand();
1885 Type *ExtendedVT = Config.getExtendedFPType(VT);
1886 if (ExtendedVT ==
nullptr)
1887 return propagateNonFTStore(*
Store, VT, Map);
1888 return propagateFTStore(*
Store, VT, ExtendedVT, Map);
1892 emitFCmpCheck(*FCmp, Map);
1897 maybeAddSuffixForNsanInterface(CB);
1901 instrumentMemIntrinsic(
MI);
1904 populateShadowStack(*CB, TLI, Map);
1909 if (!Opts.nsan_check_ret)
1912 Value *RV = RetInst->getReturnValue();
1916 Type *ExtendedVT = Config.getExtendedFPType(VT);
1917 if (ExtendedVT ==
nullptr)
1919 Value *RVShadow =
Map.getShadow(RV);
1922 RVShadow = emitCheck(RV, RVShadow, Builder, CheckLoc::makeRet());
1923 ++NumInstrumentedFTRets;
1929 Value *ShadowRetValPtr =
1937 Type *VT =
V->getType();
1938 Type *ExtendedVT = Config.getExtendedFPType(VT);
1939 if (ExtendedVT ==
nullptr)
1942 emitCheck(V,
Map.getShadow(V), Builder, CheckLoc::makeInsert());
1951 std::vector<Instruction *> &Instructions) {
1953#define MOVE_FLAG(attr, setter) \
1954 if (F.getFnAttribute(attr).getValueAsString() == "true") { \
1955 F.removeFnAttr(attr); \
1956 FMF.set##setter(); \
1958 MOVE_FLAG(
"no-signed-zeros-fp-math", NoSignedZeros)
1963 I->setFastMathFlags(FMF);
1966bool NumericalStabilitySanitizer::sanitizeFunction(
1967 Function &
F,
const TargetLibraryInfo &TLI) {
1968 if (!
F.hasFnAttribute(Attribute::SanitizeNumericalStability) ||
1972 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
2068 std::vector<Instruction *> OriginalInstructions;
2069 for (BasicBlock &BB :
F)
2070 for (Instruction &Inst : BB)
2071 OriginalInstructions.emplace_back(&Inst);
2074 ValueToShadowMap ValueToShadow(Config);
2079 std::vector<PHINode *> OriginalPhis;
2080 createShadowArguments(
F, TLI, ValueToShadow);
2081 for (Instruction *
I : OriginalInstructions) {
2083 if (PHINode *Shadow = maybeCreateShadowPhi(*Phi, TLI)) {
2084 OriginalPhis.push_back(Phi);
2085 ValueToShadow.setShadow(*Phi, *Shadow);
2091 for (Instruction *
I : OriginalInstructions)
2092 maybeCreateShadowValue(*
I, TLI, ValueToShadow);
2095 for (Instruction *
I : OriginalInstructions)
2096 propagateShadowValues(*
I, TLI, ValueToShadow);
2099 for (PHINode *Phi : OriginalPhis) {
2100 PHINode *ShadowPhi =
cast<PHINode>(ValueToShadow.getShadow(Phi));
2101 for (
unsigned I :
seq(
Phi->getNumOperands())) {
2103 Value *Shadow = ValueToShadow.getShadow(V);
2115 return !ValueToShadow.empty();
2122 if (CInt && CInt->getValue().getBitWidth() <= 64)
2123 OpSize = CInt->getValue().getZExtValue();
2131bool NumericalStabilitySanitizer::instrumentMemIntrinsic(MemIntrinsic *
MI) {
2134 FunctionCallee SetUnknownFn =
2135 NsanSetUnknownFns.getFunctionFor(
GetMemOpSize(
M->getArgOperand(2)));
2137 Builder.
CreateCall(SetUnknownFn, {
M->getArgOperand(0)});
2140 {
M->getArgOperand(0),
2145 FunctionCallee CopyFn =
2146 NsanCopyFns.getFunctionFor(
GetMemOpSize(
M->getArgOperand(2)));
2150 M->getArgOperand(1)});
2153 M->getArgOperand(1),
2161void NumericalStabilitySanitizer::maybeAddSuffixForNsanInterface(CallBase *CI) {
2169 if (Fn->
getName() ==
"__nsan_dump_shadow_mem") {
2171 "invalid prototype for __nsan_dump_shadow_mem");
2176 const uint64_t shadow_value_type_ids =
2177 (
static_cast<size_t>(Config.byValueType(kLongDouble).getNsanTypeId())
2179 (
static_cast<size_t>(Config.byValueType(kDouble).getNsanTypeId())
2181 static_cast<size_t>(Config.byValueType(kFloat).getNsanTypeId());
2182 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.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
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.
static Attribute::AttrKind getExtAttrForBoolParam(const Triple &T)
StringRef getName(LibFunc F) const
LibFunc getLibFunc(StringRef funcName) const
Searches for a particular function name.
Triple - Helper class for working with autoconf configuration names.
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.
const InstrumentationOptions & getInstrumentationOptions(const LLVMContext &C)
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)