185#include "llvm/IR/IntrinsicsAArch64.h"
186#include "llvm/IR/IntrinsicsX86.h"
216#define DEBUG_TYPE "msan"
219 "Controls which checks to insert");
222 "Controls which instruction to instrument");
245struct MemoryMapParams {
252struct PlatformMemoryMapParams {
253 const MemoryMapParams *bits32;
254 const MemoryMapParams *bits64;
431class MemorySanitizer {
433 MemorySanitizer(
const InstrumentationOptions &Opts,
Module &M,
434 MemorySanitizerOptions
Options)
437 EagerChecks(
Options.EagerChecks) {
442 MemorySanitizer(MemorySanitizer &&) =
delete;
443 MemorySanitizer &operator=(MemorySanitizer &&) =
delete;
444 MemorySanitizer(
const MemorySanitizer &) =
delete;
445 MemorySanitizer &operator=(
const MemorySanitizer &) =
delete;
447 bool sanitizeFunction(
Function &
F, TargetLibraryInfo &TLI);
450 friend struct MemorySanitizerVisitor;
451 friend struct VarArgHelperBase;
452 friend struct VarArgAMD64Helper;
453 friend struct VarArgAArch64Helper;
454 friend struct VarArgPowerPC64Helper;
455 friend struct VarArgPowerPC32Helper;
456 friend struct VarArgSystemZHelper;
457 friend struct VarArgI386Helper;
458 friend struct VarArgGenericHelper;
460 void initializeModule(
Module &M);
461 void initializeCallbacks(
Module &M,
const TargetLibraryInfo &TLI);
462 void createKernelApi(
Module &M,
const TargetLibraryInfo &TLI);
463 void createUserspaceApi(
Module &M,
const TargetLibraryInfo &TLI);
465 template <
typename... ArgsTy>
466 FunctionCallee getOrInsertMsanMetadataFunction(
Module &M, StringRef Name,
469 const InstrumentationOptions &Opts;
493 Value *ParamOriginTLS;
499 Value *RetvalOriginTLS;
505 Value *VAArgOriginTLS;
508 Value *VAArgOverflowSizeTLS;
511 bool CallbacksInitialized =
false;
514 FunctionCallee WarningFn;
518 FunctionCallee MaybeWarningVarSizeFn;
523 FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
525 FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
528 FunctionCallee MsanPoisonStackFn;
532 FunctionCallee MsanChainOriginFn;
535 FunctionCallee MsanSetOriginFn;
538 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
541 StructType *MsanContextStateTy;
542 FunctionCallee MsanGetContextStateFn;
545 FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
551 FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
552 FunctionCallee MsanMetadataPtrForLoad_1_8[4];
553 FunctionCallee MsanMetadataPtrForStore_1_8[4];
554 FunctionCallee MsanInstrumentAsmStoreFn;
557 Value *MsanMetadataAlloca;
560 FunctionCallee getKmsanShadowOriginAccessFn(
bool isStore,
int size);
563 const MemoryMapParams *MapParams;
567 MemoryMapParams CustomMapParams;
569 MDNode *ColdCallWeights;
572 MDNode *OriginStoreWeights;
583 if (!Opts.msan_with_comdat) {
600 O.Kernel =
valueOr(Opts.msan_kernel, O.Kernel);
602 Opts.msan_track_origins.value_or(O.Kernel ? 2 : O.TrackOrigins);
603 O.Recover =
valueOr(Opts.msan_keep_going, O.Kernel || O.Recover);
604 O.EagerChecks =
valueOr(Opts.msan_eager_checks, O.EagerChecks);
625 MemorySanitizer Msan(Opts, *
F.getParent(), MSanOpts);
643 static_cast<PassInfoMixin<MemorySanitizerPass> *
>(
this)->
printPipeline(
644 OS, MapClassName2PassName);
650 if (Options.EagerChecks)
651 OS <<
"eager-checks;";
652 OS <<
"track-origins=" << Options.TrackOrigins;
668template <
typename... ArgsTy>
670MemorySanitizer::getOrInsertMsanMetadataFunction(
Module &M,
StringRef Name,
675 std::forward<ArgsTy>(Args)...);
678 return M.getOrInsertFunction(Name, MsanMetadata,
679 std::forward<ArgsTy>(Args)...);
688 RetvalOriginTLS =
nullptr;
690 ParamOriginTLS =
nullptr;
692 VAArgOriginTLS =
nullptr;
693 VAArgOverflowSizeTLS =
nullptr;
695 WarningFn =
M.getOrInsertFunction(
"__msan_warning",
697 IRB.getVoidTy(), IRB.getInt32Ty());
708 MsanGetContextStateFn =
709 M.getOrInsertFunction(
"__msan_get_context_state", PtrTy);
713 for (
int ind = 0,
size = 1; ind < 4; ind++,
size <<= 1) {
714 std::string name_load =
715 "__msan_metadata_ptr_for_load_" + std::to_string(
size);
716 std::string name_store =
717 "__msan_metadata_ptr_for_store_" + std::to_string(
size);
718 MsanMetadataPtrForLoad_1_8[ind] =
719 getOrInsertMsanMetadataFunction(M, name_load, PtrTy);
720 MsanMetadataPtrForStore_1_8[ind] =
721 getOrInsertMsanMetadataFunction(M, name_store, PtrTy);
724 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
725 M,
"__msan_metadata_ptr_for_load_n", PtrTy, IntptrTy);
726 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
727 M,
"__msan_metadata_ptr_for_store_n", PtrTy, IntptrTy);
730 MsanPoisonAllocaFn =
M.getOrInsertFunction(
731 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
732 MsanUnpoisonAllocaFn =
M.getOrInsertFunction(
733 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
737 return M.getOrInsertGlobal(Name, Ty, [&] {
739 nullptr, Name,
nullptr,
745void MemorySanitizer::createUserspaceApi(
Module &M,
753 StringRef WarningFnName = Recover ?
"__msan_warning_with_origin"
754 :
"__msan_warning_with_origin_noreturn";
755 WarningFn =
M.getOrInsertFunction(WarningFnName,
757 IRB.getVoidTy(), IRB.getInt32Ty());
760 Recover ?
"__msan_warning" :
"__msan_warning_noreturn";
761 WarningFn =
M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
788 IRB.getIntPtrTy(
M.getDataLayout()));
792 unsigned AccessSize = 1 << AccessSizeIndex;
793 std::string FunctionName =
"__msan_maybe_warning_" +
itostr(AccessSize);
794 MaybeWarningFn[AccessSizeIndex] =
M.getOrInsertFunction(
796 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
797 MaybeWarningVarSizeFn =
M.getOrInsertFunction(
798 "__msan_maybe_warning_N", TLI.
getAttrList(
C, {},
false),
799 IRB.getVoidTy(), PtrTy, IRB.getInt64Ty(), IRB.getInt32Ty());
800 FunctionName =
"__msan_maybe_store_origin_" +
itostr(AccessSize);
801 MaybeStoreOriginFn[AccessSizeIndex] =
M.getOrInsertFunction(
803 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
807 MsanSetAllocaOriginWithDescriptionFn =
808 M.getOrInsertFunction(
"__msan_set_alloca_origin_with_descr",
809 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
810 MsanSetAllocaOriginNoDescriptionFn =
811 M.getOrInsertFunction(
"__msan_set_alloca_origin_no_descr",
812 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
813 MsanPoisonStackFn =
M.getOrInsertFunction(
"__msan_poison_stack",
814 IRB.getVoidTy(), PtrTy, IntptrTy);
818void MemorySanitizer::initializeCallbacks(
Module &M,
821 if (CallbacksInitialized)
827 MsanChainOriginFn =
M.getOrInsertFunction(
828 "__msan_chain_origin",
831 MsanSetOriginFn =
M.getOrInsertFunction(
833 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
835 M.getOrInsertFunction(
"__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
837 M.getOrInsertFunction(
"__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
838 MemsetFn =
M.getOrInsertFunction(
"__msan_memset",
840 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
842 MsanInstrumentAsmStoreFn =
M.getOrInsertFunction(
843 "__msan_instrument_asm_store", IRB.getVoidTy(), PtrTy, IntptrTy);
846 createKernelApi(M, TLI);
848 createUserspaceApi(M, TLI);
850 CallbacksInitialized =
true;
856 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
874void MemorySanitizer::initializeModule(
Module &M) {
875 auto &
DL =
M.getDataLayout();
877 TargetTriple =
M.getTargetTriple();
879 bool ShadowPassed = Opts.msan_shadow_base.has_value();
880 bool OriginPassed = Opts.msan_origin_base.has_value();
882 if (ShadowPassed || OriginPassed) {
883 CustomMapParams.AndMask = Opts.msan_and_mask;
884 CustomMapParams.XorMask = Opts.msan_xor_mask;
885 CustomMapParams.ShadowBase = Opts.msan_shadow_base.value_or(0);
886 CustomMapParams.OriginBase = Opts.msan_origin_base.value_or(0);
887 MapParams = &CustomMapParams;
889 switch (TargetTriple.getOS()) {
891 switch (TargetTriple.getArch()) {
906 switch (TargetTriple.getArch()) {
915 switch (TargetTriple.getArch()) {
952 C = &(
M.getContext());
954 IntptrTy = IRB.getIntPtrTy(
DL);
955 OriginTy = IRB.getInt32Ty();
956 PtrTy = IRB.getPtrTy();
961 if (!CompileKernel) {
963 M.getOrInsertGlobal(
"__msan_track_origins", IRB.getInt32Ty(), [&] {
964 return new GlobalVariable(
965 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
966 IRB.getInt32(TrackOrigins),
"__msan_track_origins");
970 M.getOrInsertGlobal(
"__msan_keep_going", IRB.getInt32Ty(), [&] {
971 return new GlobalVariable(M, IRB.getInt32Ty(), true,
972 GlobalValue::WeakODRLinkage,
973 IRB.getInt32(Recover),
"__msan_keep_going");
989 virtual ~VarArgHelper() =
default;
992 virtual void visitCallBase(CallBase &CB,
IRBuilder<> &IRB) = 0;
995 virtual void visitVAStartInst(VAStartInst &
I) = 0;
998 virtual void visitVACopyInst(VACopyInst &
I) = 0;
1004 virtual void finalizeInstrumentation() = 0;
1007struct MemorySanitizerVisitor;
1012 MemorySanitizerVisitor &Visitor);
1019 if (TypeSizeFixed <= 8)
1028class NextNodeIRBuilder :
public IRBuilder<> {
1041struct MemorySanitizerVisitor :
public InstVisitor<MemorySanitizerVisitor> {
1042 const InstrumentationOptions &Opts;
1044 MemorySanitizer &MS;
1046 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1047 std::unique_ptr<VarArgHelper> VAHelper;
1048 const TargetLibraryInfo *TLI;
1055 bool PropagateShadow;
1058 bool PoisonUndefVectors;
1060 struct ShadowOriginAndInsertPoint {
1065 ShadowOriginAndInsertPoint(
Value *S,
Value *O, Instruction *
I)
1066 : Shadow(S), Origin(
O), OrigIns(
I) {}
1069 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1070 SmallSetVector<AllocaInst *, 16> AllocaSet;
1073 int64_t SplittableBlocksCount = 0;
1075 MemorySanitizerVisitor(
Function &
F, MemorySanitizer &MS,
1076 const TargetLibraryInfo &TLI)
1079 bool SanitizeFunction =
F.hasFnAttribute(Attribute::SanitizeMemory) &&
1080 !Opts.msan_disable_checks;
1081 InsertChecks = SanitizeFunction;
1082 PropagateShadow = SanitizeFunction;
1083 PoisonStack = SanitizeFunction && Opts.msan_poison_stack;
1084 PoisonUndef = SanitizeFunction && Opts.msan_poison_undef;
1085 PoisonUndefVectors = SanitizeFunction && Opts.msan_poison_undef_vectors;
1093 MS.initializeCallbacks(*
F.getParent(), TLI);
1096 .CreateIntrinsicWithoutFolding(Intrinsic::donothing, {});
1098 if (MS.CompileKernel) {
1099 IRBuilder<> IRB(FnPrologueEnd);
1100 insertKmsanPrologue(IRB);
1104 <<
"MemorySanitizer is not inserting checks into '"
1105 <<
F.getName() <<
"'\n");
1108 bool instrumentWithCalls(
Value *V) {
1112 ++SplittableBlocksCount;
1113 return Opts.msan_instrumentation_with_call_threshold >= 0 &&
1114 SplittableBlocksCount >
1115 Opts.msan_instrumentation_with_call_threshold;
1118 bool isInPrologue(Instruction &
I) {
1119 return I.getParent() == FnPrologueEnd->
getParent() &&
1128 if (MS.TrackOrigins <= 1)
1130 return IRB.
CreateCall(MS.MsanChainOriginFn, V);
1134 const DataLayout &
DL =
F.getDataLayout();
1135 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1145 TypeSize TS, Align Alignment) {
1146 const DataLayout &
DL =
F.getDataLayout();
1147 const Align IntptrAlignment =
DL.getABITypeAlign(MS.IntptrTy);
1148 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1160 auto [InsertPt,
Index] =
1173 if (Alignment >= IntptrAlignment && IntptrSize >
kOriginSize) {
1174 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1176 for (
unsigned i = 0; i <
Size / IntptrSize; ++i) {
1181 CurrentAlignment = IntptrAlignment;
1194 Value *OriginPtr, Align Alignment) {
1195 const DataLayout &
DL =
F.getDataLayout();
1197 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
1199 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1201 if (!Opts.msan_check_constant_shadow || ConstantShadow->isNullValue()) {
1208 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1215 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1217 if (instrumentWithCalls(ConvertedShadow) &&
1219 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1220 Value *ConvertedShadow2 =
1222 CallBase *CB = IRB.
CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1226 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1230 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1235 void materializeStores() {
1236 for (StoreInst *SI : StoreList) {
1238 Value *Val =
SI->getValueOperand();
1239 Value *Addr =
SI->getPointerOperand();
1240 Value *Shadow =
SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1241 Value *ShadowPtr, *OriginPtr;
1245 std::tie(ShadowPtr, OriginPtr) =
1246 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
true);
1248 [[maybe_unused]] StoreInst *NewSI =
1255 if (MS.TrackOrigins && !
SI->isAtomic())
1256 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1263 if (MS.TrackOrigins < 2)
1266 if (LazyWarningDebugLocationCount.
empty())
1267 for (
const auto &
I : InstrumentationList)
1268 ++LazyWarningDebugLocationCount[
I.OrigIns->getDebugLoc()];
1270 return LazyWarningDebugLocationCount[
DebugLoc] >=
1271 Opts.msan_disambiguate_warning_threshold;
1285 auto NewDebugLoc = OI->getDebugLoc();
1292 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1293 Origin = updateOrigin(Origin, IRBOrigin);
1298 if (MS.CompileKernel || MS.TrackOrigins)
1309 const DataLayout &
DL =
F.getDataLayout();
1310 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1312 if (instrumentWithCalls(ConvertedShadow) && !MS.CompileKernel) {
1314 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1315 Value *ConvertedShadow2 =
1319 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1323 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1327 FunctionCallee Fn = MS.MaybeWarningVarSizeFn;
1330 unsigned ShadowSize =
DL.getTypeAllocSize(ConvertedShadow2->
getType());
1333 {ShadowAlloca, ConstantInt::get(IRB.
getInt64Ty(), ShadowSize),
1334 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1339 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1342 !MS.Recover, MS.ColdCallWeights);
1345 insertWarningFn(IRB, Origin);
1350 void materializeInstructionChecks(
1352 const DataLayout &
DL =
F.getDataLayout();
1355 bool Combine = !MS.TrackOrigins;
1357 Value *Shadow =
nullptr;
1358 for (
const auto &ShadowData : InstructionChecks) {
1359 assert(ShadowData.OrigIns == Instruction);
1362 Value *ConvertedShadow = ShadowData.Shadow;
1365 if (!Opts.msan_check_constant_shadow || ConstantShadow->isNullValue()) {
1371 insertWarningFn(IRB, ShadowData.Origin);
1381 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1386 Shadow = ConvertedShadow;
1390 Shadow = convertToBool(Shadow, IRB,
"_mscmp");
1391 ConvertedShadow = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1392 Shadow = IRB.
CreateOr(Shadow, ConvertedShadow,
"_msor");
1398 materializeOneCheck(IRB, Shadow,
nullptr);
1402 static bool isAArch64SVCount(
Type *Ty) {
1404 return TTy->
getName() ==
"aarch64.svcount";
1410 static bool isScalableNonVectorType(
Type *Ty) {
1411 if (!isAArch64SVCount(Ty))
1412 LLVM_DEBUG(
dbgs() <<
"isScalableNonVectorType: Unexpected type " << *Ty
1418 void materializeChecks() {
1421 SmallPtrSet<Instruction *, 16>
Done;
1424 for (
auto I = InstrumentationList.begin();
1425 I != InstrumentationList.end();) {
1426 auto OrigIns =
I->OrigIns;
1430 auto J = std::find_if(
I + 1, InstrumentationList.end(),
1431 [OrigIns](
const ShadowOriginAndInsertPoint &R) {
1432 return OrigIns != R.OrigIns;
1446 MS.ParamTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1447 {Zero, IRB.getInt32(0)},
"param_shadow");
1448 MS.RetvalTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1449 {Zero, IRB.getInt32(1)},
"retval_shadow");
1450 MS.VAArgTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1451 {Zero, IRB.getInt32(2)},
"va_arg_shadow");
1452 MS.VAArgOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1453 {Zero, IRB.getInt32(3)},
"va_arg_origin");
1454 MS.VAArgOverflowSizeTLS =
1455 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1456 {Zero, IRB.getInt32(4)},
"va_arg_overflow_size");
1457 MS.ParamOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1458 {Zero, IRB.getInt32(5)},
"param_origin");
1459 MS.RetvalOriginTLS =
1460 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1461 {Zero, IRB.getInt32(6)},
"retval_origin");
1463 MS.MsanMetadataAlloca = IRB.
CreateAlloca(MS.MsanMetadata, 0u);
1476 for (Instruction *
I : Instructions)
1480 for (PHINode *PN : ShadowPHINodes) {
1482 PHINode *PNO = MS.TrackOrigins ?
cast<PHINode>(getOrigin(PN)) : nullptr;
1483 size_t NumValues = PN->getNumIncomingValues();
1484 for (
size_t v = 0;
v < NumValues;
v++) {
1485 PNS->
addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1487 PNO->
addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1491 VAHelper->finalizeInstrumentation();
1495 if (Opts.msan_handle_lifetime_intrinsics) {
1496 for (
auto Item : LifetimeStartList) {
1497 instrumentAlloca(*Item.second, Item.first);
1498 AllocaSet.
remove(Item.second);
1503 for (AllocaInst *AI : AllocaSet)
1504 instrumentAlloca(*AI);
1507 materializeChecks();
1511 materializeStores();
1517 Type *getShadowTy(
Value *V) {
return getShadowTy(
V->getType()); }
1528 const DataLayout &
DL =
F.getDataLayout();
1530 uint32_t EltSize =
DL.getTypeSizeInBits(VT->getElementType());
1532 VT->getElementCount());
1535 return ArrayType::get(getShadowTy(AT->getElementType()),
1536 AT->getNumElements());
1540 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1541 Elements.push_back(getShadowTy(
ST->getElementType(i)));
1543 LLVM_DEBUG(
dbgs() <<
"getShadowTy: " << *ST <<
" ===> " << *Res <<
"\n");
1546 if (isScalableNonVectorType(OrigTy)) {
1547 LLVM_DEBUG(
dbgs() <<
"getShadowTy: Scalable non-vector type: " << *OrigTy
1552 uint32_t TypeSize =
DL.getTypeSizeInBits(OrigTy);
1557 Value *collapseStructShadow(StructType *Struct,
Value *Shadow,
1562 for (
unsigned Idx = 0;
Idx <
Struct->getNumElements();
Idx++) {
1565 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1567 if (Aggregator != FalseVal)
1568 Aggregator = IRB.
CreateOr(Aggregator, ShadowBool);
1570 Aggregator = ShadowBool;
1577 Value *collapseArrayShadow(ArrayType *Array,
Value *Shadow,
1579 if (!
Array->getNumElements())
1583 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1585 for (
unsigned Idx = 1;
Idx <
Array->getNumElements();
Idx++) {
1587 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1588 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
1598 return collapseStructShadow(Struct, V, IRB);
1600 return collapseArrayShadow(Array, V, IRB);
1605 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1613 Type *VTy =
V->getType();
1615 return convertToBool(convertShadowToScalar(V, IRB), IRB,
name);
1622 Type *ptrToIntPtrType(
Type *PtrTy)
const {
1624 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1625 VectTy->getElementCount());
1633 return VectorType::get(
1634 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1635 VectTy->getElementCount());
1644 VectTy->getElementCount(),
1645 constToIntPtr(VectTy->getElementType(),
C));
1650 return ConstantInt::get(MS.IntptrTy,
C,
false,
1664 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1667 if (
uint64_t AndMask = MS.MapParams->AndMask)
1668 OffsetLong = IRB.
CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1670 if (
uint64_t XorMask = MS.MapParams->XorMask)
1671 OffsetLong = IRB.
CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1683 std::pair<Value *, Value *>
1685 MaybeAlign Alignment) {
1690 assert(VectTy->getElementType()->isPointerTy());
1692 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1693 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1694 Value *ShadowLong = ShadowOffset;
1695 if (
uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1697 IRB.
CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1700 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1702 Value *OriginPtr =
nullptr;
1703 if (MS.TrackOrigins) {
1704 Value *OriginLong = ShadowOffset;
1705 uint64_t OriginBase = MS.MapParams->OriginBase;
1706 if (OriginBase != 0)
1708 IRB.
CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1711 OriginLong = IRB.
CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1714 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1716 return std::make_pair(ShadowPtr, OriginPtr);
1719 template <
typename... ArgsTy>
1724 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1725 return IRB.
CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1728 return IRB.
CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1731 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(
Value *Addr,
1735 Value *ShadowOriginPtrs;
1736 const DataLayout &
DL =
F.getDataLayout();
1737 TypeSize
Size =
DL.getTypeStoreSize(ShadowTy);
1739 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(
isStore,
Size);
1742 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1744 Value *SizeVal = ConstantInt::get(MS.IntptrTy,
Size);
1745 ShadowOriginPtrs = createMetadataCall(
1747 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1754 return std::make_pair(ShadowPtr, OriginPtr);
1760 std::pair<Value *, Value *> getShadowOriginPtrKernel(
Value *Addr,
1767 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy,
isStore);
1772 Value *ShadowPtrs = ConstantInt::getNullValue(
1774 Value *OriginPtrs =
nullptr;
1775 if (MS.TrackOrigins)
1776 OriginPtrs = ConstantInt::getNullValue(
1778 for (
unsigned i = 0; i < NumElements; ++i) {
1781 auto [ShadowPtr, OriginPtr] =
1782 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy,
isStore);
1785 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1786 if (MS.TrackOrigins)
1788 OriginPtrs, OriginPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1790 return {ShadowPtrs, OriginPtrs};
1793 std::pair<Value *, Value *> getShadowOriginPtr(
Value *Addr,
IRBuilder<> &IRB,
1795 MaybeAlign Alignment,
1797 if (MS.CompileKernel)
1798 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy,
isStore);
1799 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1807 ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg");
1812 if (!MS.TrackOrigins)
1815 ConstantInt::get(MS.IntptrTy, ArgOffset),
1825 Value *getOriginPtrForRetval() {
1827 return MS.RetvalOriginTLS;
1832 assert(!ShadowMap.
count(V) &&
"Values may only have one shadow");
1835 if (SV && !
V->getType()->isVoidTy() && getShadowTy(V) !=
SV->getType()) {
1838 assert(getShadowTy(V) ==
SV->getType() &&
1839 "setShadow called with mismatching types");
1842 ShadowMap[
V] = PropagateShadow ?
SV : getCleanShadow(V);
1847 if (!MS.TrackOrigins)
1849 assert(!OriginMap.
count(V) &&
"Values may only have one origin");
1850 LLVM_DEBUG(
dbgs() <<
"ORIGIN: " << *V <<
" ==> " << *Origin <<
"\n");
1851 OriginMap[
V] = Origin;
1855 Type *ShadowTy = getShadowTy(OrigTy);
1865 Constant *getCleanShadow(
Value *V) {
return getCleanShadow(
V->getType()); }
1873 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
1874 getPoisonedShadow(AT->getElementType()));
1878 SmallVector<Constant *, 4> Vals;
1879 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1880 Vals.
push_back(getPoisonedShadow(
ST->getElementType(i)));
1888 Type *ShadowTy = getShadowTy(V);
1891 return getPoisonedShadow(ShadowTy);
1903 if (!PropagateShadow ||
I->getMetadata(LLVMContext::MD_nosanitize))
1904 return getCleanShadow(V);
1906 Value *Shadow = ShadowMap[
V];
1908 LLVM_DEBUG(
dbgs() <<
"No shadow: " << *V <<
"\n" << *(
I->getParent()));
1909 assert(Shadow &&
"No shadow for a value");
1916 Value *
AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
1917 : getCleanShadow(V);
1923 Value *&ShadowPtr = ShadowMap[
V];
1928 unsigned ArgOffset = 0;
1929 const DataLayout &
DL =
F->getDataLayout();
1930 for (
auto &FArg :
F->args()) {
1931 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
1933 ?
"vscale not fully supported\n"
1934 :
"Arg is not sized\n"));
1936 ShadowPtr = getCleanShadow(V);
1937 setOrigin(
A, getCleanOrigin());
1943 unsigned Size = FArg.hasByValAttr()
1944 ?
DL.getTypeAllocSize(FArg.getParamByValType())
1945 :
DL.getTypeAllocSize(FArg.getType());
1949 if (FArg.hasByValAttr()) {
1953 const Align ArgAlign =
DL.getValueOrABITypeAlignment(
1954 FArg.getParamAlign(), FArg.getParamByValType());
1955 Value *CpShadowPtr, *CpOriginPtr;
1956 std::tie(CpShadowPtr, CpOriginPtr) =
1957 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
1959 if (!PropagateShadow || Overflow) {
1961 EntryIRB.CreateMemSet(
1965 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1967 [[maybe_unused]]
Value *Cpy = EntryIRB.CreateMemCpy(
1968 CpShadowPtr, CopyAlign,
Base, CopyAlign,
Size);
1971 if (MS.TrackOrigins) {
1972 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1976 EntryIRB.CreateMemCpy(
1985 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
1986 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
1987 ShadowPtr = getCleanShadow(V);
1988 setOrigin(
A, getCleanOrigin());
1991 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1992 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg),
Base,
1994 if (MS.TrackOrigins) {
1995 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1996 setOrigin(
A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
2000 <<
" ARG: " << FArg <<
" ==> " << *ShadowPtr <<
"\n");
2006 assert(ShadowPtr &&
"Could not find shadow for an argument");
2013 cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
2014 PoisonUndefVectors) {
2017 for (
unsigned i = 0; i != NumElems; ++i) {
2020 : getCleanShadow(Elem);
2024 LLVM_DEBUG(
dbgs() <<
"Partial undef constant vector: " << *V <<
" ==> "
2025 << *ShadowConstant <<
"\n");
2027 return ShadowConstant;
2033 return getCleanShadow(V);
2037 Value *getShadow(Instruction *
I,
int i) {
2038 return getShadow(
I->getOperand(i));
2043 if (!MS.TrackOrigins)
2046 return getCleanOrigin();
2048 "Unexpected value type in getOrigin()");
2050 if (
I->getMetadata(LLVMContext::MD_nosanitize))
2051 return getCleanOrigin();
2053 Value *Origin = OriginMap[
V];
2054 assert(Origin &&
"Missing origin");
2059 Value *getOrigin(Instruction *
I,
int i) {
2060 return getOrigin(
I->getOperand(i));
2067 void insertCheckShadow(
Value *Shadow,
Value *Origin, Instruction *OrigIns) {
2073 LLVM_DEBUG(
dbgs() <<
"Skipping check of " << *Shadow <<
" before "
2074 << *OrigIns <<
"\n");
2079 if (isScalableNonVectorType(ShadowTy)) {
2080 LLVM_DEBUG(
dbgs() <<
"Skipping check of scalable non-vector " << *Shadow
2081 <<
" before " << *OrigIns <<
"\n");
2087 "Can only insert checks for integer, vector, and aggregate shadow "
2090 InstrumentationList.push_back(
2091 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2099 void insertCheckShadowOf(
Value *Val, Instruction *OrigIns) {
2101 Value *Shadow, *Origin;
2102 if (Opts.msan_check_constant_shadow) {
2103 Shadow = getShadow(Val);
2106 Origin = getOrigin(Val);
2113 insertCheckShadow(Shadow, Origin, OrigIns);
2118 case AtomicOrdering::NotAtomic:
2119 return AtomicOrdering::NotAtomic;
2120 case AtomicOrdering::Unordered:
2121 case AtomicOrdering::Monotonic:
2122 case AtomicOrdering::Release:
2123 return AtomicOrdering::Release;
2124 case AtomicOrdering::Acquire:
2125 case AtomicOrdering::AcquireRelease:
2126 return AtomicOrdering::AcquireRelease;
2127 case AtomicOrdering::SequentiallyConsistent:
2128 return AtomicOrdering::SequentiallyConsistent;
2134 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2135 uint32_t OrderingTable[NumOrderings] = {};
2137 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2138 OrderingTable[(
int)AtomicOrderingCABI::release] =
2139 (int)AtomicOrderingCABI::release;
2140 OrderingTable[(int)AtomicOrderingCABI::consume] =
2141 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2142 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2143 (
int)AtomicOrderingCABI::acq_rel;
2144 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2145 (
int)AtomicOrderingCABI::seq_cst;
2152 case AtomicOrdering::NotAtomic:
2153 return AtomicOrdering::NotAtomic;
2154 case AtomicOrdering::Unordered:
2155 case AtomicOrdering::Monotonic:
2156 case AtomicOrdering::Acquire:
2157 return AtomicOrdering::Acquire;
2158 case AtomicOrdering::Release:
2159 case AtomicOrdering::AcquireRelease:
2160 return AtomicOrdering::AcquireRelease;
2161 case AtomicOrdering::SequentiallyConsistent:
2162 return AtomicOrdering::SequentiallyConsistent;
2168 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2169 uint32_t OrderingTable[NumOrderings] = {};
2171 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2172 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2173 OrderingTable[(int)AtomicOrderingCABI::consume] =
2174 (
int)AtomicOrderingCABI::acquire;
2175 OrderingTable[(int)AtomicOrderingCABI::release] =
2176 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
2177 (int)AtomicOrderingCABI::acq_rel;
2178 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2179 (
int)AtomicOrderingCABI::seq_cst;
2185 using InstVisitor<MemorySanitizerVisitor>
::visit;
2186 void visit(Instruction &
I) {
2187 if (
I.getMetadata(LLVMContext::MD_nosanitize))
2190 if (isInPrologue(
I))
2195 setShadow(&
I, getCleanShadow(&
I));
2196 setOrigin(&
I, getCleanOrigin());
2207 void visitLoadInst(LoadInst &
I) {
2208 assert(
I.getType()->isSized() &&
"Load type must have size");
2209 assert(!
I.getMetadata(LLVMContext::MD_nosanitize));
2210 NextNodeIRBuilder IRB(&
I);
2211 Type *ShadowTy = getShadowTy(&
I);
2212 Value *Addr =
I.getPointerOperand();
2213 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
2215 if (PropagateShadow) {
2216 std::tie(ShadowPtr, OriginPtr) =
2217 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
2221 setShadow(&
I, getCleanShadow(&
I));
2224 if (Opts.msan_check_access_address)
2225 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2230 if (MS.TrackOrigins) {
2231 if (PropagateShadow) {
2236 setOrigin(&
I, getCleanOrigin());
2245 void visitStoreInst(StoreInst &
I) {
2246 StoreList.push_back(&
I);
2247 if (Opts.msan_check_access_address)
2248 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2251 void handleCASOrRMW(Instruction &
I) {
2255 Value *Addr =
I.getOperand(0);
2256 Value *Val =
I.getOperand(1);
2257 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val),
Align(1),
2261 if (Opts.msan_check_access_address)
2262 insertCheckShadowOf(Addr, &
I);
2268 insertCheckShadowOf(Val, &
I);
2272 setShadow(&
I, getCleanShadow(&
I));
2273 setOrigin(&
I, getCleanOrigin());
2276 void visitAtomicRMWInst(AtomicRMWInst &
I) {
2281 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2343 void visitSwitchInst(SwitchInst &SI) {
2346 Value *Val =
SI.getCondition();
2347 Value *ShadowVal = getShadow(Val);
2357 int casesToConsider = Opts.msan_switch_precision;
2359 Value *ShadowCases =
nullptr;
2360 for (
auto Case :
SI.cases()) {
2361 if (casesToConsider <= 0)
2364 Value *Comparator = Case.getCaseValue();
2367 Value *ComparisonShadow = propagateEqualityComparison(
2368 IRB, Val, Comparator, ShadowVal, getShadow(Comparator));
2371 ShadowCases = IRB.
CreateOr(ShadowCases, ComparisonShadow);
2373 ShadowCases = ComparisonShadow;
2379 insertCheckShadow(ShadowCases, getOrigin(Val), &SI);
2383 void visitExtractElementInst(ExtractElementInst &
I) {
2384 insertCheckShadowOf(
I.getOperand(1), &
I);
2388 setOrigin(&
I, getOrigin(&
I, 0));
2391 void visitInsertElementInst(InsertElementInst &
I) {
2392 insertCheckShadowOf(
I.getOperand(2), &
I);
2394 auto *Shadow0 = getShadow(&
I, 0);
2395 auto *Shadow1 = getShadow(&
I, 1);
2398 setOriginForNaryOp(
I);
2401 void visitShuffleVectorInst(ShuffleVectorInst &
I) {
2403 auto *Shadow0 = getShadow(&
I, 0);
2404 auto *Shadow1 = getShadow(&
I, 1);
2407 setOriginForNaryOp(
I);
2411 void visitSExtInst(SExtInst &
I) {
2413 setShadow(&
I, IRB.
CreateSExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2414 setOrigin(&
I, getOrigin(&
I, 0));
2417 void visitZExtInst(ZExtInst &
I) {
2419 setShadow(&
I, IRB.
CreateZExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2420 setOrigin(&
I, getOrigin(&
I, 0));
2423 void visitTruncInst(TruncInst &
I) {
2425 setShadow(&
I, IRB.
CreateTrunc(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2426 setOrigin(&
I, getOrigin(&
I, 0));
2429 void visitBitCastInst(BitCastInst &
I) {
2434 if (CI->isMustTailCall())
2438 setOrigin(&
I, getOrigin(&
I, 0));
2441 void visitAddrSpaceCastInst(AddrSpaceCastInst &
I) {
2444 "_msprop_addrspacecast"));
2445 setOrigin(&
I, getOrigin(&
I, 0));
2448 void visitPtrToIntInst(PtrToIntInst &
I) {
2451 "_msprop_ptrtoint"));
2452 setOrigin(&
I, getOrigin(&
I, 0));
2455 void visitPtrToAddrInst(PtrToAddrInst &
I) {
2458 "_msprop_ptrtoaddr"));
2459 setOrigin(&
I, getOrigin(&
I, 0));
2462 void visitIntToPtrInst(IntToPtrInst &
I) {
2465 "_msprop_inttoptr"));
2466 setOrigin(&
I, getOrigin(&
I, 0));
2487 void handleGenericVectorConvertIntrinsic(Instruction &
I,
bool FixedPoint) {
2488 [[maybe_unused]]
unsigned NumArgs =
I.getNumOperands();
2490 NumArgs = CI->arg_size();
2494 Value *Precision =
I.getOperand(1);
2495 insertCheckShadowOf(Precision, &
I);
2501 Value *S0 = getShadow(&
I, 0);
2511 setShadow(&
I, OutShadow);
2512 setOriginForNaryOp(
I);
2515 void visitFPToSIInst(CastInst &
I) {
2516 handleGenericVectorConvertIntrinsic(
I,
false);
2518 void visitFPToUIInst(CastInst &
I) {
2519 handleGenericVectorConvertIntrinsic(
I,
false);
2521 void visitSIToFPInst(CastInst &
I) {
2522 handleGenericVectorConvertIntrinsic(
I,
false);
2524 void visitUIToFPInst(CastInst &
I) {
2525 handleGenericVectorConvertIntrinsic(
I,
false);
2528 void visitFPExtInst(CastInst &
I) {
2529 handleGenericVectorConvertIntrinsic(
I,
false);
2531 void visitFPTruncInst(CastInst &
I) {
2532 handleGenericVectorConvertIntrinsic(
I,
false);
2553 assert(
V1->getType()->isIntOrIntVectorTy());
2564 return IRB.
CreateOr({S1S2, V1S2, S1V2});
2568 void visitAnd(BinaryOperator &
I) {
2571 Value *V2 =
I.getOperand(1);
2573 Value *S2 = getShadow(&
I, 1);
2575 Value *OutShadow = handleBitwiseAnd(IRB,
V1, V2,
S1, S2);
2577 setShadow(&
I, OutShadow);
2578 setOriginForNaryOp(
I);
2581 void visitOr(BinaryOperator &
I) {
2594 Value *S2 = getShadow(&
I, 1);
2596 Value *V2 =
I.getOperand(1);
2600 assert(
V1->getType()->isIntOrIntVectorTy());
2616 if (Opts.msan_precise_disjoint_or &&
2621 S = IRB.
CreateOr(S, DisjointOrShadow,
"_ms_disjoint");
2625 setOriginForNaryOp(
I);
2643 template <
bool CombineShadow>
class Combiner {
2644 Value *Shadow =
nullptr;
2645 Value *Origin =
nullptr;
2647 MemorySanitizerVisitor *MSV;
2650 Combiner(MemorySanitizerVisitor *MSV,
IRBuilder<> &IRB)
2651 : IRB(IRB), MSV(MSV) {}
2655 if (CombineShadow) {
2660 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2661 Shadow = IRB.
CreateOr(Shadow, OpShadow,
"_msprop");
2665 if (MSV->MS.TrackOrigins) {
2672 if (!ConstOrigin || !ConstOrigin->
isNullValue()) {
2673 Value *
Cond = MSV->convertToBool(OpShadow, IRB);
2683 Value *OpShadow = MSV->getShadow(V);
2684 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) :
nullptr;
2685 return Add(OpShadow, OpOrigin);
2690 void Done(Instruction *
I) {
2691 if (CombineShadow) {
2693 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(
I));
2694 MSV->setShadow(
I, Shadow);
2696 if (MSV->MS.TrackOrigins) {
2698 MSV->setOrigin(
I, Origin);
2704 void DoneAndStoreOrigin(TypeSize TS,
Value *OriginPtr) {
2705 if (MSV->MS.TrackOrigins) {
2712 using ShadowAndOriginCombiner = Combiner<true>;
2713 using OriginCombiner = Combiner<false>;
2716 void setOriginForNaryOp(Instruction &
I) {
2717 if (!MS.TrackOrigins)
2720 OriginCombiner OC(
this, IRB);
2721 for (Use &
Op :
I.operands())
2726 size_t VectorOrPrimitiveTypeSizeInBits(
Type *Ty) {
2728 "Vector of pointers is not a valid shadow type");
2738 Type *srcTy =
V->getType();
2741 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2742 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2743 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2761 Type *ShadowTy = getShadowTy(V);
2762 if (
V->getType() == ShadowTy)
2764 if (
V->getType()->isPtrOrPtrVectorTy())
2771 void handleShadowOr(Instruction &
I) {
2773 ShadowAndOriginCombiner SC(
this, IRB);
2774 for (Use &
Op :
I.operands())
2801 Value *horizontalReduce(IntrinsicInst &
I,
unsigned ReductionFactor,
2802 unsigned Shards,
Value *VectorA,
Value *VectorB) {
2807 [[maybe_unused]]
unsigned TotalNumElems = NumElems;
2813 assert(NumElems % (ReductionFactor * Shards) == 0);
2818 for (
unsigned i = 0; i < ReductionFactor; i++) {
2819 SmallVector<int, 16>
Mask;
2821 for (
unsigned j = 0;
j < Shards;
j++) {
2822 unsigned Offset = NumElems / Shards *
j;
2824 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2828 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2853 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards) {
2854 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2856 assert(
I.getType()->isVectorTy());
2857 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2859 [[maybe_unused]] FixedVectorType *ParamType =
2863 [[maybe_unused]] FixedVectorType *
ReturnType =
2871 Value *FirstArgShadow = getShadow(&
I, 0);
2872 Value *SecondArgShadow =
nullptr;
2873 if (
I.arg_size() == 2)
2874 SecondArgShadow = getShadow(&
I, 1);
2876 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2877 FirstArgShadow, SecondArgShadow);
2879 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2881 setShadow(&
I, OrShadow);
2882 setOriginForNaryOp(
I);
2892 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards,
2893 int ReinterpretElemWidth) {
2894 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2896 assert(
I.getType()->isVectorTy());
2897 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2899 FixedVectorType *ParamType =
2904 [[maybe_unused]] FixedVectorType *
ReturnType =
2911 FixedVectorType *ReinterpretShadowTy =
nullptr;
2919 Value *FirstArgShadow = getShadow(&
I, 0);
2920 FirstArgShadow = IRB.
CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
2930 Value *SecondArgShadow =
nullptr;
2931 if (
I.arg_size() == 2) {
2932 SecondArgShadow = getShadow(&
I, 1);
2933 SecondArgShadow = IRB.
CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
2936 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2937 FirstArgShadow, SecondArgShadow);
2939 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2941 setShadow(&
I, OrShadow);
2942 setOriginForNaryOp(
I);
2945 void visitFNeg(UnaryOperator &
I) { handleShadowOr(
I); }
2956 void handleMulByConstant(BinaryOperator &
I, Constant *ConstArg,
2962 Type *EltTy = VTy->getElementType();
2964 for (
unsigned Idx = 0;
Idx < NumElements; ++
Idx) {
2965 if (ConstantInt *Elt =
2967 const APInt &
V = Elt->getValue();
2968 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
2969 Elements.push_back(ConstantInt::get(EltTy, V2));
2971 Elements.push_back(ConstantInt::get(EltTy, 1));
2977 const APInt &
V = Elt->getValue();
2978 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
2979 ShadowMul = ConstantInt::get(Ty, V2);
2981 ShadowMul = ConstantInt::get(Ty, 1);
2987 IRB.
CreateMul(getShadow(OtherArg), ShadowMul,
"msprop_mul_cst"));
2988 setOrigin(&
I, getOrigin(OtherArg));
2991 void visitMul(BinaryOperator &
I) {
2994 if (constOp0 && !constOp1)
2995 handleMulByConstant(
I, constOp0,
I.getOperand(1));
2996 else if (constOp1 && !constOp0)
2997 handleMulByConstant(
I, constOp1,
I.getOperand(0));
3002 void visitFAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3003 void visitFSub(BinaryOperator &
I) { handleShadowOr(
I); }
3004 void visitFMul(BinaryOperator &
I) { handleShadowOr(
I); }
3005 void visitAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3006 void visitSub(BinaryOperator &
I) { handleShadowOr(
I); }
3007 void visitXor(BinaryOperator &
I) { handleShadowOr(
I); }
3009 void handleIntegerDiv(Instruction &
I) {
3012 insertCheckShadowOf(
I.getOperand(1), &
I);
3013 setShadow(&
I, getShadow(&
I, 0));
3014 setOrigin(&
I, getOrigin(&
I, 0));
3017 void visitUDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3018 void visitSDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3019 void visitURem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3020 void visitSRem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3024 void visitFDiv(BinaryOperator &
I) { handleShadowOr(
I); }
3025 void visitFRem(BinaryOperator &
I) { handleShadowOr(
I); }
3031 void handleEqualityComparison(ICmpInst &
I) {
3035 Value *Sa = getShadow(
A);
3036 Value *Sb = getShadow(
B);
3038 Value *Si = propagateEqualityComparison(IRB,
A,
B, Sa, Sb);
3041 setOriginForNaryOp(
I);
3049 void handleRelationalComparisonExact(ICmpInst &
I) {
3053 Value *Sa = getShadow(
A);
3054 Value *Sb = getShadow(
B);
3065 bool IsSigned =
I.isSigned();
3067 auto GetMinMaxUnsigned = [&](
Value *
V,
Value *S) {
3077 V = IRB.
CreateXor(V, ConstantInt::get(
V->getType(), MinVal));
3082 return std::make_pair(Min, Max);
3085 auto [Amin, Amax] = GetMinMaxUnsigned(
A, Sa);
3086 auto [Bmin, Bmax] = GetMinMaxUnsigned(
B, Sb);
3092 setOriginForNaryOp(
I);
3099 void handleSignedRelationalComparison(ICmpInst &
I) {
3104 op =
I.getOperand(0);
3105 pre =
I.getPredicate();
3107 op =
I.getOperand(1);
3108 pre =
I.getSwappedPredicate();
3121 setShadow(&
I, Shadow);
3122 setOrigin(&
I, getOrigin(
op));
3128 void visitICmpInst(ICmpInst &
I) {
3129 if (!Opts.msan_handle_icmp) {
3133 if (
I.isEquality()) {
3134 handleEqualityComparison(
I);
3139 if (Opts.msan_handle_icmp_exact) {
3140 handleRelationalComparisonExact(
I);
3144 handleSignedRelationalComparison(
I);
3150 handleRelationalComparisonExact(
I);
3157 void visitFCmpInst(FCmpInst &
I) { handleShadowOr(
I); }
3159 void handleShift(BinaryOperator &
I) {
3164 Value *S2 = getShadow(&
I, 1);
3167 Value *V2 =
I.getOperand(1);
3169 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3170 setOriginForNaryOp(
I);
3173 void visitShl(BinaryOperator &
I) { handleShift(
I); }
3174 void visitAShr(BinaryOperator &
I) { handleShift(
I); }
3175 void visitLShr(BinaryOperator &
I) { handleShift(
I); }
3177 void handleFunnelShift(IntrinsicInst &
I) {
3181 Value *S0 = getShadow(&
I, 0);
3183 Value *S2 = getShadow(&
I, 2);
3186 Value *V2 =
I.getOperand(2);
3189 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3190 setOriginForNaryOp(
I);
3198 void handleGenericBitManipulation(IntrinsicInst &
I) {
3200 Type *ShadowTy = getShadowTy(&
I);
3203 Value *SMask = getShadow(&
I, 1);
3208 if (
Function *Func =
I.getCalledFunction())
3209 S = IRB.
CreateCall(Func, {getShadow(&
I, 0),
I.getOperand(1)});
3212 {getShadow(&I, 0), I.getOperand(1)});
3215 setOriginForNaryOp(
I);
3228 void visitMemMoveInst(MemMoveInst &
I) {
3229 getShadow(
I.getArgOperand(1));
3232 {I.getArgOperand(0), I.getArgOperand(1),
3233 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3251 void visitMemCpyInst(MemCpyInst &
I) {
3252 getShadow(
I.getArgOperand(1));
3255 {I.getArgOperand(0), I.getArgOperand(1),
3256 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3261 void visitMemSetInst(MemSetInst &
I) {
3265 {I.getArgOperand(0),
3266 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3267 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3271 void visitVAStartInst(VAStartInst &
I) { VAHelper->visitVAStartInst(
I); }
3273 void visitVACopyInst(VACopyInst &
I) { VAHelper->visitVACopyInst(
I); }
3279 bool handleVectorStoreIntrinsic(IntrinsicInst &
I) {
3283 Value *Addr =
I.getArgOperand(0);
3284 Value *Shadow = getShadow(&
I, 1);
3285 Value *ShadowPtr, *OriginPtr;
3289 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3293 if (Opts.msan_check_access_address)
3294 insertCheckShadowOf(Addr, &
I);
3297 if (MS.TrackOrigins)
3306 bool handleVectorLoadIntrinsic(IntrinsicInst &
I) {
3310 Value *Addr =
I.getArgOperand(0);
3312 Type *ShadowTy = getShadowTy(&
I);
3313 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
3314 if (PropagateShadow) {
3318 std::tie(ShadowPtr, OriginPtr) =
3319 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
3323 setShadow(&
I, getCleanShadow(&
I));
3326 if (Opts.msan_check_access_address)
3327 insertCheckShadowOf(Addr, &
I);
3329 if (MS.TrackOrigins) {
3330 if (PropagateShadow)
3331 setOrigin(&
I, IRB.
CreateLoad(MS.OriginTy, OriginPtr));
3333 setOrigin(&
I, getCleanOrigin());
3353 [[maybe_unused]]
bool
3354 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &
I,
3355 unsigned int trailingFlags) {
3356 Type *RetTy =
I.getType();
3360 unsigned NumArgOperands =
I.arg_size();
3361 assert(NumArgOperands >= trailingFlags);
3362 for (
unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3363 Type *Ty =
I.getArgOperand(i)->getType();
3369 ShadowAndOriginCombiner SC(
this, IRB);
3370 for (
unsigned i = 0; i < NumArgOperands; ++i)
3371 SC.Add(
I.getArgOperand(i));
3388 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &
I) {
3389 unsigned NumArgOperands =
I.arg_size();
3390 if (NumArgOperands == 0)
3393 if (NumArgOperands == 2 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3394 I.getArgOperand(1)->getType()->isVectorTy() &&
3395 I.getType()->isVoidTy() && !
I.onlyReadsMemory()) {
3397 return handleVectorStoreIntrinsic(
I);
3400 if (NumArgOperands == 1 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3401 I.getType()->isVectorTy() &&
I.onlyReadsMemory()) {
3403 return handleVectorLoadIntrinsic(
I);
3406 if (
I.doesNotAccessMemory())
3407 if (maybeHandleSimpleNomemIntrinsic(
I, 0))
3415 bool maybeHandleUnknownIntrinsic(IntrinsicInst &
I) {
3416 if (maybeHandleUnknownIntrinsicUnlogged(
I)) {
3417 if (Opts.msan_dump_heuristic_instructions)
3418 dumpInst(
I,
"Heuristic");
3420 LLVM_DEBUG(
dbgs() <<
"UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " <<
I
3427 void handleInvariantGroup(IntrinsicInst &
I) {
3428 setShadow(&
I, getShadow(&
I, 0));
3429 setOrigin(&
I, getOrigin(&
I, 0));
3432 void handleLifetimeStart(IntrinsicInst &
I) {
3437 LifetimeStartList.push_back(std::make_pair(&
I, AI));
3440 void handleBswap(IntrinsicInst &
I) {
3443 Type *OpType =
Op->getType();
3446 setOrigin(&
I, getOrigin(
Op));
3467 void handleCountLeadingTrailingZeros(IntrinsicInst &
I) {
3469 Value *Src =
I.getArgOperand(0);
3470 Value *SrcShadow = getShadow(Src);
3474 I.getType(),
I.getIntrinsicID(), {Src, False});
3476 I.getType(),
I.getIntrinsicID(), {SrcShadow, False});
3479 ConcreteZerosCount, ShadowZerosCount,
"_mscz_cmp_zeros");
3481 Value *NotAllZeroShadow =
3483 Value *OutputShadow =
3484 IRB.
CreateAnd(CompareConcreteZeros, NotAllZeroShadow,
"_mscz_main");
3490 OutputShadow = IRB.
CreateOr(OutputShadow, BoolZeroPoison,
"_mscz_bs");
3493 OutputShadow = IRB.
CreateSExt(OutputShadow, getShadowTy(Src),
"_mscz_os");
3495 setShadow(&
I, OutputShadow);
3496 setOriginForNaryOp(
I);
3505 FixedVectorType *maybeShrinkVectorShadowType(
Value *Src, IntrinsicInst &
I) {
3525 Value *maybeExtendVectorShadowWithZeros(
Value *Shadow, IntrinsicInst &
I) {
3530 Value *FullShadow = getCleanShadow(&
I);
3531 unsigned ShadowNumElems =
3533 unsigned FullShadowNumElems =
3536 assert((ShadowNumElems == FullShadowNumElems) ||
3537 (ShadowNumElems * 2 == FullShadowNumElems));
3539 if (ShadowNumElems == FullShadowNumElems) {
3540 FullShadow = Shadow;
3544 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3569 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &
I,
3570 bool HasRoundingMode) {
3571 if (HasRoundingMode) {
3579 Value *Src =
I.getArgOperand(0);
3580 assert(Src->getType()->isVectorTy());
3584 VectorType *ShadowType = maybeShrinkVectorShadowType(Src,
I);
3587 Value *S0 = getShadow(&
I, 0);
3599 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow,
I);
3601 setShadow(&
I, FullShadow);
3602 setOriginForNaryOp(
I);
3623 void handleSSEVectorConvertIntrinsic(IntrinsicInst &
I,
int NumUsedElements,
3624 bool HasRoundingMode =
false) {
3626 Value *CopyOp, *ConvertOp;
3628 assert((!HasRoundingMode ||
3630 "Invalid rounding mode");
3632 switch (
I.arg_size() - HasRoundingMode) {
3634 CopyOp =
I.getArgOperand(0);
3635 ConvertOp =
I.getArgOperand(1);
3638 ConvertOp =
I.getArgOperand(0);
3652 Value *ConvertShadow = getShadow(ConvertOp);
3653 Value *AggShadow =
nullptr;
3656 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
3657 for (
int i = 1; i < NumUsedElements; ++i) {
3659 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
3660 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
3663 AggShadow = ConvertShadow;
3666 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &
I);
3673 Value *ResultShadow = getShadow(CopyOp);
3675 for (
int i = 0; i < NumUsedElements; ++i) {
3677 ResultShadow, ConstantInt::getNullValue(EltTy),
3680 setShadow(&
I, ResultShadow);
3681 setOrigin(&
I, getOrigin(CopyOp));
3683 setShadow(&
I, getCleanShadow(&
I));
3684 setOrigin(&
I, getCleanOrigin());
3692 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
3695 return CreateShadowCast(IRB, S2,
T,
true);
3703 return CreateShadowCast(IRB, S2,
T,
true);
3720 void handleVectorShiftIntrinsic(IntrinsicInst &
I,
bool Variable) {
3726 Value *S2 = getShadow(&
I, 1);
3728 : Lower64ShadowExtend(IRB, S2, getShadowTy(&
I));
3730 Value *V2 =
I.getOperand(1);
3732 {IRB.CreateBitCast(S1, V1->getType()), V2});
3734 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3735 setOriginForNaryOp(
I);
3740 Type *getMMXVectorTy(
unsigned EltSizeInBits,
3741 unsigned X86_MMXSizeInBits = 64) {
3742 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3743 "Illegal MMX vector element size");
3745 X86_MMXSizeInBits / EltSizeInBits);
3752 case Intrinsic::x86_sse2_packsswb_128:
3753 case Intrinsic::x86_sse2_packuswb_128:
3754 return Intrinsic::x86_sse2_packsswb_128;
3756 case Intrinsic::x86_sse2_packssdw_128:
3757 case Intrinsic::x86_sse41_packusdw:
3758 return Intrinsic::x86_sse2_packssdw_128;
3760 case Intrinsic::x86_avx2_packsswb:
3761 case Intrinsic::x86_avx2_packuswb:
3762 return Intrinsic::x86_avx2_packsswb;
3764 case Intrinsic::x86_avx2_packssdw:
3765 case Intrinsic::x86_avx2_packusdw:
3766 return Intrinsic::x86_avx2_packssdw;
3768 case Intrinsic::x86_mmx_packsswb:
3769 case Intrinsic::x86_mmx_packuswb:
3770 return Intrinsic::x86_mmx_packsswb;
3772 case Intrinsic::x86_mmx_packssdw:
3773 return Intrinsic::x86_mmx_packssdw;
3775 case Intrinsic::x86_avx512_packssdw_512:
3776 case Intrinsic::x86_avx512_packusdw_512:
3777 return Intrinsic::x86_avx512_packssdw_512;
3779 case Intrinsic::x86_avx512_packsswb_512:
3780 case Intrinsic::x86_avx512_packuswb_512:
3781 return Intrinsic::x86_avx512_packsswb_512;
3797 void handleVectorPackIntrinsic(IntrinsicInst &
I,
3798 unsigned MMXEltSizeInBits = 0) {
3802 Value *S2 = getShadow(&
I, 1);
3803 assert(
S1->getType()->isVectorTy());
3809 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) :
S1->
getType();
3810 if (MMXEltSizeInBits) {
3818 if (MMXEltSizeInBits) {
3824 {S1_ext, S2_ext},
nullptr,
3825 "_msprop_vector_pack");
3826 if (MMXEltSizeInBits)
3829 setOriginForNaryOp(
I);
3833 Constant *createDppMask(
unsigned Width,
unsigned Mask) {
3834 SmallVector<Constant *, 4>
R(Width);
3846 const unsigned Width =
3853 Value *DstMaskV = createDppMask(Width, DstMask);
3870 void handleDppIntrinsic(IntrinsicInst &
I) {
3873 Value *S0 = getShadow(&
I, 0);
3877 const unsigned Width =
3879 assert(Width == 2 || Width == 4 || Width == 8);
3882 const unsigned SrcMask =
Mask >> 4;
3883 const unsigned DstMask =
Mask & 0xf;
3886 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3891 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3898 setOriginForNaryOp(
I);
3902 C = CreateAppToShadowCast(IRB,
C);
3911 void handleBlendvIntrinsic(IntrinsicInst &
I) {
3916 Value *Sc = getShadow(&
I, 2);
3917 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
3922 C = convertBlendvToSelectMask(IRB,
C);
3923 Sc = convertBlendvToSelectMask(IRB, Sc);
3929 handleSelectLikeInst(
I,
C,
T,
F);
3933 void handleVectorSadIntrinsic(IntrinsicInst &
I,
bool IsMMX =
false) {
3934 const unsigned SignificantBitsPerResultElement = 16;
3936 unsigned ZeroBitsPerResultElement =
3940 auto *Shadow0 = getShadow(&
I, 0);
3941 auto *Shadow1 = getShadow(&
I, 1);
3946 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
3949 setOriginForNaryOp(
I);
3973 void handleVectorDotProductIntrinsic(IntrinsicInst &
I,
3974 unsigned ReductionFactor,
3976 unsigned EltSizeInBits,
3980 [[maybe_unused]] FixedVectorType *
ReturnType =
3985 Value *Va =
nullptr;
3986 Value *Vb =
nullptr;
3987 Value *Sa =
nullptr;
3988 Value *Sb =
nullptr;
3990 assert(
I.arg_size() == 2 ||
I.arg_size() == 3);
3991 if (
I.arg_size() == 2) {
3994 Va =
I.getOperand(0);
3995 Vb =
I.getOperand(1);
3997 Sa = getShadow(&
I, 0);
3998 Sb = getShadow(&
I, 1);
3999 }
else if (
I.arg_size() == 3) {
4001 Va =
I.getOperand(1);
4002 Vb =
I.getOperand(2);
4004 Sa = getShadow(&
I, 1);
4005 Sb = getShadow(&
I, 2);
4022 Sa, getPclmulMask(Width, Lanes ==
kOddLanes));
4024 Sb, getPclmulMask(Width, Lanes ==
kOddLanes));
4034 if (
I.arg_size() == 3) {
4035 [[maybe_unused]]
auto *AccumulatorType =
4037 assert(AccumulatorType == ReturnType);
4040 FixedVectorType *ImplicitReturnType =
4043 if (EltSizeInBits) {
4045 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4057 ReturnType->getNumElements() * ReductionFactor);
4074 VaInt = CreateAppToShadowCast(IRB, Va);
4075 VbInt = CreateAppToShadowCast(IRB, Vb);
4082 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4104 ImplicitReturnType);
4109 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&
I));
4112 if (
I.arg_size() == 3)
4113 OutShadow = IRB.
CreateOr(OutShadow, getShadow(&
I, 0));
4115 setShadow(&
I, OutShadow);
4116 setOriginForNaryOp(
I);
4133 void handleVectorComparePackedIntrinsic(IntrinsicInst &
I,
4134 bool PredicateAsOperand) {
4135 if (PredicateAsOperand) {
4137 assert(
I.paramHasAttr(2, Attribute::ImmArg));
4145 Type *ResTy = getShadowTy(&
I);
4146 auto *Shadow0 = getShadow(&
I, 0);
4147 auto *Shadow1 = getShadow(&
I, 1);
4152 setOriginForNaryOp(
I);
4158 void handleVectorCompareScalarIntrinsic(IntrinsicInst &
I) {
4160 auto *Shadow0 = getShadow(&
I, 0);
4161 auto *Shadow1 = getShadow(&
I, 1);
4163 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&
I));
4165 setOriginForNaryOp(
I);
4174 void handleVectorReduceIntrinsic(IntrinsicInst &
I,
bool AllowShadowCast) {
4179 if (AllowShadowCast)
4180 S = CreateShadowCast(IRB, S, getShadowTy(&
I));
4184 setOriginForNaryOp(
I);
4194 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &
I) {
4198 Value *Shadow0 = getShadow(&
I, 0);
4204 setOriginForNaryOp(
I);
4224 void handleVectorPartialReduceAddIntrinsic(IntrinsicInst &
I) {
4229 [[maybe_unused]]
Value *Addends =
I.getArgOperand(1);
4243 Value *SAcc = getShadow(&
I, 0);
4244 Value *SAdd = getShadow(&
I, 1);
4264 SAcc->
getType(), Intrinsic::vector_partial_reduce_add, {SAcc, SAdd});
4269 setShadow(&
I, SOutput);
4270 setOriginForNaryOp(
I);
4276 void handleVectorReduceOrIntrinsic(IntrinsicInst &
I) {
4280 Value *OperandShadow = getShadow(&
I, 0);
4282 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
4290 setOrigin(&
I, getOrigin(&
I, 0));
4296 void handleVectorReduceAndIntrinsic(IntrinsicInst &
I) {
4300 Value *OperandShadow = getShadow(&
I, 0);
4301 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
4309 setOrigin(&
I, getOrigin(&
I, 0));
4312 void handleStmxcsr(IntrinsicInst &
I) {
4314 Value *Addr =
I.getArgOperand(0);
4317 getShadowOriginPtr(Addr, IRB, Ty,
Align(1),
true).first;
4321 if (Opts.msan_check_access_address)
4322 insertCheckShadowOf(Addr, &
I);
4325 void handleLdmxcsr(IntrinsicInst &
I) {
4330 Value *Addr =
I.getArgOperand(0);
4333 Value *ShadowPtr, *OriginPtr;
4334 std::tie(ShadowPtr, OriginPtr) =
4335 getShadowOriginPtr(Addr, IRB, Ty, Alignment,
false);
4337 if (Opts.msan_check_access_address)
4338 insertCheckShadowOf(Addr, &
I);
4341 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
4343 insertCheckShadow(Shadow, Origin, &
I);
4346 void handleMaskedExpandLoad(IntrinsicInst &
I) {
4348 Value *Ptr =
I.getArgOperand(0);
4349 MaybeAlign
Align =
I.getParamAlign(0);
4351 Value *PassThru =
I.getArgOperand(2);
4353 if (Opts.msan_check_access_address) {
4354 insertCheckShadowOf(Ptr, &
I);
4355 insertCheckShadowOf(Mask, &
I);
4358 if (!PropagateShadow) {
4359 setShadow(&
I, getCleanShadow(&
I));
4360 setOrigin(&
I, getCleanOrigin());
4364 Type *ShadowTy = getShadowTy(&
I);
4366 auto [ShadowPtr, OriginPtr] =
4367 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
false);
4371 getShadow(PassThru),
"_msmaskedexpload");
4373 setShadow(&
I, Shadow);
4376 setOrigin(&
I, getCleanOrigin());
4379 void handleMaskedCompressStore(IntrinsicInst &
I) {
4382 Value *Ptr =
I.getArgOperand(1);
4383 MaybeAlign
Align =
I.getParamAlign(1);
4386 if (Opts.msan_check_access_address) {
4387 insertCheckShadowOf(Ptr, &
I);
4388 insertCheckShadowOf(Mask, &
I);
4392 Type *ElementShadowTy =
4394 auto [ShadowPtr, OriginPtrs] =
4395 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
true);
4402 void handleMaskedGather(IntrinsicInst &
I) {
4404 Value *Ptrs =
I.getArgOperand(0);
4407 Value *PassThru =
I.getArgOperand(2);
4409 Type *PtrsShadowTy = getShadowTy(Ptrs);
4410 if (Opts.msan_check_access_address) {
4411 insertCheckShadowOf(Mask, &
I);
4415 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4418 if (!PropagateShadow) {
4419 setShadow(&
I, getCleanShadow(&
I));
4420 setOrigin(&
I, getCleanOrigin());
4424 Type *ShadowTy = getShadowTy(&
I);
4426 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4427 Ptrs, IRB, ElementShadowTy, Alignment,
false);
4431 getShadow(PassThru),
"_msmaskedgather");
4433 setShadow(&
I, Shadow);
4436 setOrigin(&
I, getCleanOrigin());
4439 void handleMaskedScatter(IntrinsicInst &
I) {
4442 Value *Ptrs =
I.getArgOperand(1);
4446 Type *PtrsShadowTy = getShadowTy(Ptrs);
4447 if (Opts.msan_check_access_address) {
4448 insertCheckShadowOf(Mask, &
I);
4452 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4456 Type *ElementShadowTy =
4458 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4459 Ptrs, IRB, ElementShadowTy, Alignment,
true);
4470 void handleMaskedStore(IntrinsicInst &
I) {
4472 Value *
V =
I.getArgOperand(0);
4473 Value *Ptr =
I.getArgOperand(1);
4476 Value *Shadow = getShadow(V);
4478 if (Opts.msan_check_access_address) {
4479 insertCheckShadowOf(Ptr, &
I);
4480 insertCheckShadowOf(Mask, &
I);
4485 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4486 Ptr, IRB, Shadow->
getType(), Alignment,
true);
4490 if (!MS.TrackOrigins)
4493 auto &
DL =
F.getDataLayout();
4494 paintOrigin(IRB, getOrigin(V), OriginPtr,
4503 void handleMaskedLoad(IntrinsicInst &
I) {
4505 Value *Ptr =
I.getArgOperand(0);
4508 Value *PassThru =
I.getArgOperand(2);
4510 if (Opts.msan_check_access_address) {
4511 insertCheckShadowOf(Ptr, &
I);
4512 insertCheckShadowOf(Mask, &
I);
4515 if (!PropagateShadow) {
4516 setShadow(&
I, getCleanShadow(&
I));
4517 setOrigin(&
I, getCleanOrigin());
4521 Type *ShadowTy = getShadowTy(&
I);
4522 Value *ShadowPtr, *OriginPtr;
4523 std::tie(ShadowPtr, OriginPtr) =
4524 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment,
false);
4526 getShadow(PassThru),
"_msmaskedld"));
4528 if (!MS.TrackOrigins)
4535 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
4540 setOrigin(&
I, Origin);
4550 void handleMaskedIntegerDivRem(IntrinsicInst &
I) {
4553 Value *Dividend =
I.getArgOperand(0);
4554 Value *Divisor =
I.getArgOperand(1);
4557 insertCheckShadowOf(Mask, &
I);
4560 Mask, getShadow(Divisor), getCleanShadow(Divisor),
"_msmaskeddivisor");
4561 insertCheckShadow(MaskedDivisorShadow, getOrigin(Divisor), &
I);
4563 if (!PropagateShadow) {
4564 setShadow(&
I, getCleanShadow(&
I));
4565 setOrigin(&
I, getCleanOrigin());
4570 getPoisonedShadow(&
I),
"_msmaskeddiv"));
4571 setOrigin(&
I, getOrigin(Dividend));
4576 void handleVectorExtractLastActive(IntrinsicInst &
I) {
4581 Value *PassThru =
I.getArgOperand(2);
4594 insertCheckShadowOf(Mask, &
I);
4596 if (!PropagateShadow) {
4597 setShadow(&
I, getCleanShadow(&
I));
4598 setOrigin(&
I, getCleanOrigin());
4604 Intrinsic::experimental_vector_extract_last_active,
4605 {DataShadow->
getType()}, {DataShadow,
Mask, getShadow(PassThru)},
4606 {},
"_msprop_vector_extract_last_active");
4607 setShadow(&
I, Shadow);
4609 if (MS.TrackOrigins) {
4612 getOrigin(PassThru)));
4629 void handleAVXMaskedStore(IntrinsicInst &
I) {
4634 Value *Dst =
I.getArgOperand(0);
4635 assert(Dst->getType()->isPointerTy() &&
"Destination is not a pointer!");
4640 Value *Src =
I.getArgOperand(2);
4645 Value *SrcShadow = getShadow(Src);
4647 if (Opts.msan_check_access_address) {
4648 insertCheckShadowOf(Dst, &
I);
4649 insertCheckShadowOf(Mask, &
I);
4652 Value *DstShadowPtr;
4653 Value *DstOriginPtr;
4654 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4655 Dst, IRB, SrcShadow->
getType(), Alignment,
true);
4657 SmallVector<Value *, 2> ShadowArgs;
4658 ShadowArgs.
append(1, DstShadowPtr);
4659 ShadowArgs.
append(1, Mask);
4667 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
4670 if (!MS.TrackOrigins)
4674 auto &
DL =
F.getDataLayout();
4675 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4676 DL.getTypeStoreSize(SrcShadow->
getType()),
4695 void handleAVXMaskedLoad(IntrinsicInst &
I) {
4700 Value *Src =
I.getArgOperand(0);
4701 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
4708 if (Opts.msan_check_access_address) {
4709 insertCheckShadowOf(Mask, &
I);
4712 Type *SrcShadowTy = getShadowTy(Src);
4713 Value *SrcShadowPtr, *SrcOriginPtr;
4714 std::tie(SrcShadowPtr, SrcOriginPtr) =
4715 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment,
false);
4717 SmallVector<Value *, 2> ShadowArgs;
4718 ShadowArgs.
append(1, SrcShadowPtr);
4719 ShadowArgs.
append(1, Mask);
4722 I.getType(),
I.getIntrinsicID(), ShadowArgs);
4728 if (!MS.TrackOrigins)
4735 setOrigin(&
I, PtrSrcOrigin);
4744 assert(isFixedIntVector(Idx));
4745 auto IdxVectorSize =
4753 auto *IdxShadow = getShadow(Idx);
4758 insertCheckShadow(Truncated, getOrigin(Idx),
I);
4763 void handleAVXVpermilvar(IntrinsicInst &
I) {
4765 Value *Shadow = getShadow(&
I, 0);
4766 maskedCheckAVXIndexShadow(IRB,
I.getArgOperand(1), &
I);
4770 Shadow = IRB.
CreateBitCast(Shadow,
I.getArgOperand(0)->getType());
4772 I.getType(),
I.getIntrinsicID(), {Shadow, I.getArgOperand(1)});
4775 setOriginForNaryOp(
I);
4780 void handleAVXVpermi2var(IntrinsicInst &
I) {
4785 [[maybe_unused]]
auto ArgVectorSize =
4788 ->getNumElements() == ArgVectorSize);
4790 ->getNumElements() == ArgVectorSize);
4791 assert(
I.getArgOperand(0)->getType() ==
I.getArgOperand(2)->getType());
4792 assert(
I.getType() ==
I.getArgOperand(0)->getType());
4793 assert(
I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4795 Value *AShadow = getShadow(&
I, 0);
4797 Value *BShadow = getShadow(&
I, 2);
4799 maskedCheckAVXIndexShadow(IRB, Idx, &
I);
4803 AShadow = IRB.
CreateBitCast(AShadow,
I.getArgOperand(0)->getType());
4804 BShadow = IRB.
CreateBitCast(BShadow,
I.getArgOperand(2)->getType());
4806 I.getType(),
I.getIntrinsicID(), {AShadow, Idx, BShadow});
4808 setOriginForNaryOp(
I);
4811 [[maybe_unused]]
static bool isFixedIntVectorTy(
const Type *
T) {
4815 [[maybe_unused]]
static bool isFixedFPVectorTy(
const Type *
T) {
4819 [[maybe_unused]]
static bool isFixedIntVector(
const Value *V) {
4820 return isFixedIntVectorTy(
V->getType());
4823 [[maybe_unused]]
static bool isFixedFPVector(
const Value *V) {
4824 return isFixedFPVectorTy(
V->getType());
4846 void handleAVX512VectorConvertFPToInt(IntrinsicInst &
I,
bool LastMask) {
4851 Value *WriteThrough;
4855 WriteThrough =
I.getOperand(2);
4856 Mask =
I.getOperand(3);
4859 WriteThrough =
I.getOperand(1);
4860 Mask =
I.getOperand(2);
4865 assert(isFixedIntVector(WriteThrough));
4867 unsigned ANumElements =
4869 [[maybe_unused]]
unsigned WriteThruNumElements =
4871 assert(ANumElements == WriteThruNumElements ||
4872 ANumElements * 2 == WriteThruNumElements);
4875 unsigned MaskNumElements =
Mask->getType()->getScalarSizeInBits();
4876 assert(ANumElements == MaskNumElements ||
4877 ANumElements * 2 == MaskNumElements);
4879 assert(WriteThruNumElements == MaskNumElements);
4883 insertCheckShadowOf(Mask, &
I);
4893 Value *AShadow = getShadow(
A);
4894 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
4896 if (ANumElements * 2 == MaskNumElements) {
4908 "_ms_mask_bitcast");
4918 getShadowTy(&
I),
"_ms_a_shadow");
4920 Value *WriteThroughShadow = getShadow(WriteThrough);
4922 "_ms_writethru_select");
4924 setShadow(&
I, Shadow);
4925 setOriginForNaryOp(
I);
4928 static SmallVector<int, 8> getPclmulMask(
unsigned Width,
bool OddElements) {
4929 SmallVector<int, 8>
Mask;
4930 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
4944 void handlePclmulIntrinsic(IntrinsicInst &
I) {
4949 "pclmul 3rd operand must be a constant");
4952 getPclmulMask(Width,
Imm & 0x01));
4954 getPclmulMask(Width,
Imm & 0x10));
4955 ShadowAndOriginCombiner SOC(
this, IRB);
4956 SOC.Add(Shuf0, getOrigin(&
I, 0));
4957 SOC.Add(Shuf1, getOrigin(&
I, 1));
4962 void handleUnarySdSsIntrinsic(IntrinsicInst &
I) {
4967 Value *Second = getShadow(&
I, 1);
4969 SmallVector<int, 16>
Mask;
4970 Mask.push_back(Width);
4971 for (
unsigned i = 1; i < Width; i++)
4975 setShadow(&
I, Shadow);
4976 setOriginForNaryOp(
I);
4979 void handleVtestIntrinsic(IntrinsicInst &
I) {
4981 Value *Shadow0 = getShadow(&
I, 0);
4982 Value *Shadow1 = getShadow(&
I, 1);
4988 setShadow(&
I, Shadow);
4989 setOriginForNaryOp(
I);
4992 void handleBinarySdSsIntrinsic(IntrinsicInst &
I) {
4997 Value *Second = getShadow(&
I, 1);
5000 SmallVector<int, 16>
Mask;
5001 Mask.push_back(Width);
5002 for (
unsigned i = 1; i < Width; i++)
5006 setShadow(&
I, Shadow);
5007 setOriginForNaryOp(
I);
5013 void handleRoundPdPsIntrinsic(IntrinsicInst &
I) {
5014 assert(
I.getArgOperand(0)->getType() ==
I.getType());
5019 ShadowAndOriginCombiner SC(
this, IRB);
5020 SC.Add(
I.getArgOperand(0));
5028 void handleAbsIntrinsic(IntrinsicInst &
I) {
5030 Value *Src =
I.getArgOperand(0);
5031 Value *IsIntMinPoison =
I.getArgOperand(1);
5033 assert(
I.getType()->isIntOrIntVectorTy());
5035 assert(Src->getType() ==
I.getType());
5041 Value *SrcShadow = getShadow(Src);
5045 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5048 Value *PoisonedShadow = getPoisonedShadow(Src);
5049 Value *PoisonedIfIntMinShadow =
5052 IRB.
CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5054 setShadow(&
I, Shadow);
5055 setOrigin(&
I, getOrigin(&
I, 0));
5058 void handleIsFpClass(IntrinsicInst &
I) {
5060 Value *Shadow = getShadow(&
I, 0);
5061 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5062 setOrigin(&
I, getOrigin(&
I, 0));
5065 void handleArithmeticWithOverflow(IntrinsicInst &
I) {
5067 Value *Shadow0 = getShadow(&
I, 0);
5068 Value *Shadow1 = getShadow(&
I, 1);
5071 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5077 setShadow(&
I, Shadow);
5078 setOriginForNaryOp(
I);
5081 void handleModfOrSincos(IntrinsicInst &
I) {
5083 Value *ArgShadow = getShadow(&
I, 0);
5087 setShadow(&
I, Shadow);
5088 setOrigin(&
I, getOrigin(&
I, 0));
5094 Value *Shadow = getShadow(V);
5116 void handleAVX512VectorDownConvert(IntrinsicInst &
I) {
5121 Value *WriteThrough =
I.getOperand(1);
5125 assert(isFixedIntVector(WriteThrough));
5127 unsigned ANumElements =
5129 unsigned OutputNumElements =
5131 assert(ANumElements == OutputNumElements ||
5132 ANumElements * 2 == OutputNumElements);
5142 insertCheckShadowOf(Mask, &
I);
5145 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5146 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5147 assert(
Mask->getType()->getScalarSizeInBits() == ANumElements);
5158 if (ANumElements != OutputNumElements) {
5160 Mask = IRB.
CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5167 Value *AShadow = getShadow(
A);
5171 VectorType *ShadowType = maybeShrinkVectorShadowType(
A,
I);
5181 AShadow = IRB.
CreateTrunc(AShadow, ShadowType,
"_ms_trunc_shadow");
5182 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
5184 Value *WriteThroughShadow = getShadow(WriteThrough);
5187 setShadow(&
I, Shadow);
5188 setOriginForNaryOp(
I);
5222 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &
I,
5223 SmallVector<unsigned, 4> DataIndices,
5224 unsigned WriteThruIndex,
5225 unsigned MaskIndex) {
5228 unsigned NumArgs =
I.arg_size();
5230 assert(WriteThruIndex < NumArgs);
5231 assert(MaskIndex < NumArgs);
5232 assert(WriteThruIndex != MaskIndex);
5233 Value *WriteThru =
I.getOperand(WriteThruIndex);
5235 unsigned OutputNumElements =
5240 bool isData[16] = {
false};
5242 for (
unsigned i : DataIndices) {
5244 assert(i != WriteThruIndex);
5251 [[maybe_unused]]
unsigned ANumElements =
5253 assert(ANumElements == OutputNumElements);
5258 assert(isFixedFPVector(WriteThru));
5260 for (
unsigned i = 0; i < NumArgs; ++i) {
5261 if (!isData[i] && i != WriteThruIndex) {
5264 assert(
I.getOperand(i)->getType()->isIntegerTy());
5265 insertCheckShadowOf(
I.getOperand(i), &
I);
5270 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5271 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5272 assert(
Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5279 Value *DataShadow =
nullptr;
5280 for (
unsigned i : DataIndices) {
5283 DataShadow = IRB.
CreateOr(DataShadow, getShadow(
A));
5285 DataShadow = getShadow(
A);
5293 Value *WriteThruShadow = getShadow(WriteThru);
5296 setShadow(&
I, Shadow);
5298 setOriginForNaryOp(
I);
5308 void handleAVX512FPClass(IntrinsicInst &
I) {
5314 assert(isFixedFPVector(Input));
5317 Value *Classifiers =
I.getOperand(1);
5321 assert(isFixedIntVectorTy(
I.getType()));
5327 Value *OutputShadow;
5332 OutputShadow = getCleanShadow(OutputType);
5338 OutputShadow = IRB.
CreateICmpNE(getShadow(Input), getCleanShadow(Input));
5340 setShadow(&
I, OutputShadow);
5342 setOriginForNaryOp(
I);
5352 void visitGenericScalarHalfwordInst(IntrinsicInst &
I) {
5358 Value *WriteThrough =
I.getOperand(2);
5365 insertCheckShadowOf(Mask, &
I);
5369 unsigned NumElements =
5371 assert(NumElements == 8);
5372 assert(
A->getType() ==
B->getType());
5374 assert(
Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5377 Value *ALowerShadow = extractLowerShadow(IRB,
A);
5378 Value *BLowerShadow = extractLowerShadow(IRB,
B);
5380 Value *ABLowerShadow = IRB.
CreateOr(ALowerShadow, BLowerShadow);
5382 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5389 Value *AShadow = getShadow(
A);
5390 Value *DstLowerShadow =
5391 IRB.
CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5393 AShadow, DstLowerShadow, ConstantInt::get(IRB.
getInt32Ty(), 0),
5396 setShadow(&
I, DstShadow);
5397 setOriginForNaryOp(
I);
5427 void handleAVXGF2P8Affine(IntrinsicInst &
I) {
5438 ->getScalarSizeInBits() == 8);
5440 assert(
A->getType() ==
X->getType());
5442 assert(
B->getType()->isIntegerTy());
5443 assert(
B->getType()->getScalarSizeInBits() == 8);
5445 assert(
I.getType() ==
A->getType());
5447 Value *AShadow = getShadow(
A);
5448 Value *XShadow = getShadow(
X);
5449 Value *BZeroShadow = getCleanShadow(
B);
5452 I.getType(),
I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5454 {X, AShadow, BZeroShadow});
5456 {XShadow, A, BZeroShadow});
5459 Value *BShadow = getShadow(
B);
5460 Value *BBroadcastShadow = getCleanShadow(AShadow);
5465 for (
unsigned i = 0; i < NumElements; i++)
5469 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5470 setOriginForNaryOp(
I);
5484 void handleNEONVectorLoad(IntrinsicInst &
I,
bool WithLane) {
5485 unsigned int numArgs =
I.arg_size();
5488 assert(
I.getType()->isStructTy());
5498 assert(4 <= numArgs && numArgs <= 6);
5512 for (
unsigned int i = 0; i < numArgs - 2; i++)
5513 ShadowArgs.
push_back(getShadow(
I.getArgOperand(i)));
5516 Value *LaneNumber =
I.getArgOperand(numArgs - 2);
5520 insertCheckShadowOf(LaneNumber, &
I);
5523 Value *Src =
I.getArgOperand(numArgs - 1);
5524 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
5526 Type *SrcShadowTy = getShadowTy(Src);
5527 auto [SrcShadowPtr, SrcOriginPtr] =
5528 getShadowOriginPtr(Src, IRB, SrcShadowTy,
Align(1),
false);
5535 getShadowTy(&
I),
I.getIntrinsicID(), ShadowArgs);
5538 if (!MS.TrackOrigins)
5542 setOrigin(&
I, PtrSrcOrigin);
5559 void handleNEONVectorStoreIntrinsic(IntrinsicInst &
I,
bool useLane) {
5563 int numArgOperands =
I.arg_size();
5566 assert(numArgOperands >= 1);
5567 Value *Addr =
I.getArgOperand(numArgOperands - 1);
5569 int skipTrailingOperands = 1;
5571 if (Opts.msan_check_access_address)
5572 insertCheckShadowOf(Addr, &
I);
5576 skipTrailingOperands++;
5577 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
5579 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5582 SmallVector<Value *, 8> ShadowArgs;
5584 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5586 Value *Shadow = getShadow(&
I, i);
5587 ShadowArgs.
append(1, Shadow);
5604 (numArgOperands - skipTrailingOperands));
5605 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5609 I.getArgOperand(numArgOperands - skipTrailingOperands));
5611 Value *OutputShadowPtr, *OutputOriginPtr;
5613 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5614 Addr, IRB, OutputShadowTy,
Align(1),
true);
5615 ShadowArgs.
append(1, OutputShadowPtr);
5618 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
5621 if (MS.TrackOrigins) {
5629 OriginCombiner OC(
this, IRB);
5630 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5631 OC.Add(
I.getArgOperand(i));
5633 const DataLayout &
DL =
F.getDataLayout();
5634 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
5667 void handleNEONMatrixMultiply(IntrinsicInst &
I) {
5671 Value *
R =
I.getArgOperand(0);
5672 Value *
A =
I.getArgOperand(1);
5673 Value *
B =
I.getArgOperand(2);
5675 assert(
I.getType() ==
R->getType());
5700 Value *ShadowR = getShadow(&
I, 0);
5701 Value *ShadowA = getShadow(&
I, 1);
5702 Value *ShadowB = getShadow(&
I, 2);
5720 {getCleanShadow(RTy), ShadowA, ShadowB});
5746 {RZeros, ShadowA, ShadowB});
5760 ShadowR = IRB.
CreateICmpNE(ShadowR, getCleanShadow(RTy));
5761 ShadowR = IRB.
CreateOr(ShadowAB, ShadowR);
5763 setShadow(&
I, IRB.
CreateSExt(ShadowR, getShadowTy(RTy)));
5765 setOriginForNaryOp(
I);
5805 void handleIntrinsicByApplyingToShadow(IntrinsicInst &
I,
5807 unsigned int trailingVerbatimArgs,
5808 bool forceIntegerIntrinsic) {
5811 assert(trailingVerbatimArgs <
I.arg_size());
5813 SmallVector<Value *, 8> ShadowArgs;
5815 for (
unsigned int i = 0; i <
I.arg_size() - trailingVerbatimArgs; i++) {
5816 Value *Shadow = getShadow(&
I, i);
5818 if (forceIntegerIntrinsic)
5825 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5827 Value *Arg =
I.getArgOperand(i);
5828 if (forceIntegerIntrinsic)
5833 Value *CombinedShadow;
5834 if (forceIntegerIntrinsic) {
5844 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5847 CreateShadowCast(IRB, getShadow(&
I, i), CombinedShadow->
getType());
5848 CombinedShadow = IRB.
CreateOr(Shadow, CombinedShadow,
"_msprop");
5851 setShadow(&
I, CombinedShadow);
5853 setOriginForNaryOp(
I);
5859 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &
I) {
5897 void handleNEONDotProductLaneIntrinsic(IntrinsicInst &
I,
5898 unsigned ReductionFactor) {
5902 [[maybe_unused]]
Value *VAcc =
I.getOperand(0);
5903 [[maybe_unused]]
Value *Va =
I.getOperand(1);
5904 [[maybe_unused]]
Value *Vb =
I.getOperand(2);
5905 Value *Lane =
I.getOperand(3);
5912 I.getType()->getPrimitiveSizeInBits());
5921 I.getType()->getPrimitiveSizeInBits());
5927 Value *SAcc = getShadow(&
I, 0);
5928 Value *Sa = getShadow(&
I, 1);
5929 Value *Sb = getShadow(&
I, 2);
5936 Sb, FixedVectorType::getWithSizeAndScalar(
5952 SOutput = IRB.
CreateSelect(SbClean, SOutput, getPoisonedShadow(SOutput));
5954 setShadow(&
I, SOutput);
5955 setOriginForNaryOp(
I);
5958 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &
I) {
5959 switch (
I.getIntrinsicID()) {
5960 case Intrinsic::uadd_with_overflow:
5961 case Intrinsic::sadd_with_overflow:
5962 case Intrinsic::usub_with_overflow:
5963 case Intrinsic::ssub_with_overflow:
5964 case Intrinsic::umul_with_overflow:
5965 case Intrinsic::smul_with_overflow:
5966 handleArithmeticWithOverflow(
I);
5968 case Intrinsic::modf:
5969 case Intrinsic::sincos:
5970 case Intrinsic::sincospi:
5971 handleModfOrSincos(
I);
5973 case Intrinsic::abs:
5974 handleAbsIntrinsic(
I);
5976 case Intrinsic::bitreverse:
5977 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
5981 case Intrinsic::is_fpclass:
5984 case Intrinsic::lifetime_start:
5985 handleLifetimeStart(
I);
5987 case Intrinsic::launder_invariant_group:
5988 handleInvariantGroup(
I);
5990 case Intrinsic::bswap:
5993 case Intrinsic::ctlz:
5994 case Intrinsic::cttz:
5995 handleCountLeadingTrailingZeros(
I);
5997 case Intrinsic::masked_compressstore:
5998 handleMaskedCompressStore(
I);
6000 case Intrinsic::masked_expandload:
6001 handleMaskedExpandLoad(
I);
6003 case Intrinsic::masked_gather:
6004 handleMaskedGather(
I);
6006 case Intrinsic::masked_scatter:
6007 handleMaskedScatter(
I);
6009 case Intrinsic::masked_store:
6010 handleMaskedStore(
I);
6012 case Intrinsic::masked_load:
6013 handleMaskedLoad(
I);
6015 case Intrinsic::masked_udiv:
6016 case Intrinsic::masked_sdiv:
6017 case Intrinsic::masked_urem:
6018 case Intrinsic::masked_srem:
6019 handleMaskedIntegerDivRem(
I);
6021 case Intrinsic::vector_reduce_and:
6022 handleVectorReduceAndIntrinsic(
I);
6024 case Intrinsic::vector_reduce_or:
6025 handleVectorReduceOrIntrinsic(
I);
6028 case Intrinsic::vector_reduce_add:
6029 case Intrinsic::vector_reduce_xor:
6030 case Intrinsic::vector_reduce_mul:
6033 case Intrinsic::vector_reduce_smax:
6034 case Intrinsic::vector_reduce_smin:
6035 case Intrinsic::vector_reduce_umax:
6036 case Intrinsic::vector_reduce_umin:
6039 case Intrinsic::vector_reduce_fmax:
6040 case Intrinsic::vector_reduce_fmin:
6041 handleVectorReduceIntrinsic(
I,
false);
6044 case Intrinsic::vector_reduce_fadd:
6045 case Intrinsic::vector_reduce_fmul:
6046 handleVectorReduceWithStarterIntrinsic(
I);
6050 case Intrinsic::vector_partial_reduce_add:
6051 case Intrinsic::vector_partial_reduce_fadd:
6052 handleVectorPartialReduceAddIntrinsic(
I);
6055 case Intrinsic::experimental_vector_extract_last_active:
6056 handleVectorExtractLastActive(
I);
6059 case Intrinsic::scmp:
6060 case Intrinsic::ucmp: {
6065 case Intrinsic::fshl:
6066 case Intrinsic::fshr:
6067 handleFunnelShift(
I);
6070 case Intrinsic::pdep:
6071 case Intrinsic::pext:
6072 handleGenericBitManipulation(
I);
6075 case Intrinsic::is_constant:
6077 setShadow(&
I, getCleanShadow(&
I));
6078 setOrigin(&
I, getCleanOrigin());
6085 case Intrinsic::fptosi_sat:
6086 case Intrinsic::fptoui_sat:
6087 handleGenericVectorConvertIntrinsic(
I,
false);
6094 case Intrinsic::fake_use:
6095 assert(
I.getType()->isVoidTy());
6108 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &
I) {
6109 switch (
I.getIntrinsicID()) {
6110 case Intrinsic::x86_sse_stmxcsr:
6113 case Intrinsic::x86_sse_ldmxcsr:
6120 case Intrinsic::x86_avx512_vcvtsd2usi64:
6121 case Intrinsic::x86_avx512_vcvtsd2usi32:
6122 case Intrinsic::x86_avx512_vcvtss2usi64:
6123 case Intrinsic::x86_avx512_vcvtss2usi32:
6124 case Intrinsic::x86_avx512_cvttss2usi64:
6125 case Intrinsic::x86_avx512_cvttss2usi:
6126 case Intrinsic::x86_avx512_cvttsd2usi64:
6127 case Intrinsic::x86_avx512_cvttsd2usi:
6128 case Intrinsic::x86_avx512_cvtusi2ss:
6129 case Intrinsic::x86_avx512_cvtusi642sd:
6130 case Intrinsic::x86_avx512_cvtusi642ss:
6131 handleSSEVectorConvertIntrinsic(
I, 1,
true);
6133 case Intrinsic::x86_sse2_cvtsd2si64:
6134 case Intrinsic::x86_sse2_cvtsd2si:
6135 case Intrinsic::x86_sse2_cvtsd2ss:
6136 case Intrinsic::x86_sse2_cvttsd2si64:
6137 case Intrinsic::x86_sse2_cvttsd2si:
6138 case Intrinsic::x86_sse_cvtss2si64:
6139 case Intrinsic::x86_sse_cvtss2si:
6140 case Intrinsic::x86_sse_cvttss2si64:
6141 case Intrinsic::x86_sse_cvttss2si:
6142 handleSSEVectorConvertIntrinsic(
I, 1);
6144 case Intrinsic::x86_sse_cvtps2pi:
6145 case Intrinsic::x86_sse_cvttps2pi:
6146 handleSSEVectorConvertIntrinsic(
I, 2);
6154 case Intrinsic::x86_vcvtps2ph_128:
6155 case Intrinsic::x86_vcvtps2ph_256: {
6156 handleSSEVectorConvertIntrinsicByProp(
I,
true);
6165 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
6166 handleAVX512VectorConvertFPToInt(
I,
false);
6171 case Intrinsic::x86_sse2_cvtpd2ps:
6172 case Intrinsic::x86_sse2_cvtps2dq:
6173 case Intrinsic::x86_sse2_cvtpd2dq:
6174 case Intrinsic::x86_sse2_cvttps2dq:
6175 case Intrinsic::x86_sse2_cvttpd2dq:
6176 case Intrinsic::x86_avx_cvt_pd2_ps_256:
6177 case Intrinsic::x86_avx_cvt_ps2dq_256:
6178 case Intrinsic::x86_avx_cvt_pd2dq_256:
6179 case Intrinsic::x86_avx_cvtt_ps2dq_256:
6180 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
6181 handleSSEVectorConvertIntrinsicByProp(
I,
false);
6192 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
6193 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
6194 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
6195 handleAVX512VectorConvertFPToInt(
I,
true);
6199 case Intrinsic::x86_avx512_psll_w_512:
6200 case Intrinsic::x86_avx512_psll_d_512:
6201 case Intrinsic::x86_avx512_psll_q_512:
6202 case Intrinsic::x86_avx512_pslli_w_512:
6203 case Intrinsic::x86_avx512_pslli_d_512:
6204 case Intrinsic::x86_avx512_pslli_q_512:
6205 case Intrinsic::x86_avx512_psrl_w_512:
6206 case Intrinsic::x86_avx512_psrl_d_512:
6207 case Intrinsic::x86_avx512_psrl_q_512:
6208 case Intrinsic::x86_avx512_psra_w_512:
6209 case Intrinsic::x86_avx512_psra_d_512:
6210 case Intrinsic::x86_avx512_psra_q_512:
6211 case Intrinsic::x86_avx512_psrli_w_512:
6212 case Intrinsic::x86_avx512_psrli_d_512:
6213 case Intrinsic::x86_avx512_psrli_q_512:
6214 case Intrinsic::x86_avx512_psrai_w_512:
6215 case Intrinsic::x86_avx512_psrai_d_512:
6216 case Intrinsic::x86_avx512_psrai_q_512:
6217 case Intrinsic::x86_avx512_psra_q_256:
6218 case Intrinsic::x86_avx512_psra_q_128:
6219 case Intrinsic::x86_avx512_psrai_q_256:
6220 case Intrinsic::x86_avx512_psrai_q_128:
6221 case Intrinsic::x86_avx2_psll_w:
6222 case Intrinsic::x86_avx2_psll_d:
6223 case Intrinsic::x86_avx2_psll_q:
6224 case Intrinsic::x86_avx2_pslli_w:
6225 case Intrinsic::x86_avx2_pslli_d:
6226 case Intrinsic::x86_avx2_pslli_q:
6227 case Intrinsic::x86_avx2_psrl_w:
6228 case Intrinsic::x86_avx2_psrl_d:
6229 case Intrinsic::x86_avx2_psrl_q:
6230 case Intrinsic::x86_avx2_psra_w:
6231 case Intrinsic::x86_avx2_psra_d:
6232 case Intrinsic::x86_avx2_psrli_w:
6233 case Intrinsic::x86_avx2_psrli_d:
6234 case Intrinsic::x86_avx2_psrli_q:
6235 case Intrinsic::x86_avx2_psrai_w:
6236 case Intrinsic::x86_avx2_psrai_d:
6237 case Intrinsic::x86_sse2_psll_w:
6238 case Intrinsic::x86_sse2_psll_d:
6239 case Intrinsic::x86_sse2_psll_q:
6240 case Intrinsic::x86_sse2_pslli_w:
6241 case Intrinsic::x86_sse2_pslli_d:
6242 case Intrinsic::x86_sse2_pslli_q:
6243 case Intrinsic::x86_sse2_psrl_w:
6244 case Intrinsic::x86_sse2_psrl_d:
6245 case Intrinsic::x86_sse2_psrl_q:
6246 case Intrinsic::x86_sse2_psra_w:
6247 case Intrinsic::x86_sse2_psra_d:
6248 case Intrinsic::x86_sse2_psrli_w:
6249 case Intrinsic::x86_sse2_psrli_d:
6250 case Intrinsic::x86_sse2_psrli_q:
6251 case Intrinsic::x86_sse2_psrai_w:
6252 case Intrinsic::x86_sse2_psrai_d:
6253 case Intrinsic::x86_mmx_psll_w:
6254 case Intrinsic::x86_mmx_psll_d:
6255 case Intrinsic::x86_mmx_psll_q:
6256 case Intrinsic::x86_mmx_pslli_w:
6257 case Intrinsic::x86_mmx_pslli_d:
6258 case Intrinsic::x86_mmx_pslli_q:
6259 case Intrinsic::x86_mmx_psrl_w:
6260 case Intrinsic::x86_mmx_psrl_d:
6261 case Intrinsic::x86_mmx_psrl_q:
6262 case Intrinsic::x86_mmx_psra_w:
6263 case Intrinsic::x86_mmx_psra_d:
6264 case Intrinsic::x86_mmx_psrli_w:
6265 case Intrinsic::x86_mmx_psrli_d:
6266 case Intrinsic::x86_mmx_psrli_q:
6267 case Intrinsic::x86_mmx_psrai_w:
6268 case Intrinsic::x86_mmx_psrai_d:
6269 handleVectorShiftIntrinsic(
I,
false);
6271 case Intrinsic::x86_avx2_psllv_d:
6272 case Intrinsic::x86_avx2_psllv_d_256:
6273 case Intrinsic::x86_avx512_psllv_d_512:
6274 case Intrinsic::x86_avx2_psllv_q:
6275 case Intrinsic::x86_avx2_psllv_q_256:
6276 case Intrinsic::x86_avx512_psllv_q_512:
6277 case Intrinsic::x86_avx2_psrlv_d:
6278 case Intrinsic::x86_avx2_psrlv_d_256:
6279 case Intrinsic::x86_avx512_psrlv_d_512:
6280 case Intrinsic::x86_avx2_psrlv_q:
6281 case Intrinsic::x86_avx2_psrlv_q_256:
6282 case Intrinsic::x86_avx512_psrlv_q_512:
6283 case Intrinsic::x86_avx2_psrav_d:
6284 case Intrinsic::x86_avx2_psrav_d_256:
6285 case Intrinsic::x86_avx512_psrav_d_512:
6286 case Intrinsic::x86_avx512_psrav_q_128:
6287 case Intrinsic::x86_avx512_psrav_q_256:
6288 case Intrinsic::x86_avx512_psrav_q_512:
6289 handleVectorShiftIntrinsic(
I,
true);
6293 case Intrinsic::x86_sse2_packsswb_128:
6294 case Intrinsic::x86_sse2_packssdw_128:
6295 case Intrinsic::x86_sse2_packuswb_128:
6296 case Intrinsic::x86_sse41_packusdw:
6297 case Intrinsic::x86_avx2_packsswb:
6298 case Intrinsic::x86_avx2_packssdw:
6299 case Intrinsic::x86_avx2_packuswb:
6300 case Intrinsic::x86_avx2_packusdw:
6306 case Intrinsic::x86_avx512_packsswb_512:
6307 case Intrinsic::x86_avx512_packssdw_512:
6308 case Intrinsic::x86_avx512_packuswb_512:
6309 case Intrinsic::x86_avx512_packusdw_512:
6310 handleVectorPackIntrinsic(
I);
6313 case Intrinsic::x86_sse41_pblendvb:
6314 case Intrinsic::x86_sse41_blendvpd:
6315 case Intrinsic::x86_sse41_blendvps:
6316 case Intrinsic::x86_avx_blendv_pd_256:
6317 case Intrinsic::x86_avx_blendv_ps_256:
6318 case Intrinsic::x86_avx2_pblendvb:
6319 handleBlendvIntrinsic(
I);
6322 case Intrinsic::x86_avx_dp_ps_256:
6323 case Intrinsic::x86_sse41_dppd:
6324 case Intrinsic::x86_sse41_dpps:
6325 handleDppIntrinsic(
I);
6328 case Intrinsic::x86_mmx_packsswb:
6329 case Intrinsic::x86_mmx_packuswb:
6330 handleVectorPackIntrinsic(
I, 16);
6333 case Intrinsic::x86_mmx_packssdw:
6334 handleVectorPackIntrinsic(
I, 32);
6337 case Intrinsic::x86_mmx_psad_bw:
6338 handleVectorSadIntrinsic(
I,
true);
6340 case Intrinsic::x86_sse2_psad_bw:
6341 case Intrinsic::x86_avx2_psad_bw:
6342 handleVectorSadIntrinsic(
I);
6368 case Intrinsic::x86_sse2_pmadd_wd:
6369 case Intrinsic::x86_avx2_pmadd_wd:
6370 case Intrinsic::x86_avx512_pmaddw_d_512:
6371 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6372 case Intrinsic::x86_avx2_pmadd_ub_sw:
6373 case Intrinsic::x86_avx512_pmaddubs_w_512:
6374 handleVectorDotProductIntrinsic(
I, 2,
6381 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6382 handleVectorDotProductIntrinsic(
I, 2,
6389 case Intrinsic::x86_mmx_pmadd_wd:
6390 handleVectorDotProductIntrinsic(
I, 2,
6399 case Intrinsic::aarch64_neon_bfmlalt:
6400 handleVectorDotProductIntrinsic(
I, 2,
6408 case Intrinsic::aarch64_neon_bfmlalb:
6409 handleVectorDotProductIntrinsic(
I, 2,
6507 case Intrinsic::x86_avx512_vpdpbusd_128:
6508 case Intrinsic::x86_avx512_vpdpbusd_256:
6509 case Intrinsic::x86_avx512_vpdpbusd_512:
6510 case Intrinsic::x86_avx512_vpdpbusds_128:
6511 case Intrinsic::x86_avx512_vpdpbusds_256:
6512 case Intrinsic::x86_avx512_vpdpbusds_512:
6513 case Intrinsic::x86_avx2_vpdpbssd_128:
6514 case Intrinsic::x86_avx2_vpdpbssd_256:
6515 case Intrinsic::x86_avx10_vpdpbssd_512:
6516 case Intrinsic::x86_avx2_vpdpbssds_128:
6517 case Intrinsic::x86_avx2_vpdpbssds_256:
6518 case Intrinsic::x86_avx10_vpdpbssds_512:
6519 case Intrinsic::x86_avx2_vpdpbsud_128:
6520 case Intrinsic::x86_avx2_vpdpbsud_256:
6521 case Intrinsic::x86_avx10_vpdpbsud_512:
6522 case Intrinsic::x86_avx2_vpdpbsuds_128:
6523 case Intrinsic::x86_avx2_vpdpbsuds_256:
6524 case Intrinsic::x86_avx10_vpdpbsuds_512:
6525 case Intrinsic::x86_avx2_vpdpbuud_128:
6526 case Intrinsic::x86_avx2_vpdpbuud_256:
6527 case Intrinsic::x86_avx10_vpdpbuud_512:
6528 case Intrinsic::x86_avx2_vpdpbuuds_128:
6529 case Intrinsic::x86_avx2_vpdpbuuds_256:
6530 case Intrinsic::x86_avx10_vpdpbuuds_512:
6531 handleVectorDotProductIntrinsic(
I, 4,
6629 case Intrinsic::x86_avx512_vpdpwssd_128:
6630 case Intrinsic::x86_avx512_vpdpwssd_256:
6631 case Intrinsic::x86_avx512_vpdpwssd_512:
6632 case Intrinsic::x86_avx512_vpdpwssds_128:
6633 case Intrinsic::x86_avx512_vpdpwssds_256:
6634 case Intrinsic::x86_avx512_vpdpwssds_512:
6635 case Intrinsic::x86_avx2_vpdpwsud_128:
6636 case Intrinsic::x86_avx2_vpdpwsud_256:
6637 case Intrinsic::x86_avx10_vpdpwsud_512:
6638 case Intrinsic::x86_avx2_vpdpwsuds_128:
6639 case Intrinsic::x86_avx2_vpdpwsuds_256:
6640 case Intrinsic::x86_avx10_vpdpwsuds_512:
6641 case Intrinsic::x86_avx2_vpdpwusd_128:
6642 case Intrinsic::x86_avx2_vpdpwusd_256:
6643 case Intrinsic::x86_avx10_vpdpwusd_512:
6644 case Intrinsic::x86_avx2_vpdpwusds_128:
6645 case Intrinsic::x86_avx2_vpdpwusds_256:
6646 case Intrinsic::x86_avx10_vpdpwusds_512:
6647 case Intrinsic::x86_avx2_vpdpwuud_128:
6648 case Intrinsic::x86_avx2_vpdpwuud_256:
6649 case Intrinsic::x86_avx10_vpdpwuud_512:
6650 case Intrinsic::x86_avx2_vpdpwuuds_128:
6651 case Intrinsic::x86_avx2_vpdpwuuds_256:
6652 case Intrinsic::x86_avx10_vpdpwuuds_512:
6653 handleVectorDotProductIntrinsic(
I, 2,
6667 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6668 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6669 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6670 handleVectorDotProductIntrinsic(
I, 2,
6676 case Intrinsic::x86_sse_cmp_ss:
6677 case Intrinsic::x86_sse2_cmp_sd:
6678 case Intrinsic::x86_sse_comieq_ss:
6679 case Intrinsic::x86_sse_comilt_ss:
6680 case Intrinsic::x86_sse_comile_ss:
6681 case Intrinsic::x86_sse_comigt_ss:
6682 case Intrinsic::x86_sse_comige_ss:
6683 case Intrinsic::x86_sse_comineq_ss:
6684 case Intrinsic::x86_sse_ucomieq_ss:
6685 case Intrinsic::x86_sse_ucomilt_ss:
6686 case Intrinsic::x86_sse_ucomile_ss:
6687 case Intrinsic::x86_sse_ucomigt_ss:
6688 case Intrinsic::x86_sse_ucomige_ss:
6689 case Intrinsic::x86_sse_ucomineq_ss:
6690 case Intrinsic::x86_sse2_comieq_sd:
6691 case Intrinsic::x86_sse2_comilt_sd:
6692 case Intrinsic::x86_sse2_comile_sd:
6693 case Intrinsic::x86_sse2_comigt_sd:
6694 case Intrinsic::x86_sse2_comige_sd:
6695 case Intrinsic::x86_sse2_comineq_sd:
6696 case Intrinsic::x86_sse2_ucomieq_sd:
6697 case Intrinsic::x86_sse2_ucomilt_sd:
6698 case Intrinsic::x86_sse2_ucomile_sd:
6699 case Intrinsic::x86_sse2_ucomigt_sd:
6700 case Intrinsic::x86_sse2_ucomige_sd:
6701 case Intrinsic::x86_sse2_ucomineq_sd:
6702 handleVectorCompareScalarIntrinsic(
I);
6705 case Intrinsic::x86_avx_cmp_pd_256:
6706 case Intrinsic::x86_avx_cmp_ps_256:
6707 case Intrinsic::x86_sse2_cmp_pd:
6708 case Intrinsic::x86_sse_cmp_ps:
6709 handleVectorComparePackedIntrinsic(
I,
true);
6712 case Intrinsic::x86_bmi_bextr_32:
6713 case Intrinsic::x86_bmi_bextr_64:
6714 case Intrinsic::x86_bmi_bzhi_32:
6715 case Intrinsic::x86_bmi_bzhi_64:
6716 handleGenericBitManipulation(
I);
6719 case Intrinsic::x86_pclmulqdq:
6720 case Intrinsic::x86_pclmulqdq_256:
6721 case Intrinsic::x86_pclmulqdq_512:
6722 handlePclmulIntrinsic(
I);
6725 case Intrinsic::x86_avx_round_pd_256:
6726 case Intrinsic::x86_avx_round_ps_256:
6727 case Intrinsic::x86_sse41_round_pd:
6728 case Intrinsic::x86_sse41_round_ps:
6729 handleRoundPdPsIntrinsic(
I);
6732 case Intrinsic::x86_sse41_round_sd:
6733 case Intrinsic::x86_sse41_round_ss:
6734 handleUnarySdSsIntrinsic(
I);
6737 case Intrinsic::x86_sse2_max_sd:
6738 case Intrinsic::x86_sse_max_ss:
6739 case Intrinsic::x86_sse2_min_sd:
6740 case Intrinsic::x86_sse_min_ss:
6741 handleBinarySdSsIntrinsic(
I);
6744 case Intrinsic::x86_avx_vtestc_pd:
6745 case Intrinsic::x86_avx_vtestc_pd_256:
6746 case Intrinsic::x86_avx_vtestc_ps:
6747 case Intrinsic::x86_avx_vtestc_ps_256:
6748 case Intrinsic::x86_avx_vtestnzc_pd:
6749 case Intrinsic::x86_avx_vtestnzc_pd_256:
6750 case Intrinsic::x86_avx_vtestnzc_ps:
6751 case Intrinsic::x86_avx_vtestnzc_ps_256:
6752 case Intrinsic::x86_avx_vtestz_pd:
6753 case Intrinsic::x86_avx_vtestz_pd_256:
6754 case Intrinsic::x86_avx_vtestz_ps:
6755 case Intrinsic::x86_avx_vtestz_ps_256:
6756 case Intrinsic::x86_avx_ptestc_256:
6757 case Intrinsic::x86_avx_ptestnzc_256:
6758 case Intrinsic::x86_avx_ptestz_256:
6759 case Intrinsic::x86_sse41_ptestc:
6760 case Intrinsic::x86_sse41_ptestnzc:
6761 case Intrinsic::x86_sse41_ptestz:
6762 handleVtestIntrinsic(
I);
6766 case Intrinsic::x86_ssse3_phadd_w:
6767 case Intrinsic::x86_ssse3_phadd_w_128:
6768 case Intrinsic::x86_ssse3_phsub_w:
6769 case Intrinsic::x86_ssse3_phsub_w_128:
6770 handlePairwiseShadowOrIntrinsic(
I, 1,
6774 case Intrinsic::x86_avx2_phadd_w:
6775 case Intrinsic::x86_avx2_phsub_w:
6776 handlePairwiseShadowOrIntrinsic(
I, 2,
6781 case Intrinsic::x86_ssse3_phadd_d:
6782 case Intrinsic::x86_ssse3_phadd_d_128:
6783 case Intrinsic::x86_ssse3_phsub_d:
6784 case Intrinsic::x86_ssse3_phsub_d_128:
6785 handlePairwiseShadowOrIntrinsic(
I, 1,
6789 case Intrinsic::x86_avx2_phadd_d:
6790 case Intrinsic::x86_avx2_phsub_d:
6791 handlePairwiseShadowOrIntrinsic(
I, 2,
6796 case Intrinsic::x86_ssse3_phadd_sw:
6797 case Intrinsic::x86_ssse3_phadd_sw_128:
6798 case Intrinsic::x86_ssse3_phsub_sw:
6799 case Intrinsic::x86_ssse3_phsub_sw_128:
6800 handlePairwiseShadowOrIntrinsic(
I, 1,
6804 case Intrinsic::x86_avx2_phadd_sw:
6805 case Intrinsic::x86_avx2_phsub_sw:
6806 handlePairwiseShadowOrIntrinsic(
I, 2,
6811 case Intrinsic::x86_sse3_hadd_ps:
6812 case Intrinsic::x86_sse3_hadd_pd:
6813 case Intrinsic::x86_sse3_hsub_ps:
6814 case Intrinsic::x86_sse3_hsub_pd:
6815 handlePairwiseShadowOrIntrinsic(
I, 1);
6818 case Intrinsic::x86_avx_hadd_pd_256:
6819 case Intrinsic::x86_avx_hadd_ps_256:
6820 case Intrinsic::x86_avx_hsub_pd_256:
6821 case Intrinsic::x86_avx_hsub_ps_256:
6822 handlePairwiseShadowOrIntrinsic(
I, 2);
6825 case Intrinsic::x86_avx_maskstore_ps:
6826 case Intrinsic::x86_avx_maskstore_pd:
6827 case Intrinsic::x86_avx_maskstore_ps_256:
6828 case Intrinsic::x86_avx_maskstore_pd_256:
6829 case Intrinsic::x86_avx2_maskstore_d:
6830 case Intrinsic::x86_avx2_maskstore_q:
6831 case Intrinsic::x86_avx2_maskstore_d_256:
6832 case Intrinsic::x86_avx2_maskstore_q_256: {
6833 handleAVXMaskedStore(
I);
6837 case Intrinsic::x86_avx_maskload_ps:
6838 case Intrinsic::x86_avx_maskload_pd:
6839 case Intrinsic::x86_avx_maskload_ps_256:
6840 case Intrinsic::x86_avx_maskload_pd_256:
6841 case Intrinsic::x86_avx2_maskload_d:
6842 case Intrinsic::x86_avx2_maskload_q:
6843 case Intrinsic::x86_avx2_maskload_d_256:
6844 case Intrinsic::x86_avx2_maskload_q_256: {
6845 handleAVXMaskedLoad(
I);
6850 case Intrinsic::x86_avx512fp16_add_ph_512:
6851 case Intrinsic::x86_avx512fp16_sub_ph_512:
6852 case Intrinsic::x86_avx512fp16_mul_ph_512:
6853 case Intrinsic::x86_avx512fp16_div_ph_512:
6854 case Intrinsic::x86_avx512fp16_max_ph_512:
6855 case Intrinsic::x86_avx512fp16_min_ph_512:
6856 case Intrinsic::x86_avx512_min_ps_512:
6857 case Intrinsic::x86_avx512_min_pd_512:
6858 case Intrinsic::x86_avx512_max_ps_512:
6859 case Intrinsic::x86_avx512_max_pd_512: {
6864 [[maybe_unused]]
bool Success =
6865 maybeHandleSimpleNomemIntrinsic(
I, 1);
6870 case Intrinsic::x86_avx_vpermilvar_pd:
6871 case Intrinsic::x86_avx_vpermilvar_pd_256:
6872 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6873 case Intrinsic::x86_avx_vpermilvar_ps:
6874 case Intrinsic::x86_avx_vpermilvar_ps_256:
6875 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6876 handleAVXVpermilvar(
I);
6880 case Intrinsic::x86_avx512_vpermi2var_d_128:
6881 case Intrinsic::x86_avx512_vpermi2var_d_256:
6882 case Intrinsic::x86_avx512_vpermi2var_d_512:
6883 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6884 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6885 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6886 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6887 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6888 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6889 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6890 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6891 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6892 case Intrinsic::x86_avx512_vpermi2var_q_128:
6893 case Intrinsic::x86_avx512_vpermi2var_q_256:
6894 case Intrinsic::x86_avx512_vpermi2var_q_512:
6895 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6896 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6897 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6898 handleAVXVpermi2var(
I);
6912 case Intrinsic::x86_avx2_pshuf_b:
6913 case Intrinsic::x86_sse_pshuf_w:
6914 case Intrinsic::x86_ssse3_pshuf_b_128:
6915 case Intrinsic::x86_ssse3_pshuf_b:
6916 case Intrinsic::x86_avx512_pshuf_b_512:
6917 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6924 case Intrinsic::x86_avx512_mask_pmov_dw_128:
6925 case Intrinsic::x86_avx512_mask_pmov_db_128:
6926 case Intrinsic::x86_avx512_mask_pmov_qb_128:
6927 case Intrinsic::x86_avx512_mask_pmov_qw_128:
6928 case Intrinsic::x86_avx512_mask_pmov_qd_128:
6929 case Intrinsic::x86_avx512_mask_pmov_wb_128:
6930 case Intrinsic::x86_avx512_mask_pmov_dw_256:
6931 case Intrinsic::x86_avx512_mask_pmov_db_256:
6932 case Intrinsic::x86_avx512_mask_pmov_qb_256:
6933 case Intrinsic::x86_avx512_mask_pmov_qw_256:
6934 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6935 case Intrinsic::x86_avx512_mask_pmov_db_512:
6936 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6937 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6940 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6949 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6950 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6951 handleIntrinsicByApplyingToShadow(
6952 I, Intrinsic::x86_avx512_mask_pmov_dw_512,
6957 case Intrinsic::x86_avx512_mask_pmovs_dw_256:
6958 case Intrinsic::x86_avx512_mask_pmovus_dw_256:
6959 handleIntrinsicByApplyingToShadow(
6960 I, Intrinsic::x86_avx512_mask_pmov_dw_256,
6964 case Intrinsic::x86_avx512_mask_pmovs_dw_128:
6965 case Intrinsic::x86_avx512_mask_pmovus_dw_128:
6966 handleIntrinsicByApplyingToShadow(
6967 I, Intrinsic::x86_avx512_mask_pmov_dw_128,
6971 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6972 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6973 handleIntrinsicByApplyingToShadow(
6974 I, Intrinsic::x86_avx512_mask_pmov_db_512,
6979 case Intrinsic::x86_avx512_mask_pmovs_db_256:
6980 case Intrinsic::x86_avx512_mask_pmovus_db_256:
6981 handleIntrinsicByApplyingToShadow(
6982 I, Intrinsic::x86_avx512_mask_pmov_db_256,
6986 case Intrinsic::x86_avx512_mask_pmovs_db_128:
6987 case Intrinsic::x86_avx512_mask_pmovus_db_128:
6988 handleIntrinsicByApplyingToShadow(
6989 I, Intrinsic::x86_avx512_mask_pmov_db_128,
6993 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
6994 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
6995 handleIntrinsicByApplyingToShadow(
6996 I, Intrinsic::x86_avx512_mask_pmov_qb_512,
7001 case Intrinsic::x86_avx512_mask_pmovs_qb_256:
7002 case Intrinsic::x86_avx512_mask_pmovus_qb_256:
7003 handleIntrinsicByApplyingToShadow(
7004 I, Intrinsic::x86_avx512_mask_pmov_qb_256,
7008 case Intrinsic::x86_avx512_mask_pmovs_qb_128:
7009 case Intrinsic::x86_avx512_mask_pmovus_qb_128:
7010 handleIntrinsicByApplyingToShadow(
7011 I, Intrinsic::x86_avx512_mask_pmov_qb_128,
7015 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
7016 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
7017 handleIntrinsicByApplyingToShadow(
7018 I, Intrinsic::x86_avx512_mask_pmov_qw_512,
7023 case Intrinsic::x86_avx512_mask_pmovs_qw_256:
7024 case Intrinsic::x86_avx512_mask_pmovus_qw_256:
7025 handleIntrinsicByApplyingToShadow(
7026 I, Intrinsic::x86_avx512_mask_pmov_qw_256,
7030 case Intrinsic::x86_avx512_mask_pmovs_qw_128:
7031 case Intrinsic::x86_avx512_mask_pmovus_qw_128:
7032 handleIntrinsicByApplyingToShadow(
7033 I, Intrinsic::x86_avx512_mask_pmov_qw_128,
7037 case Intrinsic::x86_avx512_mask_pmovs_qd_128:
7038 case Intrinsic::x86_avx512_mask_pmovus_qd_128:
7039 handleIntrinsicByApplyingToShadow(
7040 I, Intrinsic::x86_avx512_mask_pmov_qd_128,
7044 case Intrinsic::x86_avx512_mask_pmovs_wb_128:
7045 case Intrinsic::x86_avx512_mask_pmovus_wb_128:
7046 handleIntrinsicByApplyingToShadow(
7047 I, Intrinsic::x86_avx512_mask_pmov_wb_128,
7051 case Intrinsic::x86_avx512_mask_pmovs_qd_256:
7052 case Intrinsic::x86_avx512_mask_pmovus_qd_256:
7053 case Intrinsic::x86_avx512_mask_pmovs_wb_256:
7054 case Intrinsic::x86_avx512_mask_pmovus_wb_256:
7055 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
7056 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
7057 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
7058 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
7062 handleAVX512VectorDownConvert(
I);
7073 case Intrinsic::x86_avx512_mask_compress:
7074 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7115 case Intrinsic::x86_avx512_rsqrt14_ps_512:
7116 case Intrinsic::x86_avx512_rsqrt14_ps_256:
7117 case Intrinsic::x86_avx512_rsqrt14_ps_128:
7118 case Intrinsic::x86_avx512_rsqrt14_pd_512:
7119 case Intrinsic::x86_avx512_rsqrt14_pd_256:
7120 case Intrinsic::x86_avx512_rsqrt14_pd_128:
7121 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
7122 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
7123 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
7124 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
7125 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
7126 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
7127 handleAVX512VectorGenericMaskedFP(
I, {0},
7168 case Intrinsic::x86_avx512_rcp14_ps_512:
7169 case Intrinsic::x86_avx512_rcp14_ps_256:
7170 case Intrinsic::x86_avx512_rcp14_ps_128:
7171 case Intrinsic::x86_avx512_rcp14_pd_512:
7172 case Intrinsic::x86_avx512_rcp14_pd_256:
7173 case Intrinsic::x86_avx512_rcp14_pd_128:
7174 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
7175 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
7176 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
7177 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
7178 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
7179 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
7180 handleAVX512VectorGenericMaskedFP(
I, {0},
7225 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
7226 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
7227 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
7228 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
7229 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
7230 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
7231 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
7232 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
7233 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
7234 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
7235 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
7236 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
7237 handleAVX512VectorGenericMaskedFP(
I, {0},
7273 case Intrinsic::x86_avx512_mask_scalef_pd_512:
7274 case Intrinsic::x86_avx512_mask_scalef_pd_256:
7275 case Intrinsic::x86_avx512_mask_scalef_pd_128:
7276 case Intrinsic::x86_avx512_mask_scalef_ps_512:
7277 case Intrinsic::x86_avx512_mask_scalef_ps_256:
7278 case Intrinsic::x86_avx512_mask_scalef_ps_128:
7279 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
7280 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
7281 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
7285 handleAVX512VectorGenericMaskedFP(
I, {0, 1},
7305 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
7306 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
7307 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
7308 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
7309 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
7310 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
7311 visitGenericScalarHalfwordInst(
I);
7318 case Intrinsic::x86_avx512_fpclass_pd_512:
7319 case Intrinsic::x86_avx512_fpclass_ps_512:
7320 handleAVX512FPClass(
I);
7324 case Intrinsic::x86_vgf2p8affineqb_128:
7325 case Intrinsic::x86_vgf2p8affineqb_256:
7326 case Intrinsic::x86_vgf2p8affineqb_512:
7327 handleAVXGF2P8Affine(
I);
7337 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &
I) {
7338 switch (
I.getIntrinsicID()) {
7342 case Intrinsic::aarch64_neon_rshrn:
7343 case Intrinsic::aarch64_neon_sqrshl:
7344 case Intrinsic::aarch64_neon_sqrshrn:
7345 case Intrinsic::aarch64_neon_sqrshrun:
7346 case Intrinsic::aarch64_neon_sqshl:
7347 case Intrinsic::aarch64_neon_sqshlu:
7348 case Intrinsic::aarch64_neon_sqshrn:
7349 case Intrinsic::aarch64_neon_sqshrun:
7350 case Intrinsic::aarch64_neon_srshl:
7351 case Intrinsic::aarch64_neon_sshl:
7352 case Intrinsic::aarch64_neon_uqrshl:
7353 case Intrinsic::aarch64_neon_uqrshrn:
7354 case Intrinsic::aarch64_neon_uqshl:
7355 case Intrinsic::aarch64_neon_uqshrn:
7356 case Intrinsic::aarch64_neon_urshl:
7357 case Intrinsic::aarch64_neon_ushl:
7358 handleVectorShiftIntrinsic(
I,
false);
7371 case Intrinsic::aarch64_neon_vsli:
7372 case Intrinsic::aarch64_neon_vsri:
7373 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7380 case Intrinsic::aarch64_neon_fmaxp:
7381 case Intrinsic::aarch64_neon_fminp:
7383 case Intrinsic::aarch64_neon_fmaxnmp:
7384 case Intrinsic::aarch64_neon_fminnmp:
7386 case Intrinsic::aarch64_neon_smaxp:
7387 case Intrinsic::aarch64_neon_sminp:
7388 case Intrinsic::aarch64_neon_umaxp:
7389 case Intrinsic::aarch64_neon_uminp:
7391 case Intrinsic::aarch64_neon_addp:
7393 case Intrinsic::aarch64_neon_faddp:
7395 case Intrinsic::aarch64_neon_saddlp:
7396 case Intrinsic::aarch64_neon_uaddlp: {
7397 handlePairwiseShadowOrIntrinsic(
I, 1);
7402 case Intrinsic::aarch64_neon_fcvtas:
7403 case Intrinsic::aarch64_neon_fcvtau:
7405 case Intrinsic::aarch64_neon_fcvtms:
7406 case Intrinsic::aarch64_neon_fcvtmu:
7408 case Intrinsic::aarch64_neon_fcvtns:
7409 case Intrinsic::aarch64_neon_fcvtnu:
7411 case Intrinsic::aarch64_neon_fcvtps:
7412 case Intrinsic::aarch64_neon_fcvtpu:
7414 case Intrinsic::aarch64_neon_fcvtzs:
7415 case Intrinsic::aarch64_neon_fcvtzu:
7417 case Intrinsic::aarch64_neon_fcvtxn:
7418 handleGenericVectorConvertIntrinsic(
I,
false);
7422 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7423 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7424 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7425 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7426 handleGenericVectorConvertIntrinsic(
I,
true);
7435 case Intrinsic::aarch64_neon_faddv:
7436 case Intrinsic::aarch64_neon_saddv:
7437 case Intrinsic::aarch64_neon_uaddv:
7440 case Intrinsic::aarch64_neon_smaxv:
7441 case Intrinsic::aarch64_neon_sminv:
7442 case Intrinsic::aarch64_neon_umaxv:
7443 case Intrinsic::aarch64_neon_uminv:
7447 case Intrinsic::aarch64_neon_fmaxv:
7448 case Intrinsic::aarch64_neon_fminv:
7449 case Intrinsic::aarch64_neon_fmaxnmv:
7450 case Intrinsic::aarch64_neon_fminnmv:
7452 case Intrinsic::aarch64_neon_saddlv:
7453 case Intrinsic::aarch64_neon_uaddlv:
7454 handleVectorReduceIntrinsic(
I,
true);
7457 case Intrinsic::aarch64_neon_ld1x2:
7458 case Intrinsic::aarch64_neon_ld1x3:
7459 case Intrinsic::aarch64_neon_ld1x4:
7460 case Intrinsic::aarch64_neon_ld2:
7461 case Intrinsic::aarch64_neon_ld3:
7462 case Intrinsic::aarch64_neon_ld4:
7463 case Intrinsic::aarch64_neon_ld2r:
7464 case Intrinsic::aarch64_neon_ld3r:
7465 case Intrinsic::aarch64_neon_ld4r: {
7466 handleNEONVectorLoad(
I,
false);
7470 case Intrinsic::aarch64_neon_ld2lane:
7471 case Intrinsic::aarch64_neon_ld3lane:
7472 case Intrinsic::aarch64_neon_ld4lane: {
7473 handleNEONVectorLoad(
I,
true);
7478 case Intrinsic::aarch64_neon_sqxtn:
7479 case Intrinsic::aarch64_neon_sqxtun:
7480 case Intrinsic::aarch64_neon_uqxtn:
7487 case Intrinsic::aarch64_neon_st1x2:
7488 case Intrinsic::aarch64_neon_st1x3:
7489 case Intrinsic::aarch64_neon_st1x4:
7490 case Intrinsic::aarch64_neon_st2:
7491 case Intrinsic::aarch64_neon_st3:
7492 case Intrinsic::aarch64_neon_st4: {
7493 handleNEONVectorStoreIntrinsic(
I,
false);
7497 case Intrinsic::aarch64_neon_st2lane:
7498 case Intrinsic::aarch64_neon_st3lane:
7499 case Intrinsic::aarch64_neon_st4lane: {
7500 handleNEONVectorStoreIntrinsic(
I,
true);
7513 case Intrinsic::aarch64_neon_tbl1:
7514 case Intrinsic::aarch64_neon_tbl2:
7515 case Intrinsic::aarch64_neon_tbl3:
7516 case Intrinsic::aarch64_neon_tbl4:
7517 case Intrinsic::aarch64_neon_tbx1:
7518 case Intrinsic::aarch64_neon_tbx2:
7519 case Intrinsic::aarch64_neon_tbx3:
7520 case Intrinsic::aarch64_neon_tbx4: {
7522 handleIntrinsicByApplyingToShadow(
7523 I,
I.getIntrinsicID(),
7528 case Intrinsic::aarch64_neon_fmulx:
7529 case Intrinsic::aarch64_neon_pmul:
7530 case Intrinsic::aarch64_neon_pmull:
7531 case Intrinsic::aarch64_neon_smull:
7532 case Intrinsic::aarch64_neon_pmull64:
7533 case Intrinsic::aarch64_neon_umull: {
7534 handleNEONVectorMultiplyIntrinsic(
I);
7538 case Intrinsic::aarch64_neon_smmla:
7539 case Intrinsic::aarch64_neon_ummla:
7540 case Intrinsic::aarch64_neon_usmmla:
7541 case Intrinsic::aarch64_neon_bfmmla:
7542 handleNEONMatrixMultiply(
I);
7549 case Intrinsic::aarch64_neon_sdot:
7550 case Intrinsic::aarch64_neon_udot:
7551 case Intrinsic::aarch64_neon_usdot:
7552 handleVectorDotProductIntrinsic(
I, 4,
7562 case Intrinsic::aarch64_neon_bfdot:
7563 handleVectorDotProductIntrinsic(
I, 2,
7576 case Intrinsic::aarch64_neon_fp8_fdot2:
7577 handleVectorDotProductIntrinsic(
I, 2,
7590 case Intrinsic::aarch64_neon_fp8_fdot4:
7591 handleVectorDotProductIntrinsic(
I, 4,
7601 case Intrinsic::aarch64_neon_fp8_fdot2_lane:
7602 handleNEONDotProductLaneIntrinsic(
I, 2);
7609 case Intrinsic::aarch64_neon_fp8_fdot4_lane:
7610 handleNEONDotProductLaneIntrinsic(
I, 4);
7614 case Intrinsic::aarch64_neon_facge:
7615 case Intrinsic::aarch64_neon_facgt:
7616 handleVectorComparePackedIntrinsic(
I,
false);
7626 void visitIntrinsicInst(IntrinsicInst &
I) {
7627 if (maybeHandleCrossPlatformIntrinsic(
I))
7630 if (maybeHandleX86SIMDIntrinsic(
I))
7633 if (maybeHandleArmSIMDIntrinsic(
I))
7636 if (maybeHandleUnknownIntrinsic(
I))
7639 visitInstruction(
I);
7642 void visitLibAtomicLoad(CallBase &CB) {
7653 Value *NewOrdering =
7657 NextNodeIRBuilder NextIRB(&CB);
7658 Value *SrcShadowPtr, *SrcOriginPtr;
7659 std::tie(SrcShadowPtr, SrcOriginPtr) =
7660 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7662 Value *DstShadowPtr =
7663 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7667 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
7668 if (MS.TrackOrigins) {
7669 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7671 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7672 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7676 void visitLibAtomicStore(CallBase &CB) {
7683 Value *NewOrdering =
7687 Value *DstShadowPtr =
7697 void visitCallBase(CallBase &CB) {
7704 if (Opts.msan_handle_asm_conservative)
7705 visitAsmInstruction(CB);
7707 visitInstruction(CB);
7711 if (LF != NotLibFunc) {
7716 case LibFunc_atomic_load:
7718 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
7722 visitLibAtomicLoad(CB);
7724 case LibFunc_atomic_store:
7725 visitLibAtomicStore(CB);
7741 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7745 Func->removeFnAttrs(
B);
7751 bool MayCheckCall = MS.EagerChecks;
7755 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
7758 unsigned ArgOffset = 0;
7761 if (!
A->getType()->isSized()) {
7762 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
7766 if (
A->getType()->isScalableTy()) {
7767 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
7769 insertCheckShadowOf(
A, &CB);
7774 const DataLayout &
DL =
F.getDataLayout();
7778 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7781 insertCheckShadowOf(
A, &CB);
7782 Size =
DL.getTypeAllocSize(
A->getType());
7788 Value *ArgShadow = getShadow(
A);
7789 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7791 <<
" Shadow: " << *ArgShadow <<
"\n");
7795 assert(
A->getType()->isPointerTy() &&
7796 "ByVal argument is not a pointer!");
7804 Value *AShadowPtr, *AOriginPtr;
7805 std::tie(AShadowPtr, AOriginPtr) =
7806 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
7808 if (!PropagateShadow) {
7815 if (MS.TrackOrigins) {
7816 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7830 Size =
DL.getTypeAllocSize(
A->getType());
7836 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
7838 getOriginPtrForArgument(IRB, ArgOffset));
7850 if (FT->isVarArg()) {
7851 VAHelper->visitCallBase(CB, IRB);
7861 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
7862 setShadow(&CB, getCleanShadow(&CB));
7863 setOrigin(&CB, getCleanOrigin());
7869 Value *
Base = getShadowPtrForRetval(IRBBefore);
7870 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
7882 setShadow(&CB, getCleanShadow(&CB));
7883 setOrigin(&CB, getCleanOrigin());
7890 "Could not find insertion point for retval shadow load");
7893 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7896 setShadow(&CB, RetvalShadow);
7897 if (MS.TrackOrigins)
7898 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7903 RetVal =
I->getOperand(0);
7906 return I->isMustTailCall();
7911 void visitReturnInst(ReturnInst &
I) {
7913 Value *RetVal =
I.getReturnValue();
7919 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7920 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
7921 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7924 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
7926 Value *Shadow = getShadow(RetVal);
7927 bool StoreOrigin =
true;
7929 insertCheckShadowOf(RetVal, &
I);
7930 Shadow = getCleanShadow(RetVal);
7931 StoreOrigin =
false;
7938 if (MS.TrackOrigins && StoreOrigin)
7939 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7943 void visitPHINode(PHINode &
I) {
7945 if (!PropagateShadow) {
7946 setShadow(&
I, getCleanShadow(&
I));
7947 setOrigin(&
I, getCleanOrigin());
7951 ShadowPHINodes.push_back(&
I);
7952 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
7954 if (MS.TrackOrigins)
7956 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
7959 Value *getLocalVarIdptr(AllocaInst &
I) {
7960 ConstantInt *IntConst =
7961 ConstantInt::get(Type::getInt32Ty((*
F.getParent()).getContext()), 0);
7962 return new GlobalVariable(*
F.getParent(), IntConst->
getType(),
7967 Value *getLocalVarDescription(AllocaInst &
I) {
7972 if (PoisonStack && Opts.msan_poison_stack_with_call) {
7973 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7975 Value *ShadowBase, *OriginBase;
7976 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7979 Value *PoisonValue =
7980 IRB.
getInt8(PoisonStack ? Opts.msan_poison_stack_pattern : 0);
7981 IRB.
CreateMemSet(ShadowBase, PoisonValue, Len,
I.getAlign());
7984 if (PoisonStack && MS.TrackOrigins) {
7985 Value *Idptr = getLocalVarIdptr(
I);
7986 if (Opts.msan_print_stack_names) {
7987 Value *Descr = getLocalVarDescription(
I);
7988 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
7989 {&I, Len, Idptr, Descr});
7991 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
7997 Value *Descr = getLocalVarDescription(
I);
7999 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
8001 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
8005 void instrumentAlloca(AllocaInst &
I, Instruction *InsPoint =
nullptr) {
8008 NextNodeIRBuilder IRB(InsPoint);
8011 if (MS.CompileKernel)
8012 poisonAllocaKmsan(
I, IRB, Len);
8014 poisonAllocaUserspace(
I, IRB, Len);
8017 void visitAllocaInst(AllocaInst &
I) {
8018 setShadow(&
I, getCleanShadow(&
I));
8019 setOrigin(&
I, getCleanOrigin());
8025 void visitSelectInst(SelectInst &
I) {
8031 handleSelectLikeInst(
I,
B,
C,
D);
8037 Value *Sb = getShadow(
B);
8038 Value *Sc = getShadow(
C);
8039 Value *Sd = getShadow(
D);
8041 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
8042 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
8043 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
8048 if (
I.getType()->isAggregateType()) {
8052 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
8053 }
else if (isScalableNonVectorType(
I.getType())) {
8061 Sa1 = getCleanShadow(getShadowTy(
I.getType()));
8069 C = CreateAppToShadowCast(IRB,
C);
8070 D = CreateAppToShadowCast(IRB,
D);
8077 if (MS.TrackOrigins) {
8080 if (
B->getType()->isVectorTy()) {
8081 B = convertToBool(
B, IRB);
8082 Sb = convertToBool(Sb, IRB);
8090 void visitLandingPadInst(LandingPadInst &
I) {
8093 setShadow(&
I, getCleanShadow(&
I));
8094 setOrigin(&
I, getCleanOrigin());
8097 void visitCatchSwitchInst(CatchSwitchInst &
I) {
8098 setShadow(&
I, getCleanShadow(&
I));
8099 setOrigin(&
I, getCleanOrigin());
8102 void visitFuncletPadInst(FuncletPadInst &
I) {
8103 setShadow(&
I, getCleanShadow(&
I));
8104 setOrigin(&
I, getCleanOrigin());
8107 void visitGetElementPtrInst(GetElementPtrInst &
I) { handleShadowOr(
I); }
8109 void visitExtractValueInst(ExtractValueInst &
I) {
8111 Value *Agg =
I.getAggregateOperand();
8113 Value *AggShadow = getShadow(Agg);
8117 setShadow(&
I, ResShadow);
8118 setOriginForNaryOp(
I);
8121 void visitInsertValueInst(InsertValueInst &
I) {
8124 Value *AggShadow = getShadow(
I.getAggregateOperand());
8125 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
8131 setOriginForNaryOp(
I);
8134 void dumpInst(Instruction &
I,
const Twine &Prefix) {
8141 << CI->getCalledFunction()->
getName() <<
"\n";
8143 errs() <<
"ZZZ:" <<
Prefix <<
" " <<
I.getOpcodeName() <<
"\n";
8150 unsigned NumOperands =
I.getNumOperands();
8152 errs() <<
"YYY:" <<
Prefix <<
" call " << *
I.getType() <<
" @";
8164 errs() <<
"YYY:" <<
Prefix <<
" " << *
I.getType() <<
" "
8165 <<
I.getOpcodeName() <<
"(";
8167 for (
size_t i = 0; i < NumOperands; i++) {
8185 void visitResumeInst(ResumeInst &
I) {
8190 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
8195 void visitCatchReturnInst(CatchReturnInst &CRI) {
8200 void instrumentAsmArgument(
Value *Operand,
Type *ElemTy, Instruction &
I,
8209 insertCheckShadowOf(Operand, &
I);
8216 auto Size =
DL.getTypeStoreSize(ElemTy);
8218 if (MS.CompileKernel) {
8219 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
8225 auto [ShadowPtr,
_] =
8226 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
8236 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
8237 int NumRetOutputs = 0;
8244 NumRetOutputs =
ST->getNumElements();
8249 for (
const InlineAsm::ConstraintInfo &Info : Constraints) {
8250 switch (
Info.Type) {
8258 return NumOutputs - NumRetOutputs;
8261 void visitAsmInstruction(Instruction &
I) {
8277 const DataLayout &
DL =
F.getDataLayout();
8281 int OutputArgs = getNumOutputArgs(IA, CB);
8287 for (
int i = OutputArgs; i < NumOperands; i++) {
8295 for (
int i = 0; i < OutputArgs; i++) {
8301 setShadow(&
I, getCleanShadow(&
I));
8302 setOrigin(&
I, getCleanOrigin());
8305 void visitFreezeInst(FreezeInst &
I) {
8307 setShadow(&
I, getCleanShadow(&
I));
8308 setOrigin(&
I, getCleanOrigin());
8311 void visitInstruction(Instruction &
I) {
8313 if (Opts.msan_dump_strict_instructions)
8314 dumpInst(
I,
"Strict");
8316 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
8317 Value *Operand =
I.getOperand(i);
8319 insertCheckShadowOf(Operand, &
I);
8321 setShadow(&
I, getCleanShadow(&
I));
8322 setOrigin(&
I, getCleanOrigin());
8326struct VarArgHelperBase :
public VarArgHelper {
8328 MemorySanitizer &MS;
8329 MemorySanitizerVisitor &MSV;
8331 const unsigned VAListTagSize;
8333 VarArgHelperBase(
Function &
F, MemorySanitizer &MS,
8334 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
8335 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
8339 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
8345 MS.VAArgTLS, ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg_va_s");
8354 return getShadowPtrForVAArgument(IRB, ArgOffset);
8363 ConstantInt::get(MS.IntptrTy, ArgOffset),
8368 unsigned BaseOffset) {
8377 TailSize,
Align(8));
8380 void unpoisonVAListTagForInst(IntrinsicInst &
I) {
8382 Value *VAListTag =
I.getArgOperand(0);
8384 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
8385 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
8388 VAListTagSize, Alignment,
false);
8391 void visitVAStartInst(VAStartInst &
I)
override {
8392 if (
F.getCallingConv() == CallingConv::Win64)
8395 unpoisonVAListTagForInst(
I);
8398 void visitVACopyInst(VACopyInst &
I)
override {
8399 if (
F.getCallingConv() == CallingConv::Win64)
8401 unpoisonVAListTagForInst(
I);
8406struct VarArgAMD64Helper :
public VarArgHelperBase {
8409 static const unsigned AMD64GpEndOffset = 48;
8410 static const unsigned AMD64FpEndOffsetSSE = 176;
8412 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8414 unsigned AMD64FpEndOffset;
8415 AllocaInst *VAArgTLSCopy =
nullptr;
8416 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8417 Value *VAArgOverflowSize =
nullptr;
8419 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8421 VarArgAMD64Helper(
Function &
F, MemorySanitizer &MS,
8422 MemorySanitizerVisitor &MSV)
8423 : VarArgHelperBase(
F, MS, MSV, 24) {
8424 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8425 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
8426 if (Attr.isStringAttribute() &&
8427 (Attr.getKindAsString() ==
"target-features")) {
8428 if (Attr.getValueAsString().contains(
"-sse"))
8429 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8435 ArgKind classifyArgument(
Value *arg) {
8438 if (
T->isX86_FP80Ty())
8440 if (
T->isFPOrFPVectorTy())
8441 return AK_FloatingPoint;
8442 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
8443 return AK_GeneralPurpose;
8444 if (
T->isPointerTy())
8445 return AK_GeneralPurpose;
8457 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8458 unsigned GpOffset = 0;
8459 unsigned FpOffset = AMD64GpEndOffset;
8460 unsigned OverflowOffset = AMD64FpEndOffset;
8461 const DataLayout &
DL =
F.getDataLayout();
8472 assert(
A->getType()->isPointerTy());
8474 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8476 unsigned BaseOffset = OverflowOffset;
8477 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8478 Value *OriginBase =
nullptr;
8479 if (MS.TrackOrigins)
8480 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8481 OverflowOffset += AlignedSize;
8484 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8488 Value *ShadowPtr, *OriginPtr;
8489 std::tie(ShadowPtr, OriginPtr) =
8494 if (MS.TrackOrigins)
8498 ArgKind AK = classifyArgument(
A);
8499 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8501 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8503 Value *ShadowBase, *OriginBase =
nullptr;
8505 case AK_GeneralPurpose:
8506 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8507 if (MS.TrackOrigins)
8508 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8512 case AK_FloatingPoint:
8513 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8514 if (MS.TrackOrigins)
8515 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8522 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8524 unsigned BaseOffset = OverflowOffset;
8525 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8526 if (MS.TrackOrigins) {
8527 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8529 OverflowOffset += AlignedSize;
8532 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8541 Value *Shadow = MSV.getShadow(
A);
8543 if (MS.TrackOrigins) {
8544 Value *Origin = MSV.getOrigin(
A);
8545 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8546 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8552 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8553 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8556 void finalizeInstrumentation()
override {
8557 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8558 "finalizeInstrumentation called twice");
8559 if (!VAStartInstrumentationList.
empty()) {
8566 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8567 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8573 Intrinsic::umin, CopySize,
8577 if (MS.TrackOrigins) {
8578 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8587 for (CallInst *OrigInst : VAStartInstrumentationList) {
8588 NextNodeIRBuilder IRB(OrigInst);
8589 Value *VAListTag = OrigInst->getArgOperand(0);
8591 Value *RegSaveAreaPtrPtr =
8592 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 16));
8594 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8596 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8597 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8599 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8601 if (MS.TrackOrigins)
8602 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8603 Alignment, AMD64FpEndOffset);
8604 Value *OverflowArgAreaPtrPtr =
8605 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 8));
8606 Value *OverflowArgAreaPtr =
8607 IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8608 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8609 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8610 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8614 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8616 if (MS.TrackOrigins) {
8619 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8627struct VarArgAArch64Helper :
public VarArgHelperBase {
8628 static const unsigned kAArch64GrArgSize = 64;
8629 static const unsigned kAArch64VrArgSize = 128;
8631 static const unsigned AArch64GrBegOffset = 0;
8632 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8634 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8635 static const unsigned AArch64VrEndOffset =
8636 AArch64VrBegOffset + kAArch64VrArgSize;
8637 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8639 AllocaInst *VAArgTLSCopy =
nullptr;
8640 Value *VAArgOverflowSize =
nullptr;
8642 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8644 VarArgAArch64Helper(
Function &
F, MemorySanitizer &MS,
8645 MemorySanitizerVisitor &MSV)
8646 : VarArgHelperBase(
F, MS, MSV, 32) {}
8649 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
8650 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
8651 return {AK_GeneralPurpose, 1};
8652 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
8653 return {AK_FloatingPoint, 1};
8655 if (
T->isArrayTy()) {
8656 auto R = classifyArgument(
T->getArrayElementType());
8657 R.second *=
T->getScalarType()->getArrayNumElements();
8662 auto R = classifyArgument(FV->getScalarType());
8663 R.second *= FV->getNumElements();
8668 return {AK_Memory, 0};
8680 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8681 unsigned GrOffset = AArch64GrBegOffset;
8682 unsigned VrOffset = AArch64VrBegOffset;
8683 unsigned OverflowOffset = AArch64VAEndOffset;
8685 const DataLayout &
DL =
F.getDataLayout();
8688 auto [AK, RegNum] = classifyArgument(
A->getType());
8689 if (AK == AK_GeneralPurpose &&
8690 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8692 if (AK == AK_FloatingPoint &&
8693 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8697 case AK_GeneralPurpose:
8698 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8699 GrOffset += 8 * RegNum;
8701 case AK_FloatingPoint:
8702 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8703 VrOffset += 16 * RegNum;
8710 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8712 unsigned BaseOffset = OverflowOffset;
8713 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8714 OverflowOffset += AlignedSize;
8717 CleanUnusedTLS(IRB,
Base, BaseOffset);
8729 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8730 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8735 Value *SaveAreaPtrPtr =
8736 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8737 return IRB.
CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8742 Value *SaveAreaPtr =
8743 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8745 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
8748 void finalizeInstrumentation()
override {
8749 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8750 "finalizeInstrumentation called twice");
8751 if (!VAStartInstrumentationList.empty()) {
8758 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8759 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8765 Intrinsic::umin, CopySize,
8771 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8772 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8776 for (CallInst *OrigInst : VAStartInstrumentationList) {
8777 NextNodeIRBuilder IRB(OrigInst);
8779 Value *VAListTag = OrigInst->getArgOperand(0);
8796 Value *StackSaveAreaPtr =
8797 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8800 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8801 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8804 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8807 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8808 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8811 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8817 Value *GrRegSaveAreaShadowPtrOff =
8818 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
8820 Value *GrRegSaveAreaShadowPtr =
8821 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8827 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8833 Value *VrRegSaveAreaShadowPtrOff =
8834 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
8836 Value *VrRegSaveAreaShadowPtr =
8837 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8844 VrRegSaveAreaShadowPtrOff);
8845 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8851 Value *StackSaveAreaShadowPtr =
8852 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8857 VAArgTLSCopy, IRB.
getInt32(AArch64VAEndOffset));
8860 Align(16), VAArgOverflowSize);
8866struct VarArgPowerPC64Helper :
public VarArgHelperBase {
8867 AllocaInst *VAArgTLSCopy =
nullptr;
8868 Value *VAArgSize =
nullptr;
8870 VarArgPowerPC64Helper(
Function &
F, MemorySanitizer &MS,
8871 MemorySanitizerVisitor &MSV)
8872 : VarArgHelperBase(
F, MS, MSV, 8) {}
8874 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8882 Triple TargetTriple(
F.getParent()->getTargetTriple());
8886 if (TargetTriple.isPPC64ELFv2ABI())
8890 unsigned VAArgOffset = VAArgBase;
8891 const DataLayout &
DL =
F.getDataLayout();
8896 assert(
A->getType()->isPointerTy());
8898 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8901 ArgAlign =
Align(8);
8902 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8905 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8907 Value *AShadowPtr, *AOriginPtr;
8908 std::tie(AShadowPtr, AOriginPtr) =
8909 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8919 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8921 if (
A->getType()->isArrayTy()) {
8924 Type *ElementTy =
A->getType()->getArrayElementType();
8926 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8927 }
else if (
A->getType()->isVectorTy()) {
8929 ArgAlign =
Align(ArgSize);
8932 ArgAlign =
Align(8);
8933 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8934 if (
DL.isBigEndian()) {
8938 VAArgOffset += (8 - ArgSize);
8942 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8946 VAArgOffset += ArgSize;
8950 VAArgBase = VAArgOffset;
8954 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8957 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8960 void finalizeInstrumentation()
override {
8961 assert(!VAArgSize && !VAArgTLSCopy &&
8962 "finalizeInstrumentation called twice");
8965 Value *CopySize = VAArgSize;
8967 if (!VAStartInstrumentationList.empty()) {
8971 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8977 Intrinsic::umin, CopySize,
8985 for (CallInst *OrigInst : VAStartInstrumentationList) {
8986 NextNodeIRBuilder IRB(OrigInst);
8987 Value *VAListTag = OrigInst->getArgOperand(0);
8990 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8993 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8994 const DataLayout &
DL =
F.getDataLayout();
8995 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8997 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8998 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9000 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9007struct VarArgPowerPC32Helper :
public VarArgHelperBase {
9008 AllocaInst *VAArgTLSCopy =
nullptr;
9009 Value *VAArgSize =
nullptr;
9011 VarArgPowerPC32Helper(
Function &
F, MemorySanitizer &MS,
9012 MemorySanitizerVisitor &MSV)
9013 : VarArgHelperBase(
F, MS, MSV, 12) {}
9015 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9019 unsigned VAArgOffset = VAArgBase;
9020 const DataLayout &
DL =
F.getDataLayout();
9021 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9026 assert(
A->getType()->isPointerTy());
9028 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9030 if (ArgAlign < IntptrSize)
9031 ArgAlign =
Align(IntptrSize);
9032 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9035 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
9037 Value *AShadowPtr, *AOriginPtr;
9038 std::tie(AShadowPtr, AOriginPtr) =
9039 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9049 Type *ArgTy =
A->getType();
9055 uint64_t ArgSize =
DL.getTypeAllocSize(ArgTy);
9062 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
9065 ArgAlign =
Align(ArgSize);
9067 if (ArgAlign < IntptrSize)
9068 ArgAlign =
Align(IntptrSize);
9069 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9070 if (
DL.isBigEndian()) {
9073 if (ArgSize < IntptrSize)
9074 VAArgOffset += (IntptrSize - ArgSize);
9077 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
9083 VAArgOffset += ArgSize;
9090 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
9093 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9096 void finalizeInstrumentation()
override {
9097 assert(!VAArgSize && !VAArgTLSCopy &&
9098 "finalizeInstrumentation called twice");
9100 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9101 Value *CopySize = VAArgSize;
9103 if (!VAStartInstrumentationList.empty()) {
9107 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9113 Intrinsic::umin, CopySize,
9121 for (CallInst *OrigInst : VAStartInstrumentationList) {
9122 NextNodeIRBuilder IRB(OrigInst);
9123 Value *VAListTag = OrigInst->getArgOperand(0);
9125 Value *RegSaveAreaSize = CopySize;
9129 IRB.
CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
9133 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
9135 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9138 const DataLayout &
DL =
F.getDataLayout();
9139 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9143 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9144 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9145 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9147 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
9148 Alignment, RegSaveAreaSize);
9150 RegSaveAreaShadowPtr =
9153 ConstantInt::get(MS.IntptrTy, 32));
9158 ConstantInt::get(MS.IntptrTy, 32), Alignment);
9163 Value *OverflowAreaSize = IRB.
CreateSub(CopySize, RegSaveAreaSize);
9166 OverflowAreaPtrPtr =
9167 IRB.
CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
9168 OverflowAreaPtrPtr = IRB.
CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
9170 Value *OverflowAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
9172 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
9173 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
9174 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.
getInt8Ty(),
9177 Value *OverflowVAArgTLSCopyPtr =
9179 OverflowVAArgTLSCopyPtr =
9180 IRB.
CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
9182 OverflowVAArgTLSCopyPtr =
9185 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
9192struct VarArgSystemZHelper :
public VarArgHelperBase {
9193 static const unsigned SystemZGpOffset = 16;
9194 static const unsigned SystemZGpEndOffset = 56;
9195 static const unsigned SystemZFpOffset = 128;
9196 static const unsigned SystemZFpEndOffset = 160;
9197 static const unsigned SystemZMaxVrArgs = 8;
9198 static const unsigned SystemZRegSaveAreaSize = 160;
9199 static const unsigned SystemZOverflowOffset = 160;
9200 static const unsigned SystemZVAListTagSize = 32;
9201 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
9202 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
9204 bool IsSoftFloatABI;
9205 AllocaInst *VAArgTLSCopy =
nullptr;
9206 AllocaInst *VAArgTLSOriginCopy =
nullptr;
9207 Value *VAArgOverflowSize =
nullptr;
9209 enum class ArgKind {
9217 enum class ShadowExtension {
None,
Zero, Sign };
9219 VarArgSystemZHelper(
Function &
F, MemorySanitizer &MS,
9220 MemorySanitizerVisitor &MSV)
9221 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
9222 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
9224 ArgKind classifyArgument(
Type *
T) {
9231 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
9232 return ArgKind::Indirect;
9233 if (
T->isFloatingPointTy())
9234 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
9235 if (
T->isIntegerTy() ||
T->isPointerTy())
9236 return ArgKind::GeneralPurpose;
9237 if (
T->isVectorTy())
9238 return ArgKind::Vector;
9239 return ArgKind::Memory;
9242 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
9252 return ShadowExtension::Zero;
9256 return ShadowExtension::Sign;
9258 return ShadowExtension::None;
9261 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9262 unsigned GpOffset = SystemZGpOffset;
9263 unsigned FpOffset = SystemZFpOffset;
9264 unsigned VrIndex = 0;
9265 unsigned OverflowOffset = SystemZOverflowOffset;
9266 const DataLayout &
DL =
F.getDataLayout();
9272 ArgKind AK = classifyArgument(
T);
9273 if (AK == ArgKind::Indirect) {
9275 AK = ArgKind::GeneralPurpose;
9277 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
9278 AK = ArgKind::Memory;
9279 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
9280 AK = ArgKind::Memory;
9281 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
9282 AK = ArgKind::Memory;
9283 Value *ShadowBase =
nullptr;
9284 Value *OriginBase =
nullptr;
9285 ShadowExtension SE = ShadowExtension::None;
9287 case ArgKind::GeneralPurpose: {
9292 SE = getShadowExtension(CB, ArgNo);
9294 if (SE == ShadowExtension::None) {
9296 assert(ArgAllocSize <= ArgSize);
9297 GapSize = ArgSize - ArgAllocSize;
9299 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
9300 if (MS.TrackOrigins)
9301 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
9303 GpOffset += ArgSize;
9309 case ArgKind::FloatingPoint: {
9318 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
9319 if (MS.TrackOrigins)
9320 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
9322 FpOffset += ArgSize;
9328 case ArgKind::Vector: {
9335 case ArgKind::Memory: {
9343 SE = getShadowExtension(CB, ArgNo);
9345 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
9347 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
9348 if (MS.TrackOrigins)
9350 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
9351 OverflowOffset += ArgSize;
9358 case ArgKind::Indirect:
9361 if (ShadowBase ==
nullptr)
9363 Value *Shadow = MSV.getShadow(
A);
9364 if (SE != ShadowExtension::None)
9365 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
9366 SE == ShadowExtension::Sign);
9367 ShadowBase = IRB.
CreateIntToPtr(ShadowBase, MS.PtrTy,
"_msarg_va_s");
9369 if (MS.TrackOrigins) {
9370 Value *Origin = MSV.getOrigin(
A);
9371 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
9372 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
9376 Constant *OverflowSize = ConstantInt::get(
9377 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
9378 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
9385 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
9388 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9390 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9391 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
9396 unsigned RegSaveAreaSize =
9397 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9398 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9400 if (MS.TrackOrigins)
9401 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9402 Alignment, RegSaveAreaSize);
9411 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9413 Value *OverflowArgAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9414 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9416 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9417 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
9420 SystemZOverflowOffset);
9421 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9423 if (MS.TrackOrigins) {
9425 SystemZOverflowOffset);
9426 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9431 void finalizeInstrumentation()
override {
9432 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9433 "finalizeInstrumentation called twice");
9434 if (!VAStartInstrumentationList.empty()) {
9441 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9443 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9449 Intrinsic::umin, CopySize,
9453 if (MS.TrackOrigins) {
9454 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9463 for (CallInst *OrigInst : VAStartInstrumentationList) {
9464 NextNodeIRBuilder IRB(OrigInst);
9465 Value *VAListTag = OrigInst->getArgOperand(0);
9466 copyRegSaveArea(IRB, VAListTag);
9467 copyOverflowArea(IRB, VAListTag);
9473struct VarArgI386Helper :
public VarArgHelperBase {
9474 AllocaInst *VAArgTLSCopy =
nullptr;
9475 Value *VAArgSize =
nullptr;
9477 VarArgI386Helper(
Function &
F, MemorySanitizer &MS,
9478 MemorySanitizerVisitor &MSV)
9479 : VarArgHelperBase(
F, MS, MSV, 4) {}
9481 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9482 const DataLayout &
DL =
F.getDataLayout();
9483 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9484 unsigned VAArgOffset = 0;
9489 assert(
A->getType()->isPointerTy());
9491 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9493 if (ArgAlign < IntptrSize)
9494 ArgAlign =
Align(IntptrSize);
9495 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9497 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9499 Value *AShadowPtr, *AOriginPtr;
9500 std::tie(AShadowPtr, AOriginPtr) =
9501 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9511 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9513 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9514 if (
DL.isBigEndian()) {
9517 if (ArgSize < IntptrSize)
9518 VAArgOffset += (IntptrSize - ArgSize);
9521 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9524 VAArgOffset += ArgSize;
9530 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9533 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9536 void finalizeInstrumentation()
override {
9537 assert(!VAArgSize && !VAArgTLSCopy &&
9538 "finalizeInstrumentation called twice");
9540 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9541 Value *CopySize = VAArgSize;
9543 if (!VAStartInstrumentationList.empty()) {
9546 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9552 Intrinsic::umin, CopySize,
9560 for (CallInst *OrigInst : VAStartInstrumentationList) {
9561 NextNodeIRBuilder IRB(OrigInst);
9562 Value *VAListTag = OrigInst->getArgOperand(0);
9563 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9564 Value *RegSaveAreaPtrPtr =
9566 PointerType::get(*MS.C, 0));
9567 Value *RegSaveAreaPtr =
9568 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9569 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9570 const DataLayout &
DL =
F.getDataLayout();
9571 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9573 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9574 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9576 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9584struct VarArgGenericHelper :
public VarArgHelperBase {
9585 AllocaInst *VAArgTLSCopy =
nullptr;
9586 Value *VAArgSize =
nullptr;
9588 VarArgGenericHelper(
Function &
F, MemorySanitizer &MS,
9589 MemorySanitizerVisitor &MSV,
const unsigned VAListTagSize)
9590 : VarArgHelperBase(
F, MS, MSV, VAListTagSize) {}
9592 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9593 unsigned VAArgOffset = 0;
9594 const DataLayout &
DL =
F.getDataLayout();
9595 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9600 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9601 if (
DL.isBigEndian()) {
9604 if (ArgSize < IntptrSize)
9605 VAArgOffset += (IntptrSize - ArgSize);
9607 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9608 VAArgOffset += ArgSize;
9609 VAArgOffset =
alignTo(VAArgOffset, IntptrSize);
9615 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9618 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9621 void finalizeInstrumentation()
override {
9622 assert(!VAArgSize && !VAArgTLSCopy &&
9623 "finalizeInstrumentation called twice");
9625 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9626 Value *CopySize = VAArgSize;
9628 if (!VAStartInstrumentationList.empty()) {
9631 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9637 Intrinsic::umin, CopySize,
9645 for (CallInst *OrigInst : VAStartInstrumentationList) {
9646 NextNodeIRBuilder IRB(OrigInst);
9647 Value *VAListTag = OrigInst->getArgOperand(0);
9648 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9649 Value *RegSaveAreaPtrPtr =
9651 PointerType::get(*MS.C, 0));
9652 Value *RegSaveAreaPtr =
9653 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9654 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9655 const DataLayout &
DL =
F.getDataLayout();
9656 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9658 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9659 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9661 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9669using VarArgARM32Helper = VarArgGenericHelper;
9670using VarArgRISCVHelper = VarArgGenericHelper;
9671using VarArgMIPSHelper = VarArgGenericHelper;
9672using VarArgLoongArch64Helper = VarArgGenericHelper;
9673using VarArgHexagonHelper = VarArgGenericHelper;
9676struct VarArgNoOpHelper :
public VarArgHelper {
9677 VarArgNoOpHelper(
Function &
F, MemorySanitizer &MS,
9678 MemorySanitizerVisitor &MSV) {}
9680 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {}
9682 void visitVAStartInst(VAStartInst &
I)
override {}
9684 void visitVACopyInst(VACopyInst &
I)
override {}
9686 void finalizeInstrumentation()
override {}
9692 MemorySanitizerVisitor &Visitor) {
9695 Triple TargetTriple(Func.getParent()->getTargetTriple());
9698 return new VarArgI386Helper(Func, Msan, Visitor);
9701 return new VarArgAMD64Helper(Func, Msan, Visitor);
9703 if (TargetTriple.
isARM())
9704 return new VarArgARM32Helper(Func, Msan, Visitor, 4);
9707 return new VarArgAArch64Helper(Func, Msan, Visitor);
9710 return new VarArgSystemZHelper(Func, Msan, Visitor);
9715 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9718 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9721 return new VarArgRISCVHelper(Func, Msan, Visitor, 4);
9724 return new VarArgRISCVHelper(Func, Msan, Visitor, 8);
9727 return new VarArgMIPSHelper(Func, Msan, Visitor, 4);
9730 return new VarArgMIPSHelper(Func, Msan, Visitor, 8);
9733 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9737 return new VarArgHexagonHelper(Func, Msan, Visitor, 12);
9739 return new VarArgNoOpHelper(Func, Msan, Visitor);
9746 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9749 MemorySanitizerVisitor Visitor(
F, *
this, TLI);
9756 return Visitor.runOnFunction();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isStore(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static const size_t kNumberOfAccessSizes
VarLocInsertPt getNextNode(const DbgRecord *DVR)
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool insertModuleCtor(Module &M)
const MemoryMapParams Linux_LoongArch64_MemoryMapParams
const MemoryMapParams Linux_X86_64_MemoryMapParams
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_S390X_MemoryMapParams
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_AArch64_MemoryMapParams
static bool isAMustTailRetVal(Value *RetVal)
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
Module.h This file contains the declarations for the Module class.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
static const PlatformMemoryMapParams Linux_S390_MemoryMapParams
static const Align kMinOriginAlignment
static const PlatformMemoryMapParams Linux_X86_MemoryMapParams
static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
static MemorySanitizerOptions resolveOptions(const InstrumentationOptions &Opts, MemorySanitizerOptions O)
static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static const unsigned kOriginSize
static const Align kShadowTLSAlignment
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P
static const MemoryMapParams Linux_I386_MemoryMapParams
const char kMsanInitName[]
static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams
static GlobalVariable * createPrivateConstGlobalForString(Module &M, StringRef Str)
Create a non-const global initialized with the given string.
static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams
static const size_t kNumberOfAccessSizes
static VarArgHelper * CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, MemorySanitizerVisitor &Visitor)
static const MemoryMapParams Linux_MIPS64_MemoryMapParams
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
static const MemoryMapParams Linux_Hexagon_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams
static const unsigned kParamTLSSize
static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
static const unsigned kRetvalTLSSize
static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams
const char kMsanModuleCtorName[]
static const MemoryMapParams FreeBSD_I386_MemoryMapParams
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
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)
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
void setAlignment(Align Align)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
const T & front() const
Get the first element.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
void removeFnAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the function.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Value * getCalledOperand() const
Type * getParamElementType(unsigned ArgNo) const
Extract the elementtype type for a parameter.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_SGT
signed greater than
@ ICMP_SGE
signed greater or equal
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true, bool ByteString=false)
This method constructs a CDS and initializes it with a text string.
static LLVM_ABI Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
static bool shouldExecute(CounterInfo &Counter)
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
static FixedVectorType * getHalfElementsVectorType(FixedVectorType *VTy)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
LLVM_ABI void setComdat(Comdat *C)
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ ExternalLinkage
Externally visible function.
Analysis pass providing a never-invalidated alias analysis result.
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
LLVM_ABI Value * CreateAndReduce(Value *Src)
Create a vector int AND reduction intrinsic of the source vector.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
LLVM_ABI CallInst * CreateMaskedCompressStore(Value *Val, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr)
Create a call to Masked Compress Store intrinsic.
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
IntegerType * getInt16Ty()
Fetch the type representing a 16-bit integer.
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
LLVM_ABI Value * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI DebugLoc getCurrentDebugLocation() const
Get location information used by debugging information.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memset to the specified pointer and the specified value.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
LLVMContext & getContext() const
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
LLVM_ABI CallInst * CreateMaskedStore(Value *Val, Value *Ptr, Align Alignment, Value *Mask)
Create a call to Masked Store intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
LLVM_ABI CallInst * CreateMaskedExpandLoad(Type *Ty, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Expand Load intrinsic.
Value * CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name="")
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LLVM_ABI CallInst * CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment, Value *Mask=nullptr)
Create a call to Masked Scatter intrinsic.
LLVM_ABI CallInst * CreateMaskedGather(Type *Ty, Value *Ptrs, Align Alignment, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Gather intrinsic.
Value * CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
std::vector< ConstraintInfo > ConstraintInfoVector
void visit(Iterator Start, Iterator End)
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
A Module instance is used to store all the information related to an LLVM module.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
bool remove(const value_type &X)
Remove an item from the set vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
LibFunc getLibFunc(StringRef funcName) const
Searches for a particular function name.
Triple - Helper class for working with autoconf configuration names.
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
bool isRISCV32() const
Tests whether the target is 32-bit RISC-V.
bool isPPC32() const
Tests whether the target is 32-bit PowerPC (little and big endian).
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isRISCV64() const
Tests whether the target is 64-bit RISC-V.
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
bool isARM() const
Tests whether the target is ARM (little and big endian).
bool isPPC64() const
Tests whether the target is 64-bit PowerPC (little and big endian).
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
bool isSystemZ() const
Tests whether the target is SystemZ.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isArrayTy() const
True if this is an instance of ArrayType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isPointerTy() const
True if this is an instance of PointerType.
Type * getArrayElementType() const
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
bool isVoidTy() const
Return true if this is 'void'.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
LLVM_ABI StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
Function * Kernel
Summary of a kernel (=entry point for target offloading).
NodeAddr< FuncNode * > Func
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
const InstrumentationOptions & getInstrumentationOptions(const LLVMContext &C)
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
RelativeUniformCounterPtr Values
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI std::pair< Instruction *, Value * > SplitBlockAndInsertSimpleForLoop(Value *End, BasicBlock::iterator SplitBefore)
Insert a for (int i = 0; i < End; i++) loop structure (with the exception that End is assumed > 0,...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool FoldInstsToUnreachable=true)
Remove all blocks that can not be reached from the function's entry.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function lazily.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ Or
Bitwise or logical OR of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
RoundingMode
Rounding mode.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool valueOr(BoolOrDefault X, bool Default)
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ End
Run the machine verifier once, at the end of the pipeline.
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
std::string itostr(int64_t X)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)