185#include "llvm/IR/IntrinsicsAArch64.h"
186#include "llvm/IR/IntrinsicsX86.h"
216#define DEBUG_TYPE "msan"
219 "Controls which checks to insert");
222 "Controls which instruction to instrument");
245struct MemoryMapParams {
252struct PlatformMemoryMapParams {
253 const MemoryMapParams *bits32;
254 const MemoryMapParams *bits64;
431class MemorySanitizer {
433 MemorySanitizer(
const InstrumentationOptions &Opts,
Module &M,
434 MemorySanitizerOptions
Options)
437 EagerChecks(
Options.EagerChecks) {
442 MemorySanitizer(MemorySanitizer &&) =
delete;
443 MemorySanitizer &operator=(MemorySanitizer &&) =
delete;
444 MemorySanitizer(
const MemorySanitizer &) =
delete;
445 MemorySanitizer &operator=(
const MemorySanitizer &) =
delete;
447 bool sanitizeFunction(
Function &
F, TargetLibraryInfo &TLI);
450 friend struct MemorySanitizerVisitor;
451 friend struct VarArgHelperBase;
452 friend struct VarArgAMD64Helper;
453 friend struct VarArgAArch64Helper;
454 friend struct VarArgPowerPC64Helper;
455 friend struct VarArgPowerPC32Helper;
456 friend struct VarArgSystemZHelper;
457 friend struct VarArgI386Helper;
458 friend struct VarArgGenericHelper;
460 void initializeModule(
Module &M);
461 void initializeCallbacks(
Module &M,
const TargetLibraryInfo &TLI);
462 void createKernelApi(
Module &M,
const TargetLibraryInfo &TLI);
463 void createUserspaceApi(
Module &M,
const TargetLibraryInfo &TLI);
465 template <
typename... ArgsTy>
466 FunctionCallee getOrInsertMsanMetadataFunction(
Module &M, StringRef Name,
469 const InstrumentationOptions &Opts;
493 Value *ParamOriginTLS;
499 Value *RetvalOriginTLS;
505 Value *VAArgOriginTLS;
508 Value *VAArgOverflowSizeTLS;
511 bool CallbacksInitialized =
false;
514 FunctionCallee WarningFn;
518 FunctionCallee MaybeWarningVarSizeFn;
523 FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
525 FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
528 FunctionCallee MsanPoisonStackFn;
532 FunctionCallee MsanChainOriginFn;
535 FunctionCallee MsanSetOriginFn;
538 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
541 StructType *MsanContextStateTy;
542 FunctionCallee MsanGetContextStateFn;
545 FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
551 FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
552 FunctionCallee MsanMetadataPtrForLoad_1_8[4];
553 FunctionCallee MsanMetadataPtrForStore_1_8[4];
554 FunctionCallee MsanInstrumentAsmStoreFn;
557 Value *MsanMetadataAlloca;
560 FunctionCallee getKmsanShadowOriginAccessFn(
bool isStore,
int size);
563 const MemoryMapParams *MapParams;
567 MemoryMapParams CustomMapParams;
569 MDNode *ColdCallWeights;
572 MDNode *OriginStoreWeights;
583 if (!Opts.msan_with_comdat) {
600 O.Kernel =
valueOr(Opts.msan_kernel, O.Kernel);
602 Opts.msan_track_origins.value_or(O.Kernel ? 2 : O.TrackOrigins);
603 O.Recover =
valueOr(Opts.msan_keep_going, O.Kernel || O.Recover);
604 O.EagerChecks =
valueOr(Opts.msan_eager_checks, O.EagerChecks);
625 MemorySanitizer Msan(Opts, *
F.getParent(), MSanOpts);
643 static_cast<PassInfoMixin<MemorySanitizerPass> *
>(
this)->
printPipeline(
644 OS, MapClassName2PassName);
650 if (Options.EagerChecks)
651 OS <<
"eager-checks;";
652 OS <<
"track-origins=" << Options.TrackOrigins;
668template <
typename... ArgsTy>
670MemorySanitizer::getOrInsertMsanMetadataFunction(
Module &M,
StringRef Name,
675 std::forward<ArgsTy>(Args)...);
678 return M.getOrInsertFunction(Name, MsanMetadata,
679 std::forward<ArgsTy>(Args)...);
688 RetvalOriginTLS =
nullptr;
690 ParamOriginTLS =
nullptr;
692 VAArgOriginTLS =
nullptr;
693 VAArgOverflowSizeTLS =
nullptr;
695 WarningFn =
M.getOrInsertFunction(
"__msan_warning",
697 IRB.getVoidTy(), IRB.getInt32Ty());
708 MsanGetContextStateFn =
709 M.getOrInsertFunction(
"__msan_get_context_state", PtrTy);
713 for (
int ind = 0,
size = 1; ind < 4; ind++,
size <<= 1) {
714 std::string name_load =
715 "__msan_metadata_ptr_for_load_" + std::to_string(
size);
716 std::string name_store =
717 "__msan_metadata_ptr_for_store_" + std::to_string(
size);
718 MsanMetadataPtrForLoad_1_8[ind] =
719 getOrInsertMsanMetadataFunction(M, name_load, PtrTy);
720 MsanMetadataPtrForStore_1_8[ind] =
721 getOrInsertMsanMetadataFunction(M, name_store, PtrTy);
724 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
725 M,
"__msan_metadata_ptr_for_load_n", PtrTy, IntptrTy);
726 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
727 M,
"__msan_metadata_ptr_for_store_n", PtrTy, IntptrTy);
730 MsanPoisonAllocaFn =
M.getOrInsertFunction(
731 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
732 MsanUnpoisonAllocaFn =
M.getOrInsertFunction(
733 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
737 return M.getOrInsertGlobal(Name, Ty, [&] {
739 nullptr, Name,
nullptr,
745void MemorySanitizer::createUserspaceApi(
Module &M,
753 StringRef WarningFnName = Recover ?
"__msan_warning_with_origin"
754 :
"__msan_warning_with_origin_noreturn";
755 WarningFn =
M.getOrInsertFunction(WarningFnName,
757 IRB.getVoidTy(), IRB.getInt32Ty());
760 Recover ?
"__msan_warning" :
"__msan_warning_noreturn";
761 WarningFn =
M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
788 IRB.getIntPtrTy(
M.getDataLayout()));
792 unsigned AccessSize = 1 << AccessSizeIndex;
793 std::string FunctionName =
"__msan_maybe_warning_" +
itostr(AccessSize);
794 MaybeWarningFn[AccessSizeIndex] =
M.getOrInsertFunction(
796 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
797 MaybeWarningVarSizeFn =
M.getOrInsertFunction(
798 "__msan_maybe_warning_N", TLI.
getAttrList(
C, {},
false),
799 IRB.getVoidTy(), PtrTy, IRB.getInt64Ty(), IRB.getInt32Ty());
800 FunctionName =
"__msan_maybe_store_origin_" +
itostr(AccessSize);
801 MaybeStoreOriginFn[AccessSizeIndex] =
M.getOrInsertFunction(
803 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
807 MsanSetAllocaOriginWithDescriptionFn =
808 M.getOrInsertFunction(
"__msan_set_alloca_origin_with_descr",
809 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
810 MsanSetAllocaOriginNoDescriptionFn =
811 M.getOrInsertFunction(
"__msan_set_alloca_origin_no_descr",
812 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
813 MsanPoisonStackFn =
M.getOrInsertFunction(
"__msan_poison_stack",
814 IRB.getVoidTy(), PtrTy, IntptrTy);
818void MemorySanitizer::initializeCallbacks(
Module &M,
821 if (CallbacksInitialized)
827 MsanChainOriginFn =
M.getOrInsertFunction(
828 "__msan_chain_origin",
831 MsanSetOriginFn =
M.getOrInsertFunction(
833 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
835 M.getOrInsertFunction(
"__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
837 M.getOrInsertFunction(
"__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
838 MemsetFn =
M.getOrInsertFunction(
"__msan_memset",
840 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
842 MsanInstrumentAsmStoreFn =
M.getOrInsertFunction(
843 "__msan_instrument_asm_store", IRB.getVoidTy(), PtrTy, IntptrTy);
846 createKernelApi(M, TLI);
848 createUserspaceApi(M, TLI);
850 CallbacksInitialized =
true;
856 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
874void MemorySanitizer::initializeModule(
Module &M) {
875 auto &
DL =
M.getDataLayout();
877 TargetTriple =
M.getTargetTriple();
879 bool ShadowPassed = Opts.msan_shadow_base.has_value();
880 bool OriginPassed = Opts.msan_origin_base.has_value();
882 if (ShadowPassed || OriginPassed) {
883 CustomMapParams.AndMask = Opts.msan_and_mask;
884 CustomMapParams.XorMask = Opts.msan_xor_mask;
885 CustomMapParams.ShadowBase = Opts.msan_shadow_base.value_or(0);
886 CustomMapParams.OriginBase = Opts.msan_origin_base.value_or(0);
887 MapParams = &CustomMapParams;
889 switch (TargetTriple.getOS()) {
891 switch (TargetTriple.getArch()) {
906 switch (TargetTriple.getArch()) {
915 switch (TargetTriple.getArch()) {
952 C = &(
M.getContext());
954 IntptrTy = IRB.getIntPtrTy(
DL);
955 OriginTy = IRB.getInt32Ty();
956 PtrTy = IRB.getPtrTy();
961 if (!CompileKernel) {
963 M.getOrInsertGlobal(
"__msan_track_origins", IRB.getInt32Ty(), [&] {
964 return new GlobalVariable(
965 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
966 IRB.getInt32(TrackOrigins),
"__msan_track_origins");
970 M.getOrInsertGlobal(
"__msan_keep_going", IRB.getInt32Ty(), [&] {
971 return new GlobalVariable(M, IRB.getInt32Ty(), true,
972 GlobalValue::WeakODRLinkage,
973 IRB.getInt32(Recover),
"__msan_keep_going");
989 virtual ~VarArgHelper() =
default;
992 virtual void visitCallBase(CallBase &CB,
IRBuilder<> &IRB) = 0;
995 virtual void visitVAStartInst(VAStartInst &
I) = 0;
998 virtual void visitVACopyInst(VACopyInst &
I) = 0;
1004 virtual void finalizeInstrumentation() = 0;
1007struct MemorySanitizerVisitor;
1012 MemorySanitizerVisitor &Visitor);
1019 if (TypeSizeFixed <= 8)
1028class NextNodeIRBuilder :
public IRBuilder<> {
1041struct MemorySanitizerVisitor :
public InstVisitor<MemorySanitizerVisitor> {
1042 const InstrumentationOptions &Opts;
1044 MemorySanitizer &MS;
1046 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1047 std::unique_ptr<VarArgHelper> VAHelper;
1048 const TargetLibraryInfo *TLI;
1055 bool PropagateShadow;
1058 bool PoisonUndefVectors;
1060 struct ShadowOriginAndInsertPoint {
1065 ShadowOriginAndInsertPoint(
Value *S,
Value *O, Instruction *
I)
1066 : Shadow(S), Origin(
O), OrigIns(
I) {}
1069 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1070 SmallSetVector<AllocaInst *, 16> AllocaSet;
1073 int64_t SplittableBlocksCount = 0;
1075 MemorySanitizerVisitor(
Function &
F, MemorySanitizer &MS,
1076 const TargetLibraryInfo &TLI)
1079 bool SanitizeFunction =
F.hasFnAttribute(Attribute::SanitizeMemory) &&
1080 !Opts.msan_disable_checks;
1081 InsertChecks = SanitizeFunction;
1082 PropagateShadow = SanitizeFunction;
1083 PoisonStack = SanitizeFunction && Opts.msan_poison_stack;
1084 PoisonUndef = SanitizeFunction && Opts.msan_poison_undef;
1085 PoisonUndefVectors = SanitizeFunction && Opts.msan_poison_undef_vectors;
1093 MS.initializeCallbacks(*
F.getParent(), TLI);
1096 .CreateIntrinsicWithoutFolding(Intrinsic::donothing, {});
1098 if (MS.CompileKernel) {
1099 IRBuilder<> IRB(FnPrologueEnd);
1100 insertKmsanPrologue(IRB);
1104 <<
"MemorySanitizer is not inserting checks into '"
1105 <<
F.getName() <<
"'\n");
1108 bool instrumentWithCalls(
Value *V) {
1112 ++SplittableBlocksCount;
1113 return Opts.msan_instrumentation_with_call_threshold >= 0 &&
1114 SplittableBlocksCount >
1115 Opts.msan_instrumentation_with_call_threshold;
1118 bool isInPrologue(Instruction &
I) {
1119 return I.getParent() == FnPrologueEnd->
getParent() &&
1128 if (MS.TrackOrigins <= 1)
1130 return IRB.
CreateCall(MS.MsanChainOriginFn, V);
1134 const DataLayout &
DL =
F.getDataLayout();
1135 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1145 TypeSize TS, Align Alignment) {
1146 const DataLayout &
DL =
F.getDataLayout();
1147 const Align IntptrAlignment =
DL.getABITypeAlign(MS.IntptrTy);
1148 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1160 auto [InsertPt,
Index] =
1173 if (Alignment >= IntptrAlignment && IntptrSize >
kOriginSize) {
1174 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1176 for (
unsigned i = 0; i <
Size / IntptrSize; ++i) {
1181 CurrentAlignment = IntptrAlignment;
1194 Value *OriginPtr, Align Alignment) {
1195 const DataLayout &
DL =
F.getDataLayout();
1197 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
1199 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1201 if (!Opts.msan_check_constant_shadow || ConstantShadow->isNullValue()) {
1208 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1215 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1217 if (instrumentWithCalls(ConvertedShadow) &&
1219 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1220 Value *ConvertedShadow2 =
1222 CallBase *CB = IRB.
CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1226 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1230 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1235 void materializeStores() {
1236 for (StoreInst *SI : StoreList) {
1238 Value *Val =
SI->getValueOperand();
1239 Value *Addr =
SI->getPointerOperand();
1240 Value *Shadow =
SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1241 Value *ShadowPtr, *OriginPtr;
1245 std::tie(ShadowPtr, OriginPtr) =
1246 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
true);
1248 [[maybe_unused]] StoreInst *NewSI =
1255 if (MS.TrackOrigins && !
SI->isAtomic())
1256 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1263 if (MS.TrackOrigins < 2)
1266 if (LazyWarningDebugLocationCount.
empty())
1267 for (
const auto &
I : InstrumentationList)
1268 ++LazyWarningDebugLocationCount[
I.OrigIns->getDebugLoc()];
1270 return LazyWarningDebugLocationCount[
DebugLoc] >=
1271 Opts.msan_disambiguate_warning_threshold;
1285 auto NewDebugLoc = OI->getDebugLoc();
1292 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1293 Origin = updateOrigin(Origin, IRBOrigin);
1298 if (MS.CompileKernel || MS.TrackOrigins)
1309 const DataLayout &
DL =
F.getDataLayout();
1310 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1312 if (instrumentWithCalls(ConvertedShadow) && !MS.CompileKernel) {
1314 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1315 Value *ConvertedShadow2 =
1319 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1323 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1327 FunctionCallee Fn = MS.MaybeWarningVarSizeFn;
1330 unsigned ShadowSize =
DL.getTypeAllocSize(ConvertedShadow2->
getType());
1333 {ShadowAlloca, ConstantInt::get(IRB.
getInt64Ty(), ShadowSize),
1334 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1339 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1342 !MS.Recover, MS.ColdCallWeights);
1345 insertWarningFn(IRB, Origin);
1350 void materializeInstructionChecks(
1352 const DataLayout &
DL =
F.getDataLayout();
1355 bool Combine = !MS.TrackOrigins;
1357 Value *Shadow =
nullptr;
1358 for (
const auto &ShadowData : InstructionChecks) {
1359 assert(ShadowData.OrigIns == Instruction);
1362 Value *ConvertedShadow = ShadowData.Shadow;
1365 if (!Opts.msan_check_constant_shadow || ConstantShadow->isNullValue()) {
1371 insertWarningFn(IRB, ShadowData.Origin);
1381 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1386 Shadow = ConvertedShadow;
1390 Shadow = convertToBool(Shadow, IRB,
"_mscmp");
1391 ConvertedShadow = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1392 Shadow = IRB.
CreateOr(Shadow, ConvertedShadow,
"_msor");
1398 materializeOneCheck(IRB, Shadow,
nullptr);
1402 static bool isAArch64SVCount(
Type *Ty) {
1404 return TTy->
getName() ==
"aarch64.svcount";
1410 static bool isScalableNonVectorType(
Type *Ty) {
1411 if (!isAArch64SVCount(Ty))
1412 LLVM_DEBUG(
dbgs() <<
"isScalableNonVectorType: Unexpected type " << *Ty
1418 void materializeChecks() {
1421 SmallPtrSet<Instruction *, 16>
Done;
1424 for (
auto I = InstrumentationList.begin();
1425 I != InstrumentationList.end();) {
1426 auto OrigIns =
I->OrigIns;
1430 auto J = std::find_if(
I + 1, InstrumentationList.end(),
1431 [OrigIns](
const ShadowOriginAndInsertPoint &R) {
1432 return OrigIns != R.OrigIns;
1446 MS.ParamTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1447 {Zero, IRB.getInt32(0)},
"param_shadow");
1448 MS.RetvalTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1449 {Zero, IRB.getInt32(1)},
"retval_shadow");
1450 MS.VAArgTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1451 {Zero, IRB.getInt32(2)},
"va_arg_shadow");
1452 MS.VAArgOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1453 {Zero, IRB.getInt32(3)},
"va_arg_origin");
1454 MS.VAArgOverflowSizeTLS =
1455 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1456 {Zero, IRB.getInt32(4)},
"va_arg_overflow_size");
1457 MS.ParamOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1458 {Zero, IRB.getInt32(5)},
"param_origin");
1459 MS.RetvalOriginTLS =
1460 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1461 {Zero, IRB.getInt32(6)},
"retval_origin");
1463 MS.MsanMetadataAlloca = IRB.
CreateAlloca(MS.MsanMetadata, 0u);
1476 for (Instruction *
I : Instructions)
1480 for (PHINode *PN : ShadowPHINodes) {
1482 PHINode *PNO = MS.TrackOrigins ?
cast<PHINode>(getOrigin(PN)) : nullptr;
1483 size_t NumValues = PN->getNumIncomingValues();
1484 for (
size_t v = 0;
v < NumValues;
v++) {
1485 PNS->
addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1487 PNO->
addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1491 VAHelper->finalizeInstrumentation();
1495 if (Opts.msan_handle_lifetime_intrinsics) {
1496 for (
auto Item : LifetimeStartList) {
1497 instrumentAlloca(*Item.second, Item.first);
1498 AllocaSet.
remove(Item.second);
1503 for (AllocaInst *AI : AllocaSet)
1504 instrumentAlloca(*AI);
1507 materializeChecks();
1511 materializeStores();
1517 Type *getShadowTy(
Value *V) {
return getShadowTy(
V->getType()); }
1528 const DataLayout &
DL =
F.getDataLayout();
1530 uint32_t EltSize =
DL.getTypeSizeInBits(VT->getElementType());
1532 VT->getElementCount());
1535 return ArrayType::get(getShadowTy(AT->getElementType()),
1536 AT->getNumElements());
1540 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1541 Elements.push_back(getShadowTy(
ST->getElementType(i)));
1543 LLVM_DEBUG(
dbgs() <<
"getShadowTy: " << *ST <<
" ===> " << *Res <<
"\n");
1546 if (isScalableNonVectorType(OrigTy)) {
1547 LLVM_DEBUG(
dbgs() <<
"getShadowTy: Scalable non-vector type: " << *OrigTy
1552 uint32_t TypeSize =
DL.getTypeSizeInBits(OrigTy);
1557 Value *collapseStructShadow(StructType *Struct,
Value *Shadow,
1562 for (
unsigned Idx = 0;
Idx <
Struct->getNumElements();
Idx++) {
1565 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1567 if (Aggregator != FalseVal)
1568 Aggregator = IRB.
CreateOr(Aggregator, ShadowBool);
1570 Aggregator = ShadowBool;
1577 Value *collapseArrayShadow(ArrayType *Array,
Value *Shadow,
1579 if (!
Array->getNumElements())
1583 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1585 for (
unsigned Idx = 1;
Idx <
Array->getNumElements();
Idx++) {
1587 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1588 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
1598 return collapseStructShadow(Struct, V, IRB);
1600 return collapseArrayShadow(Array, V, IRB);
1605 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1613 Type *VTy =
V->getType();
1615 return convertToBool(convertShadowToScalar(V, IRB), IRB,
name);
1622 Type *ptrToIntPtrType(
Type *PtrTy)
const {
1624 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1625 VectTy->getElementCount());
1633 return VectorType::get(
1634 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1635 VectTy->getElementCount());
1644 VectTy->getElementCount(),
1645 constToIntPtr(VectTy->getElementType(),
C));
1650 return ConstantInt::get(MS.IntptrTy,
C,
false,
1664 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1667 if (
uint64_t AndMask = MS.MapParams->AndMask)
1668 OffsetLong = IRB.
CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1670 if (
uint64_t XorMask = MS.MapParams->XorMask)
1671 OffsetLong = IRB.
CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1683 std::pair<Value *, Value *>
1685 MaybeAlign Alignment) {
1690 assert(VectTy->getElementType()->isPointerTy());
1692 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1693 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1694 Value *ShadowLong = ShadowOffset;
1695 if (
uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1697 IRB.
CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1700 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1702 Value *OriginPtr =
nullptr;
1703 if (MS.TrackOrigins) {
1704 Value *OriginLong = ShadowOffset;
1705 uint64_t OriginBase = MS.MapParams->OriginBase;
1706 if (OriginBase != 0)
1708 IRB.
CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1711 OriginLong = IRB.
CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1714 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1716 return std::make_pair(ShadowPtr, OriginPtr);
1719 template <
typename... ArgsTy>
1724 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1725 return IRB.
CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1728 return IRB.
CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1731 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(
Value *Addr,
1735 Value *ShadowOriginPtrs;
1736 const DataLayout &
DL =
F.getDataLayout();
1737 TypeSize
Size =
DL.getTypeStoreSize(ShadowTy);
1739 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(
isStore,
Size);
1742 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1744 Value *SizeVal = ConstantInt::get(MS.IntptrTy,
Size);
1745 ShadowOriginPtrs = createMetadataCall(
1747 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1754 return std::make_pair(ShadowPtr, OriginPtr);
1760 std::pair<Value *, Value *> getShadowOriginPtrKernel(
Value *Addr,
1767 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy,
isStore);
1772 Value *ShadowPtrs = ConstantInt::getNullValue(
1774 Value *OriginPtrs =
nullptr;
1775 if (MS.TrackOrigins)
1776 OriginPtrs = ConstantInt::getNullValue(
1778 for (
unsigned i = 0; i < NumElements; ++i) {
1781 auto [ShadowPtr, OriginPtr] =
1782 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy,
isStore);
1785 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1786 if (MS.TrackOrigins)
1788 OriginPtrs, OriginPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1790 return {ShadowPtrs, OriginPtrs};
1793 std::pair<Value *, Value *> getShadowOriginPtr(
Value *Addr,
IRBuilder<> &IRB,
1795 MaybeAlign Alignment,
1797 if (MS.CompileKernel)
1798 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy,
isStore);
1799 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1807 ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg");
1812 if (!MS.TrackOrigins)
1815 ConstantInt::get(MS.IntptrTy, ArgOffset),
1825 Value *getOriginPtrForRetval() {
1827 return MS.RetvalOriginTLS;
1832 assert(!ShadowMap.
count(V) &&
"Values may only have one shadow");
1835 if (SV && !
V->getType()->isVoidTy() && getShadowTy(V) !=
SV->getType()) {
1838 assert(getShadowTy(V) ==
SV->getType() &&
1839 "setShadow called with mismatching types");
1842 ShadowMap[
V] = PropagateShadow ?
SV : getCleanShadow(V);
1847 if (!MS.TrackOrigins)
1849 assert(!OriginMap.
count(V) &&
"Values may only have one origin");
1850 LLVM_DEBUG(
dbgs() <<
"ORIGIN: " << *V <<
" ==> " << *Origin <<
"\n");
1851 OriginMap[
V] = Origin;
1855 Type *ShadowTy = getShadowTy(OrigTy);
1865 Constant *getCleanShadow(
Value *V) {
return getCleanShadow(
V->getType()); }
1873 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
1874 getPoisonedShadow(AT->getElementType()));
1878 SmallVector<Constant *, 4> Vals;
1879 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1880 Vals.
push_back(getPoisonedShadow(
ST->getElementType(i)));
1888 Type *ShadowTy = getShadowTy(V);
1891 return getPoisonedShadow(ShadowTy);
1903 if (!PropagateShadow ||
I->getMetadata(LLVMContext::MD_nosanitize))
1904 return getCleanShadow(V);
1906 Value *Shadow = ShadowMap[
V];
1908 LLVM_DEBUG(
dbgs() <<
"No shadow: " << *V <<
"\n" << *(
I->getParent()));
1909 assert(Shadow &&
"No shadow for a value");
1916 Value *
AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
1917 : getCleanShadow(V);
1923 Value *&ShadowPtr = ShadowMap[
V];
1928 unsigned ArgOffset = 0;
1929 const DataLayout &
DL =
F->getDataLayout();
1930 for (
auto &FArg :
F->args()) {
1931 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
1933 ?
"vscale not fully supported\n"
1934 :
"Arg is not sized\n"));
1936 ShadowPtr = getCleanShadow(V);
1937 setOrigin(
A, getCleanOrigin());
1943 unsigned Size = FArg.hasByValAttr()
1944 ?
DL.getTypeAllocSize(FArg.getParamByValType())
1945 :
DL.getTypeAllocSize(FArg.getType());
1949 if (FArg.hasByValAttr()) {
1953 const Align ArgAlign =
DL.getValueOrABITypeAlignment(
1954 FArg.getParamAlign(), FArg.getParamByValType());
1955 Value *CpShadowPtr, *CpOriginPtr;
1956 std::tie(CpShadowPtr, CpOriginPtr) =
1957 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
1959 if (!PropagateShadow || Overflow) {
1961 EntryIRB.CreateMemSet(
1965 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1967 [[maybe_unused]]
Value *Cpy = EntryIRB.CreateMemCpy(
1968 CpShadowPtr, CopyAlign,
Base, CopyAlign,
Size);
1971 if (MS.TrackOrigins) {
1972 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1976 EntryIRB.CreateMemCpy(
1985 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
1986 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
1987 ShadowPtr = getCleanShadow(V);
1988 setOrigin(
A, getCleanOrigin());
1991 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1992 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg),
Base,
1994 if (MS.TrackOrigins) {
1995 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1996 setOrigin(
A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
2000 <<
" ARG: " << FArg <<
" ==> " << *ShadowPtr <<
"\n");
2006 assert(ShadowPtr &&
"Could not find shadow for an argument");
2013 cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
2014 PoisonUndefVectors) {
2017 for (
unsigned i = 0; i != NumElems; ++i) {
2020 : getCleanShadow(Elem);
2024 LLVM_DEBUG(
dbgs() <<
"Partial undef constant vector: " << *V <<
" ==> "
2025 << *ShadowConstant <<
"\n");
2027 return ShadowConstant;
2033 return getCleanShadow(V);
2037 Value *getShadow(Instruction *
I,
int i) {
2038 return getShadow(
I->getOperand(i));
2043 if (!MS.TrackOrigins)
2046 return getCleanOrigin();
2048 "Unexpected value type in getOrigin()");
2050 if (
I->getMetadata(LLVMContext::MD_nosanitize))
2051 return getCleanOrigin();
2053 Value *Origin = OriginMap[
V];
2054 assert(Origin &&
"Missing origin");
2059 Value *getOrigin(Instruction *
I,
int i) {
2060 return getOrigin(
I->getOperand(i));
2067 void insertCheckShadow(
Value *Shadow,
Value *Origin, Instruction *OrigIns) {
2073 LLVM_DEBUG(
dbgs() <<
"Skipping check of " << *Shadow <<
" before "
2074 << *OrigIns <<
"\n");
2079 if (isScalableNonVectorType(ShadowTy)) {
2080 LLVM_DEBUG(
dbgs() <<
"Skipping check of scalable non-vector " << *Shadow
2081 <<
" before " << *OrigIns <<
"\n");
2087 "Can only insert checks for integer, vector, and aggregate shadow "
2090 InstrumentationList.push_back(
2091 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2099 void insertCheckShadowOf(
Value *Val, Instruction *OrigIns) {
2101 Value *Shadow, *Origin;
2102 if (Opts.msan_check_constant_shadow) {
2103 Shadow = getShadow(Val);
2106 Origin = getOrigin(Val);
2113 insertCheckShadow(Shadow, Origin, OrigIns);
2118 case AtomicOrdering::NotAtomic:
2119 return AtomicOrdering::NotAtomic;
2120 case AtomicOrdering::Unordered:
2121 case AtomicOrdering::Monotonic:
2122 case AtomicOrdering::Release:
2123 return AtomicOrdering::Release;
2124 case AtomicOrdering::Acquire:
2125 case AtomicOrdering::AcquireRelease:
2126 return AtomicOrdering::AcquireRelease;
2127 case AtomicOrdering::SequentiallyConsistent:
2128 return AtomicOrdering::SequentiallyConsistent;
2134 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2135 uint32_t OrderingTable[NumOrderings] = {};
2137 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2138 OrderingTable[(
int)AtomicOrderingCABI::release] =
2139 (int)AtomicOrderingCABI::release;
2140 OrderingTable[(int)AtomicOrderingCABI::consume] =
2141 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2142 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2143 (
int)AtomicOrderingCABI::acq_rel;
2144 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2145 (
int)AtomicOrderingCABI::seq_cst;
2152 case AtomicOrdering::NotAtomic:
2153 return AtomicOrdering::NotAtomic;
2154 case AtomicOrdering::Unordered:
2155 case AtomicOrdering::Monotonic:
2156 case AtomicOrdering::Acquire:
2157 return AtomicOrdering::Acquire;
2158 case AtomicOrdering::Release:
2159 case AtomicOrdering::AcquireRelease:
2160 return AtomicOrdering::AcquireRelease;
2161 case AtomicOrdering::SequentiallyConsistent:
2162 return AtomicOrdering::SequentiallyConsistent;
2168 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2169 uint32_t OrderingTable[NumOrderings] = {};
2171 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2172 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2173 OrderingTable[(int)AtomicOrderingCABI::consume] =
2174 (
int)AtomicOrderingCABI::acquire;
2175 OrderingTable[(int)AtomicOrderingCABI::release] =
2176 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
2177 (int)AtomicOrderingCABI::acq_rel;
2178 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2179 (
int)AtomicOrderingCABI::seq_cst;
2185 using InstVisitor<MemorySanitizerVisitor>
::visit;
2186 void visit(Instruction &
I) {
2187 if (
I.getMetadata(LLVMContext::MD_nosanitize))
2190 if (isInPrologue(
I))
2195 setShadow(&
I, getCleanShadow(&
I));
2196 setOrigin(&
I, getCleanOrigin());
2207 void visitLoadInst(LoadInst &
I) {
2208 assert(
I.getType()->isSized() &&
"Load type must have size");
2209 assert(!
I.getMetadata(LLVMContext::MD_nosanitize));
2210 NextNodeIRBuilder IRB(&
I);
2211 Type *ShadowTy = getShadowTy(&
I);
2212 Value *Addr =
I.getPointerOperand();
2213 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
2215 if (PropagateShadow) {
2216 std::tie(ShadowPtr, OriginPtr) =
2217 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
2221 setShadow(&
I, getCleanShadow(&
I));
2224 if (Opts.msan_check_access_address)
2225 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2230 if (MS.TrackOrigins) {
2231 if (PropagateShadow) {
2236 setOrigin(&
I, getCleanOrigin());
2245 void visitStoreInst(StoreInst &
I) {
2246 StoreList.push_back(&
I);
2247 if (Opts.msan_check_access_address)
2248 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2251 void handleCASOrRMW(Instruction &
I) {
2255 Value *Addr =
I.getOperand(0);
2256 Value *Val =
I.getOperand(1);
2257 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val),
Align(1),
2261 if (Opts.msan_check_access_address)
2262 insertCheckShadowOf(Addr, &
I);
2268 insertCheckShadowOf(Val, &
I);
2272 setShadow(&
I, getCleanShadow(&
I));
2273 setOrigin(&
I, getCleanOrigin());
2276 void visitAtomicRMWInst(AtomicRMWInst &
I) {
2281 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2343 void visitSwitchInst(SwitchInst &SI) {
2346 Value *Val =
SI.getCondition();
2347 Value *ShadowVal = getShadow(Val);
2357 int casesToConsider = Opts.msan_switch_precision;
2359 Value *ShadowCases =
nullptr;
2360 for (
auto Case :
SI.cases()) {
2361 if (casesToConsider <= 0)
2364 Value *Comparator = Case.getCaseValue();
2367 Value *ComparisonShadow = propagateEqualityComparison(
2368 IRB, Val, Comparator, ShadowVal, getShadow(Comparator));
2371 ShadowCases = IRB.
CreateOr(ShadowCases, ComparisonShadow);
2373 ShadowCases = ComparisonShadow;
2379 insertCheckShadow(ShadowCases, getOrigin(Val), &SI);
2383 void visitExtractElementInst(ExtractElementInst &
I) {
2384 insertCheckShadowOf(
I.getOperand(1), &
I);
2388 setOrigin(&
I, getOrigin(&
I, 0));
2391 void visitInsertElementInst(InsertElementInst &
I) {
2392 insertCheckShadowOf(
I.getOperand(2), &
I);
2394 auto *Shadow0 = getShadow(&
I, 0);
2395 auto *Shadow1 = getShadow(&
I, 1);
2398 setOriginForNaryOp(
I);
2401 void visitShuffleVectorInst(ShuffleVectorInst &
I) {
2403 auto *Shadow0 = getShadow(&
I, 0);
2404 auto *Shadow1 = getShadow(&
I, 1);
2407 setOriginForNaryOp(
I);
2411 void visitSExtInst(SExtInst &
I) {
2413 setShadow(&
I, IRB.
CreateSExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2414 setOrigin(&
I, getOrigin(&
I, 0));
2417 void visitZExtInst(ZExtInst &
I) {
2419 setShadow(&
I, IRB.
CreateZExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2420 setOrigin(&
I, getOrigin(&
I, 0));
2423 void visitTruncInst(TruncInst &
I) {
2425 setShadow(&
I, IRB.
CreateTrunc(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2426 setOrigin(&
I, getOrigin(&
I, 0));
2429 void visitBitCastInst(BitCastInst &
I) {
2434 if (CI->isMustTailCall())
2438 setOrigin(&
I, getOrigin(&
I, 0));
2441 void visitAddrSpaceCastInst(AddrSpaceCastInst &
I) {
2444 "_msprop_addrspacecast"));
2445 setOrigin(&
I, getOrigin(&
I, 0));
2448 void visitPtrToIntInst(PtrToIntInst &
I) {
2451 "_msprop_ptrtoint"));
2452 setOrigin(&
I, getOrigin(&
I, 0));
2455 void visitPtrToAddrInst(PtrToAddrInst &
I) {
2458 "_msprop_ptrtoaddr"));
2459 setOrigin(&
I, getOrigin(&
I, 0));
2462 void visitIntToPtrInst(IntToPtrInst &
I) {
2465 "_msprop_inttoptr"));
2466 setOrigin(&
I, getOrigin(&
I, 0));
2487 void handleGenericVectorConvertIntrinsic(Instruction &
I,
bool FixedPoint) {
2488 [[maybe_unused]]
unsigned NumArgs =
I.getNumOperands();
2490 NumArgs = CI->arg_size();
2494 Value *Precision =
I.getOperand(1);
2495 insertCheckShadowOf(Precision, &
I);
2501 Value *S0 = getShadow(&
I, 0);
2511 setShadow(&
I, OutShadow);
2512 setOriginForNaryOp(
I);
2515 void visitFPToSIInst(CastInst &
I) {
2516 handleGenericVectorConvertIntrinsic(
I,
false);
2518 void visitFPToUIInst(CastInst &
I) {
2519 handleGenericVectorConvertIntrinsic(
I,
false);
2521 void visitSIToFPInst(CastInst &
I) {
2522 handleGenericVectorConvertIntrinsic(
I,
false);
2524 void visitUIToFPInst(CastInst &
I) {
2525 handleGenericVectorConvertIntrinsic(
I,
false);
2528 void visitFPExtInst(CastInst &
I) {
2529 handleGenericVectorConvertIntrinsic(
I,
false);
2531 void visitFPTruncInst(CastInst &
I) {
2532 handleGenericVectorConvertIntrinsic(
I,
false);
2553 assert(
V1->getType()->isIntOrIntVectorTy());
2564 return IRB.
CreateOr({S1S2, V1S2, S1V2});
2568 void visitAnd(BinaryOperator &
I) {
2571 Value *V2 =
I.getOperand(1);
2573 Value *S2 = getShadow(&
I, 1);
2575 Value *OutShadow = handleBitwiseAnd(IRB,
V1, V2,
S1, S2);
2577 setShadow(&
I, OutShadow);
2578 setOriginForNaryOp(
I);
2581 void visitOr(BinaryOperator &
I) {
2594 Value *S2 = getShadow(&
I, 1);
2596 Value *V2 =
I.getOperand(1);
2600 assert(
V1->getType()->isIntOrIntVectorTy());
2616 if (Opts.msan_precise_disjoint_or &&
2621 S = IRB.
CreateOr(S, DisjointOrShadow,
"_ms_disjoint");
2625 setOriginForNaryOp(
I);
2643 template <
bool CombineShadow>
class Combiner {
2644 Value *Shadow =
nullptr;
2645 Value *Origin =
nullptr;
2647 MemorySanitizerVisitor *MSV;
2650 Combiner(MemorySanitizerVisitor *MSV,
IRBuilder<> &IRB)
2651 : IRB(IRB), MSV(MSV) {}
2655 if (CombineShadow) {
2660 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2661 Shadow = IRB.
CreateOr(Shadow, OpShadow,
"_msprop");
2665 if (MSV->MS.TrackOrigins) {
2672 if (!ConstOrigin || !ConstOrigin->
isNullValue()) {
2673 Value *
Cond = MSV->convertToBool(OpShadow, IRB);
2683 Value *OpShadow = MSV->getShadow(V);
2684 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) :
nullptr;
2685 return Add(OpShadow, OpOrigin);
2690 void Done(Instruction *
I) {
2691 if (CombineShadow) {
2693 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(
I));
2694 MSV->setShadow(
I, Shadow);
2696 if (MSV->MS.TrackOrigins) {
2698 MSV->setOrigin(
I, Origin);
2704 void DoneAndStoreOrigin(TypeSize TS,
Value *OriginPtr) {
2705 if (MSV->MS.TrackOrigins) {
2712 using ShadowAndOriginCombiner = Combiner<true>;
2713 using OriginCombiner = Combiner<false>;
2716 void setOriginForNaryOp(Instruction &
I) {
2717 if (!MS.TrackOrigins)
2720 OriginCombiner OC(
this, IRB);
2721 for (Use &
Op :
I.operands())
2726 size_t VectorOrPrimitiveTypeSizeInBits(
Type *Ty) {
2728 "Vector of pointers is not a valid shadow type");
2738 Type *srcTy =
V->getType();
2741 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2742 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2743 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2761 Type *ShadowTy = getShadowTy(V);
2762 if (
V->getType() == ShadowTy)
2764 if (
V->getType()->isPtrOrPtrVectorTy())
2771 void handleShadowOr(Instruction &
I) {
2773 ShadowAndOriginCombiner SC(
this, IRB);
2774 for (Use &
Op :
I.operands())
2801 Value *horizontalReduce(IntrinsicInst &
I,
unsigned ReductionFactor,
2802 unsigned Shards,
Value *VectorA,
Value *VectorB) {
2807 [[maybe_unused]]
unsigned TotalNumElems = NumElems;
2813 assert(NumElems % (ReductionFactor * Shards) == 0);
2818 for (
unsigned i = 0; i < ReductionFactor; i++) {
2819 SmallVector<int, 16>
Mask;
2821 for (
unsigned j = 0;
j < Shards;
j++) {
2822 unsigned Offset = NumElems / Shards *
j;
2824 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2828 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2853 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards) {
2854 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2856 assert(
I.getType()->isVectorTy());
2857 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2859 [[maybe_unused]] FixedVectorType *ParamType =
2863 [[maybe_unused]] FixedVectorType *
ReturnType =
2871 Value *FirstArgShadow = getShadow(&
I, 0);
2872 Value *SecondArgShadow =
nullptr;
2873 if (
I.arg_size() == 2)
2874 SecondArgShadow = getShadow(&
I, 1);
2876 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2877 FirstArgShadow, SecondArgShadow);
2879 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2881 setShadow(&
I, OrShadow);
2882 setOriginForNaryOp(
I);
2892 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards,
2893 int ReinterpretElemWidth) {
2894 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2896 assert(
I.getType()->isVectorTy());
2897 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2899 FixedVectorType *ParamType =
2904 [[maybe_unused]] FixedVectorType *
ReturnType =
2911 FixedVectorType *ReinterpretShadowTy =
nullptr;
2919 Value *FirstArgShadow = getShadow(&
I, 0);
2920 FirstArgShadow = IRB.
CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
2930 Value *SecondArgShadow =
nullptr;
2931 if (
I.arg_size() == 2) {
2932 SecondArgShadow = getShadow(&
I, 1);
2933 SecondArgShadow = IRB.
CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
2936 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2937 FirstArgShadow, SecondArgShadow);
2939 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2941 setShadow(&
I, OrShadow);
2942 setOriginForNaryOp(
I);
2945 void visitFNeg(UnaryOperator &
I) { handleShadowOr(
I); }
2956 void handleMulByConstant(BinaryOperator &
I, Constant *ConstArg,
2962 Type *EltTy = VTy->getElementType();
2964 for (
unsigned Idx = 0;
Idx < NumElements; ++
Idx) {
2965 if (ConstantInt *Elt =
2967 const APInt &
V = Elt->getValue();
2968 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
2969 Elements.push_back(ConstantInt::get(EltTy, V2));
2971 Elements.push_back(ConstantInt::get(EltTy, 1));
2977 const APInt &
V = Elt->getValue();
2978 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
2979 ShadowMul = ConstantInt::get(Ty, V2);
2981 ShadowMul = ConstantInt::get(Ty, 1);
2987 IRB.
CreateMul(getShadow(OtherArg), ShadowMul,
"msprop_mul_cst"));
2988 setOrigin(&
I, getOrigin(OtherArg));
2991 void visitMul(BinaryOperator &
I) {
2994 if (constOp0 && !constOp1)
2995 handleMulByConstant(
I, constOp0,
I.getOperand(1));
2996 else if (constOp1 && !constOp0)
2997 handleMulByConstant(
I, constOp1,
I.getOperand(0));
3002 void visitFAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3003 void visitFSub(BinaryOperator &
I) { handleShadowOr(
I); }
3004 void visitFMul(BinaryOperator &
I) { handleShadowOr(
I); }
3005 void visitAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3006 void visitSub(BinaryOperator &
I) { handleShadowOr(
I); }
3007 void visitXor(BinaryOperator &
I) { handleShadowOr(
I); }
3009 void handleIntegerDiv(Instruction &
I) {
3012 insertCheckShadowOf(
I.getOperand(1), &
I);
3013 setShadow(&
I, getShadow(&
I, 0));
3014 setOrigin(&
I, getOrigin(&
I, 0));
3017 void visitUDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3018 void visitSDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3019 void visitURem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3020 void visitSRem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3024 void visitFDiv(BinaryOperator &
I) { handleShadowOr(
I); }
3025 void visitFRem(BinaryOperator &
I) { handleShadowOr(
I); }
3031 void handleEqualityComparison(ICmpInst &
I) {
3035 Value *Sa = getShadow(
A);
3036 Value *Sb = getShadow(
B);
3038 Value *Si = propagateEqualityComparison(IRB,
A,
B, Sa, Sb);
3041 setOriginForNaryOp(
I);
3049 void handleRelationalComparisonExact(ICmpInst &
I) {
3053 Value *Sa = getShadow(
A);
3054 Value *Sb = getShadow(
B);
3065 bool IsSigned =
I.isSigned();
3067 auto GetMinMaxUnsigned = [&](
Value *
V,
Value *S) {
3077 V = IRB.
CreateXor(V, ConstantInt::get(
V->getType(), MinVal));
3082 return std::make_pair(Min, Max);
3085 auto [Amin, Amax] = GetMinMaxUnsigned(
A, Sa);
3086 auto [Bmin, Bmax] = GetMinMaxUnsigned(
B, Sb);
3092 setOriginForNaryOp(
I);
3099 void handleSignedRelationalComparison(ICmpInst &
I) {
3104 op =
I.getOperand(0);
3105 pre =
I.getPredicate();
3107 op =
I.getOperand(1);
3108 pre =
I.getSwappedPredicate();
3121 setShadow(&
I, Shadow);
3122 setOrigin(&
I, getOrigin(
op));
3128 void visitICmpInst(ICmpInst &
I) {
3129 if (!Opts.msan_handle_icmp) {
3133 if (
I.isEquality()) {
3134 handleEqualityComparison(
I);
3139 if (Opts.msan_handle_icmp_exact) {
3140 handleRelationalComparisonExact(
I);
3144 handleSignedRelationalComparison(
I);
3150 handleRelationalComparisonExact(
I);
3157 void visitFCmpInst(FCmpInst &
I) { handleShadowOr(
I); }
3159 void handleShift(BinaryOperator &
I) {
3164 Value *S2 = getShadow(&
I, 1);
3167 Value *V2 =
I.getOperand(1);
3169 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3170 setOriginForNaryOp(
I);
3173 void visitShl(BinaryOperator &
I) { handleShift(
I); }
3174 void visitAShr(BinaryOperator &
I) { handleShift(
I); }
3175 void visitLShr(BinaryOperator &
I) { handleShift(
I); }
3177 void handleFunnelShift(IntrinsicInst &
I) {
3181 Value *S0 = getShadow(&
I, 0);
3183 Value *S2 = getShadow(&
I, 2);
3186 Value *V2 =
I.getOperand(2);
3189 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3190 setOriginForNaryOp(
I);
3198 void handleGenericBitManipulation(IntrinsicInst &
I) {
3200 Type *ShadowTy = getShadowTy(&
I);
3203 Value *SMask = getShadow(&
I, 1);
3208 if (
Function *Func =
I.getCalledFunction())
3209 S = IRB.
CreateCall(Func, {getShadow(&
I, 0),
I.getOperand(1)});
3212 {getShadow(&I, 0), I.getOperand(1)});
3215 setOriginForNaryOp(
I);
3228 void visitMemMoveInst(MemMoveInst &
I) {
3229 getShadow(
I.getArgOperand(1));
3232 {I.getArgOperand(0), I.getArgOperand(1),
3233 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3251 void visitMemCpyInst(MemCpyInst &
I) {
3252 getShadow(
I.getArgOperand(1));
3255 {I.getArgOperand(0), I.getArgOperand(1),
3256 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3261 void visitMemSetInst(MemSetInst &
I) {
3265 {I.getArgOperand(0),
3266 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3267 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3271 void visitVAStartInst(VAStartInst &
I) { VAHelper->visitVAStartInst(
I); }
3273 void visitVACopyInst(VACopyInst &
I) { VAHelper->visitVACopyInst(
I); }
3279 bool handleVectorStoreIntrinsic(IntrinsicInst &
I) {
3283 Value *Addr =
I.getArgOperand(0);
3284 Value *Shadow = getShadow(&
I, 1);
3285 Value *ShadowPtr, *OriginPtr;
3289 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3293 if (Opts.msan_check_access_address)
3294 insertCheckShadowOf(Addr, &
I);
3297 if (MS.TrackOrigins)
3306 bool handleVectorLoadIntrinsic(IntrinsicInst &
I) {
3310 Value *Addr =
I.getArgOperand(0);
3312 Type *ShadowTy = getShadowTy(&
I);
3313 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
3314 if (PropagateShadow) {
3318 std::tie(ShadowPtr, OriginPtr) =
3319 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
3323 setShadow(&
I, getCleanShadow(&
I));
3326 if (Opts.msan_check_access_address)
3327 insertCheckShadowOf(Addr, &
I);
3329 if (MS.TrackOrigins) {
3330 if (PropagateShadow)
3331 setOrigin(&
I, IRB.
CreateLoad(MS.OriginTy, OriginPtr));
3333 setOrigin(&
I, getCleanOrigin());
3353 [[maybe_unused]]
bool
3354 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &
I,
3355 unsigned int trailingFlags) {
3356 Type *RetTy =
I.getType();
3360 unsigned NumArgOperands =
I.arg_size();
3361 assert(NumArgOperands >= trailingFlags);
3362 for (
unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3363 Type *Ty =
I.getArgOperand(i)->getType();
3369 ShadowAndOriginCombiner SC(
this, IRB);
3370 for (
unsigned i = 0; i < NumArgOperands; ++i)
3371 SC.Add(
I.getArgOperand(i));
3388 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &
I) {
3389 unsigned NumArgOperands =
I.arg_size();
3390 if (NumArgOperands == 0)
3393 if (NumArgOperands == 2 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3394 I.getArgOperand(1)->getType()->isVectorTy() &&
3395 I.getType()->isVoidTy() && !
I.onlyReadsMemory()) {
3397 return handleVectorStoreIntrinsic(
I);
3400 if (NumArgOperands == 1 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3401 I.getType()->isVectorTy() &&
I.onlyReadsMemory()) {
3403 return handleVectorLoadIntrinsic(
I);
3406 if (
I.doesNotAccessMemory())
3407 if (maybeHandleSimpleNomemIntrinsic(
I, 0))
3415 bool maybeHandleUnknownIntrinsic(IntrinsicInst &
I) {
3416 if (maybeHandleUnknownIntrinsicUnlogged(
I)) {
3417 if (Opts.msan_dump_heuristic_instructions)
3418 dumpInst(
I,
"Heuristic");
3420 LLVM_DEBUG(
dbgs() <<
"UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " <<
I
3427 void handleInvariantGroup(IntrinsicInst &
I) {
3428 setShadow(&
I, getShadow(&
I, 0));
3429 setOrigin(&
I, getOrigin(&
I, 0));
3432 void handleLifetimeStart(IntrinsicInst &
I) {
3437 LifetimeStartList.push_back(std::make_pair(&
I, AI));
3440 void handleBswap(IntrinsicInst &
I) {
3443 Type *OpType =
Op->getType();
3446 setOrigin(&
I, getOrigin(
Op));
3467 void handleCountLeadingTrailingZeros(IntrinsicInst &
I) {
3469 Value *Src =
I.getArgOperand(0);
3470 Value *SrcShadow = getShadow(Src);
3474 I.getType(),
I.getIntrinsicID(), {Src, False});
3476 I.getType(),
I.getIntrinsicID(), {SrcShadow, False});
3479 ConcreteZerosCount, ShadowZerosCount,
"_mscz_cmp_zeros");
3481 Value *NotAllZeroShadow =
3483 Value *OutputShadow =
3484 IRB.
CreateAnd(CompareConcreteZeros, NotAllZeroShadow,
"_mscz_main");
3490 OutputShadow = IRB.
CreateOr(OutputShadow, BoolZeroPoison,
"_mscz_bs");
3493 OutputShadow = IRB.
CreateSExt(OutputShadow, getShadowTy(Src),
"_mscz_os");
3495 setShadow(&
I, OutputShadow);
3496 setOriginForNaryOp(
I);
3505 FixedVectorType *maybeShrinkVectorShadowType(
Value *Src, IntrinsicInst &
I) {
3525 Value *maybeExtendVectorShadowWithZeros(
Value *Shadow, IntrinsicInst &
I) {
3530 Value *FullShadow = getCleanShadow(&
I);
3531 unsigned ShadowNumElems =
3533 unsigned FullShadowNumElems =
3536 assert((ShadowNumElems == FullShadowNumElems) ||
3537 (ShadowNumElems * 2 == FullShadowNumElems));
3539 if (ShadowNumElems == FullShadowNumElems) {
3540 FullShadow = Shadow;
3544 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3569 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &
I,
3570 bool HasRoundingMode) {
3571 if (HasRoundingMode) {
3579 Value *Src =
I.getArgOperand(0);
3580 assert(Src->getType()->isVectorTy());
3584 VectorType *ShadowType = maybeShrinkVectorShadowType(Src,
I);
3587 Value *S0 = getShadow(&
I, 0);
3599 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow,
I);
3601 setShadow(&
I, FullShadow);
3602 setOriginForNaryOp(
I);
3623 void handleSSEVectorConvertIntrinsic(IntrinsicInst &
I,
int NumUsedElements,
3624 bool HasRoundingMode =
false) {
3626 Value *CopyOp, *ConvertOp;
3628 assert((!HasRoundingMode ||
3630 "Invalid rounding mode");
3632 switch (
I.arg_size() - HasRoundingMode) {
3634 CopyOp =
I.getArgOperand(0);
3635 ConvertOp =
I.getArgOperand(1);
3638 ConvertOp =
I.getArgOperand(0);
3652 Value *ConvertShadow = getShadow(ConvertOp);
3653 Value *AggShadow =
nullptr;
3656 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
3657 for (
int i = 1; i < NumUsedElements; ++i) {
3659 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
3660 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
3663 AggShadow = ConvertShadow;
3666 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &
I);
3673 Value *ResultShadow = getShadow(CopyOp);
3675 for (
int i = 0; i < NumUsedElements; ++i) {
3677 ResultShadow, ConstantInt::getNullValue(EltTy),
3680 setShadow(&
I, ResultShadow);
3681 setOrigin(&
I, getOrigin(CopyOp));
3683 setShadow(&
I, getCleanShadow(&
I));
3684 setOrigin(&
I, getCleanOrigin());
3692 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
3695 return CreateShadowCast(IRB, S2,
T,
true);
3703 return CreateShadowCast(IRB, S2,
T,
true);
3720 void handleVectorShiftIntrinsic(IntrinsicInst &
I,
bool Variable) {
3726 Value *S2 = getShadow(&
I, 1);
3728 : Lower64ShadowExtend(IRB, S2, getShadowTy(&
I));
3730 Value *V2 =
I.getOperand(1);
3732 {IRB.CreateBitCast(S1, V1->getType()), V2});
3734 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3735 setOriginForNaryOp(
I);
3740 Type *getMMXVectorTy(
unsigned EltSizeInBits,
3741 unsigned X86_MMXSizeInBits = 64) {
3742 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3743 "Illegal MMX vector element size");
3745 X86_MMXSizeInBits / EltSizeInBits);
3752 case Intrinsic::x86_sse2_packsswb_128:
3753 case Intrinsic::x86_sse2_packuswb_128:
3754 return Intrinsic::x86_sse2_packsswb_128;
3756 case Intrinsic::x86_sse2_packssdw_128:
3757 case Intrinsic::x86_sse41_packusdw:
3758 return Intrinsic::x86_sse2_packssdw_128;
3760 case Intrinsic::x86_avx2_packsswb:
3761 case Intrinsic::x86_avx2_packuswb:
3762 return Intrinsic::x86_avx2_packsswb;
3764 case Intrinsic::x86_avx2_packssdw:
3765 case Intrinsic::x86_avx2_packusdw:
3766 return Intrinsic::x86_avx2_packssdw;
3768 case Intrinsic::x86_mmx_packsswb:
3769 case Intrinsic::x86_mmx_packuswb:
3770 return Intrinsic::x86_mmx_packsswb;
3772 case Intrinsic::x86_mmx_packssdw:
3773 return Intrinsic::x86_mmx_packssdw;
3775 case Intrinsic::x86_avx512_packssdw_512:
3776 case Intrinsic::x86_avx512_packusdw_512:
3777 return Intrinsic::x86_avx512_packssdw_512;
3779 case Intrinsic::x86_avx512_packsswb_512:
3780 case Intrinsic::x86_avx512_packuswb_512:
3781 return Intrinsic::x86_avx512_packsswb_512;
3797 void handleVectorPackIntrinsic(IntrinsicInst &
I,
3798 unsigned MMXEltSizeInBits = 0) {
3802 Value *S2 = getShadow(&
I, 1);
3803 assert(
S1->getType()->isVectorTy());
3809 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) :
S1->
getType();
3810 if (MMXEltSizeInBits) {
3818 if (MMXEltSizeInBits) {
3824 {S1_ext, S2_ext},
nullptr,
3825 "_msprop_vector_pack");
3826 if (MMXEltSizeInBits)
3829 setOriginForNaryOp(
I);
3833 Constant *createDppMask(
unsigned Width,
unsigned Mask) {
3834 SmallVector<Constant *, 4>
R(Width);
3846 const unsigned Width =
3853 Value *DstMaskV = createDppMask(Width, DstMask);
3870 void handleDppIntrinsic(IntrinsicInst &
I) {
3873 Value *S0 = getShadow(&
I, 0);
3877 const unsigned Width =
3879 assert(Width == 2 || Width == 4 || Width == 8);
3882 const unsigned SrcMask =
Mask >> 4;
3883 const unsigned DstMask =
Mask & 0xf;
3886 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3891 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3898 setOriginForNaryOp(
I);
3902 C = CreateAppToShadowCast(IRB,
C);
3911 void handleBlendvIntrinsic(IntrinsicInst &
I) {
3916 Value *Sc = getShadow(&
I, 2);
3917 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
3922 C = convertBlendvToSelectMask(IRB,
C);
3923 Sc = convertBlendvToSelectMask(IRB, Sc);
3929 handleSelectLikeInst(
I,
C,
T,
F);
3933 void handleVectorSadIntrinsic(IntrinsicInst &
I,
bool IsMMX =
false) {
3934 const unsigned SignificantBitsPerResultElement = 16;
3936 unsigned ZeroBitsPerResultElement =
3940 auto *Shadow0 = getShadow(&
I, 0);
3941 auto *Shadow1 = getShadow(&
I, 1);
3946 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
3949 setOriginForNaryOp(
I);
3973 void handleVectorDotProductIntrinsic(IntrinsicInst &
I,
3974 unsigned ReductionFactor,
3976 unsigned EltSizeInBits,
3980 [[maybe_unused]] FixedVectorType *
ReturnType =
3985 Value *Va =
nullptr;
3986 Value *Vb =
nullptr;
3987 Value *Sa =
nullptr;
3988 Value *Sb =
nullptr;
3990 assert(
I.arg_size() == 2 ||
I.arg_size() == 3);
3991 if (
I.arg_size() == 2) {
3994 Va =
I.getOperand(0);
3995 Vb =
I.getOperand(1);
3997 Sa = getShadow(&
I, 0);
3998 Sb = getShadow(&
I, 1);
3999 }
else if (
I.arg_size() == 3) {
4001 Va =
I.getOperand(1);
4002 Vb =
I.getOperand(2);
4004 Sa = getShadow(&
I, 1);
4005 Sb = getShadow(&
I, 2);
4022 Sa, getPclmulMask(Width, Lanes ==
kOddLanes));
4024 Sb, getPclmulMask(Width, Lanes ==
kOddLanes));
4034 if (
I.arg_size() == 3) {
4035 [[maybe_unused]]
auto *AccumulatorType =
4037 assert(AccumulatorType == ReturnType);
4040 FixedVectorType *ImplicitReturnType =
4043 if (EltSizeInBits) {
4045 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4057 ReturnType->getNumElements() * ReductionFactor);
4074 VaInt = CreateAppToShadowCast(IRB, Va);
4075 VbInt = CreateAppToShadowCast(IRB, Vb);
4082 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4104 ImplicitReturnType);
4109 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&
I));
4112 if (
I.arg_size() == 3)
4113 OutShadow = IRB.
CreateOr(OutShadow, getShadow(&
I, 0));
4115 setShadow(&
I, OutShadow);
4116 setOriginForNaryOp(
I);
4133 void handleVectorComparePackedIntrinsic(IntrinsicInst &
I,
4134 bool PredicateAsOperand) {
4135 if (PredicateAsOperand) {
4137 assert(
I.paramHasAttr(2, Attribute::ImmArg));
4145 Type *ResTy = getShadowTy(&
I);
4146 auto *Shadow0 = getShadow(&
I, 0);
4147 auto *Shadow1 = getShadow(&
I, 1);
4152 setOriginForNaryOp(
I);
4158 void handleVectorCompareScalarIntrinsic(IntrinsicInst &
I) {
4160 auto *Shadow0 = getShadow(&
I, 0);
4161 auto *Shadow1 = getShadow(&
I, 1);
4163 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&
I));
4165 setOriginForNaryOp(
I);
4174 void handleVectorReduceIntrinsic(IntrinsicInst &
I,
bool AllowShadowCast) {
4179 if (AllowShadowCast)
4180 S = CreateShadowCast(IRB, S, getShadowTy(&
I));
4184 setOriginForNaryOp(
I);
4194 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &
I) {
4198 Value *Shadow0 = getShadow(&
I, 0);
4204 setOriginForNaryOp(
I);
4224 void handleVectorPartialReduceAddIntrinsic(IntrinsicInst &
I) {
4229 [[maybe_unused]]
Value *Addends =
I.getArgOperand(1);
4243 Value *SAcc = getShadow(&
I, 0);
4244 Value *SAdd = getShadow(&
I, 1);
4264 SAcc->
getType(), Intrinsic::vector_partial_reduce_add, {SAcc, SAdd});
4269 setShadow(&
I, SOutput);
4270 setOriginForNaryOp(
I);
4276 void handleVectorReduceOrIntrinsic(IntrinsicInst &
I) {
4280 Value *OperandShadow = getShadow(&
I, 0);
4282 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
4290 setOrigin(&
I, getOrigin(&
I, 0));
4296 void handleVectorReduceAndIntrinsic(IntrinsicInst &
I) {
4300 Value *OperandShadow = getShadow(&
I, 0);
4301 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
4309 setOrigin(&
I, getOrigin(&
I, 0));
4312 void handleStmxcsr(IntrinsicInst &
I) {
4314 Value *Addr =
I.getArgOperand(0);
4317 getShadowOriginPtr(Addr, IRB, Ty,
Align(1),
true).first;
4321 if (Opts.msan_check_access_address)
4322 insertCheckShadowOf(Addr, &
I);
4325 void handleLdmxcsr(IntrinsicInst &
I) {
4330 Value *Addr =
I.getArgOperand(0);
4333 Value *ShadowPtr, *OriginPtr;
4334 std::tie(ShadowPtr, OriginPtr) =
4335 getShadowOriginPtr(Addr, IRB, Ty, Alignment,
false);
4337 if (Opts.msan_check_access_address)
4338 insertCheckShadowOf(Addr, &
I);
4341 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
4343 insertCheckShadow(Shadow, Origin, &
I);
4346 void handleMaskedExpandLoad(IntrinsicInst &
I) {
4348 Value *Ptr =
I.getArgOperand(0);
4349 MaybeAlign
Align =
I.getParamAlign(0);
4351 Value *PassThru =
I.getArgOperand(2);
4353 if (Opts.msan_check_access_address) {
4354 insertCheckShadowOf(Ptr, &
I);
4355 insertCheckShadowOf(Mask, &
I);
4358 if (!PropagateShadow) {
4359 setShadow(&
I, getCleanShadow(&
I));
4360 setOrigin(&
I, getCleanOrigin());
4364 Type *ShadowTy = getShadowTy(&
I);
4366 auto [ShadowPtr, OriginPtr] =
4367 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
false);
4371 getShadow(PassThru),
"_msmaskedexpload");
4373 setShadow(&
I, Shadow);
4376 setOrigin(&
I, getCleanOrigin());
4379 void handleMaskedCompressStore(IntrinsicInst &
I) {
4382 Value *Ptr =
I.getArgOperand(1);
4383 MaybeAlign
Align =
I.getParamAlign(1);
4386 if (Opts.msan_check_access_address) {
4387 insertCheckShadowOf(Ptr, &
I);
4388 insertCheckShadowOf(Mask, &
I);
4392 Type *ElementShadowTy =
4394 auto [ShadowPtr, OriginPtrs] =
4395 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
true);
4402 void handleMaskedGather(IntrinsicInst &
I) {
4404 Value *Ptrs =
I.getArgOperand(0);
4407 Value *PassThru =
I.getArgOperand(2);
4409 Type *PtrsShadowTy = getShadowTy(Ptrs);
4410 if (Opts.msan_check_access_address) {
4411 insertCheckShadowOf(Mask, &
I);
4415 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4418 if (!PropagateShadow) {
4419 setShadow(&
I, getCleanShadow(&
I));
4420 setOrigin(&
I, getCleanOrigin());
4424 Type *ShadowTy = getShadowTy(&
I);
4426 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4427 Ptrs, IRB, ElementShadowTy, Alignment,
false);
4431 getShadow(PassThru),
"_msmaskedgather");
4433 setShadow(&
I, Shadow);
4436 setOrigin(&
I, getCleanOrigin());
4439 void handleMaskedScatter(IntrinsicInst &
I) {
4442 Value *Ptrs =
I.getArgOperand(1);
4446 Type *PtrsShadowTy = getShadowTy(Ptrs);
4447 if (Opts.msan_check_access_address) {
4448 insertCheckShadowOf(Mask, &
I);
4452 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4456 Type *ElementShadowTy =
4458 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4459 Ptrs, IRB, ElementShadowTy, Alignment,
true);
4470 void handleMaskedStore(IntrinsicInst &
I) {
4472 Value *
V =
I.getArgOperand(0);
4473 Value *Ptr =
I.getArgOperand(1);
4476 Value *Shadow = getShadow(V);
4478 if (Opts.msan_check_access_address) {
4479 insertCheckShadowOf(Ptr, &
I);
4480 insertCheckShadowOf(Mask, &
I);
4485 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4486 Ptr, IRB, Shadow->
getType(), Alignment,
true);
4490 if (!MS.TrackOrigins)
4493 auto &
DL =
F.getDataLayout();
4494 paintOrigin(IRB, getOrigin(V), OriginPtr,
4503 void handleMaskedLoad(IntrinsicInst &
I) {
4505 Value *Ptr =
I.getArgOperand(0);
4508 Value *PassThru =
I.getArgOperand(2);
4510 if (Opts.msan_check_access_address) {
4511 insertCheckShadowOf(Ptr, &
I);
4512 insertCheckShadowOf(Mask, &
I);
4515 if (!PropagateShadow) {
4516 setShadow(&
I, getCleanShadow(&
I));
4517 setOrigin(&
I, getCleanOrigin());
4521 Type *ShadowTy = getShadowTy(&
I);
4522 Value *ShadowPtr, *OriginPtr;
4523 std::tie(ShadowPtr, OriginPtr) =
4524 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment,
false);
4526 getShadow(PassThru),
"_msmaskedld"));
4528 if (!MS.TrackOrigins)
4535 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
4540 setOrigin(&
I, Origin);
4550 void handleMaskedIntegerDivRem(IntrinsicInst &
I) {
4553 Value *Dividend =
I.getArgOperand(0);
4554 Value *Divisor =
I.getArgOperand(1);
4557 insertCheckShadowOf(Mask, &
I);
4560 Mask, getShadow(Divisor), getCleanShadow(Divisor),
"_msmaskeddivisor");
4561 insertCheckShadow(MaskedDivisorShadow, getOrigin(Divisor), &
I);
4563 if (!PropagateShadow) {
4564 setShadow(&
I, getCleanShadow(&
I));
4565 setOrigin(&
I, getCleanOrigin());
4570 getPoisonedShadow(&
I),
"_msmaskeddiv"));
4571 setOrigin(&
I, getOrigin(Dividend));
4587 void handleAVXMaskedStore(IntrinsicInst &
I) {
4592 Value *Dst =
I.getArgOperand(0);
4593 assert(Dst->getType()->isPointerTy() &&
"Destination is not a pointer!");
4598 Value *Src =
I.getArgOperand(2);
4603 Value *SrcShadow = getShadow(Src);
4605 if (Opts.msan_check_access_address) {
4606 insertCheckShadowOf(Dst, &
I);
4607 insertCheckShadowOf(Mask, &
I);
4610 Value *DstShadowPtr;
4611 Value *DstOriginPtr;
4612 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4613 Dst, IRB, SrcShadow->
getType(), Alignment,
true);
4615 SmallVector<Value *, 2> ShadowArgs;
4616 ShadowArgs.
append(1, DstShadowPtr);
4617 ShadowArgs.
append(1, Mask);
4625 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
4628 if (!MS.TrackOrigins)
4632 auto &
DL =
F.getDataLayout();
4633 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4634 DL.getTypeStoreSize(SrcShadow->
getType()),
4653 void handleAVXMaskedLoad(IntrinsicInst &
I) {
4658 Value *Src =
I.getArgOperand(0);
4659 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
4666 if (Opts.msan_check_access_address) {
4667 insertCheckShadowOf(Mask, &
I);
4670 Type *SrcShadowTy = getShadowTy(Src);
4671 Value *SrcShadowPtr, *SrcOriginPtr;
4672 std::tie(SrcShadowPtr, SrcOriginPtr) =
4673 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment,
false);
4675 SmallVector<Value *, 2> ShadowArgs;
4676 ShadowArgs.
append(1, SrcShadowPtr);
4677 ShadowArgs.
append(1, Mask);
4680 I.getType(),
I.getIntrinsicID(), ShadowArgs);
4686 if (!MS.TrackOrigins)
4693 setOrigin(&
I, PtrSrcOrigin);
4702 assert(isFixedIntVector(Idx));
4703 auto IdxVectorSize =
4711 auto *IdxShadow = getShadow(Idx);
4716 insertCheckShadow(Truncated, getOrigin(Idx),
I);
4721 void handleAVXVpermilvar(IntrinsicInst &
I) {
4723 Value *Shadow = getShadow(&
I, 0);
4724 maskedCheckAVXIndexShadow(IRB,
I.getArgOperand(1), &
I);
4728 Shadow = IRB.
CreateBitCast(Shadow,
I.getArgOperand(0)->getType());
4730 I.getType(),
I.getIntrinsicID(), {Shadow, I.getArgOperand(1)});
4733 setOriginForNaryOp(
I);
4738 void handleAVXVpermi2var(IntrinsicInst &
I) {
4743 [[maybe_unused]]
auto ArgVectorSize =
4746 ->getNumElements() == ArgVectorSize);
4748 ->getNumElements() == ArgVectorSize);
4749 assert(
I.getArgOperand(0)->getType() ==
I.getArgOperand(2)->getType());
4750 assert(
I.getType() ==
I.getArgOperand(0)->getType());
4751 assert(
I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4753 Value *AShadow = getShadow(&
I, 0);
4755 Value *BShadow = getShadow(&
I, 2);
4757 maskedCheckAVXIndexShadow(IRB, Idx, &
I);
4761 AShadow = IRB.
CreateBitCast(AShadow,
I.getArgOperand(0)->getType());
4762 BShadow = IRB.
CreateBitCast(BShadow,
I.getArgOperand(2)->getType());
4764 I.getType(),
I.getIntrinsicID(), {AShadow, Idx, BShadow});
4766 setOriginForNaryOp(
I);
4769 [[maybe_unused]]
static bool isFixedIntVectorTy(
const Type *
T) {
4773 [[maybe_unused]]
static bool isFixedFPVectorTy(
const Type *
T) {
4777 [[maybe_unused]]
static bool isFixedIntVector(
const Value *V) {
4778 return isFixedIntVectorTy(
V->getType());
4781 [[maybe_unused]]
static bool isFixedFPVector(
const Value *V) {
4782 return isFixedFPVectorTy(
V->getType());
4804 void handleAVX512VectorConvertFPToInt(IntrinsicInst &
I,
bool LastMask) {
4809 Value *WriteThrough;
4813 WriteThrough =
I.getOperand(2);
4814 Mask =
I.getOperand(3);
4817 WriteThrough =
I.getOperand(1);
4818 Mask =
I.getOperand(2);
4823 assert(isFixedIntVector(WriteThrough));
4825 unsigned ANumElements =
4827 [[maybe_unused]]
unsigned WriteThruNumElements =
4829 assert(ANumElements == WriteThruNumElements ||
4830 ANumElements * 2 == WriteThruNumElements);
4833 unsigned MaskNumElements =
Mask->getType()->getScalarSizeInBits();
4834 assert(ANumElements == MaskNumElements ||
4835 ANumElements * 2 == MaskNumElements);
4837 assert(WriteThruNumElements == MaskNumElements);
4841 insertCheckShadowOf(Mask, &
I);
4851 Value *AShadow = getShadow(
A);
4852 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
4854 if (ANumElements * 2 == MaskNumElements) {
4866 "_ms_mask_bitcast");
4876 getShadowTy(&
I),
"_ms_a_shadow");
4878 Value *WriteThroughShadow = getShadow(WriteThrough);
4880 "_ms_writethru_select");
4882 setShadow(&
I, Shadow);
4883 setOriginForNaryOp(
I);
4886 static SmallVector<int, 8> getPclmulMask(
unsigned Width,
bool OddElements) {
4887 SmallVector<int, 8>
Mask;
4888 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
4902 void handlePclmulIntrinsic(IntrinsicInst &
I) {
4907 "pclmul 3rd operand must be a constant");
4910 getPclmulMask(Width,
Imm & 0x01));
4912 getPclmulMask(Width,
Imm & 0x10));
4913 ShadowAndOriginCombiner SOC(
this, IRB);
4914 SOC.Add(Shuf0, getOrigin(&
I, 0));
4915 SOC.Add(Shuf1, getOrigin(&
I, 1));
4920 void handleUnarySdSsIntrinsic(IntrinsicInst &
I) {
4925 Value *Second = getShadow(&
I, 1);
4927 SmallVector<int, 16>
Mask;
4928 Mask.push_back(Width);
4929 for (
unsigned i = 1; i < Width; i++)
4933 setShadow(&
I, Shadow);
4934 setOriginForNaryOp(
I);
4937 void handleVtestIntrinsic(IntrinsicInst &
I) {
4939 Value *Shadow0 = getShadow(&
I, 0);
4940 Value *Shadow1 = getShadow(&
I, 1);
4946 setShadow(&
I, Shadow);
4947 setOriginForNaryOp(
I);
4950 void handleBinarySdSsIntrinsic(IntrinsicInst &
I) {
4955 Value *Second = getShadow(&
I, 1);
4958 SmallVector<int, 16>
Mask;
4959 Mask.push_back(Width);
4960 for (
unsigned i = 1; i < Width; i++)
4964 setShadow(&
I, Shadow);
4965 setOriginForNaryOp(
I);
4971 void handleRoundPdPsIntrinsic(IntrinsicInst &
I) {
4972 assert(
I.getArgOperand(0)->getType() ==
I.getType());
4977 ShadowAndOriginCombiner SC(
this, IRB);
4978 SC.Add(
I.getArgOperand(0));
4986 void handleAbsIntrinsic(IntrinsicInst &
I) {
4988 Value *Src =
I.getArgOperand(0);
4989 Value *IsIntMinPoison =
I.getArgOperand(1);
4991 assert(
I.getType()->isIntOrIntVectorTy());
4993 assert(Src->getType() ==
I.getType());
4999 Value *SrcShadow = getShadow(Src);
5003 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5006 Value *PoisonedShadow = getPoisonedShadow(Src);
5007 Value *PoisonedIfIntMinShadow =
5010 IRB.
CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5012 setShadow(&
I, Shadow);
5013 setOrigin(&
I, getOrigin(&
I, 0));
5016 void handleIsFpClass(IntrinsicInst &
I) {
5018 Value *Shadow = getShadow(&
I, 0);
5019 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5020 setOrigin(&
I, getOrigin(&
I, 0));
5023 void handleArithmeticWithOverflow(IntrinsicInst &
I) {
5025 Value *Shadow0 = getShadow(&
I, 0);
5026 Value *Shadow1 = getShadow(&
I, 1);
5029 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5035 setShadow(&
I, Shadow);
5036 setOriginForNaryOp(
I);
5039 void handleModfOrSincos(IntrinsicInst &
I) {
5041 Value *ArgShadow = getShadow(&
I, 0);
5045 setShadow(&
I, Shadow);
5046 setOrigin(&
I, getOrigin(&
I, 0));
5052 Value *Shadow = getShadow(V);
5074 void handleAVX512VectorDownConvert(IntrinsicInst &
I) {
5079 Value *WriteThrough =
I.getOperand(1);
5083 assert(isFixedIntVector(WriteThrough));
5085 unsigned ANumElements =
5087 unsigned OutputNumElements =
5089 assert(ANumElements == OutputNumElements ||
5090 ANumElements * 2 == OutputNumElements);
5100 insertCheckShadowOf(Mask, &
I);
5103 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5104 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5105 assert(
Mask->getType()->getScalarSizeInBits() == ANumElements);
5116 if (ANumElements != OutputNumElements) {
5118 Mask = IRB.
CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5125 Value *AShadow = getShadow(
A);
5129 VectorType *ShadowType = maybeShrinkVectorShadowType(
A,
I);
5139 AShadow = IRB.
CreateTrunc(AShadow, ShadowType,
"_ms_trunc_shadow");
5140 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
5142 Value *WriteThroughShadow = getShadow(WriteThrough);
5145 setShadow(&
I, Shadow);
5146 setOriginForNaryOp(
I);
5180 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &
I,
5181 SmallVector<unsigned, 4> DataIndices,
5182 unsigned WriteThruIndex,
5183 unsigned MaskIndex) {
5186 unsigned NumArgs =
I.arg_size();
5188 assert(WriteThruIndex < NumArgs);
5189 assert(MaskIndex < NumArgs);
5190 assert(WriteThruIndex != MaskIndex);
5191 Value *WriteThru =
I.getOperand(WriteThruIndex);
5193 unsigned OutputNumElements =
5198 bool isData[16] = {
false};
5200 for (
unsigned i : DataIndices) {
5202 assert(i != WriteThruIndex);
5209 [[maybe_unused]]
unsigned ANumElements =
5211 assert(ANumElements == OutputNumElements);
5216 assert(isFixedFPVector(WriteThru));
5218 for (
unsigned i = 0; i < NumArgs; ++i) {
5219 if (!isData[i] && i != WriteThruIndex) {
5222 assert(
I.getOperand(i)->getType()->isIntegerTy());
5223 insertCheckShadowOf(
I.getOperand(i), &
I);
5228 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5229 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5230 assert(
Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5237 Value *DataShadow =
nullptr;
5238 for (
unsigned i : DataIndices) {
5241 DataShadow = IRB.
CreateOr(DataShadow, getShadow(
A));
5243 DataShadow = getShadow(
A);
5251 Value *WriteThruShadow = getShadow(WriteThru);
5254 setShadow(&
I, Shadow);
5256 setOriginForNaryOp(
I);
5266 void handleAVX512FPClass(IntrinsicInst &
I) {
5271 Value *Input =
I.getOperand(0);
5272 assert(isFixedFPVector(Input));
5275 Value *Classifiers =
I.getOperand(1);
5279 assert(isFixedIntVectorTy(
I.getType()));
5285 Value *OutputShadow;
5290 OutputShadow = getCleanShadow(OutputType);
5296 OutputShadow = IRB.
CreateICmpNE(getShadow(Input), getCleanShadow(Input));
5298 setShadow(&
I, OutputShadow);
5300 setOriginForNaryOp(
I);
5310 void visitGenericScalarHalfwordInst(IntrinsicInst &
I) {
5316 Value *WriteThrough =
I.getOperand(2);
5323 insertCheckShadowOf(Mask, &
I);
5327 unsigned NumElements =
5329 assert(NumElements == 8);
5330 assert(
A->getType() ==
B->getType());
5332 assert(
Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5335 Value *ALowerShadow = extractLowerShadow(IRB,
A);
5336 Value *BLowerShadow = extractLowerShadow(IRB,
B);
5338 Value *ABLowerShadow = IRB.
CreateOr(ALowerShadow, BLowerShadow);
5340 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5347 Value *AShadow = getShadow(
A);
5348 Value *DstLowerShadow =
5349 IRB.
CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5351 AShadow, DstLowerShadow, ConstantInt::get(IRB.
getInt32Ty(), 0),
5354 setShadow(&
I, DstShadow);
5355 setOriginForNaryOp(
I);
5385 void handleAVXGF2P8Affine(IntrinsicInst &
I) {
5396 ->getScalarSizeInBits() == 8);
5398 assert(
A->getType() ==
X->getType());
5400 assert(
B->getType()->isIntegerTy());
5401 assert(
B->getType()->getScalarSizeInBits() == 8);
5403 assert(
I.getType() ==
A->getType());
5405 Value *AShadow = getShadow(
A);
5406 Value *XShadow = getShadow(
X);
5407 Value *BZeroShadow = getCleanShadow(
B);
5410 I.getType(),
I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5412 {X, AShadow, BZeroShadow});
5414 {XShadow, A, BZeroShadow});
5417 Value *BShadow = getShadow(
B);
5418 Value *BBroadcastShadow = getCleanShadow(AShadow);
5423 for (
unsigned i = 0; i < NumElements; i++)
5427 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5428 setOriginForNaryOp(
I);
5442 void handleNEONVectorLoad(IntrinsicInst &
I,
bool WithLane) {
5443 unsigned int numArgs =
I.arg_size();
5446 assert(
I.getType()->isStructTy());
5456 assert(4 <= numArgs && numArgs <= 6);
5470 for (
unsigned int i = 0; i < numArgs - 2; i++)
5471 ShadowArgs.
push_back(getShadow(
I.getArgOperand(i)));
5474 Value *LaneNumber =
I.getArgOperand(numArgs - 2);
5478 insertCheckShadowOf(LaneNumber, &
I);
5481 Value *Src =
I.getArgOperand(numArgs - 1);
5482 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
5484 Type *SrcShadowTy = getShadowTy(Src);
5485 auto [SrcShadowPtr, SrcOriginPtr] =
5486 getShadowOriginPtr(Src, IRB, SrcShadowTy,
Align(1),
false);
5493 getShadowTy(&
I),
I.getIntrinsicID(), ShadowArgs);
5496 if (!MS.TrackOrigins)
5500 setOrigin(&
I, PtrSrcOrigin);
5517 void handleNEONVectorStoreIntrinsic(IntrinsicInst &
I,
bool useLane) {
5521 int numArgOperands =
I.arg_size();
5524 assert(numArgOperands >= 1);
5525 Value *Addr =
I.getArgOperand(numArgOperands - 1);
5527 int skipTrailingOperands = 1;
5529 if (Opts.msan_check_access_address)
5530 insertCheckShadowOf(Addr, &
I);
5534 skipTrailingOperands++;
5535 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
5537 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5540 SmallVector<Value *, 8> ShadowArgs;
5542 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5544 Value *Shadow = getShadow(&
I, i);
5545 ShadowArgs.
append(1, Shadow);
5562 (numArgOperands - skipTrailingOperands));
5563 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5567 I.getArgOperand(numArgOperands - skipTrailingOperands));
5569 Value *OutputShadowPtr, *OutputOriginPtr;
5571 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5572 Addr, IRB, OutputShadowTy,
Align(1),
true);
5573 ShadowArgs.
append(1, OutputShadowPtr);
5576 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
5579 if (MS.TrackOrigins) {
5587 OriginCombiner OC(
this, IRB);
5588 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5589 OC.Add(
I.getArgOperand(i));
5591 const DataLayout &
DL =
F.getDataLayout();
5592 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
5625 void handleNEONMatrixMultiply(IntrinsicInst &
I) {
5629 Value *
R =
I.getArgOperand(0);
5630 Value *
A =
I.getArgOperand(1);
5631 Value *
B =
I.getArgOperand(2);
5633 assert(
I.getType() ==
R->getType());
5658 Value *ShadowR = getShadow(&
I, 0);
5659 Value *ShadowA = getShadow(&
I, 1);
5660 Value *ShadowB = getShadow(&
I, 2);
5678 {getCleanShadow(RTy), ShadowA, ShadowB});
5704 {RZeros, ShadowA, ShadowB});
5718 ShadowR = IRB.
CreateICmpNE(ShadowR, getCleanShadow(RTy));
5719 ShadowR = IRB.
CreateOr(ShadowAB, ShadowR);
5721 setShadow(&
I, IRB.
CreateSExt(ShadowR, getShadowTy(RTy)));
5723 setOriginForNaryOp(
I);
5763 void handleIntrinsicByApplyingToShadow(IntrinsicInst &
I,
5765 unsigned int trailingVerbatimArgs,
5766 bool forceIntegerIntrinsic) {
5769 assert(trailingVerbatimArgs <
I.arg_size());
5771 SmallVector<Value *, 8> ShadowArgs;
5773 for (
unsigned int i = 0; i <
I.arg_size() - trailingVerbatimArgs; i++) {
5774 Value *Shadow = getShadow(&
I, i);
5776 if (forceIntegerIntrinsic)
5783 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5785 Value *Arg =
I.getArgOperand(i);
5786 if (forceIntegerIntrinsic)
5791 Value *CombinedShadow;
5792 if (forceIntegerIntrinsic) {
5802 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5805 CreateShadowCast(IRB, getShadow(&
I, i), CombinedShadow->
getType());
5806 CombinedShadow = IRB.
CreateOr(Shadow, CombinedShadow,
"_msprop");
5809 setShadow(&
I, CombinedShadow);
5811 setOriginForNaryOp(
I);
5817 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &
I) {
5855 void handleNEONDotProductLaneIntrinsic(IntrinsicInst &
I,
5856 unsigned ReductionFactor) {
5860 [[maybe_unused]]
Value *VAcc =
I.getOperand(0);
5861 [[maybe_unused]]
Value *Va =
I.getOperand(1);
5862 [[maybe_unused]]
Value *Vb =
I.getOperand(2);
5863 Value *Lane =
I.getOperand(3);
5870 I.getType()->getPrimitiveSizeInBits());
5879 I.getType()->getPrimitiveSizeInBits());
5885 Value *SAcc = getShadow(&
I, 0);
5886 Value *Sa = getShadow(&
I, 1);
5887 Value *Sb = getShadow(&
I, 2);
5894 Sb, FixedVectorType::getWithSizeAndScalar(
5910 SOutput = IRB.
CreateSelect(SbClean, SOutput, getPoisonedShadow(SOutput));
5912 setShadow(&
I, SOutput);
5913 setOriginForNaryOp(
I);
5916 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &
I) {
5917 switch (
I.getIntrinsicID()) {
5918 case Intrinsic::uadd_with_overflow:
5919 case Intrinsic::sadd_with_overflow:
5920 case Intrinsic::usub_with_overflow:
5921 case Intrinsic::ssub_with_overflow:
5922 case Intrinsic::umul_with_overflow:
5923 case Intrinsic::smul_with_overflow:
5924 handleArithmeticWithOverflow(
I);
5926 case Intrinsic::modf:
5927 case Intrinsic::sincos:
5928 case Intrinsic::sincospi:
5929 handleModfOrSincos(
I);
5931 case Intrinsic::abs:
5932 handleAbsIntrinsic(
I);
5934 case Intrinsic::bitreverse:
5935 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
5939 case Intrinsic::is_fpclass:
5942 case Intrinsic::lifetime_start:
5943 handleLifetimeStart(
I);
5945 case Intrinsic::launder_invariant_group:
5946 handleInvariantGroup(
I);
5948 case Intrinsic::bswap:
5951 case Intrinsic::ctlz:
5952 case Intrinsic::cttz:
5953 handleCountLeadingTrailingZeros(
I);
5955 case Intrinsic::masked_compressstore:
5956 handleMaskedCompressStore(
I);
5958 case Intrinsic::masked_expandload:
5959 handleMaskedExpandLoad(
I);
5961 case Intrinsic::masked_gather:
5962 handleMaskedGather(
I);
5964 case Intrinsic::masked_scatter:
5965 handleMaskedScatter(
I);
5967 case Intrinsic::masked_store:
5968 handleMaskedStore(
I);
5970 case Intrinsic::masked_load:
5971 handleMaskedLoad(
I);
5973 case Intrinsic::masked_udiv:
5974 case Intrinsic::masked_sdiv:
5975 case Intrinsic::masked_urem:
5976 case Intrinsic::masked_srem:
5977 handleMaskedIntegerDivRem(
I);
5979 case Intrinsic::vector_reduce_and:
5980 handleVectorReduceAndIntrinsic(
I);
5982 case Intrinsic::vector_reduce_or:
5983 handleVectorReduceOrIntrinsic(
I);
5986 case Intrinsic::vector_reduce_add:
5987 case Intrinsic::vector_reduce_xor:
5988 case Intrinsic::vector_reduce_mul:
5991 case Intrinsic::vector_reduce_smax:
5992 case Intrinsic::vector_reduce_smin:
5993 case Intrinsic::vector_reduce_umax:
5994 case Intrinsic::vector_reduce_umin:
5997 case Intrinsic::vector_reduce_fmax:
5998 case Intrinsic::vector_reduce_fmin:
5999 handleVectorReduceIntrinsic(
I,
false);
6002 case Intrinsic::vector_reduce_fadd:
6003 case Intrinsic::vector_reduce_fmul:
6004 handleVectorReduceWithStarterIntrinsic(
I);
6008 case Intrinsic::vector_partial_reduce_add:
6009 case Intrinsic::vector_partial_reduce_fadd:
6010 handleVectorPartialReduceAddIntrinsic(
I);
6013 case Intrinsic::scmp:
6014 case Intrinsic::ucmp: {
6019 case Intrinsic::fshl:
6020 case Intrinsic::fshr:
6021 handleFunnelShift(
I);
6024 case Intrinsic::pdep:
6025 case Intrinsic::pext:
6026 handleGenericBitManipulation(
I);
6029 case Intrinsic::is_constant:
6031 setShadow(&
I, getCleanShadow(&
I));
6032 setOrigin(&
I, getCleanOrigin());
6039 case Intrinsic::fptosi_sat:
6040 case Intrinsic::fptoui_sat:
6041 handleGenericVectorConvertIntrinsic(
I,
false);
6048 case Intrinsic::fake_use:
6049 assert(
I.getType()->isVoidTy());
6062 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &
I) {
6063 switch (
I.getIntrinsicID()) {
6064 case Intrinsic::x86_sse_stmxcsr:
6067 case Intrinsic::x86_sse_ldmxcsr:
6074 case Intrinsic::x86_avx512_vcvtsd2usi64:
6075 case Intrinsic::x86_avx512_vcvtsd2usi32:
6076 case Intrinsic::x86_avx512_vcvtss2usi64:
6077 case Intrinsic::x86_avx512_vcvtss2usi32:
6078 case Intrinsic::x86_avx512_cvttss2usi64:
6079 case Intrinsic::x86_avx512_cvttss2usi:
6080 case Intrinsic::x86_avx512_cvttsd2usi64:
6081 case Intrinsic::x86_avx512_cvttsd2usi:
6082 case Intrinsic::x86_avx512_cvtusi2ss:
6083 case Intrinsic::x86_avx512_cvtusi642sd:
6084 case Intrinsic::x86_avx512_cvtusi642ss:
6085 handleSSEVectorConvertIntrinsic(
I, 1,
true);
6087 case Intrinsic::x86_sse2_cvtsd2si64:
6088 case Intrinsic::x86_sse2_cvtsd2si:
6089 case Intrinsic::x86_sse2_cvtsd2ss:
6090 case Intrinsic::x86_sse2_cvttsd2si64:
6091 case Intrinsic::x86_sse2_cvttsd2si:
6092 case Intrinsic::x86_sse_cvtss2si64:
6093 case Intrinsic::x86_sse_cvtss2si:
6094 case Intrinsic::x86_sse_cvttss2si64:
6095 case Intrinsic::x86_sse_cvttss2si:
6096 handleSSEVectorConvertIntrinsic(
I, 1);
6098 case Intrinsic::x86_sse_cvtps2pi:
6099 case Intrinsic::x86_sse_cvttps2pi:
6100 handleSSEVectorConvertIntrinsic(
I, 2);
6108 case Intrinsic::x86_vcvtps2ph_128:
6109 case Intrinsic::x86_vcvtps2ph_256: {
6110 handleSSEVectorConvertIntrinsicByProp(
I,
true);
6119 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
6120 handleAVX512VectorConvertFPToInt(
I,
false);
6125 case Intrinsic::x86_sse2_cvtpd2ps:
6126 case Intrinsic::x86_sse2_cvtps2dq:
6127 case Intrinsic::x86_sse2_cvtpd2dq:
6128 case Intrinsic::x86_sse2_cvttps2dq:
6129 case Intrinsic::x86_sse2_cvttpd2dq:
6130 case Intrinsic::x86_avx_cvt_pd2_ps_256:
6131 case Intrinsic::x86_avx_cvt_ps2dq_256:
6132 case Intrinsic::x86_avx_cvt_pd2dq_256:
6133 case Intrinsic::x86_avx_cvtt_ps2dq_256:
6134 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
6135 handleSSEVectorConvertIntrinsicByProp(
I,
false);
6146 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
6147 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
6148 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
6149 handleAVX512VectorConvertFPToInt(
I,
true);
6153 case Intrinsic::x86_avx512_psll_w_512:
6154 case Intrinsic::x86_avx512_psll_d_512:
6155 case Intrinsic::x86_avx512_psll_q_512:
6156 case Intrinsic::x86_avx512_pslli_w_512:
6157 case Intrinsic::x86_avx512_pslli_d_512:
6158 case Intrinsic::x86_avx512_pslli_q_512:
6159 case Intrinsic::x86_avx512_psrl_w_512:
6160 case Intrinsic::x86_avx512_psrl_d_512:
6161 case Intrinsic::x86_avx512_psrl_q_512:
6162 case Intrinsic::x86_avx512_psra_w_512:
6163 case Intrinsic::x86_avx512_psra_d_512:
6164 case Intrinsic::x86_avx512_psra_q_512:
6165 case Intrinsic::x86_avx512_psrli_w_512:
6166 case Intrinsic::x86_avx512_psrli_d_512:
6167 case Intrinsic::x86_avx512_psrli_q_512:
6168 case Intrinsic::x86_avx512_psrai_w_512:
6169 case Intrinsic::x86_avx512_psrai_d_512:
6170 case Intrinsic::x86_avx512_psrai_q_512:
6171 case Intrinsic::x86_avx512_psra_q_256:
6172 case Intrinsic::x86_avx512_psra_q_128:
6173 case Intrinsic::x86_avx512_psrai_q_256:
6174 case Intrinsic::x86_avx512_psrai_q_128:
6175 case Intrinsic::x86_avx2_psll_w:
6176 case Intrinsic::x86_avx2_psll_d:
6177 case Intrinsic::x86_avx2_psll_q:
6178 case Intrinsic::x86_avx2_pslli_w:
6179 case Intrinsic::x86_avx2_pslli_d:
6180 case Intrinsic::x86_avx2_pslli_q:
6181 case Intrinsic::x86_avx2_psrl_w:
6182 case Intrinsic::x86_avx2_psrl_d:
6183 case Intrinsic::x86_avx2_psrl_q:
6184 case Intrinsic::x86_avx2_psra_w:
6185 case Intrinsic::x86_avx2_psra_d:
6186 case Intrinsic::x86_avx2_psrli_w:
6187 case Intrinsic::x86_avx2_psrli_d:
6188 case Intrinsic::x86_avx2_psrli_q:
6189 case Intrinsic::x86_avx2_psrai_w:
6190 case Intrinsic::x86_avx2_psrai_d:
6191 case Intrinsic::x86_sse2_psll_w:
6192 case Intrinsic::x86_sse2_psll_d:
6193 case Intrinsic::x86_sse2_psll_q:
6194 case Intrinsic::x86_sse2_pslli_w:
6195 case Intrinsic::x86_sse2_pslli_d:
6196 case Intrinsic::x86_sse2_pslli_q:
6197 case Intrinsic::x86_sse2_psrl_w:
6198 case Intrinsic::x86_sse2_psrl_d:
6199 case Intrinsic::x86_sse2_psrl_q:
6200 case Intrinsic::x86_sse2_psra_w:
6201 case Intrinsic::x86_sse2_psra_d:
6202 case Intrinsic::x86_sse2_psrli_w:
6203 case Intrinsic::x86_sse2_psrli_d:
6204 case Intrinsic::x86_sse2_psrli_q:
6205 case Intrinsic::x86_sse2_psrai_w:
6206 case Intrinsic::x86_sse2_psrai_d:
6207 case Intrinsic::x86_mmx_psll_w:
6208 case Intrinsic::x86_mmx_psll_d:
6209 case Intrinsic::x86_mmx_psll_q:
6210 case Intrinsic::x86_mmx_pslli_w:
6211 case Intrinsic::x86_mmx_pslli_d:
6212 case Intrinsic::x86_mmx_pslli_q:
6213 case Intrinsic::x86_mmx_psrl_w:
6214 case Intrinsic::x86_mmx_psrl_d:
6215 case Intrinsic::x86_mmx_psrl_q:
6216 case Intrinsic::x86_mmx_psra_w:
6217 case Intrinsic::x86_mmx_psra_d:
6218 case Intrinsic::x86_mmx_psrli_w:
6219 case Intrinsic::x86_mmx_psrli_d:
6220 case Intrinsic::x86_mmx_psrli_q:
6221 case Intrinsic::x86_mmx_psrai_w:
6222 case Intrinsic::x86_mmx_psrai_d:
6223 handleVectorShiftIntrinsic(
I,
false);
6225 case Intrinsic::x86_avx2_psllv_d:
6226 case Intrinsic::x86_avx2_psllv_d_256:
6227 case Intrinsic::x86_avx512_psllv_d_512:
6228 case Intrinsic::x86_avx2_psllv_q:
6229 case Intrinsic::x86_avx2_psllv_q_256:
6230 case Intrinsic::x86_avx512_psllv_q_512:
6231 case Intrinsic::x86_avx2_psrlv_d:
6232 case Intrinsic::x86_avx2_psrlv_d_256:
6233 case Intrinsic::x86_avx512_psrlv_d_512:
6234 case Intrinsic::x86_avx2_psrlv_q:
6235 case Intrinsic::x86_avx2_psrlv_q_256:
6236 case Intrinsic::x86_avx512_psrlv_q_512:
6237 case Intrinsic::x86_avx2_psrav_d:
6238 case Intrinsic::x86_avx2_psrav_d_256:
6239 case Intrinsic::x86_avx512_psrav_d_512:
6240 case Intrinsic::x86_avx512_psrav_q_128:
6241 case Intrinsic::x86_avx512_psrav_q_256:
6242 case Intrinsic::x86_avx512_psrav_q_512:
6243 handleVectorShiftIntrinsic(
I,
true);
6247 case Intrinsic::x86_sse2_packsswb_128:
6248 case Intrinsic::x86_sse2_packssdw_128:
6249 case Intrinsic::x86_sse2_packuswb_128:
6250 case Intrinsic::x86_sse41_packusdw:
6251 case Intrinsic::x86_avx2_packsswb:
6252 case Intrinsic::x86_avx2_packssdw:
6253 case Intrinsic::x86_avx2_packuswb:
6254 case Intrinsic::x86_avx2_packusdw:
6260 case Intrinsic::x86_avx512_packsswb_512:
6261 case Intrinsic::x86_avx512_packssdw_512:
6262 case Intrinsic::x86_avx512_packuswb_512:
6263 case Intrinsic::x86_avx512_packusdw_512:
6264 handleVectorPackIntrinsic(
I);
6267 case Intrinsic::x86_sse41_pblendvb:
6268 case Intrinsic::x86_sse41_blendvpd:
6269 case Intrinsic::x86_sse41_blendvps:
6270 case Intrinsic::x86_avx_blendv_pd_256:
6271 case Intrinsic::x86_avx_blendv_ps_256:
6272 case Intrinsic::x86_avx2_pblendvb:
6273 handleBlendvIntrinsic(
I);
6276 case Intrinsic::x86_avx_dp_ps_256:
6277 case Intrinsic::x86_sse41_dppd:
6278 case Intrinsic::x86_sse41_dpps:
6279 handleDppIntrinsic(
I);
6282 case Intrinsic::x86_mmx_packsswb:
6283 case Intrinsic::x86_mmx_packuswb:
6284 handleVectorPackIntrinsic(
I, 16);
6287 case Intrinsic::x86_mmx_packssdw:
6288 handleVectorPackIntrinsic(
I, 32);
6291 case Intrinsic::x86_mmx_psad_bw:
6292 handleVectorSadIntrinsic(
I,
true);
6294 case Intrinsic::x86_sse2_psad_bw:
6295 case Intrinsic::x86_avx2_psad_bw:
6296 handleVectorSadIntrinsic(
I);
6322 case Intrinsic::x86_sse2_pmadd_wd:
6323 case Intrinsic::x86_avx2_pmadd_wd:
6324 case Intrinsic::x86_avx512_pmaddw_d_512:
6325 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6326 case Intrinsic::x86_avx2_pmadd_ub_sw:
6327 case Intrinsic::x86_avx512_pmaddubs_w_512:
6328 handleVectorDotProductIntrinsic(
I, 2,
6335 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6336 handleVectorDotProductIntrinsic(
I, 2,
6343 case Intrinsic::x86_mmx_pmadd_wd:
6344 handleVectorDotProductIntrinsic(
I, 2,
6353 case Intrinsic::aarch64_neon_bfmlalt:
6354 handleVectorDotProductIntrinsic(
I, 2,
6362 case Intrinsic::aarch64_neon_bfmlalb:
6363 handleVectorDotProductIntrinsic(
I, 2,
6461 case Intrinsic::x86_avx512_vpdpbusd_128:
6462 case Intrinsic::x86_avx512_vpdpbusd_256:
6463 case Intrinsic::x86_avx512_vpdpbusd_512:
6464 case Intrinsic::x86_avx512_vpdpbusds_128:
6465 case Intrinsic::x86_avx512_vpdpbusds_256:
6466 case Intrinsic::x86_avx512_vpdpbusds_512:
6467 case Intrinsic::x86_avx2_vpdpbssd_128:
6468 case Intrinsic::x86_avx2_vpdpbssd_256:
6469 case Intrinsic::x86_avx10_vpdpbssd_512:
6470 case Intrinsic::x86_avx2_vpdpbssds_128:
6471 case Intrinsic::x86_avx2_vpdpbssds_256:
6472 case Intrinsic::x86_avx10_vpdpbssds_512:
6473 case Intrinsic::x86_avx2_vpdpbsud_128:
6474 case Intrinsic::x86_avx2_vpdpbsud_256:
6475 case Intrinsic::x86_avx10_vpdpbsud_512:
6476 case Intrinsic::x86_avx2_vpdpbsuds_128:
6477 case Intrinsic::x86_avx2_vpdpbsuds_256:
6478 case Intrinsic::x86_avx10_vpdpbsuds_512:
6479 case Intrinsic::x86_avx2_vpdpbuud_128:
6480 case Intrinsic::x86_avx2_vpdpbuud_256:
6481 case Intrinsic::x86_avx10_vpdpbuud_512:
6482 case Intrinsic::x86_avx2_vpdpbuuds_128:
6483 case Intrinsic::x86_avx2_vpdpbuuds_256:
6484 case Intrinsic::x86_avx10_vpdpbuuds_512:
6485 handleVectorDotProductIntrinsic(
I, 4,
6583 case Intrinsic::x86_avx512_vpdpwssd_128:
6584 case Intrinsic::x86_avx512_vpdpwssd_256:
6585 case Intrinsic::x86_avx512_vpdpwssd_512:
6586 case Intrinsic::x86_avx512_vpdpwssds_128:
6587 case Intrinsic::x86_avx512_vpdpwssds_256:
6588 case Intrinsic::x86_avx512_vpdpwssds_512:
6589 case Intrinsic::x86_avx2_vpdpwsud_128:
6590 case Intrinsic::x86_avx2_vpdpwsud_256:
6591 case Intrinsic::x86_avx10_vpdpwsud_512:
6592 case Intrinsic::x86_avx2_vpdpwsuds_128:
6593 case Intrinsic::x86_avx2_vpdpwsuds_256:
6594 case Intrinsic::x86_avx10_vpdpwsuds_512:
6595 case Intrinsic::x86_avx2_vpdpwusd_128:
6596 case Intrinsic::x86_avx2_vpdpwusd_256:
6597 case Intrinsic::x86_avx10_vpdpwusd_512:
6598 case Intrinsic::x86_avx2_vpdpwusds_128:
6599 case Intrinsic::x86_avx2_vpdpwusds_256:
6600 case Intrinsic::x86_avx10_vpdpwusds_512:
6601 case Intrinsic::x86_avx2_vpdpwuud_128:
6602 case Intrinsic::x86_avx2_vpdpwuud_256:
6603 case Intrinsic::x86_avx10_vpdpwuud_512:
6604 case Intrinsic::x86_avx2_vpdpwuuds_128:
6605 case Intrinsic::x86_avx2_vpdpwuuds_256:
6606 case Intrinsic::x86_avx10_vpdpwuuds_512:
6607 handleVectorDotProductIntrinsic(
I, 2,
6621 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6622 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6623 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6624 handleVectorDotProductIntrinsic(
I, 2,
6630 case Intrinsic::x86_sse_cmp_ss:
6631 case Intrinsic::x86_sse2_cmp_sd:
6632 case Intrinsic::x86_sse_comieq_ss:
6633 case Intrinsic::x86_sse_comilt_ss:
6634 case Intrinsic::x86_sse_comile_ss:
6635 case Intrinsic::x86_sse_comigt_ss:
6636 case Intrinsic::x86_sse_comige_ss:
6637 case Intrinsic::x86_sse_comineq_ss:
6638 case Intrinsic::x86_sse_ucomieq_ss:
6639 case Intrinsic::x86_sse_ucomilt_ss:
6640 case Intrinsic::x86_sse_ucomile_ss:
6641 case Intrinsic::x86_sse_ucomigt_ss:
6642 case Intrinsic::x86_sse_ucomige_ss:
6643 case Intrinsic::x86_sse_ucomineq_ss:
6644 case Intrinsic::x86_sse2_comieq_sd:
6645 case Intrinsic::x86_sse2_comilt_sd:
6646 case Intrinsic::x86_sse2_comile_sd:
6647 case Intrinsic::x86_sse2_comigt_sd:
6648 case Intrinsic::x86_sse2_comige_sd:
6649 case Intrinsic::x86_sse2_comineq_sd:
6650 case Intrinsic::x86_sse2_ucomieq_sd:
6651 case Intrinsic::x86_sse2_ucomilt_sd:
6652 case Intrinsic::x86_sse2_ucomile_sd:
6653 case Intrinsic::x86_sse2_ucomigt_sd:
6654 case Intrinsic::x86_sse2_ucomige_sd:
6655 case Intrinsic::x86_sse2_ucomineq_sd:
6656 handleVectorCompareScalarIntrinsic(
I);
6659 case Intrinsic::x86_avx_cmp_pd_256:
6660 case Intrinsic::x86_avx_cmp_ps_256:
6661 case Intrinsic::x86_sse2_cmp_pd:
6662 case Intrinsic::x86_sse_cmp_ps:
6663 handleVectorComparePackedIntrinsic(
I,
true);
6666 case Intrinsic::x86_bmi_bextr_32:
6667 case Intrinsic::x86_bmi_bextr_64:
6668 case Intrinsic::x86_bmi_bzhi_32:
6669 case Intrinsic::x86_bmi_bzhi_64:
6670 handleGenericBitManipulation(
I);
6673 case Intrinsic::x86_pclmulqdq:
6674 case Intrinsic::x86_pclmulqdq_256:
6675 case Intrinsic::x86_pclmulqdq_512:
6676 handlePclmulIntrinsic(
I);
6679 case Intrinsic::x86_avx_round_pd_256:
6680 case Intrinsic::x86_avx_round_ps_256:
6681 case Intrinsic::x86_sse41_round_pd:
6682 case Intrinsic::x86_sse41_round_ps:
6683 handleRoundPdPsIntrinsic(
I);
6686 case Intrinsic::x86_sse41_round_sd:
6687 case Intrinsic::x86_sse41_round_ss:
6688 handleUnarySdSsIntrinsic(
I);
6691 case Intrinsic::x86_sse2_max_sd:
6692 case Intrinsic::x86_sse_max_ss:
6693 case Intrinsic::x86_sse2_min_sd:
6694 case Intrinsic::x86_sse_min_ss:
6695 handleBinarySdSsIntrinsic(
I);
6698 case Intrinsic::x86_avx_vtestc_pd:
6699 case Intrinsic::x86_avx_vtestc_pd_256:
6700 case Intrinsic::x86_avx_vtestc_ps:
6701 case Intrinsic::x86_avx_vtestc_ps_256:
6702 case Intrinsic::x86_avx_vtestnzc_pd:
6703 case Intrinsic::x86_avx_vtestnzc_pd_256:
6704 case Intrinsic::x86_avx_vtestnzc_ps:
6705 case Intrinsic::x86_avx_vtestnzc_ps_256:
6706 case Intrinsic::x86_avx_vtestz_pd:
6707 case Intrinsic::x86_avx_vtestz_pd_256:
6708 case Intrinsic::x86_avx_vtestz_ps:
6709 case Intrinsic::x86_avx_vtestz_ps_256:
6710 case Intrinsic::x86_avx_ptestc_256:
6711 case Intrinsic::x86_avx_ptestnzc_256:
6712 case Intrinsic::x86_avx_ptestz_256:
6713 case Intrinsic::x86_sse41_ptestc:
6714 case Intrinsic::x86_sse41_ptestnzc:
6715 case Intrinsic::x86_sse41_ptestz:
6716 handleVtestIntrinsic(
I);
6720 case Intrinsic::x86_ssse3_phadd_w:
6721 case Intrinsic::x86_ssse3_phadd_w_128:
6722 case Intrinsic::x86_ssse3_phsub_w:
6723 case Intrinsic::x86_ssse3_phsub_w_128:
6724 handlePairwiseShadowOrIntrinsic(
I, 1,
6728 case Intrinsic::x86_avx2_phadd_w:
6729 case Intrinsic::x86_avx2_phsub_w:
6730 handlePairwiseShadowOrIntrinsic(
I, 2,
6735 case Intrinsic::x86_ssse3_phadd_d:
6736 case Intrinsic::x86_ssse3_phadd_d_128:
6737 case Intrinsic::x86_ssse3_phsub_d:
6738 case Intrinsic::x86_ssse3_phsub_d_128:
6739 handlePairwiseShadowOrIntrinsic(
I, 1,
6743 case Intrinsic::x86_avx2_phadd_d:
6744 case Intrinsic::x86_avx2_phsub_d:
6745 handlePairwiseShadowOrIntrinsic(
I, 2,
6750 case Intrinsic::x86_ssse3_phadd_sw:
6751 case Intrinsic::x86_ssse3_phadd_sw_128:
6752 case Intrinsic::x86_ssse3_phsub_sw:
6753 case Intrinsic::x86_ssse3_phsub_sw_128:
6754 handlePairwiseShadowOrIntrinsic(
I, 1,
6758 case Intrinsic::x86_avx2_phadd_sw:
6759 case Intrinsic::x86_avx2_phsub_sw:
6760 handlePairwiseShadowOrIntrinsic(
I, 2,
6765 case Intrinsic::x86_sse3_hadd_ps:
6766 case Intrinsic::x86_sse3_hadd_pd:
6767 case Intrinsic::x86_sse3_hsub_ps:
6768 case Intrinsic::x86_sse3_hsub_pd:
6769 handlePairwiseShadowOrIntrinsic(
I, 1);
6772 case Intrinsic::x86_avx_hadd_pd_256:
6773 case Intrinsic::x86_avx_hadd_ps_256:
6774 case Intrinsic::x86_avx_hsub_pd_256:
6775 case Intrinsic::x86_avx_hsub_ps_256:
6776 handlePairwiseShadowOrIntrinsic(
I, 2);
6779 case Intrinsic::x86_avx_maskstore_ps:
6780 case Intrinsic::x86_avx_maskstore_pd:
6781 case Intrinsic::x86_avx_maskstore_ps_256:
6782 case Intrinsic::x86_avx_maskstore_pd_256:
6783 case Intrinsic::x86_avx2_maskstore_d:
6784 case Intrinsic::x86_avx2_maskstore_q:
6785 case Intrinsic::x86_avx2_maskstore_d_256:
6786 case Intrinsic::x86_avx2_maskstore_q_256: {
6787 handleAVXMaskedStore(
I);
6791 case Intrinsic::x86_avx_maskload_ps:
6792 case Intrinsic::x86_avx_maskload_pd:
6793 case Intrinsic::x86_avx_maskload_ps_256:
6794 case Intrinsic::x86_avx_maskload_pd_256:
6795 case Intrinsic::x86_avx2_maskload_d:
6796 case Intrinsic::x86_avx2_maskload_q:
6797 case Intrinsic::x86_avx2_maskload_d_256:
6798 case Intrinsic::x86_avx2_maskload_q_256: {
6799 handleAVXMaskedLoad(
I);
6804 case Intrinsic::x86_avx512fp16_add_ph_512:
6805 case Intrinsic::x86_avx512fp16_sub_ph_512:
6806 case Intrinsic::x86_avx512fp16_mul_ph_512:
6807 case Intrinsic::x86_avx512fp16_div_ph_512:
6808 case Intrinsic::x86_avx512fp16_max_ph_512:
6809 case Intrinsic::x86_avx512fp16_min_ph_512:
6810 case Intrinsic::x86_avx512_min_ps_512:
6811 case Intrinsic::x86_avx512_min_pd_512:
6812 case Intrinsic::x86_avx512_max_ps_512:
6813 case Intrinsic::x86_avx512_max_pd_512: {
6818 [[maybe_unused]]
bool Success =
6819 maybeHandleSimpleNomemIntrinsic(
I, 1);
6824 case Intrinsic::x86_avx_vpermilvar_pd:
6825 case Intrinsic::x86_avx_vpermilvar_pd_256:
6826 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6827 case Intrinsic::x86_avx_vpermilvar_ps:
6828 case Intrinsic::x86_avx_vpermilvar_ps_256:
6829 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6830 handleAVXVpermilvar(
I);
6834 case Intrinsic::x86_avx512_vpermi2var_d_128:
6835 case Intrinsic::x86_avx512_vpermi2var_d_256:
6836 case Intrinsic::x86_avx512_vpermi2var_d_512:
6837 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6838 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6839 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6840 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6841 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6842 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6843 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6844 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6845 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6846 case Intrinsic::x86_avx512_vpermi2var_q_128:
6847 case Intrinsic::x86_avx512_vpermi2var_q_256:
6848 case Intrinsic::x86_avx512_vpermi2var_q_512:
6849 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6850 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6851 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6852 handleAVXVpermi2var(
I);
6866 case Intrinsic::x86_avx2_pshuf_b:
6867 case Intrinsic::x86_sse_pshuf_w:
6868 case Intrinsic::x86_ssse3_pshuf_b_128:
6869 case Intrinsic::x86_ssse3_pshuf_b:
6870 case Intrinsic::x86_avx512_pshuf_b_512:
6871 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6878 case Intrinsic::x86_avx512_mask_pmov_dw_128:
6879 case Intrinsic::x86_avx512_mask_pmov_db_128:
6880 case Intrinsic::x86_avx512_mask_pmov_qb_128:
6881 case Intrinsic::x86_avx512_mask_pmov_qw_128:
6882 case Intrinsic::x86_avx512_mask_pmov_qd_128:
6883 case Intrinsic::x86_avx512_mask_pmov_wb_128:
6884 case Intrinsic::x86_avx512_mask_pmov_dw_256:
6885 case Intrinsic::x86_avx512_mask_pmov_db_256:
6886 case Intrinsic::x86_avx512_mask_pmov_qb_256:
6887 case Intrinsic::x86_avx512_mask_pmov_qw_256:
6888 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6889 case Intrinsic::x86_avx512_mask_pmov_db_512:
6890 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6891 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6894 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6903 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6904 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6905 handleIntrinsicByApplyingToShadow(
6906 I, Intrinsic::x86_avx512_mask_pmov_dw_512,
6911 case Intrinsic::x86_avx512_mask_pmovs_dw_256:
6912 case Intrinsic::x86_avx512_mask_pmovus_dw_256:
6913 handleIntrinsicByApplyingToShadow(
6914 I, Intrinsic::x86_avx512_mask_pmov_dw_256,
6918 case Intrinsic::x86_avx512_mask_pmovs_dw_128:
6919 case Intrinsic::x86_avx512_mask_pmovus_dw_128:
6920 handleIntrinsicByApplyingToShadow(
6921 I, Intrinsic::x86_avx512_mask_pmov_dw_128,
6925 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6926 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6927 handleIntrinsicByApplyingToShadow(
6928 I, Intrinsic::x86_avx512_mask_pmov_db_512,
6933 case Intrinsic::x86_avx512_mask_pmovs_db_256:
6934 case Intrinsic::x86_avx512_mask_pmovus_db_256:
6935 handleIntrinsicByApplyingToShadow(
6936 I, Intrinsic::x86_avx512_mask_pmov_db_256,
6940 case Intrinsic::x86_avx512_mask_pmovs_db_128:
6941 case Intrinsic::x86_avx512_mask_pmovus_db_128:
6942 handleIntrinsicByApplyingToShadow(
6943 I, Intrinsic::x86_avx512_mask_pmov_db_128,
6947 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
6948 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
6949 handleIntrinsicByApplyingToShadow(
6950 I, Intrinsic::x86_avx512_mask_pmov_qb_512,
6955 case Intrinsic::x86_avx512_mask_pmovs_qb_256:
6956 case Intrinsic::x86_avx512_mask_pmovus_qb_256:
6957 handleIntrinsicByApplyingToShadow(
6958 I, Intrinsic::x86_avx512_mask_pmov_qb_256,
6962 case Intrinsic::x86_avx512_mask_pmovs_qb_128:
6963 case Intrinsic::x86_avx512_mask_pmovus_qb_128:
6964 handleIntrinsicByApplyingToShadow(
6965 I, Intrinsic::x86_avx512_mask_pmov_qb_128,
6969 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
6970 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
6971 handleIntrinsicByApplyingToShadow(
6972 I, Intrinsic::x86_avx512_mask_pmov_qw_512,
6977 case Intrinsic::x86_avx512_mask_pmovs_qw_256:
6978 case Intrinsic::x86_avx512_mask_pmovus_qw_256:
6979 handleIntrinsicByApplyingToShadow(
6980 I, Intrinsic::x86_avx512_mask_pmov_qw_256,
6984 case Intrinsic::x86_avx512_mask_pmovs_qw_128:
6985 case Intrinsic::x86_avx512_mask_pmovus_qw_128:
6986 handleIntrinsicByApplyingToShadow(
6987 I, Intrinsic::x86_avx512_mask_pmov_qw_128,
6991 case Intrinsic::x86_avx512_mask_pmovs_qd_128:
6992 case Intrinsic::x86_avx512_mask_pmovus_qd_128:
6993 handleIntrinsicByApplyingToShadow(
6994 I, Intrinsic::x86_avx512_mask_pmov_qd_128,
6998 case Intrinsic::x86_avx512_mask_pmovs_wb_128:
6999 case Intrinsic::x86_avx512_mask_pmovus_wb_128:
7000 handleIntrinsicByApplyingToShadow(
7001 I, Intrinsic::x86_avx512_mask_pmov_wb_128,
7005 case Intrinsic::x86_avx512_mask_pmovs_qd_256:
7006 case Intrinsic::x86_avx512_mask_pmovus_qd_256:
7007 case Intrinsic::x86_avx512_mask_pmovs_wb_256:
7008 case Intrinsic::x86_avx512_mask_pmovus_wb_256:
7009 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
7010 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
7011 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
7012 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
7016 handleAVX512VectorDownConvert(
I);
7027 case Intrinsic::x86_avx512_mask_compress:
7028 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7069 case Intrinsic::x86_avx512_rsqrt14_ps_512:
7070 case Intrinsic::x86_avx512_rsqrt14_ps_256:
7071 case Intrinsic::x86_avx512_rsqrt14_ps_128:
7072 case Intrinsic::x86_avx512_rsqrt14_pd_512:
7073 case Intrinsic::x86_avx512_rsqrt14_pd_256:
7074 case Intrinsic::x86_avx512_rsqrt14_pd_128:
7075 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
7076 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
7077 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
7078 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
7079 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
7080 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
7081 handleAVX512VectorGenericMaskedFP(
I, {0},
7122 case Intrinsic::x86_avx512_rcp14_ps_512:
7123 case Intrinsic::x86_avx512_rcp14_ps_256:
7124 case Intrinsic::x86_avx512_rcp14_ps_128:
7125 case Intrinsic::x86_avx512_rcp14_pd_512:
7126 case Intrinsic::x86_avx512_rcp14_pd_256:
7127 case Intrinsic::x86_avx512_rcp14_pd_128:
7128 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
7129 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
7130 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
7131 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
7132 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
7133 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
7134 handleAVX512VectorGenericMaskedFP(
I, {0},
7179 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
7180 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
7181 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
7182 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
7183 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
7184 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
7185 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
7186 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
7187 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
7188 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
7189 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
7190 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
7191 handleAVX512VectorGenericMaskedFP(
I, {0},
7227 case Intrinsic::x86_avx512_mask_scalef_pd_512:
7228 case Intrinsic::x86_avx512_mask_scalef_pd_256:
7229 case Intrinsic::x86_avx512_mask_scalef_pd_128:
7230 case Intrinsic::x86_avx512_mask_scalef_ps_512:
7231 case Intrinsic::x86_avx512_mask_scalef_ps_256:
7232 case Intrinsic::x86_avx512_mask_scalef_ps_128:
7233 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
7234 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
7235 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
7239 handleAVX512VectorGenericMaskedFP(
I, {0, 1},
7259 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
7260 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
7261 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
7262 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
7263 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
7264 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
7265 visitGenericScalarHalfwordInst(
I);
7272 case Intrinsic::x86_avx512_fpclass_pd_512:
7273 case Intrinsic::x86_avx512_fpclass_ps_512:
7274 handleAVX512FPClass(
I);
7278 case Intrinsic::x86_vgf2p8affineqb_128:
7279 case Intrinsic::x86_vgf2p8affineqb_256:
7280 case Intrinsic::x86_vgf2p8affineqb_512:
7281 handleAVXGF2P8Affine(
I);
7291 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &
I) {
7292 switch (
I.getIntrinsicID()) {
7296 case Intrinsic::aarch64_neon_rshrn:
7297 case Intrinsic::aarch64_neon_sqrshl:
7298 case Intrinsic::aarch64_neon_sqrshrn:
7299 case Intrinsic::aarch64_neon_sqrshrun:
7300 case Intrinsic::aarch64_neon_sqshl:
7301 case Intrinsic::aarch64_neon_sqshlu:
7302 case Intrinsic::aarch64_neon_sqshrn:
7303 case Intrinsic::aarch64_neon_sqshrun:
7304 case Intrinsic::aarch64_neon_srshl:
7305 case Intrinsic::aarch64_neon_sshl:
7306 case Intrinsic::aarch64_neon_uqrshl:
7307 case Intrinsic::aarch64_neon_uqrshrn:
7308 case Intrinsic::aarch64_neon_uqshl:
7309 case Intrinsic::aarch64_neon_uqshrn:
7310 case Intrinsic::aarch64_neon_urshl:
7311 case Intrinsic::aarch64_neon_ushl:
7312 handleVectorShiftIntrinsic(
I,
false);
7325 case Intrinsic::aarch64_neon_vsli:
7326 case Intrinsic::aarch64_neon_vsri:
7327 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7334 case Intrinsic::aarch64_neon_fmaxp:
7335 case Intrinsic::aarch64_neon_fminp:
7337 case Intrinsic::aarch64_neon_fmaxnmp:
7338 case Intrinsic::aarch64_neon_fminnmp:
7340 case Intrinsic::aarch64_neon_smaxp:
7341 case Intrinsic::aarch64_neon_sminp:
7342 case Intrinsic::aarch64_neon_umaxp:
7343 case Intrinsic::aarch64_neon_uminp:
7345 case Intrinsic::aarch64_neon_addp:
7347 case Intrinsic::aarch64_neon_faddp:
7349 case Intrinsic::aarch64_neon_saddlp:
7350 case Intrinsic::aarch64_neon_uaddlp: {
7351 handlePairwiseShadowOrIntrinsic(
I, 1);
7356 case Intrinsic::aarch64_neon_fcvtas:
7357 case Intrinsic::aarch64_neon_fcvtau:
7359 case Intrinsic::aarch64_neon_fcvtms:
7360 case Intrinsic::aarch64_neon_fcvtmu:
7362 case Intrinsic::aarch64_neon_fcvtns:
7363 case Intrinsic::aarch64_neon_fcvtnu:
7365 case Intrinsic::aarch64_neon_fcvtps:
7366 case Intrinsic::aarch64_neon_fcvtpu:
7368 case Intrinsic::aarch64_neon_fcvtzs:
7369 case Intrinsic::aarch64_neon_fcvtzu:
7371 case Intrinsic::aarch64_neon_fcvtxn:
7372 handleGenericVectorConvertIntrinsic(
I,
false);
7376 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7377 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7378 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7379 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7380 handleGenericVectorConvertIntrinsic(
I,
true);
7389 case Intrinsic::aarch64_neon_faddv:
7390 case Intrinsic::aarch64_neon_saddv:
7391 case Intrinsic::aarch64_neon_uaddv:
7394 case Intrinsic::aarch64_neon_smaxv:
7395 case Intrinsic::aarch64_neon_sminv:
7396 case Intrinsic::aarch64_neon_umaxv:
7397 case Intrinsic::aarch64_neon_uminv:
7401 case Intrinsic::aarch64_neon_fmaxv:
7402 case Intrinsic::aarch64_neon_fminv:
7403 case Intrinsic::aarch64_neon_fmaxnmv:
7404 case Intrinsic::aarch64_neon_fminnmv:
7406 case Intrinsic::aarch64_neon_saddlv:
7407 case Intrinsic::aarch64_neon_uaddlv:
7408 handleVectorReduceIntrinsic(
I,
true);
7411 case Intrinsic::aarch64_neon_ld1x2:
7412 case Intrinsic::aarch64_neon_ld1x3:
7413 case Intrinsic::aarch64_neon_ld1x4:
7414 case Intrinsic::aarch64_neon_ld2:
7415 case Intrinsic::aarch64_neon_ld3:
7416 case Intrinsic::aarch64_neon_ld4:
7417 case Intrinsic::aarch64_neon_ld2r:
7418 case Intrinsic::aarch64_neon_ld3r:
7419 case Intrinsic::aarch64_neon_ld4r: {
7420 handleNEONVectorLoad(
I,
false);
7424 case Intrinsic::aarch64_neon_ld2lane:
7425 case Intrinsic::aarch64_neon_ld3lane:
7426 case Intrinsic::aarch64_neon_ld4lane: {
7427 handleNEONVectorLoad(
I,
true);
7432 case Intrinsic::aarch64_neon_sqxtn:
7433 case Intrinsic::aarch64_neon_sqxtun:
7434 case Intrinsic::aarch64_neon_uqxtn:
7441 case Intrinsic::aarch64_neon_st1x2:
7442 case Intrinsic::aarch64_neon_st1x3:
7443 case Intrinsic::aarch64_neon_st1x4:
7444 case Intrinsic::aarch64_neon_st2:
7445 case Intrinsic::aarch64_neon_st3:
7446 case Intrinsic::aarch64_neon_st4: {
7447 handleNEONVectorStoreIntrinsic(
I,
false);
7451 case Intrinsic::aarch64_neon_st2lane:
7452 case Intrinsic::aarch64_neon_st3lane:
7453 case Intrinsic::aarch64_neon_st4lane: {
7454 handleNEONVectorStoreIntrinsic(
I,
true);
7467 case Intrinsic::aarch64_neon_tbl1:
7468 case Intrinsic::aarch64_neon_tbl2:
7469 case Intrinsic::aarch64_neon_tbl3:
7470 case Intrinsic::aarch64_neon_tbl4:
7471 case Intrinsic::aarch64_neon_tbx1:
7472 case Intrinsic::aarch64_neon_tbx2:
7473 case Intrinsic::aarch64_neon_tbx3:
7474 case Intrinsic::aarch64_neon_tbx4: {
7476 handleIntrinsicByApplyingToShadow(
7477 I,
I.getIntrinsicID(),
7482 case Intrinsic::aarch64_neon_fmulx:
7483 case Intrinsic::aarch64_neon_pmul:
7484 case Intrinsic::aarch64_neon_pmull:
7485 case Intrinsic::aarch64_neon_smull:
7486 case Intrinsic::aarch64_neon_pmull64:
7487 case Intrinsic::aarch64_neon_umull: {
7488 handleNEONVectorMultiplyIntrinsic(
I);
7492 case Intrinsic::aarch64_neon_smmla:
7493 case Intrinsic::aarch64_neon_ummla:
7494 case Intrinsic::aarch64_neon_usmmla:
7495 case Intrinsic::aarch64_neon_bfmmla:
7496 handleNEONMatrixMultiply(
I);
7503 case Intrinsic::aarch64_neon_sdot:
7504 case Intrinsic::aarch64_neon_udot:
7505 case Intrinsic::aarch64_neon_usdot:
7506 handleVectorDotProductIntrinsic(
I, 4,
7516 case Intrinsic::aarch64_neon_bfdot:
7517 handleVectorDotProductIntrinsic(
I, 2,
7530 case Intrinsic::aarch64_neon_fp8_fdot2:
7531 handleVectorDotProductIntrinsic(
I, 2,
7544 case Intrinsic::aarch64_neon_fp8_fdot4:
7545 handleVectorDotProductIntrinsic(
I, 4,
7555 case Intrinsic::aarch64_neon_fp8_fdot2_lane:
7556 handleNEONDotProductLaneIntrinsic(
I, 2);
7563 case Intrinsic::aarch64_neon_fp8_fdot4_lane:
7564 handleNEONDotProductLaneIntrinsic(
I, 4);
7568 case Intrinsic::aarch64_neon_facge:
7569 case Intrinsic::aarch64_neon_facgt:
7570 handleVectorComparePackedIntrinsic(
I,
false);
7580 void visitIntrinsicInst(IntrinsicInst &
I) {
7581 if (maybeHandleCrossPlatformIntrinsic(
I))
7584 if (maybeHandleX86SIMDIntrinsic(
I))
7587 if (maybeHandleArmSIMDIntrinsic(
I))
7590 if (maybeHandleUnknownIntrinsic(
I))
7593 visitInstruction(
I);
7596 void visitLibAtomicLoad(CallBase &CB) {
7607 Value *NewOrdering =
7611 NextNodeIRBuilder NextIRB(&CB);
7612 Value *SrcShadowPtr, *SrcOriginPtr;
7613 std::tie(SrcShadowPtr, SrcOriginPtr) =
7614 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7616 Value *DstShadowPtr =
7617 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7621 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
7622 if (MS.TrackOrigins) {
7623 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7625 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7626 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7630 void visitLibAtomicStore(CallBase &CB) {
7637 Value *NewOrdering =
7641 Value *DstShadowPtr =
7651 void visitCallBase(CallBase &CB) {
7658 if (Opts.msan_handle_asm_conservative)
7659 visitAsmInstruction(CB);
7661 visitInstruction(CB);
7665 if (LF != NotLibFunc) {
7670 case LibFunc_atomic_load:
7672 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
7676 visitLibAtomicLoad(CB);
7678 case LibFunc_atomic_store:
7679 visitLibAtomicStore(CB);
7695 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7699 Func->removeFnAttrs(
B);
7705 bool MayCheckCall = MS.EagerChecks;
7709 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
7712 unsigned ArgOffset = 0;
7715 if (!
A->getType()->isSized()) {
7716 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
7720 if (
A->getType()->isScalableTy()) {
7721 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
7723 insertCheckShadowOf(
A, &CB);
7728 const DataLayout &
DL =
F.getDataLayout();
7732 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7735 insertCheckShadowOf(
A, &CB);
7736 Size =
DL.getTypeAllocSize(
A->getType());
7742 Value *ArgShadow = getShadow(
A);
7743 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7745 <<
" Shadow: " << *ArgShadow <<
"\n");
7749 assert(
A->getType()->isPointerTy() &&
7750 "ByVal argument is not a pointer!");
7758 Value *AShadowPtr, *AOriginPtr;
7759 std::tie(AShadowPtr, AOriginPtr) =
7760 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
7762 if (!PropagateShadow) {
7769 if (MS.TrackOrigins) {
7770 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7784 Size =
DL.getTypeAllocSize(
A->getType());
7790 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
7792 getOriginPtrForArgument(IRB, ArgOffset));
7804 if (FT->isVarArg()) {
7805 VAHelper->visitCallBase(CB, IRB);
7815 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
7816 setShadow(&CB, getCleanShadow(&CB));
7817 setOrigin(&CB, getCleanOrigin());
7823 Value *
Base = getShadowPtrForRetval(IRBBefore);
7824 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
7836 setShadow(&CB, getCleanShadow(&CB));
7837 setOrigin(&CB, getCleanOrigin());
7844 "Could not find insertion point for retval shadow load");
7847 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7850 setShadow(&CB, RetvalShadow);
7851 if (MS.TrackOrigins)
7852 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7857 RetVal =
I->getOperand(0);
7860 return I->isMustTailCall();
7865 void visitReturnInst(ReturnInst &
I) {
7867 Value *RetVal =
I.getReturnValue();
7873 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7874 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
7875 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7878 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
7880 Value *Shadow = getShadow(RetVal);
7881 bool StoreOrigin =
true;
7883 insertCheckShadowOf(RetVal, &
I);
7884 Shadow = getCleanShadow(RetVal);
7885 StoreOrigin =
false;
7892 if (MS.TrackOrigins && StoreOrigin)
7893 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7897 void visitPHINode(PHINode &
I) {
7899 if (!PropagateShadow) {
7900 setShadow(&
I, getCleanShadow(&
I));
7901 setOrigin(&
I, getCleanOrigin());
7905 ShadowPHINodes.push_back(&
I);
7906 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
7908 if (MS.TrackOrigins)
7910 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
7913 Value *getLocalVarIdptr(AllocaInst &
I) {
7914 ConstantInt *IntConst =
7915 ConstantInt::get(Type::getInt32Ty((*
F.getParent()).getContext()), 0);
7916 return new GlobalVariable(*
F.getParent(), IntConst->
getType(),
7921 Value *getLocalVarDescription(AllocaInst &
I) {
7926 if (PoisonStack && Opts.msan_poison_stack_with_call) {
7927 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7929 Value *ShadowBase, *OriginBase;
7930 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7933 Value *PoisonValue =
7934 IRB.
getInt8(PoisonStack ? Opts.msan_poison_stack_pattern : 0);
7935 IRB.
CreateMemSet(ShadowBase, PoisonValue, Len,
I.getAlign());
7938 if (PoisonStack && MS.TrackOrigins) {
7939 Value *Idptr = getLocalVarIdptr(
I);
7940 if (Opts.msan_print_stack_names) {
7941 Value *Descr = getLocalVarDescription(
I);
7942 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
7943 {&I, Len, Idptr, Descr});
7945 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
7951 Value *Descr = getLocalVarDescription(
I);
7953 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
7955 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
7959 void instrumentAlloca(AllocaInst &
I, Instruction *InsPoint =
nullptr) {
7962 NextNodeIRBuilder IRB(InsPoint);
7965 if (MS.CompileKernel)
7966 poisonAllocaKmsan(
I, IRB, Len);
7968 poisonAllocaUserspace(
I, IRB, Len);
7971 void visitAllocaInst(AllocaInst &
I) {
7972 setShadow(&
I, getCleanShadow(&
I));
7973 setOrigin(&
I, getCleanOrigin());
7979 void visitSelectInst(SelectInst &
I) {
7985 handleSelectLikeInst(
I,
B,
C,
D);
7991 Value *Sb = getShadow(
B);
7992 Value *Sc = getShadow(
C);
7993 Value *Sd = getShadow(
D);
7995 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
7996 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
7997 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
8002 if (
I.getType()->isAggregateType()) {
8006 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
8007 }
else if (isScalableNonVectorType(
I.getType())) {
8015 Sa1 = getCleanShadow(getShadowTy(
I.getType()));
8023 C = CreateAppToShadowCast(IRB,
C);
8024 D = CreateAppToShadowCast(IRB,
D);
8031 if (MS.TrackOrigins) {
8034 if (
B->getType()->isVectorTy()) {
8035 B = convertToBool(
B, IRB);
8036 Sb = convertToBool(Sb, IRB);
8044 void visitLandingPadInst(LandingPadInst &
I) {
8047 setShadow(&
I, getCleanShadow(&
I));
8048 setOrigin(&
I, getCleanOrigin());
8051 void visitCatchSwitchInst(CatchSwitchInst &
I) {
8052 setShadow(&
I, getCleanShadow(&
I));
8053 setOrigin(&
I, getCleanOrigin());
8056 void visitFuncletPadInst(FuncletPadInst &
I) {
8057 setShadow(&
I, getCleanShadow(&
I));
8058 setOrigin(&
I, getCleanOrigin());
8061 void visitGetElementPtrInst(GetElementPtrInst &
I) { handleShadowOr(
I); }
8063 void visitExtractValueInst(ExtractValueInst &
I) {
8065 Value *Agg =
I.getAggregateOperand();
8067 Value *AggShadow = getShadow(Agg);
8071 setShadow(&
I, ResShadow);
8072 setOriginForNaryOp(
I);
8075 void visitInsertValueInst(InsertValueInst &
I) {
8078 Value *AggShadow = getShadow(
I.getAggregateOperand());
8079 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
8085 setOriginForNaryOp(
I);
8088 void dumpInst(Instruction &
I,
const Twine &Prefix) {
8095 << CI->getCalledFunction()->
getName() <<
"\n";
8097 errs() <<
"ZZZ:" <<
Prefix <<
" " <<
I.getOpcodeName() <<
"\n";
8104 unsigned NumOperands =
I.getNumOperands();
8106 errs() <<
"YYY:" <<
Prefix <<
" call " << *
I.getType() <<
" @";
8118 errs() <<
"YYY:" <<
Prefix <<
" " << *
I.getType() <<
" "
8119 <<
I.getOpcodeName() <<
"(";
8121 for (
size_t i = 0; i < NumOperands; i++) {
8139 void visitResumeInst(ResumeInst &
I) {
8144 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
8149 void visitCatchReturnInst(CatchReturnInst &CRI) {
8154 void instrumentAsmArgument(
Value *Operand,
Type *ElemTy, Instruction &
I,
8163 insertCheckShadowOf(Operand, &
I);
8170 auto Size =
DL.getTypeStoreSize(ElemTy);
8172 if (MS.CompileKernel) {
8173 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
8179 auto [ShadowPtr,
_] =
8180 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
8190 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
8191 int NumRetOutputs = 0;
8198 NumRetOutputs =
ST->getNumElements();
8203 for (
const InlineAsm::ConstraintInfo &Info : Constraints) {
8204 switch (
Info.Type) {
8212 return NumOutputs - NumRetOutputs;
8215 void visitAsmInstruction(Instruction &
I) {
8231 const DataLayout &
DL =
F.getDataLayout();
8235 int OutputArgs = getNumOutputArgs(IA, CB);
8241 for (
int i = OutputArgs; i < NumOperands; i++) {
8249 for (
int i = 0; i < OutputArgs; i++) {
8255 setShadow(&
I, getCleanShadow(&
I));
8256 setOrigin(&
I, getCleanOrigin());
8259 void visitFreezeInst(FreezeInst &
I) {
8261 setShadow(&
I, getCleanShadow(&
I));
8262 setOrigin(&
I, getCleanOrigin());
8265 void visitInstruction(Instruction &
I) {
8267 if (Opts.msan_dump_strict_instructions)
8268 dumpInst(
I,
"Strict");
8270 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
8271 Value *Operand =
I.getOperand(i);
8273 insertCheckShadowOf(Operand, &
I);
8275 setShadow(&
I, getCleanShadow(&
I));
8276 setOrigin(&
I, getCleanOrigin());
8280struct VarArgHelperBase :
public VarArgHelper {
8282 MemorySanitizer &MS;
8283 MemorySanitizerVisitor &MSV;
8285 const unsigned VAListTagSize;
8287 VarArgHelperBase(
Function &
F, MemorySanitizer &MS,
8288 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
8289 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
8293 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
8299 MS.VAArgTLS, ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg_va_s");
8308 return getShadowPtrForVAArgument(IRB, ArgOffset);
8317 ConstantInt::get(MS.IntptrTy, ArgOffset),
8322 unsigned BaseOffset) {
8331 TailSize,
Align(8));
8334 void unpoisonVAListTagForInst(IntrinsicInst &
I) {
8336 Value *VAListTag =
I.getArgOperand(0);
8338 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
8339 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
8342 VAListTagSize, Alignment,
false);
8345 void visitVAStartInst(VAStartInst &
I)
override {
8346 if (
F.getCallingConv() == CallingConv::Win64)
8349 unpoisonVAListTagForInst(
I);
8352 void visitVACopyInst(VACopyInst &
I)
override {
8353 if (
F.getCallingConv() == CallingConv::Win64)
8355 unpoisonVAListTagForInst(
I);
8360struct VarArgAMD64Helper :
public VarArgHelperBase {
8363 static const unsigned AMD64GpEndOffset = 48;
8364 static const unsigned AMD64FpEndOffsetSSE = 176;
8366 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8368 unsigned AMD64FpEndOffset;
8369 AllocaInst *VAArgTLSCopy =
nullptr;
8370 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8371 Value *VAArgOverflowSize =
nullptr;
8373 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8375 VarArgAMD64Helper(
Function &
F, MemorySanitizer &MS,
8376 MemorySanitizerVisitor &MSV)
8377 : VarArgHelperBase(
F, MS, MSV, 24) {
8378 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8379 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
8380 if (Attr.isStringAttribute() &&
8381 (Attr.getKindAsString() ==
"target-features")) {
8382 if (Attr.getValueAsString().contains(
"-sse"))
8383 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8389 ArgKind classifyArgument(
Value *arg) {
8392 if (
T->isX86_FP80Ty())
8394 if (
T->isFPOrFPVectorTy())
8395 return AK_FloatingPoint;
8396 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
8397 return AK_GeneralPurpose;
8398 if (
T->isPointerTy())
8399 return AK_GeneralPurpose;
8411 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8412 unsigned GpOffset = 0;
8413 unsigned FpOffset = AMD64GpEndOffset;
8414 unsigned OverflowOffset = AMD64FpEndOffset;
8415 const DataLayout &
DL =
F.getDataLayout();
8426 assert(
A->getType()->isPointerTy());
8428 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8430 unsigned BaseOffset = OverflowOffset;
8431 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8432 Value *OriginBase =
nullptr;
8433 if (MS.TrackOrigins)
8434 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8435 OverflowOffset += AlignedSize;
8438 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8442 Value *ShadowPtr, *OriginPtr;
8443 std::tie(ShadowPtr, OriginPtr) =
8448 if (MS.TrackOrigins)
8452 ArgKind AK = classifyArgument(
A);
8453 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8455 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8457 Value *ShadowBase, *OriginBase =
nullptr;
8459 case AK_GeneralPurpose:
8460 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8461 if (MS.TrackOrigins)
8462 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8466 case AK_FloatingPoint:
8467 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8468 if (MS.TrackOrigins)
8469 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8476 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8478 unsigned BaseOffset = OverflowOffset;
8479 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8480 if (MS.TrackOrigins) {
8481 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8483 OverflowOffset += AlignedSize;
8486 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8495 Value *Shadow = MSV.getShadow(
A);
8497 if (MS.TrackOrigins) {
8498 Value *Origin = MSV.getOrigin(
A);
8499 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8500 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8506 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8507 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8510 void finalizeInstrumentation()
override {
8511 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8512 "finalizeInstrumentation called twice");
8513 if (!VAStartInstrumentationList.
empty()) {
8520 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8521 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8527 Intrinsic::umin, CopySize,
8531 if (MS.TrackOrigins) {
8532 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8541 for (CallInst *OrigInst : VAStartInstrumentationList) {
8542 NextNodeIRBuilder IRB(OrigInst);
8543 Value *VAListTag = OrigInst->getArgOperand(0);
8545 Value *RegSaveAreaPtrPtr =
8546 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 16));
8548 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8550 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8551 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8553 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8555 if (MS.TrackOrigins)
8556 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8557 Alignment, AMD64FpEndOffset);
8558 Value *OverflowArgAreaPtrPtr =
8559 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 8));
8560 Value *OverflowArgAreaPtr =
8561 IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8562 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8563 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8564 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8568 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8570 if (MS.TrackOrigins) {
8573 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8581struct VarArgAArch64Helper :
public VarArgHelperBase {
8582 static const unsigned kAArch64GrArgSize = 64;
8583 static const unsigned kAArch64VrArgSize = 128;
8585 static const unsigned AArch64GrBegOffset = 0;
8586 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8588 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8589 static const unsigned AArch64VrEndOffset =
8590 AArch64VrBegOffset + kAArch64VrArgSize;
8591 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8593 AllocaInst *VAArgTLSCopy =
nullptr;
8594 Value *VAArgOverflowSize =
nullptr;
8596 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8598 VarArgAArch64Helper(
Function &
F, MemorySanitizer &MS,
8599 MemorySanitizerVisitor &MSV)
8600 : VarArgHelperBase(
F, MS, MSV, 32) {}
8603 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
8604 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
8605 return {AK_GeneralPurpose, 1};
8606 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
8607 return {AK_FloatingPoint, 1};
8609 if (
T->isArrayTy()) {
8610 auto R = classifyArgument(
T->getArrayElementType());
8611 R.second *=
T->getScalarType()->getArrayNumElements();
8616 auto R = classifyArgument(FV->getScalarType());
8617 R.second *= FV->getNumElements();
8622 return {AK_Memory, 0};
8634 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8635 unsigned GrOffset = AArch64GrBegOffset;
8636 unsigned VrOffset = AArch64VrBegOffset;
8637 unsigned OverflowOffset = AArch64VAEndOffset;
8639 const DataLayout &
DL =
F.getDataLayout();
8642 auto [AK, RegNum] = classifyArgument(
A->getType());
8643 if (AK == AK_GeneralPurpose &&
8644 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8646 if (AK == AK_FloatingPoint &&
8647 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8651 case AK_GeneralPurpose:
8652 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8653 GrOffset += 8 * RegNum;
8655 case AK_FloatingPoint:
8656 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8657 VrOffset += 16 * RegNum;
8664 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8666 unsigned BaseOffset = OverflowOffset;
8667 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8668 OverflowOffset += AlignedSize;
8671 CleanUnusedTLS(IRB,
Base, BaseOffset);
8683 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8684 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8689 Value *SaveAreaPtrPtr =
8690 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8691 return IRB.
CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8696 Value *SaveAreaPtr =
8697 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8699 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
8702 void finalizeInstrumentation()
override {
8703 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8704 "finalizeInstrumentation called twice");
8705 if (!VAStartInstrumentationList.empty()) {
8712 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8713 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8719 Intrinsic::umin, CopySize,
8725 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8726 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8730 for (CallInst *OrigInst : VAStartInstrumentationList) {
8731 NextNodeIRBuilder IRB(OrigInst);
8733 Value *VAListTag = OrigInst->getArgOperand(0);
8750 Value *StackSaveAreaPtr =
8751 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8754 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8755 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8758 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8761 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8762 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8765 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8771 Value *GrRegSaveAreaShadowPtrOff =
8772 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
8774 Value *GrRegSaveAreaShadowPtr =
8775 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8781 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8787 Value *VrRegSaveAreaShadowPtrOff =
8788 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
8790 Value *VrRegSaveAreaShadowPtr =
8791 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8798 VrRegSaveAreaShadowPtrOff);
8799 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8805 Value *StackSaveAreaShadowPtr =
8806 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8811 VAArgTLSCopy, IRB.
getInt32(AArch64VAEndOffset));
8814 Align(16), VAArgOverflowSize);
8820struct VarArgPowerPC64Helper :
public VarArgHelperBase {
8821 AllocaInst *VAArgTLSCopy =
nullptr;
8822 Value *VAArgSize =
nullptr;
8824 VarArgPowerPC64Helper(
Function &
F, MemorySanitizer &MS,
8825 MemorySanitizerVisitor &MSV)
8826 : VarArgHelperBase(
F, MS, MSV, 8) {}
8828 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8836 Triple TargetTriple(
F.getParent()->getTargetTriple());
8840 if (TargetTriple.isPPC64ELFv2ABI())
8844 unsigned VAArgOffset = VAArgBase;
8845 const DataLayout &
DL =
F.getDataLayout();
8850 assert(
A->getType()->isPointerTy());
8852 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8855 ArgAlign =
Align(8);
8856 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8859 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8861 Value *AShadowPtr, *AOriginPtr;
8862 std::tie(AShadowPtr, AOriginPtr) =
8863 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8873 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8875 if (
A->getType()->isArrayTy()) {
8878 Type *ElementTy =
A->getType()->getArrayElementType();
8880 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8881 }
else if (
A->getType()->isVectorTy()) {
8883 ArgAlign =
Align(ArgSize);
8886 ArgAlign =
Align(8);
8887 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8888 if (
DL.isBigEndian()) {
8892 VAArgOffset += (8 - ArgSize);
8896 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8900 VAArgOffset += ArgSize;
8904 VAArgBase = VAArgOffset;
8908 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8911 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8914 void finalizeInstrumentation()
override {
8915 assert(!VAArgSize && !VAArgTLSCopy &&
8916 "finalizeInstrumentation called twice");
8919 Value *CopySize = VAArgSize;
8921 if (!VAStartInstrumentationList.empty()) {
8925 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8931 Intrinsic::umin, CopySize,
8939 for (CallInst *OrigInst : VAStartInstrumentationList) {
8940 NextNodeIRBuilder IRB(OrigInst);
8941 Value *VAListTag = OrigInst->getArgOperand(0);
8944 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8947 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8948 const DataLayout &
DL =
F.getDataLayout();
8949 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8951 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8952 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8954 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8961struct VarArgPowerPC32Helper :
public VarArgHelperBase {
8962 AllocaInst *VAArgTLSCopy =
nullptr;
8963 Value *VAArgSize =
nullptr;
8965 VarArgPowerPC32Helper(
Function &
F, MemorySanitizer &MS,
8966 MemorySanitizerVisitor &MSV)
8967 : VarArgHelperBase(
F, MS, MSV, 12) {}
8969 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8973 unsigned VAArgOffset = VAArgBase;
8974 const DataLayout &
DL =
F.getDataLayout();
8975 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8980 assert(
A->getType()->isPointerTy());
8982 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8984 if (ArgAlign < IntptrSize)
8985 ArgAlign =
Align(IntptrSize);
8986 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8989 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8991 Value *AShadowPtr, *AOriginPtr;
8992 std::tie(AShadowPtr, AOriginPtr) =
8993 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9003 Type *ArgTy =
A->getType();
9009 uint64_t ArgSize =
DL.getTypeAllocSize(ArgTy);
9016 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
9019 ArgAlign =
Align(ArgSize);
9021 if (ArgAlign < IntptrSize)
9022 ArgAlign =
Align(IntptrSize);
9023 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9024 if (
DL.isBigEndian()) {
9027 if (ArgSize < IntptrSize)
9028 VAArgOffset += (IntptrSize - ArgSize);
9031 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
9037 VAArgOffset += ArgSize;
9044 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
9047 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9050 void finalizeInstrumentation()
override {
9051 assert(!VAArgSize && !VAArgTLSCopy &&
9052 "finalizeInstrumentation called twice");
9054 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9055 Value *CopySize = VAArgSize;
9057 if (!VAStartInstrumentationList.empty()) {
9061 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9067 Intrinsic::umin, CopySize,
9075 for (CallInst *OrigInst : VAStartInstrumentationList) {
9076 NextNodeIRBuilder IRB(OrigInst);
9077 Value *VAListTag = OrigInst->getArgOperand(0);
9079 Value *RegSaveAreaSize = CopySize;
9083 IRB.
CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
9087 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
9089 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9092 const DataLayout &
DL =
F.getDataLayout();
9093 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9097 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9098 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9099 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9101 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
9102 Alignment, RegSaveAreaSize);
9104 RegSaveAreaShadowPtr =
9107 ConstantInt::get(MS.IntptrTy, 32));
9112 ConstantInt::get(MS.IntptrTy, 32), Alignment);
9117 Value *OverflowAreaSize = IRB.
CreateSub(CopySize, RegSaveAreaSize);
9120 OverflowAreaPtrPtr =
9121 IRB.
CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
9122 OverflowAreaPtrPtr = IRB.
CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
9124 Value *OverflowAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
9126 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
9127 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
9128 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.
getInt8Ty(),
9131 Value *OverflowVAArgTLSCopyPtr =
9133 OverflowVAArgTLSCopyPtr =
9134 IRB.
CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
9136 OverflowVAArgTLSCopyPtr =
9139 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
9146struct VarArgSystemZHelper :
public VarArgHelperBase {
9147 static const unsigned SystemZGpOffset = 16;
9148 static const unsigned SystemZGpEndOffset = 56;
9149 static const unsigned SystemZFpOffset = 128;
9150 static const unsigned SystemZFpEndOffset = 160;
9151 static const unsigned SystemZMaxVrArgs = 8;
9152 static const unsigned SystemZRegSaveAreaSize = 160;
9153 static const unsigned SystemZOverflowOffset = 160;
9154 static const unsigned SystemZVAListTagSize = 32;
9155 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
9156 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
9158 bool IsSoftFloatABI;
9159 AllocaInst *VAArgTLSCopy =
nullptr;
9160 AllocaInst *VAArgTLSOriginCopy =
nullptr;
9161 Value *VAArgOverflowSize =
nullptr;
9163 enum class ArgKind {
9171 enum class ShadowExtension {
None,
Zero, Sign };
9173 VarArgSystemZHelper(
Function &
F, MemorySanitizer &MS,
9174 MemorySanitizerVisitor &MSV)
9175 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
9176 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
9178 ArgKind classifyArgument(
Type *
T) {
9185 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
9186 return ArgKind::Indirect;
9187 if (
T->isFloatingPointTy())
9188 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
9189 if (
T->isIntegerTy() ||
T->isPointerTy())
9190 return ArgKind::GeneralPurpose;
9191 if (
T->isVectorTy())
9192 return ArgKind::Vector;
9193 return ArgKind::Memory;
9196 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
9206 return ShadowExtension::Zero;
9210 return ShadowExtension::Sign;
9212 return ShadowExtension::None;
9215 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9216 unsigned GpOffset = SystemZGpOffset;
9217 unsigned FpOffset = SystemZFpOffset;
9218 unsigned VrIndex = 0;
9219 unsigned OverflowOffset = SystemZOverflowOffset;
9220 const DataLayout &
DL =
F.getDataLayout();
9226 ArgKind AK = classifyArgument(
T);
9227 if (AK == ArgKind::Indirect) {
9229 AK = ArgKind::GeneralPurpose;
9231 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
9232 AK = ArgKind::Memory;
9233 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
9234 AK = ArgKind::Memory;
9235 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
9236 AK = ArgKind::Memory;
9237 Value *ShadowBase =
nullptr;
9238 Value *OriginBase =
nullptr;
9239 ShadowExtension SE = ShadowExtension::None;
9241 case ArgKind::GeneralPurpose: {
9246 SE = getShadowExtension(CB, ArgNo);
9248 if (SE == ShadowExtension::None) {
9250 assert(ArgAllocSize <= ArgSize);
9251 GapSize = ArgSize - ArgAllocSize;
9253 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
9254 if (MS.TrackOrigins)
9255 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
9257 GpOffset += ArgSize;
9263 case ArgKind::FloatingPoint: {
9272 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
9273 if (MS.TrackOrigins)
9274 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
9276 FpOffset += ArgSize;
9282 case ArgKind::Vector: {
9289 case ArgKind::Memory: {
9297 SE = getShadowExtension(CB, ArgNo);
9299 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
9301 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
9302 if (MS.TrackOrigins)
9304 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
9305 OverflowOffset += ArgSize;
9312 case ArgKind::Indirect:
9315 if (ShadowBase ==
nullptr)
9317 Value *Shadow = MSV.getShadow(
A);
9318 if (SE != ShadowExtension::None)
9319 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
9320 SE == ShadowExtension::Sign);
9321 ShadowBase = IRB.
CreateIntToPtr(ShadowBase, MS.PtrTy,
"_msarg_va_s");
9323 if (MS.TrackOrigins) {
9324 Value *Origin = MSV.getOrigin(
A);
9325 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
9326 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
9330 Constant *OverflowSize = ConstantInt::get(
9331 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
9332 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
9339 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
9342 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9344 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9345 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
9350 unsigned RegSaveAreaSize =
9351 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9352 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9354 if (MS.TrackOrigins)
9355 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9356 Alignment, RegSaveAreaSize);
9365 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9367 Value *OverflowArgAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9368 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9370 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9371 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
9374 SystemZOverflowOffset);
9375 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9377 if (MS.TrackOrigins) {
9379 SystemZOverflowOffset);
9380 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9385 void finalizeInstrumentation()
override {
9386 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9387 "finalizeInstrumentation called twice");
9388 if (!VAStartInstrumentationList.empty()) {
9395 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9397 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9403 Intrinsic::umin, CopySize,
9407 if (MS.TrackOrigins) {
9408 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9417 for (CallInst *OrigInst : VAStartInstrumentationList) {
9418 NextNodeIRBuilder IRB(OrigInst);
9419 Value *VAListTag = OrigInst->getArgOperand(0);
9420 copyRegSaveArea(IRB, VAListTag);
9421 copyOverflowArea(IRB, VAListTag);
9427struct VarArgI386Helper :
public VarArgHelperBase {
9428 AllocaInst *VAArgTLSCopy =
nullptr;
9429 Value *VAArgSize =
nullptr;
9431 VarArgI386Helper(
Function &
F, MemorySanitizer &MS,
9432 MemorySanitizerVisitor &MSV)
9433 : VarArgHelperBase(
F, MS, MSV, 4) {}
9435 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9436 const DataLayout &
DL =
F.getDataLayout();
9437 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9438 unsigned VAArgOffset = 0;
9443 assert(
A->getType()->isPointerTy());
9445 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9447 if (ArgAlign < IntptrSize)
9448 ArgAlign =
Align(IntptrSize);
9449 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9451 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9453 Value *AShadowPtr, *AOriginPtr;
9454 std::tie(AShadowPtr, AOriginPtr) =
9455 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9465 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9467 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9468 if (
DL.isBigEndian()) {
9471 if (ArgSize < IntptrSize)
9472 VAArgOffset += (IntptrSize - ArgSize);
9475 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9478 VAArgOffset += ArgSize;
9484 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9487 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9490 void finalizeInstrumentation()
override {
9491 assert(!VAArgSize && !VAArgTLSCopy &&
9492 "finalizeInstrumentation called twice");
9494 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9495 Value *CopySize = VAArgSize;
9497 if (!VAStartInstrumentationList.empty()) {
9500 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9506 Intrinsic::umin, CopySize,
9514 for (CallInst *OrigInst : VAStartInstrumentationList) {
9515 NextNodeIRBuilder IRB(OrigInst);
9516 Value *VAListTag = OrigInst->getArgOperand(0);
9517 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9518 Value *RegSaveAreaPtrPtr =
9520 PointerType::get(*MS.C, 0));
9521 Value *RegSaveAreaPtr =
9522 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9523 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9524 const DataLayout &
DL =
F.getDataLayout();
9525 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9527 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9528 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9530 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9538struct VarArgGenericHelper :
public VarArgHelperBase {
9539 AllocaInst *VAArgTLSCopy =
nullptr;
9540 Value *VAArgSize =
nullptr;
9542 VarArgGenericHelper(
Function &
F, MemorySanitizer &MS,
9543 MemorySanitizerVisitor &MSV,
const unsigned VAListTagSize)
9544 : VarArgHelperBase(
F, MS, MSV, VAListTagSize) {}
9546 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9547 unsigned VAArgOffset = 0;
9548 const DataLayout &
DL =
F.getDataLayout();
9549 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9554 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9555 if (
DL.isBigEndian()) {
9558 if (ArgSize < IntptrSize)
9559 VAArgOffset += (IntptrSize - ArgSize);
9561 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9562 VAArgOffset += ArgSize;
9563 VAArgOffset =
alignTo(VAArgOffset, IntptrSize);
9569 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9572 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9575 void finalizeInstrumentation()
override {
9576 assert(!VAArgSize && !VAArgTLSCopy &&
9577 "finalizeInstrumentation called twice");
9579 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9580 Value *CopySize = VAArgSize;
9582 if (!VAStartInstrumentationList.empty()) {
9585 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9591 Intrinsic::umin, CopySize,
9599 for (CallInst *OrigInst : VAStartInstrumentationList) {
9600 NextNodeIRBuilder IRB(OrigInst);
9601 Value *VAListTag = OrigInst->getArgOperand(0);
9602 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9603 Value *RegSaveAreaPtrPtr =
9605 PointerType::get(*MS.C, 0));
9606 Value *RegSaveAreaPtr =
9607 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9608 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9609 const DataLayout &
DL =
F.getDataLayout();
9610 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9612 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9613 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9615 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9623using VarArgARM32Helper = VarArgGenericHelper;
9624using VarArgRISCVHelper = VarArgGenericHelper;
9625using VarArgMIPSHelper = VarArgGenericHelper;
9626using VarArgLoongArch64Helper = VarArgGenericHelper;
9627using VarArgHexagonHelper = VarArgGenericHelper;
9630struct VarArgNoOpHelper :
public VarArgHelper {
9631 VarArgNoOpHelper(
Function &
F, MemorySanitizer &MS,
9632 MemorySanitizerVisitor &MSV) {}
9634 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {}
9636 void visitVAStartInst(VAStartInst &
I)
override {}
9638 void visitVACopyInst(VACopyInst &
I)
override {}
9640 void finalizeInstrumentation()
override {}
9646 MemorySanitizerVisitor &Visitor) {
9649 Triple TargetTriple(Func.getParent()->getTargetTriple());
9652 return new VarArgI386Helper(Func, Msan, Visitor);
9655 return new VarArgAMD64Helper(Func, Msan, Visitor);
9657 if (TargetTriple.
isARM())
9658 return new VarArgARM32Helper(Func, Msan, Visitor, 4);
9661 return new VarArgAArch64Helper(Func, Msan, Visitor);
9664 return new VarArgSystemZHelper(Func, Msan, Visitor);
9669 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9672 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9675 return new VarArgRISCVHelper(Func, Msan, Visitor, 4);
9678 return new VarArgRISCVHelper(Func, Msan, Visitor, 8);
9681 return new VarArgMIPSHelper(Func, Msan, Visitor, 4);
9684 return new VarArgMIPSHelper(Func, Msan, Visitor, 8);
9687 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9691 return new VarArgHexagonHelper(Func, Msan, Visitor, 12);
9693 return new VarArgNoOpHelper(Func, Msan, Visitor);
9700 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9703 MemorySanitizerVisitor Visitor(
F, *
this, TLI);
9710 return Visitor.runOnFunction();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isStore(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static const size_t kNumberOfAccessSizes
VarLocInsertPt getNextNode(const DbgRecord *DVR)
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool insertModuleCtor(Module &M)
const MemoryMapParams Linux_LoongArch64_MemoryMapParams
const MemoryMapParams Linux_X86_64_MemoryMapParams
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_S390X_MemoryMapParams
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_AArch64_MemoryMapParams
static bool isAMustTailRetVal(Value *RetVal)
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
Module.h This file contains the declarations for the Module class.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
static const PlatformMemoryMapParams Linux_S390_MemoryMapParams
static const Align kMinOriginAlignment
static const PlatformMemoryMapParams Linux_X86_MemoryMapParams
static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
static MemorySanitizerOptions resolveOptions(const InstrumentationOptions &Opts, MemorySanitizerOptions O)
static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static const unsigned kOriginSize
static const Align kShadowTLSAlignment
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P
static const MemoryMapParams Linux_I386_MemoryMapParams
const char kMsanInitName[]
static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams
static GlobalVariable * createPrivateConstGlobalForString(Module &M, StringRef Str)
Create a non-const global initialized with the given string.
static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams
static const size_t kNumberOfAccessSizes
static VarArgHelper * CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, MemorySanitizerVisitor &Visitor)
static const MemoryMapParams Linux_MIPS64_MemoryMapParams
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
static const MemoryMapParams Linux_Hexagon_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams
static const unsigned kParamTLSSize
static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
static const unsigned kRetvalTLSSize
static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams
const char kMsanModuleCtorName[]
static const MemoryMapParams FreeBSD_I386_MemoryMapParams
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
const SmallVectorImpl< MachineOperand > & Cond
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
void setAlignment(Align Align)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
const T & front() const
Get the first element.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
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...
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
void removeFnAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the function.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Value * getCalledOperand() const
Type * getParamElementType(unsigned ArgNo) const
Extract the elementtype type for a parameter.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_SGT
signed greater than
@ ICMP_SGE
signed greater or equal
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true, bool ByteString=false)
This method constructs a CDS and initializes it with a text string.
static LLVM_ABI Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
static bool shouldExecute(CounterInfo &Counter)
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
static FixedVectorType * getHalfElementsVectorType(FixedVectorType *VTy)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
LLVM_ABI void setComdat(Comdat *C)
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ ExternalLinkage
Externally visible function.
Analysis pass providing a never-invalidated alias analysis result.
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
LLVM_ABI Value * CreateAndReduce(Value *Src)
Create a vector int AND reduction intrinsic of the source vector.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
LLVM_ABI CallInst * CreateMaskedCompressStore(Value *Val, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr)
Create a call to Masked Compress Store intrinsic.
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
IntegerType * getInt16Ty()
Fetch the type representing a 16-bit integer.
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
LLVM_ABI Value * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI DebugLoc getCurrentDebugLocation() const
Get location information used by debugging information.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memset to the specified pointer and the specified value.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
LLVMContext & getContext() const
Value * CreateAnd(Value *LHS, Value *RHS, 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)
LLVM_ABI CallInst * CreateMaskedStore(Value *Val, Value *Ptr, Align Alignment, Value *Mask)
Create a call to Masked Store intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
LLVM_ABI CallInst * CreateMaskedExpandLoad(Type *Ty, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Expand Load intrinsic.
Value * CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name="")
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LLVM_ABI CallInst * CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment, Value *Mask=nullptr)
Create a call to Masked Scatter intrinsic.
LLVM_ABI CallInst * CreateMaskedGather(Type *Ty, Value *Ptrs, Align Alignment, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Gather intrinsic.
Value * CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
std::vector< ConstraintInfo > ConstraintInfoVector
void visit(Iterator Start, Iterator End)
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.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
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 LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
bool remove(const value_type &X)
Remove an item from the set vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
LibFunc getLibFunc(StringRef funcName) const
Searches for a particular function name.
Triple - Helper class for working with autoconf configuration names.
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
bool isRISCV32() const
Tests whether the target is 32-bit RISC-V.
bool isPPC32() const
Tests whether the target is 32-bit PowerPC (little and big endian).
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isRISCV64() const
Tests whether the target is 64-bit RISC-V.
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
bool isARM() const
Tests whether the target is ARM (little and big endian).
bool isPPC64() const
Tests whether the target is 64-bit PowerPC (little and big endian).
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
bool isSystemZ() const
Tests whether the target is SystemZ.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isArrayTy() const
True if this is an instance of ArrayType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isPointerTy() const
True if this is an instance of PointerType.
Type * getArrayElementType() const
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
bool isVoidTy() const
Return true if this is 'void'.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#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 std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
LLVM_ABI StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
Function * Kernel
Summary of a kernel (=entry point for target offloading).
NodeAddr< FuncNode * > Func
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)
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
RelativeUniformCounterPtr Values
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.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI std::pair< Instruction *, Value * > SplitBlockAndInsertSimpleForLoop(Value *End, BasicBlock::iterator SplitBefore)
Insert a for (int i = 0; i < End; i++) loop structure (with the exception that End is assumed > 0,...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool FoldInstsToUnreachable=true)
Remove all blocks that can not be reached from the function's entry.
auto dyn_cast_or_null(const Y &Val)
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.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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 bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ Or
Bitwise or logical OR of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
RoundingMode
Rounding mode.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
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 bool valueOr(BoolOrDefault X, bool Default)
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ End
Run the machine verifier once, at the end of the pipeline.
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...
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
std::string itostr(int64_t X)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)