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) {
597 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
609 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
611 if (!Options.Kernel) {
620 MemorySanitizer Msan(Opts, *
F.getParent(), Options);
638 static_cast<PassInfoMixin<MemorySanitizerPass> *
>(
this)->
printPipeline(
639 OS, MapClassName2PassName);
645 if (Options.EagerChecks)
646 OS <<
"eager-checks;";
647 OS <<
"track-origins=" << Options.TrackOrigins;
663template <
typename... ArgsTy>
665MemorySanitizer::getOrInsertMsanMetadataFunction(
Module &M,
StringRef Name,
670 std::forward<ArgsTy>(Args)...);
673 return M.getOrInsertFunction(Name, MsanMetadata,
674 std::forward<ArgsTy>(Args)...);
683 RetvalOriginTLS =
nullptr;
685 ParamOriginTLS =
nullptr;
687 VAArgOriginTLS =
nullptr;
688 VAArgOverflowSizeTLS =
nullptr;
690 WarningFn =
M.getOrInsertFunction(
"__msan_warning",
692 IRB.getVoidTy(), IRB.getInt32Ty());
703 MsanGetContextStateFn =
704 M.getOrInsertFunction(
"__msan_get_context_state", PtrTy);
708 for (
int ind = 0,
size = 1; ind < 4; ind++,
size <<= 1) {
709 std::string name_load =
710 "__msan_metadata_ptr_for_load_" + std::to_string(
size);
711 std::string name_store =
712 "__msan_metadata_ptr_for_store_" + std::to_string(
size);
713 MsanMetadataPtrForLoad_1_8[ind] =
714 getOrInsertMsanMetadataFunction(M, name_load, PtrTy);
715 MsanMetadataPtrForStore_1_8[ind] =
716 getOrInsertMsanMetadataFunction(M, name_store, PtrTy);
719 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
720 M,
"__msan_metadata_ptr_for_load_n", PtrTy, IntptrTy);
721 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
722 M,
"__msan_metadata_ptr_for_store_n", PtrTy, IntptrTy);
725 MsanPoisonAllocaFn =
M.getOrInsertFunction(
726 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
727 MsanUnpoisonAllocaFn =
M.getOrInsertFunction(
728 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
732 return M.getOrInsertGlobal(Name, Ty, [&] {
734 nullptr, Name,
nullptr,
740void MemorySanitizer::createUserspaceApi(
Module &M,
748 StringRef WarningFnName = Recover ?
"__msan_warning_with_origin"
749 :
"__msan_warning_with_origin_noreturn";
750 WarningFn =
M.getOrInsertFunction(WarningFnName,
752 IRB.getVoidTy(), IRB.getInt32Ty());
755 Recover ?
"__msan_warning" :
"__msan_warning_noreturn";
756 WarningFn =
M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
783 IRB.getIntPtrTy(
M.getDataLayout()));
787 unsigned AccessSize = 1 << AccessSizeIndex;
788 std::string FunctionName =
"__msan_maybe_warning_" +
itostr(AccessSize);
789 MaybeWarningFn[AccessSizeIndex] =
M.getOrInsertFunction(
791 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
792 MaybeWarningVarSizeFn =
M.getOrInsertFunction(
793 "__msan_maybe_warning_N", TLI.
getAttrList(
C, {},
false),
794 IRB.getVoidTy(), PtrTy, IRB.getInt64Ty(), IRB.getInt32Ty());
795 FunctionName =
"__msan_maybe_store_origin_" +
itostr(AccessSize);
796 MaybeStoreOriginFn[AccessSizeIndex] =
M.getOrInsertFunction(
798 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
802 MsanSetAllocaOriginWithDescriptionFn =
803 M.getOrInsertFunction(
"__msan_set_alloca_origin_with_descr",
804 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
805 MsanSetAllocaOriginNoDescriptionFn =
806 M.getOrInsertFunction(
"__msan_set_alloca_origin_no_descr",
807 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
808 MsanPoisonStackFn =
M.getOrInsertFunction(
"__msan_poison_stack",
809 IRB.getVoidTy(), PtrTy, IntptrTy);
813void MemorySanitizer::initializeCallbacks(
Module &M,
816 if (CallbacksInitialized)
822 MsanChainOriginFn =
M.getOrInsertFunction(
823 "__msan_chain_origin",
826 MsanSetOriginFn =
M.getOrInsertFunction(
828 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
830 M.getOrInsertFunction(
"__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
832 M.getOrInsertFunction(
"__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
833 MemsetFn =
M.getOrInsertFunction(
"__msan_memset",
835 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
837 MsanInstrumentAsmStoreFn =
M.getOrInsertFunction(
838 "__msan_instrument_asm_store", IRB.getVoidTy(), PtrTy, IntptrTy);
841 createKernelApi(M, TLI);
843 createUserspaceApi(M, TLI);
845 CallbacksInitialized =
true;
851 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
869void MemorySanitizer::initializeModule(
Module &M) {
870 auto &
DL =
M.getDataLayout();
872 TargetTriple =
M.getTargetTriple();
874 bool ShadowPassed = Opts.msan_shadow_base.has_value();
875 bool OriginPassed = Opts.msan_origin_base.has_value();
877 if (ShadowPassed || OriginPassed) {
878 CustomMapParams.AndMask = Opts.msan_and_mask;
879 CustomMapParams.XorMask = Opts.msan_xor_mask;
880 CustomMapParams.ShadowBase = Opts.msan_shadow_base.value_or(0);
881 CustomMapParams.OriginBase = Opts.msan_origin_base.value_or(0);
882 MapParams = &CustomMapParams;
884 switch (TargetTriple.getOS()) {
886 switch (TargetTriple.getArch()) {
901 switch (TargetTriple.getArch()) {
910 switch (TargetTriple.getArch()) {
947 C = &(
M.getContext());
949 IntptrTy = IRB.getIntPtrTy(
DL);
950 OriginTy = IRB.getInt32Ty();
951 PtrTy = IRB.getPtrTy();
956 if (!CompileKernel) {
958 M.getOrInsertGlobal(
"__msan_track_origins", IRB.getInt32Ty(), [&] {
959 return new GlobalVariable(
960 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
961 IRB.getInt32(TrackOrigins),
"__msan_track_origins");
965 M.getOrInsertGlobal(
"__msan_keep_going", IRB.getInt32Ty(), [&] {
966 return new GlobalVariable(M, IRB.getInt32Ty(), true,
967 GlobalValue::WeakODRLinkage,
968 IRB.getInt32(Recover),
"__msan_keep_going");
984 virtual ~VarArgHelper() =
default;
987 virtual void visitCallBase(CallBase &CB,
IRBuilder<> &IRB) = 0;
990 virtual void visitVAStartInst(VAStartInst &
I) = 0;
993 virtual void visitVACopyInst(VACopyInst &
I) = 0;
999 virtual void finalizeInstrumentation() = 0;
1002struct MemorySanitizerVisitor;
1007 MemorySanitizerVisitor &Visitor);
1014 if (TypeSizeFixed <= 8)
1023class NextNodeIRBuilder :
public IRBuilder<> {
1036struct MemorySanitizerVisitor :
public InstVisitor<MemorySanitizerVisitor> {
1037 const InstrumentationOptions &Opts;
1039 MemorySanitizer &MS;
1041 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1042 std::unique_ptr<VarArgHelper> VAHelper;
1043 const TargetLibraryInfo *TLI;
1050 bool PropagateShadow;
1053 bool PoisonUndefVectors;
1055 struct ShadowOriginAndInsertPoint {
1060 ShadowOriginAndInsertPoint(
Value *S,
Value *O, Instruction *
I)
1061 : Shadow(S), Origin(
O), OrigIns(
I) {}
1064 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1065 SmallSetVector<AllocaInst *, 16> AllocaSet;
1068 int64_t SplittableBlocksCount = 0;
1070 MemorySanitizerVisitor(
Function &
F, MemorySanitizer &MS,
1071 const TargetLibraryInfo &TLI)
1074 bool SanitizeFunction =
F.hasFnAttribute(Attribute::SanitizeMemory) &&
1075 !Opts.msan_disable_checks;
1076 InsertChecks = SanitizeFunction;
1077 PropagateShadow = SanitizeFunction;
1078 PoisonStack = SanitizeFunction && Opts.msan_poison_stack;
1079 PoisonUndef = SanitizeFunction && Opts.msan_poison_undef;
1080 PoisonUndefVectors = SanitizeFunction && Opts.msan_poison_undef_vectors;
1088 MS.initializeCallbacks(*
F.getParent(), TLI);
1091 .CreateIntrinsicWithoutFolding(Intrinsic::donothing, {});
1093 if (MS.CompileKernel) {
1094 IRBuilder<> IRB(FnPrologueEnd);
1095 insertKmsanPrologue(IRB);
1099 <<
"MemorySanitizer is not inserting checks into '"
1100 <<
F.getName() <<
"'\n");
1103 bool instrumentWithCalls(
Value *V) {
1107 ++SplittableBlocksCount;
1108 return Opts.msan_instrumentation_with_call_threshold >= 0 &&
1109 SplittableBlocksCount >
1110 Opts.msan_instrumentation_with_call_threshold;
1113 bool isInPrologue(Instruction &
I) {
1114 return I.getParent() == FnPrologueEnd->
getParent() &&
1123 if (MS.TrackOrigins <= 1)
1125 return IRB.
CreateCall(MS.MsanChainOriginFn, V);
1129 const DataLayout &
DL =
F.getDataLayout();
1130 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1140 TypeSize TS, Align Alignment) {
1141 const DataLayout &
DL =
F.getDataLayout();
1142 const Align IntptrAlignment =
DL.getABITypeAlign(MS.IntptrTy);
1143 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1155 auto [InsertPt,
Index] =
1168 if (Alignment >= IntptrAlignment && IntptrSize >
kOriginSize) {
1169 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1171 for (
unsigned i = 0; i <
Size / IntptrSize; ++i) {
1176 CurrentAlignment = IntptrAlignment;
1189 Value *OriginPtr, Align Alignment) {
1190 const DataLayout &
DL =
F.getDataLayout();
1192 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
1194 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1196 if (!Opts.msan_check_constant_shadow || ConstantShadow->isNullValue()) {
1203 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1210 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1212 if (instrumentWithCalls(ConvertedShadow) &&
1214 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1215 Value *ConvertedShadow2 =
1217 CallBase *CB = IRB.
CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1221 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1225 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1230 void materializeStores() {
1231 for (StoreInst *SI : StoreList) {
1233 Value *Val =
SI->getValueOperand();
1234 Value *Addr =
SI->getPointerOperand();
1235 Value *Shadow =
SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1236 Value *ShadowPtr, *OriginPtr;
1240 std::tie(ShadowPtr, OriginPtr) =
1241 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
true);
1243 [[maybe_unused]] StoreInst *NewSI =
1250 if (MS.TrackOrigins && !
SI->isAtomic())
1251 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1258 if (MS.TrackOrigins < 2)
1261 if (LazyWarningDebugLocationCount.
empty())
1262 for (
const auto &
I : InstrumentationList)
1263 ++LazyWarningDebugLocationCount[
I.OrigIns->getDebugLoc()];
1265 return LazyWarningDebugLocationCount[
DebugLoc] >=
1266 Opts.msan_disambiguate_warning_threshold;
1280 auto NewDebugLoc = OI->getDebugLoc();
1287 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1288 Origin = updateOrigin(Origin, IRBOrigin);
1293 if (MS.CompileKernel || MS.TrackOrigins)
1304 const DataLayout &
DL =
F.getDataLayout();
1305 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1307 if (instrumentWithCalls(ConvertedShadow) && !MS.CompileKernel) {
1309 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1310 Value *ConvertedShadow2 =
1314 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1318 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1322 FunctionCallee Fn = MS.MaybeWarningVarSizeFn;
1325 unsigned ShadowSize =
DL.getTypeAllocSize(ConvertedShadow2->
getType());
1328 {ShadowAlloca, ConstantInt::get(IRB.
getInt64Ty(), ShadowSize),
1329 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1334 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1337 !MS.Recover, MS.ColdCallWeights);
1340 insertWarningFn(IRB, Origin);
1345 void materializeInstructionChecks(
1347 const DataLayout &
DL =
F.getDataLayout();
1350 bool Combine = !MS.TrackOrigins;
1352 Value *Shadow =
nullptr;
1353 for (
const auto &ShadowData : InstructionChecks) {
1354 assert(ShadowData.OrigIns == Instruction);
1357 Value *ConvertedShadow = ShadowData.Shadow;
1360 if (!Opts.msan_check_constant_shadow || ConstantShadow->isNullValue()) {
1366 insertWarningFn(IRB, ShadowData.Origin);
1376 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1381 Shadow = ConvertedShadow;
1385 Shadow = convertToBool(Shadow, IRB,
"_mscmp");
1386 ConvertedShadow = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1387 Shadow = IRB.
CreateOr(Shadow, ConvertedShadow,
"_msor");
1393 materializeOneCheck(IRB, Shadow,
nullptr);
1397 static bool isAArch64SVCount(
Type *Ty) {
1399 return TTy->
getName() ==
"aarch64.svcount";
1405 static bool isScalableNonVectorType(
Type *Ty) {
1406 if (!isAArch64SVCount(Ty))
1407 LLVM_DEBUG(
dbgs() <<
"isScalableNonVectorType: Unexpected type " << *Ty
1413 void materializeChecks() {
1416 SmallPtrSet<Instruction *, 16>
Done;
1419 for (
auto I = InstrumentationList.begin();
1420 I != InstrumentationList.end();) {
1421 auto OrigIns =
I->OrigIns;
1425 auto J = std::find_if(
I + 1, InstrumentationList.end(),
1426 [OrigIns](
const ShadowOriginAndInsertPoint &R) {
1427 return OrigIns != R.OrigIns;
1441 MS.ParamTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1442 {Zero, IRB.getInt32(0)},
"param_shadow");
1443 MS.RetvalTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1444 {Zero, IRB.getInt32(1)},
"retval_shadow");
1445 MS.VAArgTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1446 {Zero, IRB.getInt32(2)},
"va_arg_shadow");
1447 MS.VAArgOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1448 {Zero, IRB.getInt32(3)},
"va_arg_origin");
1449 MS.VAArgOverflowSizeTLS =
1450 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1451 {Zero, IRB.getInt32(4)},
"va_arg_overflow_size");
1452 MS.ParamOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1453 {Zero, IRB.getInt32(5)},
"param_origin");
1454 MS.RetvalOriginTLS =
1455 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1456 {Zero, IRB.getInt32(6)},
"retval_origin");
1458 MS.MsanMetadataAlloca = IRB.
CreateAlloca(MS.MsanMetadata, 0u);
1471 for (Instruction *
I : Instructions)
1475 for (PHINode *PN : ShadowPHINodes) {
1477 PHINode *PNO = MS.TrackOrigins ?
cast<PHINode>(getOrigin(PN)) : nullptr;
1478 size_t NumValues = PN->getNumIncomingValues();
1479 for (
size_t v = 0;
v < NumValues;
v++) {
1480 PNS->
addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1482 PNO->
addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1486 VAHelper->finalizeInstrumentation();
1490 if (Opts.msan_handle_lifetime_intrinsics) {
1491 for (
auto Item : LifetimeStartList) {
1492 instrumentAlloca(*Item.second, Item.first);
1493 AllocaSet.
remove(Item.second);
1498 for (AllocaInst *AI : AllocaSet)
1499 instrumentAlloca(*AI);
1502 materializeChecks();
1506 materializeStores();
1512 Type *getShadowTy(
Value *V) {
return getShadowTy(
V->getType()); }
1523 const DataLayout &
DL =
F.getDataLayout();
1525 uint32_t EltSize =
DL.getTypeSizeInBits(VT->getElementType());
1527 VT->getElementCount());
1530 return ArrayType::get(getShadowTy(AT->getElementType()),
1531 AT->getNumElements());
1535 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1536 Elements.push_back(getShadowTy(
ST->getElementType(i)));
1538 LLVM_DEBUG(
dbgs() <<
"getShadowTy: " << *ST <<
" ===> " << *Res <<
"\n");
1541 if (isScalableNonVectorType(OrigTy)) {
1542 LLVM_DEBUG(
dbgs() <<
"getShadowTy: Scalable non-vector type: " << *OrigTy
1547 uint32_t TypeSize =
DL.getTypeSizeInBits(OrigTy);
1552 Value *collapseStructShadow(StructType *Struct,
Value *Shadow,
1557 for (
unsigned Idx = 0;
Idx <
Struct->getNumElements();
Idx++) {
1560 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1562 if (Aggregator != FalseVal)
1563 Aggregator = IRB.
CreateOr(Aggregator, ShadowBool);
1565 Aggregator = ShadowBool;
1572 Value *collapseArrayShadow(ArrayType *Array,
Value *Shadow,
1574 if (!
Array->getNumElements())
1578 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1580 for (
unsigned Idx = 1;
Idx <
Array->getNumElements();
Idx++) {
1582 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1583 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
1593 return collapseStructShadow(Struct, V, IRB);
1595 return collapseArrayShadow(Array, V, IRB);
1600 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1608 Type *VTy =
V->getType();
1610 return convertToBool(convertShadowToScalar(V, IRB), IRB,
name);
1617 Type *ptrToIntPtrType(
Type *PtrTy)
const {
1619 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1620 VectTy->getElementCount());
1628 return VectorType::get(
1629 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1630 VectTy->getElementCount());
1639 VectTy->getElementCount(),
1640 constToIntPtr(VectTy->getElementType(),
C));
1645 return ConstantInt::get(MS.IntptrTy,
C,
false,
1659 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1662 if (
uint64_t AndMask = MS.MapParams->AndMask)
1663 OffsetLong = IRB.
CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1665 if (
uint64_t XorMask = MS.MapParams->XorMask)
1666 OffsetLong = IRB.
CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1678 std::pair<Value *, Value *>
1680 MaybeAlign Alignment) {
1685 assert(VectTy->getElementType()->isPointerTy());
1687 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1688 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1689 Value *ShadowLong = ShadowOffset;
1690 if (
uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1692 IRB.
CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1695 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1697 Value *OriginPtr =
nullptr;
1698 if (MS.TrackOrigins) {
1699 Value *OriginLong = ShadowOffset;
1700 uint64_t OriginBase = MS.MapParams->OriginBase;
1701 if (OriginBase != 0)
1703 IRB.
CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1706 OriginLong = IRB.
CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1709 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1711 return std::make_pair(ShadowPtr, OriginPtr);
1714 template <
typename... ArgsTy>
1719 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1720 return IRB.
CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1723 return IRB.
CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1726 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(
Value *Addr,
1730 Value *ShadowOriginPtrs;
1731 const DataLayout &
DL =
F.getDataLayout();
1732 TypeSize
Size =
DL.getTypeStoreSize(ShadowTy);
1734 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(
isStore,
Size);
1737 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1739 Value *SizeVal = ConstantInt::get(MS.IntptrTy,
Size);
1740 ShadowOriginPtrs = createMetadataCall(
1742 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1749 return std::make_pair(ShadowPtr, OriginPtr);
1755 std::pair<Value *, Value *> getShadowOriginPtrKernel(
Value *Addr,
1762 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy,
isStore);
1767 Value *ShadowPtrs = ConstantInt::getNullValue(
1769 Value *OriginPtrs =
nullptr;
1770 if (MS.TrackOrigins)
1771 OriginPtrs = ConstantInt::getNullValue(
1773 for (
unsigned i = 0; i < NumElements; ++i) {
1776 auto [ShadowPtr, OriginPtr] =
1777 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy,
isStore);
1780 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1781 if (MS.TrackOrigins)
1783 OriginPtrs, OriginPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1785 return {ShadowPtrs, OriginPtrs};
1788 std::pair<Value *, Value *> getShadowOriginPtr(
Value *Addr,
IRBuilder<> &IRB,
1790 MaybeAlign Alignment,
1792 if (MS.CompileKernel)
1793 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy,
isStore);
1794 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1802 ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg");
1807 if (!MS.TrackOrigins)
1810 ConstantInt::get(MS.IntptrTy, ArgOffset),
1820 Value *getOriginPtrForRetval() {
1822 return MS.RetvalOriginTLS;
1827 assert(!ShadowMap.
count(V) &&
"Values may only have one shadow");
1828 ShadowMap[
V] = PropagateShadow ?
SV : getCleanShadow(V);
1833 if (!MS.TrackOrigins)
1835 assert(!OriginMap.
count(V) &&
"Values may only have one origin");
1836 LLVM_DEBUG(
dbgs() <<
"ORIGIN: " << *V <<
" ==> " << *Origin <<
"\n");
1837 OriginMap[
V] = Origin;
1841 Type *ShadowTy = getShadowTy(OrigTy);
1851 Constant *getCleanShadow(
Value *V) {
return getCleanShadow(
V->getType()); }
1859 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
1860 getPoisonedShadow(AT->getElementType()));
1864 SmallVector<Constant *, 4> Vals;
1865 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1866 Vals.
push_back(getPoisonedShadow(
ST->getElementType(i)));
1874 Type *ShadowTy = getShadowTy(V);
1877 return getPoisonedShadow(ShadowTy);
1889 if (!PropagateShadow ||
I->getMetadata(LLVMContext::MD_nosanitize))
1890 return getCleanShadow(V);
1892 Value *Shadow = ShadowMap[
V];
1894 LLVM_DEBUG(
dbgs() <<
"No shadow: " << *V <<
"\n" << *(
I->getParent()));
1895 assert(Shadow &&
"No shadow for a value");
1902 Value *
AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
1903 : getCleanShadow(V);
1909 Value *&ShadowPtr = ShadowMap[
V];
1914 unsigned ArgOffset = 0;
1915 const DataLayout &
DL =
F->getDataLayout();
1916 for (
auto &FArg :
F->args()) {
1917 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
1919 ?
"vscale not fully supported\n"
1920 :
"Arg is not sized\n"));
1922 ShadowPtr = getCleanShadow(V);
1923 setOrigin(
A, getCleanOrigin());
1929 unsigned Size = FArg.hasByValAttr()
1930 ?
DL.getTypeAllocSize(FArg.getParamByValType())
1931 :
DL.getTypeAllocSize(FArg.getType());
1935 if (FArg.hasByValAttr()) {
1939 const Align ArgAlign =
DL.getValueOrABITypeAlignment(
1940 FArg.getParamAlign(), FArg.getParamByValType());
1941 Value *CpShadowPtr, *CpOriginPtr;
1942 std::tie(CpShadowPtr, CpOriginPtr) =
1943 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
1945 if (!PropagateShadow || Overflow) {
1947 EntryIRB.CreateMemSet(
1951 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1953 [[maybe_unused]]
Value *Cpy = EntryIRB.CreateMemCpy(
1954 CpShadowPtr, CopyAlign,
Base, CopyAlign,
Size);
1957 if (MS.TrackOrigins) {
1958 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1962 EntryIRB.CreateMemCpy(
1971 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
1972 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
1973 ShadowPtr = getCleanShadow(V);
1974 setOrigin(
A, getCleanOrigin());
1977 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1978 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg),
Base,
1980 if (MS.TrackOrigins) {
1981 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1982 setOrigin(
A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
1986 <<
" ARG: " << FArg <<
" ==> " << *ShadowPtr <<
"\n");
1992 assert(ShadowPtr &&
"Could not find shadow for an argument");
1999 cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
2000 PoisonUndefVectors) {
2003 for (
unsigned i = 0; i != NumElems; ++i) {
2006 : getCleanShadow(Elem);
2010 LLVM_DEBUG(
dbgs() <<
"Partial undef constant vector: " << *V <<
" ==> "
2011 << *ShadowConstant <<
"\n");
2013 return ShadowConstant;
2019 return getCleanShadow(V);
2023 Value *getShadow(Instruction *
I,
int i) {
2024 return getShadow(
I->getOperand(i));
2029 if (!MS.TrackOrigins)
2032 return getCleanOrigin();
2034 "Unexpected value type in getOrigin()");
2036 if (
I->getMetadata(LLVMContext::MD_nosanitize))
2037 return getCleanOrigin();
2039 Value *Origin = OriginMap[
V];
2040 assert(Origin &&
"Missing origin");
2045 Value *getOrigin(Instruction *
I,
int i) {
2046 return getOrigin(
I->getOperand(i));
2053 void insertCheckShadow(
Value *Shadow,
Value *Origin, Instruction *OrigIns) {
2059 LLVM_DEBUG(
dbgs() <<
"Skipping check of " << *Shadow <<
" before "
2060 << *OrigIns <<
"\n");
2065 if (isScalableNonVectorType(ShadowTy)) {
2066 LLVM_DEBUG(
dbgs() <<
"Skipping check of scalable non-vector " << *Shadow
2067 <<
" before " << *OrigIns <<
"\n");
2073 "Can only insert checks for integer, vector, and aggregate shadow "
2076 InstrumentationList.push_back(
2077 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2085 void insertCheckShadowOf(
Value *Val, Instruction *OrigIns) {
2087 Value *Shadow, *Origin;
2088 if (Opts.msan_check_constant_shadow) {
2089 Shadow = getShadow(Val);
2092 Origin = getOrigin(Val);
2099 insertCheckShadow(Shadow, Origin, OrigIns);
2104 case AtomicOrdering::NotAtomic:
2105 return AtomicOrdering::NotAtomic;
2106 case AtomicOrdering::Unordered:
2107 case AtomicOrdering::Monotonic:
2108 case AtomicOrdering::Release:
2109 return AtomicOrdering::Release;
2110 case AtomicOrdering::Acquire:
2111 case AtomicOrdering::AcquireRelease:
2112 return AtomicOrdering::AcquireRelease;
2113 case AtomicOrdering::SequentiallyConsistent:
2114 return AtomicOrdering::SequentiallyConsistent;
2120 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2121 uint32_t OrderingTable[NumOrderings] = {};
2123 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2124 OrderingTable[(
int)AtomicOrderingCABI::release] =
2125 (int)AtomicOrderingCABI::release;
2126 OrderingTable[(int)AtomicOrderingCABI::consume] =
2127 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2128 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2129 (
int)AtomicOrderingCABI::acq_rel;
2130 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2131 (
int)AtomicOrderingCABI::seq_cst;
2138 case AtomicOrdering::NotAtomic:
2139 return AtomicOrdering::NotAtomic;
2140 case AtomicOrdering::Unordered:
2141 case AtomicOrdering::Monotonic:
2142 case AtomicOrdering::Acquire:
2143 return AtomicOrdering::Acquire;
2144 case AtomicOrdering::Release:
2145 case AtomicOrdering::AcquireRelease:
2146 return AtomicOrdering::AcquireRelease;
2147 case AtomicOrdering::SequentiallyConsistent:
2148 return AtomicOrdering::SequentiallyConsistent;
2154 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2155 uint32_t OrderingTable[NumOrderings] = {};
2157 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2158 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2159 OrderingTable[(int)AtomicOrderingCABI::consume] =
2160 (
int)AtomicOrderingCABI::acquire;
2161 OrderingTable[(int)AtomicOrderingCABI::release] =
2162 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
2163 (int)AtomicOrderingCABI::acq_rel;
2164 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2165 (
int)AtomicOrderingCABI::seq_cst;
2171 using InstVisitor<MemorySanitizerVisitor>
::visit;
2172 void visit(Instruction &
I) {
2173 if (
I.getMetadata(LLVMContext::MD_nosanitize))
2176 if (isInPrologue(
I))
2181 setShadow(&
I, getCleanShadow(&
I));
2182 setOrigin(&
I, getCleanOrigin());
2193 void visitLoadInst(LoadInst &
I) {
2194 assert(
I.getType()->isSized() &&
"Load type must have size");
2195 assert(!
I.getMetadata(LLVMContext::MD_nosanitize));
2196 NextNodeIRBuilder IRB(&
I);
2197 Type *ShadowTy = getShadowTy(&
I);
2198 Value *Addr =
I.getPointerOperand();
2199 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
2201 if (PropagateShadow) {
2202 std::tie(ShadowPtr, OriginPtr) =
2203 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
2207 setShadow(&
I, getCleanShadow(&
I));
2210 if (Opts.msan_check_access_address)
2211 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2216 if (MS.TrackOrigins) {
2217 if (PropagateShadow) {
2222 setOrigin(&
I, getCleanOrigin());
2231 void visitStoreInst(StoreInst &
I) {
2232 StoreList.push_back(&
I);
2233 if (Opts.msan_check_access_address)
2234 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2237 void handleCASOrRMW(Instruction &
I) {
2241 Value *Addr =
I.getOperand(0);
2242 Value *Val =
I.getOperand(1);
2243 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val),
Align(1),
2247 if (Opts.msan_check_access_address)
2248 insertCheckShadowOf(Addr, &
I);
2254 insertCheckShadowOf(Val, &
I);
2258 setShadow(&
I, getCleanShadow(&
I));
2259 setOrigin(&
I, getCleanOrigin());
2262 void visitAtomicRMWInst(AtomicRMWInst &
I) {
2267 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2329 void visitSwitchInst(SwitchInst &SI) {
2332 Value *Val =
SI.getCondition();
2333 Value *ShadowVal = getShadow(Val);
2343 int casesToConsider = Opts.msan_switch_precision;
2345 Value *ShadowCases =
nullptr;
2346 for (
auto Case :
SI.cases()) {
2347 if (casesToConsider <= 0)
2350 Value *Comparator = Case.getCaseValue();
2353 Value *ComparisonShadow = propagateEqualityComparison(
2354 IRB, Val, Comparator, ShadowVal, getShadow(Comparator));
2357 ShadowCases = IRB.
CreateOr(ShadowCases, ComparisonShadow);
2359 ShadowCases = ComparisonShadow;
2365 insertCheckShadow(ShadowCases, getOrigin(Val), &SI);
2369 void visitExtractElementInst(ExtractElementInst &
I) {
2370 insertCheckShadowOf(
I.getOperand(1), &
I);
2374 setOrigin(&
I, getOrigin(&
I, 0));
2377 void visitInsertElementInst(InsertElementInst &
I) {
2378 insertCheckShadowOf(
I.getOperand(2), &
I);
2380 auto *Shadow0 = getShadow(&
I, 0);
2381 auto *Shadow1 = getShadow(&
I, 1);
2384 setOriginForNaryOp(
I);
2387 void visitShuffleVectorInst(ShuffleVectorInst &
I) {
2389 auto *Shadow0 = getShadow(&
I, 0);
2390 auto *Shadow1 = getShadow(&
I, 1);
2393 setOriginForNaryOp(
I);
2397 void visitSExtInst(SExtInst &
I) {
2399 setShadow(&
I, IRB.
CreateSExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2400 setOrigin(&
I, getOrigin(&
I, 0));
2403 void visitZExtInst(ZExtInst &
I) {
2405 setShadow(&
I, IRB.
CreateZExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2406 setOrigin(&
I, getOrigin(&
I, 0));
2409 void visitTruncInst(TruncInst &
I) {
2411 setShadow(&
I, IRB.
CreateTrunc(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2412 setOrigin(&
I, getOrigin(&
I, 0));
2415 void visitBitCastInst(BitCastInst &
I) {
2420 if (CI->isMustTailCall())
2424 setOrigin(&
I, getOrigin(&
I, 0));
2427 void visitAddrSpaceCastInst(AddrSpaceCastInst &
I) {
2430 "_msprop_addrspacecast"));
2431 setOrigin(&
I, getOrigin(&
I, 0));
2434 void visitPtrToIntInst(PtrToIntInst &
I) {
2437 "_msprop_ptrtoint"));
2438 setOrigin(&
I, getOrigin(&
I, 0));
2441 void visitPtrToAddrInst(PtrToAddrInst &
I) {
2444 "_msprop_ptrtoaddr"));
2445 setOrigin(&
I, getOrigin(&
I, 0));
2448 void visitIntToPtrInst(IntToPtrInst &
I) {
2451 "_msprop_inttoptr"));
2452 setOrigin(&
I, getOrigin(&
I, 0));
2473 void handleGenericVectorConvertIntrinsic(Instruction &
I,
bool FixedPoint) {
2474 [[maybe_unused]]
unsigned NumArgs =
I.getNumOperands();
2476 NumArgs = CI->arg_size();
2480 Value *Precision =
I.getOperand(1);
2481 insertCheckShadowOf(Precision, &
I);
2487 Value *S0 = getShadow(&
I, 0);
2497 setShadow(&
I, OutShadow);
2498 setOriginForNaryOp(
I);
2501 void visitFPToSIInst(CastInst &
I) {
2502 handleGenericVectorConvertIntrinsic(
I,
false);
2504 void visitFPToUIInst(CastInst &
I) {
2505 handleGenericVectorConvertIntrinsic(
I,
false);
2507 void visitSIToFPInst(CastInst &
I) {
2508 handleGenericVectorConvertIntrinsic(
I,
false);
2510 void visitUIToFPInst(CastInst &
I) {
2511 handleGenericVectorConvertIntrinsic(
I,
false);
2514 void visitFPExtInst(CastInst &
I) {
2515 handleGenericVectorConvertIntrinsic(
I,
false);
2517 void visitFPTruncInst(CastInst &
I) {
2518 handleGenericVectorConvertIntrinsic(
I,
false);
2539 assert(
V1->getType()->isIntOrIntVectorTy());
2550 return IRB.
CreateOr({S1S2, V1S2, S1V2});
2554 void visitAnd(BinaryOperator &
I) {
2557 Value *V2 =
I.getOperand(1);
2559 Value *S2 = getShadow(&
I, 1);
2561 Value *OutShadow = handleBitwiseAnd(IRB,
V1, V2,
S1, S2);
2563 setShadow(&
I, OutShadow);
2564 setOriginForNaryOp(
I);
2567 void visitOr(BinaryOperator &
I) {
2580 Value *S2 = getShadow(&
I, 1);
2582 Value *V2 =
I.getOperand(1);
2586 assert(
V1->getType()->isIntOrIntVectorTy());
2602 if (Opts.msan_precise_disjoint_or &&
2607 S = IRB.
CreateOr(S, DisjointOrShadow,
"_ms_disjoint");
2611 setOriginForNaryOp(
I);
2629 template <
bool CombineShadow>
class Combiner {
2630 Value *Shadow =
nullptr;
2631 Value *Origin =
nullptr;
2633 MemorySanitizerVisitor *MSV;
2636 Combiner(MemorySanitizerVisitor *MSV,
IRBuilder<> &IRB)
2637 : IRB(IRB), MSV(MSV) {}
2641 if (CombineShadow) {
2646 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2647 Shadow = IRB.
CreateOr(Shadow, OpShadow,
"_msprop");
2651 if (MSV->MS.TrackOrigins) {
2658 if (!ConstOrigin || !ConstOrigin->
isNullValue()) {
2659 Value *
Cond = MSV->convertToBool(OpShadow, IRB);
2669 Value *OpShadow = MSV->getShadow(V);
2670 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) :
nullptr;
2671 return Add(OpShadow, OpOrigin);
2676 void Done(Instruction *
I) {
2677 if (CombineShadow) {
2679 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(
I));
2680 MSV->setShadow(
I, Shadow);
2682 if (MSV->MS.TrackOrigins) {
2684 MSV->setOrigin(
I, Origin);
2690 void DoneAndStoreOrigin(TypeSize TS,
Value *OriginPtr) {
2691 if (MSV->MS.TrackOrigins) {
2698 using ShadowAndOriginCombiner = Combiner<true>;
2699 using OriginCombiner = Combiner<false>;
2702 void setOriginForNaryOp(Instruction &
I) {
2703 if (!MS.TrackOrigins)
2706 OriginCombiner OC(
this, IRB);
2707 for (Use &
Op :
I.operands())
2712 size_t VectorOrPrimitiveTypeSizeInBits(
Type *Ty) {
2714 "Vector of pointers is not a valid shadow type");
2724 Type *srcTy =
V->getType();
2727 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2728 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2729 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2747 Type *ShadowTy = getShadowTy(V);
2748 if (
V->getType() == ShadowTy)
2750 if (
V->getType()->isPtrOrPtrVectorTy())
2757 void handleShadowOr(Instruction &
I) {
2759 ShadowAndOriginCombiner SC(
this, IRB);
2760 for (Use &
Op :
I.operands())
2787 Value *horizontalReduce(IntrinsicInst &
I,
unsigned ReductionFactor,
2788 unsigned Shards,
Value *VectorA,
Value *VectorB) {
2793 [[maybe_unused]]
unsigned TotalNumElems = NumElems;
2799 assert(NumElems % (ReductionFactor * Shards) == 0);
2804 for (
unsigned i = 0; i < ReductionFactor; i++) {
2805 SmallVector<int, 16>
Mask;
2807 for (
unsigned j = 0;
j < Shards;
j++) {
2808 unsigned Offset = NumElems / Shards *
j;
2810 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2814 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2839 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards) {
2840 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2842 assert(
I.getType()->isVectorTy());
2843 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2845 [[maybe_unused]] FixedVectorType *ParamType =
2849 [[maybe_unused]] FixedVectorType *
ReturnType =
2857 Value *FirstArgShadow = getShadow(&
I, 0);
2858 Value *SecondArgShadow =
nullptr;
2859 if (
I.arg_size() == 2)
2860 SecondArgShadow = getShadow(&
I, 1);
2862 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2863 FirstArgShadow, SecondArgShadow);
2865 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2867 setShadow(&
I, OrShadow);
2868 setOriginForNaryOp(
I);
2878 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards,
2879 int ReinterpretElemWidth) {
2880 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2882 assert(
I.getType()->isVectorTy());
2883 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2885 FixedVectorType *ParamType =
2890 [[maybe_unused]] FixedVectorType *
ReturnType =
2897 FixedVectorType *ReinterpretShadowTy =
nullptr;
2905 Value *FirstArgShadow = getShadow(&
I, 0);
2906 FirstArgShadow = IRB.
CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
2916 Value *SecondArgShadow =
nullptr;
2917 if (
I.arg_size() == 2) {
2918 SecondArgShadow = getShadow(&
I, 1);
2919 SecondArgShadow = IRB.
CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
2922 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2923 FirstArgShadow, SecondArgShadow);
2925 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2927 setShadow(&
I, OrShadow);
2928 setOriginForNaryOp(
I);
2931 void visitFNeg(UnaryOperator &
I) { handleShadowOr(
I); }
2942 void handleMulByConstant(BinaryOperator &
I, Constant *ConstArg,
2948 Type *EltTy = VTy->getElementType();
2950 for (
unsigned Idx = 0;
Idx < NumElements; ++
Idx) {
2951 if (ConstantInt *Elt =
2953 const APInt &
V = Elt->getValue();
2954 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
2955 Elements.push_back(ConstantInt::get(EltTy, V2));
2957 Elements.push_back(ConstantInt::get(EltTy, 1));
2963 const APInt &
V = Elt->getValue();
2964 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
2965 ShadowMul = ConstantInt::get(Ty, V2);
2967 ShadowMul = ConstantInt::get(Ty, 1);
2973 IRB.
CreateMul(getShadow(OtherArg), ShadowMul,
"msprop_mul_cst"));
2974 setOrigin(&
I, getOrigin(OtherArg));
2977 void visitMul(BinaryOperator &
I) {
2980 if (constOp0 && !constOp1)
2981 handleMulByConstant(
I, constOp0,
I.getOperand(1));
2982 else if (constOp1 && !constOp0)
2983 handleMulByConstant(
I, constOp1,
I.getOperand(0));
2988 void visitFAdd(BinaryOperator &
I) { handleShadowOr(
I); }
2989 void visitFSub(BinaryOperator &
I) { handleShadowOr(
I); }
2990 void visitFMul(BinaryOperator &
I) { handleShadowOr(
I); }
2991 void visitAdd(BinaryOperator &
I) { handleShadowOr(
I); }
2992 void visitSub(BinaryOperator &
I) { handleShadowOr(
I); }
2993 void visitXor(BinaryOperator &
I) { handleShadowOr(
I); }
2995 void handleIntegerDiv(Instruction &
I) {
2998 insertCheckShadowOf(
I.getOperand(1), &
I);
2999 setShadow(&
I, getShadow(&
I, 0));
3000 setOrigin(&
I, getOrigin(&
I, 0));
3003 void visitUDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3004 void visitSDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3005 void visitURem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3006 void visitSRem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3010 void visitFDiv(BinaryOperator &
I) { handleShadowOr(
I); }
3011 void visitFRem(BinaryOperator &
I) { handleShadowOr(
I); }
3017 void handleEqualityComparison(ICmpInst &
I) {
3021 Value *Sa = getShadow(
A);
3022 Value *Sb = getShadow(
B);
3024 Value *Si = propagateEqualityComparison(IRB,
A,
B, Sa, Sb);
3027 setOriginForNaryOp(
I);
3035 void handleRelationalComparisonExact(ICmpInst &
I) {
3039 Value *Sa = getShadow(
A);
3040 Value *Sb = getShadow(
B);
3051 bool IsSigned =
I.isSigned();
3053 auto GetMinMaxUnsigned = [&](
Value *
V,
Value *S) {
3063 V = IRB.
CreateXor(V, ConstantInt::get(
V->getType(), MinVal));
3068 return std::make_pair(Min, Max);
3071 auto [Amin, Amax] = GetMinMaxUnsigned(
A, Sa);
3072 auto [Bmin, Bmax] = GetMinMaxUnsigned(
B, Sb);
3078 setOriginForNaryOp(
I);
3085 void handleSignedRelationalComparison(ICmpInst &
I) {
3090 op =
I.getOperand(0);
3091 pre =
I.getPredicate();
3093 op =
I.getOperand(1);
3094 pre =
I.getSwappedPredicate();
3107 setShadow(&
I, Shadow);
3108 setOrigin(&
I, getOrigin(
op));
3114 void visitICmpInst(ICmpInst &
I) {
3115 if (!Opts.msan_handle_icmp) {
3119 if (
I.isEquality()) {
3120 handleEqualityComparison(
I);
3125 if (Opts.msan_handle_icmp_exact) {
3126 handleRelationalComparisonExact(
I);
3130 handleSignedRelationalComparison(
I);
3136 handleRelationalComparisonExact(
I);
3143 void visitFCmpInst(FCmpInst &
I) { handleShadowOr(
I); }
3145 void handleShift(BinaryOperator &
I) {
3150 Value *S2 = getShadow(&
I, 1);
3153 Value *V2 =
I.getOperand(1);
3155 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3156 setOriginForNaryOp(
I);
3159 void visitShl(BinaryOperator &
I) { handleShift(
I); }
3160 void visitAShr(BinaryOperator &
I) { handleShift(
I); }
3161 void visitLShr(BinaryOperator &
I) { handleShift(
I); }
3163 void handleFunnelShift(IntrinsicInst &
I) {
3167 Value *S0 = getShadow(&
I, 0);
3169 Value *S2 = getShadow(&
I, 2);
3172 Value *V2 =
I.getOperand(2);
3175 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3176 setOriginForNaryOp(
I);
3184 void handleGenericBitManipulation(IntrinsicInst &
I) {
3186 Type *ShadowTy = getShadowTy(&
I);
3189 Value *SMask = getShadow(&
I, 1);
3194 if (
Function *Func =
I.getCalledFunction())
3195 S = IRB.
CreateCall(Func, {getShadow(&
I, 0),
I.getOperand(1)});
3198 {getShadow(&I, 0), I.getOperand(1)});
3201 setOriginForNaryOp(
I);
3214 void visitMemMoveInst(MemMoveInst &
I) {
3215 getShadow(
I.getArgOperand(1));
3218 {I.getArgOperand(0), I.getArgOperand(1),
3219 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3237 void visitMemCpyInst(MemCpyInst &
I) {
3238 getShadow(
I.getArgOperand(1));
3241 {I.getArgOperand(0), I.getArgOperand(1),
3242 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3247 void visitMemSetInst(MemSetInst &
I) {
3251 {I.getArgOperand(0),
3252 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3253 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3257 void visitVAStartInst(VAStartInst &
I) { VAHelper->visitVAStartInst(
I); }
3259 void visitVACopyInst(VACopyInst &
I) { VAHelper->visitVACopyInst(
I); }
3265 bool handleVectorStoreIntrinsic(IntrinsicInst &
I) {
3269 Value *Addr =
I.getArgOperand(0);
3270 Value *Shadow = getShadow(&
I, 1);
3271 Value *ShadowPtr, *OriginPtr;
3275 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3279 if (Opts.msan_check_access_address)
3280 insertCheckShadowOf(Addr, &
I);
3283 if (MS.TrackOrigins)
3292 bool handleVectorLoadIntrinsic(IntrinsicInst &
I) {
3296 Value *Addr =
I.getArgOperand(0);
3298 Type *ShadowTy = getShadowTy(&
I);
3299 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
3300 if (PropagateShadow) {
3304 std::tie(ShadowPtr, OriginPtr) =
3305 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
3309 setShadow(&
I, getCleanShadow(&
I));
3312 if (Opts.msan_check_access_address)
3313 insertCheckShadowOf(Addr, &
I);
3315 if (MS.TrackOrigins) {
3316 if (PropagateShadow)
3317 setOrigin(&
I, IRB.
CreateLoad(MS.OriginTy, OriginPtr));
3319 setOrigin(&
I, getCleanOrigin());
3339 [[maybe_unused]]
bool
3340 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &
I,
3341 unsigned int trailingFlags) {
3342 Type *RetTy =
I.getType();
3346 unsigned NumArgOperands =
I.arg_size();
3347 assert(NumArgOperands >= trailingFlags);
3348 for (
unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3349 Type *Ty =
I.getArgOperand(i)->getType();
3355 ShadowAndOriginCombiner SC(
this, IRB);
3356 for (
unsigned i = 0; i < NumArgOperands; ++i)
3357 SC.Add(
I.getArgOperand(i));
3374 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &
I) {
3375 unsigned NumArgOperands =
I.arg_size();
3376 if (NumArgOperands == 0)
3379 if (NumArgOperands == 2 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3380 I.getArgOperand(1)->getType()->isVectorTy() &&
3381 I.getType()->isVoidTy() && !
I.onlyReadsMemory()) {
3383 return handleVectorStoreIntrinsic(
I);
3386 if (NumArgOperands == 1 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3387 I.getType()->isVectorTy() &&
I.onlyReadsMemory()) {
3389 return handleVectorLoadIntrinsic(
I);
3392 if (
I.doesNotAccessMemory())
3393 if (maybeHandleSimpleNomemIntrinsic(
I, 0))
3401 bool maybeHandleUnknownIntrinsic(IntrinsicInst &
I) {
3402 if (maybeHandleUnknownIntrinsicUnlogged(
I)) {
3403 if (Opts.msan_dump_heuristic_instructions)
3404 dumpInst(
I,
"Heuristic");
3406 LLVM_DEBUG(
dbgs() <<
"UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " <<
I
3413 void handleInvariantGroup(IntrinsicInst &
I) {
3414 setShadow(&
I, getShadow(&
I, 0));
3415 setOrigin(&
I, getOrigin(&
I, 0));
3418 void handleLifetimeStart(IntrinsicInst &
I) {
3423 LifetimeStartList.push_back(std::make_pair(&
I, AI));
3426 void handleBswap(IntrinsicInst &
I) {
3429 Type *OpType =
Op->getType();
3432 setOrigin(&
I, getOrigin(
Op));
3453 void handleCountLeadingTrailingZeros(IntrinsicInst &
I) {
3455 Value *Src =
I.getArgOperand(0);
3456 Value *SrcShadow = getShadow(Src);
3460 I.getType(),
I.getIntrinsicID(), {Src, False});
3462 I.getType(),
I.getIntrinsicID(), {SrcShadow, False});
3465 ConcreteZerosCount, ShadowZerosCount,
"_mscz_cmp_zeros");
3467 Value *NotAllZeroShadow =
3469 Value *OutputShadow =
3470 IRB.
CreateAnd(CompareConcreteZeros, NotAllZeroShadow,
"_mscz_main");
3476 OutputShadow = IRB.
CreateOr(OutputShadow, BoolZeroPoison,
"_mscz_bs");
3479 OutputShadow = IRB.
CreateSExt(OutputShadow, getShadowTy(Src),
"_mscz_os");
3481 setShadow(&
I, OutputShadow);
3482 setOriginForNaryOp(
I);
3491 FixedVectorType *maybeShrinkVectorShadowType(
Value *Src, IntrinsicInst &
I) {
3511 Value *maybeExtendVectorShadowWithZeros(
Value *Shadow, IntrinsicInst &
I) {
3516 Value *FullShadow = getCleanShadow(&
I);
3517 unsigned ShadowNumElems =
3519 unsigned FullShadowNumElems =
3522 assert((ShadowNumElems == FullShadowNumElems) ||
3523 (ShadowNumElems * 2 == FullShadowNumElems));
3525 if (ShadowNumElems == FullShadowNumElems) {
3526 FullShadow = Shadow;
3530 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3555 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &
I,
3556 bool HasRoundingMode) {
3557 if (HasRoundingMode) {
3565 Value *Src =
I.getArgOperand(0);
3566 assert(Src->getType()->isVectorTy());
3570 VectorType *ShadowType = maybeShrinkVectorShadowType(Src,
I);
3573 Value *S0 = getShadow(&
I, 0);
3585 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow,
I);
3587 setShadow(&
I, FullShadow);
3588 setOriginForNaryOp(
I);
3609 void handleSSEVectorConvertIntrinsic(IntrinsicInst &
I,
int NumUsedElements,
3610 bool HasRoundingMode =
false) {
3612 Value *CopyOp, *ConvertOp;
3614 assert((!HasRoundingMode ||
3616 "Invalid rounding mode");
3618 switch (
I.arg_size() - HasRoundingMode) {
3620 CopyOp =
I.getArgOperand(0);
3621 ConvertOp =
I.getArgOperand(1);
3624 ConvertOp =
I.getArgOperand(0);
3638 Value *ConvertShadow = getShadow(ConvertOp);
3639 Value *AggShadow =
nullptr;
3642 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
3643 for (
int i = 1; i < NumUsedElements; ++i) {
3645 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
3646 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
3649 AggShadow = ConvertShadow;
3652 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &
I);
3659 Value *ResultShadow = getShadow(CopyOp);
3661 for (
int i = 0; i < NumUsedElements; ++i) {
3663 ResultShadow, ConstantInt::getNullValue(EltTy),
3666 setShadow(&
I, ResultShadow);
3667 setOrigin(&
I, getOrigin(CopyOp));
3669 setShadow(&
I, getCleanShadow(&
I));
3670 setOrigin(&
I, getCleanOrigin());
3678 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
3681 return CreateShadowCast(IRB, S2,
T,
true);
3689 return CreateShadowCast(IRB, S2,
T,
true);
3706 void handleVectorShiftIntrinsic(IntrinsicInst &
I,
bool Variable) {
3712 Value *S2 = getShadow(&
I, 1);
3714 : Lower64ShadowExtend(IRB, S2, getShadowTy(&
I));
3716 Value *V2 =
I.getOperand(1);
3718 {IRB.CreateBitCast(S1, V1->getType()), V2});
3720 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3721 setOriginForNaryOp(
I);
3726 Type *getMMXVectorTy(
unsigned EltSizeInBits,
3727 unsigned X86_MMXSizeInBits = 64) {
3728 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3729 "Illegal MMX vector element size");
3731 X86_MMXSizeInBits / EltSizeInBits);
3738 case Intrinsic::x86_sse2_packsswb_128:
3739 case Intrinsic::x86_sse2_packuswb_128:
3740 return Intrinsic::x86_sse2_packsswb_128;
3742 case Intrinsic::x86_sse2_packssdw_128:
3743 case Intrinsic::x86_sse41_packusdw:
3744 return Intrinsic::x86_sse2_packssdw_128;
3746 case Intrinsic::x86_avx2_packsswb:
3747 case Intrinsic::x86_avx2_packuswb:
3748 return Intrinsic::x86_avx2_packsswb;
3750 case Intrinsic::x86_avx2_packssdw:
3751 case Intrinsic::x86_avx2_packusdw:
3752 return Intrinsic::x86_avx2_packssdw;
3754 case Intrinsic::x86_mmx_packsswb:
3755 case Intrinsic::x86_mmx_packuswb:
3756 return Intrinsic::x86_mmx_packsswb;
3758 case Intrinsic::x86_mmx_packssdw:
3759 return Intrinsic::x86_mmx_packssdw;
3761 case Intrinsic::x86_avx512_packssdw_512:
3762 case Intrinsic::x86_avx512_packusdw_512:
3763 return Intrinsic::x86_avx512_packssdw_512;
3765 case Intrinsic::x86_avx512_packsswb_512:
3766 case Intrinsic::x86_avx512_packuswb_512:
3767 return Intrinsic::x86_avx512_packsswb_512;
3783 void handleVectorPackIntrinsic(IntrinsicInst &
I,
3784 unsigned MMXEltSizeInBits = 0) {
3788 Value *S2 = getShadow(&
I, 1);
3789 assert(
S1->getType()->isVectorTy());
3795 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) :
S1->
getType();
3796 if (MMXEltSizeInBits) {
3804 if (MMXEltSizeInBits) {
3810 {S1_ext, S2_ext},
nullptr,
3811 "_msprop_vector_pack");
3812 if (MMXEltSizeInBits)
3815 setOriginForNaryOp(
I);
3819 Constant *createDppMask(
unsigned Width,
unsigned Mask) {
3820 SmallVector<Constant *, 4>
R(Width);
3832 const unsigned Width =
3839 Value *DstMaskV = createDppMask(Width, DstMask);
3856 void handleDppIntrinsic(IntrinsicInst &
I) {
3859 Value *S0 = getShadow(&
I, 0);
3863 const unsigned Width =
3865 assert(Width == 2 || Width == 4 || Width == 8);
3868 const unsigned SrcMask =
Mask >> 4;
3869 const unsigned DstMask =
Mask & 0xf;
3872 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3877 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3884 setOriginForNaryOp(
I);
3888 C = CreateAppToShadowCast(IRB,
C);
3897 void handleBlendvIntrinsic(IntrinsicInst &
I) {
3902 Value *Sc = getShadow(&
I, 2);
3903 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
3908 C = convertBlendvToSelectMask(IRB,
C);
3909 Sc = convertBlendvToSelectMask(IRB, Sc);
3915 handleSelectLikeInst(
I,
C,
T,
F);
3919 void handleVectorSadIntrinsic(IntrinsicInst &
I,
bool IsMMX =
false) {
3920 const unsigned SignificantBitsPerResultElement = 16;
3922 unsigned ZeroBitsPerResultElement =
3926 auto *Shadow0 = getShadow(&
I, 0);
3927 auto *Shadow1 = getShadow(&
I, 1);
3932 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
3935 setOriginForNaryOp(
I);
3959 void handleVectorDotProductIntrinsic(IntrinsicInst &
I,
3960 unsigned ReductionFactor,
3962 unsigned EltSizeInBits,
3966 [[maybe_unused]] FixedVectorType *
ReturnType =
3971 Value *Va =
nullptr;
3972 Value *Vb =
nullptr;
3973 Value *Sa =
nullptr;
3974 Value *Sb =
nullptr;
3976 assert(
I.arg_size() == 2 ||
I.arg_size() == 3);
3977 if (
I.arg_size() == 2) {
3980 Va =
I.getOperand(0);
3981 Vb =
I.getOperand(1);
3983 Sa = getShadow(&
I, 0);
3984 Sb = getShadow(&
I, 1);
3985 }
else if (
I.arg_size() == 3) {
3987 Va =
I.getOperand(1);
3988 Vb =
I.getOperand(2);
3990 Sa = getShadow(&
I, 1);
3991 Sb = getShadow(&
I, 2);
4008 Sa, getPclmulMask(Width, Lanes ==
kOddLanes));
4010 Sb, getPclmulMask(Width, Lanes ==
kOddLanes));
4020 if (
I.arg_size() == 3) {
4021 [[maybe_unused]]
auto *AccumulatorType =
4023 assert(AccumulatorType == ReturnType);
4026 FixedVectorType *ImplicitReturnType =
4029 if (EltSizeInBits) {
4031 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4043 ReturnType->getNumElements() * ReductionFactor);
4060 VaInt = CreateAppToShadowCast(IRB, Va);
4061 VbInt = CreateAppToShadowCast(IRB, Vb);
4068 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4090 ImplicitReturnType);
4095 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&
I));
4098 if (
I.arg_size() == 3)
4099 OutShadow = IRB.
CreateOr(OutShadow, getShadow(&
I, 0));
4101 setShadow(&
I, OutShadow);
4102 setOriginForNaryOp(
I);
4119 void handleVectorComparePackedIntrinsic(IntrinsicInst &
I,
4120 bool PredicateAsOperand) {
4121 if (PredicateAsOperand) {
4123 assert(
I.paramHasAttr(2, Attribute::ImmArg));
4131 Type *ResTy = getShadowTy(&
I);
4132 auto *Shadow0 = getShadow(&
I, 0);
4133 auto *Shadow1 = getShadow(&
I, 1);
4138 setOriginForNaryOp(
I);
4144 void handleVectorCompareScalarIntrinsic(IntrinsicInst &
I) {
4146 auto *Shadow0 = getShadow(&
I, 0);
4147 auto *Shadow1 = getShadow(&
I, 1);
4149 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&
I));
4151 setOriginForNaryOp(
I);
4160 void handleVectorReduceIntrinsic(IntrinsicInst &
I,
bool AllowShadowCast) {
4165 if (AllowShadowCast)
4166 S = CreateShadowCast(IRB, S, getShadowTy(&
I));
4170 setOriginForNaryOp(
I);
4180 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &
I) {
4184 Value *Shadow0 = getShadow(&
I, 0);
4190 setOriginForNaryOp(
I);
4210 void handleVectorPartialReduceAddIntrinsic(IntrinsicInst &
I) {
4215 [[maybe_unused]]
Value *Addends =
I.getArgOperand(1);
4229 Value *SAcc = getShadow(&
I, 0);
4230 Value *SAdd = getShadow(&
I, 1);
4250 SAcc->
getType(), Intrinsic::vector_partial_reduce_add, {SAcc, SAdd});
4255 setShadow(&
I, SOutput);
4256 setOriginForNaryOp(
I);
4262 void handleVectorReduceOrIntrinsic(IntrinsicInst &
I) {
4266 Value *OperandShadow = getShadow(&
I, 0);
4268 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
4276 setOrigin(&
I, getOrigin(&
I, 0));
4282 void handleVectorReduceAndIntrinsic(IntrinsicInst &
I) {
4286 Value *OperandShadow = getShadow(&
I, 0);
4287 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
4295 setOrigin(&
I, getOrigin(&
I, 0));
4298 void handleStmxcsr(IntrinsicInst &
I) {
4300 Value *Addr =
I.getArgOperand(0);
4303 getShadowOriginPtr(Addr, IRB, Ty,
Align(1),
true).first;
4307 if (Opts.msan_check_access_address)
4308 insertCheckShadowOf(Addr, &
I);
4311 void handleLdmxcsr(IntrinsicInst &
I) {
4316 Value *Addr =
I.getArgOperand(0);
4319 Value *ShadowPtr, *OriginPtr;
4320 std::tie(ShadowPtr, OriginPtr) =
4321 getShadowOriginPtr(Addr, IRB, Ty, Alignment,
false);
4323 if (Opts.msan_check_access_address)
4324 insertCheckShadowOf(Addr, &
I);
4327 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
4329 insertCheckShadow(Shadow, Origin, &
I);
4332 void handleMaskedExpandLoad(IntrinsicInst &
I) {
4334 Value *Ptr =
I.getArgOperand(0);
4335 MaybeAlign
Align =
I.getParamAlign(0);
4337 Value *PassThru =
I.getArgOperand(2);
4339 if (Opts.msan_check_access_address) {
4340 insertCheckShadowOf(Ptr, &
I);
4341 insertCheckShadowOf(Mask, &
I);
4344 if (!PropagateShadow) {
4345 setShadow(&
I, getCleanShadow(&
I));
4346 setOrigin(&
I, getCleanOrigin());
4350 Type *ShadowTy = getShadowTy(&
I);
4352 auto [ShadowPtr, OriginPtr] =
4353 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
false);
4357 getShadow(PassThru),
"_msmaskedexpload");
4359 setShadow(&
I, Shadow);
4362 setOrigin(&
I, getCleanOrigin());
4365 void handleMaskedCompressStore(IntrinsicInst &
I) {
4368 Value *Ptr =
I.getArgOperand(1);
4369 MaybeAlign
Align =
I.getParamAlign(1);
4372 if (Opts.msan_check_access_address) {
4373 insertCheckShadowOf(Ptr, &
I);
4374 insertCheckShadowOf(Mask, &
I);
4378 Type *ElementShadowTy =
4380 auto [ShadowPtr, OriginPtrs] =
4381 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
true);
4388 void handleMaskedGather(IntrinsicInst &
I) {
4390 Value *Ptrs =
I.getArgOperand(0);
4393 Value *PassThru =
I.getArgOperand(2);
4395 Type *PtrsShadowTy = getShadowTy(Ptrs);
4396 if (Opts.msan_check_access_address) {
4397 insertCheckShadowOf(Mask, &
I);
4401 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4404 if (!PropagateShadow) {
4405 setShadow(&
I, getCleanShadow(&
I));
4406 setOrigin(&
I, getCleanOrigin());
4410 Type *ShadowTy = getShadowTy(&
I);
4412 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4413 Ptrs, IRB, ElementShadowTy, Alignment,
false);
4417 getShadow(PassThru),
"_msmaskedgather");
4419 setShadow(&
I, Shadow);
4422 setOrigin(&
I, getCleanOrigin());
4425 void handleMaskedScatter(IntrinsicInst &
I) {
4428 Value *Ptrs =
I.getArgOperand(1);
4432 Type *PtrsShadowTy = getShadowTy(Ptrs);
4433 if (Opts.msan_check_access_address) {
4434 insertCheckShadowOf(Mask, &
I);
4438 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4442 Type *ElementShadowTy =
4444 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4445 Ptrs, IRB, ElementShadowTy, Alignment,
true);
4456 void handleMaskedStore(IntrinsicInst &
I) {
4458 Value *
V =
I.getArgOperand(0);
4459 Value *Ptr =
I.getArgOperand(1);
4462 Value *Shadow = getShadow(V);
4464 if (Opts.msan_check_access_address) {
4465 insertCheckShadowOf(Ptr, &
I);
4466 insertCheckShadowOf(Mask, &
I);
4471 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4472 Ptr, IRB, Shadow->
getType(), Alignment,
true);
4476 if (!MS.TrackOrigins)
4479 auto &
DL =
F.getDataLayout();
4480 paintOrigin(IRB, getOrigin(V), OriginPtr,
4489 void handleMaskedLoad(IntrinsicInst &
I) {
4491 Value *Ptr =
I.getArgOperand(0);
4494 Value *PassThru =
I.getArgOperand(2);
4496 if (Opts.msan_check_access_address) {
4497 insertCheckShadowOf(Ptr, &
I);
4498 insertCheckShadowOf(Mask, &
I);
4501 if (!PropagateShadow) {
4502 setShadow(&
I, getCleanShadow(&
I));
4503 setOrigin(&
I, getCleanOrigin());
4507 Type *ShadowTy = getShadowTy(&
I);
4508 Value *ShadowPtr, *OriginPtr;
4509 std::tie(ShadowPtr, OriginPtr) =
4510 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment,
false);
4512 getShadow(PassThru),
"_msmaskedld"));
4514 if (!MS.TrackOrigins)
4521 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
4526 setOrigin(&
I, Origin);
4536 void handleMaskedIntegerDivRem(IntrinsicInst &
I) {
4539 Value *Dividend =
I.getArgOperand(0);
4540 Value *Divisor =
I.getArgOperand(1);
4543 insertCheckShadowOf(Mask, &
I);
4546 Mask, getShadow(Divisor), getCleanShadow(Divisor),
"_msmaskeddivisor");
4547 insertCheckShadow(MaskedDivisorShadow, getOrigin(Divisor), &
I);
4549 if (!PropagateShadow) {
4550 setShadow(&
I, getCleanShadow(&
I));
4551 setOrigin(&
I, getCleanOrigin());
4556 getPoisonedShadow(&
I),
"_msmaskeddiv"));
4557 setOrigin(&
I, getOrigin(Dividend));
4573 void handleAVXMaskedStore(IntrinsicInst &
I) {
4578 Value *Dst =
I.getArgOperand(0);
4579 assert(Dst->getType()->isPointerTy() &&
"Destination is not a pointer!");
4584 Value *Src =
I.getArgOperand(2);
4589 Value *SrcShadow = getShadow(Src);
4591 if (Opts.msan_check_access_address) {
4592 insertCheckShadowOf(Dst, &
I);
4593 insertCheckShadowOf(Mask, &
I);
4596 Value *DstShadowPtr;
4597 Value *DstOriginPtr;
4598 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4599 Dst, IRB, SrcShadow->
getType(), Alignment,
true);
4601 SmallVector<Value *, 2> ShadowArgs;
4602 ShadowArgs.
append(1, DstShadowPtr);
4603 ShadowArgs.
append(1, Mask);
4611 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
4614 if (!MS.TrackOrigins)
4618 auto &
DL =
F.getDataLayout();
4619 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4620 DL.getTypeStoreSize(SrcShadow->
getType()),
4639 void handleAVXMaskedLoad(IntrinsicInst &
I) {
4644 Value *Src =
I.getArgOperand(0);
4645 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
4652 if (Opts.msan_check_access_address) {
4653 insertCheckShadowOf(Mask, &
I);
4656 Type *SrcShadowTy = getShadowTy(Src);
4657 Value *SrcShadowPtr, *SrcOriginPtr;
4658 std::tie(SrcShadowPtr, SrcOriginPtr) =
4659 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment,
false);
4661 SmallVector<Value *, 2> ShadowArgs;
4662 ShadowArgs.
append(1, SrcShadowPtr);
4663 ShadowArgs.
append(1, Mask);
4666 I.getType(),
I.getIntrinsicID(), ShadowArgs);
4672 if (!MS.TrackOrigins)
4679 setOrigin(&
I, PtrSrcOrigin);
4688 assert(isFixedIntVector(Idx));
4689 auto IdxVectorSize =
4697 auto *IdxShadow = getShadow(Idx);
4702 insertCheckShadow(Truncated, getOrigin(Idx),
I);
4707 void handleAVXVpermilvar(IntrinsicInst &
I) {
4709 Value *Shadow = getShadow(&
I, 0);
4710 maskedCheckAVXIndexShadow(IRB,
I.getArgOperand(1), &
I);
4714 Shadow = IRB.
CreateBitCast(Shadow,
I.getArgOperand(0)->getType());
4716 I.getType(),
I.getIntrinsicID(), {Shadow, I.getArgOperand(1)});
4719 setOriginForNaryOp(
I);
4724 void handleAVXVpermi2var(IntrinsicInst &
I) {
4729 [[maybe_unused]]
auto ArgVectorSize =
4732 ->getNumElements() == ArgVectorSize);
4734 ->getNumElements() == ArgVectorSize);
4735 assert(
I.getArgOperand(0)->getType() ==
I.getArgOperand(2)->getType());
4736 assert(
I.getType() ==
I.getArgOperand(0)->getType());
4737 assert(
I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4739 Value *AShadow = getShadow(&
I, 0);
4741 Value *BShadow = getShadow(&
I, 2);
4743 maskedCheckAVXIndexShadow(IRB, Idx, &
I);
4747 AShadow = IRB.
CreateBitCast(AShadow,
I.getArgOperand(0)->getType());
4748 BShadow = IRB.
CreateBitCast(BShadow,
I.getArgOperand(2)->getType());
4750 I.getType(),
I.getIntrinsicID(), {AShadow, Idx, BShadow});
4752 setOriginForNaryOp(
I);
4755 [[maybe_unused]]
static bool isFixedIntVectorTy(
const Type *
T) {
4759 [[maybe_unused]]
static bool isFixedFPVectorTy(
const Type *
T) {
4763 [[maybe_unused]]
static bool isFixedIntVector(
const Value *V) {
4764 return isFixedIntVectorTy(
V->getType());
4767 [[maybe_unused]]
static bool isFixedFPVector(
const Value *V) {
4768 return isFixedFPVectorTy(
V->getType());
4790 void handleAVX512VectorConvertFPToInt(IntrinsicInst &
I,
bool LastMask) {
4795 Value *WriteThrough;
4799 WriteThrough =
I.getOperand(2);
4800 Mask =
I.getOperand(3);
4803 WriteThrough =
I.getOperand(1);
4804 Mask =
I.getOperand(2);
4809 assert(isFixedIntVector(WriteThrough));
4811 unsigned ANumElements =
4813 [[maybe_unused]]
unsigned WriteThruNumElements =
4815 assert(ANumElements == WriteThruNumElements ||
4816 ANumElements * 2 == WriteThruNumElements);
4819 unsigned MaskNumElements =
Mask->getType()->getScalarSizeInBits();
4820 assert(ANumElements == MaskNumElements ||
4821 ANumElements * 2 == MaskNumElements);
4823 assert(WriteThruNumElements == MaskNumElements);
4827 insertCheckShadowOf(Mask, &
I);
4837 Value *AShadow = getShadow(
A);
4838 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
4840 if (ANumElements * 2 == MaskNumElements) {
4852 "_ms_mask_bitcast");
4862 getShadowTy(&
I),
"_ms_a_shadow");
4864 Value *WriteThroughShadow = getShadow(WriteThrough);
4866 "_ms_writethru_select");
4868 setShadow(&
I, Shadow);
4869 setOriginForNaryOp(
I);
4872 static SmallVector<int, 8> getPclmulMask(
unsigned Width,
bool OddElements) {
4873 SmallVector<int, 8>
Mask;
4874 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
4888 void handlePclmulIntrinsic(IntrinsicInst &
I) {
4893 "pclmul 3rd operand must be a constant");
4896 getPclmulMask(Width,
Imm & 0x01));
4898 getPclmulMask(Width,
Imm & 0x10));
4899 ShadowAndOriginCombiner SOC(
this, IRB);
4900 SOC.Add(Shuf0, getOrigin(&
I, 0));
4901 SOC.Add(Shuf1, getOrigin(&
I, 1));
4906 void handleUnarySdSsIntrinsic(IntrinsicInst &
I) {
4911 Value *Second = getShadow(&
I, 1);
4913 SmallVector<int, 16>
Mask;
4914 Mask.push_back(Width);
4915 for (
unsigned i = 1; i < Width; i++)
4919 setShadow(&
I, Shadow);
4920 setOriginForNaryOp(
I);
4923 void handleVtestIntrinsic(IntrinsicInst &
I) {
4925 Value *Shadow0 = getShadow(&
I, 0);
4926 Value *Shadow1 = getShadow(&
I, 1);
4932 setShadow(&
I, Shadow);
4933 setOriginForNaryOp(
I);
4936 void handleBinarySdSsIntrinsic(IntrinsicInst &
I) {
4941 Value *Second = getShadow(&
I, 1);
4944 SmallVector<int, 16>
Mask;
4945 Mask.push_back(Width);
4946 for (
unsigned i = 1; i < Width; i++)
4950 setShadow(&
I, Shadow);
4951 setOriginForNaryOp(
I);
4957 void handleRoundPdPsIntrinsic(IntrinsicInst &
I) {
4958 assert(
I.getArgOperand(0)->getType() ==
I.getType());
4963 ShadowAndOriginCombiner SC(
this, IRB);
4964 SC.Add(
I.getArgOperand(0));
4972 void handleAbsIntrinsic(IntrinsicInst &
I) {
4974 Value *Src =
I.getArgOperand(0);
4975 Value *IsIntMinPoison =
I.getArgOperand(1);
4977 assert(
I.getType()->isIntOrIntVectorTy());
4979 assert(Src->getType() ==
I.getType());
4985 Value *SrcShadow = getShadow(Src);
4989 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
4992 Value *PoisonedShadow = getPoisonedShadow(Src);
4993 Value *PoisonedIfIntMinShadow =
4996 IRB.
CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
4998 setShadow(&
I, Shadow);
4999 setOrigin(&
I, getOrigin(&
I, 0));
5002 void handleIsFpClass(IntrinsicInst &
I) {
5004 Value *Shadow = getShadow(&
I, 0);
5005 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5006 setOrigin(&
I, getOrigin(&
I, 0));
5009 void handleArithmeticWithOverflow(IntrinsicInst &
I) {
5011 Value *Shadow0 = getShadow(&
I, 0);
5012 Value *Shadow1 = getShadow(&
I, 1);
5015 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5021 setShadow(&
I, Shadow);
5022 setOriginForNaryOp(
I);
5025 void handleModfOrSincos(IntrinsicInst &
I) {
5027 Value *ArgShadow = getShadow(&
I, 0);
5031 setShadow(&
I, Shadow);
5032 setOrigin(&
I, getOrigin(&
I, 0));
5038 Value *Shadow = getShadow(V);
5060 void handleAVX512VectorDownConvert(IntrinsicInst &
I) {
5065 Value *WriteThrough =
I.getOperand(1);
5069 assert(isFixedIntVector(WriteThrough));
5071 unsigned ANumElements =
5073 unsigned OutputNumElements =
5075 assert(ANumElements == OutputNumElements ||
5076 ANumElements * 2 == OutputNumElements);
5086 insertCheckShadowOf(Mask, &
I);
5089 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5090 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5091 assert(
Mask->getType()->getScalarSizeInBits() == ANumElements);
5102 if (ANumElements != OutputNumElements) {
5104 Mask = IRB.
CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5111 Value *AShadow = getShadow(
A);
5115 VectorType *ShadowType = maybeShrinkVectorShadowType(
A,
I);
5125 AShadow = IRB.
CreateTrunc(AShadow, ShadowType,
"_ms_trunc_shadow");
5126 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
5128 Value *WriteThroughShadow = getShadow(WriteThrough);
5131 setShadow(&
I, Shadow);
5132 setOriginForNaryOp(
I);
5166 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &
I,
5167 SmallVector<unsigned, 4> DataIndices,
5168 unsigned WriteThruIndex,
5169 unsigned MaskIndex) {
5172 unsigned NumArgs =
I.arg_size();
5174 assert(WriteThruIndex < NumArgs);
5175 assert(MaskIndex < NumArgs);
5176 assert(WriteThruIndex != MaskIndex);
5177 Value *WriteThru =
I.getOperand(WriteThruIndex);
5179 unsigned OutputNumElements =
5184 bool isData[16] = {
false};
5186 for (
unsigned i : DataIndices) {
5188 assert(i != WriteThruIndex);
5195 [[maybe_unused]]
unsigned ANumElements =
5197 assert(ANumElements == OutputNumElements);
5202 assert(isFixedFPVector(WriteThru));
5204 for (
unsigned i = 0; i < NumArgs; ++i) {
5205 if (!isData[i] && i != WriteThruIndex) {
5208 assert(
I.getOperand(i)->getType()->isIntegerTy());
5209 insertCheckShadowOf(
I.getOperand(i), &
I);
5214 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5215 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5216 assert(
Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5223 Value *DataShadow =
nullptr;
5224 for (
unsigned i : DataIndices) {
5227 DataShadow = IRB.
CreateOr(DataShadow, getShadow(
A));
5229 DataShadow = getShadow(
A);
5237 Value *WriteThruShadow = getShadow(WriteThru);
5240 setShadow(&
I, Shadow);
5242 setOriginForNaryOp(
I);
5252 void handleAVX512FPClass(IntrinsicInst &
I) {
5257 Value *Input =
I.getOperand(0);
5258 assert(isFixedFPVector(Input));
5261 Value *Classifiers =
I.getOperand(1);
5265 assert(isFixedIntVectorTy(
I.getType()));
5271 Value *OutputShadow;
5276 OutputShadow = getCleanShadow(OutputType);
5282 OutputShadow = IRB.
CreateICmpNE(getShadow(Input), getCleanShadow(Input));
5284 setShadow(&
I, OutputShadow);
5286 setOriginForNaryOp(
I);
5296 void visitGenericScalarHalfwordInst(IntrinsicInst &
I) {
5302 Value *WriteThrough =
I.getOperand(2);
5309 insertCheckShadowOf(Mask, &
I);
5313 unsigned NumElements =
5315 assert(NumElements == 8);
5316 assert(
A->getType() ==
B->getType());
5318 assert(
Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5321 Value *ALowerShadow = extractLowerShadow(IRB,
A);
5322 Value *BLowerShadow = extractLowerShadow(IRB,
B);
5324 Value *ABLowerShadow = IRB.
CreateOr(ALowerShadow, BLowerShadow);
5326 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5333 Value *AShadow = getShadow(
A);
5334 Value *DstLowerShadow =
5335 IRB.
CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5337 AShadow, DstLowerShadow, ConstantInt::get(IRB.
getInt32Ty(), 0),
5340 setShadow(&
I, DstShadow);
5341 setOriginForNaryOp(
I);
5371 void handleAVXGF2P8Affine(IntrinsicInst &
I) {
5382 ->getScalarSizeInBits() == 8);
5384 assert(
A->getType() ==
X->getType());
5386 assert(
B->getType()->isIntegerTy());
5387 assert(
B->getType()->getScalarSizeInBits() == 8);
5389 assert(
I.getType() ==
A->getType());
5391 Value *AShadow = getShadow(
A);
5392 Value *XShadow = getShadow(
X);
5393 Value *BZeroShadow = getCleanShadow(
B);
5396 I.getType(),
I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5398 {X, AShadow, BZeroShadow});
5400 {XShadow, A, BZeroShadow});
5403 Value *BShadow = getShadow(
B);
5404 Value *BBroadcastShadow = getCleanShadow(AShadow);
5409 for (
unsigned i = 0; i < NumElements; i++)
5413 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5414 setOriginForNaryOp(
I);
5428 void handleNEONVectorLoad(IntrinsicInst &
I,
bool WithLane) {
5429 unsigned int numArgs =
I.arg_size();
5432 assert(
I.getType()->isStructTy());
5442 assert(4 <= numArgs && numArgs <= 6);
5456 for (
unsigned int i = 0; i < numArgs - 2; i++)
5457 ShadowArgs.
push_back(getShadow(
I.getArgOperand(i)));
5460 Value *LaneNumber =
I.getArgOperand(numArgs - 2);
5464 insertCheckShadowOf(LaneNumber, &
I);
5467 Value *Src =
I.getArgOperand(numArgs - 1);
5468 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
5470 Type *SrcShadowTy = getShadowTy(Src);
5471 auto [SrcShadowPtr, SrcOriginPtr] =
5472 getShadowOriginPtr(Src, IRB, SrcShadowTy,
Align(1),
false);
5479 getShadowTy(&
I),
I.getIntrinsicID(), ShadowArgs);
5482 if (!MS.TrackOrigins)
5486 setOrigin(&
I, PtrSrcOrigin);
5503 void handleNEONVectorStoreIntrinsic(IntrinsicInst &
I,
bool useLane) {
5507 int numArgOperands =
I.arg_size();
5510 assert(numArgOperands >= 1);
5511 Value *Addr =
I.getArgOperand(numArgOperands - 1);
5513 int skipTrailingOperands = 1;
5515 if (Opts.msan_check_access_address)
5516 insertCheckShadowOf(Addr, &
I);
5520 skipTrailingOperands++;
5521 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
5523 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5526 SmallVector<Value *, 8> ShadowArgs;
5528 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5530 Value *Shadow = getShadow(&
I, i);
5531 ShadowArgs.
append(1, Shadow);
5548 (numArgOperands - skipTrailingOperands));
5549 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5553 I.getArgOperand(numArgOperands - skipTrailingOperands));
5555 Value *OutputShadowPtr, *OutputOriginPtr;
5557 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5558 Addr, IRB, OutputShadowTy,
Align(1),
true);
5559 ShadowArgs.
append(1, OutputShadowPtr);
5562 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
5565 if (MS.TrackOrigins) {
5573 OriginCombiner OC(
this, IRB);
5574 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5575 OC.Add(
I.getArgOperand(i));
5577 const DataLayout &
DL =
F.getDataLayout();
5578 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
5611 void handleNEONMatrixMultiply(IntrinsicInst &
I) {
5615 Value *
R =
I.getArgOperand(0);
5616 Value *
A =
I.getArgOperand(1);
5617 Value *
B =
I.getArgOperand(2);
5619 assert(
I.getType() ==
R->getType());
5644 Value *ShadowR = getShadow(&
I, 0);
5645 Value *ShadowA = getShadow(&
I, 1);
5646 Value *ShadowB = getShadow(&
I, 2);
5664 {getCleanShadow(RTy), ShadowA, ShadowB});
5690 {RZeros, ShadowA, ShadowB});
5704 ShadowR = IRB.
CreateICmpNE(ShadowR, getCleanShadow(RTy));
5705 ShadowR = IRB.
CreateOr(ShadowAB, ShadowR);
5707 setShadow(&
I, IRB.
CreateSExt(ShadowR, getShadowTy(RTy)));
5709 setOriginForNaryOp(
I);
5749 void handleIntrinsicByApplyingToShadow(IntrinsicInst &
I,
5751 unsigned int trailingVerbatimArgs,
5752 bool forceIntegerIntrinsic) {
5755 assert(trailingVerbatimArgs <
I.arg_size());
5757 SmallVector<Value *, 8> ShadowArgs;
5759 for (
unsigned int i = 0; i <
I.arg_size() - trailingVerbatimArgs; i++) {
5760 Value *Shadow = getShadow(&
I, i);
5762 if (forceIntegerIntrinsic)
5769 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5771 Value *Arg =
I.getArgOperand(i);
5772 if (forceIntegerIntrinsic)
5777 Value *CombinedShadow;
5778 if (forceIntegerIntrinsic) {
5788 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5791 CreateShadowCast(IRB, getShadow(&
I, i), CombinedShadow->
getType());
5792 CombinedShadow = IRB.
CreateOr(Shadow, CombinedShadow,
"_msprop");
5795 setShadow(&
I, CombinedShadow);
5797 setOriginForNaryOp(
I);
5803 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &
I) {
5841 void handleNEONDotProductLaneIntrinsic(IntrinsicInst &
I,
5842 unsigned ReductionFactor) {
5846 [[maybe_unused]]
Value *VAcc =
I.getOperand(0);
5847 [[maybe_unused]]
Value *Va =
I.getOperand(1);
5848 [[maybe_unused]]
Value *Vb =
I.getOperand(2);
5849 Value *Lane =
I.getOperand(3);
5856 I.getType()->getPrimitiveSizeInBits());
5865 I.getType()->getPrimitiveSizeInBits());
5871 Value *SAcc = getShadow(&
I, 0);
5872 Value *Sa = getShadow(&
I, 1);
5873 Value *Sb = getShadow(&
I, 2);
5880 Sb, FixedVectorType::getWithSizeAndScalar(
5896 SOutput = IRB.
CreateSelect(SbClean, SOutput, getPoisonedShadow(SOutput));
5898 setShadow(&
I, SOutput);
5899 setOriginForNaryOp(
I);
5902 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &
I) {
5903 switch (
I.getIntrinsicID()) {
5904 case Intrinsic::uadd_with_overflow:
5905 case Intrinsic::sadd_with_overflow:
5906 case Intrinsic::usub_with_overflow:
5907 case Intrinsic::ssub_with_overflow:
5908 case Intrinsic::umul_with_overflow:
5909 case Intrinsic::smul_with_overflow:
5910 handleArithmeticWithOverflow(
I);
5912 case Intrinsic::modf:
5913 case Intrinsic::sincos:
5914 case Intrinsic::sincospi:
5915 handleModfOrSincos(
I);
5917 case Intrinsic::abs:
5918 handleAbsIntrinsic(
I);
5920 case Intrinsic::bitreverse:
5921 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
5925 case Intrinsic::is_fpclass:
5928 case Intrinsic::lifetime_start:
5929 handleLifetimeStart(
I);
5931 case Intrinsic::launder_invariant_group:
5932 handleInvariantGroup(
I);
5934 case Intrinsic::bswap:
5937 case Intrinsic::ctlz:
5938 case Intrinsic::cttz:
5939 handleCountLeadingTrailingZeros(
I);
5941 case Intrinsic::masked_compressstore:
5942 handleMaskedCompressStore(
I);
5944 case Intrinsic::masked_expandload:
5945 handleMaskedExpandLoad(
I);
5947 case Intrinsic::masked_gather:
5948 handleMaskedGather(
I);
5950 case Intrinsic::masked_scatter:
5951 handleMaskedScatter(
I);
5953 case Intrinsic::masked_store:
5954 handleMaskedStore(
I);
5956 case Intrinsic::masked_load:
5957 handleMaskedLoad(
I);
5959 case Intrinsic::masked_udiv:
5960 case Intrinsic::masked_sdiv:
5961 case Intrinsic::masked_urem:
5962 case Intrinsic::masked_srem:
5963 handleMaskedIntegerDivRem(
I);
5965 case Intrinsic::vector_reduce_and:
5966 handleVectorReduceAndIntrinsic(
I);
5968 case Intrinsic::vector_reduce_or:
5969 handleVectorReduceOrIntrinsic(
I);
5972 case Intrinsic::vector_reduce_add:
5973 case Intrinsic::vector_reduce_xor:
5974 case Intrinsic::vector_reduce_mul:
5977 case Intrinsic::vector_reduce_smax:
5978 case Intrinsic::vector_reduce_smin:
5979 case Intrinsic::vector_reduce_umax:
5980 case Intrinsic::vector_reduce_umin:
5983 case Intrinsic::vector_reduce_fmax:
5984 case Intrinsic::vector_reduce_fmin:
5985 handleVectorReduceIntrinsic(
I,
false);
5988 case Intrinsic::vector_reduce_fadd:
5989 case Intrinsic::vector_reduce_fmul:
5990 handleVectorReduceWithStarterIntrinsic(
I);
5994 case Intrinsic::vector_partial_reduce_add:
5995 case Intrinsic::vector_partial_reduce_fadd:
5996 handleVectorPartialReduceAddIntrinsic(
I);
5999 case Intrinsic::scmp:
6000 case Intrinsic::ucmp: {
6005 case Intrinsic::fshl:
6006 case Intrinsic::fshr:
6007 handleFunnelShift(
I);
6010 case Intrinsic::pdep:
6011 case Intrinsic::pext:
6012 handleGenericBitManipulation(
I);
6015 case Intrinsic::is_constant:
6017 setShadow(&
I, getCleanShadow(&
I));
6018 setOrigin(&
I, getCleanOrigin());
6025 case Intrinsic::fptosi_sat:
6026 case Intrinsic::fptoui_sat:
6027 handleGenericVectorConvertIntrinsic(
I,
false);
6034 case Intrinsic::fake_use:
6035 assert(
I.getType()->isVoidTy());
6048 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &
I) {
6049 switch (
I.getIntrinsicID()) {
6050 case Intrinsic::x86_sse_stmxcsr:
6053 case Intrinsic::x86_sse_ldmxcsr:
6060 case Intrinsic::x86_avx512_vcvtsd2usi64:
6061 case Intrinsic::x86_avx512_vcvtsd2usi32:
6062 case Intrinsic::x86_avx512_vcvtss2usi64:
6063 case Intrinsic::x86_avx512_vcvtss2usi32:
6064 case Intrinsic::x86_avx512_cvttss2usi64:
6065 case Intrinsic::x86_avx512_cvttss2usi:
6066 case Intrinsic::x86_avx512_cvttsd2usi64:
6067 case Intrinsic::x86_avx512_cvttsd2usi:
6068 case Intrinsic::x86_avx512_cvtusi2ss:
6069 case Intrinsic::x86_avx512_cvtusi642sd:
6070 case Intrinsic::x86_avx512_cvtusi642ss:
6071 handleSSEVectorConvertIntrinsic(
I, 1,
true);
6073 case Intrinsic::x86_sse2_cvtsd2si64:
6074 case Intrinsic::x86_sse2_cvtsd2si:
6075 case Intrinsic::x86_sse2_cvtsd2ss:
6076 case Intrinsic::x86_sse2_cvttsd2si64:
6077 case Intrinsic::x86_sse2_cvttsd2si:
6078 case Intrinsic::x86_sse_cvtss2si64:
6079 case Intrinsic::x86_sse_cvtss2si:
6080 case Intrinsic::x86_sse_cvttss2si64:
6081 case Intrinsic::x86_sse_cvttss2si:
6082 handleSSEVectorConvertIntrinsic(
I, 1);
6084 case Intrinsic::x86_sse_cvtps2pi:
6085 case Intrinsic::x86_sse_cvttps2pi:
6086 handleSSEVectorConvertIntrinsic(
I, 2);
6094 case Intrinsic::x86_vcvtps2ph_128:
6095 case Intrinsic::x86_vcvtps2ph_256: {
6096 handleSSEVectorConvertIntrinsicByProp(
I,
true);
6105 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
6106 handleAVX512VectorConvertFPToInt(
I,
false);
6111 case Intrinsic::x86_sse2_cvtpd2ps:
6112 case Intrinsic::x86_sse2_cvtps2dq:
6113 case Intrinsic::x86_sse2_cvtpd2dq:
6114 case Intrinsic::x86_sse2_cvttps2dq:
6115 case Intrinsic::x86_sse2_cvttpd2dq:
6116 case Intrinsic::x86_avx_cvt_pd2_ps_256:
6117 case Intrinsic::x86_avx_cvt_ps2dq_256:
6118 case Intrinsic::x86_avx_cvt_pd2dq_256:
6119 case Intrinsic::x86_avx_cvtt_ps2dq_256:
6120 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
6121 handleSSEVectorConvertIntrinsicByProp(
I,
false);
6132 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
6133 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
6134 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
6135 handleAVX512VectorConvertFPToInt(
I,
true);
6139 case Intrinsic::x86_avx512_psll_w_512:
6140 case Intrinsic::x86_avx512_psll_d_512:
6141 case Intrinsic::x86_avx512_psll_q_512:
6142 case Intrinsic::x86_avx512_pslli_w_512:
6143 case Intrinsic::x86_avx512_pslli_d_512:
6144 case Intrinsic::x86_avx512_pslli_q_512:
6145 case Intrinsic::x86_avx512_psrl_w_512:
6146 case Intrinsic::x86_avx512_psrl_d_512:
6147 case Intrinsic::x86_avx512_psrl_q_512:
6148 case Intrinsic::x86_avx512_psra_w_512:
6149 case Intrinsic::x86_avx512_psra_d_512:
6150 case Intrinsic::x86_avx512_psra_q_512:
6151 case Intrinsic::x86_avx512_psrli_w_512:
6152 case Intrinsic::x86_avx512_psrli_d_512:
6153 case Intrinsic::x86_avx512_psrli_q_512:
6154 case Intrinsic::x86_avx512_psrai_w_512:
6155 case Intrinsic::x86_avx512_psrai_d_512:
6156 case Intrinsic::x86_avx512_psrai_q_512:
6157 case Intrinsic::x86_avx512_psra_q_256:
6158 case Intrinsic::x86_avx512_psra_q_128:
6159 case Intrinsic::x86_avx512_psrai_q_256:
6160 case Intrinsic::x86_avx512_psrai_q_128:
6161 case Intrinsic::x86_avx2_psll_w:
6162 case Intrinsic::x86_avx2_psll_d:
6163 case Intrinsic::x86_avx2_psll_q:
6164 case Intrinsic::x86_avx2_pslli_w:
6165 case Intrinsic::x86_avx2_pslli_d:
6166 case Intrinsic::x86_avx2_pslli_q:
6167 case Intrinsic::x86_avx2_psrl_w:
6168 case Intrinsic::x86_avx2_psrl_d:
6169 case Intrinsic::x86_avx2_psrl_q:
6170 case Intrinsic::x86_avx2_psra_w:
6171 case Intrinsic::x86_avx2_psra_d:
6172 case Intrinsic::x86_avx2_psrli_w:
6173 case Intrinsic::x86_avx2_psrli_d:
6174 case Intrinsic::x86_avx2_psrli_q:
6175 case Intrinsic::x86_avx2_psrai_w:
6176 case Intrinsic::x86_avx2_psrai_d:
6177 case Intrinsic::x86_sse2_psll_w:
6178 case Intrinsic::x86_sse2_psll_d:
6179 case Intrinsic::x86_sse2_psll_q:
6180 case Intrinsic::x86_sse2_pslli_w:
6181 case Intrinsic::x86_sse2_pslli_d:
6182 case Intrinsic::x86_sse2_pslli_q:
6183 case Intrinsic::x86_sse2_psrl_w:
6184 case Intrinsic::x86_sse2_psrl_d:
6185 case Intrinsic::x86_sse2_psrl_q:
6186 case Intrinsic::x86_sse2_psra_w:
6187 case Intrinsic::x86_sse2_psra_d:
6188 case Intrinsic::x86_sse2_psrli_w:
6189 case Intrinsic::x86_sse2_psrli_d:
6190 case Intrinsic::x86_sse2_psrli_q:
6191 case Intrinsic::x86_sse2_psrai_w:
6192 case Intrinsic::x86_sse2_psrai_d:
6193 case Intrinsic::x86_mmx_psll_w:
6194 case Intrinsic::x86_mmx_psll_d:
6195 case Intrinsic::x86_mmx_psll_q:
6196 case Intrinsic::x86_mmx_pslli_w:
6197 case Intrinsic::x86_mmx_pslli_d:
6198 case Intrinsic::x86_mmx_pslli_q:
6199 case Intrinsic::x86_mmx_psrl_w:
6200 case Intrinsic::x86_mmx_psrl_d:
6201 case Intrinsic::x86_mmx_psrl_q:
6202 case Intrinsic::x86_mmx_psra_w:
6203 case Intrinsic::x86_mmx_psra_d:
6204 case Intrinsic::x86_mmx_psrli_w:
6205 case Intrinsic::x86_mmx_psrli_d:
6206 case Intrinsic::x86_mmx_psrli_q:
6207 case Intrinsic::x86_mmx_psrai_w:
6208 case Intrinsic::x86_mmx_psrai_d:
6209 handleVectorShiftIntrinsic(
I,
false);
6211 case Intrinsic::x86_avx2_psllv_d:
6212 case Intrinsic::x86_avx2_psllv_d_256:
6213 case Intrinsic::x86_avx512_psllv_d_512:
6214 case Intrinsic::x86_avx2_psllv_q:
6215 case Intrinsic::x86_avx2_psllv_q_256:
6216 case Intrinsic::x86_avx512_psllv_q_512:
6217 case Intrinsic::x86_avx2_psrlv_d:
6218 case Intrinsic::x86_avx2_psrlv_d_256:
6219 case Intrinsic::x86_avx512_psrlv_d_512:
6220 case Intrinsic::x86_avx2_psrlv_q:
6221 case Intrinsic::x86_avx2_psrlv_q_256:
6222 case Intrinsic::x86_avx512_psrlv_q_512:
6223 case Intrinsic::x86_avx2_psrav_d:
6224 case Intrinsic::x86_avx2_psrav_d_256:
6225 case Intrinsic::x86_avx512_psrav_d_512:
6226 case Intrinsic::x86_avx512_psrav_q_128:
6227 case Intrinsic::x86_avx512_psrav_q_256:
6228 case Intrinsic::x86_avx512_psrav_q_512:
6229 handleVectorShiftIntrinsic(
I,
true);
6233 case Intrinsic::x86_sse2_packsswb_128:
6234 case Intrinsic::x86_sse2_packssdw_128:
6235 case Intrinsic::x86_sse2_packuswb_128:
6236 case Intrinsic::x86_sse41_packusdw:
6237 case Intrinsic::x86_avx2_packsswb:
6238 case Intrinsic::x86_avx2_packssdw:
6239 case Intrinsic::x86_avx2_packuswb:
6240 case Intrinsic::x86_avx2_packusdw:
6246 case Intrinsic::x86_avx512_packsswb_512:
6247 case Intrinsic::x86_avx512_packssdw_512:
6248 case Intrinsic::x86_avx512_packuswb_512:
6249 case Intrinsic::x86_avx512_packusdw_512:
6250 handleVectorPackIntrinsic(
I);
6253 case Intrinsic::x86_sse41_pblendvb:
6254 case Intrinsic::x86_sse41_blendvpd:
6255 case Intrinsic::x86_sse41_blendvps:
6256 case Intrinsic::x86_avx_blendv_pd_256:
6257 case Intrinsic::x86_avx_blendv_ps_256:
6258 case Intrinsic::x86_avx2_pblendvb:
6259 handleBlendvIntrinsic(
I);
6262 case Intrinsic::x86_avx_dp_ps_256:
6263 case Intrinsic::x86_sse41_dppd:
6264 case Intrinsic::x86_sse41_dpps:
6265 handleDppIntrinsic(
I);
6268 case Intrinsic::x86_mmx_packsswb:
6269 case Intrinsic::x86_mmx_packuswb:
6270 handleVectorPackIntrinsic(
I, 16);
6273 case Intrinsic::x86_mmx_packssdw:
6274 handleVectorPackIntrinsic(
I, 32);
6277 case Intrinsic::x86_mmx_psad_bw:
6278 handleVectorSadIntrinsic(
I,
true);
6280 case Intrinsic::x86_sse2_psad_bw:
6281 case Intrinsic::x86_avx2_psad_bw:
6282 handleVectorSadIntrinsic(
I);
6308 case Intrinsic::x86_sse2_pmadd_wd:
6309 case Intrinsic::x86_avx2_pmadd_wd:
6310 case Intrinsic::x86_avx512_pmaddw_d_512:
6311 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6312 case Intrinsic::x86_avx2_pmadd_ub_sw:
6313 case Intrinsic::x86_avx512_pmaddubs_w_512:
6314 handleVectorDotProductIntrinsic(
I, 2,
6321 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6322 handleVectorDotProductIntrinsic(
I, 2,
6329 case Intrinsic::x86_mmx_pmadd_wd:
6330 handleVectorDotProductIntrinsic(
I, 2,
6339 case Intrinsic::aarch64_neon_bfmlalt:
6340 handleVectorDotProductIntrinsic(
I, 2,
6348 case Intrinsic::aarch64_neon_bfmlalb:
6349 handleVectorDotProductIntrinsic(
I, 2,
6447 case Intrinsic::x86_avx512_vpdpbusd_128:
6448 case Intrinsic::x86_avx512_vpdpbusd_256:
6449 case Intrinsic::x86_avx512_vpdpbusd_512:
6450 case Intrinsic::x86_avx512_vpdpbusds_128:
6451 case Intrinsic::x86_avx512_vpdpbusds_256:
6452 case Intrinsic::x86_avx512_vpdpbusds_512:
6453 case Intrinsic::x86_avx2_vpdpbssd_128:
6454 case Intrinsic::x86_avx2_vpdpbssd_256:
6455 case Intrinsic::x86_avx10_vpdpbssd_512:
6456 case Intrinsic::x86_avx2_vpdpbssds_128:
6457 case Intrinsic::x86_avx2_vpdpbssds_256:
6458 case Intrinsic::x86_avx10_vpdpbssds_512:
6459 case Intrinsic::x86_avx2_vpdpbsud_128:
6460 case Intrinsic::x86_avx2_vpdpbsud_256:
6461 case Intrinsic::x86_avx10_vpdpbsud_512:
6462 case Intrinsic::x86_avx2_vpdpbsuds_128:
6463 case Intrinsic::x86_avx2_vpdpbsuds_256:
6464 case Intrinsic::x86_avx10_vpdpbsuds_512:
6465 case Intrinsic::x86_avx2_vpdpbuud_128:
6466 case Intrinsic::x86_avx2_vpdpbuud_256:
6467 case Intrinsic::x86_avx10_vpdpbuud_512:
6468 case Intrinsic::x86_avx2_vpdpbuuds_128:
6469 case Intrinsic::x86_avx2_vpdpbuuds_256:
6470 case Intrinsic::x86_avx10_vpdpbuuds_512:
6471 handleVectorDotProductIntrinsic(
I, 4,
6569 case Intrinsic::x86_avx512_vpdpwssd_128:
6570 case Intrinsic::x86_avx512_vpdpwssd_256:
6571 case Intrinsic::x86_avx512_vpdpwssd_512:
6572 case Intrinsic::x86_avx512_vpdpwssds_128:
6573 case Intrinsic::x86_avx512_vpdpwssds_256:
6574 case Intrinsic::x86_avx512_vpdpwssds_512:
6575 case Intrinsic::x86_avx2_vpdpwsud_128:
6576 case Intrinsic::x86_avx2_vpdpwsud_256:
6577 case Intrinsic::x86_avx10_vpdpwsud_512:
6578 case Intrinsic::x86_avx2_vpdpwsuds_128:
6579 case Intrinsic::x86_avx2_vpdpwsuds_256:
6580 case Intrinsic::x86_avx10_vpdpwsuds_512:
6581 case Intrinsic::x86_avx2_vpdpwusd_128:
6582 case Intrinsic::x86_avx2_vpdpwusd_256:
6583 case Intrinsic::x86_avx10_vpdpwusd_512:
6584 case Intrinsic::x86_avx2_vpdpwusds_128:
6585 case Intrinsic::x86_avx2_vpdpwusds_256:
6586 case Intrinsic::x86_avx10_vpdpwusds_512:
6587 case Intrinsic::x86_avx2_vpdpwuud_128:
6588 case Intrinsic::x86_avx2_vpdpwuud_256:
6589 case Intrinsic::x86_avx10_vpdpwuud_512:
6590 case Intrinsic::x86_avx2_vpdpwuuds_128:
6591 case Intrinsic::x86_avx2_vpdpwuuds_256:
6592 case Intrinsic::x86_avx10_vpdpwuuds_512:
6593 handleVectorDotProductIntrinsic(
I, 2,
6607 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6608 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6609 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6610 handleVectorDotProductIntrinsic(
I, 2,
6616 case Intrinsic::x86_sse_cmp_ss:
6617 case Intrinsic::x86_sse2_cmp_sd:
6618 case Intrinsic::x86_sse_comieq_ss:
6619 case Intrinsic::x86_sse_comilt_ss:
6620 case Intrinsic::x86_sse_comile_ss:
6621 case Intrinsic::x86_sse_comigt_ss:
6622 case Intrinsic::x86_sse_comige_ss:
6623 case Intrinsic::x86_sse_comineq_ss:
6624 case Intrinsic::x86_sse_ucomieq_ss:
6625 case Intrinsic::x86_sse_ucomilt_ss:
6626 case Intrinsic::x86_sse_ucomile_ss:
6627 case Intrinsic::x86_sse_ucomigt_ss:
6628 case Intrinsic::x86_sse_ucomige_ss:
6629 case Intrinsic::x86_sse_ucomineq_ss:
6630 case Intrinsic::x86_sse2_comieq_sd:
6631 case Intrinsic::x86_sse2_comilt_sd:
6632 case Intrinsic::x86_sse2_comile_sd:
6633 case Intrinsic::x86_sse2_comigt_sd:
6634 case Intrinsic::x86_sse2_comige_sd:
6635 case Intrinsic::x86_sse2_comineq_sd:
6636 case Intrinsic::x86_sse2_ucomieq_sd:
6637 case Intrinsic::x86_sse2_ucomilt_sd:
6638 case Intrinsic::x86_sse2_ucomile_sd:
6639 case Intrinsic::x86_sse2_ucomigt_sd:
6640 case Intrinsic::x86_sse2_ucomige_sd:
6641 case Intrinsic::x86_sse2_ucomineq_sd:
6642 handleVectorCompareScalarIntrinsic(
I);
6645 case Intrinsic::x86_avx_cmp_pd_256:
6646 case Intrinsic::x86_avx_cmp_ps_256:
6647 case Intrinsic::x86_sse2_cmp_pd:
6648 case Intrinsic::x86_sse_cmp_ps:
6649 handleVectorComparePackedIntrinsic(
I,
true);
6652 case Intrinsic::x86_bmi_bextr_32:
6653 case Intrinsic::x86_bmi_bextr_64:
6654 case Intrinsic::x86_bmi_bzhi_32:
6655 case Intrinsic::x86_bmi_bzhi_64:
6656 handleGenericBitManipulation(
I);
6659 case Intrinsic::x86_pclmulqdq:
6660 case Intrinsic::x86_pclmulqdq_256:
6661 case Intrinsic::x86_pclmulqdq_512:
6662 handlePclmulIntrinsic(
I);
6665 case Intrinsic::x86_avx_round_pd_256:
6666 case Intrinsic::x86_avx_round_ps_256:
6667 case Intrinsic::x86_sse41_round_pd:
6668 case Intrinsic::x86_sse41_round_ps:
6669 handleRoundPdPsIntrinsic(
I);
6672 case Intrinsic::x86_sse41_round_sd:
6673 case Intrinsic::x86_sse41_round_ss:
6674 handleUnarySdSsIntrinsic(
I);
6677 case Intrinsic::x86_sse2_max_sd:
6678 case Intrinsic::x86_sse_max_ss:
6679 case Intrinsic::x86_sse2_min_sd:
6680 case Intrinsic::x86_sse_min_ss:
6681 handleBinarySdSsIntrinsic(
I);
6684 case Intrinsic::x86_avx_vtestc_pd:
6685 case Intrinsic::x86_avx_vtestc_pd_256:
6686 case Intrinsic::x86_avx_vtestc_ps:
6687 case Intrinsic::x86_avx_vtestc_ps_256:
6688 case Intrinsic::x86_avx_vtestnzc_pd:
6689 case Intrinsic::x86_avx_vtestnzc_pd_256:
6690 case Intrinsic::x86_avx_vtestnzc_ps:
6691 case Intrinsic::x86_avx_vtestnzc_ps_256:
6692 case Intrinsic::x86_avx_vtestz_pd:
6693 case Intrinsic::x86_avx_vtestz_pd_256:
6694 case Intrinsic::x86_avx_vtestz_ps:
6695 case Intrinsic::x86_avx_vtestz_ps_256:
6696 case Intrinsic::x86_avx_ptestc_256:
6697 case Intrinsic::x86_avx_ptestnzc_256:
6698 case Intrinsic::x86_avx_ptestz_256:
6699 case Intrinsic::x86_sse41_ptestc:
6700 case Intrinsic::x86_sse41_ptestnzc:
6701 case Intrinsic::x86_sse41_ptestz:
6702 handleVtestIntrinsic(
I);
6706 case Intrinsic::x86_ssse3_phadd_w:
6707 case Intrinsic::x86_ssse3_phadd_w_128:
6708 case Intrinsic::x86_ssse3_phsub_w:
6709 case Intrinsic::x86_ssse3_phsub_w_128:
6710 handlePairwiseShadowOrIntrinsic(
I, 1,
6714 case Intrinsic::x86_avx2_phadd_w:
6715 case Intrinsic::x86_avx2_phsub_w:
6716 handlePairwiseShadowOrIntrinsic(
I, 2,
6721 case Intrinsic::x86_ssse3_phadd_d:
6722 case Intrinsic::x86_ssse3_phadd_d_128:
6723 case Intrinsic::x86_ssse3_phsub_d:
6724 case Intrinsic::x86_ssse3_phsub_d_128:
6725 handlePairwiseShadowOrIntrinsic(
I, 1,
6729 case Intrinsic::x86_avx2_phadd_d:
6730 case Intrinsic::x86_avx2_phsub_d:
6731 handlePairwiseShadowOrIntrinsic(
I, 2,
6736 case Intrinsic::x86_ssse3_phadd_sw:
6737 case Intrinsic::x86_ssse3_phadd_sw_128:
6738 case Intrinsic::x86_ssse3_phsub_sw:
6739 case Intrinsic::x86_ssse3_phsub_sw_128:
6740 handlePairwiseShadowOrIntrinsic(
I, 1,
6744 case Intrinsic::x86_avx2_phadd_sw:
6745 case Intrinsic::x86_avx2_phsub_sw:
6746 handlePairwiseShadowOrIntrinsic(
I, 2,
6751 case Intrinsic::x86_sse3_hadd_ps:
6752 case Intrinsic::x86_sse3_hadd_pd:
6753 case Intrinsic::x86_sse3_hsub_ps:
6754 case Intrinsic::x86_sse3_hsub_pd:
6755 handlePairwiseShadowOrIntrinsic(
I, 1);
6758 case Intrinsic::x86_avx_hadd_pd_256:
6759 case Intrinsic::x86_avx_hadd_ps_256:
6760 case Intrinsic::x86_avx_hsub_pd_256:
6761 case Intrinsic::x86_avx_hsub_ps_256:
6762 handlePairwiseShadowOrIntrinsic(
I, 2);
6765 case Intrinsic::x86_avx_maskstore_ps:
6766 case Intrinsic::x86_avx_maskstore_pd:
6767 case Intrinsic::x86_avx_maskstore_ps_256:
6768 case Intrinsic::x86_avx_maskstore_pd_256:
6769 case Intrinsic::x86_avx2_maskstore_d:
6770 case Intrinsic::x86_avx2_maskstore_q:
6771 case Intrinsic::x86_avx2_maskstore_d_256:
6772 case Intrinsic::x86_avx2_maskstore_q_256: {
6773 handleAVXMaskedStore(
I);
6777 case Intrinsic::x86_avx_maskload_ps:
6778 case Intrinsic::x86_avx_maskload_pd:
6779 case Intrinsic::x86_avx_maskload_ps_256:
6780 case Intrinsic::x86_avx_maskload_pd_256:
6781 case Intrinsic::x86_avx2_maskload_d:
6782 case Intrinsic::x86_avx2_maskload_q:
6783 case Intrinsic::x86_avx2_maskload_d_256:
6784 case Intrinsic::x86_avx2_maskload_q_256: {
6785 handleAVXMaskedLoad(
I);
6790 case Intrinsic::x86_avx512fp16_add_ph_512:
6791 case Intrinsic::x86_avx512fp16_sub_ph_512:
6792 case Intrinsic::x86_avx512fp16_mul_ph_512:
6793 case Intrinsic::x86_avx512fp16_div_ph_512:
6794 case Intrinsic::x86_avx512fp16_max_ph_512:
6795 case Intrinsic::x86_avx512fp16_min_ph_512:
6796 case Intrinsic::x86_avx512_min_ps_512:
6797 case Intrinsic::x86_avx512_min_pd_512:
6798 case Intrinsic::x86_avx512_max_ps_512:
6799 case Intrinsic::x86_avx512_max_pd_512: {
6804 [[maybe_unused]]
bool Success =
6805 maybeHandleSimpleNomemIntrinsic(
I, 1);
6810 case Intrinsic::x86_avx_vpermilvar_pd:
6811 case Intrinsic::x86_avx_vpermilvar_pd_256:
6812 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6813 case Intrinsic::x86_avx_vpermilvar_ps:
6814 case Intrinsic::x86_avx_vpermilvar_ps_256:
6815 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6816 handleAVXVpermilvar(
I);
6820 case Intrinsic::x86_avx512_vpermi2var_d_128:
6821 case Intrinsic::x86_avx512_vpermi2var_d_256:
6822 case Intrinsic::x86_avx512_vpermi2var_d_512:
6823 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6824 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6825 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6826 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6827 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6828 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6829 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6830 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6831 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6832 case Intrinsic::x86_avx512_vpermi2var_q_128:
6833 case Intrinsic::x86_avx512_vpermi2var_q_256:
6834 case Intrinsic::x86_avx512_vpermi2var_q_512:
6835 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6836 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6837 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6838 handleAVXVpermi2var(
I);
6852 case Intrinsic::x86_avx2_pshuf_b:
6853 case Intrinsic::x86_sse_pshuf_w:
6854 case Intrinsic::x86_ssse3_pshuf_b_128:
6855 case Intrinsic::x86_ssse3_pshuf_b:
6856 case Intrinsic::x86_avx512_pshuf_b_512:
6857 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6864 case Intrinsic::x86_avx512_mask_pmov_dw_128:
6865 case Intrinsic::x86_avx512_mask_pmov_db_128:
6866 case Intrinsic::x86_avx512_mask_pmov_qb_128:
6867 case Intrinsic::x86_avx512_mask_pmov_qw_128:
6868 case Intrinsic::x86_avx512_mask_pmov_qd_128:
6869 case Intrinsic::x86_avx512_mask_pmov_wb_128:
6870 case Intrinsic::x86_avx512_mask_pmov_dw_256:
6871 case Intrinsic::x86_avx512_mask_pmov_db_256:
6872 case Intrinsic::x86_avx512_mask_pmov_qb_256:
6873 case Intrinsic::x86_avx512_mask_pmov_qw_256:
6874 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6875 case Intrinsic::x86_avx512_mask_pmov_db_512:
6876 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6877 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6880 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6889 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6890 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6891 handleIntrinsicByApplyingToShadow(
6892 I, Intrinsic::x86_avx512_mask_pmov_dw_512,
6897 case Intrinsic::x86_avx512_mask_pmovs_dw_256:
6898 case Intrinsic::x86_avx512_mask_pmovus_dw_256:
6899 handleIntrinsicByApplyingToShadow(
6900 I, Intrinsic::x86_avx512_mask_pmov_dw_256,
6904 case Intrinsic::x86_avx512_mask_pmovs_dw_128:
6905 case Intrinsic::x86_avx512_mask_pmovus_dw_128:
6906 handleIntrinsicByApplyingToShadow(
6907 I, Intrinsic::x86_avx512_mask_pmov_dw_128,
6911 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6912 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6913 handleIntrinsicByApplyingToShadow(
6914 I, Intrinsic::x86_avx512_mask_pmov_db_512,
6919 case Intrinsic::x86_avx512_mask_pmovs_db_256:
6920 case Intrinsic::x86_avx512_mask_pmovus_db_256:
6921 handleIntrinsicByApplyingToShadow(
6922 I, Intrinsic::x86_avx512_mask_pmov_db_256,
6926 case Intrinsic::x86_avx512_mask_pmovs_db_128:
6927 case Intrinsic::x86_avx512_mask_pmovus_db_128:
6928 handleIntrinsicByApplyingToShadow(
6929 I, Intrinsic::x86_avx512_mask_pmov_db_128,
6933 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
6934 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
6935 handleIntrinsicByApplyingToShadow(
6936 I, Intrinsic::x86_avx512_mask_pmov_qb_512,
6941 case Intrinsic::x86_avx512_mask_pmovs_qb_256:
6942 case Intrinsic::x86_avx512_mask_pmovus_qb_256:
6943 handleIntrinsicByApplyingToShadow(
6944 I, Intrinsic::x86_avx512_mask_pmov_qb_256,
6948 case Intrinsic::x86_avx512_mask_pmovs_qb_128:
6949 case Intrinsic::x86_avx512_mask_pmovus_qb_128:
6950 handleIntrinsicByApplyingToShadow(
6951 I, Intrinsic::x86_avx512_mask_pmov_qb_128,
6955 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
6956 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
6957 handleIntrinsicByApplyingToShadow(
6958 I, Intrinsic::x86_avx512_mask_pmov_qw_512,
6963 case Intrinsic::x86_avx512_mask_pmovs_qw_256:
6964 case Intrinsic::x86_avx512_mask_pmovus_qw_256:
6965 handleIntrinsicByApplyingToShadow(
6966 I, Intrinsic::x86_avx512_mask_pmov_qw_256,
6970 case Intrinsic::x86_avx512_mask_pmovs_qw_128:
6971 case Intrinsic::x86_avx512_mask_pmovus_qw_128:
6972 handleIntrinsicByApplyingToShadow(
6973 I, Intrinsic::x86_avx512_mask_pmov_qw_128,
6977 case Intrinsic::x86_avx512_mask_pmovs_qd_128:
6978 case Intrinsic::x86_avx512_mask_pmovus_qd_128:
6979 handleIntrinsicByApplyingToShadow(
6980 I, Intrinsic::x86_avx512_mask_pmov_qd_128,
6984 case Intrinsic::x86_avx512_mask_pmovs_wb_128:
6985 case Intrinsic::x86_avx512_mask_pmovus_wb_128:
6986 handleIntrinsicByApplyingToShadow(
6987 I, Intrinsic::x86_avx512_mask_pmov_wb_128,
6991 case Intrinsic::x86_avx512_mask_pmovs_qd_256:
6992 case Intrinsic::x86_avx512_mask_pmovus_qd_256:
6993 case Intrinsic::x86_avx512_mask_pmovs_wb_256:
6994 case Intrinsic::x86_avx512_mask_pmovus_wb_256:
6995 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
6996 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
6997 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
6998 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
7002 handleAVX512VectorDownConvert(
I);
7013 case Intrinsic::x86_avx512_mask_compress:
7014 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7055 case Intrinsic::x86_avx512_rsqrt14_ps_512:
7056 case Intrinsic::x86_avx512_rsqrt14_ps_256:
7057 case Intrinsic::x86_avx512_rsqrt14_ps_128:
7058 case Intrinsic::x86_avx512_rsqrt14_pd_512:
7059 case Intrinsic::x86_avx512_rsqrt14_pd_256:
7060 case Intrinsic::x86_avx512_rsqrt14_pd_128:
7061 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
7062 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
7063 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
7064 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
7065 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
7066 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
7067 handleAVX512VectorGenericMaskedFP(
I, {0},
7108 case Intrinsic::x86_avx512_rcp14_ps_512:
7109 case Intrinsic::x86_avx512_rcp14_ps_256:
7110 case Intrinsic::x86_avx512_rcp14_ps_128:
7111 case Intrinsic::x86_avx512_rcp14_pd_512:
7112 case Intrinsic::x86_avx512_rcp14_pd_256:
7113 case Intrinsic::x86_avx512_rcp14_pd_128:
7114 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
7115 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
7116 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
7117 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
7118 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
7119 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
7120 handleAVX512VectorGenericMaskedFP(
I, {0},
7165 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
7166 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
7167 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
7168 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
7169 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
7170 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
7171 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
7172 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
7173 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
7174 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
7175 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
7176 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
7177 handleAVX512VectorGenericMaskedFP(
I, {0},
7213 case Intrinsic::x86_avx512_mask_scalef_pd_512:
7214 case Intrinsic::x86_avx512_mask_scalef_pd_256:
7215 case Intrinsic::x86_avx512_mask_scalef_pd_128:
7216 case Intrinsic::x86_avx512_mask_scalef_ps_512:
7217 case Intrinsic::x86_avx512_mask_scalef_ps_256:
7218 case Intrinsic::x86_avx512_mask_scalef_ps_128:
7219 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
7220 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
7221 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
7225 handleAVX512VectorGenericMaskedFP(
I, {0, 1},
7245 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
7246 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
7247 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
7248 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
7249 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
7250 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
7251 visitGenericScalarHalfwordInst(
I);
7258 case Intrinsic::x86_avx512_fpclass_pd_512:
7259 case Intrinsic::x86_avx512_fpclass_ps_512:
7260 handleAVX512FPClass(
I);
7264 case Intrinsic::x86_vgf2p8affineqb_128:
7265 case Intrinsic::x86_vgf2p8affineqb_256:
7266 case Intrinsic::x86_vgf2p8affineqb_512:
7267 handleAVXGF2P8Affine(
I);
7277 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &
I) {
7278 switch (
I.getIntrinsicID()) {
7282 case Intrinsic::aarch64_neon_rshrn:
7283 case Intrinsic::aarch64_neon_sqrshl:
7284 case Intrinsic::aarch64_neon_sqrshrn:
7285 case Intrinsic::aarch64_neon_sqrshrun:
7286 case Intrinsic::aarch64_neon_sqshl:
7287 case Intrinsic::aarch64_neon_sqshlu:
7288 case Intrinsic::aarch64_neon_sqshrn:
7289 case Intrinsic::aarch64_neon_sqshrun:
7290 case Intrinsic::aarch64_neon_srshl:
7291 case Intrinsic::aarch64_neon_sshl:
7292 case Intrinsic::aarch64_neon_uqrshl:
7293 case Intrinsic::aarch64_neon_uqrshrn:
7294 case Intrinsic::aarch64_neon_uqshl:
7295 case Intrinsic::aarch64_neon_uqshrn:
7296 case Intrinsic::aarch64_neon_urshl:
7297 case Intrinsic::aarch64_neon_ushl:
7298 handleVectorShiftIntrinsic(
I,
false);
7311 case Intrinsic::aarch64_neon_vsli:
7312 case Intrinsic::aarch64_neon_vsri:
7313 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7320 case Intrinsic::aarch64_neon_fmaxp:
7321 case Intrinsic::aarch64_neon_fminp:
7323 case Intrinsic::aarch64_neon_fmaxnmp:
7324 case Intrinsic::aarch64_neon_fminnmp:
7326 case Intrinsic::aarch64_neon_smaxp:
7327 case Intrinsic::aarch64_neon_sminp:
7328 case Intrinsic::aarch64_neon_umaxp:
7329 case Intrinsic::aarch64_neon_uminp:
7331 case Intrinsic::aarch64_neon_addp:
7333 case Intrinsic::aarch64_neon_faddp:
7335 case Intrinsic::aarch64_neon_saddlp:
7336 case Intrinsic::aarch64_neon_uaddlp: {
7337 handlePairwiseShadowOrIntrinsic(
I, 1);
7342 case Intrinsic::aarch64_neon_fcvtas:
7343 case Intrinsic::aarch64_neon_fcvtau:
7345 case Intrinsic::aarch64_neon_fcvtms:
7346 case Intrinsic::aarch64_neon_fcvtmu:
7348 case Intrinsic::aarch64_neon_fcvtns:
7349 case Intrinsic::aarch64_neon_fcvtnu:
7351 case Intrinsic::aarch64_neon_fcvtps:
7352 case Intrinsic::aarch64_neon_fcvtpu:
7354 case Intrinsic::aarch64_neon_fcvtzs:
7355 case Intrinsic::aarch64_neon_fcvtzu:
7357 case Intrinsic::aarch64_neon_fcvtxn:
7358 handleGenericVectorConvertIntrinsic(
I,
false);
7362 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7363 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7364 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7365 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7366 handleGenericVectorConvertIntrinsic(
I,
true);
7375 case Intrinsic::aarch64_neon_faddv:
7376 case Intrinsic::aarch64_neon_saddv:
7377 case Intrinsic::aarch64_neon_uaddv:
7380 case Intrinsic::aarch64_neon_smaxv:
7381 case Intrinsic::aarch64_neon_sminv:
7382 case Intrinsic::aarch64_neon_umaxv:
7383 case Intrinsic::aarch64_neon_uminv:
7387 case Intrinsic::aarch64_neon_fmaxv:
7388 case Intrinsic::aarch64_neon_fminv:
7389 case Intrinsic::aarch64_neon_fmaxnmv:
7390 case Intrinsic::aarch64_neon_fminnmv:
7392 case Intrinsic::aarch64_neon_saddlv:
7393 case Intrinsic::aarch64_neon_uaddlv:
7394 handleVectorReduceIntrinsic(
I,
true);
7397 case Intrinsic::aarch64_neon_ld1x2:
7398 case Intrinsic::aarch64_neon_ld1x3:
7399 case Intrinsic::aarch64_neon_ld1x4:
7400 case Intrinsic::aarch64_neon_ld2:
7401 case Intrinsic::aarch64_neon_ld3:
7402 case Intrinsic::aarch64_neon_ld4:
7403 case Intrinsic::aarch64_neon_ld2r:
7404 case Intrinsic::aarch64_neon_ld3r:
7405 case Intrinsic::aarch64_neon_ld4r: {
7406 handleNEONVectorLoad(
I,
false);
7410 case Intrinsic::aarch64_neon_ld2lane:
7411 case Intrinsic::aarch64_neon_ld3lane:
7412 case Intrinsic::aarch64_neon_ld4lane: {
7413 handleNEONVectorLoad(
I,
true);
7418 case Intrinsic::aarch64_neon_sqxtn:
7419 case Intrinsic::aarch64_neon_sqxtun:
7420 case Intrinsic::aarch64_neon_uqxtn:
7427 case Intrinsic::aarch64_neon_st1x2:
7428 case Intrinsic::aarch64_neon_st1x3:
7429 case Intrinsic::aarch64_neon_st1x4:
7430 case Intrinsic::aarch64_neon_st2:
7431 case Intrinsic::aarch64_neon_st3:
7432 case Intrinsic::aarch64_neon_st4: {
7433 handleNEONVectorStoreIntrinsic(
I,
false);
7437 case Intrinsic::aarch64_neon_st2lane:
7438 case Intrinsic::aarch64_neon_st3lane:
7439 case Intrinsic::aarch64_neon_st4lane: {
7440 handleNEONVectorStoreIntrinsic(
I,
true);
7453 case Intrinsic::aarch64_neon_tbl1:
7454 case Intrinsic::aarch64_neon_tbl2:
7455 case Intrinsic::aarch64_neon_tbl3:
7456 case Intrinsic::aarch64_neon_tbl4:
7457 case Intrinsic::aarch64_neon_tbx1:
7458 case Intrinsic::aarch64_neon_tbx2:
7459 case Intrinsic::aarch64_neon_tbx3:
7460 case Intrinsic::aarch64_neon_tbx4: {
7462 handleIntrinsicByApplyingToShadow(
7463 I,
I.getIntrinsicID(),
7468 case Intrinsic::aarch64_neon_fmulx:
7469 case Intrinsic::aarch64_neon_pmul:
7470 case Intrinsic::aarch64_neon_pmull:
7471 case Intrinsic::aarch64_neon_smull:
7472 case Intrinsic::aarch64_neon_pmull64:
7473 case Intrinsic::aarch64_neon_umull: {
7474 handleNEONVectorMultiplyIntrinsic(
I);
7478 case Intrinsic::aarch64_neon_smmla:
7479 case Intrinsic::aarch64_neon_ummla:
7480 case Intrinsic::aarch64_neon_usmmla:
7481 case Intrinsic::aarch64_neon_bfmmla:
7482 handleNEONMatrixMultiply(
I);
7489 case Intrinsic::aarch64_neon_sdot:
7490 case Intrinsic::aarch64_neon_udot:
7491 case Intrinsic::aarch64_neon_usdot:
7492 handleVectorDotProductIntrinsic(
I, 4,
7502 case Intrinsic::aarch64_neon_bfdot:
7503 handleVectorDotProductIntrinsic(
I, 2,
7516 case Intrinsic::aarch64_neon_fp8_fdot2:
7517 handleVectorDotProductIntrinsic(
I, 2,
7530 case Intrinsic::aarch64_neon_fp8_fdot4:
7531 handleVectorDotProductIntrinsic(
I, 4,
7541 case Intrinsic::aarch64_neon_fp8_fdot2_lane:
7542 handleNEONDotProductLaneIntrinsic(
I, 2);
7549 case Intrinsic::aarch64_neon_fp8_fdot4_lane:
7550 handleNEONDotProductLaneIntrinsic(
I, 4);
7554 case Intrinsic::aarch64_neon_facge:
7555 case Intrinsic::aarch64_neon_facgt:
7556 handleVectorComparePackedIntrinsic(
I,
false);
7566 void visitIntrinsicInst(IntrinsicInst &
I) {
7567 if (maybeHandleCrossPlatformIntrinsic(
I))
7570 if (maybeHandleX86SIMDIntrinsic(
I))
7573 if (maybeHandleArmSIMDIntrinsic(
I))
7576 if (maybeHandleUnknownIntrinsic(
I))
7579 visitInstruction(
I);
7582 void visitLibAtomicLoad(CallBase &CB) {
7593 Value *NewOrdering =
7597 NextNodeIRBuilder NextIRB(&CB);
7598 Value *SrcShadowPtr, *SrcOriginPtr;
7599 std::tie(SrcShadowPtr, SrcOriginPtr) =
7600 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7602 Value *DstShadowPtr =
7603 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7607 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
7608 if (MS.TrackOrigins) {
7609 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7611 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7612 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7616 void visitLibAtomicStore(CallBase &CB) {
7623 Value *NewOrdering =
7627 Value *DstShadowPtr =
7637 void visitCallBase(CallBase &CB) {
7644 if (Opts.msan_handle_asm_conservative)
7645 visitAsmInstruction(CB);
7647 visitInstruction(CB);
7651 if (LF != NotLibFunc) {
7656 case LibFunc_atomic_load:
7658 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
7662 visitLibAtomicLoad(CB);
7664 case LibFunc_atomic_store:
7665 visitLibAtomicStore(CB);
7681 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7685 Func->removeFnAttrs(
B);
7691 bool MayCheckCall = MS.EagerChecks;
7695 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
7698 unsigned ArgOffset = 0;
7701 if (!
A->getType()->isSized()) {
7702 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
7706 if (
A->getType()->isScalableTy()) {
7707 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
7709 insertCheckShadowOf(
A, &CB);
7714 const DataLayout &
DL =
F.getDataLayout();
7718 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7721 insertCheckShadowOf(
A, &CB);
7722 Size =
DL.getTypeAllocSize(
A->getType());
7728 Value *ArgShadow = getShadow(
A);
7729 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7731 <<
" Shadow: " << *ArgShadow <<
"\n");
7735 assert(
A->getType()->isPointerTy() &&
7736 "ByVal argument is not a pointer!");
7744 Value *AShadowPtr, *AOriginPtr;
7745 std::tie(AShadowPtr, AOriginPtr) =
7746 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
7748 if (!PropagateShadow) {
7755 if (MS.TrackOrigins) {
7756 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7770 Size =
DL.getTypeAllocSize(
A->getType());
7776 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
7778 getOriginPtrForArgument(IRB, ArgOffset));
7790 if (FT->isVarArg()) {
7791 VAHelper->visitCallBase(CB, IRB);
7801 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
7802 setShadow(&CB, getCleanShadow(&CB));
7803 setOrigin(&CB, getCleanOrigin());
7809 Value *
Base = getShadowPtrForRetval(IRBBefore);
7810 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
7822 setShadow(&CB, getCleanShadow(&CB));
7823 setOrigin(&CB, getCleanOrigin());
7830 "Could not find insertion point for retval shadow load");
7833 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7836 setShadow(&CB, RetvalShadow);
7837 if (MS.TrackOrigins)
7838 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7843 RetVal =
I->getOperand(0);
7846 return I->isMustTailCall();
7851 void visitReturnInst(ReturnInst &
I) {
7853 Value *RetVal =
I.getReturnValue();
7859 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7860 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
7861 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7864 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
7866 Value *Shadow = getShadow(RetVal);
7867 bool StoreOrigin =
true;
7869 insertCheckShadowOf(RetVal, &
I);
7870 Shadow = getCleanShadow(RetVal);
7871 StoreOrigin =
false;
7878 if (MS.TrackOrigins && StoreOrigin)
7879 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7883 void visitPHINode(PHINode &
I) {
7885 if (!PropagateShadow) {
7886 setShadow(&
I, getCleanShadow(&
I));
7887 setOrigin(&
I, getCleanOrigin());
7891 ShadowPHINodes.push_back(&
I);
7892 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
7894 if (MS.TrackOrigins)
7896 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
7899 Value *getLocalVarIdptr(AllocaInst &
I) {
7900 ConstantInt *IntConst =
7901 ConstantInt::get(Type::getInt32Ty((*
F.getParent()).getContext()), 0);
7902 return new GlobalVariable(*
F.getParent(), IntConst->
getType(),
7907 Value *getLocalVarDescription(AllocaInst &
I) {
7912 if (PoisonStack && Opts.msan_poison_stack_with_call) {
7913 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7915 Value *ShadowBase, *OriginBase;
7916 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7919 Value *PoisonValue =
7920 IRB.
getInt8(PoisonStack ? Opts.msan_poison_stack_pattern : 0);
7921 IRB.
CreateMemSet(ShadowBase, PoisonValue, Len,
I.getAlign());
7924 if (PoisonStack && MS.TrackOrigins) {
7925 Value *Idptr = getLocalVarIdptr(
I);
7926 if (Opts.msan_print_stack_names) {
7927 Value *Descr = getLocalVarDescription(
I);
7928 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
7929 {&I, Len, Idptr, Descr});
7931 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
7937 Value *Descr = getLocalVarDescription(
I);
7939 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
7941 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
7945 void instrumentAlloca(AllocaInst &
I, Instruction *InsPoint =
nullptr) {
7948 NextNodeIRBuilder IRB(InsPoint);
7951 if (MS.CompileKernel)
7952 poisonAllocaKmsan(
I, IRB, Len);
7954 poisonAllocaUserspace(
I, IRB, Len);
7957 void visitAllocaInst(AllocaInst &
I) {
7958 setShadow(&
I, getCleanShadow(&
I));
7959 setOrigin(&
I, getCleanOrigin());
7965 void visitSelectInst(SelectInst &
I) {
7971 handleSelectLikeInst(
I,
B,
C,
D);
7977 Value *Sb = getShadow(
B);
7978 Value *Sc = getShadow(
C);
7979 Value *Sd = getShadow(
D);
7981 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
7982 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
7983 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
7988 if (
I.getType()->isAggregateType()) {
7992 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
7993 }
else if (isScalableNonVectorType(
I.getType())) {
8001 Sa1 = getCleanShadow(getShadowTy(
I.getType()));
8009 C = CreateAppToShadowCast(IRB,
C);
8010 D = CreateAppToShadowCast(IRB,
D);
8017 if (MS.TrackOrigins) {
8020 if (
B->getType()->isVectorTy()) {
8021 B = convertToBool(
B, IRB);
8022 Sb = convertToBool(Sb, IRB);
8030 void visitLandingPadInst(LandingPadInst &
I) {
8033 setShadow(&
I, getCleanShadow(&
I));
8034 setOrigin(&
I, getCleanOrigin());
8037 void visitCatchSwitchInst(CatchSwitchInst &
I) {
8038 setShadow(&
I, getCleanShadow(&
I));
8039 setOrigin(&
I, getCleanOrigin());
8042 void visitFuncletPadInst(FuncletPadInst &
I) {
8043 setShadow(&
I, getCleanShadow(&
I));
8044 setOrigin(&
I, getCleanOrigin());
8047 void visitGetElementPtrInst(GetElementPtrInst &
I) { handleShadowOr(
I); }
8049 void visitExtractValueInst(ExtractValueInst &
I) {
8051 Value *Agg =
I.getAggregateOperand();
8053 Value *AggShadow = getShadow(Agg);
8057 setShadow(&
I, ResShadow);
8058 setOriginForNaryOp(
I);
8061 void visitInsertValueInst(InsertValueInst &
I) {
8064 Value *AggShadow = getShadow(
I.getAggregateOperand());
8065 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
8071 setOriginForNaryOp(
I);
8074 void dumpInst(Instruction &
I,
const Twine &Prefix) {
8081 << CI->getCalledFunction()->
getName() <<
"\n";
8083 errs() <<
"ZZZ:" <<
Prefix <<
" " <<
I.getOpcodeName() <<
"\n";
8090 unsigned NumOperands =
I.getNumOperands();
8092 errs() <<
"YYY:" <<
Prefix <<
" call " << *
I.getType() <<
" @";
8104 errs() <<
"YYY:" <<
Prefix <<
" " << *
I.getType() <<
" "
8105 <<
I.getOpcodeName() <<
"(";
8107 for (
size_t i = 0; i < NumOperands; i++) {
8125 void visitResumeInst(ResumeInst &
I) {
8130 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
8135 void visitCatchReturnInst(CatchReturnInst &CRI) {
8140 void instrumentAsmArgument(
Value *Operand,
Type *ElemTy, Instruction &
I,
8149 insertCheckShadowOf(Operand, &
I);
8156 auto Size =
DL.getTypeStoreSize(ElemTy);
8158 if (MS.CompileKernel) {
8159 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
8165 auto [ShadowPtr,
_] =
8166 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
8176 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
8177 int NumRetOutputs = 0;
8184 NumRetOutputs =
ST->getNumElements();
8189 for (
const InlineAsm::ConstraintInfo &Info : Constraints) {
8190 switch (
Info.Type) {
8198 return NumOutputs - NumRetOutputs;
8201 void visitAsmInstruction(Instruction &
I) {
8217 const DataLayout &
DL =
F.getDataLayout();
8221 int OutputArgs = getNumOutputArgs(IA, CB);
8227 for (
int i = OutputArgs; i < NumOperands; i++) {
8235 for (
int i = 0; i < OutputArgs; i++) {
8241 setShadow(&
I, getCleanShadow(&
I));
8242 setOrigin(&
I, getCleanOrigin());
8245 void visitFreezeInst(FreezeInst &
I) {
8247 setShadow(&
I, getCleanShadow(&
I));
8248 setOrigin(&
I, getCleanOrigin());
8251 void visitInstruction(Instruction &
I) {
8253 if (Opts.msan_dump_strict_instructions)
8254 dumpInst(
I,
"Strict");
8256 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
8257 Value *Operand =
I.getOperand(i);
8259 insertCheckShadowOf(Operand, &
I);
8261 setShadow(&
I, getCleanShadow(&
I));
8262 setOrigin(&
I, getCleanOrigin());
8266struct VarArgHelperBase :
public VarArgHelper {
8268 MemorySanitizer &MS;
8269 MemorySanitizerVisitor &MSV;
8271 const unsigned VAListTagSize;
8273 VarArgHelperBase(
Function &
F, MemorySanitizer &MS,
8274 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
8275 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
8279 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
8285 MS.VAArgTLS, ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg_va_s");
8294 return getShadowPtrForVAArgument(IRB, ArgOffset);
8303 ConstantInt::get(MS.IntptrTy, ArgOffset),
8308 unsigned BaseOffset) {
8317 TailSize,
Align(8));
8320 void unpoisonVAListTagForInst(IntrinsicInst &
I) {
8322 Value *VAListTag =
I.getArgOperand(0);
8324 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
8325 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
8328 VAListTagSize, Alignment,
false);
8331 void visitVAStartInst(VAStartInst &
I)
override {
8332 if (
F.getCallingConv() == CallingConv::Win64)
8335 unpoisonVAListTagForInst(
I);
8338 void visitVACopyInst(VACopyInst &
I)
override {
8339 if (
F.getCallingConv() == CallingConv::Win64)
8341 unpoisonVAListTagForInst(
I);
8346struct VarArgAMD64Helper :
public VarArgHelperBase {
8349 static const unsigned AMD64GpEndOffset = 48;
8350 static const unsigned AMD64FpEndOffsetSSE = 176;
8352 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8354 unsigned AMD64FpEndOffset;
8355 AllocaInst *VAArgTLSCopy =
nullptr;
8356 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8357 Value *VAArgOverflowSize =
nullptr;
8359 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8361 VarArgAMD64Helper(
Function &
F, MemorySanitizer &MS,
8362 MemorySanitizerVisitor &MSV)
8363 : VarArgHelperBase(
F, MS, MSV, 24) {
8364 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8365 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
8366 if (Attr.isStringAttribute() &&
8367 (Attr.getKindAsString() ==
"target-features")) {
8368 if (Attr.getValueAsString().contains(
"-sse"))
8369 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8375 ArgKind classifyArgument(
Value *arg) {
8378 if (
T->isX86_FP80Ty())
8380 if (
T->isFPOrFPVectorTy())
8381 return AK_FloatingPoint;
8382 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
8383 return AK_GeneralPurpose;
8384 if (
T->isPointerTy())
8385 return AK_GeneralPurpose;
8397 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8398 unsigned GpOffset = 0;
8399 unsigned FpOffset = AMD64GpEndOffset;
8400 unsigned OverflowOffset = AMD64FpEndOffset;
8401 const DataLayout &
DL =
F.getDataLayout();
8412 assert(
A->getType()->isPointerTy());
8414 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8416 unsigned BaseOffset = OverflowOffset;
8417 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8418 Value *OriginBase =
nullptr;
8419 if (MS.TrackOrigins)
8420 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8421 OverflowOffset += AlignedSize;
8424 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8428 Value *ShadowPtr, *OriginPtr;
8429 std::tie(ShadowPtr, OriginPtr) =
8434 if (MS.TrackOrigins)
8438 ArgKind AK = classifyArgument(
A);
8439 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8441 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8443 Value *ShadowBase, *OriginBase =
nullptr;
8445 case AK_GeneralPurpose:
8446 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8447 if (MS.TrackOrigins)
8448 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8452 case AK_FloatingPoint:
8453 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8454 if (MS.TrackOrigins)
8455 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8462 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8464 unsigned BaseOffset = OverflowOffset;
8465 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8466 if (MS.TrackOrigins) {
8467 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8469 OverflowOffset += AlignedSize;
8472 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8481 Value *Shadow = MSV.getShadow(
A);
8483 if (MS.TrackOrigins) {
8484 Value *Origin = MSV.getOrigin(
A);
8485 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8486 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8492 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8493 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8496 void finalizeInstrumentation()
override {
8497 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8498 "finalizeInstrumentation called twice");
8499 if (!VAStartInstrumentationList.
empty()) {
8506 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8507 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8513 Intrinsic::umin, CopySize,
8517 if (MS.TrackOrigins) {
8518 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8527 for (CallInst *OrigInst : VAStartInstrumentationList) {
8528 NextNodeIRBuilder IRB(OrigInst);
8529 Value *VAListTag = OrigInst->getArgOperand(0);
8531 Value *RegSaveAreaPtrPtr =
8532 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 16));
8534 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8536 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8537 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8539 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8541 if (MS.TrackOrigins)
8542 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8543 Alignment, AMD64FpEndOffset);
8544 Value *OverflowArgAreaPtrPtr =
8545 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 8));
8546 Value *OverflowArgAreaPtr =
8547 IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8548 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8549 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8550 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8554 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8556 if (MS.TrackOrigins) {
8559 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8567struct VarArgAArch64Helper :
public VarArgHelperBase {
8568 static const unsigned kAArch64GrArgSize = 64;
8569 static const unsigned kAArch64VrArgSize = 128;
8571 static const unsigned AArch64GrBegOffset = 0;
8572 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8574 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8575 static const unsigned AArch64VrEndOffset =
8576 AArch64VrBegOffset + kAArch64VrArgSize;
8577 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8579 AllocaInst *VAArgTLSCopy =
nullptr;
8580 Value *VAArgOverflowSize =
nullptr;
8582 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8584 VarArgAArch64Helper(
Function &
F, MemorySanitizer &MS,
8585 MemorySanitizerVisitor &MSV)
8586 : VarArgHelperBase(
F, MS, MSV, 32) {}
8589 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
8590 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
8591 return {AK_GeneralPurpose, 1};
8592 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
8593 return {AK_FloatingPoint, 1};
8595 if (
T->isArrayTy()) {
8596 auto R = classifyArgument(
T->getArrayElementType());
8597 R.second *=
T->getScalarType()->getArrayNumElements();
8602 auto R = classifyArgument(FV->getScalarType());
8603 R.second *= FV->getNumElements();
8608 return {AK_Memory, 0};
8620 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8621 unsigned GrOffset = AArch64GrBegOffset;
8622 unsigned VrOffset = AArch64VrBegOffset;
8623 unsigned OverflowOffset = AArch64VAEndOffset;
8625 const DataLayout &
DL =
F.getDataLayout();
8628 auto [AK, RegNum] = classifyArgument(
A->getType());
8629 if (AK == AK_GeneralPurpose &&
8630 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8632 if (AK == AK_FloatingPoint &&
8633 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8637 case AK_GeneralPurpose:
8638 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8639 GrOffset += 8 * RegNum;
8641 case AK_FloatingPoint:
8642 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8643 VrOffset += 16 * RegNum;
8650 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8652 unsigned BaseOffset = OverflowOffset;
8653 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8654 OverflowOffset += AlignedSize;
8657 CleanUnusedTLS(IRB,
Base, BaseOffset);
8669 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8670 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8675 Value *SaveAreaPtrPtr =
8676 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8677 return IRB.
CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8682 Value *SaveAreaPtr =
8683 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8685 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
8688 void finalizeInstrumentation()
override {
8689 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8690 "finalizeInstrumentation called twice");
8691 if (!VAStartInstrumentationList.empty()) {
8698 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8699 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8705 Intrinsic::umin, CopySize,
8711 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8712 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8716 for (CallInst *OrigInst : VAStartInstrumentationList) {
8717 NextNodeIRBuilder IRB(OrigInst);
8719 Value *VAListTag = OrigInst->getArgOperand(0);
8736 Value *StackSaveAreaPtr =
8737 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8740 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8741 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8744 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8747 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8748 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8751 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8757 Value *GrRegSaveAreaShadowPtrOff =
8758 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
8760 Value *GrRegSaveAreaShadowPtr =
8761 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8767 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8773 Value *VrRegSaveAreaShadowPtrOff =
8774 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
8776 Value *VrRegSaveAreaShadowPtr =
8777 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8784 VrRegSaveAreaShadowPtrOff);
8785 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8791 Value *StackSaveAreaShadowPtr =
8792 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8797 VAArgTLSCopy, IRB.
getInt32(AArch64VAEndOffset));
8800 Align(16), VAArgOverflowSize);
8806struct VarArgPowerPC64Helper :
public VarArgHelperBase {
8807 AllocaInst *VAArgTLSCopy =
nullptr;
8808 Value *VAArgSize =
nullptr;
8810 VarArgPowerPC64Helper(
Function &
F, MemorySanitizer &MS,
8811 MemorySanitizerVisitor &MSV)
8812 : VarArgHelperBase(
F, MS, MSV, 8) {}
8814 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8822 Triple TargetTriple(
F.getParent()->getTargetTriple());
8826 if (TargetTriple.isPPC64ELFv2ABI())
8830 unsigned VAArgOffset = VAArgBase;
8831 const DataLayout &
DL =
F.getDataLayout();
8836 assert(
A->getType()->isPointerTy());
8838 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8841 ArgAlign =
Align(8);
8842 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8845 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8847 Value *AShadowPtr, *AOriginPtr;
8848 std::tie(AShadowPtr, AOriginPtr) =
8849 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8859 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8861 if (
A->getType()->isArrayTy()) {
8864 Type *ElementTy =
A->getType()->getArrayElementType();
8866 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8867 }
else if (
A->getType()->isVectorTy()) {
8869 ArgAlign =
Align(ArgSize);
8872 ArgAlign =
Align(8);
8873 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8874 if (
DL.isBigEndian()) {
8878 VAArgOffset += (8 - ArgSize);
8882 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8886 VAArgOffset += ArgSize;
8890 VAArgBase = VAArgOffset;
8894 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8897 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8900 void finalizeInstrumentation()
override {
8901 assert(!VAArgSize && !VAArgTLSCopy &&
8902 "finalizeInstrumentation called twice");
8905 Value *CopySize = VAArgSize;
8907 if (!VAStartInstrumentationList.empty()) {
8911 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8917 Intrinsic::umin, CopySize,
8925 for (CallInst *OrigInst : VAStartInstrumentationList) {
8926 NextNodeIRBuilder IRB(OrigInst);
8927 Value *VAListTag = OrigInst->getArgOperand(0);
8930 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8933 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8934 const DataLayout &
DL =
F.getDataLayout();
8935 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8937 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8938 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8940 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8947struct VarArgPowerPC32Helper :
public VarArgHelperBase {
8948 AllocaInst *VAArgTLSCopy =
nullptr;
8949 Value *VAArgSize =
nullptr;
8951 VarArgPowerPC32Helper(
Function &
F, MemorySanitizer &MS,
8952 MemorySanitizerVisitor &MSV)
8953 : VarArgHelperBase(
F, MS, MSV, 12) {}
8955 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8959 unsigned VAArgOffset = VAArgBase;
8960 const DataLayout &
DL =
F.getDataLayout();
8961 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8966 assert(
A->getType()->isPointerTy());
8968 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8970 if (ArgAlign < IntptrSize)
8971 ArgAlign =
Align(IntptrSize);
8972 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8975 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8977 Value *AShadowPtr, *AOriginPtr;
8978 std::tie(AShadowPtr, AOriginPtr) =
8979 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8989 Type *ArgTy =
A->getType();
8995 uint64_t ArgSize =
DL.getTypeAllocSize(ArgTy);
9002 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
9005 ArgAlign =
Align(ArgSize);
9007 if (ArgAlign < IntptrSize)
9008 ArgAlign =
Align(IntptrSize);
9009 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9010 if (
DL.isBigEndian()) {
9013 if (ArgSize < IntptrSize)
9014 VAArgOffset += (IntptrSize - ArgSize);
9017 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
9023 VAArgOffset += ArgSize;
9030 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
9033 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9036 void finalizeInstrumentation()
override {
9037 assert(!VAArgSize && !VAArgTLSCopy &&
9038 "finalizeInstrumentation called twice");
9040 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9041 Value *CopySize = VAArgSize;
9043 if (!VAStartInstrumentationList.empty()) {
9047 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9053 Intrinsic::umin, CopySize,
9061 for (CallInst *OrigInst : VAStartInstrumentationList) {
9062 NextNodeIRBuilder IRB(OrigInst);
9063 Value *VAListTag = OrigInst->getArgOperand(0);
9065 Value *RegSaveAreaSize = CopySize;
9069 IRB.
CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
9073 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
9075 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9078 const DataLayout &
DL =
F.getDataLayout();
9079 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9083 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9084 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9085 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9087 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
9088 Alignment, RegSaveAreaSize);
9090 RegSaveAreaShadowPtr =
9093 ConstantInt::get(MS.IntptrTy, 32));
9098 ConstantInt::get(MS.IntptrTy, 32), Alignment);
9103 Value *OverflowAreaSize = IRB.
CreateSub(CopySize, RegSaveAreaSize);
9106 OverflowAreaPtrPtr =
9107 IRB.
CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
9108 OverflowAreaPtrPtr = IRB.
CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
9110 Value *OverflowAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
9112 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
9113 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
9114 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.
getInt8Ty(),
9117 Value *OverflowVAArgTLSCopyPtr =
9119 OverflowVAArgTLSCopyPtr =
9120 IRB.
CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
9122 OverflowVAArgTLSCopyPtr =
9125 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
9132struct VarArgSystemZHelper :
public VarArgHelperBase {
9133 static const unsigned SystemZGpOffset = 16;
9134 static const unsigned SystemZGpEndOffset = 56;
9135 static const unsigned SystemZFpOffset = 128;
9136 static const unsigned SystemZFpEndOffset = 160;
9137 static const unsigned SystemZMaxVrArgs = 8;
9138 static const unsigned SystemZRegSaveAreaSize = 160;
9139 static const unsigned SystemZOverflowOffset = 160;
9140 static const unsigned SystemZVAListTagSize = 32;
9141 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
9142 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
9144 bool IsSoftFloatABI;
9145 AllocaInst *VAArgTLSCopy =
nullptr;
9146 AllocaInst *VAArgTLSOriginCopy =
nullptr;
9147 Value *VAArgOverflowSize =
nullptr;
9149 enum class ArgKind {
9157 enum class ShadowExtension {
None,
Zero, Sign };
9159 VarArgSystemZHelper(
Function &
F, MemorySanitizer &MS,
9160 MemorySanitizerVisitor &MSV)
9161 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
9162 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
9164 ArgKind classifyArgument(
Type *
T) {
9171 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
9172 return ArgKind::Indirect;
9173 if (
T->isFloatingPointTy())
9174 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
9175 if (
T->isIntegerTy() ||
T->isPointerTy())
9176 return ArgKind::GeneralPurpose;
9177 if (
T->isVectorTy())
9178 return ArgKind::Vector;
9179 return ArgKind::Memory;
9182 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
9192 return ShadowExtension::Zero;
9196 return ShadowExtension::Sign;
9198 return ShadowExtension::None;
9201 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9202 unsigned GpOffset = SystemZGpOffset;
9203 unsigned FpOffset = SystemZFpOffset;
9204 unsigned VrIndex = 0;
9205 unsigned OverflowOffset = SystemZOverflowOffset;
9206 const DataLayout &
DL =
F.getDataLayout();
9212 ArgKind AK = classifyArgument(
T);
9213 if (AK == ArgKind::Indirect) {
9215 AK = ArgKind::GeneralPurpose;
9217 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
9218 AK = ArgKind::Memory;
9219 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
9220 AK = ArgKind::Memory;
9221 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
9222 AK = ArgKind::Memory;
9223 Value *ShadowBase =
nullptr;
9224 Value *OriginBase =
nullptr;
9225 ShadowExtension SE = ShadowExtension::None;
9227 case ArgKind::GeneralPurpose: {
9232 SE = getShadowExtension(CB, ArgNo);
9234 if (SE == ShadowExtension::None) {
9236 assert(ArgAllocSize <= ArgSize);
9237 GapSize = ArgSize - ArgAllocSize;
9239 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
9240 if (MS.TrackOrigins)
9241 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
9243 GpOffset += ArgSize;
9249 case ArgKind::FloatingPoint: {
9258 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
9259 if (MS.TrackOrigins)
9260 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
9262 FpOffset += ArgSize;
9268 case ArgKind::Vector: {
9275 case ArgKind::Memory: {
9283 SE = getShadowExtension(CB, ArgNo);
9285 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
9287 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
9288 if (MS.TrackOrigins)
9290 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
9291 OverflowOffset += ArgSize;
9298 case ArgKind::Indirect:
9301 if (ShadowBase ==
nullptr)
9303 Value *Shadow = MSV.getShadow(
A);
9304 if (SE != ShadowExtension::None)
9305 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
9306 SE == ShadowExtension::Sign);
9307 ShadowBase = IRB.
CreateIntToPtr(ShadowBase, MS.PtrTy,
"_msarg_va_s");
9309 if (MS.TrackOrigins) {
9310 Value *Origin = MSV.getOrigin(
A);
9311 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
9312 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
9316 Constant *OverflowSize = ConstantInt::get(
9317 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
9318 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
9325 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
9328 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9330 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9331 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
9336 unsigned RegSaveAreaSize =
9337 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9338 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9340 if (MS.TrackOrigins)
9341 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9342 Alignment, RegSaveAreaSize);
9351 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9353 Value *OverflowArgAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9354 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9356 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9357 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
9360 SystemZOverflowOffset);
9361 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9363 if (MS.TrackOrigins) {
9365 SystemZOverflowOffset);
9366 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9371 void finalizeInstrumentation()
override {
9372 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9373 "finalizeInstrumentation called twice");
9374 if (!VAStartInstrumentationList.empty()) {
9381 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9383 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9389 Intrinsic::umin, CopySize,
9393 if (MS.TrackOrigins) {
9394 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9403 for (CallInst *OrigInst : VAStartInstrumentationList) {
9404 NextNodeIRBuilder IRB(OrigInst);
9405 Value *VAListTag = OrigInst->getArgOperand(0);
9406 copyRegSaveArea(IRB, VAListTag);
9407 copyOverflowArea(IRB, VAListTag);
9413struct VarArgI386Helper :
public VarArgHelperBase {
9414 AllocaInst *VAArgTLSCopy =
nullptr;
9415 Value *VAArgSize =
nullptr;
9417 VarArgI386Helper(
Function &
F, MemorySanitizer &MS,
9418 MemorySanitizerVisitor &MSV)
9419 : VarArgHelperBase(
F, MS, MSV, 4) {}
9421 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9422 const DataLayout &
DL =
F.getDataLayout();
9423 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9424 unsigned VAArgOffset = 0;
9429 assert(
A->getType()->isPointerTy());
9431 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9433 if (ArgAlign < IntptrSize)
9434 ArgAlign =
Align(IntptrSize);
9435 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9437 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9439 Value *AShadowPtr, *AOriginPtr;
9440 std::tie(AShadowPtr, AOriginPtr) =
9441 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9451 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9453 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9454 if (
DL.isBigEndian()) {
9457 if (ArgSize < IntptrSize)
9458 VAArgOffset += (IntptrSize - ArgSize);
9461 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9464 VAArgOffset += ArgSize;
9470 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9473 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9476 void finalizeInstrumentation()
override {
9477 assert(!VAArgSize && !VAArgTLSCopy &&
9478 "finalizeInstrumentation called twice");
9480 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9481 Value *CopySize = VAArgSize;
9483 if (!VAStartInstrumentationList.empty()) {
9486 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9492 Intrinsic::umin, CopySize,
9500 for (CallInst *OrigInst : VAStartInstrumentationList) {
9501 NextNodeIRBuilder IRB(OrigInst);
9502 Value *VAListTag = OrigInst->getArgOperand(0);
9503 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9504 Value *RegSaveAreaPtrPtr =
9506 PointerType::get(*MS.C, 0));
9507 Value *RegSaveAreaPtr =
9508 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9509 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9510 const DataLayout &
DL =
F.getDataLayout();
9511 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9513 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9514 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9516 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9524struct VarArgGenericHelper :
public VarArgHelperBase {
9525 AllocaInst *VAArgTLSCopy =
nullptr;
9526 Value *VAArgSize =
nullptr;
9528 VarArgGenericHelper(
Function &
F, MemorySanitizer &MS,
9529 MemorySanitizerVisitor &MSV,
const unsigned VAListTagSize)
9530 : VarArgHelperBase(
F, MS, MSV, VAListTagSize) {}
9532 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9533 unsigned VAArgOffset = 0;
9534 const DataLayout &
DL =
F.getDataLayout();
9535 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9540 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9541 if (
DL.isBigEndian()) {
9544 if (ArgSize < IntptrSize)
9545 VAArgOffset += (IntptrSize - ArgSize);
9547 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9548 VAArgOffset += ArgSize;
9549 VAArgOffset =
alignTo(VAArgOffset, IntptrSize);
9555 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9558 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9561 void finalizeInstrumentation()
override {
9562 assert(!VAArgSize && !VAArgTLSCopy &&
9563 "finalizeInstrumentation called twice");
9565 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9566 Value *CopySize = VAArgSize;
9568 if (!VAStartInstrumentationList.empty()) {
9571 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9577 Intrinsic::umin, CopySize,
9585 for (CallInst *OrigInst : VAStartInstrumentationList) {
9586 NextNodeIRBuilder IRB(OrigInst);
9587 Value *VAListTag = OrigInst->getArgOperand(0);
9588 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9589 Value *RegSaveAreaPtrPtr =
9591 PointerType::get(*MS.C, 0));
9592 Value *RegSaveAreaPtr =
9593 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9594 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9595 const DataLayout &
DL =
F.getDataLayout();
9596 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9598 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9599 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9601 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9609using VarArgARM32Helper = VarArgGenericHelper;
9610using VarArgRISCVHelper = VarArgGenericHelper;
9611using VarArgMIPSHelper = VarArgGenericHelper;
9612using VarArgLoongArch64Helper = VarArgGenericHelper;
9613using VarArgHexagonHelper = VarArgGenericHelper;
9616struct VarArgNoOpHelper :
public VarArgHelper {
9617 VarArgNoOpHelper(
Function &
F, MemorySanitizer &MS,
9618 MemorySanitizerVisitor &MSV) {}
9620 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {}
9622 void visitVAStartInst(VAStartInst &
I)
override {}
9624 void visitVACopyInst(VACopyInst &
I)
override {}
9626 void finalizeInstrumentation()
override {}
9632 MemorySanitizerVisitor &Visitor) {
9635 Triple TargetTriple(Func.getParent()->getTargetTriple());
9638 return new VarArgI386Helper(Func, Msan, Visitor);
9641 return new VarArgAMD64Helper(Func, Msan, Visitor);
9643 if (TargetTriple.
isARM())
9644 return new VarArgARM32Helper(Func, Msan, Visitor, 4);
9647 return new VarArgAArch64Helper(Func, Msan, Visitor);
9650 return new VarArgSystemZHelper(Func, Msan, Visitor);
9655 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9658 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9661 return new VarArgRISCVHelper(Func, Msan, Visitor, 4);
9664 return new VarArgRISCVHelper(Func, Msan, Visitor, 8);
9667 return new VarArgMIPSHelper(Func, Msan, Visitor, 4);
9670 return new VarArgMIPSHelper(Func, Msan, Visitor, 8);
9673 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9677 return new VarArgHexagonHelper(Func, Msan, Visitor, 12);
9679 return new VarArgNoOpHelper(Func, Msan, Visitor);
9686 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9689 MemorySanitizerVisitor Visitor(
F, *
this, TLI);
9696 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 const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static const unsigned kOriginSize
static const Align kShadowTLSAlignment
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P
static const MemoryMapParams Linux_I386_MemoryMapParams
const char kMsanInitName[]
static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams
static GlobalVariable * createPrivateConstGlobalForString(Module &M, StringRef Str)
Create a non-const global initialized with the given string.
static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams
static const size_t kNumberOfAccessSizes
static VarArgHelper * CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, MemorySanitizerVisitor &Visitor)
static const MemoryMapParams Linux_MIPS64_MemoryMapParams
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
static const MemoryMapParams Linux_Hexagon_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams
static const unsigned kParamTLSSize
static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
static const unsigned kRetvalTLSSize
static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams
const char kMsanModuleCtorName[]
static const MemoryMapParams FreeBSD_I386_MemoryMapParams
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
const SmallVectorImpl< MachineOperand > & Cond
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
void setAlignment(Align Align)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
const T & front() const
Get the first element.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
void removeFnAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the function.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Value * getCalledOperand() const
Type * getParamElementType(unsigned ArgNo) const
Extract the elementtype type for a parameter.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_SGT
signed greater than
@ ICMP_SGE
signed greater or equal
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true, bool ByteString=false)
This method constructs a CDS and initializes it with a text string.
static LLVM_ABI Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
static bool shouldExecute(CounterInfo &Counter)
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
static FixedVectorType * getHalfElementsVectorType(FixedVectorType *VTy)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
LLVM_ABI void setComdat(Comdat *C)
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ ExternalLinkage
Externally visible function.
Analysis pass providing a never-invalidated alias analysis result.
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
LLVM_ABI Value * CreateAndReduce(Value *Src)
Create a vector int AND reduction intrinsic of the source vector.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
LLVM_ABI CallInst * CreateMaskedCompressStore(Value *Val, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr)
Create a call to Masked Compress Store intrinsic.
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
IntegerType * getInt16Ty()
Fetch the type representing a 16-bit integer.
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
LLVM_ABI Value * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI DebugLoc getCurrentDebugLocation() const
Get location information used by debugging information.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memset to the specified pointer and the specified value.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
LLVMContext & getContext() const
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
LLVM_ABI CallInst * CreateMaskedStore(Value *Val, Value *Ptr, Align Alignment, Value *Mask)
Create a call to Masked Store intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
LLVM_ABI CallInst * CreateMaskedExpandLoad(Type *Ty, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Expand Load intrinsic.
Value * CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name="")
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LLVM_ABI CallInst * CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment, Value *Mask=nullptr)
Create a call to Masked Scatter intrinsic.
LLVM_ABI CallInst * CreateMaskedGather(Type *Ty, Value *Ptrs, Align Alignment, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Gather intrinsic.
Value * CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
std::vector< ConstraintInfo > ConstraintInfoVector
void visit(Iterator Start, Iterator End)
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
A Module instance is used to store all the information related to an LLVM module.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
bool remove(const value_type &X)
Remove an item from the set vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
LibFunc getLibFunc(StringRef funcName) const
Searches for a particular function name.
Triple - Helper class for working with autoconf configuration names.
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
bool isRISCV32() const
Tests whether the target is 32-bit RISC-V.
bool isPPC32() const
Tests whether the target is 32-bit PowerPC (little and big endian).
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isRISCV64() const
Tests whether the target is 64-bit RISC-V.
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
bool isARM() const
Tests whether the target is ARM (little and big endian).
bool isPPC64() const
Tests whether the target is 64-bit PowerPC (little and big endian).
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
bool isSystemZ() const
Tests whether the target is SystemZ.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isArrayTy() const
True if this is an instance of ArrayType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isPointerTy() const
True if this is an instance of PointerType.
Type * getArrayElementType() const
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
bool isVoidTy() const
Return true if this is 'void'.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
LLVM_ABI StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
Function * Kernel
Summary of a kernel (=entry point for target offloading).
NodeAddr< FuncNode * > Func
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
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)