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) {
3009 insertCheckShadowOf(
I.getOperand(1), &
I);
3010 setShadow(&
I, getShadow(&
I, 0));
3011 setOrigin(&
I, getOrigin(&
I, 0));
3014 void visitUDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3015 void visitSDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3016 void visitURem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3017 void visitSRem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3021 void visitFDiv(BinaryOperator &
I) { handleShadowOr(
I); }
3022 void visitFRem(BinaryOperator &
I) { handleShadowOr(
I); }
3028 void handleEqualityComparison(ICmpInst &
I) {
3032 Value *Sa = getShadow(
A);
3033 Value *Sb = getShadow(
B);
3035 Value *Si = propagateEqualityComparison(IRB,
A,
B, Sa, Sb);
3038 setOriginForNaryOp(
I);
3046 void handleRelationalComparisonExact(ICmpInst &
I) {
3050 Value *Sa = getShadow(
A);
3051 Value *Sb = getShadow(
B);
3062 bool IsSigned =
I.isSigned();
3064 auto GetMinMaxUnsigned = [&](
Value *
V,
Value *S) {
3074 V = IRB.
CreateXor(
V, ConstantInt::get(
V->getType(), MinVal));
3079 return std::make_pair(Min, Max);
3082 auto [Amin, Amax] = GetMinMaxUnsigned(
A, Sa);
3083 auto [Bmin, Bmax] = GetMinMaxUnsigned(
B, Sb);
3089 setOriginForNaryOp(
I);
3096 void handleSignedRelationalComparison(ICmpInst &
I) {
3101 op =
I.getOperand(0);
3102 pre =
I.getPredicate();
3104 op =
I.getOperand(1);
3105 pre =
I.getSwappedPredicate();
3118 setShadow(&
I, Shadow);
3119 setOrigin(&
I, getOrigin(
op));
3125 void visitICmpInst(ICmpInst &
I) {
3126 if (!Opts.msan_handle_icmp) {
3130 if (
I.isEquality()) {
3131 handleEqualityComparison(
I);
3136 if (Opts.msan_handle_icmp_exact) {
3137 handleRelationalComparisonExact(
I);
3141 handleSignedRelationalComparison(
I);
3147 handleRelationalComparisonExact(
I);
3154 void visitFCmpInst(FCmpInst &
I) { handleShadowOr(
I); }
3156 void handleShift(BinaryOperator &
I) {
3161 Value *S2 = getShadow(&
I, 1);
3164 Value *V2 =
I.getOperand(1);
3166 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3167 setOriginForNaryOp(
I);
3170 void visitShl(BinaryOperator &
I) { handleShift(
I); }
3171 void visitAShr(BinaryOperator &
I) { handleShift(
I); }
3172 void visitLShr(BinaryOperator &
I) { handleShift(
I); }
3174 void handleFunnelShift(IntrinsicInst &
I) {
3178 Value *S0 = getShadow(&
I, 0);
3180 Value *S2 = getShadow(&
I, 2);
3183 Value *V2 =
I.getOperand(2);
3186 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3187 setOriginForNaryOp(
I);
3195 void handleGenericBitManipulation(IntrinsicInst &
I) {
3197 Type *ShadowTy = getShadowTy(&
I);
3200 Value *SMask = getShadow(&
I, 1);
3205 if (
Function *Func =
I.getCalledFunction())
3206 S = IRB.
CreateCall(Func, {getShadow(&
I, 0),
I.getOperand(1)});
3209 {getShadow(&I, 0), I.getOperand(1)});
3212 setOriginForNaryOp(
I);
3225 void visitMemMoveInst(MemMoveInst &
I) {
3226 getShadow(
I.getArgOperand(1));
3229 {I.getArgOperand(0), I.getArgOperand(1),
3230 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3248 void visitMemCpyInst(MemCpyInst &
I) {
3249 getShadow(
I.getArgOperand(1));
3252 {I.getArgOperand(0), I.getArgOperand(1),
3253 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3258 void visitMemSetInst(MemSetInst &
I) {
3262 {I.getArgOperand(0),
3263 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3264 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3268 void visitVAStartInst(VAStartInst &
I) { VAHelper->visitVAStartInst(
I); }
3270 void visitVACopyInst(VACopyInst &
I) { VAHelper->visitVACopyInst(
I); }
3276 bool handleVectorStoreIntrinsic(IntrinsicInst &
I) {
3280 Value *Addr =
I.getArgOperand(0);
3281 Value *Shadow = getShadow(&
I, 1);
3282 Value *ShadowPtr, *OriginPtr;
3286 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3290 if (Opts.msan_check_access_address)
3291 insertCheckShadowOf(Addr, &
I);
3294 if (MS.TrackOrigins)
3303 bool handleVectorLoadIntrinsic(IntrinsicInst &
I) {
3307 Value *Addr =
I.getArgOperand(0);
3309 Type *ShadowTy = getShadowTy(&
I);
3310 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
3311 if (PropagateShadow) {
3315 std::tie(ShadowPtr, OriginPtr) =
3316 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
3320 setShadow(&
I, getCleanShadow(&
I));
3323 if (Opts.msan_check_access_address)
3324 insertCheckShadowOf(Addr, &
I);
3326 if (MS.TrackOrigins) {
3327 if (PropagateShadow)
3328 setOrigin(&
I, IRB.
CreateLoad(MS.OriginTy, OriginPtr));
3330 setOrigin(&
I, getCleanOrigin());
3350 [[maybe_unused]]
bool
3351 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &
I,
3352 unsigned int trailingFlags) {
3353 Type *RetTy =
I.getType();
3357 unsigned NumArgOperands =
I.arg_size();
3358 assert(NumArgOperands >= trailingFlags);
3359 for (
unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3360 Type *Ty =
I.getArgOperand(i)->getType();
3366 ShadowAndOriginCombiner SC(
this, IRB);
3367 for (
unsigned i = 0; i < NumArgOperands; ++i)
3368 SC.Add(
I.getArgOperand(i));
3385 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &
I) {
3386 unsigned NumArgOperands =
I.arg_size();
3387 if (NumArgOperands == 0)
3390 if (NumArgOperands == 2 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3391 I.getArgOperand(1)->getType()->isVectorTy() &&
3392 I.getType()->isVoidTy() && !
I.onlyReadsMemory()) {
3394 return handleVectorStoreIntrinsic(
I);
3397 if (NumArgOperands == 1 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3398 I.getType()->isVectorTy() &&
I.onlyReadsMemory()) {
3400 return handleVectorLoadIntrinsic(
I);
3403 if (
I.doesNotAccessMemory())
3404 if (maybeHandleSimpleNomemIntrinsic(
I, 0))
3412 bool maybeHandleUnknownIntrinsic(IntrinsicInst &
I) {
3413 if (maybeHandleUnknownIntrinsicUnlogged(
I)) {
3414 if (Opts.msan_dump_heuristic_instructions)
3415 dumpInst(
I,
"Heuristic");
3417 LLVM_DEBUG(
dbgs() <<
"UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " <<
I
3424 void handleInvariantGroup(IntrinsicInst &
I) {
3425 setShadow(&
I, getShadow(&
I, 0));
3426 setOrigin(&
I, getOrigin(&
I, 0));
3429 void handleLifetimeStart(IntrinsicInst &
I) {
3434 LifetimeStartList.push_back(std::make_pair(&
I, AI));
3437 void handleBswap(IntrinsicInst &
I) {
3440 Type *OpType =
Op->getType();
3443 setOrigin(&
I, getOrigin(
Op));
3464 void handleCountLeadingTrailingZeros(IntrinsicInst &
I) {
3466 Value *Src =
I.getArgOperand(0);
3467 Value *SrcShadow = getShadow(Src);
3471 I.getType(),
I.getIntrinsicID(), {Src, False});
3473 I.getType(),
I.getIntrinsicID(), {SrcShadow, False});
3476 ConcreteZerosCount, ShadowZerosCount,
"_mscz_cmp_zeros");
3478 Value *NotAllZeroShadow =
3480 Value *OutputShadow =
3481 IRB.
CreateAnd(CompareConcreteZeros, NotAllZeroShadow,
"_mscz_main");
3487 OutputShadow = IRB.
CreateOr(OutputShadow, BoolZeroPoison,
"_mscz_bs");
3490 OutputShadow = IRB.
CreateSExt(OutputShadow, getShadowTy(Src),
"_mscz_os");
3492 setShadow(&
I, OutputShadow);
3493 setOriginForNaryOp(
I);
3502 FixedVectorType *maybeShrinkVectorShadowType(
Value *Src, IntrinsicInst &
I) {
3522 Value *maybeExtendVectorShadowWithZeros(
Value *Shadow, IntrinsicInst &
I) {
3527 Value *FullShadow = getCleanShadow(&
I);
3528 unsigned ShadowNumElems =
3530 unsigned FullShadowNumElems =
3533 assert((ShadowNumElems == FullShadowNumElems) ||
3534 (ShadowNumElems * 2 == FullShadowNumElems));
3536 if (ShadowNumElems == FullShadowNumElems) {
3537 FullShadow = Shadow;
3541 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3566 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &
I,
3567 bool HasRoundingMode) {
3568 if (HasRoundingMode) {
3576 Value *Src =
I.getArgOperand(0);
3577 assert(Src->getType()->isVectorTy());
3581 VectorType *ShadowType = maybeShrinkVectorShadowType(Src,
I);
3584 Value *S0 = getShadow(&
I, 0);
3596 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow,
I);
3598 setShadow(&
I, FullShadow);
3599 setOriginForNaryOp(
I);
3620 void handleSSEVectorConvertIntrinsic(IntrinsicInst &
I,
int NumUsedElements,
3621 bool HasRoundingMode =
false) {
3623 Value *CopyOp, *ConvertOp;
3625 assert((!HasRoundingMode ||
3627 "Invalid rounding mode");
3629 switch (
I.arg_size() - HasRoundingMode) {
3631 CopyOp =
I.getArgOperand(0);
3632 ConvertOp =
I.getArgOperand(1);
3635 ConvertOp =
I.getArgOperand(0);
3649 Value *ConvertShadow = getShadow(ConvertOp);
3650 Value *AggShadow =
nullptr;
3653 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
3654 for (
int i = 1; i < NumUsedElements; ++i) {
3656 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
3657 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
3660 AggShadow = ConvertShadow;
3663 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &
I);
3670 Value *ResultShadow = getShadow(CopyOp);
3672 for (
int i = 0; i < NumUsedElements; ++i) {
3674 ResultShadow, ConstantInt::getNullValue(EltTy),
3677 setShadow(&
I, ResultShadow);
3678 setOrigin(&
I, getOrigin(CopyOp));
3680 setShadow(&
I, getCleanShadow(&
I));
3681 setOrigin(&
I, getCleanOrigin());
3689 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
3692 return CreateShadowCast(IRB, S2,
T,
true);
3700 return CreateShadowCast(IRB, S2,
T,
true);
3717 void handleVectorShiftIntrinsic(IntrinsicInst &
I,
bool Variable) {
3723 Value *S2 = getShadow(&
I, 1);
3725 : Lower64ShadowExtend(IRB, S2, getShadowTy(&
I));
3727 Value *V2 =
I.getOperand(1);
3729 {IRB.CreateBitCast(S1, V1->getType()), V2});
3731 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3732 setOriginForNaryOp(
I);
3737 Type *getMMXVectorTy(
unsigned EltSizeInBits,
3738 unsigned X86_MMXSizeInBits = 64) {
3739 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3740 "Illegal MMX vector element size");
3742 X86_MMXSizeInBits / EltSizeInBits);
3749 case Intrinsic::x86_sse2_packsswb_128:
3750 case Intrinsic::x86_sse2_packuswb_128:
3751 return Intrinsic::x86_sse2_packsswb_128;
3753 case Intrinsic::x86_sse2_packssdw_128:
3754 case Intrinsic::x86_sse41_packusdw:
3755 return Intrinsic::x86_sse2_packssdw_128;
3757 case Intrinsic::x86_avx2_packsswb:
3758 case Intrinsic::x86_avx2_packuswb:
3759 return Intrinsic::x86_avx2_packsswb;
3761 case Intrinsic::x86_avx2_packssdw:
3762 case Intrinsic::x86_avx2_packusdw:
3763 return Intrinsic::x86_avx2_packssdw;
3765 case Intrinsic::x86_mmx_packsswb:
3766 case Intrinsic::x86_mmx_packuswb:
3767 return Intrinsic::x86_mmx_packsswb;
3769 case Intrinsic::x86_mmx_packssdw:
3770 return Intrinsic::x86_mmx_packssdw;
3772 case Intrinsic::x86_avx512_packssdw_512:
3773 case Intrinsic::x86_avx512_packusdw_512:
3774 return Intrinsic::x86_avx512_packssdw_512;
3776 case Intrinsic::x86_avx512_packsswb_512:
3777 case Intrinsic::x86_avx512_packuswb_512:
3778 return Intrinsic::x86_avx512_packsswb_512;
3794 void handleVectorPackIntrinsic(IntrinsicInst &
I,
3795 unsigned MMXEltSizeInBits = 0) {
3799 Value *S2 = getShadow(&
I, 1);
3800 assert(
S1->getType()->isVectorTy());
3806 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) :
S1->
getType();
3807 if (MMXEltSizeInBits) {
3815 if (MMXEltSizeInBits) {
3821 {S1_ext, S2_ext},
nullptr,
3822 "_msprop_vector_pack");
3823 if (MMXEltSizeInBits)
3826 setOriginForNaryOp(
I);
3830 Constant *createDppMask(
unsigned Width,
unsigned Mask) {
3831 SmallVector<Constant *, 4>
R(Width);
3843 const unsigned Width =
3850 Value *DstMaskV = createDppMask(Width, DstMask);
3867 void handleDppIntrinsic(IntrinsicInst &
I) {
3870 Value *S0 = getShadow(&
I, 0);
3874 const unsigned Width =
3876 assert(Width == 2 || Width == 4 || Width == 8);
3879 const unsigned SrcMask =
Mask >> 4;
3880 const unsigned DstMask =
Mask & 0xf;
3883 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3888 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3895 setOriginForNaryOp(
I);
3899 C = CreateAppToShadowCast(IRB,
C);
3908 void handleBlendvIntrinsic(IntrinsicInst &
I) {
3913 Value *Sc = getShadow(&
I, 2);
3914 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
3919 C = convertBlendvToSelectMask(IRB,
C);
3920 Sc = convertBlendvToSelectMask(IRB, Sc);
3926 handleSelectLikeInst(
I,
C,
T,
F);
3930 void handleVectorSadIntrinsic(IntrinsicInst &
I,
bool IsMMX =
false) {
3931 const unsigned SignificantBitsPerResultElement = 16;
3933 unsigned ZeroBitsPerResultElement =
3937 auto *Shadow0 = getShadow(&
I, 0);
3938 auto *Shadow1 = getShadow(&
I, 1);
3943 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
3946 setOriginForNaryOp(
I);
3970 void handleVectorDotProductIntrinsic(IntrinsicInst &
I,
3971 unsigned ReductionFactor,
3973 unsigned EltSizeInBits,
3977 [[maybe_unused]] FixedVectorType *
ReturnType =
3982 Value *Va =
nullptr;
3983 Value *Vb =
nullptr;
3984 Value *Sa =
nullptr;
3985 Value *Sb =
nullptr;
3987 assert(
I.arg_size() == 2 ||
I.arg_size() == 3);
3988 if (
I.arg_size() == 2) {
3991 Va =
I.getOperand(0);
3992 Vb =
I.getOperand(1);
3994 Sa = getShadow(&
I, 0);
3995 Sb = getShadow(&
I, 1);
3996 }
else if (
I.arg_size() == 3) {
3998 Va =
I.getOperand(1);
3999 Vb =
I.getOperand(2);
4001 Sa = getShadow(&
I, 1);
4002 Sb = getShadow(&
I, 2);
4019 Sa, getPclmulMask(Width, Lanes ==
kOddLanes));
4021 Sb, getPclmulMask(Width, Lanes ==
kOddLanes));
4031 if (
I.arg_size() == 3) {
4032 [[maybe_unused]]
auto *AccumulatorType =
4034 assert(AccumulatorType == ReturnType);
4037 FixedVectorType *ImplicitReturnType =
4040 if (EltSizeInBits) {
4042 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4054 ReturnType->getNumElements() * ReductionFactor);
4071 VaInt = CreateAppToShadowCast(IRB, Va);
4072 VbInt = CreateAppToShadowCast(IRB, Vb);
4079 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4101 ImplicitReturnType);
4106 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&
I));
4109 if (
I.arg_size() == 3)
4110 OutShadow = IRB.
CreateOr(OutShadow, getShadow(&
I, 0));
4112 setShadow(&
I, OutShadow);
4113 setOriginForNaryOp(
I);
4130 void handleVectorComparePackedIntrinsic(IntrinsicInst &
I,
4131 bool PredicateAsOperand) {
4132 if (PredicateAsOperand) {
4134 assert(
I.paramHasAttr(2, Attribute::ImmArg));
4142 Type *ResTy = getShadowTy(&
I);
4143 auto *Shadow0 = getShadow(&
I, 0);
4144 auto *Shadow1 = getShadow(&
I, 1);
4149 setOriginForNaryOp(
I);
4155 void handleVectorCompareScalarIntrinsic(IntrinsicInst &
I) {
4157 auto *Shadow0 = getShadow(&
I, 0);
4158 auto *Shadow1 = getShadow(&
I, 1);
4160 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&
I));
4162 setOriginForNaryOp(
I);
4171 void handleVectorReduceIntrinsic(IntrinsicInst &
I,
bool AllowShadowCast) {
4176 if (AllowShadowCast)
4177 S = CreateShadowCast(IRB, S, getShadowTy(&
I));
4181 setOriginForNaryOp(
I);
4191 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &
I) {
4195 Value *Shadow0 = getShadow(&
I, 0);
4201 setOriginForNaryOp(
I);
4221 void handleVectorPartialReduceAddIntrinsic(IntrinsicInst &
I) {
4226 [[maybe_unused]]
Value *Addends =
I.getArgOperand(1);
4240 Value *SAcc = getShadow(&
I, 0);
4241 Value *SAdd = getShadow(&
I, 1);
4261 SAcc->
getType(), Intrinsic::vector_partial_reduce_add, {SAcc, SAdd});
4266 setShadow(&
I, SOutput);
4267 setOriginForNaryOp(
I);
4273 void handleVectorReduceOrIntrinsic(IntrinsicInst &
I) {
4277 Value *OperandShadow = getShadow(&
I, 0);
4279 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
4287 setOrigin(&
I, getOrigin(&
I, 0));
4293 void handleVectorReduceAndIntrinsic(IntrinsicInst &
I) {
4297 Value *OperandShadow = getShadow(&
I, 0);
4298 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
4306 setOrigin(&
I, getOrigin(&
I, 0));
4309 void handleStmxcsr(IntrinsicInst &
I) {
4311 Value *Addr =
I.getArgOperand(0);
4314 getShadowOriginPtr(Addr, IRB, Ty,
Align(1),
true).first;
4318 if (Opts.msan_check_access_address)
4319 insertCheckShadowOf(Addr, &
I);
4322 void handleLdmxcsr(IntrinsicInst &
I) {
4327 Value *Addr =
I.getArgOperand(0);
4330 Value *ShadowPtr, *OriginPtr;
4331 std::tie(ShadowPtr, OriginPtr) =
4332 getShadowOriginPtr(Addr, IRB, Ty, Alignment,
false);
4334 if (Opts.msan_check_access_address)
4335 insertCheckShadowOf(Addr, &
I);
4338 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
4340 insertCheckShadow(Shadow, Origin, &
I);
4343 void handleMaskedExpandLoad(IntrinsicInst &
I) {
4345 Value *Ptr =
I.getArgOperand(0);
4346 MaybeAlign
Align =
I.getParamAlign(0);
4348 Value *PassThru =
I.getArgOperand(2);
4350 if (Opts.msan_check_access_address) {
4351 insertCheckShadowOf(Ptr, &
I);
4352 insertCheckShadowOf(Mask, &
I);
4355 if (!PropagateShadow) {
4356 setShadow(&
I, getCleanShadow(&
I));
4357 setOrigin(&
I, getCleanOrigin());
4361 Type *ShadowTy = getShadowTy(&
I);
4363 auto [ShadowPtr, OriginPtr] =
4364 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
false);
4368 getShadow(PassThru),
"_msmaskedexpload");
4370 setShadow(&
I, Shadow);
4373 setOrigin(&
I, getCleanOrigin());
4376 void handleMaskedCompressStore(IntrinsicInst &
I) {
4379 Value *Ptr =
I.getArgOperand(1);
4380 MaybeAlign
Align =
I.getParamAlign(1);
4383 if (Opts.msan_check_access_address) {
4384 insertCheckShadowOf(Ptr, &
I);
4385 insertCheckShadowOf(Mask, &
I);
4389 Type *ElementShadowTy =
4391 auto [ShadowPtr, OriginPtrs] =
4392 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
true);
4399 void handleMaskedGather(IntrinsicInst &
I) {
4401 Value *Ptrs =
I.getArgOperand(0);
4404 Value *PassThru =
I.getArgOperand(2);
4406 Type *PtrsShadowTy = getShadowTy(Ptrs);
4407 if (Opts.msan_check_access_address) {
4408 insertCheckShadowOf(Mask, &
I);
4412 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4415 if (!PropagateShadow) {
4416 setShadow(&
I, getCleanShadow(&
I));
4417 setOrigin(&
I, getCleanOrigin());
4421 Type *ShadowTy = getShadowTy(&
I);
4423 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4424 Ptrs, IRB, ElementShadowTy, Alignment,
false);
4428 getShadow(PassThru),
"_msmaskedgather");
4430 setShadow(&
I, Shadow);
4433 setOrigin(&
I, getCleanOrigin());
4436 void handleMaskedScatter(IntrinsicInst &
I) {
4439 Value *Ptrs =
I.getArgOperand(1);
4443 Type *PtrsShadowTy = getShadowTy(Ptrs);
4444 if (Opts.msan_check_access_address) {
4445 insertCheckShadowOf(Mask, &
I);
4449 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4453 Type *ElementShadowTy =
4455 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4456 Ptrs, IRB, ElementShadowTy, Alignment,
true);
4467 void handleMaskedStore(IntrinsicInst &
I) {
4469 Value *
V =
I.getArgOperand(0);
4470 Value *Ptr =
I.getArgOperand(1);
4473 Value *Shadow = getShadow(
V);
4475 if (Opts.msan_check_access_address) {
4476 insertCheckShadowOf(Ptr, &
I);
4477 insertCheckShadowOf(Mask, &
I);
4482 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4483 Ptr, IRB, Shadow->
getType(), Alignment,
true);
4487 if (!MS.TrackOrigins)
4490 auto &
DL =
F.getDataLayout();
4491 paintOrigin(IRB, getOrigin(
V), OriginPtr,
4500 void handleMaskedLoad(IntrinsicInst &
I) {
4502 Value *Ptr =
I.getArgOperand(0);
4505 Value *PassThru =
I.getArgOperand(2);
4507 if (Opts.msan_check_access_address) {
4508 insertCheckShadowOf(Ptr, &
I);
4509 insertCheckShadowOf(Mask, &
I);
4512 if (!PropagateShadow) {
4513 setShadow(&
I, getCleanShadow(&
I));
4514 setOrigin(&
I, getCleanOrigin());
4518 Type *ShadowTy = getShadowTy(&
I);
4519 Value *ShadowPtr, *OriginPtr;
4520 std::tie(ShadowPtr, OriginPtr) =
4521 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment,
false);
4523 getShadow(PassThru),
"_msmaskedld"));
4525 if (!MS.TrackOrigins)
4532 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
4537 setOrigin(&
I, Origin);
4547 void handleMaskedIntegerDivRem(IntrinsicInst &
I) {
4550 Value *Dividend =
I.getArgOperand(0);
4551 Value *Divisor =
I.getArgOperand(1);
4554 insertCheckShadowOf(Mask, &
I);
4557 Mask, getShadow(Divisor), getCleanShadow(Divisor),
"_msmaskeddivisor");
4558 insertCheckShadow(MaskedDivisorShadow, getOrigin(Divisor), &
I);
4560 if (!PropagateShadow) {
4561 setShadow(&
I, getCleanShadow(&
I));
4562 setOrigin(&
I, getCleanOrigin());
4567 getPoisonedShadow(&
I),
"_msmaskeddiv"));
4568 setOrigin(&
I, getOrigin(Dividend));
4573 void handleVectorExtractLastActive(IntrinsicInst &
I) {
4578 Value *PassThru =
I.getArgOperand(2);
4591 insertCheckShadowOf(Mask, &
I);
4593 if (!PropagateShadow) {
4594 setShadow(&
I, getCleanShadow(&
I));
4595 setOrigin(&
I, getCleanOrigin());
4601 Intrinsic::experimental_vector_extract_last_active,
4602 {DataShadow->
getType()}, {DataShadow,
Mask, getShadow(PassThru)},
4603 {},
"_msprop_vector_extract_last_active");
4604 setShadow(&
I, Shadow);
4606 if (MS.TrackOrigins) {
4609 getOrigin(PassThru)));
4626 void handleAVXMaskedStore(IntrinsicInst &
I) {
4631 Value *Dst =
I.getArgOperand(0);
4632 assert(Dst->getType()->isPointerTy() &&
"Destination is not a pointer!");
4637 Value *Src =
I.getArgOperand(2);
4642 Value *SrcShadow = getShadow(Src);
4644 if (Opts.msan_check_access_address) {
4645 insertCheckShadowOf(Dst, &
I);
4646 insertCheckShadowOf(Mask, &
I);
4649 Value *DstShadowPtr;
4650 Value *DstOriginPtr;
4651 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4652 Dst, IRB, SrcShadow->
getType(), Alignment,
true);
4654 SmallVector<Value *, 2> ShadowArgs;
4655 ShadowArgs.
append(1, DstShadowPtr);
4656 ShadowArgs.
append(1, Mask);
4664 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
4667 if (!MS.TrackOrigins)
4671 auto &
DL =
F.getDataLayout();
4672 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4673 DL.getTypeStoreSize(SrcShadow->
getType()),
4692 void handleAVXMaskedLoad(IntrinsicInst &
I) {
4697 Value *Src =
I.getArgOperand(0);
4698 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
4705 if (Opts.msan_check_access_address) {
4706 insertCheckShadowOf(Mask, &
I);
4709 Type *SrcShadowTy = getShadowTy(Src);
4710 Value *SrcShadowPtr, *SrcOriginPtr;
4711 std::tie(SrcShadowPtr, SrcOriginPtr) =
4712 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment,
false);
4714 SmallVector<Value *, 2> ShadowArgs;
4715 ShadowArgs.
append(1, SrcShadowPtr);
4716 ShadowArgs.
append(1, Mask);
4719 I.getType(),
I.getIntrinsicID(), ShadowArgs);
4725 if (!MS.TrackOrigins)
4732 setOrigin(&
I, PtrSrcOrigin);
4741 assert(isFixedIntVector(Idx));
4742 auto IdxVectorSize =
4750 auto *IdxShadow = getShadow(Idx);
4755 insertCheckShadow(Truncated, getOrigin(Idx),
I);
4760 void handleAVXVpermilvar(IntrinsicInst &
I) {
4762 Value *Shadow = getShadow(&
I, 0);
4763 maskedCheckAVXIndexShadow(IRB,
I.getArgOperand(1), &
I);
4767 Shadow = IRB.
CreateBitCast(Shadow,
I.getArgOperand(0)->getType());
4769 I.getType(),
I.getIntrinsicID(), {Shadow, I.getArgOperand(1)});
4772 setOriginForNaryOp(
I);
4777 void handleAVXVpermi2var(IntrinsicInst &
I) {
4782 [[maybe_unused]]
auto ArgVectorSize =
4785 ->getNumElements() == ArgVectorSize);
4787 ->getNumElements() == ArgVectorSize);
4788 assert(
I.getArgOperand(0)->getType() ==
I.getArgOperand(2)->getType());
4789 assert(
I.getType() ==
I.getArgOperand(0)->getType());
4790 assert(
I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4792 Value *AShadow = getShadow(&
I, 0);
4794 Value *BShadow = getShadow(&
I, 2);
4796 maskedCheckAVXIndexShadow(IRB, Idx, &
I);
4800 AShadow = IRB.
CreateBitCast(AShadow,
I.getArgOperand(0)->getType());
4801 BShadow = IRB.
CreateBitCast(BShadow,
I.getArgOperand(2)->getType());
4803 I.getType(),
I.getIntrinsicID(), {AShadow, Idx, BShadow});
4805 setOriginForNaryOp(
I);
4808 [[maybe_unused]]
static bool isFixedIntVectorTy(
const Type *
T) {
4812 [[maybe_unused]]
static bool isFixedFPVectorTy(
const Type *
T) {
4816 [[maybe_unused]]
static bool isFixedIntVector(
const Value *
V) {
4817 return isFixedIntVectorTy(
V->getType());
4820 [[maybe_unused]]
static bool isFixedFPVector(
const Value *
V) {
4821 return isFixedFPVectorTy(
V->getType());
4843 void handleAVX512VectorConvertFPToInt(IntrinsicInst &
I,
bool LastMask) {
4848 Value *WriteThrough;
4852 WriteThrough =
I.getOperand(2);
4853 Mask =
I.getOperand(3);
4856 WriteThrough =
I.getOperand(1);
4857 Mask =
I.getOperand(2);
4862 assert(isFixedIntVector(WriteThrough));
4864 unsigned ANumElements =
4866 [[maybe_unused]]
unsigned WriteThruNumElements =
4868 assert(ANumElements == WriteThruNumElements ||
4869 ANumElements * 2 == WriteThruNumElements);
4872 unsigned MaskNumElements =
Mask->getType()->getScalarSizeInBits();
4873 assert(ANumElements == MaskNumElements ||
4874 ANumElements * 2 == MaskNumElements);
4876 assert(WriteThruNumElements == MaskNumElements);
4880 insertCheckShadowOf(Mask, &
I);
4890 Value *AShadow = getShadow(
A);
4891 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
4893 if (ANumElements * 2 == MaskNumElements) {
4905 "_ms_mask_bitcast");
4915 getShadowTy(&
I),
"_ms_a_shadow");
4917 Value *WriteThroughShadow = getShadow(WriteThrough);
4919 "_ms_writethru_select");
4921 setShadow(&
I, Shadow);
4922 setOriginForNaryOp(
I);
4925 static SmallVector<int, 8> getPclmulMask(
unsigned Width,
bool OddElements) {
4926 SmallVector<int, 8>
Mask;
4927 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
4941 void handlePclmulIntrinsic(IntrinsicInst &
I) {
4946 "pclmul 3rd operand must be a constant");
4949 getPclmulMask(Width,
Imm & 0x01));
4951 getPclmulMask(Width,
Imm & 0x10));
4952 ShadowAndOriginCombiner SOC(
this, IRB);
4953 SOC.Add(Shuf0, getOrigin(&
I, 0));
4954 SOC.Add(Shuf1, getOrigin(&
I, 1));
4959 void handleUnarySdSsIntrinsic(IntrinsicInst &
I) {
4964 Value *Second = getShadow(&
I, 1);
4966 SmallVector<int, 16>
Mask;
4967 Mask.push_back(Width);
4968 for (
unsigned i = 1; i < Width; i++)
4972 setShadow(&
I, Shadow);
4973 setOriginForNaryOp(
I);
4976 void handleVtestIntrinsic(IntrinsicInst &
I) {
4978 Value *Shadow0 = getShadow(&
I, 0);
4979 Value *Shadow1 = getShadow(&
I, 1);
4985 setShadow(&
I, Shadow);
4986 setOriginForNaryOp(
I);
4989 void handleBinarySdSsIntrinsic(IntrinsicInst &
I) {
4994 Value *Second = getShadow(&
I, 1);
4997 SmallVector<int, 16>
Mask;
4998 Mask.push_back(Width);
4999 for (
unsigned i = 1; i < Width; i++)
5003 setShadow(&
I, Shadow);
5004 setOriginForNaryOp(
I);
5010 void handleRoundPdPsIntrinsic(IntrinsicInst &
I) {
5011 assert(
I.getArgOperand(0)->getType() ==
I.getType());
5016 ShadowAndOriginCombiner SC(
this, IRB);
5017 SC.Add(
I.getArgOperand(0));
5025 void handleAbsIntrinsic(IntrinsicInst &
I) {
5027 Value *Src =
I.getArgOperand(0);
5028 Value *IsIntMinPoison =
I.getArgOperand(1);
5030 assert(
I.getType()->isIntOrIntVectorTy());
5032 assert(Src->getType() ==
I.getType());
5038 Value *SrcShadow = getShadow(Src);
5042 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5045 Value *PoisonedShadow = getPoisonedShadow(Src);
5046 Value *PoisonedIfIntMinShadow =
5049 IRB.
CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5051 setShadow(&
I, Shadow);
5052 setOrigin(&
I, getOrigin(&
I, 0));
5055 void handleIsFpClass(IntrinsicInst &
I) {
5057 Value *Shadow = getShadow(&
I, 0);
5058 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5059 setOrigin(&
I, getOrigin(&
I, 0));
5062 void handleArithmeticWithOverflow(IntrinsicInst &
I) {
5064 Value *Shadow0 = getShadow(&
I, 0);
5065 Value *Shadow1 = getShadow(&
I, 1);
5068 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5074 setShadow(&
I, Shadow);
5075 setOriginForNaryOp(
I);
5078 void handleModfOrSincos(IntrinsicInst &
I) {
5080 Value *ArgShadow = getShadow(&
I, 0);
5084 setShadow(&
I, Shadow);
5085 setOrigin(&
I, getOrigin(&
I, 0));
5091 Value *Shadow = getShadow(
V);
5113 void handleAVX512VectorDownConvert(IntrinsicInst &
I) {
5118 Value *WriteThrough =
I.getOperand(1);
5122 assert(isFixedIntVector(WriteThrough));
5124 unsigned ANumElements =
5126 unsigned OutputNumElements =
5128 assert(ANumElements == OutputNumElements ||
5129 ANumElements * 2 == OutputNumElements);
5139 insertCheckShadowOf(Mask, &
I);
5142 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5143 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5144 assert(
Mask->getType()->getScalarSizeInBits() == ANumElements);
5155 if (ANumElements != OutputNumElements) {
5157 Mask = IRB.
CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5164 Value *AShadow = getShadow(
A);
5168 VectorType *ShadowType = maybeShrinkVectorShadowType(
A,
I);
5178 AShadow = IRB.
CreateTrunc(AShadow, ShadowType,
"_ms_trunc_shadow");
5179 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
5181 Value *WriteThroughShadow = getShadow(WriteThrough);
5184 setShadow(&
I, Shadow);
5185 setOriginForNaryOp(
I);
5219 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &
I,
5220 SmallVector<unsigned, 4> DataIndices,
5221 unsigned WriteThruIndex,
5222 unsigned MaskIndex) {
5225 unsigned NumArgs =
I.arg_size();
5227 assert(WriteThruIndex < NumArgs);
5228 assert(MaskIndex < NumArgs);
5229 assert(WriteThruIndex != MaskIndex);
5230 Value *WriteThru =
I.getOperand(WriteThruIndex);
5232 unsigned OutputNumElements =
5237 bool isData[16] = {
false};
5239 for (
unsigned i : DataIndices) {
5241 assert(i != WriteThruIndex);
5248 [[maybe_unused]]
unsigned ANumElements =
5250 assert(ANumElements == OutputNumElements);
5255 assert(isFixedFPVector(WriteThru));
5257 for (
unsigned i = 0; i < NumArgs; ++i) {
5258 if (!isData[i] && i != WriteThruIndex) {
5261 assert(
I.getOperand(i)->getType()->isIntegerTy());
5262 insertCheckShadowOf(
I.getOperand(i), &
I);
5267 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5268 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5269 assert(
Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5276 Value *DataShadow =
nullptr;
5277 for (
unsigned i : DataIndices) {
5280 DataShadow = IRB.
CreateOr(DataShadow, getShadow(
A));
5282 DataShadow = getShadow(
A);
5290 Value *WriteThruShadow = getShadow(WriteThru);
5293 setShadow(&
I, Shadow);
5295 setOriginForNaryOp(
I);
5305 void handleAVX512FPClass(IntrinsicInst &
I) {
5311 assert(isFixedFPVector(Input));
5314 Value *Classifiers =
I.getOperand(1);
5318 assert(isFixedIntVectorTy(
I.getType()));
5324 Value *OutputShadow;
5329 OutputShadow = getCleanShadow(OutputType);
5335 OutputShadow = IRB.
CreateICmpNE(getShadow(Input), getCleanShadow(Input));
5337 setShadow(&
I, OutputShadow);
5339 setOriginForNaryOp(
I);
5349 void visitGenericScalarHalfwordInst(IntrinsicInst &
I) {
5355 Value *WriteThrough =
I.getOperand(2);
5362 insertCheckShadowOf(Mask, &
I);
5366 unsigned NumElements =
5368 assert(NumElements == 8);
5369 assert(
A->getType() ==
B->getType());
5371 assert(
Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5374 Value *ALowerShadow = extractLowerShadow(IRB,
A);
5375 Value *BLowerShadow = extractLowerShadow(IRB,
B);
5377 Value *ABLowerShadow = IRB.
CreateOr(ALowerShadow, BLowerShadow);
5379 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5386 Value *AShadow = getShadow(
A);
5387 Value *DstLowerShadow =
5388 IRB.
CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5390 AShadow, DstLowerShadow, ConstantInt::get(IRB.
getInt32Ty(), 0),
5393 setShadow(&
I, DstShadow);
5394 setOriginForNaryOp(
I);
5424 void handleAVXGF2P8Affine(IntrinsicInst &
I) {
5435 ->getScalarSizeInBits() == 8);
5437 assert(
A->getType() ==
X->getType());
5439 assert(
B->getType()->isIntegerTy());
5440 assert(
B->getType()->getScalarSizeInBits() == 8);
5442 assert(
I.getType() ==
A->getType());
5444 Value *AShadow = getShadow(
A);
5445 Value *XShadow = getShadow(
X);
5446 Value *BZeroShadow = getCleanShadow(
B);
5449 I.getType(),
I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5451 {X, AShadow, BZeroShadow});
5453 {XShadow, A, BZeroShadow});
5456 Value *BShadow = getShadow(
B);
5457 Value *BBroadcastShadow = getCleanShadow(AShadow);
5462 for (
unsigned i = 0; i < NumElements; i++)
5466 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5467 setOriginForNaryOp(
I);
5481 void handleNEONVectorLoad(IntrinsicInst &
I,
bool WithLane) {
5482 unsigned int numArgs =
I.arg_size();
5485 assert(
I.getType()->isStructTy());
5495 assert(4 <= numArgs && numArgs <= 6);
5509 for (
unsigned int i = 0; i < numArgs - 2; i++)
5510 ShadowArgs.
push_back(getShadow(
I.getArgOperand(i)));
5513 Value *LaneNumber =
I.getArgOperand(numArgs - 2);
5517 insertCheckShadowOf(LaneNumber, &
I);
5520 Value *Src =
I.getArgOperand(numArgs - 1);
5521 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
5523 Type *SrcShadowTy = getShadowTy(Src);
5524 auto [SrcShadowPtr, SrcOriginPtr] =
5525 getShadowOriginPtr(Src, IRB, SrcShadowTy,
Align(1),
false);
5532 getShadowTy(&
I),
I.getIntrinsicID(), ShadowArgs);
5535 if (!MS.TrackOrigins)
5539 setOrigin(&
I, PtrSrcOrigin);
5556 void handleNEONVectorStoreIntrinsic(IntrinsicInst &
I,
bool useLane) {
5560 int numArgOperands =
I.arg_size();
5563 assert(numArgOperands >= 1);
5564 Value *Addr =
I.getArgOperand(numArgOperands - 1);
5566 int skipTrailingOperands = 1;
5568 if (Opts.msan_check_access_address)
5569 insertCheckShadowOf(Addr, &
I);
5573 skipTrailingOperands++;
5574 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
5576 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5579 SmallVector<Value *, 8> ShadowArgs;
5581 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5583 Value *Shadow = getShadow(&
I, i);
5584 ShadowArgs.
append(1, Shadow);
5601 (numArgOperands - skipTrailingOperands));
5602 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5606 I.getArgOperand(numArgOperands - skipTrailingOperands));
5608 Value *OutputShadowPtr, *OutputOriginPtr;
5610 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5611 Addr, IRB, OutputShadowTy,
Align(1),
true);
5612 ShadowArgs.
append(1, OutputShadowPtr);
5615 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
5618 if (MS.TrackOrigins) {
5626 OriginCombiner OC(
this, IRB);
5627 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5628 OC.Add(
I.getArgOperand(i));
5630 const DataLayout &
DL =
F.getDataLayout();
5631 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
5664 void handleNEONMatrixMultiply(IntrinsicInst &
I) {
5668 Value *
R =
I.getArgOperand(0);
5669 Value *
A =
I.getArgOperand(1);
5670 Value *
B =
I.getArgOperand(2);
5672 assert(
I.getType() ==
R->getType());
5697 Value *ShadowR = getShadow(&
I, 0);
5698 Value *ShadowA = getShadow(&
I, 1);
5699 Value *ShadowB = getShadow(&
I, 2);
5717 {getCleanShadow(RTy), ShadowA, ShadowB});
5743 {RZeros, ShadowA, ShadowB});
5757 ShadowR = IRB.
CreateICmpNE(ShadowR, getCleanShadow(RTy));
5758 ShadowR = IRB.
CreateOr(ShadowAB, ShadowR);
5760 setShadow(&
I, IRB.
CreateSExt(ShadowR, getShadowTy(RTy)));
5762 setOriginForNaryOp(
I);
5804 void handleIntrinsicByApplyingToShadow(IntrinsicInst &
I,
5806 ArrayRef<int> verbatimArgIndices,
5807 bool forceIntegerIntrinsic) {
5810 assert(verbatimArgIndices.
size() <=
I.arg_size());
5814 SmallVector<bool, 4> verbatimArgLookup(
I.arg_size(),
false);
5816 for (
int index : verbatimArgIndices) {
5818 index +=
I.arg_size();
5819 assert(index >= 0 &&
static_cast<unsigned int>(index) <
I.arg_size());
5820 verbatimArgLookup[index] =
true;
5823 SmallVector<Value *, 8> ShadowArgs;
5825 for (
unsigned int i = 0; i <
I.arg_size(); i++) {
5826 if (verbatimArgLookup[i]) {
5827 Value *Arg =
I.getArgOperand(i);
5829 if (forceIntegerIntrinsic)
5834 Value *Shadow = getShadow(&
I, i);
5836 if (forceIntegerIntrinsic)
5844 Value *CombinedShadow;
5845 if (forceIntegerIntrinsic) {
5858 for (
unsigned int i = 0; i <
I.arg_size(); i++) {
5859 if (!verbatimArgLookup[i])
5863 CreateShadowCast(IRB, getShadow(&
I, i), CombinedShadow->
getType());
5864 CombinedShadow = IRB.
CreateOr(Shadow, CombinedShadow,
"_msprop");
5867 setShadow(&
I, CombinedShadow);
5869 setOriginForNaryOp(
I);
5875 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &
I) {
5913 void handleNEONDotProductLaneIntrinsic(IntrinsicInst &
I,
5914 unsigned ReductionFactor) {
5918 [[maybe_unused]]
Value *VAcc =
I.getOperand(0);
5919 [[maybe_unused]]
Value *Va =
I.getOperand(1);
5920 [[maybe_unused]]
Value *Vb =
I.getOperand(2);
5921 Value *Lane =
I.getOperand(3);
5928 I.getType()->getPrimitiveSizeInBits());
5937 I.getType()->getPrimitiveSizeInBits());
5943 Value *SAcc = getShadow(&
I, 0);
5944 Value *Sa = getShadow(&
I, 1);
5945 Value *Sb = getShadow(&
I, 2);
5952 Sb, FixedVectorType::getWithSizeAndScalar(
5968 SOutput = IRB.
CreateSelect(SbClean, SOutput, getPoisonedShadow(SOutput));
5970 setShadow(&
I, SOutput);
5971 setOriginForNaryOp(
I);
5974 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &
I) {
5975 switch (
I.getIntrinsicID()) {
5976 case Intrinsic::uadd_with_overflow:
5977 case Intrinsic::sadd_with_overflow:
5978 case Intrinsic::usub_with_overflow:
5979 case Intrinsic::ssub_with_overflow:
5980 case Intrinsic::umul_with_overflow:
5981 case Intrinsic::smul_with_overflow:
5982 handleArithmeticWithOverflow(
I);
5984 case Intrinsic::modf:
5985 case Intrinsic::sincos:
5986 case Intrinsic::sincospi:
5987 handleModfOrSincos(
I);
5989 case Intrinsic::abs:
5990 handleAbsIntrinsic(
I);
5992 case Intrinsic::bitreverse:
5993 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
5997 case Intrinsic::is_fpclass:
6000 case Intrinsic::lifetime_start:
6001 handleLifetimeStart(
I);
6003 case Intrinsic::launder_invariant_group:
6004 handleInvariantGroup(
I);
6006 case Intrinsic::bswap:
6009 case Intrinsic::ctlz:
6010 case Intrinsic::cttz:
6011 handleCountLeadingTrailingZeros(
I);
6013 case Intrinsic::masked_compressstore:
6014 handleMaskedCompressStore(
I);
6016 case Intrinsic::masked_expandload:
6017 handleMaskedExpandLoad(
I);
6019 case Intrinsic::masked_gather:
6020 handleMaskedGather(
I);
6022 case Intrinsic::masked_scatter:
6023 handleMaskedScatter(
I);
6025 case Intrinsic::masked_store:
6026 handleMaskedStore(
I);
6028 case Intrinsic::masked_load:
6029 handleMaskedLoad(
I);
6031 case Intrinsic::masked_udiv:
6032 case Intrinsic::masked_sdiv:
6033 case Intrinsic::masked_urem:
6034 case Intrinsic::masked_srem:
6035 handleMaskedIntegerDivRem(
I);
6037 case Intrinsic::vector_reduce_and:
6038 handleVectorReduceAndIntrinsic(
I);
6040 case Intrinsic::vector_reduce_or:
6041 handleVectorReduceOrIntrinsic(
I);
6044 case Intrinsic::vector_reduce_add:
6045 case Intrinsic::vector_reduce_xor:
6046 case Intrinsic::vector_reduce_mul:
6049 case Intrinsic::vector_reduce_smax:
6050 case Intrinsic::vector_reduce_smin:
6051 case Intrinsic::vector_reduce_umax:
6052 case Intrinsic::vector_reduce_umin:
6055 case Intrinsic::vector_reduce_fmax:
6056 case Intrinsic::vector_reduce_fmin:
6057 handleVectorReduceIntrinsic(
I,
false);
6060 case Intrinsic::vector_reduce_fadd:
6061 case Intrinsic::vector_reduce_fmul:
6062 handleVectorReduceWithStarterIntrinsic(
I);
6066 case Intrinsic::vector_partial_reduce_add:
6067 case Intrinsic::vector_partial_reduce_fadd:
6068 handleVectorPartialReduceAddIntrinsic(
I);
6071 case Intrinsic::experimental_vector_extract_last_active:
6072 handleVectorExtractLastActive(
I);
6075 case Intrinsic::scmp:
6076 case Intrinsic::ucmp: {
6081 case Intrinsic::fshl:
6082 case Intrinsic::fshr:
6083 handleFunnelShift(
I);
6086 case Intrinsic::pdep:
6087 case Intrinsic::pext:
6088 handleGenericBitManipulation(
I);
6091 case Intrinsic::is_constant:
6093 setShadow(&
I, getCleanShadow(&
I));
6094 setOrigin(&
I, getCleanOrigin());
6101 case Intrinsic::fptosi_sat:
6102 case Intrinsic::fptoui_sat:
6103 handleGenericVectorConvertIntrinsic(
I,
false);
6110 case Intrinsic::fake_use:
6111 assert(
I.getType()->isVoidTy());
6124 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &
I) {
6125 switch (
I.getIntrinsicID()) {
6126 case Intrinsic::x86_sse_stmxcsr:
6129 case Intrinsic::x86_sse_ldmxcsr:
6136 case Intrinsic::x86_avx512_vcvtsd2usi64:
6137 case Intrinsic::x86_avx512_vcvtsd2usi32:
6138 case Intrinsic::x86_avx512_vcvtss2usi64:
6139 case Intrinsic::x86_avx512_vcvtss2usi32:
6140 case Intrinsic::x86_avx512_cvttss2usi64:
6141 case Intrinsic::x86_avx512_cvttss2usi:
6142 case Intrinsic::x86_avx512_cvttsd2usi64:
6143 case Intrinsic::x86_avx512_cvttsd2usi:
6144 case Intrinsic::x86_avx512_cvtusi2ss:
6145 case Intrinsic::x86_avx512_cvtusi642sd:
6146 case Intrinsic::x86_avx512_cvtusi642ss:
6147 handleSSEVectorConvertIntrinsic(
I, 1,
true);
6149 case Intrinsic::x86_sse2_cvtsd2si64:
6150 case Intrinsic::x86_sse2_cvtsd2si:
6151 case Intrinsic::x86_sse2_cvtsd2ss:
6152 case Intrinsic::x86_sse2_cvttsd2si64:
6153 case Intrinsic::x86_sse2_cvttsd2si:
6154 case Intrinsic::x86_sse_cvtss2si64:
6155 case Intrinsic::x86_sse_cvtss2si:
6156 case Intrinsic::x86_sse_cvttss2si64:
6157 case Intrinsic::x86_sse_cvttss2si:
6158 handleSSEVectorConvertIntrinsic(
I, 1);
6160 case Intrinsic::x86_sse_cvtps2pi:
6161 case Intrinsic::x86_sse_cvttps2pi:
6162 handleSSEVectorConvertIntrinsic(
I, 2);
6170 case Intrinsic::x86_vcvtps2ph_128:
6171 case Intrinsic::x86_vcvtps2ph_256: {
6172 handleSSEVectorConvertIntrinsicByProp(
I,
true);
6181 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
6182 handleAVX512VectorConvertFPToInt(
I,
false);
6187 case Intrinsic::x86_sse2_cvtpd2ps:
6188 case Intrinsic::x86_sse2_cvtps2dq:
6189 case Intrinsic::x86_sse2_cvtpd2dq:
6190 case Intrinsic::x86_sse2_cvttps2dq:
6191 case Intrinsic::x86_sse2_cvttpd2dq:
6192 case Intrinsic::x86_avx_cvt_pd2_ps_256:
6193 case Intrinsic::x86_avx_cvt_ps2dq_256:
6194 case Intrinsic::x86_avx_cvt_pd2dq_256:
6195 case Intrinsic::x86_avx_cvtt_ps2dq_256:
6196 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
6197 handleSSEVectorConvertIntrinsicByProp(
I,
false);
6208 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
6209 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
6210 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
6211 handleAVX512VectorConvertFPToInt(
I,
true);
6215 case Intrinsic::x86_avx512_psll_w_512:
6216 case Intrinsic::x86_avx512_psll_d_512:
6217 case Intrinsic::x86_avx512_psll_q_512:
6218 case Intrinsic::x86_avx512_pslli_w_512:
6219 case Intrinsic::x86_avx512_pslli_d_512:
6220 case Intrinsic::x86_avx512_pslli_q_512:
6221 case Intrinsic::x86_avx512_psrl_w_512:
6222 case Intrinsic::x86_avx512_psrl_d_512:
6223 case Intrinsic::x86_avx512_psrl_q_512:
6224 case Intrinsic::x86_avx512_psra_w_512:
6225 case Intrinsic::x86_avx512_psra_d_512:
6226 case Intrinsic::x86_avx512_psra_q_512:
6227 case Intrinsic::x86_avx512_psrli_w_512:
6228 case Intrinsic::x86_avx512_psrli_d_512:
6229 case Intrinsic::x86_avx512_psrli_q_512:
6230 case Intrinsic::x86_avx512_psrai_w_512:
6231 case Intrinsic::x86_avx512_psrai_d_512:
6232 case Intrinsic::x86_avx512_psrai_q_512:
6233 case Intrinsic::x86_avx512_psra_q_256:
6234 case Intrinsic::x86_avx512_psra_q_128:
6235 case Intrinsic::x86_avx512_psrai_q_256:
6236 case Intrinsic::x86_avx512_psrai_q_128:
6237 case Intrinsic::x86_avx2_psll_w:
6238 case Intrinsic::x86_avx2_psll_d:
6239 case Intrinsic::x86_avx2_psll_q:
6240 case Intrinsic::x86_avx2_pslli_w:
6241 case Intrinsic::x86_avx2_pslli_d:
6242 case Intrinsic::x86_avx2_pslli_q:
6243 case Intrinsic::x86_avx2_psrl_w:
6244 case Intrinsic::x86_avx2_psrl_d:
6245 case Intrinsic::x86_avx2_psrl_q:
6246 case Intrinsic::x86_avx2_psra_w:
6247 case Intrinsic::x86_avx2_psra_d:
6248 case Intrinsic::x86_avx2_psrli_w:
6249 case Intrinsic::x86_avx2_psrli_d:
6250 case Intrinsic::x86_avx2_psrli_q:
6251 case Intrinsic::x86_avx2_psrai_w:
6252 case Intrinsic::x86_avx2_psrai_d:
6253 case Intrinsic::x86_sse2_psll_w:
6254 case Intrinsic::x86_sse2_psll_d:
6255 case Intrinsic::x86_sse2_psll_q:
6256 case Intrinsic::x86_sse2_pslli_w:
6257 case Intrinsic::x86_sse2_pslli_d:
6258 case Intrinsic::x86_sse2_pslli_q:
6259 case Intrinsic::x86_sse2_psrl_w:
6260 case Intrinsic::x86_sse2_psrl_d:
6261 case Intrinsic::x86_sse2_psrl_q:
6262 case Intrinsic::x86_sse2_psra_w:
6263 case Intrinsic::x86_sse2_psra_d:
6264 case Intrinsic::x86_sse2_psrli_w:
6265 case Intrinsic::x86_sse2_psrli_d:
6266 case Intrinsic::x86_sse2_psrli_q:
6267 case Intrinsic::x86_sse2_psrai_w:
6268 case Intrinsic::x86_sse2_psrai_d:
6269 case Intrinsic::x86_mmx_psll_w:
6270 case Intrinsic::x86_mmx_psll_d:
6271 case Intrinsic::x86_mmx_psll_q:
6272 case Intrinsic::x86_mmx_pslli_w:
6273 case Intrinsic::x86_mmx_pslli_d:
6274 case Intrinsic::x86_mmx_pslli_q:
6275 case Intrinsic::x86_mmx_psrl_w:
6276 case Intrinsic::x86_mmx_psrl_d:
6277 case Intrinsic::x86_mmx_psrl_q:
6278 case Intrinsic::x86_mmx_psra_w:
6279 case Intrinsic::x86_mmx_psra_d:
6280 case Intrinsic::x86_mmx_psrli_w:
6281 case Intrinsic::x86_mmx_psrli_d:
6282 case Intrinsic::x86_mmx_psrli_q:
6283 case Intrinsic::x86_mmx_psrai_w:
6284 case Intrinsic::x86_mmx_psrai_d:
6285 handleVectorShiftIntrinsic(
I,
false);
6287 case Intrinsic::x86_avx2_psllv_d:
6288 case Intrinsic::x86_avx2_psllv_d_256:
6289 case Intrinsic::x86_avx512_psllv_d_512:
6290 case Intrinsic::x86_avx2_psllv_q:
6291 case Intrinsic::x86_avx2_psllv_q_256:
6292 case Intrinsic::x86_avx512_psllv_q_512:
6293 case Intrinsic::x86_avx2_psrlv_d:
6294 case Intrinsic::x86_avx2_psrlv_d_256:
6295 case Intrinsic::x86_avx512_psrlv_d_512:
6296 case Intrinsic::x86_avx2_psrlv_q:
6297 case Intrinsic::x86_avx2_psrlv_q_256:
6298 case Intrinsic::x86_avx512_psrlv_q_512:
6299 case Intrinsic::x86_avx2_psrav_d:
6300 case Intrinsic::x86_avx2_psrav_d_256:
6301 case Intrinsic::x86_avx512_psrav_d_512:
6302 case Intrinsic::x86_avx512_psrav_q_128:
6303 case Intrinsic::x86_avx512_psrav_q_256:
6304 case Intrinsic::x86_avx512_psrav_q_512:
6305 handleVectorShiftIntrinsic(
I,
true);
6309 case Intrinsic::x86_sse2_packsswb_128:
6310 case Intrinsic::x86_sse2_packssdw_128:
6311 case Intrinsic::x86_sse2_packuswb_128:
6312 case Intrinsic::x86_sse41_packusdw:
6313 case Intrinsic::x86_avx2_packsswb:
6314 case Intrinsic::x86_avx2_packssdw:
6315 case Intrinsic::x86_avx2_packuswb:
6316 case Intrinsic::x86_avx2_packusdw:
6322 case Intrinsic::x86_avx512_packsswb_512:
6323 case Intrinsic::x86_avx512_packssdw_512:
6324 case Intrinsic::x86_avx512_packuswb_512:
6325 case Intrinsic::x86_avx512_packusdw_512:
6326 handleVectorPackIntrinsic(
I);
6329 case Intrinsic::x86_sse41_pblendvb:
6330 case Intrinsic::x86_sse41_blendvpd:
6331 case Intrinsic::x86_sse41_blendvps:
6332 case Intrinsic::x86_avx_blendv_pd_256:
6333 case Intrinsic::x86_avx_blendv_ps_256:
6334 case Intrinsic::x86_avx2_pblendvb:
6335 handleBlendvIntrinsic(
I);
6338 case Intrinsic::x86_avx_dp_ps_256:
6339 case Intrinsic::x86_sse41_dppd:
6340 case Intrinsic::x86_sse41_dpps:
6341 handleDppIntrinsic(
I);
6344 case Intrinsic::x86_mmx_packsswb:
6345 case Intrinsic::x86_mmx_packuswb:
6346 handleVectorPackIntrinsic(
I, 16);
6349 case Intrinsic::x86_mmx_packssdw:
6350 handleVectorPackIntrinsic(
I, 32);
6353 case Intrinsic::x86_mmx_psad_bw:
6354 handleVectorSadIntrinsic(
I,
true);
6356 case Intrinsic::x86_sse2_psad_bw:
6357 case Intrinsic::x86_avx2_psad_bw:
6358 handleVectorSadIntrinsic(
I);
6384 case Intrinsic::x86_sse2_pmadd_wd:
6385 case Intrinsic::x86_avx2_pmadd_wd:
6386 case Intrinsic::x86_avx512_pmaddw_d_512:
6387 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6388 case Intrinsic::x86_avx2_pmadd_ub_sw:
6389 case Intrinsic::x86_avx512_pmaddubs_w_512:
6390 handleVectorDotProductIntrinsic(
I, 2,
6397 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6398 handleVectorDotProductIntrinsic(
I, 2,
6405 case Intrinsic::x86_mmx_pmadd_wd:
6406 handleVectorDotProductIntrinsic(
I, 2,
6415 case Intrinsic::aarch64_neon_bfmlalt:
6416 handleVectorDotProductIntrinsic(
I, 2,
6424 case Intrinsic::aarch64_neon_bfmlalb:
6425 handleVectorDotProductIntrinsic(
I, 2,
6523 case Intrinsic::x86_avx512_vpdpbusd_128:
6524 case Intrinsic::x86_avx512_vpdpbusd_256:
6525 case Intrinsic::x86_avx512_vpdpbusd_512:
6526 case Intrinsic::x86_avx512_vpdpbusds_128:
6527 case Intrinsic::x86_avx512_vpdpbusds_256:
6528 case Intrinsic::x86_avx512_vpdpbusds_512:
6529 case Intrinsic::x86_avx2_vpdpbssd_128:
6530 case Intrinsic::x86_avx2_vpdpbssd_256:
6531 case Intrinsic::x86_avx10_vpdpbssd_512:
6532 case Intrinsic::x86_avx2_vpdpbssds_128:
6533 case Intrinsic::x86_avx2_vpdpbssds_256:
6534 case Intrinsic::x86_avx10_vpdpbssds_512:
6535 case Intrinsic::x86_avx2_vpdpbsud_128:
6536 case Intrinsic::x86_avx2_vpdpbsud_256:
6537 case Intrinsic::x86_avx10_vpdpbsud_512:
6538 case Intrinsic::x86_avx2_vpdpbsuds_128:
6539 case Intrinsic::x86_avx2_vpdpbsuds_256:
6540 case Intrinsic::x86_avx10_vpdpbsuds_512:
6541 case Intrinsic::x86_avx2_vpdpbuud_128:
6542 case Intrinsic::x86_avx2_vpdpbuud_256:
6543 case Intrinsic::x86_avx10_vpdpbuud_512:
6544 case Intrinsic::x86_avx2_vpdpbuuds_128:
6545 case Intrinsic::x86_avx2_vpdpbuuds_256:
6546 case Intrinsic::x86_avx10_vpdpbuuds_512:
6547 handleVectorDotProductIntrinsic(
I, 4,
6645 case Intrinsic::x86_avx512_vpdpwssd_128:
6646 case Intrinsic::x86_avx512_vpdpwssd_256:
6647 case Intrinsic::x86_avx512_vpdpwssd_512:
6648 case Intrinsic::x86_avx512_vpdpwssds_128:
6649 case Intrinsic::x86_avx512_vpdpwssds_256:
6650 case Intrinsic::x86_avx512_vpdpwssds_512:
6651 case Intrinsic::x86_avx2_vpdpwsud_128:
6652 case Intrinsic::x86_avx2_vpdpwsud_256:
6653 case Intrinsic::x86_avx10_vpdpwsud_512:
6654 case Intrinsic::x86_avx2_vpdpwsuds_128:
6655 case Intrinsic::x86_avx2_vpdpwsuds_256:
6656 case Intrinsic::x86_avx10_vpdpwsuds_512:
6657 case Intrinsic::x86_avx2_vpdpwusd_128:
6658 case Intrinsic::x86_avx2_vpdpwusd_256:
6659 case Intrinsic::x86_avx10_vpdpwusd_512:
6660 case Intrinsic::x86_avx2_vpdpwusds_128:
6661 case Intrinsic::x86_avx2_vpdpwusds_256:
6662 case Intrinsic::x86_avx10_vpdpwusds_512:
6663 case Intrinsic::x86_avx2_vpdpwuud_128:
6664 case Intrinsic::x86_avx2_vpdpwuud_256:
6665 case Intrinsic::x86_avx10_vpdpwuud_512:
6666 case Intrinsic::x86_avx2_vpdpwuuds_128:
6667 case Intrinsic::x86_avx2_vpdpwuuds_256:
6668 case Intrinsic::x86_avx10_vpdpwuuds_512:
6669 handleVectorDotProductIntrinsic(
I, 2,
6683 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6684 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6685 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6686 handleVectorDotProductIntrinsic(
I, 2,
6692 case Intrinsic::x86_sse_cmp_ss:
6693 case Intrinsic::x86_sse2_cmp_sd:
6694 case Intrinsic::x86_sse_comieq_ss:
6695 case Intrinsic::x86_sse_comilt_ss:
6696 case Intrinsic::x86_sse_comile_ss:
6697 case Intrinsic::x86_sse_comigt_ss:
6698 case Intrinsic::x86_sse_comige_ss:
6699 case Intrinsic::x86_sse_comineq_ss:
6700 case Intrinsic::x86_sse_ucomieq_ss:
6701 case Intrinsic::x86_sse_ucomilt_ss:
6702 case Intrinsic::x86_sse_ucomile_ss:
6703 case Intrinsic::x86_sse_ucomigt_ss:
6704 case Intrinsic::x86_sse_ucomige_ss:
6705 case Intrinsic::x86_sse_ucomineq_ss:
6706 case Intrinsic::x86_sse2_comieq_sd:
6707 case Intrinsic::x86_sse2_comilt_sd:
6708 case Intrinsic::x86_sse2_comile_sd:
6709 case Intrinsic::x86_sse2_comigt_sd:
6710 case Intrinsic::x86_sse2_comige_sd:
6711 case Intrinsic::x86_sse2_comineq_sd:
6712 case Intrinsic::x86_sse2_ucomieq_sd:
6713 case Intrinsic::x86_sse2_ucomilt_sd:
6714 case Intrinsic::x86_sse2_ucomile_sd:
6715 case Intrinsic::x86_sse2_ucomigt_sd:
6716 case Intrinsic::x86_sse2_ucomige_sd:
6717 case Intrinsic::x86_sse2_ucomineq_sd:
6718 handleVectorCompareScalarIntrinsic(
I);
6721 case Intrinsic::x86_avx_cmp_pd_256:
6722 case Intrinsic::x86_avx_cmp_ps_256:
6723 case Intrinsic::x86_sse2_cmp_pd:
6724 case Intrinsic::x86_sse_cmp_ps:
6725 handleVectorComparePackedIntrinsic(
I,
true);
6728 case Intrinsic::x86_bmi_bextr_32:
6729 case Intrinsic::x86_bmi_bextr_64:
6730 case Intrinsic::x86_bmi_bzhi_32:
6731 case Intrinsic::x86_bmi_bzhi_64:
6732 handleGenericBitManipulation(
I);
6735 case Intrinsic::x86_pclmulqdq:
6736 case Intrinsic::x86_pclmulqdq_256:
6737 case Intrinsic::x86_pclmulqdq_512:
6738 handlePclmulIntrinsic(
I);
6741 case Intrinsic::x86_avx_round_pd_256:
6742 case Intrinsic::x86_avx_round_ps_256:
6743 case Intrinsic::x86_sse41_round_pd:
6744 case Intrinsic::x86_sse41_round_ps:
6745 handleRoundPdPsIntrinsic(
I);
6748 case Intrinsic::x86_sse41_round_sd:
6749 case Intrinsic::x86_sse41_round_ss:
6750 handleUnarySdSsIntrinsic(
I);
6753 case Intrinsic::x86_sse2_max_sd:
6754 case Intrinsic::x86_sse_max_ss:
6755 case Intrinsic::x86_sse2_min_sd:
6756 case Intrinsic::x86_sse_min_ss:
6757 handleBinarySdSsIntrinsic(
I);
6760 case Intrinsic::x86_avx_vtestc_pd:
6761 case Intrinsic::x86_avx_vtestc_pd_256:
6762 case Intrinsic::x86_avx_vtestc_ps:
6763 case Intrinsic::x86_avx_vtestc_ps_256:
6764 case Intrinsic::x86_avx_vtestnzc_pd:
6765 case Intrinsic::x86_avx_vtestnzc_pd_256:
6766 case Intrinsic::x86_avx_vtestnzc_ps:
6767 case Intrinsic::x86_avx_vtestnzc_ps_256:
6768 case Intrinsic::x86_avx_vtestz_pd:
6769 case Intrinsic::x86_avx_vtestz_pd_256:
6770 case Intrinsic::x86_avx_vtestz_ps:
6771 case Intrinsic::x86_avx_vtestz_ps_256:
6772 case Intrinsic::x86_avx_ptestc_256:
6773 case Intrinsic::x86_avx_ptestnzc_256:
6774 case Intrinsic::x86_avx_ptestz_256:
6775 case Intrinsic::x86_sse41_ptestc:
6776 case Intrinsic::x86_sse41_ptestnzc:
6777 case Intrinsic::x86_sse41_ptestz:
6778 handleVtestIntrinsic(
I);
6782 case Intrinsic::x86_ssse3_phadd_w:
6783 case Intrinsic::x86_ssse3_phadd_w_128:
6784 case Intrinsic::x86_ssse3_phsub_w:
6785 case Intrinsic::x86_ssse3_phsub_w_128:
6786 handlePairwiseShadowOrIntrinsic(
I, 1,
6790 case Intrinsic::x86_avx2_phadd_w:
6791 case Intrinsic::x86_avx2_phsub_w:
6792 handlePairwiseShadowOrIntrinsic(
I, 2,
6797 case Intrinsic::x86_ssse3_phadd_d:
6798 case Intrinsic::x86_ssse3_phadd_d_128:
6799 case Intrinsic::x86_ssse3_phsub_d:
6800 case Intrinsic::x86_ssse3_phsub_d_128:
6801 handlePairwiseShadowOrIntrinsic(
I, 1,
6805 case Intrinsic::x86_avx2_phadd_d:
6806 case Intrinsic::x86_avx2_phsub_d:
6807 handlePairwiseShadowOrIntrinsic(
I, 2,
6812 case Intrinsic::x86_ssse3_phadd_sw:
6813 case Intrinsic::x86_ssse3_phadd_sw_128:
6814 case Intrinsic::x86_ssse3_phsub_sw:
6815 case Intrinsic::x86_ssse3_phsub_sw_128:
6816 handlePairwiseShadowOrIntrinsic(
I, 1,
6820 case Intrinsic::x86_avx2_phadd_sw:
6821 case Intrinsic::x86_avx2_phsub_sw:
6822 handlePairwiseShadowOrIntrinsic(
I, 2,
6827 case Intrinsic::x86_sse3_hadd_ps:
6828 case Intrinsic::x86_sse3_hadd_pd:
6829 case Intrinsic::x86_sse3_hsub_ps:
6830 case Intrinsic::x86_sse3_hsub_pd:
6831 handlePairwiseShadowOrIntrinsic(
I, 1);
6834 case Intrinsic::x86_avx_hadd_pd_256:
6835 case Intrinsic::x86_avx_hadd_ps_256:
6836 case Intrinsic::x86_avx_hsub_pd_256:
6837 case Intrinsic::x86_avx_hsub_ps_256:
6838 handlePairwiseShadowOrIntrinsic(
I, 2);
6841 case Intrinsic::x86_avx_maskstore_ps:
6842 case Intrinsic::x86_avx_maskstore_pd:
6843 case Intrinsic::x86_avx_maskstore_ps_256:
6844 case Intrinsic::x86_avx_maskstore_pd_256:
6845 case Intrinsic::x86_avx2_maskstore_d:
6846 case Intrinsic::x86_avx2_maskstore_q:
6847 case Intrinsic::x86_avx2_maskstore_d_256:
6848 case Intrinsic::x86_avx2_maskstore_q_256: {
6849 handleAVXMaskedStore(
I);
6853 case Intrinsic::x86_avx_maskload_ps:
6854 case Intrinsic::x86_avx_maskload_pd:
6855 case Intrinsic::x86_avx_maskload_ps_256:
6856 case Intrinsic::x86_avx_maskload_pd_256:
6857 case Intrinsic::x86_avx2_maskload_d:
6858 case Intrinsic::x86_avx2_maskload_q:
6859 case Intrinsic::x86_avx2_maskload_d_256:
6860 case Intrinsic::x86_avx2_maskload_q_256: {
6861 handleAVXMaskedLoad(
I);
6866 case Intrinsic::x86_avx512fp16_add_ph_512:
6867 case Intrinsic::x86_avx512fp16_sub_ph_512:
6868 case Intrinsic::x86_avx512fp16_mul_ph_512:
6869 case Intrinsic::x86_avx512fp16_div_ph_512:
6870 case Intrinsic::x86_avx512fp16_max_ph_512:
6871 case Intrinsic::x86_avx512fp16_min_ph_512:
6872 case Intrinsic::x86_avx512_min_ps_512:
6873 case Intrinsic::x86_avx512_min_pd_512:
6874 case Intrinsic::x86_avx512_max_ps_512:
6875 case Intrinsic::x86_avx512_max_pd_512: {
6880 [[maybe_unused]]
bool Success =
6881 maybeHandleSimpleNomemIntrinsic(
I, 1);
6886 case Intrinsic::x86_avx_vpermilvar_pd:
6887 case Intrinsic::x86_avx_vpermilvar_pd_256:
6888 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6889 case Intrinsic::x86_avx_vpermilvar_ps:
6890 case Intrinsic::x86_avx_vpermilvar_ps_256:
6891 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6892 handleAVXVpermilvar(
I);
6896 case Intrinsic::x86_avx512_vpermi2var_d_128:
6897 case Intrinsic::x86_avx512_vpermi2var_d_256:
6898 case Intrinsic::x86_avx512_vpermi2var_d_512:
6899 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6900 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6901 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6902 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6903 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6904 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6905 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6906 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6907 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6908 case Intrinsic::x86_avx512_vpermi2var_q_128:
6909 case Intrinsic::x86_avx512_vpermi2var_q_256:
6910 case Intrinsic::x86_avx512_vpermi2var_q_512:
6911 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6912 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6913 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6914 handleAVXVpermi2var(
I);
6928 case Intrinsic::x86_avx2_pshuf_b:
6929 case Intrinsic::x86_sse_pshuf_w:
6930 case Intrinsic::x86_ssse3_pshuf_b_128:
6931 case Intrinsic::x86_ssse3_pshuf_b:
6932 case Intrinsic::x86_avx512_pshuf_b_512:
6933 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6940 case Intrinsic::x86_avx512_mask_pmov_dw_128:
6941 case Intrinsic::x86_avx512_mask_pmov_db_128:
6942 case Intrinsic::x86_avx512_mask_pmov_qb_128:
6943 case Intrinsic::x86_avx512_mask_pmov_qw_128:
6944 case Intrinsic::x86_avx512_mask_pmov_qd_128:
6945 case Intrinsic::x86_avx512_mask_pmov_wb_128:
6946 case Intrinsic::x86_avx512_mask_pmov_dw_256:
6947 case Intrinsic::x86_avx512_mask_pmov_db_256:
6948 case Intrinsic::x86_avx512_mask_pmov_qb_256:
6949 case Intrinsic::x86_avx512_mask_pmov_qw_256:
6950 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6951 case Intrinsic::x86_avx512_mask_pmov_db_512:
6952 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6953 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6956 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6965 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6966 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6967 handleIntrinsicByApplyingToShadow(
6968 I, Intrinsic::x86_avx512_mask_pmov_dw_512,
6973 case Intrinsic::x86_avx512_mask_pmovs_dw_256:
6974 case Intrinsic::x86_avx512_mask_pmovus_dw_256:
6975 handleIntrinsicByApplyingToShadow(
6976 I, Intrinsic::x86_avx512_mask_pmov_dw_256,
6980 case Intrinsic::x86_avx512_mask_pmovs_dw_128:
6981 case Intrinsic::x86_avx512_mask_pmovus_dw_128:
6982 handleIntrinsicByApplyingToShadow(
6983 I, Intrinsic::x86_avx512_mask_pmov_dw_128,
6987 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6988 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6989 handleIntrinsicByApplyingToShadow(
6990 I, Intrinsic::x86_avx512_mask_pmov_db_512,
6995 case Intrinsic::x86_avx512_mask_pmovs_db_256:
6996 case Intrinsic::x86_avx512_mask_pmovus_db_256:
6997 handleIntrinsicByApplyingToShadow(
6998 I, Intrinsic::x86_avx512_mask_pmov_db_256,
7002 case Intrinsic::x86_avx512_mask_pmovs_db_128:
7003 case Intrinsic::x86_avx512_mask_pmovus_db_128:
7004 handleIntrinsicByApplyingToShadow(
7005 I, Intrinsic::x86_avx512_mask_pmov_db_128,
7009 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
7010 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
7011 handleIntrinsicByApplyingToShadow(
7012 I, Intrinsic::x86_avx512_mask_pmov_qb_512,
7017 case Intrinsic::x86_avx512_mask_pmovs_qb_256:
7018 case Intrinsic::x86_avx512_mask_pmovus_qb_256:
7019 handleIntrinsicByApplyingToShadow(
7020 I, Intrinsic::x86_avx512_mask_pmov_qb_256,
7024 case Intrinsic::x86_avx512_mask_pmovs_qb_128:
7025 case Intrinsic::x86_avx512_mask_pmovus_qb_128:
7026 handleIntrinsicByApplyingToShadow(
7027 I, Intrinsic::x86_avx512_mask_pmov_qb_128,
7031 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
7032 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
7033 handleIntrinsicByApplyingToShadow(
7034 I, Intrinsic::x86_avx512_mask_pmov_qw_512,
7039 case Intrinsic::x86_avx512_mask_pmovs_qw_256:
7040 case Intrinsic::x86_avx512_mask_pmovus_qw_256:
7041 handleIntrinsicByApplyingToShadow(
7042 I, Intrinsic::x86_avx512_mask_pmov_qw_256,
7046 case Intrinsic::x86_avx512_mask_pmovs_qw_128:
7047 case Intrinsic::x86_avx512_mask_pmovus_qw_128:
7048 handleIntrinsicByApplyingToShadow(
7049 I, Intrinsic::x86_avx512_mask_pmov_qw_128,
7053 case Intrinsic::x86_avx512_mask_pmovs_qd_128:
7054 case Intrinsic::x86_avx512_mask_pmovus_qd_128:
7055 handleIntrinsicByApplyingToShadow(
7056 I, Intrinsic::x86_avx512_mask_pmov_qd_128,
7060 case Intrinsic::x86_avx512_mask_pmovs_wb_128:
7061 case Intrinsic::x86_avx512_mask_pmovus_wb_128:
7062 handleIntrinsicByApplyingToShadow(
7063 I, Intrinsic::x86_avx512_mask_pmov_wb_128,
7067 case Intrinsic::x86_avx512_mask_pmovs_qd_256:
7068 case Intrinsic::x86_avx512_mask_pmovus_qd_256:
7069 case Intrinsic::x86_avx512_mask_pmovs_wb_256:
7070 case Intrinsic::x86_avx512_mask_pmovus_wb_256:
7071 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
7072 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
7073 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
7074 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
7078 handleAVX512VectorDownConvert(
I);
7089 case Intrinsic::x86_avx512_mask_compress:
7090 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7131 case Intrinsic::x86_avx512_rsqrt14_ps_512:
7132 case Intrinsic::x86_avx512_rsqrt14_ps_256:
7133 case Intrinsic::x86_avx512_rsqrt14_ps_128:
7134 case Intrinsic::x86_avx512_rsqrt14_pd_512:
7135 case Intrinsic::x86_avx512_rsqrt14_pd_256:
7136 case Intrinsic::x86_avx512_rsqrt14_pd_128:
7137 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
7138 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
7139 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
7140 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
7141 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
7142 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
7143 handleAVX512VectorGenericMaskedFP(
I, {0},
7184 case Intrinsic::x86_avx512_rcp14_ps_512:
7185 case Intrinsic::x86_avx512_rcp14_ps_256:
7186 case Intrinsic::x86_avx512_rcp14_ps_128:
7187 case Intrinsic::x86_avx512_rcp14_pd_512:
7188 case Intrinsic::x86_avx512_rcp14_pd_256:
7189 case Intrinsic::x86_avx512_rcp14_pd_128:
7190 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
7191 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
7192 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
7193 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
7194 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
7195 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
7196 handleAVX512VectorGenericMaskedFP(
I, {0},
7241 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
7242 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
7243 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
7244 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
7245 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
7246 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
7247 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
7248 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
7249 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
7250 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
7251 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
7252 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
7253 handleAVX512VectorGenericMaskedFP(
I, {0},
7289 case Intrinsic::x86_avx512_mask_scalef_pd_512:
7290 case Intrinsic::x86_avx512_mask_scalef_pd_256:
7291 case Intrinsic::x86_avx512_mask_scalef_pd_128:
7292 case Intrinsic::x86_avx512_mask_scalef_ps_512:
7293 case Intrinsic::x86_avx512_mask_scalef_ps_256:
7294 case Intrinsic::x86_avx512_mask_scalef_ps_128:
7295 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
7296 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
7297 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
7301 handleAVX512VectorGenericMaskedFP(
I, {0, 1},
7321 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
7322 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
7323 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
7324 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
7325 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
7326 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
7327 visitGenericScalarHalfwordInst(
I);
7334 case Intrinsic::x86_avx512_fpclass_pd_512:
7335 case Intrinsic::x86_avx512_fpclass_ps_512:
7336 handleAVX512FPClass(
I);
7340 case Intrinsic::x86_vgf2p8affineqb_128:
7341 case Intrinsic::x86_vgf2p8affineqb_256:
7342 case Intrinsic::x86_vgf2p8affineqb_512:
7343 handleAVXGF2P8Affine(
I);
7353 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &
I) {
7354 switch (
I.getIntrinsicID()) {
7358 case Intrinsic::aarch64_neon_rshrn:
7359 case Intrinsic::aarch64_neon_sqrshl:
7360 case Intrinsic::aarch64_neon_sqrshrn:
7361 case Intrinsic::aarch64_neon_sqrshrun:
7362 case Intrinsic::aarch64_neon_sqshl:
7363 case Intrinsic::aarch64_neon_sqshlu:
7364 case Intrinsic::aarch64_neon_sqshrn:
7365 case Intrinsic::aarch64_neon_sqshrun:
7366 case Intrinsic::aarch64_neon_srshl:
7367 case Intrinsic::aarch64_neon_sshl:
7368 case Intrinsic::aarch64_neon_uqrshl:
7369 case Intrinsic::aarch64_neon_uqrshrn:
7370 case Intrinsic::aarch64_neon_uqshl:
7371 case Intrinsic::aarch64_neon_uqshrn:
7372 case Intrinsic::aarch64_neon_urshl:
7373 case Intrinsic::aarch64_neon_ushl:
7374 handleVectorShiftIntrinsic(
I,
false);
7387 case Intrinsic::aarch64_neon_vsli:
7388 case Intrinsic::aarch64_neon_vsri:
7389 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7396 case Intrinsic::aarch64_neon_fmaxp:
7397 case Intrinsic::aarch64_neon_fminp:
7399 case Intrinsic::aarch64_neon_fmaxnmp:
7400 case Intrinsic::aarch64_neon_fminnmp:
7402 case Intrinsic::aarch64_neon_smaxp:
7403 case Intrinsic::aarch64_neon_sminp:
7404 case Intrinsic::aarch64_neon_umaxp:
7405 case Intrinsic::aarch64_neon_uminp:
7407 case Intrinsic::aarch64_neon_addp:
7409 case Intrinsic::aarch64_neon_faddp:
7411 case Intrinsic::aarch64_neon_saddlp:
7412 case Intrinsic::aarch64_neon_uaddlp: {
7413 handlePairwiseShadowOrIntrinsic(
I, 1);
7418 case Intrinsic::aarch64_neon_fcvtas:
7419 case Intrinsic::aarch64_neon_fcvtau:
7421 case Intrinsic::aarch64_neon_fcvtms:
7422 case Intrinsic::aarch64_neon_fcvtmu:
7424 case Intrinsic::aarch64_neon_fcvtns:
7425 case Intrinsic::aarch64_neon_fcvtnu:
7427 case Intrinsic::aarch64_neon_fcvtps:
7428 case Intrinsic::aarch64_neon_fcvtpu:
7430 case Intrinsic::aarch64_neon_fcvtzs:
7431 case Intrinsic::aarch64_neon_fcvtzu:
7433 case Intrinsic::aarch64_neon_fcvtxn:
7434 handleGenericVectorConvertIntrinsic(
I,
false);
7438 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7439 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7440 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7441 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7442 handleGenericVectorConvertIntrinsic(
I,
true);
7451 case Intrinsic::aarch64_neon_faddv:
7452 case Intrinsic::aarch64_neon_saddv:
7453 case Intrinsic::aarch64_neon_uaddv:
7456 case Intrinsic::aarch64_neon_smaxv:
7457 case Intrinsic::aarch64_neon_sminv:
7458 case Intrinsic::aarch64_neon_umaxv:
7459 case Intrinsic::aarch64_neon_uminv:
7463 case Intrinsic::aarch64_neon_fmaxv:
7464 case Intrinsic::aarch64_neon_fminv:
7465 case Intrinsic::aarch64_neon_fmaxnmv:
7466 case Intrinsic::aarch64_neon_fminnmv:
7468 case Intrinsic::aarch64_neon_saddlv:
7469 case Intrinsic::aarch64_neon_uaddlv:
7470 handleVectorReduceIntrinsic(
I,
true);
7473 case Intrinsic::aarch64_neon_ld1x2:
7474 case Intrinsic::aarch64_neon_ld1x3:
7475 case Intrinsic::aarch64_neon_ld1x4:
7476 case Intrinsic::aarch64_neon_ld2:
7477 case Intrinsic::aarch64_neon_ld3:
7478 case Intrinsic::aarch64_neon_ld4:
7479 case Intrinsic::aarch64_neon_ld2r:
7480 case Intrinsic::aarch64_neon_ld3r:
7481 case Intrinsic::aarch64_neon_ld4r: {
7482 handleNEONVectorLoad(
I,
false);
7486 case Intrinsic::aarch64_neon_ld2lane:
7487 case Intrinsic::aarch64_neon_ld3lane:
7488 case Intrinsic::aarch64_neon_ld4lane: {
7489 handleNEONVectorLoad(
I,
true);
7494 case Intrinsic::aarch64_neon_sqxtn:
7495 case Intrinsic::aarch64_neon_sqxtun:
7496 case Intrinsic::aarch64_neon_uqxtn:
7503 case Intrinsic::aarch64_neon_st1x2:
7504 case Intrinsic::aarch64_neon_st1x3:
7505 case Intrinsic::aarch64_neon_st1x4:
7506 case Intrinsic::aarch64_neon_st2:
7507 case Intrinsic::aarch64_neon_st3:
7508 case Intrinsic::aarch64_neon_st4: {
7509 handleNEONVectorStoreIntrinsic(
I,
false);
7513 case Intrinsic::aarch64_neon_st2lane:
7514 case Intrinsic::aarch64_neon_st3lane:
7515 case Intrinsic::aarch64_neon_st4lane: {
7516 handleNEONVectorStoreIntrinsic(
I,
true);
7529 case Intrinsic::aarch64_neon_tbl1:
7530 case Intrinsic::aarch64_neon_tbl2:
7531 case Intrinsic::aarch64_neon_tbl3:
7532 case Intrinsic::aarch64_neon_tbl4:
7533 case Intrinsic::aarch64_neon_tbx1:
7534 case Intrinsic::aarch64_neon_tbx2:
7535 case Intrinsic::aarch64_neon_tbx3:
7536 case Intrinsic::aarch64_neon_tbx4: {
7538 handleIntrinsicByApplyingToShadow(
7539 I,
I.getIntrinsicID(),
7544 case Intrinsic::aarch64_neon_fmulx:
7545 case Intrinsic::aarch64_neon_pmul:
7546 case Intrinsic::aarch64_neon_pmull:
7547 case Intrinsic::aarch64_neon_smull:
7548 case Intrinsic::aarch64_neon_pmull64:
7549 case Intrinsic::aarch64_neon_umull: {
7550 handleNEONVectorMultiplyIntrinsic(
I);
7554 case Intrinsic::aarch64_neon_smmla:
7555 case Intrinsic::aarch64_neon_ummla:
7556 case Intrinsic::aarch64_neon_usmmla:
7557 case Intrinsic::aarch64_neon_bfmmla:
7558 handleNEONMatrixMultiply(
I);
7565 case Intrinsic::aarch64_neon_sdot:
7566 case Intrinsic::aarch64_neon_udot:
7567 case Intrinsic::aarch64_neon_usdot:
7568 handleVectorDotProductIntrinsic(
I, 4,
7578 case Intrinsic::aarch64_neon_bfdot:
7579 handleVectorDotProductIntrinsic(
I, 2,
7592 case Intrinsic::aarch64_neon_fp8_fdot2:
7593 handleVectorDotProductIntrinsic(
I, 2,
7606 case Intrinsic::aarch64_neon_fp8_fdot4:
7607 handleVectorDotProductIntrinsic(
I, 4,
7617 case Intrinsic::aarch64_neon_fp8_fdot2_lane:
7618 handleNEONDotProductLaneIntrinsic(
I, 2);
7625 case Intrinsic::aarch64_neon_fp8_fdot4_lane:
7626 handleNEONDotProductLaneIntrinsic(
I, 4);
7630 case Intrinsic::aarch64_neon_facge:
7631 case Intrinsic::aarch64_neon_facgt:
7632 handleVectorComparePackedIntrinsic(
I,
false);
7642 void visitIntrinsicInst(IntrinsicInst &
I) {
7643 if (maybeHandleCrossPlatformIntrinsic(
I))
7646 if (maybeHandleX86SIMDIntrinsic(
I))
7649 if (maybeHandleArmSIMDIntrinsic(
I))
7652 if (maybeHandleUnknownIntrinsic(
I))
7655 visitInstruction(
I);
7658 void visitLibAtomicLoad(CallBase &CB) {
7669 Value *NewOrdering =
7673 NextNodeIRBuilder NextIRB(&CB);
7674 Value *SrcShadowPtr, *SrcOriginPtr;
7675 std::tie(SrcShadowPtr, SrcOriginPtr) =
7676 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7678 Value *DstShadowPtr =
7679 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7683 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
7684 if (MS.TrackOrigins) {
7685 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7687 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7688 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7692 void visitLibAtomicStore(CallBase &CB) {
7699 Value *NewOrdering =
7703 Value *DstShadowPtr =
7713 void visitCallBase(CallBase &CB) {
7720 if (Opts.msan_handle_asm_conservative)
7721 visitAsmInstruction(CB);
7723 visitInstruction(CB);
7726 LibFunc LF =
TLI->getLibFunc(CB);
7727 if (LF != NotLibFunc) {
7732 case LibFunc_atomic_load:
7734 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
7738 visitLibAtomicLoad(CB);
7740 case LibFunc_atomic_store:
7741 visitLibAtomicStore(CB);
7757 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7761 Func->removeFnAttrs(
B);
7767 bool MayCheckCall = MS.EagerChecks;
7771 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
7774 unsigned ArgOffset = 0;
7777 if (!
A->getType()->isSized()) {
7778 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
7782 if (
A->getType()->isScalableTy()) {
7783 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
7785 insertCheckShadowOf(
A, &CB);
7790 const DataLayout &
DL =
F.getDataLayout();
7794 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7797 insertCheckShadowOf(
A, &CB);
7798 Size =
DL.getTypeAllocSize(
A->getType());
7804 Value *ArgShadow = getShadow(
A);
7805 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7807 <<
" Shadow: " << *ArgShadow <<
"\n");
7811 assert(
A->getType()->isPointerTy() &&
7812 "ByVal argument is not a pointer!");
7820 Value *AShadowPtr, *AOriginPtr;
7821 std::tie(AShadowPtr, AOriginPtr) =
7822 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
7824 if (!PropagateShadow) {
7831 if (MS.TrackOrigins) {
7832 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7846 Size =
DL.getTypeAllocSize(
A->getType());
7852 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
7854 getOriginPtrForArgument(IRB, ArgOffset));
7866 if (FT->isVarArg()) {
7867 VAHelper->visitCallBase(CB, IRB);
7877 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
7878 setShadow(&CB, getCleanShadow(&CB));
7879 setOrigin(&CB, getCleanOrigin());
7885 Value *
Base = getShadowPtrForRetval(IRBBefore);
7886 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
7898 setShadow(&CB, getCleanShadow(&CB));
7899 setOrigin(&CB, getCleanOrigin());
7906 "Could not find insertion point for retval shadow load");
7909 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7912 setShadow(&CB, RetvalShadow);
7913 if (MS.TrackOrigins)
7914 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7919 RetVal =
I->getOperand(0);
7922 return I->isMustTailCall();
7927 void visitReturnInst(ReturnInst &
I) {
7929 Value *RetVal =
I.getReturnValue();
7935 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7936 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
7937 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7940 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
7942 Value *Shadow = getShadow(RetVal);
7943 bool StoreOrigin =
true;
7945 insertCheckShadowOf(RetVal, &
I);
7946 Shadow = getCleanShadow(RetVal);
7947 StoreOrigin =
false;
7954 if (MS.TrackOrigins && StoreOrigin)
7955 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7959 void visitPHINode(PHINode &
I) {
7961 if (!PropagateShadow) {
7962 setShadow(&
I, getCleanShadow(&
I));
7963 setOrigin(&
I, getCleanOrigin());
7967 ShadowPHINodes.push_back(&
I);
7968 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
7970 if (MS.TrackOrigins)
7972 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
7975 Value *getLocalVarIdptr(AllocaInst &
I) {
7976 ConstantInt *IntConst =
7977 ConstantInt::get(Type::getInt32Ty((*
F.getParent()).getContext()), 0);
7978 return new GlobalVariable(*
F.getParent(), IntConst->
getType(),
7983 Value *getLocalVarDescription(AllocaInst &
I) {
7988 if (PoisonStack && Opts.msan_poison_stack_with_call) {
7989 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7991 Value *ShadowBase, *OriginBase;
7992 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7995 Value *PoisonValue =
7996 IRB.
getInt8(PoisonStack ? Opts.msan_poison_stack_pattern : 0);
7997 IRB.
CreateMemSet(ShadowBase, PoisonValue, Len,
I.getAlign());
8000 if (PoisonStack && MS.TrackOrigins) {
8001 Value *Idptr = getLocalVarIdptr(
I);
8002 if (Opts.msan_print_stack_names) {
8003 Value *Descr = getLocalVarDescription(
I);
8004 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
8005 {&I, Len, Idptr, Descr});
8007 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
8013 Value *Descr = getLocalVarDescription(
I);
8015 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
8017 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
8021 void instrumentAlloca(AllocaInst &
I, Instruction *InsPoint =
nullptr) {
8024 NextNodeIRBuilder IRB(InsPoint);
8027 if (MS.CompileKernel)
8028 poisonAllocaKmsan(
I, IRB, Len);
8030 poisonAllocaUserspace(
I, IRB, Len);
8033 void visitAllocaInst(AllocaInst &
I) {
8034 setShadow(&
I, getCleanShadow(&
I));
8035 setOrigin(&
I, getCleanOrigin());
8041 void visitSelectInst(SelectInst &
I) {
8047 handleSelectLikeInst(
I,
B,
C,
D);
8053 Value *Sb = getShadow(
B);
8054 Value *Sc = getShadow(
C);
8055 Value *Sd = getShadow(
D);
8057 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
8058 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
8059 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
8064 if (
I.getType()->isAggregateType()) {
8068 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
8069 }
else if (isScalableNonVectorType(
I.getType())) {
8077 Sa1 = getCleanShadow(getShadowTy(
I.getType()));
8085 C = CreateAppToShadowCast(IRB,
C);
8086 D = CreateAppToShadowCast(IRB,
D);
8093 if (MS.TrackOrigins) {
8096 if (
B->getType()->isVectorTy()) {
8097 B = convertToBool(
B, IRB);
8098 Sb = convertToBool(Sb, IRB);
8106 void visitLandingPadInst(LandingPadInst &
I) {
8109 setShadow(&
I, getCleanShadow(&
I));
8110 setOrigin(&
I, getCleanOrigin());
8113 void visitCatchSwitchInst(CatchSwitchInst &
I) {
8114 setShadow(&
I, getCleanShadow(&
I));
8115 setOrigin(&
I, getCleanOrigin());
8118 void visitFuncletPadInst(FuncletPadInst &
I) {
8119 setShadow(&
I, getCleanShadow(&
I));
8120 setOrigin(&
I, getCleanOrigin());
8123 void visitGetElementPtrInst(GetElementPtrInst &
I) { handleShadowOr(
I); }
8125 void visitExtractValueInst(ExtractValueInst &
I) {
8127 Value *Agg =
I.getAggregateOperand();
8129 Value *AggShadow = getShadow(Agg);
8133 setShadow(&
I, ResShadow);
8134 setOriginForNaryOp(
I);
8137 void visitInsertValueInst(InsertValueInst &
I) {
8140 Value *AggShadow = getShadow(
I.getAggregateOperand());
8141 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
8147 setOriginForNaryOp(
I);
8150 void dumpInst(Instruction &
I,
const Twine &Prefix) {
8157 << CI->getCalledFunction()->
getName() <<
"\n";
8159 errs() <<
"ZZZ:" <<
Prefix <<
" " <<
I.getOpcodeName() <<
"\n";
8166 unsigned NumOperands =
I.getNumOperands();
8168 errs() <<
"YYY:" <<
Prefix <<
" call " << *
I.getType() <<
" @";
8180 errs() <<
"YYY:" <<
Prefix <<
" " << *
I.getType() <<
" "
8181 <<
I.getOpcodeName() <<
"(";
8183 for (
size_t i = 0; i < NumOperands; i++) {
8201 void visitResumeInst(ResumeInst &
I) {
8206 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
8211 void visitCatchReturnInst(CatchReturnInst &CRI) {
8216 void instrumentAsmArgument(
Value *Operand,
Type *ElemTy, Instruction &
I,
8225 insertCheckShadowOf(Operand, &
I);
8232 auto Size =
DL.getTypeStoreSize(ElemTy);
8234 if (MS.CompileKernel) {
8235 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
8241 auto [ShadowPtr,
_] =
8242 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
8252 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
8253 int NumRetOutputs = 0;
8260 NumRetOutputs =
ST->getNumElements();
8265 for (
const InlineAsm::ConstraintInfo &Info : Constraints) {
8266 switch (
Info.Type) {
8274 return NumOutputs - NumRetOutputs;
8277 void visitAsmInstruction(Instruction &
I) {
8293 const DataLayout &
DL =
F.getDataLayout();
8297 int OutputArgs = getNumOutputArgs(IA, CB);
8303 for (
int i = OutputArgs; i < NumOperands; i++) {
8311 for (
int i = 0; i < OutputArgs; i++) {
8317 setShadow(&
I, getCleanShadow(&
I));
8318 setOrigin(&
I, getCleanOrigin());
8321 void visitFreezeInst(FreezeInst &
I) {
8323 setShadow(&
I, getCleanShadow(&
I));
8324 setOrigin(&
I, getCleanOrigin());
8327 void visitInstruction(Instruction &
I) {
8329 if (Opts.msan_dump_strict_instructions)
8330 dumpInst(
I,
"Strict");
8332 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
8333 Value *Operand =
I.getOperand(i);
8335 insertCheckShadowOf(Operand, &
I);
8337 setShadow(&
I, getCleanShadow(&
I));
8338 setOrigin(&
I, getCleanOrigin());
8342struct VarArgHelperBase :
public VarArgHelper {
8344 MemorySanitizer &MS;
8345 MemorySanitizerVisitor &MSV;
8347 const unsigned VAListTagSize;
8349 VarArgHelperBase(
Function &
F, MemorySanitizer &MS,
8350 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
8351 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
8355 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
8370 return getShadowPtrForVAArgument(IRB, ArgOffset);
8383 unsigned BaseOffset) {
8392 TailSize,
Align(8));
8395 void unpoisonVAListTagForInst(IntrinsicInst &
I) {
8397 Value *VAListTag =
I.getArgOperand(0);
8399 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
8400 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
8403 VAListTagSize, Alignment,
false);
8406 void visitVAStartInst(VAStartInst &
I)
override {
8407 if (
F.getCallingConv() == CallingConv::Win64)
8410 unpoisonVAListTagForInst(
I);
8413 void visitVACopyInst(VACopyInst &
I)
override {
8414 if (
F.getCallingConv() == CallingConv::Win64)
8416 unpoisonVAListTagForInst(
I);
8421struct VarArgAMD64Helper :
public VarArgHelperBase {
8424 static const unsigned AMD64GpEndOffset = 48;
8425 static const unsigned AMD64FpEndOffsetSSE = 176;
8427 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8429 unsigned AMD64FpEndOffset;
8430 AllocaInst *VAArgTLSCopy =
nullptr;
8431 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8432 Value *VAArgOverflowSize =
nullptr;
8434 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8436 VarArgAMD64Helper(
Function &
F, MemorySanitizer &MS,
8437 MemorySanitizerVisitor &MSV)
8438 : VarArgHelperBase(
F, MS, MSV, 24) {
8439 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8440 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
8441 if (Attr.isStringAttribute() &&
8442 (Attr.getKindAsString() ==
"target-features")) {
8443 if (Attr.getValueAsString().contains(
"-sse"))
8444 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8450 ArgKind classifyArgument(
Value *arg) {
8453 if (
T->isX86_FP80Ty())
8455 if (
T->isFPOrFPVectorTy())
8456 return AK_FloatingPoint;
8457 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
8458 return AK_GeneralPurpose;
8459 if (
T->isPointerTy())
8460 return AK_GeneralPurpose;
8472 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8473 unsigned GpOffset = 0;
8474 unsigned FpOffset = AMD64GpEndOffset;
8475 unsigned OverflowOffset = AMD64FpEndOffset;
8476 const DataLayout &
DL =
F.getDataLayout();
8487 assert(
A->getType()->isPointerTy());
8489 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8491 unsigned BaseOffset = OverflowOffset;
8492 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8493 Value *OriginBase =
nullptr;
8494 if (MS.TrackOrigins)
8495 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8496 OverflowOffset += AlignedSize;
8499 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8503 Value *ShadowPtr, *OriginPtr;
8504 std::tie(ShadowPtr, OriginPtr) =
8509 if (MS.TrackOrigins)
8513 ArgKind AK = classifyArgument(
A);
8514 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8516 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8518 Value *ShadowBase, *OriginBase =
nullptr;
8520 case AK_GeneralPurpose:
8521 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8522 if (MS.TrackOrigins)
8523 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8527 case AK_FloatingPoint:
8528 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8529 if (MS.TrackOrigins)
8530 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8537 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8539 unsigned BaseOffset = OverflowOffset;
8540 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8541 if (MS.TrackOrigins) {
8542 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8544 OverflowOffset += AlignedSize;
8547 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8556 Value *Shadow = MSV.getShadow(
A);
8558 if (MS.TrackOrigins) {
8559 Value *Origin = MSV.getOrigin(
A);
8560 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8561 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8567 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8568 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8571 void finalizeInstrumentation()
override {
8572 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8573 "finalizeInstrumentation called twice");
8574 if (!VAStartInstrumentationList.
empty()) {
8581 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8582 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8588 Intrinsic::umin, CopySize,
8592 if (MS.TrackOrigins) {
8593 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8602 for (CallInst *OrigInst : VAStartInstrumentationList) {
8603 NextNodeIRBuilder IRB(OrigInst);
8604 Value *VAListTag = OrigInst->getArgOperand(0);
8606 Value *RegSaveAreaPtrPtr =
8609 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8611 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8612 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8614 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8616 if (MS.TrackOrigins)
8617 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8618 Alignment, AMD64FpEndOffset);
8619 Value *OverflowArgAreaPtrPtr =
8621 Value *OverflowArgAreaPtr =
8622 IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8623 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8624 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8625 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8629 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8631 if (MS.TrackOrigins) {
8634 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8642struct VarArgAArch64Helper :
public VarArgHelperBase {
8643 static const unsigned kAArch64GrArgSize = 64;
8644 static const unsigned kAArch64VrArgSize = 128;
8646 static const unsigned AArch64GrBegOffset = 0;
8647 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8649 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8650 static const unsigned AArch64VrEndOffset =
8651 AArch64VrBegOffset + kAArch64VrArgSize;
8652 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8654 AllocaInst *VAArgTLSCopy =
nullptr;
8655 Value *VAArgOverflowSize =
nullptr;
8657 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8659 VarArgAArch64Helper(
Function &
F, MemorySanitizer &MS,
8660 MemorySanitizerVisitor &MSV)
8661 : VarArgHelperBase(
F, MS, MSV, 32) {}
8664 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
8665 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
8666 return {AK_GeneralPurpose, 1};
8667 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
8668 return {AK_FloatingPoint, 1};
8670 if (
T->isArrayTy()) {
8671 auto R = classifyArgument(
T->getArrayElementType());
8672 R.second *=
T->getScalarType()->getArrayNumElements();
8677 auto R = classifyArgument(FV->getScalarType());
8678 R.second *= FV->getNumElements();
8683 return {AK_Memory, 0};
8695 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8696 unsigned GrOffset = AArch64GrBegOffset;
8697 unsigned VrOffset = AArch64VrBegOffset;
8698 unsigned OverflowOffset = AArch64VAEndOffset;
8700 const DataLayout &
DL =
F.getDataLayout();
8703 auto [AK, RegNum] = classifyArgument(
A->getType());
8704 if (AK == AK_GeneralPurpose &&
8705 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8707 if (AK == AK_FloatingPoint &&
8708 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8712 case AK_GeneralPurpose:
8713 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8714 GrOffset += 8 * RegNum;
8716 case AK_FloatingPoint:
8717 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8718 VrOffset += 16 * RegNum;
8725 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8727 unsigned BaseOffset = OverflowOffset;
8728 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8729 OverflowOffset += AlignedSize;
8732 CleanUnusedTLS(IRB,
Base, BaseOffset);
8744 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8745 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8750 Value *SaveAreaPtrPtr =
8752 return IRB.
CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8759 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
8762 void finalizeInstrumentation()
override {
8763 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8764 "finalizeInstrumentation called twice");
8765 if (!VAStartInstrumentationList.empty()) {
8772 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8773 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8779 Intrinsic::umin, CopySize,
8785 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8786 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8790 for (CallInst *OrigInst : VAStartInstrumentationList) {
8791 NextNodeIRBuilder IRB(OrigInst);
8793 Value *VAListTag = OrigInst->getArgOperand(0);
8810 Value *StackSaveAreaPtr =
8811 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8814 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8815 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8818 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8821 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8822 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8825 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8831 Value *GrRegSaveAreaShadowPtrOff =
8832 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
8834 Value *GrRegSaveAreaShadowPtr =
8835 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8841 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8847 Value *VrRegSaveAreaShadowPtrOff =
8848 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
8850 Value *VrRegSaveAreaShadowPtr =
8851 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8858 VrRegSaveAreaShadowPtrOff);
8859 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8865 Value *StackSaveAreaShadowPtr =
8866 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8874 Align(16), VAArgOverflowSize);
8880struct VarArgPowerPC64Helper :
public VarArgHelperBase {
8881 AllocaInst *VAArgTLSCopy =
nullptr;
8882 Value *VAArgSize =
nullptr;
8884 VarArgPowerPC64Helper(
Function &
F, MemorySanitizer &MS,
8885 MemorySanitizerVisitor &MSV)
8886 : VarArgHelperBase(
F, MS, MSV, 8) {}
8888 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8896 Triple TargetTriple(
F.getParent()->getTargetTriple());
8900 if (TargetTriple.isPPC64ELFv2ABI())
8904 unsigned VAArgOffset = VAArgBase;
8905 const DataLayout &
DL =
F.getDataLayout();
8910 assert(
A->getType()->isPointerTy());
8912 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8915 ArgAlign =
Align(8);
8916 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8919 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8921 Value *AShadowPtr, *AOriginPtr;
8922 std::tie(AShadowPtr, AOriginPtr) =
8923 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8933 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8935 if (
A->getType()->isArrayTy()) {
8938 Type *ElementTy =
A->getType()->getArrayElementType();
8940 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8941 }
else if (
A->getType()->isVectorTy()) {
8943 ArgAlign =
Align(ArgSize);
8946 ArgAlign =
Align(8);
8947 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8948 if (
DL.isBigEndian()) {
8952 VAArgOffset += (8 - ArgSize);
8956 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8960 VAArgOffset += ArgSize;
8964 VAArgBase = VAArgOffset;
8968 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8971 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8974 void finalizeInstrumentation()
override {
8975 assert(!VAArgSize && !VAArgTLSCopy &&
8976 "finalizeInstrumentation called twice");
8979 Value *CopySize = VAArgSize;
8981 if (!VAStartInstrumentationList.empty()) {
8985 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8991 Intrinsic::umin, CopySize,
8999 for (CallInst *OrigInst : VAStartInstrumentationList) {
9000 NextNodeIRBuilder IRB(OrigInst);
9001 Value *VAListTag = OrigInst->getArgOperand(0);
9004 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9007 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9008 const DataLayout &
DL =
F.getDataLayout();
9009 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9011 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9012 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9014 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9021struct VarArgPowerPC32Helper :
public VarArgHelperBase {
9022 AllocaInst *VAArgTLSCopy =
nullptr;
9023 Value *VAArgSize =
nullptr;
9025 VarArgPowerPC32Helper(
Function &
F, MemorySanitizer &MS,
9026 MemorySanitizerVisitor &MSV)
9027 : VarArgHelperBase(
F, MS, MSV, 12) {}
9029 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9033 unsigned VAArgOffset = VAArgBase;
9034 const DataLayout &
DL =
F.getDataLayout();
9035 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9040 assert(
A->getType()->isPointerTy());
9042 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9044 if (ArgAlign < IntptrSize)
9045 ArgAlign =
Align(IntptrSize);
9046 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9049 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
9051 Value *AShadowPtr, *AOriginPtr;
9052 std::tie(AShadowPtr, AOriginPtr) =
9053 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9063 Type *ArgTy =
A->getType();
9069 uint64_t ArgSize =
DL.getTypeAllocSize(ArgTy);
9076 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
9079 ArgAlign =
Align(ArgSize);
9081 if (ArgAlign < IntptrSize)
9082 ArgAlign =
Align(IntptrSize);
9083 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9084 if (
DL.isBigEndian()) {
9087 if (ArgSize < IntptrSize)
9088 VAArgOffset += (IntptrSize - ArgSize);
9091 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
9097 VAArgOffset += ArgSize;
9104 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
9107 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9110 void finalizeInstrumentation()
override {
9111 assert(!VAArgSize && !VAArgTLSCopy &&
9112 "finalizeInstrumentation called twice");
9114 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9115 Value *CopySize = VAArgSize;
9117 if (!VAStartInstrumentationList.empty()) {
9121 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9127 Intrinsic::umin, CopySize,
9135 for (CallInst *OrigInst : VAStartInstrumentationList) {
9136 NextNodeIRBuilder IRB(OrigInst);
9137 Value *VAListTag = OrigInst->getArgOperand(0);
9139 Value *RegSaveAreaSize = CopySize;
9143 IRB.
CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
9147 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
9149 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9152 const DataLayout &
DL =
F.getDataLayout();
9153 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9157 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9158 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9159 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9161 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
9162 Alignment, RegSaveAreaSize);
9164 RegSaveAreaShadowPtr =
9167 ConstantInt::get(MS.IntptrTy, 32));
9172 ConstantInt::get(MS.IntptrTy, 32), Alignment);
9177 Value *OverflowAreaSize = IRB.
CreateSub(CopySize, RegSaveAreaSize);
9180 OverflowAreaPtrPtr =
9181 IRB.
CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
9182 OverflowAreaPtrPtr = IRB.
CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
9184 Value *OverflowAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
9186 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
9187 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
9188 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.
getInt8Ty(),
9191 Value *OverflowVAArgTLSCopyPtr =
9193 OverflowVAArgTLSCopyPtr =
9194 IRB.
CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
9196 OverflowVAArgTLSCopyPtr =
9199 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
9206struct VarArgSystemZHelper :
public VarArgHelperBase {
9207 static const unsigned SystemZGpOffset = 16;
9208 static const unsigned SystemZGpEndOffset = 56;
9209 static const unsigned SystemZFpOffset = 128;
9210 static const unsigned SystemZFpEndOffset = 160;
9211 static const unsigned SystemZMaxVrArgs = 8;
9212 static const unsigned SystemZRegSaveAreaSize = 160;
9213 static const unsigned SystemZOverflowOffset = 160;
9214 static const unsigned SystemZVAListTagSize = 32;
9215 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
9216 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
9218 bool IsSoftFloatABI;
9219 AllocaInst *VAArgTLSCopy =
nullptr;
9220 AllocaInst *VAArgTLSOriginCopy =
nullptr;
9221 Value *VAArgOverflowSize =
nullptr;
9223 enum class ArgKind {
9233 VarArgSystemZHelper(
Function &
F, MemorySanitizer &MS,
9234 MemorySanitizerVisitor &MSV)
9235 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
9236 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
9238 ArgKind classifyArgument(
Type *
T) {
9245 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
9246 return ArgKind::Indirect;
9247 if (
T->isFloatingPointTy())
9248 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
9249 if (
T->isIntegerTy() ||
T->isPointerTy())
9250 return ArgKind::GeneralPurpose;
9251 if (
T->isVectorTy())
9252 return ArgKind::Vector;
9253 return ArgKind::Memory;
9256 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
9266 return ShadowExtension::Zero;
9270 return ShadowExtension::Sign;
9272 return ShadowExtension::None;
9275 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9276 unsigned GpOffset = SystemZGpOffset;
9277 unsigned FpOffset = SystemZFpOffset;
9278 unsigned VrIndex = 0;
9279 unsigned OverflowOffset = SystemZOverflowOffset;
9280 const DataLayout &
DL =
F.getDataLayout();
9286 ArgKind AK = classifyArgument(
T);
9287 if (AK == ArgKind::Indirect) {
9289 AK = ArgKind::GeneralPurpose;
9291 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
9292 AK = ArgKind::Memory;
9293 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
9294 AK = ArgKind::Memory;
9295 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
9296 AK = ArgKind::Memory;
9297 Value *ShadowBase =
nullptr;
9298 Value *OriginBase =
nullptr;
9299 ShadowExtension SE = ShadowExtension::None;
9301 case ArgKind::GeneralPurpose: {
9306 SE = getShadowExtension(CB, ArgNo);
9308 if (SE == ShadowExtension::None) {
9310 assert(ArgAllocSize <= ArgSize);
9311 GapSize = ArgSize - ArgAllocSize;
9313 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
9314 if (MS.TrackOrigins)
9315 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
9317 GpOffset += ArgSize;
9323 case ArgKind::FloatingPoint: {
9332 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
9333 if (MS.TrackOrigins)
9334 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
9336 FpOffset += ArgSize;
9342 case ArgKind::Vector: {
9349 case ArgKind::Memory: {
9357 SE = getShadowExtension(CB, ArgNo);
9359 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
9361 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
9362 if (MS.TrackOrigins)
9364 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
9365 OverflowOffset += ArgSize;
9372 case ArgKind::Indirect:
9375 if (ShadowBase ==
nullptr)
9377 Value *Shadow = MSV.getShadow(
A);
9378 if (SE != ShadowExtension::None)
9379 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
9380 SE == ShadowExtension::Sign);
9381 ShadowBase = IRB.
CreateIntToPtr(ShadowBase, MS.PtrTy,
"_msarg_va_s");
9383 if (MS.TrackOrigins) {
9384 Value *Origin = MSV.getOrigin(
A);
9385 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
9386 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
9390 Constant *OverflowSize = ConstantInt::get(
9391 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
9392 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
9399 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
9402 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9404 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9405 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
9410 unsigned RegSaveAreaSize =
9411 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9412 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9414 if (MS.TrackOrigins)
9415 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9416 Alignment, RegSaveAreaSize);
9425 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9427 Value *OverflowArgAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9428 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9430 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9431 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
9434 SystemZOverflowOffset);
9435 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9437 if (MS.TrackOrigins) {
9439 SystemZOverflowOffset);
9440 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9445 void finalizeInstrumentation()
override {
9446 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9447 "finalizeInstrumentation called twice");
9448 if (!VAStartInstrumentationList.empty()) {
9455 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9457 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9463 Intrinsic::umin, CopySize,
9467 if (MS.TrackOrigins) {
9468 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9477 for (CallInst *OrigInst : VAStartInstrumentationList) {
9478 NextNodeIRBuilder IRB(OrigInst);
9479 Value *VAListTag = OrigInst->getArgOperand(0);
9480 copyRegSaveArea(IRB, VAListTag);
9481 copyOverflowArea(IRB, VAListTag);
9487struct VarArgI386Helper :
public VarArgHelperBase {
9488 AllocaInst *VAArgTLSCopy =
nullptr;
9489 Value *VAArgSize =
nullptr;
9491 VarArgI386Helper(
Function &
F, MemorySanitizer &MS,
9492 MemorySanitizerVisitor &MSV)
9493 : VarArgHelperBase(
F, MS, MSV, 4) {}
9495 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9496 const DataLayout &
DL =
F.getDataLayout();
9497 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9498 unsigned VAArgOffset = 0;
9503 assert(
A->getType()->isPointerTy());
9505 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9507 if (ArgAlign < IntptrSize)
9508 ArgAlign =
Align(IntptrSize);
9509 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9511 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9513 Value *AShadowPtr, *AOriginPtr;
9514 std::tie(AShadowPtr, AOriginPtr) =
9515 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9525 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9527 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9528 if (
DL.isBigEndian()) {
9531 if (ArgSize < IntptrSize)
9532 VAArgOffset += (IntptrSize - ArgSize);
9535 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9538 VAArgOffset += ArgSize;
9544 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9547 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9550 void finalizeInstrumentation()
override {
9551 assert(!VAArgSize && !VAArgTLSCopy &&
9552 "finalizeInstrumentation called twice");
9554 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9555 Value *CopySize = VAArgSize;
9557 if (!VAStartInstrumentationList.empty()) {
9560 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9566 Intrinsic::umin, CopySize,
9574 for (CallInst *OrigInst : VAStartInstrumentationList) {
9575 NextNodeIRBuilder IRB(OrigInst);
9576 Value *VAListTag = OrigInst->getArgOperand(0);
9577 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9578 Value *RegSaveAreaPtrPtr =
9580 PointerType::get(*MS.C, 0));
9581 Value *RegSaveAreaPtr =
9582 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9583 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9584 const DataLayout &
DL =
F.getDataLayout();
9585 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9587 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9588 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9590 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9598struct VarArgGenericHelper :
public VarArgHelperBase {
9599 AllocaInst *VAArgTLSCopy =
nullptr;
9600 Value *VAArgSize =
nullptr;
9602 VarArgGenericHelper(
Function &
F, MemorySanitizer &MS,
9603 MemorySanitizerVisitor &MSV,
const unsigned VAListTagSize)
9604 : VarArgHelperBase(
F, MS, MSV, VAListTagSize) {}
9606 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9607 unsigned VAArgOffset = 0;
9608 const DataLayout &
DL =
F.getDataLayout();
9609 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9614 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9615 if (
DL.isBigEndian()) {
9618 if (ArgSize < IntptrSize)
9619 VAArgOffset += (IntptrSize - ArgSize);
9621 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9622 VAArgOffset += ArgSize;
9623 VAArgOffset =
alignTo(VAArgOffset, IntptrSize);
9629 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9632 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9635 void finalizeInstrumentation()
override {
9636 assert(!VAArgSize && !VAArgTLSCopy &&
9637 "finalizeInstrumentation called twice");
9639 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9640 Value *CopySize = VAArgSize;
9642 if (!VAStartInstrumentationList.empty()) {
9645 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9651 Intrinsic::umin, CopySize,
9659 for (CallInst *OrigInst : VAStartInstrumentationList) {
9660 NextNodeIRBuilder IRB(OrigInst);
9661 Value *VAListTag = OrigInst->getArgOperand(0);
9662 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9663 Value *RegSaveAreaPtrPtr =
9665 PointerType::get(*MS.C, 0));
9666 Value *RegSaveAreaPtr =
9667 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9668 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9669 const DataLayout &
DL =
F.getDataLayout();
9670 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9672 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9673 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9675 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9683using VarArgARM32Helper = VarArgGenericHelper;
9684using VarArgRISCVHelper = VarArgGenericHelper;
9685using VarArgMIPSHelper = VarArgGenericHelper;
9686using VarArgLoongArch64Helper = VarArgGenericHelper;
9687using VarArgHexagonHelper = VarArgGenericHelper;
9690struct VarArgNoOpHelper :
public VarArgHelper {
9691 VarArgNoOpHelper(
Function &
F, MemorySanitizer &MS,
9692 MemorySanitizerVisitor &MSV) {}
9694 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {}
9696 void visitVAStartInst(VAStartInst &
I)
override {}
9698 void visitVACopyInst(VACopyInst &
I)
override {}
9700 void finalizeInstrumentation()
override {}
9706 MemorySanitizerVisitor &Visitor) {
9709 Triple TargetTriple(Func.getParent()->getTargetTriple());
9712 return new VarArgI386Helper(Func, Msan, Visitor);
9715 return new VarArgAMD64Helper(Func, Msan, Visitor);
9717 if (TargetTriple.
isARM())
9718 return new VarArgARM32Helper(Func, Msan, Visitor, 4);
9721 return new VarArgAArch64Helper(Func, Msan, Visitor);
9724 return new VarArgSystemZHelper(Func, Msan, Visitor);
9729 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9732 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9735 return new VarArgRISCVHelper(Func, Msan, Visitor, 4);
9738 return new VarArgRISCVHelper(Func, Msan, Visitor, 8);
9741 return new VarArgMIPSHelper(Func, Msan, Visitor, 4);
9744 return new VarArgMIPSHelper(Func, Msan, Visitor, 8);
9747 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9751 return new VarArgHexagonHelper(Func, Msan, Visitor, 12);
9753 return new VarArgNoOpHelper(Func, Msan, Visitor);
9760 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9763 MemorySanitizerVisitor Visitor(
F, *
this,
TLI);
9770 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 * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="", bool HasSameSign=false)
LLVM_ABI Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
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 * 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 * 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)