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",
696 TLI.getAttrList(
C, {0},
false),
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,
756 TLI.getAttrList(
C, {0},
false),
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(
795 FunctionName,
TLI.getAttrList(
C, {0, 1},
false),
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(
802 FunctionName,
TLI.getAttrList(
C, {0, 2},
false),
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",
829 TLI.getAttrList(
C, {0},
false,
true), IRB.getInt32Ty(),
831 MsanSetOriginFn =
M.getOrInsertFunction(
832 "__msan_set_origin",
TLI.getAttrList(
C, {2},
false),
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",
839 TLI.getAttrList(
C, {1},
true),
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)
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);
1811 if (!MS.TrackOrigins)
1823 Value *getOriginPtrForRetval() {
1825 return MS.RetvalOriginTLS;
1830 assert(!ShadowMap.
count(
V) &&
"Values may only have one shadow");
1833 if (SV && !
V->getType()->isVoidTy() && getShadowTy(
V) !=
SV->getType()) {
1836 assert(getShadowTy(
V) ==
SV->getType() &&
1837 "setShadow called with mismatching types");
1840 ShadowMap[
V] = PropagateShadow ?
SV : getCleanShadow(
V);
1845 if (!MS.TrackOrigins)
1847 assert(!OriginMap.
count(
V) &&
"Values may only have one origin");
1849 OriginMap[
V] = Origin;
1853 Type *ShadowTy = getShadowTy(OrigTy);
1863 Constant *getCleanShadow(
Value *
V) {
return getCleanShadow(
V->getType()); }
1871 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
1872 getPoisonedShadow(AT->getElementType()));
1876 SmallVector<Constant *, 4> Vals;
1877 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1878 Vals.
push_back(getPoisonedShadow(
ST->getElementType(i)));
1886 Type *ShadowTy = getShadowTy(
V);
1889 return getPoisonedShadow(ShadowTy);
1901 if (!PropagateShadow ||
I->getMetadata(LLVMContext::MD_nosanitize))
1902 return getCleanShadow(
V);
1904 Value *Shadow = ShadowMap[
V];
1907 assert(Shadow &&
"No shadow for a value");
1914 Value *
AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(
V)
1915 : getCleanShadow(
V);
1921 Value *&ShadowPtr = ShadowMap[
V];
1926 unsigned ArgOffset = 0;
1927 const DataLayout &
DL =
F->getDataLayout();
1928 for (
auto &FArg :
F->args()) {
1929 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
1931 ?
"vscale not fully supported\n"
1932 :
"Arg is not sized\n"));
1934 ShadowPtr = getCleanShadow(
V);
1935 setOrigin(
A, getCleanOrigin());
1941 unsigned Size = FArg.hasByValAttr()
1942 ?
DL.getTypeAllocSize(FArg.getParamByValType())
1943 :
DL.getTypeAllocSize(FArg.getType());
1947 if (FArg.hasByValAttr()) {
1951 const Align ArgAlign =
DL.getValueOrABITypeAlignment(
1952 FArg.getParamAlign(), FArg.getParamByValType());
1953 Value *CpShadowPtr, *CpOriginPtr;
1954 std::tie(CpShadowPtr, CpOriginPtr) =
1955 getShadowOriginPtr(
V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
1957 if (!PropagateShadow || Overflow) {
1959 EntryIRB.CreateMemSet(
1963 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1965 [[maybe_unused]]
Value *Cpy = EntryIRB.CreateMemCpy(
1966 CpShadowPtr, CopyAlign,
Base, CopyAlign,
Size);
1969 if (MS.TrackOrigins) {
1970 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1974 EntryIRB.CreateMemCpy(
1983 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
1984 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
1985 ShadowPtr = getCleanShadow(
V);
1986 setOrigin(
A, getCleanOrigin());
1989 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1990 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg),
Base,
1992 if (MS.TrackOrigins) {
1993 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1994 setOrigin(
A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
1998 <<
" ARG: " << FArg <<
" ==> " << *ShadowPtr <<
"\n");
2004 assert(ShadowPtr &&
"Could not find shadow for an argument");
2011 cast<Constant>(
V)->containsUndefOrPoisonElement() && PropagateShadow &&
2012 PoisonUndefVectors) {
2015 for (
unsigned i = 0; i != NumElems; ++i) {
2018 : getCleanShadow(Elem);
2022 LLVM_DEBUG(
dbgs() <<
"Partial undef constant vector: " << *
V <<
" ==> "
2023 << *ShadowConstant <<
"\n");
2025 return ShadowConstant;
2031 return getCleanShadow(
V);
2035 Value *getShadow(Instruction *
I,
int i) {
2036 return getShadow(
I->getOperand(i));
2041 if (!MS.TrackOrigins)
2044 return getCleanOrigin();
2046 "Unexpected value type in getOrigin()");
2048 if (
I->getMetadata(LLVMContext::MD_nosanitize))
2049 return getCleanOrigin();
2051 Value *Origin = OriginMap[
V];
2052 assert(Origin &&
"Missing origin");
2057 Value *getOrigin(Instruction *
I,
int i) {
2058 return getOrigin(
I->getOperand(i));
2065 void insertCheckShadow(
Value *Shadow,
Value *Origin, Instruction *OrigIns) {
2071 LLVM_DEBUG(
dbgs() <<
"Skipping check of " << *Shadow <<
" before "
2072 << *OrigIns <<
"\n");
2077 if (isScalableNonVectorType(ShadowTy)) {
2078 LLVM_DEBUG(
dbgs() <<
"Skipping check of scalable non-vector " << *Shadow
2079 <<
" before " << *OrigIns <<
"\n");
2085 "Can only insert checks for integer, vector, and aggregate shadow "
2088 InstrumentationList.push_back(
2089 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2097 void insertCheckShadowOf(
Value *Val, Instruction *OrigIns) {
2099 Value *Shadow, *Origin;
2100 if (Opts.msan_check_constant_shadow) {
2101 Shadow = getShadow(Val);
2104 Origin = getOrigin(Val);
2111 insertCheckShadow(Shadow, Origin, OrigIns);
2116 case AtomicOrdering::NotAtomic:
2117 return AtomicOrdering::NotAtomic;
2118 case AtomicOrdering::Unordered:
2119 case AtomicOrdering::Monotonic:
2120 case AtomicOrdering::Release:
2121 return AtomicOrdering::Release;
2122 case AtomicOrdering::Acquire:
2123 case AtomicOrdering::AcquireRelease:
2124 return AtomicOrdering::AcquireRelease;
2125 case AtomicOrdering::SequentiallyConsistent:
2126 return AtomicOrdering::SequentiallyConsistent;
2132 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2133 uint32_t OrderingTable[NumOrderings] = {};
2135 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2136 OrderingTable[(
int)AtomicOrderingCABI::release] =
2137 (int)AtomicOrderingCABI::release;
2138 OrderingTable[(int)AtomicOrderingCABI::consume] =
2139 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2140 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2141 (
int)AtomicOrderingCABI::acq_rel;
2142 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2143 (
int)AtomicOrderingCABI::seq_cst;
2150 case AtomicOrdering::NotAtomic:
2151 return AtomicOrdering::NotAtomic;
2152 case AtomicOrdering::Unordered:
2153 case AtomicOrdering::Monotonic:
2154 case AtomicOrdering::Acquire:
2155 return AtomicOrdering::Acquire;
2156 case AtomicOrdering::Release:
2157 case AtomicOrdering::AcquireRelease:
2158 return AtomicOrdering::AcquireRelease;
2159 case AtomicOrdering::SequentiallyConsistent:
2160 return AtomicOrdering::SequentiallyConsistent;
2166 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2167 uint32_t OrderingTable[NumOrderings] = {};
2169 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2170 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2171 OrderingTable[(int)AtomicOrderingCABI::consume] =
2172 (
int)AtomicOrderingCABI::acquire;
2173 OrderingTable[(int)AtomicOrderingCABI::release] =
2174 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
2175 (int)AtomicOrderingCABI::acq_rel;
2176 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2177 (
int)AtomicOrderingCABI::seq_cst;
2183 using InstVisitor<MemorySanitizerVisitor>
::visit;
2184 void visit(Instruction &
I) {
2185 if (
I.getMetadata(LLVMContext::MD_nosanitize))
2188 if (isInPrologue(
I))
2193 setShadow(&
I, getCleanShadow(&
I));
2194 setOrigin(&
I, getCleanOrigin());
2205 void visitLoadInst(LoadInst &
I) {
2206 assert(
I.getType()->isSized() &&
"Load type must have size");
2207 assert(!
I.getMetadata(LLVMContext::MD_nosanitize));
2208 NextNodeIRBuilder IRB(&
I);
2209 Type *ShadowTy = getShadowTy(&
I);
2210 Value *Addr =
I.getPointerOperand();
2211 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
2213 if (PropagateShadow) {
2214 std::tie(ShadowPtr, OriginPtr) =
2215 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
2219 setShadow(&
I, getCleanShadow(&
I));
2222 if (Opts.msan_check_access_address)
2223 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2228 if (MS.TrackOrigins) {
2229 if (PropagateShadow) {
2234 setOrigin(&
I, getCleanOrigin());
2243 void visitStoreInst(StoreInst &
I) {
2244 StoreList.push_back(&
I);
2245 if (Opts.msan_check_access_address)
2246 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2249 void handleCASOrRMW(Instruction &
I) {
2253 Value *Addr =
I.getOperand(0);
2254 Value *Val =
I.getOperand(1);
2255 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val),
Align(1),
2259 if (Opts.msan_check_access_address)
2260 insertCheckShadowOf(Addr, &
I);
2266 insertCheckShadowOf(Val, &
I);
2270 setShadow(&
I, getCleanShadow(&
I));
2271 setOrigin(&
I, getCleanOrigin());
2274 void visitAtomicRMWInst(AtomicRMWInst &
I) {
2279 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2341 void visitSwitchInst(SwitchInst &SI) {
2344 Value *Val =
SI.getCondition();
2345 Value *ShadowVal = getShadow(Val);
2355 int casesToConsider = Opts.msan_switch_precision;
2357 Value *ShadowCases =
nullptr;
2358 for (
auto Case :
SI.cases()) {
2359 if (casesToConsider <= 0)
2362 Value *Comparator = Case.getCaseValue();
2365 Value *ComparisonShadow = propagateEqualityComparison(
2366 IRB, Val, Comparator, ShadowVal, getShadow(Comparator));
2369 ShadowCases = IRB.
CreateOr(ShadowCases, ComparisonShadow);
2371 ShadowCases = ComparisonShadow;
2377 insertCheckShadow(ShadowCases, getOrigin(Val), &SI);
2381 void visitExtractElementInst(ExtractElementInst &
I) {
2382 insertCheckShadowOf(
I.getOperand(1), &
I);
2386 setOrigin(&
I, getOrigin(&
I, 0));
2389 void visitInsertElementInst(InsertElementInst &
I) {
2390 insertCheckShadowOf(
I.getOperand(2), &
I);
2392 auto *Shadow0 = getShadow(&
I, 0);
2393 auto *Shadow1 = getShadow(&
I, 1);
2396 setOriginForNaryOp(
I);
2399 void visitShuffleVectorInst(ShuffleVectorInst &
I) {
2401 auto *Shadow0 = getShadow(&
I, 0);
2402 auto *Shadow1 = getShadow(&
I, 1);
2405 setOriginForNaryOp(
I);
2409 void visitSExtInst(SExtInst &
I) {
2411 setShadow(&
I, IRB.
CreateSExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2412 setOrigin(&
I, getOrigin(&
I, 0));
2415 void visitZExtInst(ZExtInst &
I) {
2417 setShadow(&
I, IRB.
CreateZExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2418 setOrigin(&
I, getOrigin(&
I, 0));
2421 void visitTruncInst(TruncInst &
I) {
2423 setShadow(&
I, IRB.
CreateTrunc(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2424 setOrigin(&
I, getOrigin(&
I, 0));
2427 void visitBitCastInst(BitCastInst &
I) {
2432 if (CI->isMustTailCall())
2436 setOrigin(&
I, getOrigin(&
I, 0));
2439 void visitAddrSpaceCastInst(AddrSpaceCastInst &
I) {
2442 "_msprop_addrspacecast"));
2443 setOrigin(&
I, getOrigin(&
I, 0));
2446 void visitPtrToIntInst(PtrToIntInst &
I) {
2449 "_msprop_ptrtoint"));
2450 setOrigin(&
I, getOrigin(&
I, 0));
2453 void visitPtrToAddrInst(PtrToAddrInst &
I) {
2456 "_msprop_ptrtoaddr"));
2457 setOrigin(&
I, getOrigin(&
I, 0));
2460 void visitIntToPtrInst(IntToPtrInst &
I) {
2463 "_msprop_inttoptr"));
2464 setOrigin(&
I, getOrigin(&
I, 0));
2485 void handleGenericVectorConvertIntrinsic(Instruction &
I,
bool FixedPoint) {
2486 [[maybe_unused]]
unsigned NumArgs =
I.getNumOperands();
2488 NumArgs = CI->arg_size();
2492 Value *Precision =
I.getOperand(1);
2493 insertCheckShadowOf(Precision, &
I);
2499 Value *S0 = getShadow(&
I, 0);
2509 setShadow(&
I, OutShadow);
2510 setOriginForNaryOp(
I);
2513 void visitFPToSIInst(CastInst &
I) {
2514 handleGenericVectorConvertIntrinsic(
I,
false);
2516 void visitFPToUIInst(CastInst &
I) {
2517 handleGenericVectorConvertIntrinsic(
I,
false);
2519 void visitSIToFPInst(CastInst &
I) {
2520 handleGenericVectorConvertIntrinsic(
I,
false);
2522 void visitUIToFPInst(CastInst &
I) {
2523 handleGenericVectorConvertIntrinsic(
I,
false);
2526 void visitFPExtInst(CastInst &
I) {
2527 handleGenericVectorConvertIntrinsic(
I,
false);
2529 void visitFPTruncInst(CastInst &
I) {
2530 handleGenericVectorConvertIntrinsic(
I,
false);
2551 assert(
V1->getType()->isIntOrIntVectorTy());
2562 return IRB.
CreateOr({S1S2, V1S2, S1V2});
2566 void visitAnd(BinaryOperator &
I) {
2569 Value *V2 =
I.getOperand(1);
2571 Value *S2 = getShadow(&
I, 1);
2573 Value *OutShadow = handleBitwiseAnd(IRB,
V1, V2,
S1, S2);
2575 setShadow(&
I, OutShadow);
2576 setOriginForNaryOp(
I);
2579 void visitOr(BinaryOperator &
I) {
2592 Value *S2 = getShadow(&
I, 1);
2594 Value *V2 =
I.getOperand(1);
2598 assert(
V1->getType()->isIntOrIntVectorTy());
2614 if (Opts.msan_precise_disjoint_or &&
2619 S = IRB.
CreateOr(S, DisjointOrShadow,
"_ms_disjoint");
2623 setOriginForNaryOp(
I);
2641 template <
bool CombineShadow>
class Combiner {
2642 Value *Shadow =
nullptr;
2643 Value *Origin =
nullptr;
2645 MemorySanitizerVisitor *MSV;
2648 Combiner(MemorySanitizerVisitor *MSV,
IRBuilder<> &IRB)
2649 : IRB(IRB), MSV(MSV) {}
2653 if (CombineShadow) {
2658 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2659 Shadow = IRB.
CreateOr(Shadow, OpShadow,
"_msprop");
2663 if (MSV->MS.TrackOrigins) {
2670 if (!ConstOrigin || !ConstOrigin->
isNullValue()) {
2671 Value *
Cond = MSV->convertToBool(OpShadow, IRB);
2681 Value *OpShadow = MSV->getShadow(
V);
2682 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(
V) :
nullptr;
2683 return Add(OpShadow, OpOrigin);
2688 void Done(Instruction *
I) {
2689 if (CombineShadow) {
2691 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(
I));
2692 MSV->setShadow(
I, Shadow);
2694 if (MSV->MS.TrackOrigins) {
2696 MSV->setOrigin(
I, Origin);
2702 void DoneAndStoreOrigin(TypeSize TS,
Value *OriginPtr) {
2703 if (MSV->MS.TrackOrigins) {
2710 using ShadowAndOriginCombiner = Combiner<true>;
2711 using OriginCombiner = Combiner<false>;
2714 void setOriginForNaryOp(Instruction &
I) {
2715 if (!MS.TrackOrigins)
2718 OriginCombiner OC(
this, IRB);
2719 for (Use &
Op :
I.operands())
2724 size_t VectorOrPrimitiveTypeSizeInBits(
Type *Ty) {
2726 "Vector of pointers is not a valid shadow type");
2736 Type *srcTy =
V->getType();
2739 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2740 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2741 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2759 Type *ShadowTy = getShadowTy(
V);
2760 if (
V->getType() == ShadowTy)
2762 if (
V->getType()->isPtrOrPtrVectorTy())
2769 void handleShadowOr(Instruction &
I) {
2771 ShadowAndOriginCombiner SC(
this, IRB);
2772 for (Use &
Op :
I.operands())
2799 Value *horizontalReduce(IntrinsicInst &
I,
unsigned ReductionFactor,
2800 unsigned Shards,
Value *VectorA,
Value *VectorB) {
2805 [[maybe_unused]]
unsigned TotalNumElems = NumElems;
2811 assert(NumElems % (ReductionFactor * Shards) == 0);
2816 for (
unsigned i = 0; i < ReductionFactor; i++) {
2817 SmallVector<int, 16>
Mask;
2819 for (
unsigned j = 0;
j < Shards;
j++) {
2820 unsigned Offset = NumElems / Shards *
j;
2822 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2826 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2851 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards) {
2852 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2854 assert(
I.getType()->isVectorTy());
2855 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2857 [[maybe_unused]] FixedVectorType *ParamType =
2861 [[maybe_unused]] FixedVectorType *
ReturnType =
2869 Value *FirstArgShadow = getShadow(&
I, 0);
2870 Value *SecondArgShadow =
nullptr;
2871 if (
I.arg_size() == 2)
2872 SecondArgShadow = getShadow(&
I, 1);
2874 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2875 FirstArgShadow, SecondArgShadow);
2877 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2879 setShadow(&
I, OrShadow);
2880 setOriginForNaryOp(
I);
2890 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards,
2891 int ReinterpretElemWidth) {
2892 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2894 assert(
I.getType()->isVectorTy());
2895 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2897 FixedVectorType *ParamType =
2902 [[maybe_unused]] FixedVectorType *
ReturnType =
2909 FixedVectorType *ReinterpretShadowTy =
nullptr;
2917 Value *FirstArgShadow = getShadow(&
I, 0);
2918 FirstArgShadow = IRB.
CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
2928 Value *SecondArgShadow =
nullptr;
2929 if (
I.arg_size() == 2) {
2930 SecondArgShadow = getShadow(&
I, 1);
2931 SecondArgShadow = IRB.
CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
2934 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2935 FirstArgShadow, SecondArgShadow);
2937 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2939 setShadow(&
I, OrShadow);
2940 setOriginForNaryOp(
I);
2943 void visitFNeg(UnaryOperator &
I) { handleShadowOr(
I); }
2954 void handleMulByConstant(BinaryOperator &
I, Constant *ConstArg,
2960 Type *EltTy = VTy->getElementType();
2962 for (
unsigned Idx = 0;
Idx < NumElements; ++
Idx) {
2963 if (ConstantInt *Elt =
2965 const APInt &
V = Elt->getValue();
2966 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
2967 Elements.push_back(ConstantInt::get(EltTy, V2));
2969 Elements.push_back(ConstantInt::get(EltTy, 1));
2975 const APInt &
V = Elt->getValue();
2977 ShadowMul = ConstantInt::get(Ty, V2);
2979 ShadowMul = ConstantInt::get(Ty, 1);
2985 IRB.
CreateMul(getShadow(OtherArg), ShadowMul,
"msprop_mul_cst"));
2986 setOrigin(&
I, getOrigin(OtherArg));
2989 void visitMul(BinaryOperator &
I) {
2992 if (constOp0 && !constOp1)
2993 handleMulByConstant(
I, constOp0,
I.getOperand(1));
2994 else if (constOp1 && !constOp0)
2995 handleMulByConstant(
I, constOp1,
I.getOperand(0));
3000 void visitFAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3001 void visitFSub(BinaryOperator &
I) { handleShadowOr(
I); }
3002 void visitFMul(BinaryOperator &
I) { handleShadowOr(
I); }
3003 void visitAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3004 void visitSub(BinaryOperator &
I) { handleShadowOr(
I); }
3005 void visitXor(BinaryOperator &
I) { handleShadowOr(
I); }
3007 void handleIntegerDiv(Instruction &
I) {
3010 insertCheckShadowOf(
I.getOperand(1), &
I);
3011 setShadow(&
I, getShadow(&
I, 0));
3012 setOrigin(&
I, getOrigin(&
I, 0));
3015 void visitUDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3016 void visitSDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3017 void visitURem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3018 void visitSRem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3022 void visitFDiv(BinaryOperator &
I) { handleShadowOr(
I); }
3023 void visitFRem(BinaryOperator &
I) { handleShadowOr(
I); }
3029 void handleEqualityComparison(ICmpInst &
I) {
3033 Value *Sa = getShadow(
A);
3034 Value *Sb = getShadow(
B);
3036 Value *Si = propagateEqualityComparison(IRB,
A,
B, Sa, Sb);
3039 setOriginForNaryOp(
I);
3047 void handleRelationalComparisonExact(ICmpInst &
I) {
3051 Value *Sa = getShadow(
A);
3052 Value *Sb = getShadow(
B);
3063 bool IsSigned =
I.isSigned();
3065 auto GetMinMaxUnsigned = [&](
Value *
V,
Value *S) {
3075 V = IRB.
CreateXor(
V, ConstantInt::get(
V->getType(), MinVal));
3080 return std::make_pair(Min, Max);
3083 auto [Amin, Amax] = GetMinMaxUnsigned(
A, Sa);
3084 auto [Bmin, Bmax] = GetMinMaxUnsigned(
B, Sb);
3090 setOriginForNaryOp(
I);
3097 void handleSignedRelationalComparison(ICmpInst &
I) {
3102 op =
I.getOperand(0);
3103 pre =
I.getPredicate();
3105 op =
I.getOperand(1);
3106 pre =
I.getSwappedPredicate();
3119 setShadow(&
I, Shadow);
3120 setOrigin(&
I, getOrigin(
op));
3126 void visitICmpInst(ICmpInst &
I) {
3127 if (!Opts.msan_handle_icmp) {
3131 if (
I.isEquality()) {
3132 handleEqualityComparison(
I);
3137 if (Opts.msan_handle_icmp_exact) {
3138 handleRelationalComparisonExact(
I);
3142 handleSignedRelationalComparison(
I);
3148 handleRelationalComparisonExact(
I);
3155 void visitFCmpInst(FCmpInst &
I) { handleShadowOr(
I); }
3157 void handleShift(BinaryOperator &
I) {
3162 Value *S2 = getShadow(&
I, 1);
3165 Value *V2 =
I.getOperand(1);
3167 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3168 setOriginForNaryOp(
I);
3171 void visitShl(BinaryOperator &
I) { handleShift(
I); }
3172 void visitAShr(BinaryOperator &
I) { handleShift(
I); }
3173 void visitLShr(BinaryOperator &
I) { handleShift(
I); }
3175 void handleFunnelShift(IntrinsicInst &
I) {
3179 Value *S0 = getShadow(&
I, 0);
3181 Value *S2 = getShadow(&
I, 2);
3184 Value *V2 =
I.getOperand(2);
3187 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3188 setOriginForNaryOp(
I);
3196 void handleGenericBitManipulation(IntrinsicInst &
I) {
3198 Type *ShadowTy = getShadowTy(&
I);
3201 Value *SMask = getShadow(&
I, 1);
3206 if (
Function *Func =
I.getCalledFunction())
3207 S = IRB.
CreateCall(Func, {getShadow(&
I, 0),
I.getOperand(1)});
3210 {getShadow(&I, 0), I.getOperand(1)});
3213 setOriginForNaryOp(
I);
3226 void visitMemMoveInst(MemMoveInst &
I) {
3227 getShadow(
I.getArgOperand(1));
3230 {I.getArgOperand(0), I.getArgOperand(1),
3231 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3249 void visitMemCpyInst(MemCpyInst &
I) {
3250 getShadow(
I.getArgOperand(1));
3253 {I.getArgOperand(0), I.getArgOperand(1),
3254 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3259 void visitMemSetInst(MemSetInst &
I) {
3263 {I.getArgOperand(0),
3264 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3265 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3269 void visitVAStartInst(VAStartInst &
I) { VAHelper->visitVAStartInst(
I); }
3271 void visitVACopyInst(VACopyInst &
I) { VAHelper->visitVACopyInst(
I); }
3277 bool handleVectorStoreIntrinsic(IntrinsicInst &
I) {
3281 Value *Addr =
I.getArgOperand(0);
3282 Value *Shadow = getShadow(&
I, 1);
3283 Value *ShadowPtr, *OriginPtr;
3287 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3291 if (Opts.msan_check_access_address)
3292 insertCheckShadowOf(Addr, &
I);
3295 if (MS.TrackOrigins)
3304 bool handleVectorLoadIntrinsic(IntrinsicInst &
I) {
3308 Value *Addr =
I.getArgOperand(0);
3310 Type *ShadowTy = getShadowTy(&
I);
3311 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
3312 if (PropagateShadow) {
3316 std::tie(ShadowPtr, OriginPtr) =
3317 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
3321 setShadow(&
I, getCleanShadow(&
I));
3324 if (Opts.msan_check_access_address)
3325 insertCheckShadowOf(Addr, &
I);
3327 if (MS.TrackOrigins) {
3328 if (PropagateShadow)
3329 setOrigin(&
I, IRB.
CreateLoad(MS.OriginTy, OriginPtr));
3331 setOrigin(&
I, getCleanOrigin());
3351 [[maybe_unused]]
bool
3352 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &
I,
3353 unsigned int trailingFlags) {
3354 Type *RetTy =
I.getType();
3358 unsigned NumArgOperands =
I.arg_size();
3359 assert(NumArgOperands >= trailingFlags);
3360 for (
unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3361 Type *Ty =
I.getArgOperand(i)->getType();
3367 ShadowAndOriginCombiner SC(
this, IRB);
3368 for (
unsigned i = 0; i < NumArgOperands; ++i)
3369 SC.Add(
I.getArgOperand(i));
3386 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &
I) {
3387 unsigned NumArgOperands =
I.arg_size();
3388 if (NumArgOperands == 0)
3391 if (NumArgOperands == 2 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3392 I.getArgOperand(1)->getType()->isVectorTy() &&
3393 I.getType()->isVoidTy() && !
I.onlyReadsMemory()) {
3395 return handleVectorStoreIntrinsic(
I);
3398 if (NumArgOperands == 1 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3399 I.getType()->isVectorTy() &&
I.onlyReadsMemory()) {
3401 return handleVectorLoadIntrinsic(
I);
3404 if (
I.doesNotAccessMemory())
3405 if (maybeHandleSimpleNomemIntrinsic(
I, 0))
3413 bool maybeHandleUnknownIntrinsic(IntrinsicInst &
I) {
3414 if (maybeHandleUnknownIntrinsicUnlogged(
I)) {
3415 if (Opts.msan_dump_heuristic_instructions)
3416 dumpInst(
I,
"Heuristic");
3418 LLVM_DEBUG(
dbgs() <<
"UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " <<
I
3425 void handleInvariantGroup(IntrinsicInst &
I) {
3426 setShadow(&
I, getShadow(&
I, 0));
3427 setOrigin(&
I, getOrigin(&
I, 0));
3430 void handleLifetimeStart(IntrinsicInst &
I) {
3435 LifetimeStartList.push_back(std::make_pair(&
I, AI));
3438 void handleBswap(IntrinsicInst &
I) {
3441 Type *OpType =
Op->getType();
3444 setOrigin(&
I, getOrigin(
Op));
3465 void handleCountLeadingTrailingZeros(IntrinsicInst &
I) {
3467 Value *Src =
I.getArgOperand(0);
3468 Value *SrcShadow = getShadow(Src);
3472 I.getType(),
I.getIntrinsicID(), {Src, False});
3474 I.getType(),
I.getIntrinsicID(), {SrcShadow, False});
3477 ConcreteZerosCount, ShadowZerosCount,
"_mscz_cmp_zeros");
3479 Value *NotAllZeroShadow =
3481 Value *OutputShadow =
3482 IRB.
CreateAnd(CompareConcreteZeros, NotAllZeroShadow,
"_mscz_main");
3488 OutputShadow = IRB.
CreateOr(OutputShadow, BoolZeroPoison,
"_mscz_bs");
3491 OutputShadow = IRB.
CreateSExt(OutputShadow, getShadowTy(Src),
"_mscz_os");
3493 setShadow(&
I, OutputShadow);
3494 setOriginForNaryOp(
I);
3503 FixedVectorType *maybeShrinkVectorShadowType(
Value *Src, IntrinsicInst &
I) {
3523 Value *maybeExtendVectorShadowWithZeros(
Value *Shadow, IntrinsicInst &
I) {
3528 Value *FullShadow = getCleanShadow(&
I);
3529 unsigned ShadowNumElems =
3531 unsigned FullShadowNumElems =
3534 assert((ShadowNumElems == FullShadowNumElems) ||
3535 (ShadowNumElems * 2 == FullShadowNumElems));
3537 if (ShadowNumElems == FullShadowNumElems) {
3538 FullShadow = Shadow;
3542 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3567 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &
I,
3568 bool HasRoundingMode) {
3569 if (HasRoundingMode) {
3577 Value *Src =
I.getArgOperand(0);
3578 assert(Src->getType()->isVectorTy());
3582 VectorType *ShadowType = maybeShrinkVectorShadowType(Src,
I);
3585 Value *S0 = getShadow(&
I, 0);
3597 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow,
I);
3599 setShadow(&
I, FullShadow);
3600 setOriginForNaryOp(
I);
3621 void handleSSEVectorConvertIntrinsic(IntrinsicInst &
I,
int NumUsedElements,
3622 bool HasRoundingMode =
false) {
3624 Value *CopyOp, *ConvertOp;
3626 assert((!HasRoundingMode ||
3628 "Invalid rounding mode");
3630 switch (
I.arg_size() - HasRoundingMode) {
3632 CopyOp =
I.getArgOperand(0);
3633 ConvertOp =
I.getArgOperand(1);
3636 ConvertOp =
I.getArgOperand(0);
3650 Value *ConvertShadow = getShadow(ConvertOp);
3651 Value *AggShadow =
nullptr;
3654 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
3655 for (
int i = 1; i < NumUsedElements; ++i) {
3657 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
3658 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
3661 AggShadow = ConvertShadow;
3664 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &
I);
3671 Value *ResultShadow = getShadow(CopyOp);
3673 for (
int i = 0; i < NumUsedElements; ++i) {
3675 ResultShadow, ConstantInt::getNullValue(EltTy),
3678 setShadow(&
I, ResultShadow);
3679 setOrigin(&
I, getOrigin(CopyOp));
3681 setShadow(&
I, getCleanShadow(&
I));
3682 setOrigin(&
I, getCleanOrigin());
3690 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
3693 return CreateShadowCast(IRB, S2,
T,
true);
3701 return CreateShadowCast(IRB, S2,
T,
true);
3718 void handleVectorShiftIntrinsic(IntrinsicInst &
I,
bool Variable) {
3724 Value *S2 = getShadow(&
I, 1);
3726 : Lower64ShadowExtend(IRB, S2, getShadowTy(&
I));
3728 Value *V2 =
I.getOperand(1);
3730 {IRB.CreateBitCast(S1, V1->getType()), V2});
3732 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3733 setOriginForNaryOp(
I);
3738 Type *getMMXVectorTy(
unsigned EltSizeInBits,
3739 unsigned X86_MMXSizeInBits = 64) {
3740 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3741 "Illegal MMX vector element size");
3743 X86_MMXSizeInBits / EltSizeInBits);
3750 case Intrinsic::x86_sse2_packsswb_128:
3751 case Intrinsic::x86_sse2_packuswb_128:
3752 return Intrinsic::x86_sse2_packsswb_128;
3754 case Intrinsic::x86_sse2_packssdw_128:
3755 case Intrinsic::x86_sse41_packusdw:
3756 return Intrinsic::x86_sse2_packssdw_128;
3758 case Intrinsic::x86_avx2_packsswb:
3759 case Intrinsic::x86_avx2_packuswb:
3760 return Intrinsic::x86_avx2_packsswb;
3762 case Intrinsic::x86_avx2_packssdw:
3763 case Intrinsic::x86_avx2_packusdw:
3764 return Intrinsic::x86_avx2_packssdw;
3766 case Intrinsic::x86_mmx_packsswb:
3767 case Intrinsic::x86_mmx_packuswb:
3768 return Intrinsic::x86_mmx_packsswb;
3770 case Intrinsic::x86_mmx_packssdw:
3771 return Intrinsic::x86_mmx_packssdw;
3773 case Intrinsic::x86_avx512_packssdw_512:
3774 case Intrinsic::x86_avx512_packusdw_512:
3775 return Intrinsic::x86_avx512_packssdw_512;
3777 case Intrinsic::x86_avx512_packsswb_512:
3778 case Intrinsic::x86_avx512_packuswb_512:
3779 return Intrinsic::x86_avx512_packsswb_512;
3795 void handleVectorPackIntrinsic(IntrinsicInst &
I,
3796 unsigned MMXEltSizeInBits = 0) {
3800 Value *S2 = getShadow(&
I, 1);
3801 assert(
S1->getType()->isVectorTy());
3807 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) :
S1->
getType();
3808 if (MMXEltSizeInBits) {
3816 if (MMXEltSizeInBits) {
3822 {S1_ext, S2_ext},
nullptr,
3823 "_msprop_vector_pack");
3824 if (MMXEltSizeInBits)
3827 setOriginForNaryOp(
I);
3831 Constant *createDppMask(
unsigned Width,
unsigned Mask) {
3832 SmallVector<Constant *, 4>
R(Width);
3844 const unsigned Width =
3851 Value *DstMaskV = createDppMask(Width, DstMask);
3868 void handleDppIntrinsic(IntrinsicInst &
I) {
3871 Value *S0 = getShadow(&
I, 0);
3875 const unsigned Width =
3877 assert(Width == 2 || Width == 4 || Width == 8);
3880 const unsigned SrcMask =
Mask >> 4;
3881 const unsigned DstMask =
Mask & 0xf;
3884 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3889 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3896 setOriginForNaryOp(
I);
3900 C = CreateAppToShadowCast(IRB,
C);
3909 void handleBlendvIntrinsic(IntrinsicInst &
I) {
3914 Value *Sc = getShadow(&
I, 2);
3915 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
3920 C = convertBlendvToSelectMask(IRB,
C);
3921 Sc = convertBlendvToSelectMask(IRB, Sc);
3927 handleSelectLikeInst(
I,
C,
T,
F);
3931 void handleVectorSadIntrinsic(IntrinsicInst &
I,
bool IsMMX =
false) {
3932 const unsigned SignificantBitsPerResultElement = 16;
3934 unsigned ZeroBitsPerResultElement =
3938 auto *Shadow0 = getShadow(&
I, 0);
3939 auto *Shadow1 = getShadow(&
I, 1);
3944 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
3947 setOriginForNaryOp(
I);
3971 void handleVectorDotProductIntrinsic(IntrinsicInst &
I,
3972 unsigned ReductionFactor,
3974 unsigned EltSizeInBits,
3978 [[maybe_unused]] FixedVectorType *
ReturnType =
3983 Value *Va =
nullptr;
3984 Value *Vb =
nullptr;
3985 Value *Sa =
nullptr;
3986 Value *Sb =
nullptr;
3988 assert(
I.arg_size() == 2 ||
I.arg_size() == 3);
3989 if (
I.arg_size() == 2) {
3992 Va =
I.getOperand(0);
3993 Vb =
I.getOperand(1);
3995 Sa = getShadow(&
I, 0);
3996 Sb = getShadow(&
I, 1);
3997 }
else if (
I.arg_size() == 3) {
3999 Va =
I.getOperand(1);
4000 Vb =
I.getOperand(2);
4002 Sa = getShadow(&
I, 1);
4003 Sb = getShadow(&
I, 2);
4020 Sa, getPclmulMask(Width, Lanes ==
kOddLanes));
4022 Sb, getPclmulMask(Width, Lanes ==
kOddLanes));
4032 if (
I.arg_size() == 3) {
4033 [[maybe_unused]]
auto *AccumulatorType =
4035 assert(AccumulatorType == ReturnType);
4038 FixedVectorType *ImplicitReturnType =
4041 if (EltSizeInBits) {
4043 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4055 ReturnType->getNumElements() * ReductionFactor);
4072 VaInt = CreateAppToShadowCast(IRB, Va);
4073 VbInt = CreateAppToShadowCast(IRB, Vb);
4080 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4102 ImplicitReturnType);
4107 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&
I));
4110 if (
I.arg_size() == 3)
4111 OutShadow = IRB.
CreateOr(OutShadow, getShadow(&
I, 0));
4113 setShadow(&
I, OutShadow);
4114 setOriginForNaryOp(
I);
4131 void handleVectorComparePackedIntrinsic(IntrinsicInst &
I,
4132 bool PredicateAsOperand) {
4133 if (PredicateAsOperand) {
4135 assert(
I.paramHasAttr(2, Attribute::ImmArg));
4143 Type *ResTy = getShadowTy(&
I);
4144 auto *Shadow0 = getShadow(&
I, 0);
4145 auto *Shadow1 = getShadow(&
I, 1);
4150 setOriginForNaryOp(
I);
4156 void handleVectorCompareScalarIntrinsic(IntrinsicInst &
I) {
4158 auto *Shadow0 = getShadow(&
I, 0);
4159 auto *Shadow1 = getShadow(&
I, 1);
4161 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&
I));
4163 setOriginForNaryOp(
I);
4172 void handleVectorReduceIntrinsic(IntrinsicInst &
I,
bool AllowShadowCast) {
4177 if (AllowShadowCast)
4178 S = CreateShadowCast(IRB, S, getShadowTy(&
I));
4182 setOriginForNaryOp(
I);
4192 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &
I) {
4196 Value *Shadow0 = getShadow(&
I, 0);
4202 setOriginForNaryOp(
I);
4222 void handleVectorPartialReduceAddIntrinsic(IntrinsicInst &
I) {
4227 [[maybe_unused]]
Value *Addends =
I.getArgOperand(1);
4241 Value *SAcc = getShadow(&
I, 0);
4242 Value *SAdd = getShadow(&
I, 1);
4262 SAcc->
getType(), Intrinsic::vector_partial_reduce_add, {SAcc, SAdd});
4267 setShadow(&
I, SOutput);
4268 setOriginForNaryOp(
I);
4274 void handleVectorReduceOrIntrinsic(IntrinsicInst &
I) {
4278 Value *OperandShadow = getShadow(&
I, 0);
4280 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
4288 setOrigin(&
I, getOrigin(&
I, 0));
4294 void handleVectorReduceAndIntrinsic(IntrinsicInst &
I) {
4298 Value *OperandShadow = getShadow(&
I, 0);
4299 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
4307 setOrigin(&
I, getOrigin(&
I, 0));
4310 void handleStmxcsr(IntrinsicInst &
I) {
4312 Value *Addr =
I.getArgOperand(0);
4315 getShadowOriginPtr(Addr, IRB, Ty,
Align(1),
true).first;
4319 if (Opts.msan_check_access_address)
4320 insertCheckShadowOf(Addr, &
I);
4323 void handleLdmxcsr(IntrinsicInst &
I) {
4328 Value *Addr =
I.getArgOperand(0);
4331 Value *ShadowPtr, *OriginPtr;
4332 std::tie(ShadowPtr, OriginPtr) =
4333 getShadowOriginPtr(Addr, IRB, Ty, Alignment,
false);
4335 if (Opts.msan_check_access_address)
4336 insertCheckShadowOf(Addr, &
I);
4339 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
4341 insertCheckShadow(Shadow, Origin, &
I);
4344 void handleMaskedExpandLoad(IntrinsicInst &
I) {
4346 Value *Ptr =
I.getArgOperand(0);
4347 MaybeAlign
Align =
I.getParamAlign(0);
4349 Value *PassThru =
I.getArgOperand(2);
4351 if (Opts.msan_check_access_address) {
4352 insertCheckShadowOf(Ptr, &
I);
4353 insertCheckShadowOf(Mask, &
I);
4356 if (!PropagateShadow) {
4357 setShadow(&
I, getCleanShadow(&
I));
4358 setOrigin(&
I, getCleanOrigin());
4362 Type *ShadowTy = getShadowTy(&
I);
4364 auto [ShadowPtr, OriginPtr] =
4365 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
false);
4369 getShadow(PassThru),
"_msmaskedexpload");
4371 setShadow(&
I, Shadow);
4374 setOrigin(&
I, getCleanOrigin());
4377 void handleMaskedCompressStore(IntrinsicInst &
I) {
4380 Value *Ptr =
I.getArgOperand(1);
4381 MaybeAlign
Align =
I.getParamAlign(1);
4384 if (Opts.msan_check_access_address) {
4385 insertCheckShadowOf(Ptr, &
I);
4386 insertCheckShadowOf(Mask, &
I);
4390 Type *ElementShadowTy =
4392 auto [ShadowPtr, OriginPtrs] =
4393 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
true);
4400 void handleMaskedGather(IntrinsicInst &
I) {
4402 Value *Ptrs =
I.getArgOperand(0);
4405 Value *PassThru =
I.getArgOperand(2);
4407 Type *PtrsShadowTy = getShadowTy(Ptrs);
4408 if (Opts.msan_check_access_address) {
4409 insertCheckShadowOf(Mask, &
I);
4413 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4416 if (!PropagateShadow) {
4417 setShadow(&
I, getCleanShadow(&
I));
4418 setOrigin(&
I, getCleanOrigin());
4422 Type *ShadowTy = getShadowTy(&
I);
4424 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4425 Ptrs, IRB, ElementShadowTy, Alignment,
false);
4429 getShadow(PassThru),
"_msmaskedgather");
4431 setShadow(&
I, Shadow);
4434 setOrigin(&
I, getCleanOrigin());
4437 void handleMaskedScatter(IntrinsicInst &
I) {
4440 Value *Ptrs =
I.getArgOperand(1);
4444 Type *PtrsShadowTy = getShadowTy(Ptrs);
4445 if (Opts.msan_check_access_address) {
4446 insertCheckShadowOf(Mask, &
I);
4450 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4454 Type *ElementShadowTy =
4456 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4457 Ptrs, IRB, ElementShadowTy, Alignment,
true);
4468 void handleMaskedStore(IntrinsicInst &
I) {
4470 Value *
V =
I.getArgOperand(0);
4471 Value *Ptr =
I.getArgOperand(1);
4474 Value *Shadow = getShadow(
V);
4476 if (Opts.msan_check_access_address) {
4477 insertCheckShadowOf(Ptr, &
I);
4478 insertCheckShadowOf(Mask, &
I);
4483 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4484 Ptr, IRB, Shadow->
getType(), Alignment,
true);
4488 if (!MS.TrackOrigins)
4491 auto &
DL =
F.getDataLayout();
4492 paintOrigin(IRB, getOrigin(
V), OriginPtr,
4501 void handleMaskedLoad(IntrinsicInst &
I) {
4503 Value *Ptr =
I.getArgOperand(0);
4506 Value *PassThru =
I.getArgOperand(2);
4508 if (Opts.msan_check_access_address) {
4509 insertCheckShadowOf(Ptr, &
I);
4510 insertCheckShadowOf(Mask, &
I);
4513 if (!PropagateShadow) {
4514 setShadow(&
I, getCleanShadow(&
I));
4515 setOrigin(&
I, getCleanOrigin());
4519 Type *ShadowTy = getShadowTy(&
I);
4520 Value *ShadowPtr, *OriginPtr;
4521 std::tie(ShadowPtr, OriginPtr) =
4522 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment,
false);
4524 getShadow(PassThru),
"_msmaskedld"));
4526 if (!MS.TrackOrigins)
4533 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
4538 setOrigin(&
I, Origin);
4548 void handleMaskedIntegerDivRem(IntrinsicInst &
I) {
4551 Value *Dividend =
I.getArgOperand(0);
4552 Value *Divisor =
I.getArgOperand(1);
4555 insertCheckShadowOf(Mask, &
I);
4558 Mask, getShadow(Divisor), getCleanShadow(Divisor),
"_msmaskeddivisor");
4559 insertCheckShadow(MaskedDivisorShadow, getOrigin(Divisor), &
I);
4561 if (!PropagateShadow) {
4562 setShadow(&
I, getCleanShadow(&
I));
4563 setOrigin(&
I, getCleanOrigin());
4568 getPoisonedShadow(&
I),
"_msmaskeddiv"));
4569 setOrigin(&
I, getOrigin(Dividend));
4574 void handleVectorExtractLastActive(IntrinsicInst &
I) {
4579 Value *PassThru =
I.getArgOperand(2);
4592 insertCheckShadowOf(Mask, &
I);
4594 if (!PropagateShadow) {
4595 setShadow(&
I, getCleanShadow(&
I));
4596 setOrigin(&
I, getCleanOrigin());
4602 Intrinsic::experimental_vector_extract_last_active,
4603 {DataShadow->
getType()}, {DataShadow,
Mask, getShadow(PassThru)},
4604 {},
"_msprop_vector_extract_last_active");
4605 setShadow(&
I, Shadow);
4607 if (MS.TrackOrigins) {
4610 getOrigin(PassThru)));
4627 void handleAVXMaskedStore(IntrinsicInst &
I) {
4632 Value *Dst =
I.getArgOperand(0);
4633 assert(Dst->getType()->isPointerTy() &&
"Destination is not a pointer!");
4638 Value *Src =
I.getArgOperand(2);
4643 Value *SrcShadow = getShadow(Src);
4645 if (Opts.msan_check_access_address) {
4646 insertCheckShadowOf(Dst, &
I);
4647 insertCheckShadowOf(Mask, &
I);
4650 Value *DstShadowPtr;
4651 Value *DstOriginPtr;
4652 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4653 Dst, IRB, SrcShadow->
getType(), Alignment,
true);
4655 SmallVector<Value *, 2> ShadowArgs;
4656 ShadowArgs.
append(1, DstShadowPtr);
4657 ShadowArgs.
append(1, Mask);
4665 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
4668 if (!MS.TrackOrigins)
4672 auto &
DL =
F.getDataLayout();
4673 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4674 DL.getTypeStoreSize(SrcShadow->
getType()),
4693 void handleAVXMaskedLoad(IntrinsicInst &
I) {
4698 Value *Src =
I.getArgOperand(0);
4699 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
4706 if (Opts.msan_check_access_address) {
4707 insertCheckShadowOf(Mask, &
I);
4710 Type *SrcShadowTy = getShadowTy(Src);
4711 Value *SrcShadowPtr, *SrcOriginPtr;
4712 std::tie(SrcShadowPtr, SrcOriginPtr) =
4713 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment,
false);
4715 SmallVector<Value *, 2> ShadowArgs;
4716 ShadowArgs.
append(1, SrcShadowPtr);
4717 ShadowArgs.
append(1, Mask);
4720 I.getType(),
I.getIntrinsicID(), ShadowArgs);
4726 if (!MS.TrackOrigins)
4733 setOrigin(&
I, PtrSrcOrigin);
4742 assert(isFixedIntVector(Idx));
4743 auto IdxVectorSize =
4751 auto *IdxShadow = getShadow(Idx);
4756 insertCheckShadow(Truncated, getOrigin(Idx),
I);
4761 void handleAVXVpermilvar(IntrinsicInst &
I) {
4763 Value *Shadow = getShadow(&
I, 0);
4764 maskedCheckAVXIndexShadow(IRB,
I.getArgOperand(1), &
I);
4768 Shadow = IRB.
CreateBitCast(Shadow,
I.getArgOperand(0)->getType());
4770 I.getType(),
I.getIntrinsicID(), {Shadow, I.getArgOperand(1)});
4773 setOriginForNaryOp(
I);
4778 void handleAVXVpermi2var(IntrinsicInst &
I) {
4783 [[maybe_unused]]
auto ArgVectorSize =
4786 ->getNumElements() == ArgVectorSize);
4788 ->getNumElements() == ArgVectorSize);
4789 assert(
I.getArgOperand(0)->getType() ==
I.getArgOperand(2)->getType());
4790 assert(
I.getType() ==
I.getArgOperand(0)->getType());
4791 assert(
I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4793 Value *AShadow = getShadow(&
I, 0);
4795 Value *BShadow = getShadow(&
I, 2);
4797 maskedCheckAVXIndexShadow(IRB, Idx, &
I);
4801 AShadow = IRB.
CreateBitCast(AShadow,
I.getArgOperand(0)->getType());
4802 BShadow = IRB.
CreateBitCast(BShadow,
I.getArgOperand(2)->getType());
4804 I.getType(),
I.getIntrinsicID(), {AShadow, Idx, BShadow});
4806 setOriginForNaryOp(
I);
4809 [[maybe_unused]]
static bool isFixedIntVectorTy(
const Type *
T) {
4813 [[maybe_unused]]
static bool isFixedFPVectorTy(
const Type *
T) {
4817 [[maybe_unused]]
static bool isFixedIntVector(
const Value *
V) {
4818 return isFixedIntVectorTy(
V->getType());
4821 [[maybe_unused]]
static bool isFixedFPVector(
const Value *
V) {
4822 return isFixedFPVectorTy(
V->getType());
4844 void handleAVX512VectorConvertFPToInt(IntrinsicInst &
I,
bool LastMask) {
4849 Value *WriteThrough;
4853 WriteThrough =
I.getOperand(2);
4854 Mask =
I.getOperand(3);
4857 WriteThrough =
I.getOperand(1);
4858 Mask =
I.getOperand(2);
4863 assert(isFixedIntVector(WriteThrough));
4865 unsigned ANumElements =
4867 [[maybe_unused]]
unsigned WriteThruNumElements =
4869 assert(ANumElements == WriteThruNumElements ||
4870 ANumElements * 2 == WriteThruNumElements);
4873 unsigned MaskNumElements =
Mask->getType()->getScalarSizeInBits();
4874 assert(ANumElements == MaskNumElements ||
4875 ANumElements * 2 == MaskNumElements);
4877 assert(WriteThruNumElements == MaskNumElements);
4881 insertCheckShadowOf(Mask, &
I);
4891 Value *AShadow = getShadow(
A);
4892 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
4894 if (ANumElements * 2 == MaskNumElements) {
4906 "_ms_mask_bitcast");
4916 getShadowTy(&
I),
"_ms_a_shadow");
4918 Value *WriteThroughShadow = getShadow(WriteThrough);
4920 "_ms_writethru_select");
4922 setShadow(&
I, Shadow);
4923 setOriginForNaryOp(
I);
4926 static SmallVector<int, 8> getPclmulMask(
unsigned Width,
bool OddElements) {
4927 SmallVector<int, 8>
Mask;
4928 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
4942 void handlePclmulIntrinsic(IntrinsicInst &
I) {
4947 "pclmul 3rd operand must be a constant");
4950 getPclmulMask(Width,
Imm & 0x01));
4952 getPclmulMask(Width,
Imm & 0x10));
4953 ShadowAndOriginCombiner SOC(
this, IRB);
4954 SOC.Add(Shuf0, getOrigin(&
I, 0));
4955 SOC.Add(Shuf1, getOrigin(&
I, 1));
4960 void handleUnarySdSsIntrinsic(IntrinsicInst &
I) {
4965 Value *Second = getShadow(&
I, 1);
4967 SmallVector<int, 16>
Mask;
4968 Mask.push_back(Width);
4969 for (
unsigned i = 1; i < Width; i++)
4973 setShadow(&
I, Shadow);
4974 setOriginForNaryOp(
I);
4977 void handleVtestIntrinsic(IntrinsicInst &
I) {
4979 Value *Shadow0 = getShadow(&
I, 0);
4980 Value *Shadow1 = getShadow(&
I, 1);
4986 setShadow(&
I, Shadow);
4987 setOriginForNaryOp(
I);
4990 void handleBinarySdSsIntrinsic(IntrinsicInst &
I) {
4995 Value *Second = getShadow(&
I, 1);
4998 SmallVector<int, 16>
Mask;
4999 Mask.push_back(Width);
5000 for (
unsigned i = 1; i < Width; i++)
5004 setShadow(&
I, Shadow);
5005 setOriginForNaryOp(
I);
5011 void handleRoundPdPsIntrinsic(IntrinsicInst &
I) {
5012 assert(
I.getArgOperand(0)->getType() ==
I.getType());
5017 ShadowAndOriginCombiner SC(
this, IRB);
5018 SC.Add(
I.getArgOperand(0));
5026 void handleAbsIntrinsic(IntrinsicInst &
I) {
5028 Value *Src =
I.getArgOperand(0);
5029 Value *IsIntMinPoison =
I.getArgOperand(1);
5031 assert(
I.getType()->isIntOrIntVectorTy());
5033 assert(Src->getType() ==
I.getType());
5039 Value *SrcShadow = getShadow(Src);
5043 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5046 Value *PoisonedShadow = getPoisonedShadow(Src);
5047 Value *PoisonedIfIntMinShadow =
5050 IRB.
CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5052 setShadow(&
I, Shadow);
5053 setOrigin(&
I, getOrigin(&
I, 0));
5056 void handleIsFpClass(IntrinsicInst &
I) {
5058 Value *Shadow = getShadow(&
I, 0);
5059 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5060 setOrigin(&
I, getOrigin(&
I, 0));
5063 void handleArithmeticWithOverflow(IntrinsicInst &
I) {
5065 Value *Shadow0 = getShadow(&
I, 0);
5066 Value *Shadow1 = getShadow(&
I, 1);
5069 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5075 setShadow(&
I, Shadow);
5076 setOriginForNaryOp(
I);
5079 void handleModfOrSincos(IntrinsicInst &
I) {
5081 Value *ArgShadow = getShadow(&
I, 0);
5085 setShadow(&
I, Shadow);
5086 setOrigin(&
I, getOrigin(&
I, 0));
5092 Value *Shadow = getShadow(
V);
5114 void handleAVX512VectorDownConvert(IntrinsicInst &
I) {
5119 Value *WriteThrough =
I.getOperand(1);
5123 assert(isFixedIntVector(WriteThrough));
5125 unsigned ANumElements =
5127 unsigned OutputNumElements =
5129 assert(ANumElements == OutputNumElements ||
5130 ANumElements * 2 == OutputNumElements);
5140 insertCheckShadowOf(Mask, &
I);
5143 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5144 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5145 assert(
Mask->getType()->getScalarSizeInBits() == ANumElements);
5156 if (ANumElements != OutputNumElements) {
5158 Mask = IRB.
CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5165 Value *AShadow = getShadow(
A);
5169 VectorType *ShadowType = maybeShrinkVectorShadowType(
A,
I);
5179 AShadow = IRB.
CreateTrunc(AShadow, ShadowType,
"_ms_trunc_shadow");
5180 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
5182 Value *WriteThroughShadow = getShadow(WriteThrough);
5185 setShadow(&
I, Shadow);
5186 setOriginForNaryOp(
I);
5220 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &
I,
5221 SmallVector<unsigned, 4> DataIndices,
5222 unsigned WriteThruIndex,
5223 unsigned MaskIndex) {
5226 unsigned NumArgs =
I.arg_size();
5228 assert(WriteThruIndex < NumArgs);
5229 assert(MaskIndex < NumArgs);
5230 assert(WriteThruIndex != MaskIndex);
5231 Value *WriteThru =
I.getOperand(WriteThruIndex);
5233 unsigned OutputNumElements =
5238 bool isData[16] = {
false};
5240 for (
unsigned i : DataIndices) {
5242 assert(i != WriteThruIndex);
5249 [[maybe_unused]]
unsigned ANumElements =
5251 assert(ANumElements == OutputNumElements);
5256 assert(isFixedFPVector(WriteThru));
5258 for (
unsigned i = 0; i < NumArgs; ++i) {
5259 if (!isData[i] && i != WriteThruIndex) {
5262 assert(
I.getOperand(i)->getType()->isIntegerTy());
5263 insertCheckShadowOf(
I.getOperand(i), &
I);
5268 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5269 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5270 assert(
Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5277 Value *DataShadow =
nullptr;
5278 for (
unsigned i : DataIndices) {
5281 DataShadow = IRB.
CreateOr(DataShadow, getShadow(
A));
5283 DataShadow = getShadow(
A);
5291 Value *WriteThruShadow = getShadow(WriteThru);
5294 setShadow(&
I, Shadow);
5296 setOriginForNaryOp(
I);
5306 void handleAVX512FPClass(IntrinsicInst &
I) {
5312 assert(isFixedFPVector(Input));
5315 Value *Classifiers =
I.getOperand(1);
5319 assert(isFixedIntVectorTy(
I.getType()));
5325 Value *OutputShadow;
5330 OutputShadow = getCleanShadow(OutputType);
5336 OutputShadow = IRB.
CreateICmpNE(getShadow(Input), getCleanShadow(Input));
5338 setShadow(&
I, OutputShadow);
5340 setOriginForNaryOp(
I);
5350 void visitGenericScalarHalfwordInst(IntrinsicInst &
I) {
5356 Value *WriteThrough =
I.getOperand(2);
5363 insertCheckShadowOf(Mask, &
I);
5367 unsigned NumElements =
5369 assert(NumElements == 8);
5370 assert(
A->getType() ==
B->getType());
5372 assert(
Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5375 Value *ALowerShadow = extractLowerShadow(IRB,
A);
5376 Value *BLowerShadow = extractLowerShadow(IRB,
B);
5378 Value *ABLowerShadow = IRB.
CreateOr(ALowerShadow, BLowerShadow);
5380 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5387 Value *AShadow = getShadow(
A);
5388 Value *DstLowerShadow =
5389 IRB.
CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5391 AShadow, DstLowerShadow, ConstantInt::get(IRB.
getInt32Ty(), 0),
5394 setShadow(&
I, DstShadow);
5395 setOriginForNaryOp(
I);
5425 void handleAVXGF2P8Affine(IntrinsicInst &
I) {
5436 ->getScalarSizeInBits() == 8);
5438 assert(
A->getType() ==
X->getType());
5440 assert(
B->getType()->isIntegerTy());
5441 assert(
B->getType()->getScalarSizeInBits() == 8);
5443 assert(
I.getType() ==
A->getType());
5445 Value *AShadow = getShadow(
A);
5446 Value *XShadow = getShadow(
X);
5447 Value *BZeroShadow = getCleanShadow(
B);
5450 I.getType(),
I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5452 {X, AShadow, BZeroShadow});
5454 {XShadow, A, BZeroShadow});
5457 Value *BShadow = getShadow(
B);
5458 Value *BBroadcastShadow = getCleanShadow(AShadow);
5463 for (
unsigned i = 0; i < NumElements; i++)
5467 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5468 setOriginForNaryOp(
I);
5482 void handleNEONVectorLoad(IntrinsicInst &
I,
bool WithLane) {
5483 unsigned int numArgs =
I.arg_size();
5486 assert(
I.getType()->isStructTy());
5496 assert(4 <= numArgs && numArgs <= 6);
5510 for (
unsigned int i = 0; i < numArgs - 2; i++)
5511 ShadowArgs.
push_back(getShadow(
I.getArgOperand(i)));
5514 Value *LaneNumber =
I.getArgOperand(numArgs - 2);
5518 insertCheckShadowOf(LaneNumber, &
I);
5521 Value *Src =
I.getArgOperand(numArgs - 1);
5522 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
5524 Type *SrcShadowTy = getShadowTy(Src);
5525 auto [SrcShadowPtr, SrcOriginPtr] =
5526 getShadowOriginPtr(Src, IRB, SrcShadowTy,
Align(1),
false);
5533 getShadowTy(&
I),
I.getIntrinsicID(), ShadowArgs);
5536 if (!MS.TrackOrigins)
5540 setOrigin(&
I, PtrSrcOrigin);
5557 void handleNEONVectorStoreIntrinsic(IntrinsicInst &
I,
bool useLane) {
5561 int numArgOperands =
I.arg_size();
5564 assert(numArgOperands >= 1);
5565 Value *Addr =
I.getArgOperand(numArgOperands - 1);
5567 int skipTrailingOperands = 1;
5569 if (Opts.msan_check_access_address)
5570 insertCheckShadowOf(Addr, &
I);
5574 skipTrailingOperands++;
5575 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
5577 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5580 SmallVector<Value *, 8> ShadowArgs;
5582 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5584 Value *Shadow = getShadow(&
I, i);
5585 ShadowArgs.
append(1, Shadow);
5602 (numArgOperands - skipTrailingOperands));
5603 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5607 I.getArgOperand(numArgOperands - skipTrailingOperands));
5609 Value *OutputShadowPtr, *OutputOriginPtr;
5611 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5612 Addr, IRB, OutputShadowTy,
Align(1),
true);
5613 ShadowArgs.
append(1, OutputShadowPtr);
5616 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
5619 if (MS.TrackOrigins) {
5627 OriginCombiner OC(
this, IRB);
5628 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5629 OC.Add(
I.getArgOperand(i));
5631 const DataLayout &
DL =
F.getDataLayout();
5632 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
5665 void handleNEONMatrixMultiply(IntrinsicInst &
I) {
5669 Value *
R =
I.getArgOperand(0);
5670 Value *
A =
I.getArgOperand(1);
5671 Value *
B =
I.getArgOperand(2);
5673 assert(
I.getType() ==
R->getType());
5698 Value *ShadowR = getShadow(&
I, 0);
5699 Value *ShadowA = getShadow(&
I, 1);
5700 Value *ShadowB = getShadow(&
I, 2);
5718 {getCleanShadow(RTy), ShadowA, ShadowB});
5744 {RZeros, ShadowA, ShadowB});
5758 ShadowR = IRB.
CreateICmpNE(ShadowR, getCleanShadow(RTy));
5759 ShadowR = IRB.
CreateOr(ShadowAB, ShadowR);
5761 setShadow(&
I, IRB.
CreateSExt(ShadowR, getShadowTy(RTy)));
5763 setOriginForNaryOp(
I);
5805 void handleIntrinsicByApplyingToShadow(IntrinsicInst &
I,
5807 ArrayRef<int> verbatimArgIndices,
5808 bool forceIntegerIntrinsic) {
5811 assert(verbatimArgIndices.
size() <=
I.arg_size());
5815 SmallVector<bool, 4> verbatimArgLookup(
I.arg_size(),
false);
5817 for (
int index : verbatimArgIndices) {
5819 index +=
I.arg_size();
5820 assert(index >= 0 &&
static_cast<unsigned int>(index) <
I.arg_size());
5821 verbatimArgLookup[index] =
true;
5824 SmallVector<Value *, 8> ShadowArgs;
5826 for (
unsigned int i = 0; i <
I.arg_size(); i++) {
5827 if (verbatimArgLookup[i]) {
5828 Value *Arg =
I.getArgOperand(i);
5830 if (forceIntegerIntrinsic)
5835 Value *Shadow = getShadow(&
I, i);
5837 if (forceIntegerIntrinsic)
5845 Value *CombinedShadow;
5846 if (forceIntegerIntrinsic) {
5859 for (
unsigned int i = 0; i <
I.arg_size(); i++) {
5860 if (!verbatimArgLookup[i])
5864 CreateShadowCast(IRB, getShadow(&
I, i), CombinedShadow->
getType());
5865 CombinedShadow = IRB.
CreateOr(Shadow, CombinedShadow,
"_msprop");
5868 setShadow(&
I, CombinedShadow);
5870 setOriginForNaryOp(
I);
5876 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &
I) {
5914 void handleNEONDotProductLaneIntrinsic(IntrinsicInst &
I,
5915 unsigned ReductionFactor) {
5919 [[maybe_unused]]
Value *VAcc =
I.getOperand(0);
5920 [[maybe_unused]]
Value *Va =
I.getOperand(1);
5921 [[maybe_unused]]
Value *Vb =
I.getOperand(2);
5922 Value *Lane =
I.getOperand(3);
5929 I.getType()->getPrimitiveSizeInBits());
5938 I.getType()->getPrimitiveSizeInBits());
5944 Value *SAcc = getShadow(&
I, 0);
5945 Value *Sa = getShadow(&
I, 1);
5946 Value *Sb = getShadow(&
I, 2);
5953 Sb, FixedVectorType::getWithSizeAndScalar(
5969 SOutput = IRB.
CreateSelect(SbClean, SOutput, getPoisonedShadow(SOutput));
5971 setShadow(&
I, SOutput);
5972 setOriginForNaryOp(
I);
5975 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &
I) {
5976 switch (
I.getIntrinsicID()) {
5977 case Intrinsic::uadd_with_overflow:
5978 case Intrinsic::sadd_with_overflow:
5979 case Intrinsic::usub_with_overflow:
5980 case Intrinsic::ssub_with_overflow:
5981 case Intrinsic::umul_with_overflow:
5982 case Intrinsic::smul_with_overflow:
5983 handleArithmeticWithOverflow(
I);
5985 case Intrinsic::modf:
5986 case Intrinsic::sincos:
5987 case Intrinsic::sincospi:
5988 handleModfOrSincos(
I);
5990 case Intrinsic::abs:
5991 handleAbsIntrinsic(
I);
5993 case Intrinsic::bitreverse:
5994 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
5998 case Intrinsic::is_fpclass:
6001 case Intrinsic::lifetime_start:
6002 handleLifetimeStart(
I);
6004 case Intrinsic::launder_invariant_group:
6005 handleInvariantGroup(
I);
6007 case Intrinsic::bswap:
6010 case Intrinsic::ctlz:
6011 case Intrinsic::cttz:
6012 handleCountLeadingTrailingZeros(
I);
6014 case Intrinsic::masked_compressstore:
6015 handleMaskedCompressStore(
I);
6017 case Intrinsic::masked_expandload:
6018 handleMaskedExpandLoad(
I);
6020 case Intrinsic::masked_gather:
6021 handleMaskedGather(
I);
6023 case Intrinsic::masked_scatter:
6024 handleMaskedScatter(
I);
6026 case Intrinsic::masked_store:
6027 handleMaskedStore(
I);
6029 case Intrinsic::masked_load:
6030 handleMaskedLoad(
I);
6032 case Intrinsic::masked_udiv:
6033 case Intrinsic::masked_sdiv:
6034 case Intrinsic::masked_urem:
6035 case Intrinsic::masked_srem:
6036 handleMaskedIntegerDivRem(
I);
6038 case Intrinsic::vector_reduce_and:
6039 handleVectorReduceAndIntrinsic(
I);
6041 case Intrinsic::vector_reduce_or:
6042 handleVectorReduceOrIntrinsic(
I);
6045 case Intrinsic::vector_reduce_add:
6046 case Intrinsic::vector_reduce_xor:
6047 case Intrinsic::vector_reduce_mul:
6050 case Intrinsic::vector_reduce_smax:
6051 case Intrinsic::vector_reduce_smin:
6052 case Intrinsic::vector_reduce_umax:
6053 case Intrinsic::vector_reduce_umin:
6056 case Intrinsic::vector_reduce_fmax:
6057 case Intrinsic::vector_reduce_fmin:
6058 handleVectorReduceIntrinsic(
I,
false);
6061 case Intrinsic::vector_reduce_fadd:
6062 case Intrinsic::vector_reduce_fmul:
6063 handleVectorReduceWithStarterIntrinsic(
I);
6067 case Intrinsic::vector_partial_reduce_add:
6068 case Intrinsic::vector_partial_reduce_fadd:
6069 handleVectorPartialReduceAddIntrinsic(
I);
6072 case Intrinsic::experimental_vector_extract_last_active:
6073 handleVectorExtractLastActive(
I);
6076 case Intrinsic::scmp:
6077 case Intrinsic::ucmp: {
6082 case Intrinsic::fshl:
6083 case Intrinsic::fshr:
6084 handleFunnelShift(
I);
6087 case Intrinsic::pdep:
6088 case Intrinsic::pext:
6089 handleGenericBitManipulation(
I);
6092 case Intrinsic::is_constant:
6094 setShadow(&
I, getCleanShadow(&
I));
6095 setOrigin(&
I, getCleanOrigin());
6102 case Intrinsic::fptosi_sat:
6103 case Intrinsic::fptoui_sat:
6104 handleGenericVectorConvertIntrinsic(
I,
false);
6111 case Intrinsic::fake_use:
6112 assert(
I.getType()->isVoidTy());
6125 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &
I) {
6126 switch (
I.getIntrinsicID()) {
6127 case Intrinsic::x86_sse_stmxcsr:
6130 case Intrinsic::x86_sse_ldmxcsr:
6137 case Intrinsic::x86_avx512_vcvtsd2usi64:
6138 case Intrinsic::x86_avx512_vcvtsd2usi32:
6139 case Intrinsic::x86_avx512_vcvtss2usi64:
6140 case Intrinsic::x86_avx512_vcvtss2usi32:
6141 case Intrinsic::x86_avx512_cvttss2usi64:
6142 case Intrinsic::x86_avx512_cvttss2usi:
6143 case Intrinsic::x86_avx512_cvttsd2usi64:
6144 case Intrinsic::x86_avx512_cvttsd2usi:
6145 case Intrinsic::x86_avx512_cvtusi2ss:
6146 case Intrinsic::x86_avx512_cvtusi642sd:
6147 case Intrinsic::x86_avx512_cvtusi642ss:
6148 handleSSEVectorConvertIntrinsic(
I, 1,
true);
6150 case Intrinsic::x86_sse2_cvtsd2si64:
6151 case Intrinsic::x86_sse2_cvtsd2si:
6152 case Intrinsic::x86_sse2_cvtsd2ss:
6153 case Intrinsic::x86_sse2_cvttsd2si64:
6154 case Intrinsic::x86_sse2_cvttsd2si:
6155 case Intrinsic::x86_sse_cvtss2si64:
6156 case Intrinsic::x86_sse_cvtss2si:
6157 case Intrinsic::x86_sse_cvttss2si64:
6158 case Intrinsic::x86_sse_cvttss2si:
6159 handleSSEVectorConvertIntrinsic(
I, 1);
6161 case Intrinsic::x86_sse_cvtps2pi:
6162 case Intrinsic::x86_sse_cvttps2pi:
6163 handleSSEVectorConvertIntrinsic(
I, 2);
6171 case Intrinsic::x86_vcvtps2ph_128:
6172 case Intrinsic::x86_vcvtps2ph_256: {
6173 handleSSEVectorConvertIntrinsicByProp(
I,
true);
6182 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
6183 handleAVX512VectorConvertFPToInt(
I,
false);
6188 case Intrinsic::x86_sse2_cvtpd2ps:
6189 case Intrinsic::x86_sse2_cvtps2dq:
6190 case Intrinsic::x86_sse2_cvtpd2dq:
6191 case Intrinsic::x86_sse2_cvttps2dq:
6192 case Intrinsic::x86_sse2_cvttpd2dq:
6193 case Intrinsic::x86_avx_cvt_pd2_ps_256:
6194 case Intrinsic::x86_avx_cvt_ps2dq_256:
6195 case Intrinsic::x86_avx_cvt_pd2dq_256:
6196 case Intrinsic::x86_avx_cvtt_ps2dq_256:
6197 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
6198 handleSSEVectorConvertIntrinsicByProp(
I,
false);
6209 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
6210 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
6211 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
6212 handleAVX512VectorConvertFPToInt(
I,
true);
6216 case Intrinsic::x86_avx512_psll_w_512:
6217 case Intrinsic::x86_avx512_psll_d_512:
6218 case Intrinsic::x86_avx512_psll_q_512:
6219 case Intrinsic::x86_avx512_pslli_w_512:
6220 case Intrinsic::x86_avx512_pslli_d_512:
6221 case Intrinsic::x86_avx512_pslli_q_512:
6222 case Intrinsic::x86_avx512_psrl_w_512:
6223 case Intrinsic::x86_avx512_psrl_d_512:
6224 case Intrinsic::x86_avx512_psrl_q_512:
6225 case Intrinsic::x86_avx512_psra_w_512:
6226 case Intrinsic::x86_avx512_psra_d_512:
6227 case Intrinsic::x86_avx512_psra_q_512:
6228 case Intrinsic::x86_avx512_psrli_w_512:
6229 case Intrinsic::x86_avx512_psrli_d_512:
6230 case Intrinsic::x86_avx512_psrli_q_512:
6231 case Intrinsic::x86_avx512_psrai_w_512:
6232 case Intrinsic::x86_avx512_psrai_d_512:
6233 case Intrinsic::x86_avx512_psrai_q_512:
6234 case Intrinsic::x86_avx512_psra_q_256:
6235 case Intrinsic::x86_avx512_psra_q_128:
6236 case Intrinsic::x86_avx512_psrai_q_256:
6237 case Intrinsic::x86_avx512_psrai_q_128:
6238 case Intrinsic::x86_avx2_psll_w:
6239 case Intrinsic::x86_avx2_psll_d:
6240 case Intrinsic::x86_avx2_psll_q:
6241 case Intrinsic::x86_avx2_pslli_w:
6242 case Intrinsic::x86_avx2_pslli_d:
6243 case Intrinsic::x86_avx2_pslli_q:
6244 case Intrinsic::x86_avx2_psrl_w:
6245 case Intrinsic::x86_avx2_psrl_d:
6246 case Intrinsic::x86_avx2_psrl_q:
6247 case Intrinsic::x86_avx2_psra_w:
6248 case Intrinsic::x86_avx2_psra_d:
6249 case Intrinsic::x86_avx2_psrli_w:
6250 case Intrinsic::x86_avx2_psrli_d:
6251 case Intrinsic::x86_avx2_psrli_q:
6252 case Intrinsic::x86_avx2_psrai_w:
6253 case Intrinsic::x86_avx2_psrai_d:
6254 case Intrinsic::x86_sse2_psll_w:
6255 case Intrinsic::x86_sse2_psll_d:
6256 case Intrinsic::x86_sse2_psll_q:
6257 case Intrinsic::x86_sse2_pslli_w:
6258 case Intrinsic::x86_sse2_pslli_d:
6259 case Intrinsic::x86_sse2_pslli_q:
6260 case Intrinsic::x86_sse2_psrl_w:
6261 case Intrinsic::x86_sse2_psrl_d:
6262 case Intrinsic::x86_sse2_psrl_q:
6263 case Intrinsic::x86_sse2_psra_w:
6264 case Intrinsic::x86_sse2_psra_d:
6265 case Intrinsic::x86_sse2_psrli_w:
6266 case Intrinsic::x86_sse2_psrli_d:
6267 case Intrinsic::x86_sse2_psrli_q:
6268 case Intrinsic::x86_sse2_psrai_w:
6269 case Intrinsic::x86_sse2_psrai_d:
6270 case Intrinsic::x86_mmx_psll_w:
6271 case Intrinsic::x86_mmx_psll_d:
6272 case Intrinsic::x86_mmx_psll_q:
6273 case Intrinsic::x86_mmx_pslli_w:
6274 case Intrinsic::x86_mmx_pslli_d:
6275 case Intrinsic::x86_mmx_pslli_q:
6276 case Intrinsic::x86_mmx_psrl_w:
6277 case Intrinsic::x86_mmx_psrl_d:
6278 case Intrinsic::x86_mmx_psrl_q:
6279 case Intrinsic::x86_mmx_psra_w:
6280 case Intrinsic::x86_mmx_psra_d:
6281 case Intrinsic::x86_mmx_psrli_w:
6282 case Intrinsic::x86_mmx_psrli_d:
6283 case Intrinsic::x86_mmx_psrli_q:
6284 case Intrinsic::x86_mmx_psrai_w:
6285 case Intrinsic::x86_mmx_psrai_d:
6286 handleVectorShiftIntrinsic(
I,
false);
6288 case Intrinsic::x86_avx2_psllv_d:
6289 case Intrinsic::x86_avx2_psllv_d_256:
6290 case Intrinsic::x86_avx512_psllv_d_512:
6291 case Intrinsic::x86_avx2_psllv_q:
6292 case Intrinsic::x86_avx2_psllv_q_256:
6293 case Intrinsic::x86_avx512_psllv_q_512:
6294 case Intrinsic::x86_avx2_psrlv_d:
6295 case Intrinsic::x86_avx2_psrlv_d_256:
6296 case Intrinsic::x86_avx512_psrlv_d_512:
6297 case Intrinsic::x86_avx2_psrlv_q:
6298 case Intrinsic::x86_avx2_psrlv_q_256:
6299 case Intrinsic::x86_avx512_psrlv_q_512:
6300 case Intrinsic::x86_avx2_psrav_d:
6301 case Intrinsic::x86_avx2_psrav_d_256:
6302 case Intrinsic::x86_avx512_psrav_d_512:
6303 case Intrinsic::x86_avx512_psrav_q_128:
6304 case Intrinsic::x86_avx512_psrav_q_256:
6305 case Intrinsic::x86_avx512_psrav_q_512:
6306 handleVectorShiftIntrinsic(
I,
true);
6310 case Intrinsic::x86_sse2_packsswb_128:
6311 case Intrinsic::x86_sse2_packssdw_128:
6312 case Intrinsic::x86_sse2_packuswb_128:
6313 case Intrinsic::x86_sse41_packusdw:
6314 case Intrinsic::x86_avx2_packsswb:
6315 case Intrinsic::x86_avx2_packssdw:
6316 case Intrinsic::x86_avx2_packuswb:
6317 case Intrinsic::x86_avx2_packusdw:
6323 case Intrinsic::x86_avx512_packsswb_512:
6324 case Intrinsic::x86_avx512_packssdw_512:
6325 case Intrinsic::x86_avx512_packuswb_512:
6326 case Intrinsic::x86_avx512_packusdw_512:
6327 handleVectorPackIntrinsic(
I);
6330 case Intrinsic::x86_sse41_pblendvb:
6331 case Intrinsic::x86_sse41_blendvpd:
6332 case Intrinsic::x86_sse41_blendvps:
6333 case Intrinsic::x86_avx_blendv_pd_256:
6334 case Intrinsic::x86_avx_blendv_ps_256:
6335 case Intrinsic::x86_avx2_pblendvb:
6336 handleBlendvIntrinsic(
I);
6339 case Intrinsic::x86_avx_dp_ps_256:
6340 case Intrinsic::x86_sse41_dppd:
6341 case Intrinsic::x86_sse41_dpps:
6342 handleDppIntrinsic(
I);
6345 case Intrinsic::x86_mmx_packsswb:
6346 case Intrinsic::x86_mmx_packuswb:
6347 handleVectorPackIntrinsic(
I, 16);
6350 case Intrinsic::x86_mmx_packssdw:
6351 handleVectorPackIntrinsic(
I, 32);
6354 case Intrinsic::x86_mmx_psad_bw:
6355 handleVectorSadIntrinsic(
I,
true);
6357 case Intrinsic::x86_sse2_psad_bw:
6358 case Intrinsic::x86_avx2_psad_bw:
6359 handleVectorSadIntrinsic(
I);
6385 case Intrinsic::x86_sse2_pmadd_wd:
6386 case Intrinsic::x86_avx2_pmadd_wd:
6387 case Intrinsic::x86_avx512_pmaddw_d_512:
6388 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6389 case Intrinsic::x86_avx2_pmadd_ub_sw:
6390 case Intrinsic::x86_avx512_pmaddubs_w_512:
6391 handleVectorDotProductIntrinsic(
I, 2,
6398 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6399 handleVectorDotProductIntrinsic(
I, 2,
6406 case Intrinsic::x86_mmx_pmadd_wd:
6407 handleVectorDotProductIntrinsic(
I, 2,
6416 case Intrinsic::aarch64_neon_bfmlalt:
6417 handleVectorDotProductIntrinsic(
I, 2,
6425 case Intrinsic::aarch64_neon_bfmlalb:
6426 handleVectorDotProductIntrinsic(
I, 2,
6524 case Intrinsic::x86_avx512_vpdpbusd_128:
6525 case Intrinsic::x86_avx512_vpdpbusd_256:
6526 case Intrinsic::x86_avx512_vpdpbusd_512:
6527 case Intrinsic::x86_avx512_vpdpbusds_128:
6528 case Intrinsic::x86_avx512_vpdpbusds_256:
6529 case Intrinsic::x86_avx512_vpdpbusds_512:
6530 case Intrinsic::x86_avx2_vpdpbssd_128:
6531 case Intrinsic::x86_avx2_vpdpbssd_256:
6532 case Intrinsic::x86_avx10_vpdpbssd_512:
6533 case Intrinsic::x86_avx2_vpdpbssds_128:
6534 case Intrinsic::x86_avx2_vpdpbssds_256:
6535 case Intrinsic::x86_avx10_vpdpbssds_512:
6536 case Intrinsic::x86_avx2_vpdpbsud_128:
6537 case Intrinsic::x86_avx2_vpdpbsud_256:
6538 case Intrinsic::x86_avx10_vpdpbsud_512:
6539 case Intrinsic::x86_avx2_vpdpbsuds_128:
6540 case Intrinsic::x86_avx2_vpdpbsuds_256:
6541 case Intrinsic::x86_avx10_vpdpbsuds_512:
6542 case Intrinsic::x86_avx2_vpdpbuud_128:
6543 case Intrinsic::x86_avx2_vpdpbuud_256:
6544 case Intrinsic::x86_avx10_vpdpbuud_512:
6545 case Intrinsic::x86_avx2_vpdpbuuds_128:
6546 case Intrinsic::x86_avx2_vpdpbuuds_256:
6547 case Intrinsic::x86_avx10_vpdpbuuds_512:
6548 handleVectorDotProductIntrinsic(
I, 4,
6646 case Intrinsic::x86_avx512_vpdpwssd_128:
6647 case Intrinsic::x86_avx512_vpdpwssd_256:
6648 case Intrinsic::x86_avx512_vpdpwssd_512:
6649 case Intrinsic::x86_avx512_vpdpwssds_128:
6650 case Intrinsic::x86_avx512_vpdpwssds_256:
6651 case Intrinsic::x86_avx512_vpdpwssds_512:
6652 case Intrinsic::x86_avx2_vpdpwsud_128:
6653 case Intrinsic::x86_avx2_vpdpwsud_256:
6654 case Intrinsic::x86_avx10_vpdpwsud_512:
6655 case Intrinsic::x86_avx2_vpdpwsuds_128:
6656 case Intrinsic::x86_avx2_vpdpwsuds_256:
6657 case Intrinsic::x86_avx10_vpdpwsuds_512:
6658 case Intrinsic::x86_avx2_vpdpwusd_128:
6659 case Intrinsic::x86_avx2_vpdpwusd_256:
6660 case Intrinsic::x86_avx10_vpdpwusd_512:
6661 case Intrinsic::x86_avx2_vpdpwusds_128:
6662 case Intrinsic::x86_avx2_vpdpwusds_256:
6663 case Intrinsic::x86_avx10_vpdpwusds_512:
6664 case Intrinsic::x86_avx2_vpdpwuud_128:
6665 case Intrinsic::x86_avx2_vpdpwuud_256:
6666 case Intrinsic::x86_avx10_vpdpwuud_512:
6667 case Intrinsic::x86_avx2_vpdpwuuds_128:
6668 case Intrinsic::x86_avx2_vpdpwuuds_256:
6669 case Intrinsic::x86_avx10_vpdpwuuds_512:
6670 handleVectorDotProductIntrinsic(
I, 2,
6684 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6685 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6686 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6687 handleVectorDotProductIntrinsic(
I, 2,
6693 case Intrinsic::x86_sse_cmp_ss:
6694 case Intrinsic::x86_sse2_cmp_sd:
6695 case Intrinsic::x86_sse_comieq_ss:
6696 case Intrinsic::x86_sse_comilt_ss:
6697 case Intrinsic::x86_sse_comile_ss:
6698 case Intrinsic::x86_sse_comigt_ss:
6699 case Intrinsic::x86_sse_comige_ss:
6700 case Intrinsic::x86_sse_comineq_ss:
6701 case Intrinsic::x86_sse_ucomieq_ss:
6702 case Intrinsic::x86_sse_ucomilt_ss:
6703 case Intrinsic::x86_sse_ucomile_ss:
6704 case Intrinsic::x86_sse_ucomigt_ss:
6705 case Intrinsic::x86_sse_ucomige_ss:
6706 case Intrinsic::x86_sse_ucomineq_ss:
6707 case Intrinsic::x86_sse2_comieq_sd:
6708 case Intrinsic::x86_sse2_comilt_sd:
6709 case Intrinsic::x86_sse2_comile_sd:
6710 case Intrinsic::x86_sse2_comigt_sd:
6711 case Intrinsic::x86_sse2_comige_sd:
6712 case Intrinsic::x86_sse2_comineq_sd:
6713 case Intrinsic::x86_sse2_ucomieq_sd:
6714 case Intrinsic::x86_sse2_ucomilt_sd:
6715 case Intrinsic::x86_sse2_ucomile_sd:
6716 case Intrinsic::x86_sse2_ucomigt_sd:
6717 case Intrinsic::x86_sse2_ucomige_sd:
6718 case Intrinsic::x86_sse2_ucomineq_sd:
6719 handleVectorCompareScalarIntrinsic(
I);
6722 case Intrinsic::x86_avx_cmp_pd_256:
6723 case Intrinsic::x86_avx_cmp_ps_256:
6724 case Intrinsic::x86_sse2_cmp_pd:
6725 case Intrinsic::x86_sse_cmp_ps:
6726 handleVectorComparePackedIntrinsic(
I,
true);
6729 case Intrinsic::x86_bmi_bextr_32:
6730 case Intrinsic::x86_bmi_bextr_64:
6731 case Intrinsic::x86_bmi_bzhi_32:
6732 case Intrinsic::x86_bmi_bzhi_64:
6733 handleGenericBitManipulation(
I);
6736 case Intrinsic::x86_pclmulqdq:
6737 case Intrinsic::x86_pclmulqdq_256:
6738 case Intrinsic::x86_pclmulqdq_512:
6739 handlePclmulIntrinsic(
I);
6742 case Intrinsic::x86_avx_round_pd_256:
6743 case Intrinsic::x86_avx_round_ps_256:
6744 case Intrinsic::x86_sse41_round_pd:
6745 case Intrinsic::x86_sse41_round_ps:
6746 handleRoundPdPsIntrinsic(
I);
6749 case Intrinsic::x86_sse41_round_sd:
6750 case Intrinsic::x86_sse41_round_ss:
6751 handleUnarySdSsIntrinsic(
I);
6754 case Intrinsic::x86_sse2_max_sd:
6755 case Intrinsic::x86_sse_max_ss:
6756 case Intrinsic::x86_sse2_min_sd:
6757 case Intrinsic::x86_sse_min_ss:
6758 handleBinarySdSsIntrinsic(
I);
6761 case Intrinsic::x86_avx_vtestc_pd:
6762 case Intrinsic::x86_avx_vtestc_pd_256:
6763 case Intrinsic::x86_avx_vtestc_ps:
6764 case Intrinsic::x86_avx_vtestc_ps_256:
6765 case Intrinsic::x86_avx_vtestnzc_pd:
6766 case Intrinsic::x86_avx_vtestnzc_pd_256:
6767 case Intrinsic::x86_avx_vtestnzc_ps:
6768 case Intrinsic::x86_avx_vtestnzc_ps_256:
6769 case Intrinsic::x86_avx_vtestz_pd:
6770 case Intrinsic::x86_avx_vtestz_pd_256:
6771 case Intrinsic::x86_avx_vtestz_ps:
6772 case Intrinsic::x86_avx_vtestz_ps_256:
6773 case Intrinsic::x86_avx_ptestc_256:
6774 case Intrinsic::x86_avx_ptestnzc_256:
6775 case Intrinsic::x86_avx_ptestz_256:
6776 case Intrinsic::x86_sse41_ptestc:
6777 case Intrinsic::x86_sse41_ptestnzc:
6778 case Intrinsic::x86_sse41_ptestz:
6779 handleVtestIntrinsic(
I);
6783 case Intrinsic::x86_ssse3_phadd_w:
6784 case Intrinsic::x86_ssse3_phadd_w_128:
6785 case Intrinsic::x86_ssse3_phsub_w:
6786 case Intrinsic::x86_ssse3_phsub_w_128:
6787 handlePairwiseShadowOrIntrinsic(
I, 1,
6791 case Intrinsic::x86_avx2_phadd_w:
6792 case Intrinsic::x86_avx2_phsub_w:
6793 handlePairwiseShadowOrIntrinsic(
I, 2,
6798 case Intrinsic::x86_ssse3_phadd_d:
6799 case Intrinsic::x86_ssse3_phadd_d_128:
6800 case Intrinsic::x86_ssse3_phsub_d:
6801 case Intrinsic::x86_ssse3_phsub_d_128:
6802 handlePairwiseShadowOrIntrinsic(
I, 1,
6806 case Intrinsic::x86_avx2_phadd_d:
6807 case Intrinsic::x86_avx2_phsub_d:
6808 handlePairwiseShadowOrIntrinsic(
I, 2,
6813 case Intrinsic::x86_ssse3_phadd_sw:
6814 case Intrinsic::x86_ssse3_phadd_sw_128:
6815 case Intrinsic::x86_ssse3_phsub_sw:
6816 case Intrinsic::x86_ssse3_phsub_sw_128:
6817 handlePairwiseShadowOrIntrinsic(
I, 1,
6821 case Intrinsic::x86_avx2_phadd_sw:
6822 case Intrinsic::x86_avx2_phsub_sw:
6823 handlePairwiseShadowOrIntrinsic(
I, 2,
6828 case Intrinsic::x86_sse3_hadd_ps:
6829 case Intrinsic::x86_sse3_hadd_pd:
6830 case Intrinsic::x86_sse3_hsub_ps:
6831 case Intrinsic::x86_sse3_hsub_pd:
6832 handlePairwiseShadowOrIntrinsic(
I, 1);
6835 case Intrinsic::x86_avx_hadd_pd_256:
6836 case Intrinsic::x86_avx_hadd_ps_256:
6837 case Intrinsic::x86_avx_hsub_pd_256:
6838 case Intrinsic::x86_avx_hsub_ps_256:
6839 handlePairwiseShadowOrIntrinsic(
I, 2);
6842 case Intrinsic::x86_avx_maskstore_ps:
6843 case Intrinsic::x86_avx_maskstore_pd:
6844 case Intrinsic::x86_avx_maskstore_ps_256:
6845 case Intrinsic::x86_avx_maskstore_pd_256:
6846 case Intrinsic::x86_avx2_maskstore_d:
6847 case Intrinsic::x86_avx2_maskstore_q:
6848 case Intrinsic::x86_avx2_maskstore_d_256:
6849 case Intrinsic::x86_avx2_maskstore_q_256: {
6850 handleAVXMaskedStore(
I);
6854 case Intrinsic::x86_avx_maskload_ps:
6855 case Intrinsic::x86_avx_maskload_pd:
6856 case Intrinsic::x86_avx_maskload_ps_256:
6857 case Intrinsic::x86_avx_maskload_pd_256:
6858 case Intrinsic::x86_avx2_maskload_d:
6859 case Intrinsic::x86_avx2_maskload_q:
6860 case Intrinsic::x86_avx2_maskload_d_256:
6861 case Intrinsic::x86_avx2_maskload_q_256: {
6862 handleAVXMaskedLoad(
I);
6867 case Intrinsic::x86_avx512fp16_add_ph_512:
6868 case Intrinsic::x86_avx512fp16_sub_ph_512:
6869 case Intrinsic::x86_avx512fp16_mul_ph_512:
6870 case Intrinsic::x86_avx512fp16_div_ph_512:
6871 case Intrinsic::x86_avx512fp16_max_ph_512:
6872 case Intrinsic::x86_avx512fp16_min_ph_512:
6873 case Intrinsic::x86_avx512_min_ps_512:
6874 case Intrinsic::x86_avx512_min_pd_512:
6875 case Intrinsic::x86_avx512_max_ps_512:
6876 case Intrinsic::x86_avx512_max_pd_512: {
6881 [[maybe_unused]]
bool Success =
6882 maybeHandleSimpleNomemIntrinsic(
I, 1);
6887 case Intrinsic::x86_avx_vpermilvar_pd:
6888 case Intrinsic::x86_avx_vpermilvar_pd_256:
6889 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6890 case Intrinsic::x86_avx_vpermilvar_ps:
6891 case Intrinsic::x86_avx_vpermilvar_ps_256:
6892 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6893 handleAVXVpermilvar(
I);
6897 case Intrinsic::x86_avx512_vpermi2var_d_128:
6898 case Intrinsic::x86_avx512_vpermi2var_d_256:
6899 case Intrinsic::x86_avx512_vpermi2var_d_512:
6900 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6901 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6902 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6903 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6904 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6905 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6906 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6907 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6908 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6909 case Intrinsic::x86_avx512_vpermi2var_q_128:
6910 case Intrinsic::x86_avx512_vpermi2var_q_256:
6911 case Intrinsic::x86_avx512_vpermi2var_q_512:
6912 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6913 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6914 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6915 handleAVXVpermi2var(
I);
6929 case Intrinsic::x86_avx2_pshuf_b:
6930 case Intrinsic::x86_sse_pshuf_w:
6931 case Intrinsic::x86_ssse3_pshuf_b_128:
6932 case Intrinsic::x86_ssse3_pshuf_b:
6933 case Intrinsic::x86_avx512_pshuf_b_512:
6934 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6941 case Intrinsic::x86_avx512_mask_pmov_dw_128:
6942 case Intrinsic::x86_avx512_mask_pmov_db_128:
6943 case Intrinsic::x86_avx512_mask_pmov_qb_128:
6944 case Intrinsic::x86_avx512_mask_pmov_qw_128:
6945 case Intrinsic::x86_avx512_mask_pmov_qd_128:
6946 case Intrinsic::x86_avx512_mask_pmov_wb_128:
6947 case Intrinsic::x86_avx512_mask_pmov_dw_256:
6948 case Intrinsic::x86_avx512_mask_pmov_db_256:
6949 case Intrinsic::x86_avx512_mask_pmov_qb_256:
6950 case Intrinsic::x86_avx512_mask_pmov_qw_256:
6951 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6952 case Intrinsic::x86_avx512_mask_pmov_db_512:
6953 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6954 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6957 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6966 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6967 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6968 handleIntrinsicByApplyingToShadow(
6969 I, Intrinsic::x86_avx512_mask_pmov_dw_512,
6974 case Intrinsic::x86_avx512_mask_pmovs_dw_256:
6975 case Intrinsic::x86_avx512_mask_pmovus_dw_256:
6976 handleIntrinsicByApplyingToShadow(
6977 I, Intrinsic::x86_avx512_mask_pmov_dw_256,
6981 case Intrinsic::x86_avx512_mask_pmovs_dw_128:
6982 case Intrinsic::x86_avx512_mask_pmovus_dw_128:
6983 handleIntrinsicByApplyingToShadow(
6984 I, Intrinsic::x86_avx512_mask_pmov_dw_128,
6988 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6989 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6990 handleIntrinsicByApplyingToShadow(
6991 I, Intrinsic::x86_avx512_mask_pmov_db_512,
6996 case Intrinsic::x86_avx512_mask_pmovs_db_256:
6997 case Intrinsic::x86_avx512_mask_pmovus_db_256:
6998 handleIntrinsicByApplyingToShadow(
6999 I, Intrinsic::x86_avx512_mask_pmov_db_256,
7003 case Intrinsic::x86_avx512_mask_pmovs_db_128:
7004 case Intrinsic::x86_avx512_mask_pmovus_db_128:
7005 handleIntrinsicByApplyingToShadow(
7006 I, Intrinsic::x86_avx512_mask_pmov_db_128,
7010 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
7011 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
7012 handleIntrinsicByApplyingToShadow(
7013 I, Intrinsic::x86_avx512_mask_pmov_qb_512,
7018 case Intrinsic::x86_avx512_mask_pmovs_qb_256:
7019 case Intrinsic::x86_avx512_mask_pmovus_qb_256:
7020 handleIntrinsicByApplyingToShadow(
7021 I, Intrinsic::x86_avx512_mask_pmov_qb_256,
7025 case Intrinsic::x86_avx512_mask_pmovs_qb_128:
7026 case Intrinsic::x86_avx512_mask_pmovus_qb_128:
7027 handleIntrinsicByApplyingToShadow(
7028 I, Intrinsic::x86_avx512_mask_pmov_qb_128,
7032 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
7033 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
7034 handleIntrinsicByApplyingToShadow(
7035 I, Intrinsic::x86_avx512_mask_pmov_qw_512,
7040 case Intrinsic::x86_avx512_mask_pmovs_qw_256:
7041 case Intrinsic::x86_avx512_mask_pmovus_qw_256:
7042 handleIntrinsicByApplyingToShadow(
7043 I, Intrinsic::x86_avx512_mask_pmov_qw_256,
7047 case Intrinsic::x86_avx512_mask_pmovs_qw_128:
7048 case Intrinsic::x86_avx512_mask_pmovus_qw_128:
7049 handleIntrinsicByApplyingToShadow(
7050 I, Intrinsic::x86_avx512_mask_pmov_qw_128,
7054 case Intrinsic::x86_avx512_mask_pmovs_qd_128:
7055 case Intrinsic::x86_avx512_mask_pmovus_qd_128:
7056 handleIntrinsicByApplyingToShadow(
7057 I, Intrinsic::x86_avx512_mask_pmov_qd_128,
7061 case Intrinsic::x86_avx512_mask_pmovs_wb_128:
7062 case Intrinsic::x86_avx512_mask_pmovus_wb_128:
7063 handleIntrinsicByApplyingToShadow(
7064 I, Intrinsic::x86_avx512_mask_pmov_wb_128,
7068 case Intrinsic::x86_avx512_mask_pmovs_qd_256:
7069 case Intrinsic::x86_avx512_mask_pmovus_qd_256:
7070 case Intrinsic::x86_avx512_mask_pmovs_wb_256:
7071 case Intrinsic::x86_avx512_mask_pmovus_wb_256:
7072 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
7073 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
7074 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
7075 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
7079 handleAVX512VectorDownConvert(
I);
7090 case Intrinsic::x86_avx512_mask_compress:
7091 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7132 case Intrinsic::x86_avx512_rsqrt14_ps_512:
7133 case Intrinsic::x86_avx512_rsqrt14_ps_256:
7134 case Intrinsic::x86_avx512_rsqrt14_ps_128:
7135 case Intrinsic::x86_avx512_rsqrt14_pd_512:
7136 case Intrinsic::x86_avx512_rsqrt14_pd_256:
7137 case Intrinsic::x86_avx512_rsqrt14_pd_128:
7138 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
7139 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
7140 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
7141 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
7142 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
7143 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
7144 handleAVX512VectorGenericMaskedFP(
I, {0},
7185 case Intrinsic::x86_avx512_rcp14_ps_512:
7186 case Intrinsic::x86_avx512_rcp14_ps_256:
7187 case Intrinsic::x86_avx512_rcp14_ps_128:
7188 case Intrinsic::x86_avx512_rcp14_pd_512:
7189 case Intrinsic::x86_avx512_rcp14_pd_256:
7190 case Intrinsic::x86_avx512_rcp14_pd_128:
7191 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
7192 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
7193 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
7194 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
7195 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
7196 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
7197 handleAVX512VectorGenericMaskedFP(
I, {0},
7242 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
7243 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
7244 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
7245 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
7246 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
7247 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
7248 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
7249 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
7250 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
7251 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
7252 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
7253 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
7254 handleAVX512VectorGenericMaskedFP(
I, {0},
7290 case Intrinsic::x86_avx512_mask_scalef_pd_512:
7291 case Intrinsic::x86_avx512_mask_scalef_pd_256:
7292 case Intrinsic::x86_avx512_mask_scalef_pd_128:
7293 case Intrinsic::x86_avx512_mask_scalef_ps_512:
7294 case Intrinsic::x86_avx512_mask_scalef_ps_256:
7295 case Intrinsic::x86_avx512_mask_scalef_ps_128:
7296 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
7297 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
7298 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
7302 handleAVX512VectorGenericMaskedFP(
I, {0, 1},
7322 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
7323 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
7324 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
7325 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
7326 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
7327 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
7328 visitGenericScalarHalfwordInst(
I);
7335 case Intrinsic::x86_avx512_fpclass_pd_512:
7336 case Intrinsic::x86_avx512_fpclass_ps_512:
7337 handleAVX512FPClass(
I);
7341 case Intrinsic::x86_vgf2p8affineqb_128:
7342 case Intrinsic::x86_vgf2p8affineqb_256:
7343 case Intrinsic::x86_vgf2p8affineqb_512:
7344 handleAVXGF2P8Affine(
I);
7354 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &
I) {
7355 switch (
I.getIntrinsicID()) {
7359 case Intrinsic::aarch64_neon_rshrn:
7360 case Intrinsic::aarch64_neon_sqrshl:
7361 case Intrinsic::aarch64_neon_sqrshrn:
7362 case Intrinsic::aarch64_neon_sqrshrun:
7363 case Intrinsic::aarch64_neon_sqshl:
7364 case Intrinsic::aarch64_neon_sqshlu:
7365 case Intrinsic::aarch64_neon_sqshrn:
7366 case Intrinsic::aarch64_neon_sqshrun:
7367 case Intrinsic::aarch64_neon_srshl:
7368 case Intrinsic::aarch64_neon_sshl:
7369 case Intrinsic::aarch64_neon_uqrshl:
7370 case Intrinsic::aarch64_neon_uqrshrn:
7371 case Intrinsic::aarch64_neon_uqshl:
7372 case Intrinsic::aarch64_neon_uqshrn:
7373 case Intrinsic::aarch64_neon_urshl:
7374 case Intrinsic::aarch64_neon_ushl:
7375 handleVectorShiftIntrinsic(
I,
false);
7388 case Intrinsic::aarch64_neon_vsli:
7389 case Intrinsic::aarch64_neon_vsri:
7390 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7397 case Intrinsic::aarch64_neon_fmaxp:
7398 case Intrinsic::aarch64_neon_fminp:
7400 case Intrinsic::aarch64_neon_fmaxnmp:
7401 case Intrinsic::aarch64_neon_fminnmp:
7403 case Intrinsic::aarch64_neon_smaxp:
7404 case Intrinsic::aarch64_neon_sminp:
7405 case Intrinsic::aarch64_neon_umaxp:
7406 case Intrinsic::aarch64_neon_uminp:
7408 case Intrinsic::aarch64_neon_addp:
7410 case Intrinsic::aarch64_neon_faddp:
7412 case Intrinsic::aarch64_neon_saddlp:
7413 case Intrinsic::aarch64_neon_uaddlp: {
7414 handlePairwiseShadowOrIntrinsic(
I, 1);
7419 case Intrinsic::aarch64_neon_fcvtas:
7420 case Intrinsic::aarch64_neon_fcvtau:
7422 case Intrinsic::aarch64_neon_fcvtms:
7423 case Intrinsic::aarch64_neon_fcvtmu:
7425 case Intrinsic::aarch64_neon_fcvtns:
7426 case Intrinsic::aarch64_neon_fcvtnu:
7428 case Intrinsic::aarch64_neon_fcvtps:
7429 case Intrinsic::aarch64_neon_fcvtpu:
7431 case Intrinsic::aarch64_neon_fcvtzs:
7432 case Intrinsic::aarch64_neon_fcvtzu:
7434 case Intrinsic::aarch64_neon_fcvtxn:
7435 handleGenericVectorConvertIntrinsic(
I,
false);
7439 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7440 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7441 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7442 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7443 handleGenericVectorConvertIntrinsic(
I,
true);
7452 case Intrinsic::aarch64_neon_faddv:
7453 case Intrinsic::aarch64_neon_saddv:
7454 case Intrinsic::aarch64_neon_uaddv:
7457 case Intrinsic::aarch64_neon_smaxv:
7458 case Intrinsic::aarch64_neon_sminv:
7459 case Intrinsic::aarch64_neon_umaxv:
7460 case Intrinsic::aarch64_neon_uminv:
7464 case Intrinsic::aarch64_neon_fmaxv:
7465 case Intrinsic::aarch64_neon_fminv:
7466 case Intrinsic::aarch64_neon_fmaxnmv:
7467 case Intrinsic::aarch64_neon_fminnmv:
7469 case Intrinsic::aarch64_neon_saddlv:
7470 case Intrinsic::aarch64_neon_uaddlv:
7471 handleVectorReduceIntrinsic(
I,
true);
7474 case Intrinsic::aarch64_neon_ld1x2:
7475 case Intrinsic::aarch64_neon_ld1x3:
7476 case Intrinsic::aarch64_neon_ld1x4:
7477 case Intrinsic::aarch64_neon_ld2:
7478 case Intrinsic::aarch64_neon_ld3:
7479 case Intrinsic::aarch64_neon_ld4:
7480 case Intrinsic::aarch64_neon_ld2r:
7481 case Intrinsic::aarch64_neon_ld3r:
7482 case Intrinsic::aarch64_neon_ld4r: {
7483 handleNEONVectorLoad(
I,
false);
7487 case Intrinsic::aarch64_neon_ld2lane:
7488 case Intrinsic::aarch64_neon_ld3lane:
7489 case Intrinsic::aarch64_neon_ld4lane: {
7490 handleNEONVectorLoad(
I,
true);
7495 case Intrinsic::aarch64_neon_sqxtn:
7496 case Intrinsic::aarch64_neon_sqxtun:
7497 case Intrinsic::aarch64_neon_uqxtn:
7504 case Intrinsic::aarch64_neon_st1x2:
7505 case Intrinsic::aarch64_neon_st1x3:
7506 case Intrinsic::aarch64_neon_st1x4:
7507 case Intrinsic::aarch64_neon_st2:
7508 case Intrinsic::aarch64_neon_st3:
7509 case Intrinsic::aarch64_neon_st4: {
7510 handleNEONVectorStoreIntrinsic(
I,
false);
7514 case Intrinsic::aarch64_neon_st2lane:
7515 case Intrinsic::aarch64_neon_st3lane:
7516 case Intrinsic::aarch64_neon_st4lane: {
7517 handleNEONVectorStoreIntrinsic(
I,
true);
7530 case Intrinsic::aarch64_neon_tbl1:
7531 case Intrinsic::aarch64_neon_tbl2:
7532 case Intrinsic::aarch64_neon_tbl3:
7533 case Intrinsic::aarch64_neon_tbl4:
7534 case Intrinsic::aarch64_neon_tbx1:
7535 case Intrinsic::aarch64_neon_tbx2:
7536 case Intrinsic::aarch64_neon_tbx3:
7537 case Intrinsic::aarch64_neon_tbx4: {
7539 handleIntrinsicByApplyingToShadow(
7540 I,
I.getIntrinsicID(),
7545 case Intrinsic::aarch64_neon_fmulx:
7546 case Intrinsic::aarch64_neon_pmul:
7547 case Intrinsic::aarch64_neon_pmull:
7548 case Intrinsic::aarch64_neon_smull:
7549 case Intrinsic::aarch64_neon_pmull64:
7550 case Intrinsic::aarch64_neon_umull: {
7551 handleNEONVectorMultiplyIntrinsic(
I);
7555 case Intrinsic::aarch64_neon_smmla:
7556 case Intrinsic::aarch64_neon_ummla:
7557 case Intrinsic::aarch64_neon_usmmla:
7558 case Intrinsic::aarch64_neon_bfmmla:
7559 handleNEONMatrixMultiply(
I);
7566 case Intrinsic::aarch64_neon_sdot:
7567 case Intrinsic::aarch64_neon_udot:
7568 case Intrinsic::aarch64_neon_usdot:
7569 handleVectorDotProductIntrinsic(
I, 4,
7579 case Intrinsic::aarch64_neon_bfdot:
7580 handleVectorDotProductIntrinsic(
I, 2,
7593 case Intrinsic::aarch64_neon_fp8_fdot2:
7594 handleVectorDotProductIntrinsic(
I, 2,
7607 case Intrinsic::aarch64_neon_fp8_fdot4:
7608 handleVectorDotProductIntrinsic(
I, 4,
7618 case Intrinsic::aarch64_neon_fp8_fdot2_lane:
7619 handleNEONDotProductLaneIntrinsic(
I, 2);
7626 case Intrinsic::aarch64_neon_fp8_fdot4_lane:
7627 handleNEONDotProductLaneIntrinsic(
I, 4);
7631 case Intrinsic::aarch64_neon_facge:
7632 case Intrinsic::aarch64_neon_facgt:
7633 handleVectorComparePackedIntrinsic(
I,
false);
7643 void visitIntrinsicInst(IntrinsicInst &
I) {
7644 if (maybeHandleCrossPlatformIntrinsic(
I))
7647 if (maybeHandleX86SIMDIntrinsic(
I))
7650 if (maybeHandleArmSIMDIntrinsic(
I))
7653 if (maybeHandleUnknownIntrinsic(
I))
7656 visitInstruction(
I);
7659 void visitLibAtomicLoad(CallBase &CB) {
7670 Value *NewOrdering =
7674 NextNodeIRBuilder NextIRB(&CB);
7675 Value *SrcShadowPtr, *SrcOriginPtr;
7676 std::tie(SrcShadowPtr, SrcOriginPtr) =
7677 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7679 Value *DstShadowPtr =
7680 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7684 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
7685 if (MS.TrackOrigins) {
7686 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7688 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7689 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7693 void visitLibAtomicStore(CallBase &CB) {
7700 Value *NewOrdering =
7704 Value *DstShadowPtr =
7714 void visitCallBase(CallBase &CB) {
7721 if (Opts.msan_handle_asm_conservative)
7722 visitAsmInstruction(CB);
7724 visitInstruction(CB);
7727 LibFunc LF =
TLI->getLibFunc(CB);
7728 if (LF != NotLibFunc) {
7733 case LibFunc_atomic_load:
7735 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
7739 visitLibAtomicLoad(CB);
7741 case LibFunc_atomic_store:
7742 visitLibAtomicStore(CB);
7758 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7762 Func->removeFnAttrs(
B);
7768 bool MayCheckCall = MS.EagerChecks;
7772 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
7775 unsigned ArgOffset = 0;
7778 if (!
A->getType()->isSized()) {
7779 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
7783 if (
A->getType()->isScalableTy()) {
7784 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
7786 insertCheckShadowOf(
A, &CB);
7791 const DataLayout &
DL =
F.getDataLayout();
7795 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7798 insertCheckShadowOf(
A, &CB);
7799 Size =
DL.getTypeAllocSize(
A->getType());
7805 Value *ArgShadow = getShadow(
A);
7806 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7808 <<
" Shadow: " << *ArgShadow <<
"\n");
7812 assert(
A->getType()->isPointerTy() &&
7813 "ByVal argument is not a pointer!");
7821 Value *AShadowPtr, *AOriginPtr;
7822 std::tie(AShadowPtr, AOriginPtr) =
7823 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
7825 if (!PropagateShadow) {
7832 if (MS.TrackOrigins) {
7833 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7847 Size =
DL.getTypeAllocSize(
A->getType());
7853 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
7855 getOriginPtrForArgument(IRB, ArgOffset));
7867 if (FT->isVarArg()) {
7868 VAHelper->visitCallBase(CB, IRB);
7878 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
7879 setShadow(&CB, getCleanShadow(&CB));
7880 setOrigin(&CB, getCleanOrigin());
7886 Value *
Base = getShadowPtrForRetval(IRBBefore);
7887 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
7899 setShadow(&CB, getCleanShadow(&CB));
7900 setOrigin(&CB, getCleanOrigin());
7907 "Could not find insertion point for retval shadow load");
7910 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7913 setShadow(&CB, RetvalShadow);
7914 if (MS.TrackOrigins)
7915 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7920 RetVal =
I->getOperand(0);
7923 return I->isMustTailCall();
7928 void visitReturnInst(ReturnInst &
I) {
7930 Value *RetVal =
I.getReturnValue();
7936 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7937 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
7938 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7941 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
7943 Value *Shadow = getShadow(RetVal);
7944 bool StoreOrigin =
true;
7946 insertCheckShadowOf(RetVal, &
I);
7947 Shadow = getCleanShadow(RetVal);
7948 StoreOrigin =
false;
7955 if (MS.TrackOrigins && StoreOrigin)
7956 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7960 void visitPHINode(PHINode &
I) {
7962 if (!PropagateShadow) {
7963 setShadow(&
I, getCleanShadow(&
I));
7964 setOrigin(&
I, getCleanOrigin());
7968 ShadowPHINodes.push_back(&
I);
7969 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
7971 if (MS.TrackOrigins)
7973 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
7976 Value *getLocalVarIdptr(AllocaInst &
I) {
7977 ConstantInt *IntConst =
7978 ConstantInt::get(Type::getInt32Ty((*
F.getParent()).getContext()), 0);
7979 return new GlobalVariable(*
F.getParent(), IntConst->
getType(),
7984 Value *getLocalVarDescription(AllocaInst &
I) {
7989 if (PoisonStack && Opts.msan_poison_stack_with_call) {
7990 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7992 Value *ShadowBase, *OriginBase;
7993 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7996 Value *PoisonValue =
7997 IRB.
getInt8(PoisonStack ? Opts.msan_poison_stack_pattern : 0);
7998 IRB.
CreateMemSet(ShadowBase, PoisonValue, Len,
I.getAlign());
8001 if (PoisonStack && MS.TrackOrigins) {
8002 Value *Idptr = getLocalVarIdptr(
I);
8003 if (Opts.msan_print_stack_names) {
8004 Value *Descr = getLocalVarDescription(
I);
8005 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
8006 {&I, Len, Idptr, Descr});
8008 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
8014 Value *Descr = getLocalVarDescription(
I);
8016 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
8018 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
8022 void instrumentAlloca(AllocaInst &
I, Instruction *InsPoint =
nullptr) {
8025 NextNodeIRBuilder IRB(InsPoint);
8028 if (MS.CompileKernel)
8029 poisonAllocaKmsan(
I, IRB, Len);
8031 poisonAllocaUserspace(
I, IRB, Len);
8034 void visitAllocaInst(AllocaInst &
I) {
8035 setShadow(&
I, getCleanShadow(&
I));
8036 setOrigin(&
I, getCleanOrigin());
8042 void visitSelectInst(SelectInst &
I) {
8048 handleSelectLikeInst(
I,
B,
C,
D);
8054 Value *Sb = getShadow(
B);
8055 Value *Sc = getShadow(
C);
8056 Value *Sd = getShadow(
D);
8058 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
8059 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
8060 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
8065 if (
I.getType()->isAggregateType()) {
8069 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
8070 }
else if (isScalableNonVectorType(
I.getType())) {
8078 Sa1 = getCleanShadow(getShadowTy(
I.getType()));
8086 C = CreateAppToShadowCast(IRB,
C);
8087 D = CreateAppToShadowCast(IRB,
D);
8094 if (MS.TrackOrigins) {
8097 if (
B->getType()->isVectorTy()) {
8098 B = convertToBool(
B, IRB);
8099 Sb = convertToBool(Sb, IRB);
8107 void visitLandingPadInst(LandingPadInst &
I) {
8110 setShadow(&
I, getCleanShadow(&
I));
8111 setOrigin(&
I, getCleanOrigin());
8114 void visitCatchSwitchInst(CatchSwitchInst &
I) {
8115 setShadow(&
I, getCleanShadow(&
I));
8116 setOrigin(&
I, getCleanOrigin());
8119 void visitFuncletPadInst(FuncletPadInst &
I) {
8120 setShadow(&
I, getCleanShadow(&
I));
8121 setOrigin(&
I, getCleanOrigin());
8124 void visitGetElementPtrInst(GetElementPtrInst &
I) { handleShadowOr(
I); }
8126 void visitExtractValueInst(ExtractValueInst &
I) {
8128 Value *Agg =
I.getAggregateOperand();
8130 Value *AggShadow = getShadow(Agg);
8134 setShadow(&
I, ResShadow);
8135 setOriginForNaryOp(
I);
8138 void visitInsertValueInst(InsertValueInst &
I) {
8141 Value *AggShadow = getShadow(
I.getAggregateOperand());
8142 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
8148 setOriginForNaryOp(
I);
8151 void dumpInst(Instruction &
I,
const Twine &Prefix) {
8158 << CI->getCalledFunction()->
getName() <<
"\n";
8160 errs() <<
"ZZZ:" <<
Prefix <<
" " <<
I.getOpcodeName() <<
"\n";
8167 unsigned NumOperands =
I.getNumOperands();
8169 errs() <<
"YYY:" <<
Prefix <<
" call " << *
I.getType() <<
" @";
8181 errs() <<
"YYY:" <<
Prefix <<
" " << *
I.getType() <<
" "
8182 <<
I.getOpcodeName() <<
"(";
8184 for (
size_t i = 0; i < NumOperands; i++) {
8202 void visitResumeInst(ResumeInst &
I) {
8207 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
8212 void visitCatchReturnInst(CatchReturnInst &CRI) {
8217 void instrumentAsmArgument(
Value *Operand,
Type *ElemTy, Instruction &
I,
8226 insertCheckShadowOf(Operand, &
I);
8233 auto Size =
DL.getTypeStoreSize(ElemTy);
8235 if (MS.CompileKernel) {
8236 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
8242 auto [ShadowPtr,
_] =
8243 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
8253 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
8254 int NumRetOutputs = 0;
8261 NumRetOutputs =
ST->getNumElements();
8266 for (
const InlineAsm::ConstraintInfo &Info : Constraints) {
8267 switch (
Info.Type) {
8275 return NumOutputs - NumRetOutputs;
8278 void visitAsmInstruction(Instruction &
I) {
8294 const DataLayout &
DL =
F.getDataLayout();
8298 int OutputArgs = getNumOutputArgs(IA, CB);
8304 for (
int i = OutputArgs; i < NumOperands; i++) {
8312 for (
int i = 0; i < OutputArgs; i++) {
8318 setShadow(&
I, getCleanShadow(&
I));
8319 setOrigin(&
I, getCleanOrigin());
8322 void visitFreezeInst(FreezeInst &
I) {
8324 setShadow(&
I, getCleanShadow(&
I));
8325 setOrigin(&
I, getCleanOrigin());
8328 void visitInstruction(Instruction &
I) {
8330 if (Opts.msan_dump_strict_instructions)
8331 dumpInst(
I,
"Strict");
8333 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
8334 Value *Operand =
I.getOperand(i);
8336 insertCheckShadowOf(Operand, &
I);
8338 setShadow(&
I, getCleanShadow(&
I));
8339 setOrigin(&
I, getCleanOrigin());
8343struct VarArgHelperBase :
public VarArgHelper {
8345 MemorySanitizer &MS;
8346 MemorySanitizerVisitor &MSV;
8348 const unsigned VAListTagSize;
8350 VarArgHelperBase(
Function &
F, MemorySanitizer &MS,
8351 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
8352 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
8356 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
8371 return getShadowPtrForVAArgument(IRB, ArgOffset);
8384 unsigned BaseOffset) {
8393 TailSize,
Align(8));
8396 void unpoisonVAListTagForInst(IntrinsicInst &
I) {
8398 Value *VAListTag =
I.getArgOperand(0);
8400 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
8401 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
8404 VAListTagSize, Alignment,
false);
8407 void visitVAStartInst(VAStartInst &
I)
override {
8408 if (
F.getCallingConv() == CallingConv::Win64)
8411 unpoisonVAListTagForInst(
I);
8414 void visitVACopyInst(VACopyInst &
I)
override {
8415 if (
F.getCallingConv() == CallingConv::Win64)
8417 unpoisonVAListTagForInst(
I);
8422struct VarArgAMD64Helper :
public VarArgHelperBase {
8425 static const unsigned AMD64GpEndOffset = 48;
8426 static const unsigned AMD64FpEndOffsetSSE = 176;
8428 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8430 unsigned AMD64FpEndOffset;
8431 AllocaInst *VAArgTLSCopy =
nullptr;
8432 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8433 Value *VAArgOverflowSize =
nullptr;
8435 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8437 VarArgAMD64Helper(
Function &
F, MemorySanitizer &MS,
8438 MemorySanitizerVisitor &MSV)
8439 : VarArgHelperBase(
F, MS, MSV, 24) {
8440 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8441 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
8442 if (Attr.isStringAttribute() &&
8443 (Attr.getKindAsString() ==
"target-features")) {
8444 if (Attr.getValueAsString().contains(
"-sse"))
8445 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8451 ArgKind classifyArgument(
Value *arg) {
8454 if (
T->isX86_FP80Ty())
8456 if (
T->isFPOrFPVectorTy())
8457 return AK_FloatingPoint;
8458 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
8459 return AK_GeneralPurpose;
8460 if (
T->isPointerTy())
8461 return AK_GeneralPurpose;
8473 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8474 unsigned GpOffset = 0;
8475 unsigned FpOffset = AMD64GpEndOffset;
8476 unsigned OverflowOffset = AMD64FpEndOffset;
8477 const DataLayout &
DL =
F.getDataLayout();
8488 assert(
A->getType()->isPointerTy());
8490 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8492 unsigned BaseOffset = OverflowOffset;
8493 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8494 Value *OriginBase =
nullptr;
8495 if (MS.TrackOrigins)
8496 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8497 OverflowOffset += AlignedSize;
8500 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8504 Value *ShadowPtr, *OriginPtr;
8505 std::tie(ShadowPtr, OriginPtr) =
8510 if (MS.TrackOrigins)
8514 ArgKind AK = classifyArgument(
A);
8515 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8517 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8519 Value *ShadowBase, *OriginBase =
nullptr;
8521 case AK_GeneralPurpose:
8522 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8523 if (MS.TrackOrigins)
8524 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8528 case AK_FloatingPoint:
8529 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8530 if (MS.TrackOrigins)
8531 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8538 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8540 unsigned BaseOffset = OverflowOffset;
8541 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8542 if (MS.TrackOrigins) {
8543 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8545 OverflowOffset += AlignedSize;
8548 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8557 Value *Shadow = MSV.getShadow(
A);
8559 if (MS.TrackOrigins) {
8560 Value *Origin = MSV.getOrigin(
A);
8561 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8562 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8568 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8569 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8572 void finalizeInstrumentation()
override {
8573 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8574 "finalizeInstrumentation called twice");
8575 if (!VAStartInstrumentationList.
empty()) {
8582 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8583 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8589 Intrinsic::umin, CopySize,
8593 if (MS.TrackOrigins) {
8594 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8603 for (CallInst *OrigInst : VAStartInstrumentationList) {
8604 NextNodeIRBuilder IRB(OrigInst);
8605 Value *VAListTag = OrigInst->getArgOperand(0);
8607 Value *RegSaveAreaPtrPtr =
8610 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8612 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8613 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8615 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8617 if (MS.TrackOrigins)
8618 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8619 Alignment, AMD64FpEndOffset);
8620 Value *OverflowArgAreaPtrPtr =
8622 Value *OverflowArgAreaPtr =
8623 IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8624 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8625 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8626 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8630 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8632 if (MS.TrackOrigins) {
8635 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8643struct VarArgAArch64Helper :
public VarArgHelperBase {
8644 static const unsigned kAArch64GrArgSize = 64;
8645 static const unsigned kAArch64VrArgSize = 128;
8647 static const unsigned AArch64GrBegOffset = 0;
8648 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8650 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8651 static const unsigned AArch64VrEndOffset =
8652 AArch64VrBegOffset + kAArch64VrArgSize;
8653 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8655 AllocaInst *VAArgTLSCopy =
nullptr;
8656 Value *VAArgOverflowSize =
nullptr;
8658 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8660 VarArgAArch64Helper(
Function &
F, MemorySanitizer &MS,
8661 MemorySanitizerVisitor &MSV)
8662 : VarArgHelperBase(
F, MS, MSV, 32) {}
8665 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
8666 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
8667 return {AK_GeneralPurpose, 1};
8668 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
8669 return {AK_FloatingPoint, 1};
8671 if (
T->isArrayTy()) {
8672 auto R = classifyArgument(
T->getArrayElementType());
8673 R.second *=
T->getScalarType()->getArrayNumElements();
8678 auto R = classifyArgument(FV->getScalarType());
8679 R.second *= FV->getNumElements();
8684 return {AK_Memory, 0};
8696 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8697 unsigned GrOffset = AArch64GrBegOffset;
8698 unsigned VrOffset = AArch64VrBegOffset;
8699 unsigned OverflowOffset = AArch64VAEndOffset;
8701 const DataLayout &
DL =
F.getDataLayout();
8704 auto [AK, RegNum] = classifyArgument(
A->getType());
8705 if (AK == AK_GeneralPurpose &&
8706 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8708 if (AK == AK_FloatingPoint &&
8709 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8713 case AK_GeneralPurpose:
8714 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8715 GrOffset += 8 * RegNum;
8717 case AK_FloatingPoint:
8718 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8719 VrOffset += 16 * RegNum;
8726 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8728 unsigned BaseOffset = OverflowOffset;
8729 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8730 OverflowOffset += AlignedSize;
8733 CleanUnusedTLS(IRB,
Base, BaseOffset);
8745 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8746 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8751 Value *SaveAreaPtrPtr =
8753 return IRB.
CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8760 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
8763 void finalizeInstrumentation()
override {
8764 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8765 "finalizeInstrumentation called twice");
8766 if (!VAStartInstrumentationList.empty()) {
8773 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8774 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8780 Intrinsic::umin, CopySize,
8786 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8787 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8791 for (CallInst *OrigInst : VAStartInstrumentationList) {
8792 NextNodeIRBuilder IRB(OrigInst);
8794 Value *VAListTag = OrigInst->getArgOperand(0);
8811 Value *StackSaveAreaPtr =
8812 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8815 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8816 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8819 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8822 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8823 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8826 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8832 Value *GrRegSaveAreaShadowPtrOff =
8833 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
8835 Value *GrRegSaveAreaShadowPtr =
8836 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8842 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8848 Value *VrRegSaveAreaShadowPtrOff =
8849 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
8851 Value *VrRegSaveAreaShadowPtr =
8852 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8859 VrRegSaveAreaShadowPtrOff);
8860 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8866 Value *StackSaveAreaShadowPtr =
8867 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8875 Align(16), VAArgOverflowSize);
8881struct VarArgPowerPC64Helper :
public VarArgHelperBase {
8882 AllocaInst *VAArgTLSCopy =
nullptr;
8883 Value *VAArgSize =
nullptr;
8885 VarArgPowerPC64Helper(
Function &
F, MemorySanitizer &MS,
8886 MemorySanitizerVisitor &MSV)
8887 : VarArgHelperBase(
F, MS, MSV, 8) {}
8889 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8897 Triple TargetTriple(
F.getParent()->getTargetTriple());
8901 if (TargetTriple.isPPC64ELFv2ABI())
8905 unsigned VAArgOffset = VAArgBase;
8906 const DataLayout &
DL =
F.getDataLayout();
8911 assert(
A->getType()->isPointerTy());
8913 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8916 ArgAlign =
Align(8);
8917 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8920 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8922 Value *AShadowPtr, *AOriginPtr;
8923 std::tie(AShadowPtr, AOriginPtr) =
8924 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8934 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8936 if (
A->getType()->isArrayTy()) {
8939 Type *ElementTy =
A->getType()->getArrayElementType();
8941 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8942 }
else if (
A->getType()->isVectorTy()) {
8944 ArgAlign =
Align(ArgSize);
8947 ArgAlign =
Align(8);
8948 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8949 if (
DL.isBigEndian()) {
8953 VAArgOffset += (8 - ArgSize);
8957 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8961 VAArgOffset += ArgSize;
8965 VAArgBase = VAArgOffset;
8969 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8972 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8975 void finalizeInstrumentation()
override {
8976 assert(!VAArgSize && !VAArgTLSCopy &&
8977 "finalizeInstrumentation called twice");
8980 Value *CopySize = VAArgSize;
8982 if (!VAStartInstrumentationList.empty()) {
8986 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8992 Intrinsic::umin, CopySize,
9000 for (CallInst *OrigInst : VAStartInstrumentationList) {
9001 NextNodeIRBuilder IRB(OrigInst);
9002 Value *VAListTag = OrigInst->getArgOperand(0);
9005 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9008 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9009 const DataLayout &
DL =
F.getDataLayout();
9010 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9012 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9013 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9015 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9022struct VarArgPowerPC32Helper :
public VarArgHelperBase {
9023 AllocaInst *VAArgTLSCopy =
nullptr;
9024 Value *VAArgSize =
nullptr;
9026 VarArgPowerPC32Helper(
Function &
F, MemorySanitizer &MS,
9027 MemorySanitizerVisitor &MSV)
9028 : VarArgHelperBase(
F, MS, MSV, 12) {}
9030 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9034 unsigned VAArgOffset = VAArgBase;
9035 const DataLayout &
DL =
F.getDataLayout();
9036 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9041 assert(
A->getType()->isPointerTy());
9043 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9045 if (ArgAlign < IntptrSize)
9046 ArgAlign =
Align(IntptrSize);
9047 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9050 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
9052 Value *AShadowPtr, *AOriginPtr;
9053 std::tie(AShadowPtr, AOriginPtr) =
9054 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9064 Type *ArgTy =
A->getType();
9070 uint64_t ArgSize =
DL.getTypeAllocSize(ArgTy);
9077 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
9080 ArgAlign =
Align(ArgSize);
9082 if (ArgAlign < IntptrSize)
9083 ArgAlign =
Align(IntptrSize);
9084 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9085 if (
DL.isBigEndian()) {
9088 if (ArgSize < IntptrSize)
9089 VAArgOffset += (IntptrSize - ArgSize);
9092 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
9098 VAArgOffset += ArgSize;
9105 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
9108 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9111 void finalizeInstrumentation()
override {
9112 assert(!VAArgSize && !VAArgTLSCopy &&
9113 "finalizeInstrumentation called twice");
9115 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9116 Value *CopySize = VAArgSize;
9118 if (!VAStartInstrumentationList.empty()) {
9122 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9128 Intrinsic::umin, CopySize,
9136 for (CallInst *OrigInst : VAStartInstrumentationList) {
9137 NextNodeIRBuilder IRB(OrigInst);
9138 Value *VAListTag = OrigInst->getArgOperand(0);
9140 Value *RegSaveAreaSize = CopySize;
9144 IRB.
CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
9148 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
9150 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9153 const DataLayout &
DL =
F.getDataLayout();
9154 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9158 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9159 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9160 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9162 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
9163 Alignment, RegSaveAreaSize);
9165 RegSaveAreaShadowPtr =
9168 ConstantInt::get(MS.IntptrTy, 32));
9173 ConstantInt::get(MS.IntptrTy, 32), Alignment);
9178 Value *OverflowAreaSize = IRB.
CreateSub(CopySize, RegSaveAreaSize);
9181 OverflowAreaPtrPtr =
9182 IRB.
CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
9183 OverflowAreaPtrPtr = IRB.
CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
9185 Value *OverflowAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
9187 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
9188 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
9189 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.
getInt8Ty(),
9192 Value *OverflowVAArgTLSCopyPtr =
9194 OverflowVAArgTLSCopyPtr =
9195 IRB.
CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
9197 OverflowVAArgTLSCopyPtr =
9200 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
9207struct VarArgSystemZHelper :
public VarArgHelperBase {
9208 static const unsigned SystemZGpOffset = 16;
9209 static const unsigned SystemZGpEndOffset = 56;
9210 static const unsigned SystemZFpOffset = 128;
9211 static const unsigned SystemZFpEndOffset = 160;
9212 static const unsigned SystemZMaxVrArgs = 8;
9213 static const unsigned SystemZRegSaveAreaSize = 160;
9214 static const unsigned SystemZOverflowOffset = 160;
9215 static const unsigned SystemZVAListTagSize = 32;
9216 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
9217 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
9219 bool IsSoftFloatABI;
9220 AllocaInst *VAArgTLSCopy =
nullptr;
9221 AllocaInst *VAArgTLSOriginCopy =
nullptr;
9222 Value *VAArgOverflowSize =
nullptr;
9224 enum class ArgKind {
9234 VarArgSystemZHelper(
Function &
F, MemorySanitizer &MS,
9235 MemorySanitizerVisitor &MSV)
9236 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
9237 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
9239 ArgKind classifyArgument(
Type *
T) {
9246 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
9247 return ArgKind::Indirect;
9248 if (
T->isFloatingPointTy())
9249 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
9250 if (
T->isIntegerTy() ||
T->isPointerTy())
9251 return ArgKind::GeneralPurpose;
9252 if (
T->isVectorTy())
9253 return ArgKind::Vector;
9254 return ArgKind::Memory;
9257 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
9267 return ShadowExtension::Zero;
9271 return ShadowExtension::Sign;
9273 return ShadowExtension::None;
9276 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9277 unsigned GpOffset = SystemZGpOffset;
9278 unsigned FpOffset = SystemZFpOffset;
9279 unsigned VrIndex = 0;
9280 unsigned OverflowOffset = SystemZOverflowOffset;
9281 const DataLayout &
DL =
F.getDataLayout();
9287 ArgKind AK = classifyArgument(
T);
9288 if (AK == ArgKind::Indirect) {
9290 AK = ArgKind::GeneralPurpose;
9292 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
9293 AK = ArgKind::Memory;
9294 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
9295 AK = ArgKind::Memory;
9296 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
9297 AK = ArgKind::Memory;
9298 Value *ShadowBase =
nullptr;
9299 Value *OriginBase =
nullptr;
9300 ShadowExtension SE = ShadowExtension::None;
9302 case ArgKind::GeneralPurpose: {
9307 SE = getShadowExtension(CB, ArgNo);
9309 if (SE == ShadowExtension::None) {
9311 assert(ArgAllocSize <= ArgSize);
9312 GapSize = ArgSize - ArgAllocSize;
9314 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
9315 if (MS.TrackOrigins)
9316 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
9318 GpOffset += ArgSize;
9324 case ArgKind::FloatingPoint: {
9333 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
9334 if (MS.TrackOrigins)
9335 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
9337 FpOffset += ArgSize;
9343 case ArgKind::Vector: {
9350 case ArgKind::Memory: {
9358 SE = getShadowExtension(CB, ArgNo);
9360 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
9362 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
9363 if (MS.TrackOrigins)
9365 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
9366 OverflowOffset += ArgSize;
9373 case ArgKind::Indirect:
9376 if (ShadowBase ==
nullptr)
9378 Value *Shadow = MSV.getShadow(
A);
9379 if (SE != ShadowExtension::None)
9380 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
9381 SE == ShadowExtension::Sign);
9382 ShadowBase = IRB.
CreateIntToPtr(ShadowBase, MS.PtrTy,
"_msarg_va_s");
9384 if (MS.TrackOrigins) {
9385 Value *Origin = MSV.getOrigin(
A);
9386 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
9387 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
9391 Constant *OverflowSize = ConstantInt::get(
9392 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
9393 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
9400 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
9403 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9405 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9406 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
9411 unsigned RegSaveAreaSize =
9412 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9413 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9415 if (MS.TrackOrigins)
9416 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9417 Alignment, RegSaveAreaSize);
9426 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9428 Value *OverflowArgAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9429 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9431 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9432 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
9435 SystemZOverflowOffset);
9436 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9438 if (MS.TrackOrigins) {
9440 SystemZOverflowOffset);
9441 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9446 void finalizeInstrumentation()
override {
9447 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9448 "finalizeInstrumentation called twice");
9449 if (!VAStartInstrumentationList.empty()) {
9456 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9458 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9464 Intrinsic::umin, CopySize,
9468 if (MS.TrackOrigins) {
9469 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9478 for (CallInst *OrigInst : VAStartInstrumentationList) {
9479 NextNodeIRBuilder IRB(OrigInst);
9480 Value *VAListTag = OrigInst->getArgOperand(0);
9481 copyRegSaveArea(IRB, VAListTag);
9482 copyOverflowArea(IRB, VAListTag);
9488struct VarArgI386Helper :
public VarArgHelperBase {
9489 AllocaInst *VAArgTLSCopy =
nullptr;
9490 Value *VAArgSize =
nullptr;
9492 VarArgI386Helper(
Function &
F, MemorySanitizer &MS,
9493 MemorySanitizerVisitor &MSV)
9494 : VarArgHelperBase(
F, MS, MSV, 4) {}
9496 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9497 const DataLayout &
DL =
F.getDataLayout();
9498 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9499 unsigned VAArgOffset = 0;
9504 assert(
A->getType()->isPointerTy());
9506 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9508 if (ArgAlign < IntptrSize)
9509 ArgAlign =
Align(IntptrSize);
9510 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9512 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9514 Value *AShadowPtr, *AOriginPtr;
9515 std::tie(AShadowPtr, AOriginPtr) =
9516 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9526 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9528 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9529 if (
DL.isBigEndian()) {
9532 if (ArgSize < IntptrSize)
9533 VAArgOffset += (IntptrSize - ArgSize);
9536 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9539 VAArgOffset += ArgSize;
9545 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9548 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9551 void finalizeInstrumentation()
override {
9552 assert(!VAArgSize && !VAArgTLSCopy &&
9553 "finalizeInstrumentation called twice");
9555 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9556 Value *CopySize = VAArgSize;
9558 if (!VAStartInstrumentationList.empty()) {
9561 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9567 Intrinsic::umin, CopySize,
9575 for (CallInst *OrigInst : VAStartInstrumentationList) {
9576 NextNodeIRBuilder IRB(OrigInst);
9577 Value *VAListTag = OrigInst->getArgOperand(0);
9578 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9579 Value *RegSaveAreaPtrPtr =
9581 PointerType::get(*MS.C, 0));
9582 Value *RegSaveAreaPtr =
9583 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9584 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9585 const DataLayout &
DL =
F.getDataLayout();
9586 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9588 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9589 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9591 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9599struct VarArgGenericHelper :
public VarArgHelperBase {
9600 AllocaInst *VAArgTLSCopy =
nullptr;
9601 Value *VAArgSize =
nullptr;
9603 VarArgGenericHelper(
Function &
F, MemorySanitizer &MS,
9604 MemorySanitizerVisitor &MSV,
const unsigned VAListTagSize)
9605 : VarArgHelperBase(
F, MS, MSV, VAListTagSize) {}
9607 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9608 unsigned VAArgOffset = 0;
9609 const DataLayout &
DL =
F.getDataLayout();
9610 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9615 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9616 if (
DL.isBigEndian()) {
9619 if (ArgSize < IntptrSize)
9620 VAArgOffset += (IntptrSize - ArgSize);
9622 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9623 VAArgOffset += ArgSize;
9624 VAArgOffset =
alignTo(VAArgOffset, IntptrSize);
9630 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9633 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9636 void finalizeInstrumentation()
override {
9637 assert(!VAArgSize && !VAArgTLSCopy &&
9638 "finalizeInstrumentation called twice");
9640 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9641 Value *CopySize = VAArgSize;
9643 if (!VAStartInstrumentationList.empty()) {
9646 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9652 Intrinsic::umin, CopySize,
9660 for (CallInst *OrigInst : VAStartInstrumentationList) {
9661 NextNodeIRBuilder IRB(OrigInst);
9662 Value *VAListTag = OrigInst->getArgOperand(0);
9663 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9664 Value *RegSaveAreaPtrPtr =
9666 PointerType::get(*MS.C, 0));
9667 Value *RegSaveAreaPtr =
9668 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9669 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9670 const DataLayout &
DL =
F.getDataLayout();
9671 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9673 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9674 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9676 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9684using VarArgARM32Helper = VarArgGenericHelper;
9685using VarArgRISCVHelper = VarArgGenericHelper;
9686using VarArgMIPSHelper = VarArgGenericHelper;
9687using VarArgLoongArch64Helper = VarArgGenericHelper;
9688using VarArgHexagonHelper = VarArgGenericHelper;
9691struct VarArgNoOpHelper :
public VarArgHelper {
9692 VarArgNoOpHelper(
Function &
F, MemorySanitizer &MS,
9693 MemorySanitizerVisitor &MSV) {}
9695 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {}
9697 void visitVAStartInst(VAStartInst &
I)
override {}
9699 void visitVACopyInst(VACopyInst &
I)
override {}
9701 void finalizeInstrumentation()
override {}
9707 MemorySanitizerVisitor &Visitor) {
9710 Triple TargetTriple(Func.getParent()->getTargetTriple());
9713 return new VarArgI386Helper(Func, Msan, Visitor);
9716 return new VarArgAMD64Helper(Func, Msan, Visitor);
9718 if (TargetTriple.
isARM())
9719 return new VarArgARM32Helper(Func, Msan, Visitor, 4);
9722 return new VarArgAArch64Helper(Func, Msan, Visitor);
9725 return new VarArgSystemZHelper(Func, Msan, Visitor);
9730 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9733 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9736 return new VarArgRISCVHelper(Func, Msan, Visitor, 4);
9739 return new VarArgRISCVHelper(Func, Msan, Visitor, 8);
9742 return new VarArgMIPSHelper(Func, Msan, Visitor, 4);
9745 return new VarArgMIPSHelper(Func, Msan, Visitor, 8);
9748 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9752 return new VarArgHexagonHelper(Func, Msan, Visitor, 12);
9754 return new VarArgNoOpHelper(Func, Msan, Visitor);
9761 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9764 MemorySanitizerVisitor Visitor(
F, *
this,
TLI);
9771 return Visitor.runOnFunction();
const TargetLowering & TLI
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
SmallVector< MachineOperand, 4 > 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)
unsigned countr_zero() const
Count the number of trailing zero bits.
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.
size_t size() const
Get the array size.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
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.
static GEPNoWrapFlags inBounds()
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 * CreatePtrAddWithUnsignedOffset(Value *Ptr, uint64_t Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Create a ptradd with an unsigned constant offset.
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.
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.
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)