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);
4196 void handleVectorReduceOrIntrinsic(IntrinsicInst &
I) {
4200 Value *OperandShadow = getShadow(&
I, 0);
4202 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
4210 setOrigin(&
I, getOrigin(&
I, 0));
4216 void handleVectorReduceAndIntrinsic(IntrinsicInst &
I) {
4220 Value *OperandShadow = getShadow(&
I, 0);
4221 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
4229 setOrigin(&
I, getOrigin(&
I, 0));
4232 void handleStmxcsr(IntrinsicInst &
I) {
4234 Value *Addr =
I.getArgOperand(0);
4237 getShadowOriginPtr(Addr, IRB, Ty,
Align(1),
true).first;
4241 if (Opts.msan_check_access_address)
4242 insertCheckShadowOf(Addr, &
I);
4245 void handleLdmxcsr(IntrinsicInst &
I) {
4250 Value *Addr =
I.getArgOperand(0);
4253 Value *ShadowPtr, *OriginPtr;
4254 std::tie(ShadowPtr, OriginPtr) =
4255 getShadowOriginPtr(Addr, IRB, Ty, Alignment,
false);
4257 if (Opts.msan_check_access_address)
4258 insertCheckShadowOf(Addr, &
I);
4261 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
4263 insertCheckShadow(Shadow, Origin, &
I);
4266 void handleMaskedExpandLoad(IntrinsicInst &
I) {
4268 Value *Ptr =
I.getArgOperand(0);
4269 MaybeAlign
Align =
I.getParamAlign(0);
4271 Value *PassThru =
I.getArgOperand(2);
4273 if (Opts.msan_check_access_address) {
4274 insertCheckShadowOf(Ptr, &
I);
4275 insertCheckShadowOf(Mask, &
I);
4278 if (!PropagateShadow) {
4279 setShadow(&
I, getCleanShadow(&
I));
4280 setOrigin(&
I, getCleanOrigin());
4284 Type *ShadowTy = getShadowTy(&
I);
4286 auto [ShadowPtr, OriginPtr] =
4287 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
false);
4291 getShadow(PassThru),
"_msmaskedexpload");
4293 setShadow(&
I, Shadow);
4296 setOrigin(&
I, getCleanOrigin());
4299 void handleMaskedCompressStore(IntrinsicInst &
I) {
4302 Value *Ptr =
I.getArgOperand(1);
4303 MaybeAlign
Align =
I.getParamAlign(1);
4306 if (Opts.msan_check_access_address) {
4307 insertCheckShadowOf(Ptr, &
I);
4308 insertCheckShadowOf(Mask, &
I);
4312 Type *ElementShadowTy =
4314 auto [ShadowPtr, OriginPtrs] =
4315 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
true);
4322 void handleMaskedGather(IntrinsicInst &
I) {
4324 Value *Ptrs =
I.getArgOperand(0);
4327 Value *PassThru =
I.getArgOperand(2);
4329 Type *PtrsShadowTy = getShadowTy(Ptrs);
4330 if (Opts.msan_check_access_address) {
4331 insertCheckShadowOf(Mask, &
I);
4335 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4338 if (!PropagateShadow) {
4339 setShadow(&
I, getCleanShadow(&
I));
4340 setOrigin(&
I, getCleanOrigin());
4344 Type *ShadowTy = getShadowTy(&
I);
4346 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4347 Ptrs, IRB, ElementShadowTy, Alignment,
false);
4351 getShadow(PassThru),
"_msmaskedgather");
4353 setShadow(&
I, Shadow);
4356 setOrigin(&
I, getCleanOrigin());
4359 void handleMaskedScatter(IntrinsicInst &
I) {
4362 Value *Ptrs =
I.getArgOperand(1);
4366 Type *PtrsShadowTy = getShadowTy(Ptrs);
4367 if (Opts.msan_check_access_address) {
4368 insertCheckShadowOf(Mask, &
I);
4372 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4376 Type *ElementShadowTy =
4378 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4379 Ptrs, IRB, ElementShadowTy, Alignment,
true);
4390 void handleMaskedStore(IntrinsicInst &
I) {
4392 Value *
V =
I.getArgOperand(0);
4393 Value *Ptr =
I.getArgOperand(1);
4396 Value *Shadow = getShadow(V);
4398 if (Opts.msan_check_access_address) {
4399 insertCheckShadowOf(Ptr, &
I);
4400 insertCheckShadowOf(Mask, &
I);
4405 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4406 Ptr, IRB, Shadow->
getType(), Alignment,
true);
4410 if (!MS.TrackOrigins)
4413 auto &
DL =
F.getDataLayout();
4414 paintOrigin(IRB, getOrigin(V), OriginPtr,
4423 void handleMaskedLoad(IntrinsicInst &
I) {
4425 Value *Ptr =
I.getArgOperand(0);
4428 Value *PassThru =
I.getArgOperand(2);
4430 if (Opts.msan_check_access_address) {
4431 insertCheckShadowOf(Ptr, &
I);
4432 insertCheckShadowOf(Mask, &
I);
4435 if (!PropagateShadow) {
4436 setShadow(&
I, getCleanShadow(&
I));
4437 setOrigin(&
I, getCleanOrigin());
4441 Type *ShadowTy = getShadowTy(&
I);
4442 Value *ShadowPtr, *OriginPtr;
4443 std::tie(ShadowPtr, OriginPtr) =
4444 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment,
false);
4446 getShadow(PassThru),
"_msmaskedld"));
4448 if (!MS.TrackOrigins)
4455 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
4460 setOrigin(&
I, Origin);
4470 void handleMaskedIntegerDivRem(IntrinsicInst &
I) {
4473 Value *Dividend =
I.getArgOperand(0);
4474 Value *Divisor =
I.getArgOperand(1);
4477 insertCheckShadowOf(Mask, &
I);
4480 Mask, getShadow(Divisor), getCleanShadow(Divisor),
"_msmaskeddivisor");
4481 insertCheckShadow(MaskedDivisorShadow, getOrigin(Divisor), &
I);
4483 if (!PropagateShadow) {
4484 setShadow(&
I, getCleanShadow(&
I));
4485 setOrigin(&
I, getCleanOrigin());
4490 getPoisonedShadow(&
I),
"_msmaskeddiv"));
4491 setOrigin(&
I, getOrigin(Dividend));
4507 void handleAVXMaskedStore(IntrinsicInst &
I) {
4512 Value *Dst =
I.getArgOperand(0);
4513 assert(Dst->getType()->isPointerTy() &&
"Destination is not a pointer!");
4518 Value *Src =
I.getArgOperand(2);
4523 Value *SrcShadow = getShadow(Src);
4525 if (Opts.msan_check_access_address) {
4526 insertCheckShadowOf(Dst, &
I);
4527 insertCheckShadowOf(Mask, &
I);
4530 Value *DstShadowPtr;
4531 Value *DstOriginPtr;
4532 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4533 Dst, IRB, SrcShadow->
getType(), Alignment,
true);
4535 SmallVector<Value *, 2> ShadowArgs;
4536 ShadowArgs.
append(1, DstShadowPtr);
4537 ShadowArgs.
append(1, Mask);
4545 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
4548 if (!MS.TrackOrigins)
4552 auto &
DL =
F.getDataLayout();
4553 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4554 DL.getTypeStoreSize(SrcShadow->
getType()),
4573 void handleAVXMaskedLoad(IntrinsicInst &
I) {
4578 Value *Src =
I.getArgOperand(0);
4579 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
4586 if (Opts.msan_check_access_address) {
4587 insertCheckShadowOf(Mask, &
I);
4590 Type *SrcShadowTy = getShadowTy(Src);
4591 Value *SrcShadowPtr, *SrcOriginPtr;
4592 std::tie(SrcShadowPtr, SrcOriginPtr) =
4593 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment,
false);
4595 SmallVector<Value *, 2> ShadowArgs;
4596 ShadowArgs.
append(1, SrcShadowPtr);
4597 ShadowArgs.
append(1, Mask);
4600 I.getType(),
I.getIntrinsicID(), ShadowArgs);
4606 if (!MS.TrackOrigins)
4613 setOrigin(&
I, PtrSrcOrigin);
4622 assert(isFixedIntVector(Idx));
4623 auto IdxVectorSize =
4631 auto *IdxShadow = getShadow(Idx);
4636 insertCheckShadow(Truncated, getOrigin(Idx),
I);
4641 void handleAVXVpermilvar(IntrinsicInst &
I) {
4643 Value *Shadow = getShadow(&
I, 0);
4644 maskedCheckAVXIndexShadow(IRB,
I.getArgOperand(1), &
I);
4648 Shadow = IRB.
CreateBitCast(Shadow,
I.getArgOperand(0)->getType());
4650 I.getType(),
I.getIntrinsicID(), {Shadow, I.getArgOperand(1)});
4653 setOriginForNaryOp(
I);
4658 void handleAVXVpermi2var(IntrinsicInst &
I) {
4663 [[maybe_unused]]
auto ArgVectorSize =
4666 ->getNumElements() == ArgVectorSize);
4668 ->getNumElements() == ArgVectorSize);
4669 assert(
I.getArgOperand(0)->getType() ==
I.getArgOperand(2)->getType());
4670 assert(
I.getType() ==
I.getArgOperand(0)->getType());
4671 assert(
I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4673 Value *AShadow = getShadow(&
I, 0);
4675 Value *BShadow = getShadow(&
I, 2);
4677 maskedCheckAVXIndexShadow(IRB, Idx, &
I);
4681 AShadow = IRB.
CreateBitCast(AShadow,
I.getArgOperand(0)->getType());
4682 BShadow = IRB.
CreateBitCast(BShadow,
I.getArgOperand(2)->getType());
4684 I.getType(),
I.getIntrinsicID(), {AShadow, Idx, BShadow});
4686 setOriginForNaryOp(
I);
4689 [[maybe_unused]]
static bool isFixedIntVectorTy(
const Type *
T) {
4693 [[maybe_unused]]
static bool isFixedFPVectorTy(
const Type *
T) {
4697 [[maybe_unused]]
static bool isFixedIntVector(
const Value *V) {
4698 return isFixedIntVectorTy(
V->getType());
4701 [[maybe_unused]]
static bool isFixedFPVector(
const Value *V) {
4702 return isFixedFPVectorTy(
V->getType());
4724 void handleAVX512VectorConvertFPToInt(IntrinsicInst &
I,
bool LastMask) {
4729 Value *WriteThrough;
4733 WriteThrough =
I.getOperand(2);
4734 Mask =
I.getOperand(3);
4737 WriteThrough =
I.getOperand(1);
4738 Mask =
I.getOperand(2);
4743 assert(isFixedIntVector(WriteThrough));
4745 unsigned ANumElements =
4747 [[maybe_unused]]
unsigned WriteThruNumElements =
4749 assert(ANumElements == WriteThruNumElements ||
4750 ANumElements * 2 == WriteThruNumElements);
4753 unsigned MaskNumElements =
Mask->getType()->getScalarSizeInBits();
4754 assert(ANumElements == MaskNumElements ||
4755 ANumElements * 2 == MaskNumElements);
4757 assert(WriteThruNumElements == MaskNumElements);
4761 insertCheckShadowOf(Mask, &
I);
4771 Value *AShadow = getShadow(
A);
4772 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
4774 if (ANumElements * 2 == MaskNumElements) {
4786 "_ms_mask_bitcast");
4796 getShadowTy(&
I),
"_ms_a_shadow");
4798 Value *WriteThroughShadow = getShadow(WriteThrough);
4800 "_ms_writethru_select");
4802 setShadow(&
I, Shadow);
4803 setOriginForNaryOp(
I);
4806 static SmallVector<int, 8> getPclmulMask(
unsigned Width,
bool OddElements) {
4807 SmallVector<int, 8>
Mask;
4808 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
4822 void handlePclmulIntrinsic(IntrinsicInst &
I) {
4827 "pclmul 3rd operand must be a constant");
4830 getPclmulMask(Width,
Imm & 0x01));
4832 getPclmulMask(Width,
Imm & 0x10));
4833 ShadowAndOriginCombiner SOC(
this, IRB);
4834 SOC.Add(Shuf0, getOrigin(&
I, 0));
4835 SOC.Add(Shuf1, getOrigin(&
I, 1));
4840 void handleUnarySdSsIntrinsic(IntrinsicInst &
I) {
4845 Value *Second = getShadow(&
I, 1);
4847 SmallVector<int, 16>
Mask;
4848 Mask.push_back(Width);
4849 for (
unsigned i = 1; i < Width; i++)
4853 setShadow(&
I, Shadow);
4854 setOriginForNaryOp(
I);
4857 void handleVtestIntrinsic(IntrinsicInst &
I) {
4859 Value *Shadow0 = getShadow(&
I, 0);
4860 Value *Shadow1 = getShadow(&
I, 1);
4866 setShadow(&
I, Shadow);
4867 setOriginForNaryOp(
I);
4870 void handleBinarySdSsIntrinsic(IntrinsicInst &
I) {
4875 Value *Second = getShadow(&
I, 1);
4878 SmallVector<int, 16>
Mask;
4879 Mask.push_back(Width);
4880 for (
unsigned i = 1; i < Width; i++)
4884 setShadow(&
I, Shadow);
4885 setOriginForNaryOp(
I);
4891 void handleRoundPdPsIntrinsic(IntrinsicInst &
I) {
4892 assert(
I.getArgOperand(0)->getType() ==
I.getType());
4897 ShadowAndOriginCombiner SC(
this, IRB);
4898 SC.Add(
I.getArgOperand(0));
4906 void handleAbsIntrinsic(IntrinsicInst &
I) {
4908 Value *Src =
I.getArgOperand(0);
4909 Value *IsIntMinPoison =
I.getArgOperand(1);
4911 assert(
I.getType()->isIntOrIntVectorTy());
4913 assert(Src->getType() ==
I.getType());
4919 Value *SrcShadow = getShadow(Src);
4923 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
4926 Value *PoisonedShadow = getPoisonedShadow(Src);
4927 Value *PoisonedIfIntMinShadow =
4930 IRB.
CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
4932 setShadow(&
I, Shadow);
4933 setOrigin(&
I, getOrigin(&
I, 0));
4936 void handleIsFpClass(IntrinsicInst &
I) {
4938 Value *Shadow = getShadow(&
I, 0);
4939 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
4940 setOrigin(&
I, getOrigin(&
I, 0));
4943 void handleArithmeticWithOverflow(IntrinsicInst &
I) {
4945 Value *Shadow0 = getShadow(&
I, 0);
4946 Value *Shadow1 = getShadow(&
I, 1);
4949 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
4955 setShadow(&
I, Shadow);
4956 setOriginForNaryOp(
I);
4959 void handleModfOrSincos(IntrinsicInst &
I) {
4961 Value *ArgShadow = getShadow(&
I, 0);
4965 setShadow(&
I, Shadow);
4966 setOrigin(&
I, getOrigin(&
I, 0));
4972 Value *Shadow = getShadow(V);
4994 void handleAVX512VectorDownConvert(IntrinsicInst &
I) {
4999 Value *WriteThrough =
I.getOperand(1);
5003 assert(isFixedIntVector(WriteThrough));
5005 unsigned ANumElements =
5007 unsigned OutputNumElements =
5009 assert(ANumElements == OutputNumElements ||
5010 ANumElements * 2 == OutputNumElements);
5020 insertCheckShadowOf(Mask, &
I);
5023 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5024 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5025 assert(
Mask->getType()->getScalarSizeInBits() == ANumElements);
5036 if (ANumElements != OutputNumElements) {
5038 Mask = IRB.
CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5045 Value *AShadow = getShadow(
A);
5049 VectorType *ShadowType = maybeShrinkVectorShadowType(
A,
I);
5059 AShadow = IRB.
CreateTrunc(AShadow, ShadowType,
"_ms_trunc_shadow");
5060 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
5062 Value *WriteThroughShadow = getShadow(WriteThrough);
5065 setShadow(&
I, Shadow);
5066 setOriginForNaryOp(
I);
5100 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &
I,
5101 SmallVector<unsigned, 4> DataIndices,
5102 unsigned WriteThruIndex,
5103 unsigned MaskIndex) {
5106 unsigned NumArgs =
I.arg_size();
5108 assert(WriteThruIndex < NumArgs);
5109 assert(MaskIndex < NumArgs);
5110 assert(WriteThruIndex != MaskIndex);
5111 Value *WriteThru =
I.getOperand(WriteThruIndex);
5113 unsigned OutputNumElements =
5118 bool isData[16] = {
false};
5120 for (
unsigned i : DataIndices) {
5122 assert(i != WriteThruIndex);
5129 [[maybe_unused]]
unsigned ANumElements =
5131 assert(ANumElements == OutputNumElements);
5136 assert(isFixedFPVector(WriteThru));
5138 for (
unsigned i = 0; i < NumArgs; ++i) {
5139 if (!isData[i] && i != WriteThruIndex) {
5142 assert(
I.getOperand(i)->getType()->isIntegerTy());
5143 insertCheckShadowOf(
I.getOperand(i), &
I);
5148 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5149 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5150 assert(
Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5157 Value *DataShadow =
nullptr;
5158 for (
unsigned i : DataIndices) {
5161 DataShadow = IRB.
CreateOr(DataShadow, getShadow(
A));
5163 DataShadow = getShadow(
A);
5171 Value *WriteThruShadow = getShadow(WriteThru);
5174 setShadow(&
I, Shadow);
5176 setOriginForNaryOp(
I);
5186 void handleAVX512FPClass(IntrinsicInst &
I) {
5191 Value *Input =
I.getOperand(0);
5192 assert(isFixedFPVector(Input));
5195 Value *Classifiers =
I.getOperand(1);
5199 assert(isFixedIntVectorTy(
I.getType()));
5205 Value *OutputShadow;
5210 OutputShadow = getCleanShadow(OutputType);
5216 OutputShadow = IRB.
CreateICmpNE(getShadow(Input), getCleanShadow(Input));
5218 setShadow(&
I, OutputShadow);
5220 setOriginForNaryOp(
I);
5230 void visitGenericScalarHalfwordInst(IntrinsicInst &
I) {
5236 Value *WriteThrough =
I.getOperand(2);
5243 insertCheckShadowOf(Mask, &
I);
5247 unsigned NumElements =
5249 assert(NumElements == 8);
5250 assert(
A->getType() ==
B->getType());
5252 assert(
Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5255 Value *ALowerShadow = extractLowerShadow(IRB,
A);
5256 Value *BLowerShadow = extractLowerShadow(IRB,
B);
5258 Value *ABLowerShadow = IRB.
CreateOr(ALowerShadow, BLowerShadow);
5260 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5267 Value *AShadow = getShadow(
A);
5268 Value *DstLowerShadow =
5269 IRB.
CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5271 AShadow, DstLowerShadow, ConstantInt::get(IRB.
getInt32Ty(), 0),
5274 setShadow(&
I, DstShadow);
5275 setOriginForNaryOp(
I);
5305 void handleAVXGF2P8Affine(IntrinsicInst &
I) {
5316 ->getScalarSizeInBits() == 8);
5318 assert(
A->getType() ==
X->getType());
5320 assert(
B->getType()->isIntegerTy());
5321 assert(
B->getType()->getScalarSizeInBits() == 8);
5323 assert(
I.getType() ==
A->getType());
5325 Value *AShadow = getShadow(
A);
5326 Value *XShadow = getShadow(
X);
5327 Value *BZeroShadow = getCleanShadow(
B);
5330 I.getType(),
I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5332 {X, AShadow, BZeroShadow});
5334 {XShadow, A, BZeroShadow});
5337 Value *BShadow = getShadow(
B);
5338 Value *BBroadcastShadow = getCleanShadow(AShadow);
5343 for (
unsigned i = 0; i < NumElements; i++)
5347 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5348 setOriginForNaryOp(
I);
5362 void handleNEONVectorLoad(IntrinsicInst &
I,
bool WithLane) {
5363 unsigned int numArgs =
I.arg_size();
5366 assert(
I.getType()->isStructTy());
5376 assert(4 <= numArgs && numArgs <= 6);
5390 for (
unsigned int i = 0; i < numArgs - 2; i++)
5391 ShadowArgs.
push_back(getShadow(
I.getArgOperand(i)));
5394 Value *LaneNumber =
I.getArgOperand(numArgs - 2);
5398 insertCheckShadowOf(LaneNumber, &
I);
5401 Value *Src =
I.getArgOperand(numArgs - 1);
5402 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
5404 Type *SrcShadowTy = getShadowTy(Src);
5405 auto [SrcShadowPtr, SrcOriginPtr] =
5406 getShadowOriginPtr(Src, IRB, SrcShadowTy,
Align(1),
false);
5413 getShadowTy(&
I),
I.getIntrinsicID(), ShadowArgs);
5416 if (!MS.TrackOrigins)
5420 setOrigin(&
I, PtrSrcOrigin);
5437 void handleNEONVectorStoreIntrinsic(IntrinsicInst &
I,
bool useLane) {
5441 int numArgOperands =
I.arg_size();
5444 assert(numArgOperands >= 1);
5445 Value *Addr =
I.getArgOperand(numArgOperands - 1);
5447 int skipTrailingOperands = 1;
5449 if (Opts.msan_check_access_address)
5450 insertCheckShadowOf(Addr, &
I);
5454 skipTrailingOperands++;
5455 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
5457 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5460 SmallVector<Value *, 8> ShadowArgs;
5462 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5464 Value *Shadow = getShadow(&
I, i);
5465 ShadowArgs.
append(1, Shadow);
5482 (numArgOperands - skipTrailingOperands));
5483 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5487 I.getArgOperand(numArgOperands - skipTrailingOperands));
5489 Value *OutputShadowPtr, *OutputOriginPtr;
5491 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5492 Addr, IRB, OutputShadowTy,
Align(1),
true);
5493 ShadowArgs.
append(1, OutputShadowPtr);
5496 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
5499 if (MS.TrackOrigins) {
5507 OriginCombiner OC(
this, IRB);
5508 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5509 OC.Add(
I.getArgOperand(i));
5511 const DataLayout &
DL =
F.getDataLayout();
5512 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
5545 void handleNEONMatrixMultiply(IntrinsicInst &
I) {
5549 Value *
R =
I.getArgOperand(0);
5550 Value *
A =
I.getArgOperand(1);
5551 Value *
B =
I.getArgOperand(2);
5553 assert(
I.getType() ==
R->getType());
5578 Value *ShadowR = getShadow(&
I, 0);
5579 Value *ShadowA = getShadow(&
I, 1);
5580 Value *ShadowB = getShadow(&
I, 2);
5598 {getCleanShadow(RTy), ShadowA, ShadowB});
5624 {RZeros, ShadowA, ShadowB});
5638 ShadowR = IRB.
CreateICmpNE(ShadowR, getCleanShadow(RTy));
5639 ShadowR = IRB.
CreateOr(ShadowAB, ShadowR);
5641 setShadow(&
I, IRB.
CreateSExt(ShadowR, getShadowTy(RTy)));
5643 setOriginForNaryOp(
I);
5683 void handleIntrinsicByApplyingToShadow(IntrinsicInst &
I,
5685 unsigned int trailingVerbatimArgs,
5686 bool forceIntegerIntrinsic) {
5689 assert(trailingVerbatimArgs <
I.arg_size());
5691 SmallVector<Value *, 8> ShadowArgs;
5693 for (
unsigned int i = 0; i <
I.arg_size() - trailingVerbatimArgs; i++) {
5694 Value *Shadow = getShadow(&
I, i);
5696 if (forceIntegerIntrinsic)
5703 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5705 Value *Arg =
I.getArgOperand(i);
5706 if (forceIntegerIntrinsic)
5711 Value *CombinedShadow;
5712 if (forceIntegerIntrinsic) {
5722 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5725 CreateShadowCast(IRB, getShadow(&
I, i), CombinedShadow->
getType());
5726 CombinedShadow = IRB.
CreateOr(Shadow, CombinedShadow,
"_msprop");
5729 setShadow(&
I, CombinedShadow);
5731 setOriginForNaryOp(
I);
5737 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &
I) {
5775 void handleNEONDotProductLaneIntrinsic(IntrinsicInst &
I,
5776 unsigned ReductionFactor) {
5780 [[maybe_unused]]
Value *VAcc =
I.getOperand(0);
5781 [[maybe_unused]]
Value *Va =
I.getOperand(1);
5782 [[maybe_unused]]
Value *Vb =
I.getOperand(2);
5783 Value *Lane =
I.getOperand(3);
5790 I.getType()->getPrimitiveSizeInBits());
5799 I.getType()->getPrimitiveSizeInBits());
5805 Value *SAcc = getShadow(&
I, 0);
5806 Value *Sa = getShadow(&
I, 1);
5807 Value *Sb = getShadow(&
I, 2);
5814 Sb, FixedVectorType::getWithSizeAndScalar(
5830 SOutput = IRB.
CreateSelect(SbClean, SOutput, getPoisonedShadow(SOutput));
5832 setShadow(&
I, SOutput);
5833 setOriginForNaryOp(
I);
5836 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &
I) {
5837 switch (
I.getIntrinsicID()) {
5838 case Intrinsic::uadd_with_overflow:
5839 case Intrinsic::sadd_with_overflow:
5840 case Intrinsic::usub_with_overflow:
5841 case Intrinsic::ssub_with_overflow:
5842 case Intrinsic::umul_with_overflow:
5843 case Intrinsic::smul_with_overflow:
5844 handleArithmeticWithOverflow(
I);
5846 case Intrinsic::modf:
5847 case Intrinsic::sincos:
5848 case Intrinsic::sincospi:
5849 handleModfOrSincos(
I);
5851 case Intrinsic::abs:
5852 handleAbsIntrinsic(
I);
5854 case Intrinsic::bitreverse:
5855 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
5859 case Intrinsic::is_fpclass:
5862 case Intrinsic::lifetime_start:
5863 handleLifetimeStart(
I);
5865 case Intrinsic::launder_invariant_group:
5866 handleInvariantGroup(
I);
5868 case Intrinsic::bswap:
5871 case Intrinsic::ctlz:
5872 case Intrinsic::cttz:
5873 handleCountLeadingTrailingZeros(
I);
5875 case Intrinsic::masked_compressstore:
5876 handleMaskedCompressStore(
I);
5878 case Intrinsic::masked_expandload:
5879 handleMaskedExpandLoad(
I);
5881 case Intrinsic::masked_gather:
5882 handleMaskedGather(
I);
5884 case Intrinsic::masked_scatter:
5885 handleMaskedScatter(
I);
5887 case Intrinsic::masked_store:
5888 handleMaskedStore(
I);
5890 case Intrinsic::masked_load:
5891 handleMaskedLoad(
I);
5893 case Intrinsic::masked_udiv:
5894 case Intrinsic::masked_sdiv:
5895 case Intrinsic::masked_urem:
5896 case Intrinsic::masked_srem:
5897 handleMaskedIntegerDivRem(
I);
5899 case Intrinsic::vector_reduce_and:
5900 handleVectorReduceAndIntrinsic(
I);
5902 case Intrinsic::vector_reduce_or:
5903 handleVectorReduceOrIntrinsic(
I);
5906 case Intrinsic::vector_reduce_add:
5907 case Intrinsic::vector_reduce_xor:
5908 case Intrinsic::vector_reduce_mul:
5911 case Intrinsic::vector_reduce_smax:
5912 case Intrinsic::vector_reduce_smin:
5913 case Intrinsic::vector_reduce_umax:
5914 case Intrinsic::vector_reduce_umin:
5917 case Intrinsic::vector_reduce_fmax:
5918 case Intrinsic::vector_reduce_fmin:
5919 handleVectorReduceIntrinsic(
I,
false);
5922 case Intrinsic::vector_reduce_fadd:
5923 case Intrinsic::vector_reduce_fmul:
5924 handleVectorReduceWithStarterIntrinsic(
I);
5927 case Intrinsic::scmp:
5928 case Intrinsic::ucmp: {
5933 case Intrinsic::fshl:
5934 case Intrinsic::fshr:
5935 handleFunnelShift(
I);
5938 case Intrinsic::pdep:
5939 case Intrinsic::pext:
5940 handleGenericBitManipulation(
I);
5943 case Intrinsic::is_constant:
5945 setShadow(&
I, getCleanShadow(&
I));
5946 setOrigin(&
I, getCleanOrigin());
5953 case Intrinsic::fptosi_sat:
5954 case Intrinsic::fptoui_sat:
5955 handleGenericVectorConvertIntrinsic(
I,
false);
5962 case Intrinsic::fake_use:
5963 assert(
I.getType()->isVoidTy());
5976 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &
I) {
5977 switch (
I.getIntrinsicID()) {
5978 case Intrinsic::x86_sse_stmxcsr:
5981 case Intrinsic::x86_sse_ldmxcsr:
5988 case Intrinsic::x86_avx512_vcvtsd2usi64:
5989 case Intrinsic::x86_avx512_vcvtsd2usi32:
5990 case Intrinsic::x86_avx512_vcvtss2usi64:
5991 case Intrinsic::x86_avx512_vcvtss2usi32:
5992 case Intrinsic::x86_avx512_cvttss2usi64:
5993 case Intrinsic::x86_avx512_cvttss2usi:
5994 case Intrinsic::x86_avx512_cvttsd2usi64:
5995 case Intrinsic::x86_avx512_cvttsd2usi:
5996 case Intrinsic::x86_avx512_cvtusi2ss:
5997 case Intrinsic::x86_avx512_cvtusi642sd:
5998 case Intrinsic::x86_avx512_cvtusi642ss:
5999 handleSSEVectorConvertIntrinsic(
I, 1,
true);
6001 case Intrinsic::x86_sse2_cvtsd2si64:
6002 case Intrinsic::x86_sse2_cvtsd2si:
6003 case Intrinsic::x86_sse2_cvtsd2ss:
6004 case Intrinsic::x86_sse2_cvttsd2si64:
6005 case Intrinsic::x86_sse2_cvttsd2si:
6006 case Intrinsic::x86_sse_cvtss2si64:
6007 case Intrinsic::x86_sse_cvtss2si:
6008 case Intrinsic::x86_sse_cvttss2si64:
6009 case Intrinsic::x86_sse_cvttss2si:
6010 handleSSEVectorConvertIntrinsic(
I, 1);
6012 case Intrinsic::x86_sse_cvtps2pi:
6013 case Intrinsic::x86_sse_cvttps2pi:
6014 handleSSEVectorConvertIntrinsic(
I, 2);
6022 case Intrinsic::x86_vcvtps2ph_128:
6023 case Intrinsic::x86_vcvtps2ph_256: {
6024 handleSSEVectorConvertIntrinsicByProp(
I,
true);
6033 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
6034 handleAVX512VectorConvertFPToInt(
I,
false);
6039 case Intrinsic::x86_sse2_cvtpd2ps:
6040 case Intrinsic::x86_sse2_cvtps2dq:
6041 case Intrinsic::x86_sse2_cvtpd2dq:
6042 case Intrinsic::x86_sse2_cvttps2dq:
6043 case Intrinsic::x86_sse2_cvttpd2dq:
6044 case Intrinsic::x86_avx_cvt_pd2_ps_256:
6045 case Intrinsic::x86_avx_cvt_ps2dq_256:
6046 case Intrinsic::x86_avx_cvt_pd2dq_256:
6047 case Intrinsic::x86_avx_cvtt_ps2dq_256:
6048 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
6049 handleSSEVectorConvertIntrinsicByProp(
I,
false);
6060 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
6061 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
6062 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
6063 handleAVX512VectorConvertFPToInt(
I,
true);
6067 case Intrinsic::x86_avx512_psll_w_512:
6068 case Intrinsic::x86_avx512_psll_d_512:
6069 case Intrinsic::x86_avx512_psll_q_512:
6070 case Intrinsic::x86_avx512_pslli_w_512:
6071 case Intrinsic::x86_avx512_pslli_d_512:
6072 case Intrinsic::x86_avx512_pslli_q_512:
6073 case Intrinsic::x86_avx512_psrl_w_512:
6074 case Intrinsic::x86_avx512_psrl_d_512:
6075 case Intrinsic::x86_avx512_psrl_q_512:
6076 case Intrinsic::x86_avx512_psra_w_512:
6077 case Intrinsic::x86_avx512_psra_d_512:
6078 case Intrinsic::x86_avx512_psra_q_512:
6079 case Intrinsic::x86_avx512_psrli_w_512:
6080 case Intrinsic::x86_avx512_psrli_d_512:
6081 case Intrinsic::x86_avx512_psrli_q_512:
6082 case Intrinsic::x86_avx512_psrai_w_512:
6083 case Intrinsic::x86_avx512_psrai_d_512:
6084 case Intrinsic::x86_avx512_psrai_q_512:
6085 case Intrinsic::x86_avx512_psra_q_256:
6086 case Intrinsic::x86_avx512_psra_q_128:
6087 case Intrinsic::x86_avx512_psrai_q_256:
6088 case Intrinsic::x86_avx512_psrai_q_128:
6089 case Intrinsic::x86_avx2_psll_w:
6090 case Intrinsic::x86_avx2_psll_d:
6091 case Intrinsic::x86_avx2_psll_q:
6092 case Intrinsic::x86_avx2_pslli_w:
6093 case Intrinsic::x86_avx2_pslli_d:
6094 case Intrinsic::x86_avx2_pslli_q:
6095 case Intrinsic::x86_avx2_psrl_w:
6096 case Intrinsic::x86_avx2_psrl_d:
6097 case Intrinsic::x86_avx2_psrl_q:
6098 case Intrinsic::x86_avx2_psra_w:
6099 case Intrinsic::x86_avx2_psra_d:
6100 case Intrinsic::x86_avx2_psrli_w:
6101 case Intrinsic::x86_avx2_psrli_d:
6102 case Intrinsic::x86_avx2_psrli_q:
6103 case Intrinsic::x86_avx2_psrai_w:
6104 case Intrinsic::x86_avx2_psrai_d:
6105 case Intrinsic::x86_sse2_psll_w:
6106 case Intrinsic::x86_sse2_psll_d:
6107 case Intrinsic::x86_sse2_psll_q:
6108 case Intrinsic::x86_sse2_pslli_w:
6109 case Intrinsic::x86_sse2_pslli_d:
6110 case Intrinsic::x86_sse2_pslli_q:
6111 case Intrinsic::x86_sse2_psrl_w:
6112 case Intrinsic::x86_sse2_psrl_d:
6113 case Intrinsic::x86_sse2_psrl_q:
6114 case Intrinsic::x86_sse2_psra_w:
6115 case Intrinsic::x86_sse2_psra_d:
6116 case Intrinsic::x86_sse2_psrli_w:
6117 case Intrinsic::x86_sse2_psrli_d:
6118 case Intrinsic::x86_sse2_psrli_q:
6119 case Intrinsic::x86_sse2_psrai_w:
6120 case Intrinsic::x86_sse2_psrai_d:
6121 case Intrinsic::x86_mmx_psll_w:
6122 case Intrinsic::x86_mmx_psll_d:
6123 case Intrinsic::x86_mmx_psll_q:
6124 case Intrinsic::x86_mmx_pslli_w:
6125 case Intrinsic::x86_mmx_pslli_d:
6126 case Intrinsic::x86_mmx_pslli_q:
6127 case Intrinsic::x86_mmx_psrl_w:
6128 case Intrinsic::x86_mmx_psrl_d:
6129 case Intrinsic::x86_mmx_psrl_q:
6130 case Intrinsic::x86_mmx_psra_w:
6131 case Intrinsic::x86_mmx_psra_d:
6132 case Intrinsic::x86_mmx_psrli_w:
6133 case Intrinsic::x86_mmx_psrli_d:
6134 case Intrinsic::x86_mmx_psrli_q:
6135 case Intrinsic::x86_mmx_psrai_w:
6136 case Intrinsic::x86_mmx_psrai_d:
6137 handleVectorShiftIntrinsic(
I,
false);
6139 case Intrinsic::x86_avx2_psllv_d:
6140 case Intrinsic::x86_avx2_psllv_d_256:
6141 case Intrinsic::x86_avx512_psllv_d_512:
6142 case Intrinsic::x86_avx2_psllv_q:
6143 case Intrinsic::x86_avx2_psllv_q_256:
6144 case Intrinsic::x86_avx512_psllv_q_512:
6145 case Intrinsic::x86_avx2_psrlv_d:
6146 case Intrinsic::x86_avx2_psrlv_d_256:
6147 case Intrinsic::x86_avx512_psrlv_d_512:
6148 case Intrinsic::x86_avx2_psrlv_q:
6149 case Intrinsic::x86_avx2_psrlv_q_256:
6150 case Intrinsic::x86_avx512_psrlv_q_512:
6151 case Intrinsic::x86_avx2_psrav_d:
6152 case Intrinsic::x86_avx2_psrav_d_256:
6153 case Intrinsic::x86_avx512_psrav_d_512:
6154 case Intrinsic::x86_avx512_psrav_q_128:
6155 case Intrinsic::x86_avx512_psrav_q_256:
6156 case Intrinsic::x86_avx512_psrav_q_512:
6157 handleVectorShiftIntrinsic(
I,
true);
6161 case Intrinsic::x86_sse2_packsswb_128:
6162 case Intrinsic::x86_sse2_packssdw_128:
6163 case Intrinsic::x86_sse2_packuswb_128:
6164 case Intrinsic::x86_sse41_packusdw:
6165 case Intrinsic::x86_avx2_packsswb:
6166 case Intrinsic::x86_avx2_packssdw:
6167 case Intrinsic::x86_avx2_packuswb:
6168 case Intrinsic::x86_avx2_packusdw:
6174 case Intrinsic::x86_avx512_packsswb_512:
6175 case Intrinsic::x86_avx512_packssdw_512:
6176 case Intrinsic::x86_avx512_packuswb_512:
6177 case Intrinsic::x86_avx512_packusdw_512:
6178 handleVectorPackIntrinsic(
I);
6181 case Intrinsic::x86_sse41_pblendvb:
6182 case Intrinsic::x86_sse41_blendvpd:
6183 case Intrinsic::x86_sse41_blendvps:
6184 case Intrinsic::x86_avx_blendv_pd_256:
6185 case Intrinsic::x86_avx_blendv_ps_256:
6186 case Intrinsic::x86_avx2_pblendvb:
6187 handleBlendvIntrinsic(
I);
6190 case Intrinsic::x86_avx_dp_ps_256:
6191 case Intrinsic::x86_sse41_dppd:
6192 case Intrinsic::x86_sse41_dpps:
6193 handleDppIntrinsic(
I);
6196 case Intrinsic::x86_mmx_packsswb:
6197 case Intrinsic::x86_mmx_packuswb:
6198 handleVectorPackIntrinsic(
I, 16);
6201 case Intrinsic::x86_mmx_packssdw:
6202 handleVectorPackIntrinsic(
I, 32);
6205 case Intrinsic::x86_mmx_psad_bw:
6206 handleVectorSadIntrinsic(
I,
true);
6208 case Intrinsic::x86_sse2_psad_bw:
6209 case Intrinsic::x86_avx2_psad_bw:
6210 handleVectorSadIntrinsic(
I);
6236 case Intrinsic::x86_sse2_pmadd_wd:
6237 case Intrinsic::x86_avx2_pmadd_wd:
6238 case Intrinsic::x86_avx512_pmaddw_d_512:
6239 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6240 case Intrinsic::x86_avx2_pmadd_ub_sw:
6241 case Intrinsic::x86_avx512_pmaddubs_w_512:
6242 handleVectorDotProductIntrinsic(
I, 2,
6249 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6250 handleVectorDotProductIntrinsic(
I, 2,
6257 case Intrinsic::x86_mmx_pmadd_wd:
6258 handleVectorDotProductIntrinsic(
I, 2,
6267 case Intrinsic::aarch64_neon_bfmlalt:
6268 handleVectorDotProductIntrinsic(
I, 2,
6276 case Intrinsic::aarch64_neon_bfmlalb:
6277 handleVectorDotProductIntrinsic(
I, 2,
6375 case Intrinsic::x86_avx512_vpdpbusd_128:
6376 case Intrinsic::x86_avx512_vpdpbusd_256:
6377 case Intrinsic::x86_avx512_vpdpbusd_512:
6378 case Intrinsic::x86_avx512_vpdpbusds_128:
6379 case Intrinsic::x86_avx512_vpdpbusds_256:
6380 case Intrinsic::x86_avx512_vpdpbusds_512:
6381 case Intrinsic::x86_avx2_vpdpbssd_128:
6382 case Intrinsic::x86_avx2_vpdpbssd_256:
6383 case Intrinsic::x86_avx10_vpdpbssd_512:
6384 case Intrinsic::x86_avx2_vpdpbssds_128:
6385 case Intrinsic::x86_avx2_vpdpbssds_256:
6386 case Intrinsic::x86_avx10_vpdpbssds_512:
6387 case Intrinsic::x86_avx2_vpdpbsud_128:
6388 case Intrinsic::x86_avx2_vpdpbsud_256:
6389 case Intrinsic::x86_avx10_vpdpbsud_512:
6390 case Intrinsic::x86_avx2_vpdpbsuds_128:
6391 case Intrinsic::x86_avx2_vpdpbsuds_256:
6392 case Intrinsic::x86_avx10_vpdpbsuds_512:
6393 case Intrinsic::x86_avx2_vpdpbuud_128:
6394 case Intrinsic::x86_avx2_vpdpbuud_256:
6395 case Intrinsic::x86_avx10_vpdpbuud_512:
6396 case Intrinsic::x86_avx2_vpdpbuuds_128:
6397 case Intrinsic::x86_avx2_vpdpbuuds_256:
6398 case Intrinsic::x86_avx10_vpdpbuuds_512:
6399 handleVectorDotProductIntrinsic(
I, 4,
6497 case Intrinsic::x86_avx512_vpdpwssd_128:
6498 case Intrinsic::x86_avx512_vpdpwssd_256:
6499 case Intrinsic::x86_avx512_vpdpwssd_512:
6500 case Intrinsic::x86_avx512_vpdpwssds_128:
6501 case Intrinsic::x86_avx512_vpdpwssds_256:
6502 case Intrinsic::x86_avx512_vpdpwssds_512:
6503 case Intrinsic::x86_avx2_vpdpwsud_128:
6504 case Intrinsic::x86_avx2_vpdpwsud_256:
6505 case Intrinsic::x86_avx10_vpdpwsud_512:
6506 case Intrinsic::x86_avx2_vpdpwsuds_128:
6507 case Intrinsic::x86_avx2_vpdpwsuds_256:
6508 case Intrinsic::x86_avx10_vpdpwsuds_512:
6509 case Intrinsic::x86_avx2_vpdpwusd_128:
6510 case Intrinsic::x86_avx2_vpdpwusd_256:
6511 case Intrinsic::x86_avx10_vpdpwusd_512:
6512 case Intrinsic::x86_avx2_vpdpwusds_128:
6513 case Intrinsic::x86_avx2_vpdpwusds_256:
6514 case Intrinsic::x86_avx10_vpdpwusds_512:
6515 case Intrinsic::x86_avx2_vpdpwuud_128:
6516 case Intrinsic::x86_avx2_vpdpwuud_256:
6517 case Intrinsic::x86_avx10_vpdpwuud_512:
6518 case Intrinsic::x86_avx2_vpdpwuuds_128:
6519 case Intrinsic::x86_avx2_vpdpwuuds_256:
6520 case Intrinsic::x86_avx10_vpdpwuuds_512:
6521 handleVectorDotProductIntrinsic(
I, 2,
6535 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6536 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6537 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6538 handleVectorDotProductIntrinsic(
I, 2,
6544 case Intrinsic::x86_sse_cmp_ss:
6545 case Intrinsic::x86_sse2_cmp_sd:
6546 case Intrinsic::x86_sse_comieq_ss:
6547 case Intrinsic::x86_sse_comilt_ss:
6548 case Intrinsic::x86_sse_comile_ss:
6549 case Intrinsic::x86_sse_comigt_ss:
6550 case Intrinsic::x86_sse_comige_ss:
6551 case Intrinsic::x86_sse_comineq_ss:
6552 case Intrinsic::x86_sse_ucomieq_ss:
6553 case Intrinsic::x86_sse_ucomilt_ss:
6554 case Intrinsic::x86_sse_ucomile_ss:
6555 case Intrinsic::x86_sse_ucomigt_ss:
6556 case Intrinsic::x86_sse_ucomige_ss:
6557 case Intrinsic::x86_sse_ucomineq_ss:
6558 case Intrinsic::x86_sse2_comieq_sd:
6559 case Intrinsic::x86_sse2_comilt_sd:
6560 case Intrinsic::x86_sse2_comile_sd:
6561 case Intrinsic::x86_sse2_comigt_sd:
6562 case Intrinsic::x86_sse2_comige_sd:
6563 case Intrinsic::x86_sse2_comineq_sd:
6564 case Intrinsic::x86_sse2_ucomieq_sd:
6565 case Intrinsic::x86_sse2_ucomilt_sd:
6566 case Intrinsic::x86_sse2_ucomile_sd:
6567 case Intrinsic::x86_sse2_ucomigt_sd:
6568 case Intrinsic::x86_sse2_ucomige_sd:
6569 case Intrinsic::x86_sse2_ucomineq_sd:
6570 handleVectorCompareScalarIntrinsic(
I);
6573 case Intrinsic::x86_avx_cmp_pd_256:
6574 case Intrinsic::x86_avx_cmp_ps_256:
6575 case Intrinsic::x86_sse2_cmp_pd:
6576 case Intrinsic::x86_sse_cmp_ps:
6577 handleVectorComparePackedIntrinsic(
I,
true);
6580 case Intrinsic::x86_bmi_bextr_32:
6581 case Intrinsic::x86_bmi_bextr_64:
6582 case Intrinsic::x86_bmi_bzhi_32:
6583 case Intrinsic::x86_bmi_bzhi_64:
6584 handleGenericBitManipulation(
I);
6587 case Intrinsic::x86_pclmulqdq:
6588 case Intrinsic::x86_pclmulqdq_256:
6589 case Intrinsic::x86_pclmulqdq_512:
6590 handlePclmulIntrinsic(
I);
6593 case Intrinsic::x86_avx_round_pd_256:
6594 case Intrinsic::x86_avx_round_ps_256:
6595 case Intrinsic::x86_sse41_round_pd:
6596 case Intrinsic::x86_sse41_round_ps:
6597 handleRoundPdPsIntrinsic(
I);
6600 case Intrinsic::x86_sse41_round_sd:
6601 case Intrinsic::x86_sse41_round_ss:
6602 handleUnarySdSsIntrinsic(
I);
6605 case Intrinsic::x86_sse2_max_sd:
6606 case Intrinsic::x86_sse_max_ss:
6607 case Intrinsic::x86_sse2_min_sd:
6608 case Intrinsic::x86_sse_min_ss:
6609 handleBinarySdSsIntrinsic(
I);
6612 case Intrinsic::x86_avx_vtestc_pd:
6613 case Intrinsic::x86_avx_vtestc_pd_256:
6614 case Intrinsic::x86_avx_vtestc_ps:
6615 case Intrinsic::x86_avx_vtestc_ps_256:
6616 case Intrinsic::x86_avx_vtestnzc_pd:
6617 case Intrinsic::x86_avx_vtestnzc_pd_256:
6618 case Intrinsic::x86_avx_vtestnzc_ps:
6619 case Intrinsic::x86_avx_vtestnzc_ps_256:
6620 case Intrinsic::x86_avx_vtestz_pd:
6621 case Intrinsic::x86_avx_vtestz_pd_256:
6622 case Intrinsic::x86_avx_vtestz_ps:
6623 case Intrinsic::x86_avx_vtestz_ps_256:
6624 case Intrinsic::x86_avx_ptestc_256:
6625 case Intrinsic::x86_avx_ptestnzc_256:
6626 case Intrinsic::x86_avx_ptestz_256:
6627 case Intrinsic::x86_sse41_ptestc:
6628 case Intrinsic::x86_sse41_ptestnzc:
6629 case Intrinsic::x86_sse41_ptestz:
6630 handleVtestIntrinsic(
I);
6634 case Intrinsic::x86_ssse3_phadd_w:
6635 case Intrinsic::x86_ssse3_phadd_w_128:
6636 case Intrinsic::x86_ssse3_phsub_w:
6637 case Intrinsic::x86_ssse3_phsub_w_128:
6638 handlePairwiseShadowOrIntrinsic(
I, 1,
6642 case Intrinsic::x86_avx2_phadd_w:
6643 case Intrinsic::x86_avx2_phsub_w:
6644 handlePairwiseShadowOrIntrinsic(
I, 2,
6649 case Intrinsic::x86_ssse3_phadd_d:
6650 case Intrinsic::x86_ssse3_phadd_d_128:
6651 case Intrinsic::x86_ssse3_phsub_d:
6652 case Intrinsic::x86_ssse3_phsub_d_128:
6653 handlePairwiseShadowOrIntrinsic(
I, 1,
6657 case Intrinsic::x86_avx2_phadd_d:
6658 case Intrinsic::x86_avx2_phsub_d:
6659 handlePairwiseShadowOrIntrinsic(
I, 2,
6664 case Intrinsic::x86_ssse3_phadd_sw:
6665 case Intrinsic::x86_ssse3_phadd_sw_128:
6666 case Intrinsic::x86_ssse3_phsub_sw:
6667 case Intrinsic::x86_ssse3_phsub_sw_128:
6668 handlePairwiseShadowOrIntrinsic(
I, 1,
6672 case Intrinsic::x86_avx2_phadd_sw:
6673 case Intrinsic::x86_avx2_phsub_sw:
6674 handlePairwiseShadowOrIntrinsic(
I, 2,
6679 case Intrinsic::x86_sse3_hadd_ps:
6680 case Intrinsic::x86_sse3_hadd_pd:
6681 case Intrinsic::x86_sse3_hsub_ps:
6682 case Intrinsic::x86_sse3_hsub_pd:
6683 handlePairwiseShadowOrIntrinsic(
I, 1);
6686 case Intrinsic::x86_avx_hadd_pd_256:
6687 case Intrinsic::x86_avx_hadd_ps_256:
6688 case Intrinsic::x86_avx_hsub_pd_256:
6689 case Intrinsic::x86_avx_hsub_ps_256:
6690 handlePairwiseShadowOrIntrinsic(
I, 2);
6693 case Intrinsic::x86_avx_maskstore_ps:
6694 case Intrinsic::x86_avx_maskstore_pd:
6695 case Intrinsic::x86_avx_maskstore_ps_256:
6696 case Intrinsic::x86_avx_maskstore_pd_256:
6697 case Intrinsic::x86_avx2_maskstore_d:
6698 case Intrinsic::x86_avx2_maskstore_q:
6699 case Intrinsic::x86_avx2_maskstore_d_256:
6700 case Intrinsic::x86_avx2_maskstore_q_256: {
6701 handleAVXMaskedStore(
I);
6705 case Intrinsic::x86_avx_maskload_ps:
6706 case Intrinsic::x86_avx_maskload_pd:
6707 case Intrinsic::x86_avx_maskload_ps_256:
6708 case Intrinsic::x86_avx_maskload_pd_256:
6709 case Intrinsic::x86_avx2_maskload_d:
6710 case Intrinsic::x86_avx2_maskload_q:
6711 case Intrinsic::x86_avx2_maskload_d_256:
6712 case Intrinsic::x86_avx2_maskload_q_256: {
6713 handleAVXMaskedLoad(
I);
6718 case Intrinsic::x86_avx512fp16_add_ph_512:
6719 case Intrinsic::x86_avx512fp16_sub_ph_512:
6720 case Intrinsic::x86_avx512fp16_mul_ph_512:
6721 case Intrinsic::x86_avx512fp16_div_ph_512:
6722 case Intrinsic::x86_avx512fp16_max_ph_512:
6723 case Intrinsic::x86_avx512fp16_min_ph_512:
6724 case Intrinsic::x86_avx512_min_ps_512:
6725 case Intrinsic::x86_avx512_min_pd_512:
6726 case Intrinsic::x86_avx512_max_ps_512:
6727 case Intrinsic::x86_avx512_max_pd_512: {
6732 [[maybe_unused]]
bool Success =
6733 maybeHandleSimpleNomemIntrinsic(
I, 1);
6738 case Intrinsic::x86_avx_vpermilvar_pd:
6739 case Intrinsic::x86_avx_vpermilvar_pd_256:
6740 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6741 case Intrinsic::x86_avx_vpermilvar_ps:
6742 case Intrinsic::x86_avx_vpermilvar_ps_256:
6743 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6744 handleAVXVpermilvar(
I);
6748 case Intrinsic::x86_avx512_vpermi2var_d_128:
6749 case Intrinsic::x86_avx512_vpermi2var_d_256:
6750 case Intrinsic::x86_avx512_vpermi2var_d_512:
6751 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6752 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6753 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6754 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6755 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6756 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6757 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6758 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6759 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6760 case Intrinsic::x86_avx512_vpermi2var_q_128:
6761 case Intrinsic::x86_avx512_vpermi2var_q_256:
6762 case Intrinsic::x86_avx512_vpermi2var_q_512:
6763 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6764 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6765 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6766 handleAVXVpermi2var(
I);
6780 case Intrinsic::x86_avx2_pshuf_b:
6781 case Intrinsic::x86_sse_pshuf_w:
6782 case Intrinsic::x86_ssse3_pshuf_b_128:
6783 case Intrinsic::x86_ssse3_pshuf_b:
6784 case Intrinsic::x86_avx512_pshuf_b_512:
6785 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6792 case Intrinsic::x86_avx512_mask_pmov_dw_128:
6793 case Intrinsic::x86_avx512_mask_pmov_db_128:
6794 case Intrinsic::x86_avx512_mask_pmov_qb_128:
6795 case Intrinsic::x86_avx512_mask_pmov_qw_128:
6796 case Intrinsic::x86_avx512_mask_pmov_qd_128:
6797 case Intrinsic::x86_avx512_mask_pmov_wb_128:
6798 case Intrinsic::x86_avx512_mask_pmov_dw_256:
6799 case Intrinsic::x86_avx512_mask_pmov_db_256:
6800 case Intrinsic::x86_avx512_mask_pmov_qb_256:
6801 case Intrinsic::x86_avx512_mask_pmov_qw_256:
6802 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6803 case Intrinsic::x86_avx512_mask_pmov_db_512:
6804 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6805 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6808 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6817 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6818 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6819 handleIntrinsicByApplyingToShadow(
6820 I, Intrinsic::x86_avx512_mask_pmov_dw_512,
6825 case Intrinsic::x86_avx512_mask_pmovs_dw_256:
6826 case Intrinsic::x86_avx512_mask_pmovus_dw_256:
6827 handleIntrinsicByApplyingToShadow(
6828 I, Intrinsic::x86_avx512_mask_pmov_dw_256,
6832 case Intrinsic::x86_avx512_mask_pmovs_dw_128:
6833 case Intrinsic::x86_avx512_mask_pmovus_dw_128:
6834 handleIntrinsicByApplyingToShadow(
6835 I, Intrinsic::x86_avx512_mask_pmov_dw_128,
6839 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6840 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6841 handleIntrinsicByApplyingToShadow(
6842 I, Intrinsic::x86_avx512_mask_pmov_db_512,
6847 case Intrinsic::x86_avx512_mask_pmovs_db_256:
6848 case Intrinsic::x86_avx512_mask_pmovus_db_256:
6849 handleIntrinsicByApplyingToShadow(
6850 I, Intrinsic::x86_avx512_mask_pmov_db_256,
6854 case Intrinsic::x86_avx512_mask_pmovs_db_128:
6855 case Intrinsic::x86_avx512_mask_pmovus_db_128:
6856 handleIntrinsicByApplyingToShadow(
6857 I, Intrinsic::x86_avx512_mask_pmov_db_128,
6861 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
6862 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
6863 handleIntrinsicByApplyingToShadow(
6864 I, Intrinsic::x86_avx512_mask_pmov_qb_512,
6869 case Intrinsic::x86_avx512_mask_pmovs_qb_256:
6870 case Intrinsic::x86_avx512_mask_pmovus_qb_256:
6871 handleIntrinsicByApplyingToShadow(
6872 I, Intrinsic::x86_avx512_mask_pmov_qb_256,
6876 case Intrinsic::x86_avx512_mask_pmovs_qb_128:
6877 case Intrinsic::x86_avx512_mask_pmovus_qb_128:
6878 handleIntrinsicByApplyingToShadow(
6879 I, Intrinsic::x86_avx512_mask_pmov_qb_128,
6883 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
6884 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
6885 handleIntrinsicByApplyingToShadow(
6886 I, Intrinsic::x86_avx512_mask_pmov_qw_512,
6891 case Intrinsic::x86_avx512_mask_pmovs_qw_256:
6892 case Intrinsic::x86_avx512_mask_pmovus_qw_256:
6893 handleIntrinsicByApplyingToShadow(
6894 I, Intrinsic::x86_avx512_mask_pmov_qw_256,
6898 case Intrinsic::x86_avx512_mask_pmovs_qw_128:
6899 case Intrinsic::x86_avx512_mask_pmovus_qw_128:
6900 handleIntrinsicByApplyingToShadow(
6901 I, Intrinsic::x86_avx512_mask_pmov_qw_128,
6905 case Intrinsic::x86_avx512_mask_pmovs_qd_128:
6906 case Intrinsic::x86_avx512_mask_pmovus_qd_128:
6907 handleIntrinsicByApplyingToShadow(
6908 I, Intrinsic::x86_avx512_mask_pmov_qd_128,
6912 case Intrinsic::x86_avx512_mask_pmovs_wb_128:
6913 case Intrinsic::x86_avx512_mask_pmovus_wb_128:
6914 handleIntrinsicByApplyingToShadow(
6915 I, Intrinsic::x86_avx512_mask_pmov_wb_128,
6919 case Intrinsic::x86_avx512_mask_pmovs_qd_256:
6920 case Intrinsic::x86_avx512_mask_pmovus_qd_256:
6921 case Intrinsic::x86_avx512_mask_pmovs_wb_256:
6922 case Intrinsic::x86_avx512_mask_pmovus_wb_256:
6923 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
6924 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
6925 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
6926 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
6930 handleAVX512VectorDownConvert(
I);
6941 case Intrinsic::x86_avx512_mask_compress:
6942 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6983 case Intrinsic::x86_avx512_rsqrt14_ps_512:
6984 case Intrinsic::x86_avx512_rsqrt14_ps_256:
6985 case Intrinsic::x86_avx512_rsqrt14_ps_128:
6986 case Intrinsic::x86_avx512_rsqrt14_pd_512:
6987 case Intrinsic::x86_avx512_rsqrt14_pd_256:
6988 case Intrinsic::x86_avx512_rsqrt14_pd_128:
6989 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
6990 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
6991 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
6992 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
6993 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
6994 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
6995 handleAVX512VectorGenericMaskedFP(
I, {0},
7036 case Intrinsic::x86_avx512_rcp14_ps_512:
7037 case Intrinsic::x86_avx512_rcp14_ps_256:
7038 case Intrinsic::x86_avx512_rcp14_ps_128:
7039 case Intrinsic::x86_avx512_rcp14_pd_512:
7040 case Intrinsic::x86_avx512_rcp14_pd_256:
7041 case Intrinsic::x86_avx512_rcp14_pd_128:
7042 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
7043 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
7044 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
7045 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
7046 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
7047 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
7048 handleAVX512VectorGenericMaskedFP(
I, {0},
7093 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
7094 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
7095 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
7096 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
7097 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
7098 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
7099 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
7100 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
7101 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
7102 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
7103 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
7104 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
7105 handleAVX512VectorGenericMaskedFP(
I, {0},
7141 case Intrinsic::x86_avx512_mask_scalef_pd_512:
7142 case Intrinsic::x86_avx512_mask_scalef_pd_256:
7143 case Intrinsic::x86_avx512_mask_scalef_pd_128:
7144 case Intrinsic::x86_avx512_mask_scalef_ps_512:
7145 case Intrinsic::x86_avx512_mask_scalef_ps_256:
7146 case Intrinsic::x86_avx512_mask_scalef_ps_128:
7147 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
7148 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
7149 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
7153 handleAVX512VectorGenericMaskedFP(
I, {0, 1},
7173 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
7174 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
7175 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
7176 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
7177 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
7178 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
7179 visitGenericScalarHalfwordInst(
I);
7186 case Intrinsic::x86_avx512_fpclass_pd_512:
7187 case Intrinsic::x86_avx512_fpclass_ps_512:
7188 handleAVX512FPClass(
I);
7192 case Intrinsic::x86_vgf2p8affineqb_128:
7193 case Intrinsic::x86_vgf2p8affineqb_256:
7194 case Intrinsic::x86_vgf2p8affineqb_512:
7195 handleAVXGF2P8Affine(
I);
7205 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &
I) {
7206 switch (
I.getIntrinsicID()) {
7210 case Intrinsic::aarch64_neon_rshrn:
7211 case Intrinsic::aarch64_neon_sqrshl:
7212 case Intrinsic::aarch64_neon_sqrshrn:
7213 case Intrinsic::aarch64_neon_sqrshrun:
7214 case Intrinsic::aarch64_neon_sqshl:
7215 case Intrinsic::aarch64_neon_sqshlu:
7216 case Intrinsic::aarch64_neon_sqshrn:
7217 case Intrinsic::aarch64_neon_sqshrun:
7218 case Intrinsic::aarch64_neon_srshl:
7219 case Intrinsic::aarch64_neon_sshl:
7220 case Intrinsic::aarch64_neon_uqrshl:
7221 case Intrinsic::aarch64_neon_uqrshrn:
7222 case Intrinsic::aarch64_neon_uqshl:
7223 case Intrinsic::aarch64_neon_uqshrn:
7224 case Intrinsic::aarch64_neon_urshl:
7225 case Intrinsic::aarch64_neon_ushl:
7226 handleVectorShiftIntrinsic(
I,
false);
7239 case Intrinsic::aarch64_neon_vsli:
7240 case Intrinsic::aarch64_neon_vsri:
7241 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7248 case Intrinsic::aarch64_neon_fmaxp:
7249 case Intrinsic::aarch64_neon_fminp:
7251 case Intrinsic::aarch64_neon_fmaxnmp:
7252 case Intrinsic::aarch64_neon_fminnmp:
7254 case Intrinsic::aarch64_neon_smaxp:
7255 case Intrinsic::aarch64_neon_sminp:
7256 case Intrinsic::aarch64_neon_umaxp:
7257 case Intrinsic::aarch64_neon_uminp:
7259 case Intrinsic::aarch64_neon_addp:
7261 case Intrinsic::aarch64_neon_faddp:
7263 case Intrinsic::aarch64_neon_saddlp:
7264 case Intrinsic::aarch64_neon_uaddlp: {
7265 handlePairwiseShadowOrIntrinsic(
I, 1);
7270 case Intrinsic::aarch64_neon_fcvtas:
7271 case Intrinsic::aarch64_neon_fcvtau:
7273 case Intrinsic::aarch64_neon_fcvtms:
7274 case Intrinsic::aarch64_neon_fcvtmu:
7276 case Intrinsic::aarch64_neon_fcvtns:
7277 case Intrinsic::aarch64_neon_fcvtnu:
7279 case Intrinsic::aarch64_neon_fcvtps:
7280 case Intrinsic::aarch64_neon_fcvtpu:
7282 case Intrinsic::aarch64_neon_fcvtzs:
7283 case Intrinsic::aarch64_neon_fcvtzu:
7285 case Intrinsic::aarch64_neon_fcvtxn:
7286 handleGenericVectorConvertIntrinsic(
I,
false);
7290 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7291 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7292 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7293 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7294 handleGenericVectorConvertIntrinsic(
I,
true);
7303 case Intrinsic::aarch64_neon_faddv:
7304 case Intrinsic::aarch64_neon_saddv:
7305 case Intrinsic::aarch64_neon_uaddv:
7308 case Intrinsic::aarch64_neon_smaxv:
7309 case Intrinsic::aarch64_neon_sminv:
7310 case Intrinsic::aarch64_neon_umaxv:
7311 case Intrinsic::aarch64_neon_uminv:
7315 case Intrinsic::aarch64_neon_fmaxv:
7316 case Intrinsic::aarch64_neon_fminv:
7317 case Intrinsic::aarch64_neon_fmaxnmv:
7318 case Intrinsic::aarch64_neon_fminnmv:
7320 case Intrinsic::aarch64_neon_saddlv:
7321 case Intrinsic::aarch64_neon_uaddlv:
7322 handleVectorReduceIntrinsic(
I,
true);
7325 case Intrinsic::aarch64_neon_ld1x2:
7326 case Intrinsic::aarch64_neon_ld1x3:
7327 case Intrinsic::aarch64_neon_ld1x4:
7328 case Intrinsic::aarch64_neon_ld2:
7329 case Intrinsic::aarch64_neon_ld3:
7330 case Intrinsic::aarch64_neon_ld4:
7331 case Intrinsic::aarch64_neon_ld2r:
7332 case Intrinsic::aarch64_neon_ld3r:
7333 case Intrinsic::aarch64_neon_ld4r: {
7334 handleNEONVectorLoad(
I,
false);
7338 case Intrinsic::aarch64_neon_ld2lane:
7339 case Intrinsic::aarch64_neon_ld3lane:
7340 case Intrinsic::aarch64_neon_ld4lane: {
7341 handleNEONVectorLoad(
I,
true);
7346 case Intrinsic::aarch64_neon_sqxtn:
7347 case Intrinsic::aarch64_neon_sqxtun:
7348 case Intrinsic::aarch64_neon_uqxtn:
7355 case Intrinsic::aarch64_neon_st1x2:
7356 case Intrinsic::aarch64_neon_st1x3:
7357 case Intrinsic::aarch64_neon_st1x4:
7358 case Intrinsic::aarch64_neon_st2:
7359 case Intrinsic::aarch64_neon_st3:
7360 case Intrinsic::aarch64_neon_st4: {
7361 handleNEONVectorStoreIntrinsic(
I,
false);
7365 case Intrinsic::aarch64_neon_st2lane:
7366 case Intrinsic::aarch64_neon_st3lane:
7367 case Intrinsic::aarch64_neon_st4lane: {
7368 handleNEONVectorStoreIntrinsic(
I,
true);
7381 case Intrinsic::aarch64_neon_tbl1:
7382 case Intrinsic::aarch64_neon_tbl2:
7383 case Intrinsic::aarch64_neon_tbl3:
7384 case Intrinsic::aarch64_neon_tbl4:
7385 case Intrinsic::aarch64_neon_tbx1:
7386 case Intrinsic::aarch64_neon_tbx2:
7387 case Intrinsic::aarch64_neon_tbx3:
7388 case Intrinsic::aarch64_neon_tbx4: {
7390 handleIntrinsicByApplyingToShadow(
7391 I,
I.getIntrinsicID(),
7396 case Intrinsic::aarch64_neon_fmulx:
7397 case Intrinsic::aarch64_neon_pmul:
7398 case Intrinsic::aarch64_neon_pmull:
7399 case Intrinsic::aarch64_neon_smull:
7400 case Intrinsic::aarch64_neon_pmull64:
7401 case Intrinsic::aarch64_neon_umull: {
7402 handleNEONVectorMultiplyIntrinsic(
I);
7406 case Intrinsic::aarch64_neon_smmla:
7407 case Intrinsic::aarch64_neon_ummla:
7408 case Intrinsic::aarch64_neon_usmmla:
7409 case Intrinsic::aarch64_neon_bfmmla:
7410 handleNEONMatrixMultiply(
I);
7417 case Intrinsic::aarch64_neon_sdot:
7418 case Intrinsic::aarch64_neon_udot:
7419 case Intrinsic::aarch64_neon_usdot:
7420 handleVectorDotProductIntrinsic(
I, 4,
7430 case Intrinsic::aarch64_neon_bfdot:
7431 handleVectorDotProductIntrinsic(
I, 2,
7444 case Intrinsic::aarch64_neon_fp8_fdot2:
7445 handleVectorDotProductIntrinsic(
I, 2,
7458 case Intrinsic::aarch64_neon_fp8_fdot4:
7459 handleVectorDotProductIntrinsic(
I, 4,
7469 case Intrinsic::aarch64_neon_fp8_fdot2_lane:
7470 handleNEONDotProductLaneIntrinsic(
I, 2);
7477 case Intrinsic::aarch64_neon_fp8_fdot4_lane:
7478 handleNEONDotProductLaneIntrinsic(
I, 4);
7482 case Intrinsic::aarch64_neon_facge:
7483 case Intrinsic::aarch64_neon_facgt:
7484 handleVectorComparePackedIntrinsic(
I,
false);
7494 void visitIntrinsicInst(IntrinsicInst &
I) {
7495 if (maybeHandleCrossPlatformIntrinsic(
I))
7498 if (maybeHandleX86SIMDIntrinsic(
I))
7501 if (maybeHandleArmSIMDIntrinsic(
I))
7504 if (maybeHandleUnknownIntrinsic(
I))
7507 visitInstruction(
I);
7510 void visitLibAtomicLoad(CallBase &CB) {
7521 Value *NewOrdering =
7525 NextNodeIRBuilder NextIRB(&CB);
7526 Value *SrcShadowPtr, *SrcOriginPtr;
7527 std::tie(SrcShadowPtr, SrcOriginPtr) =
7528 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7530 Value *DstShadowPtr =
7531 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7535 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
7536 if (MS.TrackOrigins) {
7537 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7539 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7540 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7544 void visitLibAtomicStore(CallBase &CB) {
7551 Value *NewOrdering =
7555 Value *DstShadowPtr =
7565 void visitCallBase(CallBase &CB) {
7572 if (Opts.msan_handle_asm_conservative)
7573 visitAsmInstruction(CB);
7575 visitInstruction(CB);
7579 if (LF != NotLibFunc) {
7584 case LibFunc_atomic_load:
7586 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
7590 visitLibAtomicLoad(CB);
7592 case LibFunc_atomic_store:
7593 visitLibAtomicStore(CB);
7609 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7613 Func->removeFnAttrs(
B);
7619 bool MayCheckCall = MS.EagerChecks;
7623 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
7626 unsigned ArgOffset = 0;
7629 if (!
A->getType()->isSized()) {
7630 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
7634 if (
A->getType()->isScalableTy()) {
7635 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
7637 insertCheckShadowOf(
A, &CB);
7642 const DataLayout &
DL =
F.getDataLayout();
7646 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7649 insertCheckShadowOf(
A, &CB);
7650 Size =
DL.getTypeAllocSize(
A->getType());
7656 Value *ArgShadow = getShadow(
A);
7657 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7659 <<
" Shadow: " << *ArgShadow <<
"\n");
7663 assert(
A->getType()->isPointerTy() &&
7664 "ByVal argument is not a pointer!");
7672 Value *AShadowPtr, *AOriginPtr;
7673 std::tie(AShadowPtr, AOriginPtr) =
7674 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
7676 if (!PropagateShadow) {
7683 if (MS.TrackOrigins) {
7684 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7698 Size =
DL.getTypeAllocSize(
A->getType());
7704 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
7706 getOriginPtrForArgument(IRB, ArgOffset));
7718 if (FT->isVarArg()) {
7719 VAHelper->visitCallBase(CB, IRB);
7729 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
7730 setShadow(&CB, getCleanShadow(&CB));
7731 setOrigin(&CB, getCleanOrigin());
7737 Value *
Base = getShadowPtrForRetval(IRBBefore);
7738 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
7750 setShadow(&CB, getCleanShadow(&CB));
7751 setOrigin(&CB, getCleanOrigin());
7758 "Could not find insertion point for retval shadow load");
7761 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7764 setShadow(&CB, RetvalShadow);
7765 if (MS.TrackOrigins)
7766 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7771 RetVal =
I->getOperand(0);
7774 return I->isMustTailCall();
7779 void visitReturnInst(ReturnInst &
I) {
7781 Value *RetVal =
I.getReturnValue();
7787 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7788 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
7789 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7792 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
7794 Value *Shadow = getShadow(RetVal);
7795 bool StoreOrigin =
true;
7797 insertCheckShadowOf(RetVal, &
I);
7798 Shadow = getCleanShadow(RetVal);
7799 StoreOrigin =
false;
7806 if (MS.TrackOrigins && StoreOrigin)
7807 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7811 void visitPHINode(PHINode &
I) {
7813 if (!PropagateShadow) {
7814 setShadow(&
I, getCleanShadow(&
I));
7815 setOrigin(&
I, getCleanOrigin());
7819 ShadowPHINodes.push_back(&
I);
7820 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
7822 if (MS.TrackOrigins)
7824 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
7827 Value *getLocalVarIdptr(AllocaInst &
I) {
7828 ConstantInt *IntConst =
7829 ConstantInt::get(Type::getInt32Ty((*
F.getParent()).getContext()), 0);
7830 return new GlobalVariable(*
F.getParent(), IntConst->
getType(),
7835 Value *getLocalVarDescription(AllocaInst &
I) {
7840 if (PoisonStack && Opts.msan_poison_stack_with_call) {
7841 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7843 Value *ShadowBase, *OriginBase;
7844 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7847 Value *PoisonValue =
7848 IRB.
getInt8(PoisonStack ? Opts.msan_poison_stack_pattern : 0);
7849 IRB.
CreateMemSet(ShadowBase, PoisonValue, Len,
I.getAlign());
7852 if (PoisonStack && MS.TrackOrigins) {
7853 Value *Idptr = getLocalVarIdptr(
I);
7854 if (Opts.msan_print_stack_names) {
7855 Value *Descr = getLocalVarDescription(
I);
7856 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
7857 {&I, Len, Idptr, Descr});
7859 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
7865 Value *Descr = getLocalVarDescription(
I);
7867 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
7869 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
7873 void instrumentAlloca(AllocaInst &
I, Instruction *InsPoint =
nullptr) {
7876 NextNodeIRBuilder IRB(InsPoint);
7879 if (MS.CompileKernel)
7880 poisonAllocaKmsan(
I, IRB, Len);
7882 poisonAllocaUserspace(
I, IRB, Len);
7885 void visitAllocaInst(AllocaInst &
I) {
7886 setShadow(&
I, getCleanShadow(&
I));
7887 setOrigin(&
I, getCleanOrigin());
7893 void visitSelectInst(SelectInst &
I) {
7899 handleSelectLikeInst(
I,
B,
C,
D);
7905 Value *Sb = getShadow(
B);
7906 Value *Sc = getShadow(
C);
7907 Value *Sd = getShadow(
D);
7909 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
7910 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
7911 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
7916 if (
I.getType()->isAggregateType()) {
7920 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
7921 }
else if (isScalableNonVectorType(
I.getType())) {
7929 Sa1 = getCleanShadow(getShadowTy(
I.getType()));
7937 C = CreateAppToShadowCast(IRB,
C);
7938 D = CreateAppToShadowCast(IRB,
D);
7945 if (MS.TrackOrigins) {
7948 if (
B->getType()->isVectorTy()) {
7949 B = convertToBool(
B, IRB);
7950 Sb = convertToBool(Sb, IRB);
7958 void visitLandingPadInst(LandingPadInst &
I) {
7961 setShadow(&
I, getCleanShadow(&
I));
7962 setOrigin(&
I, getCleanOrigin());
7965 void visitCatchSwitchInst(CatchSwitchInst &
I) {
7966 setShadow(&
I, getCleanShadow(&
I));
7967 setOrigin(&
I, getCleanOrigin());
7970 void visitFuncletPadInst(FuncletPadInst &
I) {
7971 setShadow(&
I, getCleanShadow(&
I));
7972 setOrigin(&
I, getCleanOrigin());
7975 void visitGetElementPtrInst(GetElementPtrInst &
I) { handleShadowOr(
I); }
7977 void visitExtractValueInst(ExtractValueInst &
I) {
7979 Value *Agg =
I.getAggregateOperand();
7981 Value *AggShadow = getShadow(Agg);
7985 setShadow(&
I, ResShadow);
7986 setOriginForNaryOp(
I);
7989 void visitInsertValueInst(InsertValueInst &
I) {
7992 Value *AggShadow = getShadow(
I.getAggregateOperand());
7993 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
7999 setOriginForNaryOp(
I);
8002 void dumpInst(Instruction &
I,
const Twine &Prefix) {
8009 << CI->getCalledFunction()->
getName() <<
"\n";
8011 errs() <<
"ZZZ:" <<
Prefix <<
" " <<
I.getOpcodeName() <<
"\n";
8018 unsigned NumOperands =
I.getNumOperands();
8020 errs() <<
"YYY:" <<
Prefix <<
" call " << *
I.getType() <<
" @";
8032 errs() <<
"YYY:" <<
Prefix <<
" " << *
I.getType() <<
" "
8033 <<
I.getOpcodeName() <<
"(";
8035 for (
size_t i = 0; i < NumOperands; i++) {
8053 void visitResumeInst(ResumeInst &
I) {
8058 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
8063 void visitCatchReturnInst(CatchReturnInst &CRI) {
8068 void instrumentAsmArgument(
Value *Operand,
Type *ElemTy, Instruction &
I,
8077 insertCheckShadowOf(Operand, &
I);
8084 auto Size =
DL.getTypeStoreSize(ElemTy);
8086 if (MS.CompileKernel) {
8087 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
8093 auto [ShadowPtr,
_] =
8094 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
8104 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
8105 int NumRetOutputs = 0;
8112 NumRetOutputs =
ST->getNumElements();
8117 for (
const InlineAsm::ConstraintInfo &Info : Constraints) {
8118 switch (
Info.Type) {
8126 return NumOutputs - NumRetOutputs;
8129 void visitAsmInstruction(Instruction &
I) {
8145 const DataLayout &
DL =
F.getDataLayout();
8149 int OutputArgs = getNumOutputArgs(IA, CB);
8155 for (
int i = OutputArgs; i < NumOperands; i++) {
8163 for (
int i = 0; i < OutputArgs; i++) {
8169 setShadow(&
I, getCleanShadow(&
I));
8170 setOrigin(&
I, getCleanOrigin());
8173 void visitFreezeInst(FreezeInst &
I) {
8175 setShadow(&
I, getCleanShadow(&
I));
8176 setOrigin(&
I, getCleanOrigin());
8179 void visitInstruction(Instruction &
I) {
8181 if (Opts.msan_dump_strict_instructions)
8182 dumpInst(
I,
"Strict");
8184 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
8185 Value *Operand =
I.getOperand(i);
8187 insertCheckShadowOf(Operand, &
I);
8189 setShadow(&
I, getCleanShadow(&
I));
8190 setOrigin(&
I, getCleanOrigin());
8194struct VarArgHelperBase :
public VarArgHelper {
8196 MemorySanitizer &MS;
8197 MemorySanitizerVisitor &MSV;
8199 const unsigned VAListTagSize;
8201 VarArgHelperBase(
Function &
F, MemorySanitizer &MS,
8202 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
8203 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
8207 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
8213 MS.VAArgTLS, ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg_va_s");
8222 return getShadowPtrForVAArgument(IRB, ArgOffset);
8231 ConstantInt::get(MS.IntptrTy, ArgOffset),
8236 unsigned BaseOffset) {
8245 TailSize,
Align(8));
8248 void unpoisonVAListTagForInst(IntrinsicInst &
I) {
8250 Value *VAListTag =
I.getArgOperand(0);
8252 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
8253 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
8256 VAListTagSize, Alignment,
false);
8259 void visitVAStartInst(VAStartInst &
I)
override {
8260 if (
F.getCallingConv() == CallingConv::Win64)
8263 unpoisonVAListTagForInst(
I);
8266 void visitVACopyInst(VACopyInst &
I)
override {
8267 if (
F.getCallingConv() == CallingConv::Win64)
8269 unpoisonVAListTagForInst(
I);
8274struct VarArgAMD64Helper :
public VarArgHelperBase {
8277 static const unsigned AMD64GpEndOffset = 48;
8278 static const unsigned AMD64FpEndOffsetSSE = 176;
8280 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8282 unsigned AMD64FpEndOffset;
8283 AllocaInst *VAArgTLSCopy =
nullptr;
8284 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8285 Value *VAArgOverflowSize =
nullptr;
8287 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8289 VarArgAMD64Helper(
Function &
F, MemorySanitizer &MS,
8290 MemorySanitizerVisitor &MSV)
8291 : VarArgHelperBase(
F, MS, MSV, 24) {
8292 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8293 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
8294 if (Attr.isStringAttribute() &&
8295 (Attr.getKindAsString() ==
"target-features")) {
8296 if (Attr.getValueAsString().contains(
"-sse"))
8297 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8303 ArgKind classifyArgument(
Value *arg) {
8306 if (
T->isX86_FP80Ty())
8308 if (
T->isFPOrFPVectorTy())
8309 return AK_FloatingPoint;
8310 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
8311 return AK_GeneralPurpose;
8312 if (
T->isPointerTy())
8313 return AK_GeneralPurpose;
8325 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8326 unsigned GpOffset = 0;
8327 unsigned FpOffset = AMD64GpEndOffset;
8328 unsigned OverflowOffset = AMD64FpEndOffset;
8329 const DataLayout &
DL =
F.getDataLayout();
8340 assert(
A->getType()->isPointerTy());
8342 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8344 unsigned BaseOffset = OverflowOffset;
8345 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8346 Value *OriginBase =
nullptr;
8347 if (MS.TrackOrigins)
8348 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8349 OverflowOffset += AlignedSize;
8352 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8356 Value *ShadowPtr, *OriginPtr;
8357 std::tie(ShadowPtr, OriginPtr) =
8362 if (MS.TrackOrigins)
8366 ArgKind AK = classifyArgument(
A);
8367 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8369 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8371 Value *ShadowBase, *OriginBase =
nullptr;
8373 case AK_GeneralPurpose:
8374 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8375 if (MS.TrackOrigins)
8376 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8380 case AK_FloatingPoint:
8381 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8382 if (MS.TrackOrigins)
8383 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8390 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8392 unsigned BaseOffset = OverflowOffset;
8393 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8394 if (MS.TrackOrigins) {
8395 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8397 OverflowOffset += AlignedSize;
8400 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8409 Value *Shadow = MSV.getShadow(
A);
8411 if (MS.TrackOrigins) {
8412 Value *Origin = MSV.getOrigin(
A);
8413 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8414 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8420 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8421 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8424 void finalizeInstrumentation()
override {
8425 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8426 "finalizeInstrumentation called twice");
8427 if (!VAStartInstrumentationList.
empty()) {
8434 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8435 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8441 Intrinsic::umin, CopySize,
8445 if (MS.TrackOrigins) {
8446 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8455 for (CallInst *OrigInst : VAStartInstrumentationList) {
8456 NextNodeIRBuilder IRB(OrigInst);
8457 Value *VAListTag = OrigInst->getArgOperand(0);
8459 Value *RegSaveAreaPtrPtr =
8460 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 16));
8462 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8464 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8465 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8467 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8469 if (MS.TrackOrigins)
8470 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8471 Alignment, AMD64FpEndOffset);
8472 Value *OverflowArgAreaPtrPtr =
8473 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 8));
8474 Value *OverflowArgAreaPtr =
8475 IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8476 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8477 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8478 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8482 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8484 if (MS.TrackOrigins) {
8487 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8495struct VarArgAArch64Helper :
public VarArgHelperBase {
8496 static const unsigned kAArch64GrArgSize = 64;
8497 static const unsigned kAArch64VrArgSize = 128;
8499 static const unsigned AArch64GrBegOffset = 0;
8500 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8502 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8503 static const unsigned AArch64VrEndOffset =
8504 AArch64VrBegOffset + kAArch64VrArgSize;
8505 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8507 AllocaInst *VAArgTLSCopy =
nullptr;
8508 Value *VAArgOverflowSize =
nullptr;
8510 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8512 VarArgAArch64Helper(
Function &
F, MemorySanitizer &MS,
8513 MemorySanitizerVisitor &MSV)
8514 : VarArgHelperBase(
F, MS, MSV, 32) {}
8517 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
8518 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
8519 return {AK_GeneralPurpose, 1};
8520 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
8521 return {AK_FloatingPoint, 1};
8523 if (
T->isArrayTy()) {
8524 auto R = classifyArgument(
T->getArrayElementType());
8525 R.second *=
T->getScalarType()->getArrayNumElements();
8530 auto R = classifyArgument(FV->getScalarType());
8531 R.second *= FV->getNumElements();
8536 return {AK_Memory, 0};
8548 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8549 unsigned GrOffset = AArch64GrBegOffset;
8550 unsigned VrOffset = AArch64VrBegOffset;
8551 unsigned OverflowOffset = AArch64VAEndOffset;
8553 const DataLayout &
DL =
F.getDataLayout();
8556 auto [AK, RegNum] = classifyArgument(
A->getType());
8557 if (AK == AK_GeneralPurpose &&
8558 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8560 if (AK == AK_FloatingPoint &&
8561 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8565 case AK_GeneralPurpose:
8566 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8567 GrOffset += 8 * RegNum;
8569 case AK_FloatingPoint:
8570 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8571 VrOffset += 16 * RegNum;
8578 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8580 unsigned BaseOffset = OverflowOffset;
8581 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8582 OverflowOffset += AlignedSize;
8585 CleanUnusedTLS(IRB,
Base, BaseOffset);
8597 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8598 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8603 Value *SaveAreaPtrPtr =
8604 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8605 return IRB.
CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8610 Value *SaveAreaPtr =
8611 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8613 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
8616 void finalizeInstrumentation()
override {
8617 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8618 "finalizeInstrumentation called twice");
8619 if (!VAStartInstrumentationList.empty()) {
8626 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8627 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8633 Intrinsic::umin, CopySize,
8639 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8640 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8644 for (CallInst *OrigInst : VAStartInstrumentationList) {
8645 NextNodeIRBuilder IRB(OrigInst);
8647 Value *VAListTag = OrigInst->getArgOperand(0);
8664 Value *StackSaveAreaPtr =
8665 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8668 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8669 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8672 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8675 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8676 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8679 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8685 Value *GrRegSaveAreaShadowPtrOff =
8686 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
8688 Value *GrRegSaveAreaShadowPtr =
8689 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8695 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8701 Value *VrRegSaveAreaShadowPtrOff =
8702 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
8704 Value *VrRegSaveAreaShadowPtr =
8705 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8712 VrRegSaveAreaShadowPtrOff);
8713 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8719 Value *StackSaveAreaShadowPtr =
8720 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8725 VAArgTLSCopy, IRB.
getInt32(AArch64VAEndOffset));
8728 Align(16), VAArgOverflowSize);
8734struct VarArgPowerPC64Helper :
public VarArgHelperBase {
8735 AllocaInst *VAArgTLSCopy =
nullptr;
8736 Value *VAArgSize =
nullptr;
8738 VarArgPowerPC64Helper(
Function &
F, MemorySanitizer &MS,
8739 MemorySanitizerVisitor &MSV)
8740 : VarArgHelperBase(
F, MS, MSV, 8) {}
8742 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8750 Triple TargetTriple(
F.getParent()->getTargetTriple());
8754 if (TargetTriple.isPPC64ELFv2ABI())
8758 unsigned VAArgOffset = VAArgBase;
8759 const DataLayout &
DL =
F.getDataLayout();
8764 assert(
A->getType()->isPointerTy());
8766 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8769 ArgAlign =
Align(8);
8770 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8773 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8775 Value *AShadowPtr, *AOriginPtr;
8776 std::tie(AShadowPtr, AOriginPtr) =
8777 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8787 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8789 if (
A->getType()->isArrayTy()) {
8792 Type *ElementTy =
A->getType()->getArrayElementType();
8794 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8795 }
else if (
A->getType()->isVectorTy()) {
8797 ArgAlign =
Align(ArgSize);
8800 ArgAlign =
Align(8);
8801 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8802 if (
DL.isBigEndian()) {
8806 VAArgOffset += (8 - ArgSize);
8810 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8814 VAArgOffset += ArgSize;
8818 VAArgBase = VAArgOffset;
8822 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8825 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8828 void finalizeInstrumentation()
override {
8829 assert(!VAArgSize && !VAArgTLSCopy &&
8830 "finalizeInstrumentation called twice");
8833 Value *CopySize = VAArgSize;
8835 if (!VAStartInstrumentationList.empty()) {
8839 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8845 Intrinsic::umin, CopySize,
8853 for (CallInst *OrigInst : VAStartInstrumentationList) {
8854 NextNodeIRBuilder IRB(OrigInst);
8855 Value *VAListTag = OrigInst->getArgOperand(0);
8858 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8861 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8862 const DataLayout &
DL =
F.getDataLayout();
8863 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8865 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8866 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8868 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8875struct VarArgPowerPC32Helper :
public VarArgHelperBase {
8876 AllocaInst *VAArgTLSCopy =
nullptr;
8877 Value *VAArgSize =
nullptr;
8879 VarArgPowerPC32Helper(
Function &
F, MemorySanitizer &MS,
8880 MemorySanitizerVisitor &MSV)
8881 : VarArgHelperBase(
F, MS, MSV, 12) {}
8883 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8887 unsigned VAArgOffset = VAArgBase;
8888 const DataLayout &
DL =
F.getDataLayout();
8889 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8894 assert(
A->getType()->isPointerTy());
8896 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8898 if (ArgAlign < IntptrSize)
8899 ArgAlign =
Align(IntptrSize);
8900 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8903 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8905 Value *AShadowPtr, *AOriginPtr;
8906 std::tie(AShadowPtr, AOriginPtr) =
8907 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8917 Type *ArgTy =
A->getType();
8923 uint64_t ArgSize =
DL.getTypeAllocSize(ArgTy);
8930 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8933 ArgAlign =
Align(ArgSize);
8935 if (ArgAlign < IntptrSize)
8936 ArgAlign =
Align(IntptrSize);
8937 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8938 if (
DL.isBigEndian()) {
8941 if (ArgSize < IntptrSize)
8942 VAArgOffset += (IntptrSize - ArgSize);
8945 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
8951 VAArgOffset += ArgSize;
8958 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8961 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8964 void finalizeInstrumentation()
override {
8965 assert(!VAArgSize && !VAArgTLSCopy &&
8966 "finalizeInstrumentation called twice");
8968 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
8969 Value *CopySize = VAArgSize;
8971 if (!VAStartInstrumentationList.empty()) {
8975 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8981 Intrinsic::umin, CopySize,
8989 for (CallInst *OrigInst : VAStartInstrumentationList) {
8990 NextNodeIRBuilder IRB(OrigInst);
8991 Value *VAListTag = OrigInst->getArgOperand(0);
8993 Value *RegSaveAreaSize = CopySize;
8997 IRB.
CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
9001 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
9003 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9006 const DataLayout &
DL =
F.getDataLayout();
9007 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9011 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9012 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9013 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9015 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
9016 Alignment, RegSaveAreaSize);
9018 RegSaveAreaShadowPtr =
9021 ConstantInt::get(MS.IntptrTy, 32));
9026 ConstantInt::get(MS.IntptrTy, 32), Alignment);
9031 Value *OverflowAreaSize = IRB.
CreateSub(CopySize, RegSaveAreaSize);
9034 OverflowAreaPtrPtr =
9035 IRB.
CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
9036 OverflowAreaPtrPtr = IRB.
CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
9038 Value *OverflowAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
9040 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
9041 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
9042 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.
getInt8Ty(),
9045 Value *OverflowVAArgTLSCopyPtr =
9047 OverflowVAArgTLSCopyPtr =
9048 IRB.
CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
9050 OverflowVAArgTLSCopyPtr =
9053 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
9060struct VarArgSystemZHelper :
public VarArgHelperBase {
9061 static const unsigned SystemZGpOffset = 16;
9062 static const unsigned SystemZGpEndOffset = 56;
9063 static const unsigned SystemZFpOffset = 128;
9064 static const unsigned SystemZFpEndOffset = 160;
9065 static const unsigned SystemZMaxVrArgs = 8;
9066 static const unsigned SystemZRegSaveAreaSize = 160;
9067 static const unsigned SystemZOverflowOffset = 160;
9068 static const unsigned SystemZVAListTagSize = 32;
9069 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
9070 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
9072 bool IsSoftFloatABI;
9073 AllocaInst *VAArgTLSCopy =
nullptr;
9074 AllocaInst *VAArgTLSOriginCopy =
nullptr;
9075 Value *VAArgOverflowSize =
nullptr;
9077 enum class ArgKind {
9085 enum class ShadowExtension {
None,
Zero, Sign };
9087 VarArgSystemZHelper(
Function &
F, MemorySanitizer &MS,
9088 MemorySanitizerVisitor &MSV)
9089 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
9090 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
9092 ArgKind classifyArgument(
Type *
T) {
9099 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
9100 return ArgKind::Indirect;
9101 if (
T->isFloatingPointTy())
9102 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
9103 if (
T->isIntegerTy() ||
T->isPointerTy())
9104 return ArgKind::GeneralPurpose;
9105 if (
T->isVectorTy())
9106 return ArgKind::Vector;
9107 return ArgKind::Memory;
9110 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
9120 return ShadowExtension::Zero;
9124 return ShadowExtension::Sign;
9126 return ShadowExtension::None;
9129 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9130 unsigned GpOffset = SystemZGpOffset;
9131 unsigned FpOffset = SystemZFpOffset;
9132 unsigned VrIndex = 0;
9133 unsigned OverflowOffset = SystemZOverflowOffset;
9134 const DataLayout &
DL =
F.getDataLayout();
9140 ArgKind AK = classifyArgument(
T);
9141 if (AK == ArgKind::Indirect) {
9143 AK = ArgKind::GeneralPurpose;
9145 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
9146 AK = ArgKind::Memory;
9147 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
9148 AK = ArgKind::Memory;
9149 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
9150 AK = ArgKind::Memory;
9151 Value *ShadowBase =
nullptr;
9152 Value *OriginBase =
nullptr;
9153 ShadowExtension SE = ShadowExtension::None;
9155 case ArgKind::GeneralPurpose: {
9160 SE = getShadowExtension(CB, ArgNo);
9162 if (SE == ShadowExtension::None) {
9164 assert(ArgAllocSize <= ArgSize);
9165 GapSize = ArgSize - ArgAllocSize;
9167 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
9168 if (MS.TrackOrigins)
9169 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
9171 GpOffset += ArgSize;
9177 case ArgKind::FloatingPoint: {
9186 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
9187 if (MS.TrackOrigins)
9188 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
9190 FpOffset += ArgSize;
9196 case ArgKind::Vector: {
9203 case ArgKind::Memory: {
9211 SE = getShadowExtension(CB, ArgNo);
9213 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
9215 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
9216 if (MS.TrackOrigins)
9218 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
9219 OverflowOffset += ArgSize;
9226 case ArgKind::Indirect:
9229 if (ShadowBase ==
nullptr)
9231 Value *Shadow = MSV.getShadow(
A);
9232 if (SE != ShadowExtension::None)
9233 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
9234 SE == ShadowExtension::Sign);
9235 ShadowBase = IRB.
CreateIntToPtr(ShadowBase, MS.PtrTy,
"_msarg_va_s");
9237 if (MS.TrackOrigins) {
9238 Value *Origin = MSV.getOrigin(
A);
9239 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
9240 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
9244 Constant *OverflowSize = ConstantInt::get(
9245 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
9246 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
9253 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
9256 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9258 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9259 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
9264 unsigned RegSaveAreaSize =
9265 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9266 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9268 if (MS.TrackOrigins)
9269 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9270 Alignment, RegSaveAreaSize);
9279 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9281 Value *OverflowArgAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9282 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9284 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9285 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
9288 SystemZOverflowOffset);
9289 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9291 if (MS.TrackOrigins) {
9293 SystemZOverflowOffset);
9294 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9299 void finalizeInstrumentation()
override {
9300 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9301 "finalizeInstrumentation called twice");
9302 if (!VAStartInstrumentationList.empty()) {
9309 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9311 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9317 Intrinsic::umin, CopySize,
9321 if (MS.TrackOrigins) {
9322 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9331 for (CallInst *OrigInst : VAStartInstrumentationList) {
9332 NextNodeIRBuilder IRB(OrigInst);
9333 Value *VAListTag = OrigInst->getArgOperand(0);
9334 copyRegSaveArea(IRB, VAListTag);
9335 copyOverflowArea(IRB, VAListTag);
9341struct VarArgI386Helper :
public VarArgHelperBase {
9342 AllocaInst *VAArgTLSCopy =
nullptr;
9343 Value *VAArgSize =
nullptr;
9345 VarArgI386Helper(
Function &
F, MemorySanitizer &MS,
9346 MemorySanitizerVisitor &MSV)
9347 : VarArgHelperBase(
F, MS, MSV, 4) {}
9349 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9350 const DataLayout &
DL =
F.getDataLayout();
9351 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9352 unsigned VAArgOffset = 0;
9357 assert(
A->getType()->isPointerTy());
9359 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9361 if (ArgAlign < IntptrSize)
9362 ArgAlign =
Align(IntptrSize);
9363 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9365 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9367 Value *AShadowPtr, *AOriginPtr;
9368 std::tie(AShadowPtr, AOriginPtr) =
9369 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9379 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9381 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9382 if (
DL.isBigEndian()) {
9385 if (ArgSize < IntptrSize)
9386 VAArgOffset += (IntptrSize - ArgSize);
9389 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9392 VAArgOffset += ArgSize;
9398 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9401 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9404 void finalizeInstrumentation()
override {
9405 assert(!VAArgSize && !VAArgTLSCopy &&
9406 "finalizeInstrumentation called twice");
9408 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9409 Value *CopySize = VAArgSize;
9411 if (!VAStartInstrumentationList.empty()) {
9414 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9420 Intrinsic::umin, CopySize,
9428 for (CallInst *OrigInst : VAStartInstrumentationList) {
9429 NextNodeIRBuilder IRB(OrigInst);
9430 Value *VAListTag = OrigInst->getArgOperand(0);
9431 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9432 Value *RegSaveAreaPtrPtr =
9434 PointerType::get(*MS.C, 0));
9435 Value *RegSaveAreaPtr =
9436 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9437 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9438 const DataLayout &
DL =
F.getDataLayout();
9439 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9441 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9442 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9444 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9452struct VarArgGenericHelper :
public VarArgHelperBase {
9453 AllocaInst *VAArgTLSCopy =
nullptr;
9454 Value *VAArgSize =
nullptr;
9456 VarArgGenericHelper(
Function &
F, MemorySanitizer &MS,
9457 MemorySanitizerVisitor &MSV,
const unsigned VAListTagSize)
9458 : VarArgHelperBase(
F, MS, MSV, VAListTagSize) {}
9460 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9461 unsigned VAArgOffset = 0;
9462 const DataLayout &
DL =
F.getDataLayout();
9463 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9468 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9469 if (
DL.isBigEndian()) {
9472 if (ArgSize < IntptrSize)
9473 VAArgOffset += (IntptrSize - ArgSize);
9475 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9476 VAArgOffset += ArgSize;
9477 VAArgOffset =
alignTo(VAArgOffset, IntptrSize);
9483 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9486 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9489 void finalizeInstrumentation()
override {
9490 assert(!VAArgSize && !VAArgTLSCopy &&
9491 "finalizeInstrumentation called twice");
9493 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9494 Value *CopySize = VAArgSize;
9496 if (!VAStartInstrumentationList.empty()) {
9499 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9505 Intrinsic::umin, CopySize,
9513 for (CallInst *OrigInst : VAStartInstrumentationList) {
9514 NextNodeIRBuilder IRB(OrigInst);
9515 Value *VAListTag = OrigInst->getArgOperand(0);
9516 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9517 Value *RegSaveAreaPtrPtr =
9519 PointerType::get(*MS.C, 0));
9520 Value *RegSaveAreaPtr =
9521 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9522 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9523 const DataLayout &
DL =
F.getDataLayout();
9524 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9526 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9527 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9529 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9537using VarArgARM32Helper = VarArgGenericHelper;
9538using VarArgRISCVHelper = VarArgGenericHelper;
9539using VarArgMIPSHelper = VarArgGenericHelper;
9540using VarArgLoongArch64Helper = VarArgGenericHelper;
9541using VarArgHexagonHelper = VarArgGenericHelper;
9544struct VarArgNoOpHelper :
public VarArgHelper {
9545 VarArgNoOpHelper(
Function &
F, MemorySanitizer &MS,
9546 MemorySanitizerVisitor &MSV) {}
9548 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {}
9550 void visitVAStartInst(VAStartInst &
I)
override {}
9552 void visitVACopyInst(VACopyInst &
I)
override {}
9554 void finalizeInstrumentation()
override {}
9560 MemorySanitizerVisitor &Visitor) {
9563 Triple TargetTriple(Func.getParent()->getTargetTriple());
9566 return new VarArgI386Helper(Func, Msan, Visitor);
9569 return new VarArgAMD64Helper(Func, Msan, Visitor);
9571 if (TargetTriple.
isARM())
9572 return new VarArgARM32Helper(Func, Msan, Visitor, 4);
9575 return new VarArgAArch64Helper(Func, Msan, Visitor);
9578 return new VarArgSystemZHelper(Func, Msan, Visitor);
9583 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9586 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9589 return new VarArgRISCVHelper(Func, Msan, Visitor, 4);
9592 return new VarArgRISCVHelper(Func, Msan, Visitor, 8);
9595 return new VarArgMIPSHelper(Func, Msan, Visitor, 4);
9598 return new VarArgMIPSHelper(Func, Msan, Visitor, 8);
9601 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9605 return new VarArgHexagonHelper(Func, Msan, Visitor, 12);
9607 return new VarArgNoOpHelper(Func, Msan, Visitor);
9614 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9617 MemorySanitizerVisitor Visitor(
F, *
this, TLI);
9624 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="")
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 ...
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)