184#include "llvm/IR/IntrinsicsAArch64.h"
185#include "llvm/IR/IntrinsicsX86.h"
216#define DEBUG_TYPE "msan"
219 "Controls which checks to insert");
222 "Controls which instruction to instrument");
241 "msan-track-origins",
246 cl::desc(
"keep going after reporting a UMR"),
255 "msan-poison-stack-with-call",
260 "msan-poison-stack-pattern",
261 cl::desc(
"poison uninitialized stack variables with the given pattern"),
266 cl::desc(
"Print name of local stack variable"),
271 cl::desc(
"Poison fully undef temporary values. "
272 "Partially undefined constant vectors "
273 "are unaffected by this flag (see "
274 "-msan-poison-undef-vectors)."),
278 "msan-poison-undef-vectors",
279 cl::desc(
"Precisely poison partially undefined constant vectors. "
280 "If false (legacy behavior), the entire vector is "
281 "considered fully initialized, which may lead to false "
282 "negatives. Fully undefined constant vectors are "
283 "unaffected by this flag (see -msan-poison-undef)."),
287 "msan-precise-disjoint-or",
288 cl::desc(
"Precisely poison disjoint OR. If false (legacy behavior), "
289 "disjointedness is ignored (i.e., 1|1 is initialized)."),
294 cl::desc(
"propagate shadow through ICmpEQ and ICmpNE"),
299 cl::desc(
"exact handling of relational integer ICmp"),
303 "msan-switch-precision",
304 cl::desc(
"Controls the number of cases considered by MSan for LLVM switch "
305 "instructions. 0 means no UUMs detected. Higher values lead to "
306 "fewer false negatives but may impact compiler and/or "
307 "application performance. N.B. LLVM switch instructions do not "
308 "correspond exactly to C++ switch statements."),
312 "msan-handle-lifetime-intrinsics",
314 "when possible, poison scoped variables at the beginning of the scope "
315 "(slower, but more precise)"),
326 "msan-handle-asm-conservative",
337 "msan-check-access-address",
338 cl::desc(
"report accesses through a pointer which has poisoned shadow"),
343 cl::desc(
"check arguments and return values at function call boundaries"),
347 "msan-dump-strict-instructions",
348 cl::desc(
"print out instructions with default strict semantics i.e.,"
349 "check that all the inputs are fully initialized, and mark "
350 "the output as fully initialized. These semantics are applied "
351 "to instructions that could not be handled explicitly nor "
360 "msan-dump-heuristic-instructions",
361 cl::desc(
"Prints 'unknown' instructions that were handled heuristically. "
362 "Use -msan-dump-strict-instructions to print instructions that "
363 "could not be handled explicitly nor heuristically."),
367 "msan-instrumentation-with-call-threshold",
369 "If the function being instrumented requires more than "
370 "this number of checks and origin stores, use callbacks instead of "
371 "inline checks (-1 means never use callbacks)."),
376 cl::desc(
"Enable KernelMemorySanitizer instrumentation"),
386 cl::desc(
"Insert checks for constant shadow values"),
393 cl::desc(
"Place MSan constructors in comdat sections"),
399 cl::desc(
"Define custom MSan AndMask"),
403 cl::desc(
"Define custom MSan XorMask"),
407 cl::desc(
"Define custom MSan ShadowBase"),
411 cl::desc(
"Define custom MSan OriginBase"),
416 cl::desc(
"Define threshold for number of checks per "
417 "debug location to force origin update."),
429struct MemoryMapParams {
436struct PlatformMemoryMapParams {
437 const MemoryMapParams *bits32;
438 const MemoryMapParams *bits64;
615class MemorySanitizer {
624 MemorySanitizer(MemorySanitizer &&) =
delete;
625 MemorySanitizer &operator=(MemorySanitizer &&) =
delete;
626 MemorySanitizer(
const MemorySanitizer &) =
delete;
627 MemorySanitizer &operator=(
const MemorySanitizer &) =
delete;
629 bool sanitizeFunction(Function &
F, TargetLibraryInfo &TLI);
632 friend struct MemorySanitizerVisitor;
633 friend struct VarArgHelperBase;
634 friend struct VarArgAMD64Helper;
635 friend struct VarArgAArch64Helper;
636 friend struct VarArgPowerPC64Helper;
637 friend struct VarArgPowerPC32Helper;
638 friend struct VarArgSystemZHelper;
639 friend struct VarArgI386Helper;
640 friend struct VarArgGenericHelper;
642 void initializeModule(
Module &M);
643 void initializeCallbacks(
Module &M,
const TargetLibraryInfo &TLI);
644 void createKernelApi(
Module &M,
const TargetLibraryInfo &TLI);
645 void createUserspaceApi(
Module &M,
const TargetLibraryInfo &TLI);
647 template <
typename... ArgsTy>
648 FunctionCallee getOrInsertMsanMetadataFunction(
Module &M, StringRef Name,
674 Value *ParamOriginTLS;
680 Value *RetvalOriginTLS;
686 Value *VAArgOriginTLS;
689 Value *VAArgOverflowSizeTLS;
692 bool CallbacksInitialized =
false;
695 FunctionCallee WarningFn;
699 FunctionCallee MaybeWarningVarSizeFn;
704 FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
706 FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
709 FunctionCallee MsanPoisonStackFn;
713 FunctionCallee MsanChainOriginFn;
716 FunctionCallee MsanSetOriginFn;
719 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
722 StructType *MsanContextStateTy;
723 FunctionCallee MsanGetContextStateFn;
726 FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
732 FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
733 FunctionCallee MsanMetadataPtrForLoad_1_8[4];
734 FunctionCallee MsanMetadataPtrForStore_1_8[4];
735 FunctionCallee MsanInstrumentAsmStoreFn;
738 Value *MsanMetadataAlloca;
741 FunctionCallee getKmsanShadowOriginAccessFn(
bool isStore,
int size);
744 const MemoryMapParams *MapParams;
748 MemoryMapParams CustomMapParams;
750 MDNode *ColdCallWeights;
753 MDNode *OriginStoreWeights;
756void insertModuleCtor(
Module &M) {
793 if (!Options.Kernel) {
802 MemorySanitizer Msan(*
F.getParent(), Options);
821 OS, MapClassName2PassName);
827 if (Options.EagerChecks)
828 OS <<
"eager-checks;";
829 OS <<
"track-origins=" << Options.TrackOrigins;
845template <
typename... ArgsTy>
847MemorySanitizer::getOrInsertMsanMetadataFunction(
Module &M,
StringRef Name,
852 std::forward<ArgsTy>(Args)...);
855 return M.getOrInsertFunction(Name, MsanMetadata,
856 std::forward<ArgsTy>(Args)...);
865 RetvalOriginTLS =
nullptr;
867 ParamOriginTLS =
nullptr;
869 VAArgOriginTLS =
nullptr;
870 VAArgOverflowSizeTLS =
nullptr;
872 WarningFn =
M.getOrInsertFunction(
"__msan_warning",
874 IRB.getVoidTy(), IRB.getInt32Ty());
885 MsanGetContextStateFn =
886 M.getOrInsertFunction(
"__msan_get_context_state", PtrTy);
890 for (
int ind = 0,
size = 1; ind < 4; ind++,
size <<= 1) {
891 std::string name_load =
892 "__msan_metadata_ptr_for_load_" + std::to_string(
size);
893 std::string name_store =
894 "__msan_metadata_ptr_for_store_" + std::to_string(
size);
895 MsanMetadataPtrForLoad_1_8[ind] =
896 getOrInsertMsanMetadataFunction(M, name_load, PtrTy);
897 MsanMetadataPtrForStore_1_8[ind] =
898 getOrInsertMsanMetadataFunction(M, name_store, PtrTy);
901 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
902 M,
"__msan_metadata_ptr_for_load_n", PtrTy, IntptrTy);
903 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
904 M,
"__msan_metadata_ptr_for_store_n", PtrTy, IntptrTy);
907 MsanPoisonAllocaFn =
M.getOrInsertFunction(
908 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
909 MsanUnpoisonAllocaFn =
M.getOrInsertFunction(
910 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
914 return M.getOrInsertGlobal(Name, Ty, [&] {
916 nullptr, Name,
nullptr,
922void MemorySanitizer::createUserspaceApi(
Module &M,
930 StringRef WarningFnName = Recover ?
"__msan_warning_with_origin"
931 :
"__msan_warning_with_origin_noreturn";
932 WarningFn =
M.getOrInsertFunction(WarningFnName,
934 IRB.getVoidTy(), IRB.getInt32Ty());
937 Recover ?
"__msan_warning" :
"__msan_warning_noreturn";
938 WarningFn =
M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
965 IRB.getIntPtrTy(
M.getDataLayout()));
969 unsigned AccessSize = 1 << AccessSizeIndex;
970 std::string FunctionName =
"__msan_maybe_warning_" +
itostr(AccessSize);
971 MaybeWarningFn[AccessSizeIndex] =
M.getOrInsertFunction(
973 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
974 MaybeWarningVarSizeFn =
M.getOrInsertFunction(
975 "__msan_maybe_warning_N", TLI.
getAttrList(
C, {},
false),
976 IRB.getVoidTy(), PtrTy, IRB.getInt64Ty(), IRB.getInt32Ty());
977 FunctionName =
"__msan_maybe_store_origin_" +
itostr(AccessSize);
978 MaybeStoreOriginFn[AccessSizeIndex] =
M.getOrInsertFunction(
980 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
984 MsanSetAllocaOriginWithDescriptionFn =
985 M.getOrInsertFunction(
"__msan_set_alloca_origin_with_descr",
986 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
987 MsanSetAllocaOriginNoDescriptionFn =
988 M.getOrInsertFunction(
"__msan_set_alloca_origin_no_descr",
989 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
990 MsanPoisonStackFn =
M.getOrInsertFunction(
"__msan_poison_stack",
991 IRB.getVoidTy(), PtrTy, IntptrTy);
995void MemorySanitizer::initializeCallbacks(
Module &M,
998 if (CallbacksInitialized)
1004 MsanChainOriginFn =
M.getOrInsertFunction(
1005 "__msan_chain_origin",
1006 TLI.
getAttrList(
C, {0},
false,
true), IRB.getInt32Ty(),
1008 MsanSetOriginFn =
M.getOrInsertFunction(
1010 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
1012 M.getOrInsertFunction(
"__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
1014 M.getOrInsertFunction(
"__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
1015 MemsetFn =
M.getOrInsertFunction(
"__msan_memset",
1017 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
1019 MsanInstrumentAsmStoreFn =
M.getOrInsertFunction(
1020 "__msan_instrument_asm_store", IRB.getVoidTy(), PtrTy, IntptrTy);
1022 if (CompileKernel) {
1023 createKernelApi(M, TLI);
1025 createUserspaceApi(M, TLI);
1027 CallbacksInitialized =
true;
1033 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
1051void MemorySanitizer::initializeModule(
Module &M) {
1052 auto &
DL =
M.getDataLayout();
1054 TargetTriple =
M.getTargetTriple();
1056 bool ShadowPassed =
ClShadowBase.getNumOccurrences() > 0;
1057 bool OriginPassed =
ClOriginBase.getNumOccurrences() > 0;
1059 if (ShadowPassed || OriginPassed) {
1064 MapParams = &CustomMapParams;
1066 switch (TargetTriple.getOS()) {
1068 switch (TargetTriple.getArch()) {
1083 switch (TargetTriple.getArch()) {
1092 switch (TargetTriple.getArch()) {
1129 C = &(
M.getContext());
1131 IntptrTy = IRB.getIntPtrTy(
DL);
1132 OriginTy = IRB.getInt32Ty();
1133 PtrTy = IRB.getPtrTy();
1138 if (!CompileKernel) {
1140 M.getOrInsertGlobal(
"__msan_track_origins", IRB.getInt32Ty(), [&] {
1141 return new GlobalVariable(
1142 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
1143 IRB.getInt32(TrackOrigins),
"__msan_track_origins");
1147 M.getOrInsertGlobal(
"__msan_keep_going", IRB.getInt32Ty(), [&] {
1148 return new GlobalVariable(M, IRB.getInt32Ty(), true,
1149 GlobalValue::WeakODRLinkage,
1150 IRB.getInt32(Recover),
"__msan_keep_going");
1165struct VarArgHelper {
1166 virtual ~VarArgHelper() =
default;
1169 virtual void visitCallBase(CallBase &CB,
IRBuilder<> &IRB) = 0;
1172 virtual void visitVAStartInst(VAStartInst &
I) = 0;
1175 virtual void visitVACopyInst(VACopyInst &
I) = 0;
1181 virtual void finalizeInstrumentation() = 0;
1184struct MemorySanitizerVisitor;
1189 MemorySanitizerVisitor &Visitor);
1196 if (TypeSizeFixed <= 8)
1205class NextNodeIRBuilder :
public IRBuilder<> {
1218struct MemorySanitizerVisitor :
public InstVisitor<MemorySanitizerVisitor> {
1220 MemorySanitizer &MS;
1222 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1223 std::unique_ptr<VarArgHelper> VAHelper;
1224 const TargetLibraryInfo *TLI;
1231 bool PropagateShadow;
1234 bool PoisonUndefVectors;
1236 struct ShadowOriginAndInsertPoint {
1241 ShadowOriginAndInsertPoint(
Value *S,
Value *O, Instruction *
I)
1242 : Shadow(S), Origin(
O), OrigIns(
I) {}
1245 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1246 SmallSetVector<AllocaInst *, 16> AllocaSet;
1249 int64_t SplittableBlocksCount = 0;
1251 MemorySanitizerVisitor(Function &
F, MemorySanitizer &MS,
1252 const TargetLibraryInfo &TLI)
1254 bool SanitizeFunction =
1256 InsertChecks = SanitizeFunction;
1257 PropagateShadow = SanitizeFunction;
1268 MS.initializeCallbacks(*
F.getParent(), TLI);
1270 IRBuilder<>(&
F.getEntryBlock(),
F.getEntryBlock().getFirstNonPHIIt())
1271 .CreateIntrinsic(Intrinsic::donothing, {});
1273 if (MS.CompileKernel) {
1275 insertKmsanPrologue(IRB);
1279 <<
"MemorySanitizer is not inserting checks into '"
1280 <<
F.getName() <<
"'\n");
1283 bool instrumentWithCalls(
Value *V) {
1287 ++SplittableBlocksCount;
1292 bool isInPrologue(Instruction &
I) {
1293 return I.getParent() == FnPrologueEnd->
getParent() &&
1302 if (MS.TrackOrigins <= 1)
1304 return IRB.
CreateCall(MS.MsanChainOriginFn, V);
1308 const DataLayout &
DL =
F.getDataLayout();
1309 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1319 TypeSize TS, Align Alignment) {
1320 const DataLayout &
DL =
F.getDataLayout();
1321 const Align IntptrAlignment =
DL.getABITypeAlign(MS.IntptrTy);
1322 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1334 auto [InsertPt,
Index] =
1346 Align CurrentAlignment = Alignment;
1347 if (Alignment >= IntptrAlignment && IntptrSize >
kOriginSize) {
1348 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1350 for (
unsigned i = 0; i <
Size / IntptrSize; ++i) {
1355 CurrentAlignment = IntptrAlignment;
1368 Value *OriginPtr, Align Alignment) {
1369 const DataLayout &
DL =
F.getDataLayout();
1371 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
1373 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1382 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1389 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1391 if (instrumentWithCalls(ConvertedShadow) &&
1393 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1394 Value *ConvertedShadow2 =
1396 CallBase *CB = IRB.
CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1400 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1404 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1409 void materializeStores() {
1410 for (StoreInst *SI : StoreList) {
1412 Value *Val =
SI->getValueOperand();
1413 Value *Addr =
SI->getPointerOperand();
1414 Value *Shadow =
SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1415 Value *ShadowPtr, *OriginPtr;
1417 const Align Alignment =
SI->getAlign();
1419 std::tie(ShadowPtr, OriginPtr) =
1420 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
true);
1422 [[maybe_unused]] StoreInst *NewSI =
1429 if (MS.TrackOrigins && !
SI->isAtomic())
1430 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1437 if (MS.TrackOrigins < 2)
1440 if (LazyWarningDebugLocationCount.
empty())
1441 for (
const auto &
I : InstrumentationList)
1442 ++LazyWarningDebugLocationCount[
I.OrigIns->getDebugLoc()];
1458 auto NewDebugLoc = OI->getDebugLoc();
1465 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1466 Origin = updateOrigin(Origin, IRBOrigin);
1471 if (MS.CompileKernel || MS.TrackOrigins)
1482 const DataLayout &
DL =
F.getDataLayout();
1483 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1485 if (instrumentWithCalls(ConvertedShadow) && !MS.CompileKernel) {
1487 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1488 Value *ConvertedShadow2 =
1492 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1496 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1500 FunctionCallee Fn = MS.MaybeWarningVarSizeFn;
1503 unsigned ShadowSize =
DL.getTypeAllocSize(ConvertedShadow2->
getType());
1506 {ShadowAlloca, ConstantInt::get(IRB.
getInt64Ty(), ShadowSize),
1507 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1512 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1515 !MS.Recover, MS.ColdCallWeights);
1518 insertWarningFn(IRB, Origin);
1523 void materializeInstructionChecks(
1525 const DataLayout &
DL =
F.getDataLayout();
1528 bool Combine = !MS.TrackOrigins;
1530 Value *Shadow =
nullptr;
1531 for (
const auto &ShadowData : InstructionChecks) {
1532 assert(ShadowData.OrigIns == Instruction);
1535 Value *ConvertedShadow = ShadowData.Shadow;
1544 insertWarningFn(IRB, ShadowData.Origin);
1554 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1559 Shadow = ConvertedShadow;
1563 Shadow = convertToBool(Shadow, IRB,
"_mscmp");
1564 ConvertedShadow = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1565 Shadow = IRB.
CreateOr(Shadow, ConvertedShadow,
"_msor");
1571 materializeOneCheck(IRB, Shadow,
nullptr);
1575 static bool isAArch64SVCount(
Type *Ty) {
1577 return TTy->
getName() ==
"aarch64.svcount";
1583 static bool isScalableNonVectorType(
Type *Ty) {
1584 if (!isAArch64SVCount(Ty))
1585 LLVM_DEBUG(
dbgs() <<
"isScalableNonVectorType: Unexpected type " << *Ty
1591 void materializeChecks() {
1594 SmallPtrSet<Instruction *, 16>
Done;
1597 for (
auto I = InstrumentationList.begin();
1598 I != InstrumentationList.end();) {
1599 auto OrigIns =
I->OrigIns;
1603 auto J = std::find_if(
I + 1, InstrumentationList.end(),
1604 [OrigIns](
const ShadowOriginAndInsertPoint &R) {
1605 return OrigIns != R.OrigIns;
1619 MS.ParamTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1620 {Zero, IRB.getInt32(0)},
"param_shadow");
1621 MS.RetvalTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1622 {Zero, IRB.getInt32(1)},
"retval_shadow");
1623 MS.VAArgTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1624 {Zero, IRB.getInt32(2)},
"va_arg_shadow");
1625 MS.VAArgOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1626 {Zero, IRB.getInt32(3)},
"va_arg_origin");
1627 MS.VAArgOverflowSizeTLS =
1628 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1629 {Zero, IRB.getInt32(4)},
"va_arg_overflow_size");
1630 MS.ParamOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1631 {Zero, IRB.getInt32(5)},
"param_origin");
1632 MS.RetvalOriginTLS =
1633 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1634 {Zero, IRB.getInt32(6)},
"retval_origin");
1636 MS.MsanMetadataAlloca = IRB.
CreateAlloca(MS.MsanMetadata, 0u);
1649 for (Instruction *
I : Instructions)
1653 for (PHINode *PN : ShadowPHINodes) {
1655 PHINode *PNO = MS.TrackOrigins ?
cast<PHINode>(getOrigin(PN)) : nullptr;
1656 size_t NumValues = PN->getNumIncomingValues();
1657 for (
size_t v = 0;
v < NumValues;
v++) {
1658 PNS->
addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1660 PNO->
addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1664 VAHelper->finalizeInstrumentation();
1669 for (
auto Item : LifetimeStartList) {
1670 instrumentAlloca(*Item.second, Item.first);
1671 AllocaSet.
remove(Item.second);
1676 for (AllocaInst *AI : AllocaSet)
1677 instrumentAlloca(*AI);
1680 materializeChecks();
1684 materializeStores();
1690 Type *getShadowTy(
Value *V) {
return getShadowTy(
V->getType()); }
1701 const DataLayout &
DL =
F.getDataLayout();
1703 uint32_t EltSize =
DL.getTypeSizeInBits(VT->getElementType());
1705 VT->getElementCount());
1708 return ArrayType::get(getShadowTy(AT->getElementType()),
1709 AT->getNumElements());
1713 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1714 Elements.push_back(getShadowTy(
ST->getElementType(i)));
1716 LLVM_DEBUG(
dbgs() <<
"getShadowTy: " << *ST <<
" ===> " << *Res <<
"\n");
1719 if (isScalableNonVectorType(OrigTy)) {
1720 LLVM_DEBUG(
dbgs() <<
"getShadowTy: Scalable non-vector type: " << *OrigTy
1725 uint32_t TypeSize =
DL.getTypeSizeInBits(OrigTy);
1730 Value *collapseStructShadow(StructType *Struct,
Value *Shadow,
1735 for (
unsigned Idx = 0; Idx <
Struct->getNumElements(); Idx++) {
1738 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1740 if (Aggregator != FalseVal)
1741 Aggregator = IRB.
CreateOr(Aggregator, ShadowBool);
1743 Aggregator = ShadowBool;
1750 Value *collapseArrayShadow(ArrayType *Array,
Value *Shadow,
1752 if (!
Array->getNumElements())
1756 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1758 for (
unsigned Idx = 1; Idx <
Array->getNumElements(); Idx++) {
1760 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1761 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
1771 return collapseStructShadow(Struct, V, IRB);
1773 return collapseArrayShadow(Array, V, IRB);
1778 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1786 Type *VTy =
V->getType();
1788 return convertToBool(convertShadowToScalar(V, IRB), IRB,
name);
1795 Type *ptrToIntPtrType(
Type *PtrTy)
const {
1797 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1798 VectTy->getElementCount());
1804 Type *getPtrToShadowPtrType(
Type *IntPtrTy,
Type *ShadowTy)
const {
1806 return VectorType::get(
1807 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1808 VectTy->getElementCount());
1810 assert(IntPtrTy == MS.IntptrTy);
1817 VectTy->getElementCount(),
1818 constToIntPtr(VectTy->getElementType(),
C));
1820 assert(IntPtrTy == MS.IntptrTy);
1823 return ConstantInt::get(MS.IntptrTy,
C,
false,
1837 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1840 if (uint64_t AndMask = MS.MapParams->AndMask)
1841 OffsetLong = IRB.
CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1843 if (uint64_t XorMask = MS.MapParams->XorMask)
1844 OffsetLong = IRB.
CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1856 std::pair<Value *, Value *>
1858 MaybeAlign Alignment) {
1863 assert(VectTy->getElementType()->isPointerTy());
1865 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1866 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1867 Value *ShadowLong = ShadowOffset;
1868 if (uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1870 IRB.
CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1873 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1875 Value *OriginPtr =
nullptr;
1876 if (MS.TrackOrigins) {
1877 Value *OriginLong = ShadowOffset;
1878 uint64_t OriginBase = MS.MapParams->OriginBase;
1879 if (OriginBase != 0)
1881 IRB.
CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1884 OriginLong = IRB.
CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1887 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1889 return std::make_pair(ShadowPtr, OriginPtr);
1892 template <
typename... ArgsTy>
1897 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1898 return IRB.
CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1901 return IRB.
CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1904 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(
Value *Addr,
1908 Value *ShadowOriginPtrs;
1909 const DataLayout &
DL =
F.getDataLayout();
1910 TypeSize
Size =
DL.getTypeStoreSize(ShadowTy);
1912 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(
isStore,
Size);
1915 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1917 Value *SizeVal = ConstantInt::get(MS.IntptrTy,
Size);
1918 ShadowOriginPtrs = createMetadataCall(
1920 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1927 return std::make_pair(ShadowPtr, OriginPtr);
1933 std::pair<Value *, Value *> getShadowOriginPtrKernel(
Value *Addr,
1940 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy,
isStore);
1945 Value *ShadowPtrs = ConstantInt::getNullValue(
1947 Value *OriginPtrs =
nullptr;
1948 if (MS.TrackOrigins)
1949 OriginPtrs = ConstantInt::getNullValue(
1951 for (
unsigned i = 0; i < NumElements; ++i) {
1954 auto [ShadowPtr, OriginPtr] =
1955 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy,
isStore);
1958 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1959 if (MS.TrackOrigins)
1961 OriginPtrs, OriginPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1963 return {ShadowPtrs, OriginPtrs};
1966 std::pair<Value *, Value *> getShadowOriginPtr(
Value *Addr,
IRBuilder<> &IRB,
1968 MaybeAlign Alignment,
1970 if (MS.CompileKernel)
1971 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy,
isStore);
1972 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1980 ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg");
1985 if (!MS.TrackOrigins)
1988 ConstantInt::get(MS.IntptrTy, ArgOffset),
1998 Value *getOriginPtrForRetval() {
2000 return MS.RetvalOriginTLS;
2005 assert(!ShadowMap.
count(V) &&
"Values may only have one shadow");
2006 ShadowMap[
V] = PropagateShadow ? SV : getCleanShadow(V);
2011 if (!MS.TrackOrigins)
2013 assert(!OriginMap.
count(V) &&
"Values may only have one origin");
2014 LLVM_DEBUG(
dbgs() <<
"ORIGIN: " << *V <<
" ==> " << *Origin <<
"\n");
2015 OriginMap[
V] = Origin;
2019 Type *ShadowTy = getShadowTy(OrigTy);
2029 Constant *getCleanShadow(
Value *V) {
return getCleanShadow(
V->getType()); }
2037 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
2038 getPoisonedShadow(AT->getElementType()));
2042 SmallVector<Constant *, 4> Vals;
2043 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
2044 Vals.
push_back(getPoisonedShadow(
ST->getElementType(i)));
2052 Type *ShadowTy = getShadowTy(V);
2055 return getPoisonedShadow(ShadowTy);
2067 if (!PropagateShadow ||
I->getMetadata(LLVMContext::MD_nosanitize))
2068 return getCleanShadow(V);
2070 Value *Shadow = ShadowMap[
V];
2072 LLVM_DEBUG(
dbgs() <<
"No shadow: " << *V <<
"\n" << *(
I->getParent()));
2073 assert(Shadow &&
"No shadow for a value");
2080 Value *
AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
2081 : getCleanShadow(V);
2087 Value *&ShadowPtr = ShadowMap[
V];
2092 unsigned ArgOffset = 0;
2093 const DataLayout &
DL =
F->getDataLayout();
2094 for (
auto &FArg :
F->args()) {
2095 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
2097 ?
"vscale not fully supported\n"
2098 :
"Arg is not sized\n"));
2100 ShadowPtr = getCleanShadow(V);
2101 setOrigin(
A, getCleanOrigin());
2107 unsigned Size = FArg.hasByValAttr()
2108 ?
DL.getTypeAllocSize(FArg.getParamByValType())
2109 :
DL.getTypeAllocSize(FArg.getType());
2113 if (FArg.hasByValAttr()) {
2117 const Align ArgAlign =
DL.getValueOrABITypeAlignment(
2118 FArg.getParamAlign(), FArg.getParamByValType());
2119 Value *CpShadowPtr, *CpOriginPtr;
2120 std::tie(CpShadowPtr, CpOriginPtr) =
2121 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
2123 if (!PropagateShadow || Overflow) {
2125 EntryIRB.CreateMemSet(
2129 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2131 [[maybe_unused]]
Value *Cpy = EntryIRB.CreateMemCpy(
2132 CpShadowPtr, CopyAlign,
Base, CopyAlign,
Size);
2135 if (MS.TrackOrigins) {
2136 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
2140 EntryIRB.CreateMemCpy(
2149 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
2150 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
2151 ShadowPtr = getCleanShadow(V);
2152 setOrigin(
A, getCleanOrigin());
2155 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2156 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg),
Base,
2158 if (MS.TrackOrigins) {
2159 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
2160 setOrigin(
A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
2164 <<
" ARG: " << FArg <<
" ==> " << *ShadowPtr <<
"\n");
2170 assert(ShadowPtr &&
"Could not find shadow for an argument");
2177 cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
2178 PoisonUndefVectors) {
2181 for (
unsigned i = 0; i != NumElems; ++i) {
2184 : getCleanShadow(Elem);
2188 LLVM_DEBUG(
dbgs() <<
"Partial undef constant vector: " << *V <<
" ==> "
2189 << *ShadowConstant <<
"\n");
2191 return ShadowConstant;
2197 return getCleanShadow(V);
2201 Value *getShadow(Instruction *
I,
int i) {
2202 return getShadow(
I->getOperand(i));
2207 if (!MS.TrackOrigins)
2210 return getCleanOrigin();
2212 "Unexpected value type in getOrigin()");
2214 if (
I->getMetadata(LLVMContext::MD_nosanitize))
2215 return getCleanOrigin();
2217 Value *Origin = OriginMap[
V];
2218 assert(Origin &&
"Missing origin");
2223 Value *getOrigin(Instruction *
I,
int i) {
2224 return getOrigin(
I->getOperand(i));
2231 void insertCheckShadow(
Value *Shadow,
Value *Origin, Instruction *OrigIns) {
2237 LLVM_DEBUG(
dbgs() <<
"Skipping check of " << *Shadow <<
" before "
2238 << *OrigIns <<
"\n");
2243 if (isScalableNonVectorType(ShadowTy)) {
2244 LLVM_DEBUG(
dbgs() <<
"Skipping check of scalable non-vector " << *Shadow
2245 <<
" before " << *OrigIns <<
"\n");
2251 "Can only insert checks for integer, vector, and aggregate shadow "
2254 InstrumentationList.push_back(
2255 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2263 void insertCheckShadowOf(
Value *Val, Instruction *OrigIns) {
2265 Value *Shadow, *Origin;
2267 Shadow = getShadow(Val);
2270 Origin = getOrigin(Val);
2277 insertCheckShadow(Shadow, Origin, OrigIns);
2282 case AtomicOrdering::NotAtomic:
2283 return AtomicOrdering::NotAtomic;
2284 case AtomicOrdering::Unordered:
2285 case AtomicOrdering::Monotonic:
2286 case AtomicOrdering::Release:
2287 return AtomicOrdering::Release;
2288 case AtomicOrdering::Acquire:
2289 case AtomicOrdering::AcquireRelease:
2290 return AtomicOrdering::AcquireRelease;
2291 case AtomicOrdering::SequentiallyConsistent:
2292 return AtomicOrdering::SequentiallyConsistent;
2298 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2299 uint32_t OrderingTable[NumOrderings] = {};
2301 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2302 OrderingTable[(
int)AtomicOrderingCABI::release] =
2303 (int)AtomicOrderingCABI::release;
2304 OrderingTable[(int)AtomicOrderingCABI::consume] =
2305 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2306 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2307 (
int)AtomicOrderingCABI::acq_rel;
2308 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2309 (
int)AtomicOrderingCABI::seq_cst;
2316 case AtomicOrdering::NotAtomic:
2317 return AtomicOrdering::NotAtomic;
2318 case AtomicOrdering::Unordered:
2319 case AtomicOrdering::Monotonic:
2320 case AtomicOrdering::Acquire:
2321 return AtomicOrdering::Acquire;
2322 case AtomicOrdering::Release:
2323 case AtomicOrdering::AcquireRelease:
2324 return AtomicOrdering::AcquireRelease;
2325 case AtomicOrdering::SequentiallyConsistent:
2326 return AtomicOrdering::SequentiallyConsistent;
2332 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2333 uint32_t OrderingTable[NumOrderings] = {};
2335 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2336 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2337 OrderingTable[(int)AtomicOrderingCABI::consume] =
2338 (
int)AtomicOrderingCABI::acquire;
2339 OrderingTable[(int)AtomicOrderingCABI::release] =
2340 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
2341 (int)AtomicOrderingCABI::acq_rel;
2342 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2343 (
int)AtomicOrderingCABI::seq_cst;
2349 using InstVisitor<MemorySanitizerVisitor>
::visit;
2350 void visit(Instruction &
I) {
2351 if (
I.getMetadata(LLVMContext::MD_nosanitize))
2354 if (isInPrologue(
I))
2359 setShadow(&
I, getCleanShadow(&
I));
2360 setOrigin(&
I, getCleanOrigin());
2371 void visitLoadInst(LoadInst &
I) {
2372 assert(
I.getType()->isSized() &&
"Load type must have size");
2373 assert(!
I.getMetadata(LLVMContext::MD_nosanitize));
2374 NextNodeIRBuilder IRB(&
I);
2375 Type *ShadowTy = getShadowTy(&
I);
2376 Value *Addr =
I.getPointerOperand();
2377 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
2378 const Align Alignment =
I.getAlign();
2379 if (PropagateShadow) {
2380 std::tie(ShadowPtr, OriginPtr) =
2381 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
2385 setShadow(&
I, getCleanShadow(&
I));
2389 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2394 if (MS.TrackOrigins) {
2395 if (PropagateShadow) {
2400 setOrigin(&
I, getCleanOrigin());
2409 void visitStoreInst(StoreInst &
I) {
2410 StoreList.push_back(&
I);
2412 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2415 void handleCASOrRMW(Instruction &
I) {
2419 Value *Addr =
I.getOperand(0);
2420 Value *Val =
I.getOperand(1);
2421 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val),
Align(1),
2426 insertCheckShadowOf(Addr, &
I);
2432 insertCheckShadowOf(Val, &
I);
2436 setShadow(&
I, getCleanShadow(&
I));
2437 setOrigin(&
I, getCleanOrigin());
2440 void visitAtomicRMWInst(AtomicRMWInst &
I) {
2445 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2507 void visitSwitchInst(SwitchInst &SI) {
2510 Value *Val =
SI.getCondition();
2511 Value *ShadowVal = getShadow(Val);
2523 Value *ShadowCases =
nullptr;
2524 for (
auto Case :
SI.cases()) {
2525 if (casesToConsider <= 0)
2528 Value *Comparator = Case.getCaseValue();
2531 Value *ComparisonShadow = propagateEqualityComparison(
2532 IRB, Val, Comparator, ShadowVal, getShadow(Comparator));
2535 ShadowCases = IRB.
CreateOr(ShadowCases, ComparisonShadow);
2537 ShadowCases = ComparisonShadow;
2543 insertCheckShadow(ShadowCases, getOrigin(Val), &SI);
2547 void visitExtractElementInst(ExtractElementInst &
I) {
2548 insertCheckShadowOf(
I.getOperand(1), &
I);
2552 setOrigin(&
I, getOrigin(&
I, 0));
2555 void visitInsertElementInst(InsertElementInst &
I) {
2556 insertCheckShadowOf(
I.getOperand(2), &
I);
2558 auto *Shadow0 = getShadow(&
I, 0);
2559 auto *Shadow1 = getShadow(&
I, 1);
2562 setOriginForNaryOp(
I);
2565 void visitShuffleVectorInst(ShuffleVectorInst &
I) {
2567 auto *Shadow0 = getShadow(&
I, 0);
2568 auto *Shadow1 = getShadow(&
I, 1);
2571 setOriginForNaryOp(
I);
2575 void visitSExtInst(SExtInst &
I) {
2577 setShadow(&
I, IRB.
CreateSExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2578 setOrigin(&
I, getOrigin(&
I, 0));
2581 void visitZExtInst(ZExtInst &
I) {
2583 setShadow(&
I, IRB.
CreateZExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2584 setOrigin(&
I, getOrigin(&
I, 0));
2587 void visitTruncInst(TruncInst &
I) {
2589 setShadow(&
I, IRB.
CreateTrunc(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2590 setOrigin(&
I, getOrigin(&
I, 0));
2593 void visitBitCastInst(BitCastInst &
I) {
2598 if (CI->isMustTailCall())
2602 setOrigin(&
I, getOrigin(&
I, 0));
2605 void visitPtrToIntInst(PtrToIntInst &
I) {
2608 "_msprop_ptrtoint"));
2609 setOrigin(&
I, getOrigin(&
I, 0));
2612 void visitIntToPtrInst(IntToPtrInst &
I) {
2615 "_msprop_inttoptr"));
2616 setOrigin(&
I, getOrigin(&
I, 0));
2619 void visitFPToSIInst(CastInst &
I) { handleShadowOr(
I); }
2620 void visitFPToUIInst(CastInst &
I) { handleShadowOr(
I); }
2621 void visitSIToFPInst(CastInst &
I) { handleShadowOr(
I); }
2622 void visitUIToFPInst(CastInst &
I) { handleShadowOr(
I); }
2623 void visitFPExtInst(CastInst &
I) { handleShadowOr(
I); }
2624 void visitFPTruncInst(CastInst &
I) { handleShadowOr(
I); }
2655 return IRB.
CreateOr({S1S2, V1S2, S1V2});
2659 void visitAnd(BinaryOperator &
I) {
2661 Value *V1 =
I.getOperand(0);
2662 Value *V2 =
I.getOperand(1);
2664 Value *S2 = getShadow(&
I, 1);
2666 Value *OutShadow = handleBitwiseAnd(IRB, V1, V2,
S1, S2);
2668 setShadow(&
I, OutShadow);
2669 setOriginForNaryOp(
I);
2672 void visitOr(BinaryOperator &
I) {
2685 Value *S2 = getShadow(&
I, 1);
2686 Value *V1 =
I.getOperand(0);
2687 Value *V2 =
I.getOperand(1);
2711 S = IRB.
CreateOr(S, DisjointOrShadow,
"_ms_disjoint");
2715 setOriginForNaryOp(
I);
2733 template <
bool CombineShadow>
class Combiner {
2734 Value *Shadow =
nullptr;
2735 Value *Origin =
nullptr;
2737 MemorySanitizerVisitor *MSV;
2740 Combiner(MemorySanitizerVisitor *MSV,
IRBuilder<> &IRB)
2741 : IRB(IRB), MSV(MSV) {}
2745 if (CombineShadow) {
2750 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2751 Shadow = IRB.
CreateOr(Shadow, OpShadow,
"_msprop");
2755 if (MSV->MS.TrackOrigins) {
2762 if (!ConstOrigin || !ConstOrigin->
isNullValue()) {
2763 Value *
Cond = MSV->convertToBool(OpShadow, IRB);
2773 Value *OpShadow = MSV->getShadow(V);
2774 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) :
nullptr;
2775 return Add(OpShadow, OpOrigin);
2780 void Done(Instruction *
I) {
2781 if (CombineShadow) {
2783 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(
I));
2784 MSV->setShadow(
I, Shadow);
2786 if (MSV->MS.TrackOrigins) {
2788 MSV->setOrigin(
I, Origin);
2794 void DoneAndStoreOrigin(TypeSize TS,
Value *OriginPtr) {
2795 if (MSV->MS.TrackOrigins) {
2802 using ShadowAndOriginCombiner = Combiner<true>;
2803 using OriginCombiner = Combiner<false>;
2806 void setOriginForNaryOp(Instruction &
I) {
2807 if (!MS.TrackOrigins)
2810 OriginCombiner OC(
this, IRB);
2811 for (Use &
Op :
I.operands())
2816 size_t VectorOrPrimitiveTypeSizeInBits(
Type *Ty) {
2818 "Vector of pointers is not a valid shadow type");
2828 Type *srcTy =
V->getType();
2831 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2832 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2833 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2851 Type *ShadowTy = getShadowTy(V);
2852 if (
V->getType() == ShadowTy)
2854 if (
V->getType()->isPtrOrPtrVectorTy())
2861 void handleShadowOr(Instruction &
I) {
2863 ShadowAndOriginCombiner SC(
this, IRB);
2864 for (Use &
Op :
I.operands())
2891 Value *horizontalReduce(IntrinsicInst &
I,
unsigned ReductionFactor,
2892 unsigned Shards,
Value *VectorA,
Value *VectorB) {
2897 [[maybe_unused]]
unsigned TotalNumElems = NumElems;
2903 assert(NumElems % (ReductionFactor * Shards) == 0);
2908 for (
unsigned i = 0; i < ReductionFactor; i++) {
2909 SmallVector<int, 16>
Mask;
2911 for (
unsigned j = 0;
j < Shards;
j++) {
2912 unsigned Offset = NumElems / Shards *
j;
2914 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2918 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2943 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards) {
2944 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2946 assert(
I.getType()->isVectorTy());
2947 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2949 [[maybe_unused]] FixedVectorType *ParamType =
2953 [[maybe_unused]] FixedVectorType *
ReturnType =
2961 Value *FirstArgShadow = getShadow(&
I, 0);
2962 Value *SecondArgShadow =
nullptr;
2963 if (
I.arg_size() == 2)
2964 SecondArgShadow = getShadow(&
I, 1);
2966 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2967 FirstArgShadow, SecondArgShadow);
2969 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2971 setShadow(&
I, OrShadow);
2972 setOriginForNaryOp(
I);
2982 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards,
2983 int ReinterpretElemWidth) {
2984 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2986 assert(
I.getType()->isVectorTy());
2987 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2989 FixedVectorType *ParamType =
2994 [[maybe_unused]] FixedVectorType *
ReturnType =
3001 FixedVectorType *ReinterpretShadowTy =
nullptr;
3009 Value *FirstArgShadow = getShadow(&
I, 0);
3010 FirstArgShadow = IRB.
CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
3020 Value *SecondArgShadow =
nullptr;
3021 if (
I.arg_size() == 2) {
3022 SecondArgShadow = getShadow(&
I, 1);
3023 SecondArgShadow = IRB.
CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
3026 Value *OrShadow = horizontalReduce(
I, 2, Shards,
3027 FirstArgShadow, SecondArgShadow);
3029 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
3031 setShadow(&
I, OrShadow);
3032 setOriginForNaryOp(
I);
3035 void visitFNeg(UnaryOperator &
I) { handleShadowOr(
I); }
3046 void handleMulByConstant(BinaryOperator &
I, Constant *ConstArg,
3052 Type *EltTy = VTy->getElementType();
3054 for (
unsigned Idx = 0; Idx < NumElements; ++Idx) {
3055 if (ConstantInt *Elt =
3057 const APInt &
V = Elt->getValue();
3058 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
3059 Elements.push_back(ConstantInt::get(EltTy, V2));
3061 Elements.push_back(ConstantInt::get(EltTy, 1));
3067 const APInt &
V = Elt->getValue();
3068 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
3069 ShadowMul = ConstantInt::get(Ty, V2);
3071 ShadowMul = ConstantInt::get(Ty, 1);
3077 IRB.
CreateMul(getShadow(OtherArg), ShadowMul,
"msprop_mul_cst"));
3078 setOrigin(&
I, getOrigin(OtherArg));
3081 void visitMul(BinaryOperator &
I) {
3084 if (constOp0 && !constOp1)
3085 handleMulByConstant(
I, constOp0,
I.getOperand(1));
3086 else if (constOp1 && !constOp0)
3087 handleMulByConstant(
I, constOp1,
I.getOperand(0));
3092 void visitFAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3093 void visitFSub(BinaryOperator &
I) { handleShadowOr(
I); }
3094 void visitFMul(BinaryOperator &
I) { handleShadowOr(
I); }
3095 void visitAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3096 void visitSub(BinaryOperator &
I) { handleShadowOr(
I); }
3097 void visitXor(BinaryOperator &
I) { handleShadowOr(
I); }
3099 void handleIntegerDiv(Instruction &
I) {
3102 insertCheckShadowOf(
I.getOperand(1), &
I);
3103 setShadow(&
I, getShadow(&
I, 0));
3104 setOrigin(&
I, getOrigin(&
I, 0));
3107 void visitUDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3108 void visitSDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3109 void visitURem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3110 void visitSRem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3114 void visitFDiv(BinaryOperator &
I) { handleShadowOr(
I); }
3115 void visitFRem(BinaryOperator &
I) { handleShadowOr(
I); }
3121 void handleEqualityComparison(ICmpInst &
I) {
3125 Value *Sa = getShadow(
A);
3126 Value *Sb = getShadow(
B);
3128 Value *Si = propagateEqualityComparison(IRB,
A,
B, Sa, Sb);
3131 setOriginForNaryOp(
I);
3139 void handleRelationalComparisonExact(ICmpInst &
I) {
3143 Value *Sa = getShadow(
A);
3144 Value *Sb = getShadow(
B);
3155 bool IsSigned =
I.isSigned();
3157 auto GetMinMaxUnsigned = [&](
Value *
V,
Value *S) {
3167 V = IRB.
CreateXor(V, ConstantInt::get(
V->getType(), MinVal));
3172 return std::make_pair(Min, Max);
3175 auto [Amin, Amax] = GetMinMaxUnsigned(
A, Sa);
3176 auto [Bmin, Bmax] = GetMinMaxUnsigned(
B, Sb);
3182 setOriginForNaryOp(
I);
3189 void handleSignedRelationalComparison(ICmpInst &
I) {
3194 op =
I.getOperand(0);
3195 pre =
I.getPredicate();
3197 op =
I.getOperand(1);
3198 pre =
I.getSwappedPredicate();
3211 setShadow(&
I, Shadow);
3212 setOrigin(&
I, getOrigin(
op));
3218 void visitICmpInst(ICmpInst &
I) {
3223 if (
I.isEquality()) {
3224 handleEqualityComparison(
I);
3230 handleRelationalComparisonExact(
I);
3234 handleSignedRelationalComparison(
I);
3240 handleRelationalComparisonExact(
I);
3247 void visitFCmpInst(FCmpInst &
I) { handleShadowOr(
I); }
3249 void handleShift(BinaryOperator &
I) {
3254 Value *S2 = getShadow(&
I, 1);
3257 Value *V2 =
I.getOperand(1);
3259 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3260 setOriginForNaryOp(
I);
3263 void visitShl(BinaryOperator &
I) { handleShift(
I); }
3264 void visitAShr(BinaryOperator &
I) { handleShift(
I); }
3265 void visitLShr(BinaryOperator &
I) { handleShift(
I); }
3267 void handleFunnelShift(IntrinsicInst &
I) {
3271 Value *S0 = getShadow(&
I, 0);
3273 Value *S2 = getShadow(&
I, 2);
3276 Value *V2 =
I.getOperand(2);
3279 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3280 setOriginForNaryOp(
I);
3293 void visitMemMoveInst(MemMoveInst &
I) {
3294 getShadow(
I.getArgOperand(1));
3297 {I.getArgOperand(0), I.getArgOperand(1),
3298 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3316 void visitMemCpyInst(MemCpyInst &
I) {
3317 getShadow(
I.getArgOperand(1));
3320 {I.getArgOperand(0), I.getArgOperand(1),
3321 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3326 void visitMemSetInst(MemSetInst &
I) {
3330 {I.getArgOperand(0),
3331 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3332 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3336 void visitVAStartInst(VAStartInst &
I) { VAHelper->visitVAStartInst(
I); }
3338 void visitVACopyInst(VACopyInst &
I) { VAHelper->visitVACopyInst(
I); }
3344 bool handleVectorStoreIntrinsic(IntrinsicInst &
I) {
3348 Value *Addr =
I.getArgOperand(0);
3349 Value *Shadow = getShadow(&
I, 1);
3350 Value *ShadowPtr, *OriginPtr;
3354 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3359 insertCheckShadowOf(Addr, &
I);
3362 if (MS.TrackOrigins)
3371 bool handleVectorLoadIntrinsic(IntrinsicInst &
I) {
3375 Value *Addr =
I.getArgOperand(0);
3377 Type *ShadowTy = getShadowTy(&
I);
3378 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
3379 if (PropagateShadow) {
3383 std::tie(ShadowPtr, OriginPtr) =
3384 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
3388 setShadow(&
I, getCleanShadow(&
I));
3392 insertCheckShadowOf(Addr, &
I);
3394 if (MS.TrackOrigins) {
3395 if (PropagateShadow)
3396 setOrigin(&
I, IRB.
CreateLoad(MS.OriginTy, OriginPtr));
3398 setOrigin(&
I, getCleanOrigin());
3418 [[maybe_unused]]
bool
3419 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &
I,
3420 unsigned int trailingFlags) {
3421 Type *RetTy =
I.getType();
3425 unsigned NumArgOperands =
I.arg_size();
3426 assert(NumArgOperands >= trailingFlags);
3427 for (
unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3428 Type *Ty =
I.getArgOperand(i)->getType();
3434 ShadowAndOriginCombiner SC(
this, IRB);
3435 for (
unsigned i = 0; i < NumArgOperands; ++i)
3436 SC.Add(
I.getArgOperand(i));
3453 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &
I) {
3454 unsigned NumArgOperands =
I.arg_size();
3455 if (NumArgOperands == 0)
3458 if (NumArgOperands == 2 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3459 I.getArgOperand(1)->getType()->isVectorTy() &&
3460 I.getType()->isVoidTy() && !
I.onlyReadsMemory()) {
3462 return handleVectorStoreIntrinsic(
I);
3465 if (NumArgOperands == 1 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3466 I.getType()->isVectorTy() &&
I.onlyReadsMemory()) {
3468 return handleVectorLoadIntrinsic(
I);
3471 if (
I.doesNotAccessMemory())
3472 if (maybeHandleSimpleNomemIntrinsic(
I, 0))
3480 bool maybeHandleUnknownIntrinsic(IntrinsicInst &
I) {
3481 if (maybeHandleUnknownIntrinsicUnlogged(
I)) {
3483 dumpInst(
I,
"Heuristic");
3485 LLVM_DEBUG(
dbgs() <<
"UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " <<
I
3492 void handleInvariantGroup(IntrinsicInst &
I) {
3493 setShadow(&
I, getShadow(&
I, 0));
3494 setOrigin(&
I, getOrigin(&
I, 0));
3497 void handleLifetimeStart(IntrinsicInst &
I) {
3502 LifetimeStartList.push_back(std::make_pair(&
I, AI));
3505 void handleBswap(IntrinsicInst &
I) {
3508 Type *OpType =
Op->getType();
3511 setOrigin(&
I, getOrigin(
Op));
3532 void handleCountLeadingTrailingZeros(IntrinsicInst &
I) {
3534 Value *Src =
I.getArgOperand(0);
3535 Value *SrcShadow = getShadow(Src);
3539 I.getType(),
I.getIntrinsicID(), {Src, False});
3541 I.getType(),
I.getIntrinsicID(), {SrcShadow, False});
3544 ConcreteZerosCount, ShadowZerosCount,
"_mscz_cmp_zeros");
3546 Value *NotAllZeroShadow =
3548 Value *OutputShadow =
3549 IRB.
CreateAnd(CompareConcreteZeros, NotAllZeroShadow,
"_mscz_main");
3555 OutputShadow = IRB.
CreateOr(OutputShadow, BoolZeroPoison,
"_mscz_bs");
3558 OutputShadow = IRB.
CreateSExt(OutputShadow, getShadowTy(Src),
"_mscz_os");
3560 setShadow(&
I, OutputShadow);
3561 setOriginForNaryOp(
I);
3576 void handleNEONVectorConvertIntrinsic(IntrinsicInst &
I,
bool FixedPoint) {
3583 Value *S0 = getShadow(&
I, 0);
3586 Value *Precision =
I.getOperand(1);
3587 insertCheckShadowOf(Precision, &
I);
3597 setShadow(&
I, OutShadow);
3598 setOriginForNaryOp(
I);
3607 FixedVectorType *maybeShrinkVectorShadowType(
Value *Src, IntrinsicInst &
I) {
3627 Value *maybeExtendVectorShadowWithZeros(
Value *Shadow, IntrinsicInst &
I) {
3632 Value *FullShadow = getCleanShadow(&
I);
3633 unsigned ShadowNumElems =
3635 unsigned FullShadowNumElems =
3638 assert((ShadowNumElems == FullShadowNumElems) ||
3639 (ShadowNumElems * 2 == FullShadowNumElems));
3641 if (ShadowNumElems == FullShadowNumElems) {
3642 FullShadow = Shadow;
3646 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3671 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &
I,
3672 bool HasRoundingMode) {
3673 if (HasRoundingMode) {
3681 Value *Src =
I.getArgOperand(0);
3682 assert(Src->getType()->isVectorTy());
3686 VectorType *ShadowType = maybeShrinkVectorShadowType(Src,
I);
3689 Value *S0 = getShadow(&
I, 0);
3701 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow,
I);
3703 setShadow(&
I, FullShadow);
3704 setOriginForNaryOp(
I);
3725 void handleSSEVectorConvertIntrinsic(IntrinsicInst &
I,
int NumUsedElements,
3726 bool HasRoundingMode =
false) {
3728 Value *CopyOp, *ConvertOp;
3730 assert((!HasRoundingMode ||
3732 "Invalid rounding mode");
3734 switch (
I.arg_size() - HasRoundingMode) {
3736 CopyOp =
I.getArgOperand(0);
3737 ConvertOp =
I.getArgOperand(1);
3740 ConvertOp =
I.getArgOperand(0);
3754 Value *ConvertShadow = getShadow(ConvertOp);
3755 Value *AggShadow =
nullptr;
3758 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
3759 for (
int i = 1; i < NumUsedElements; ++i) {
3761 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
3762 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
3765 AggShadow = ConvertShadow;
3768 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &
I);
3775 Value *ResultShadow = getShadow(CopyOp);
3777 for (
int i = 0; i < NumUsedElements; ++i) {
3779 ResultShadow, ConstantInt::getNullValue(EltTy),
3782 setShadow(&
I, ResultShadow);
3783 setOrigin(&
I, getOrigin(CopyOp));
3785 setShadow(&
I, getCleanShadow(&
I));
3786 setOrigin(&
I, getCleanOrigin());
3794 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
3797 return CreateShadowCast(IRB, S2,
T,
true);
3805 return CreateShadowCast(IRB, S2,
T,
true);
3822 void handleVectorShiftIntrinsic(IntrinsicInst &
I,
bool Variable) {
3828 Value *S2 = getShadow(&
I, 1);
3830 : Lower64ShadowExtend(IRB, S2, getShadowTy(&
I));
3831 Value *V1 =
I.getOperand(0);
3832 Value *V2 =
I.getOperand(1);
3834 {IRB.CreateBitCast(S1, V1->getType()), V2});
3836 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3837 setOriginForNaryOp(
I);
3842 Type *getMMXVectorTy(
unsigned EltSizeInBits,
3843 unsigned X86_MMXSizeInBits = 64) {
3844 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3845 "Illegal MMX vector element size");
3847 X86_MMXSizeInBits / EltSizeInBits);
3854 case Intrinsic::x86_sse2_packsswb_128:
3855 case Intrinsic::x86_sse2_packuswb_128:
3856 return Intrinsic::x86_sse2_packsswb_128;
3858 case Intrinsic::x86_sse2_packssdw_128:
3859 case Intrinsic::x86_sse41_packusdw:
3860 return Intrinsic::x86_sse2_packssdw_128;
3862 case Intrinsic::x86_avx2_packsswb:
3863 case Intrinsic::x86_avx2_packuswb:
3864 return Intrinsic::x86_avx2_packsswb;
3866 case Intrinsic::x86_avx2_packssdw:
3867 case Intrinsic::x86_avx2_packusdw:
3868 return Intrinsic::x86_avx2_packssdw;
3870 case Intrinsic::x86_mmx_packsswb:
3871 case Intrinsic::x86_mmx_packuswb:
3872 return Intrinsic::x86_mmx_packsswb;
3874 case Intrinsic::x86_mmx_packssdw:
3875 return Intrinsic::x86_mmx_packssdw;
3877 case Intrinsic::x86_avx512_packssdw_512:
3878 case Intrinsic::x86_avx512_packusdw_512:
3879 return Intrinsic::x86_avx512_packssdw_512;
3881 case Intrinsic::x86_avx512_packsswb_512:
3882 case Intrinsic::x86_avx512_packuswb_512:
3883 return Intrinsic::x86_avx512_packsswb_512;
3899 void handleVectorPackIntrinsic(IntrinsicInst &
I,
3900 unsigned MMXEltSizeInBits = 0) {
3904 Value *S2 = getShadow(&
I, 1);
3905 assert(
S1->getType()->isVectorTy());
3911 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) :
S1->
getType();
3912 if (MMXEltSizeInBits) {
3920 if (MMXEltSizeInBits) {
3926 {S1_ext, S2_ext},
nullptr,
3927 "_msprop_vector_pack");
3928 if (MMXEltSizeInBits)
3931 setOriginForNaryOp(
I);
3935 Constant *createDppMask(
unsigned Width,
unsigned Mask) {
3936 SmallVector<Constant *, 4>
R(Width);
3948 const unsigned Width =
3955 Value *DstMaskV = createDppMask(Width, DstMask);
3972 void handleDppIntrinsic(IntrinsicInst &
I) {
3975 Value *S0 = getShadow(&
I, 0);
3979 const unsigned Width =
3981 assert(Width == 2 || Width == 4 || Width == 8);
3984 const unsigned SrcMask =
Mask >> 4;
3985 const unsigned DstMask =
Mask & 0xf;
3988 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3993 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
4000 setOriginForNaryOp(
I);
4004 C = CreateAppToShadowCast(IRB,
C);
4013 void handleBlendvIntrinsic(IntrinsicInst &
I) {
4018 Value *Sc = getShadow(&
I, 2);
4019 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
4024 C = convertBlendvToSelectMask(IRB,
C);
4025 Sc = convertBlendvToSelectMask(IRB, Sc);
4031 handleSelectLikeInst(
I,
C,
T,
F);
4035 void handleVectorSadIntrinsic(IntrinsicInst &
I,
bool IsMMX =
false) {
4036 const unsigned SignificantBitsPerResultElement = 16;
4038 unsigned ZeroBitsPerResultElement =
4042 auto *Shadow0 = getShadow(&
I, 0);
4043 auto *Shadow1 = getShadow(&
I, 1);
4048 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
4051 setOriginForNaryOp(
I);
4075 void handleVectorDotProductIntrinsic(IntrinsicInst &
I,
4076 unsigned ReductionFactor,
4078 unsigned EltSizeInBits,
4082 [[maybe_unused]] FixedVectorType *
ReturnType =
4087 Value *Va =
nullptr;
4088 Value *Vb =
nullptr;
4089 Value *Sa =
nullptr;
4090 Value *Sb =
nullptr;
4092 assert(
I.arg_size() == 2 ||
I.arg_size() == 3);
4093 if (
I.arg_size() == 2) {
4096 Va =
I.getOperand(0);
4097 Vb =
I.getOperand(1);
4099 Sa = getShadow(&
I, 0);
4100 Sb = getShadow(&
I, 1);
4101 }
else if (
I.arg_size() == 3) {
4103 Va =
I.getOperand(1);
4104 Vb =
I.getOperand(2);
4106 Sa = getShadow(&
I, 1);
4107 Sb = getShadow(&
I, 2);
4124 Sa, getPclmulMask(Width, Lanes ==
kOddLanes));
4126 Sb, getPclmulMask(Width, Lanes ==
kOddLanes));
4136 if (
I.arg_size() == 3) {
4137 [[maybe_unused]]
auto *AccumulatorType =
4139 assert(AccumulatorType == ReturnType);
4142 FixedVectorType *ImplicitReturnType =
4145 if (EltSizeInBits) {
4147 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4159 ReturnType->getNumElements() * ReductionFactor);
4176 VaInt = CreateAppToShadowCast(IRB, Va);
4177 VbInt = CreateAppToShadowCast(IRB, Vb);
4184 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4206 ImplicitReturnType);
4211 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&
I));
4214 if (
I.arg_size() == 3)
4215 OutShadow = IRB.
CreateOr(OutShadow, getShadow(&
I, 0));
4217 setShadow(&
I, OutShadow);
4218 setOriginForNaryOp(
I);
4235 void handleVectorComparePackedIntrinsic(IntrinsicInst &
I,
4236 bool PredicateAsOperand) {
4237 if (PredicateAsOperand) {
4239 assert(
I.paramHasAttr(2, Attribute::ImmArg));
4247 Type *ResTy = getShadowTy(&
I);
4248 auto *Shadow0 = getShadow(&
I, 0);
4249 auto *Shadow1 = getShadow(&
I, 1);
4254 setOriginForNaryOp(
I);
4260 void handleVectorCompareScalarIntrinsic(IntrinsicInst &
I) {
4262 auto *Shadow0 = getShadow(&
I, 0);
4263 auto *Shadow1 = getShadow(&
I, 1);
4265 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&
I));
4267 setOriginForNaryOp(
I);
4276 void handleVectorReduceIntrinsic(IntrinsicInst &
I,
bool AllowShadowCast) {
4281 if (AllowShadowCast)
4282 S = CreateShadowCast(IRB, S, getShadowTy(&
I));
4286 setOriginForNaryOp(
I);
4296 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &
I) {
4300 Value *Shadow0 = getShadow(&
I, 0);
4306 setOriginForNaryOp(
I);
4312 void handleVectorReduceOrIntrinsic(IntrinsicInst &
I) {
4316 Value *OperandShadow = getShadow(&
I, 0);
4318 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
4326 setOrigin(&
I, getOrigin(&
I, 0));
4332 void handleVectorReduceAndIntrinsic(IntrinsicInst &
I) {
4336 Value *OperandShadow = getShadow(&
I, 0);
4337 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
4345 setOrigin(&
I, getOrigin(&
I, 0));
4348 void handleStmxcsr(IntrinsicInst &
I) {
4350 Value *Addr =
I.getArgOperand(0);
4353 getShadowOriginPtr(Addr, IRB, Ty,
Align(1),
true).first;
4358 insertCheckShadowOf(Addr, &
I);
4361 void handleLdmxcsr(IntrinsicInst &
I) {
4366 Value *Addr =
I.getArgOperand(0);
4369 Value *ShadowPtr, *OriginPtr;
4370 std::tie(ShadowPtr, OriginPtr) =
4371 getShadowOriginPtr(Addr, IRB, Ty, Alignment,
false);
4374 insertCheckShadowOf(Addr, &
I);
4377 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
4379 insertCheckShadow(Shadow, Origin, &
I);
4382 void handleMaskedExpandLoad(IntrinsicInst &
I) {
4384 Value *Ptr =
I.getArgOperand(0);
4385 MaybeAlign
Align =
I.getParamAlign(0);
4387 Value *PassThru =
I.getArgOperand(2);
4390 insertCheckShadowOf(Ptr, &
I);
4391 insertCheckShadowOf(Mask, &
I);
4394 if (!PropagateShadow) {
4395 setShadow(&
I, getCleanShadow(&
I));
4396 setOrigin(&
I, getCleanOrigin());
4400 Type *ShadowTy = getShadowTy(&
I);
4402 auto [ShadowPtr, OriginPtr] =
4403 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
false);
4407 getShadow(PassThru),
"_msmaskedexpload");
4409 setShadow(&
I, Shadow);
4412 setOrigin(&
I, getCleanOrigin());
4415 void handleMaskedCompressStore(IntrinsicInst &
I) {
4417 Value *Values =
I.getArgOperand(0);
4418 Value *Ptr =
I.getArgOperand(1);
4419 MaybeAlign
Align =
I.getParamAlign(1);
4423 insertCheckShadowOf(Ptr, &
I);
4424 insertCheckShadowOf(Mask, &
I);
4427 Value *Shadow = getShadow(Values);
4428 Type *ElementShadowTy =
4430 auto [ShadowPtr, OriginPtrs] =
4431 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
true);
4438 void handleMaskedGather(IntrinsicInst &
I) {
4440 Value *Ptrs =
I.getArgOperand(0);
4441 const Align Alignment =
I.getParamAlign(0).valueOrOne();
4443 Value *PassThru =
I.getArgOperand(2);
4445 Type *PtrsShadowTy = getShadowTy(Ptrs);
4447 insertCheckShadowOf(Mask, &
I);
4451 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4454 if (!PropagateShadow) {
4455 setShadow(&
I, getCleanShadow(&
I));
4456 setOrigin(&
I, getCleanOrigin());
4460 Type *ShadowTy = getShadowTy(&
I);
4462 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4463 Ptrs, IRB, ElementShadowTy, Alignment,
false);
4467 getShadow(PassThru),
"_msmaskedgather");
4469 setShadow(&
I, Shadow);
4472 setOrigin(&
I, getCleanOrigin());
4475 void handleMaskedScatter(IntrinsicInst &
I) {
4477 Value *Values =
I.getArgOperand(0);
4478 Value *Ptrs =
I.getArgOperand(1);
4479 const Align Alignment =
I.getParamAlign(1).valueOrOne();
4482 Type *PtrsShadowTy = getShadowTy(Ptrs);
4484 insertCheckShadowOf(Mask, &
I);
4488 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4491 Value *Shadow = getShadow(Values);
4492 Type *ElementShadowTy =
4494 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4495 Ptrs, IRB, ElementShadowTy, Alignment,
true);
4506 void handleMaskedStore(IntrinsicInst &
I) {
4508 Value *
V =
I.getArgOperand(0);
4509 Value *Ptr =
I.getArgOperand(1);
4510 const Align Alignment =
I.getParamAlign(1).valueOrOne();
4512 Value *Shadow = getShadow(V);
4515 insertCheckShadowOf(Ptr, &
I);
4516 insertCheckShadowOf(Mask, &
I);
4521 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4522 Ptr, IRB, Shadow->
getType(), Alignment,
true);
4526 if (!MS.TrackOrigins)
4529 auto &
DL =
F.getDataLayout();
4530 paintOrigin(IRB, getOrigin(V), OriginPtr,
4539 void handleMaskedLoad(IntrinsicInst &
I) {
4541 Value *Ptr =
I.getArgOperand(0);
4542 const Align Alignment =
I.getParamAlign(0).valueOrOne();
4544 Value *PassThru =
I.getArgOperand(2);
4547 insertCheckShadowOf(Ptr, &
I);
4548 insertCheckShadowOf(Mask, &
I);
4551 if (!PropagateShadow) {
4552 setShadow(&
I, getCleanShadow(&
I));
4553 setOrigin(&
I, getCleanOrigin());
4557 Type *ShadowTy = getShadowTy(&
I);
4558 Value *ShadowPtr, *OriginPtr;
4559 std::tie(ShadowPtr, OriginPtr) =
4560 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment,
false);
4562 getShadow(PassThru),
"_msmaskedld"));
4564 if (!MS.TrackOrigins)
4571 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
4576 setOrigin(&
I, Origin);
4592 void handleAVXMaskedStore(IntrinsicInst &
I) {
4597 Value *Dst =
I.getArgOperand(0);
4598 assert(Dst->getType()->isPointerTy() &&
"Destination is not a pointer!");
4603 Value *Src =
I.getArgOperand(2);
4608 Value *SrcShadow = getShadow(Src);
4611 insertCheckShadowOf(Dst, &
I);
4612 insertCheckShadowOf(Mask, &
I);
4615 Value *DstShadowPtr;
4616 Value *DstOriginPtr;
4617 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4618 Dst, IRB, SrcShadow->
getType(), Alignment,
true);
4620 SmallVector<Value *, 2> ShadowArgs;
4621 ShadowArgs.
append(1, DstShadowPtr);
4622 ShadowArgs.
append(1, Mask);
4633 if (!MS.TrackOrigins)
4637 auto &
DL =
F.getDataLayout();
4638 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4639 DL.getTypeStoreSize(SrcShadow->
getType()),
4658 void handleAVXMaskedLoad(IntrinsicInst &
I) {
4663 Value *Src =
I.getArgOperand(0);
4664 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
4672 insertCheckShadowOf(Mask, &
I);
4675 Type *SrcShadowTy = getShadowTy(Src);
4676 Value *SrcShadowPtr, *SrcOriginPtr;
4677 std::tie(SrcShadowPtr, SrcOriginPtr) =
4678 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment,
false);
4680 SmallVector<Value *, 2> ShadowArgs;
4681 ShadowArgs.
append(1, SrcShadowPtr);
4682 ShadowArgs.
append(1, Mask);
4691 if (!MS.TrackOrigins)
4698 setOrigin(&
I, PtrSrcOrigin);
4707 assert(isFixedIntVector(Idx));
4708 auto IdxVectorSize =
4716 auto *IdxShadow = getShadow(Idx);
4721 insertCheckShadow(Truncated, getOrigin(Idx),
I);
4726 void handleAVXVpermilvar(IntrinsicInst &
I) {
4728 Value *Shadow = getShadow(&
I, 0);
4729 maskedCheckAVXIndexShadow(IRB,
I.getArgOperand(1), &
I);
4733 Shadow = IRB.
CreateBitCast(Shadow,
I.getArgOperand(0)->getType());
4735 {Shadow, I.getArgOperand(1)});
4738 setOriginForNaryOp(
I);
4743 void handleAVXVpermi2var(IntrinsicInst &
I) {
4748 [[maybe_unused]]
auto ArgVectorSize =
4751 ->getNumElements() == ArgVectorSize);
4753 ->getNumElements() == ArgVectorSize);
4754 assert(
I.getArgOperand(0)->getType() ==
I.getArgOperand(2)->getType());
4755 assert(
I.getType() ==
I.getArgOperand(0)->getType());
4756 assert(
I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4758 Value *AShadow = getShadow(&
I, 0);
4759 Value *Idx =
I.getArgOperand(1);
4760 Value *BShadow = getShadow(&
I, 2);
4762 maskedCheckAVXIndexShadow(IRB, Idx, &
I);
4766 AShadow = IRB.
CreateBitCast(AShadow,
I.getArgOperand(0)->getType());
4767 BShadow = IRB.
CreateBitCast(BShadow,
I.getArgOperand(2)->getType());
4769 {AShadow, Idx, BShadow});
4771 setOriginForNaryOp(
I);
4774 [[maybe_unused]]
static bool isFixedIntVectorTy(
const Type *
T) {
4778 [[maybe_unused]]
static bool isFixedFPVectorTy(
const Type *
T) {
4782 [[maybe_unused]]
static bool isFixedIntVector(
const Value *V) {
4783 return isFixedIntVectorTy(
V->getType());
4786 [[maybe_unused]]
static bool isFixedFPVector(
const Value *V) {
4787 return isFixedFPVectorTy(
V->getType());
4809 void handleAVX512VectorConvertFPToInt(IntrinsicInst &
I,
bool LastMask) {
4814 Value *WriteThrough;
4818 WriteThrough =
I.getOperand(2);
4819 Mask =
I.getOperand(3);
4822 WriteThrough =
I.getOperand(1);
4823 Mask =
I.getOperand(2);
4828 assert(isFixedIntVector(WriteThrough));
4830 unsigned ANumElements =
4832 [[maybe_unused]]
unsigned WriteThruNumElements =
4834 assert(ANumElements == WriteThruNumElements ||
4835 ANumElements * 2 == WriteThruNumElements);
4838 unsigned MaskNumElements =
Mask->getType()->getScalarSizeInBits();
4839 assert(ANumElements == MaskNumElements ||
4840 ANumElements * 2 == MaskNumElements);
4842 assert(WriteThruNumElements == MaskNumElements);
4846 insertCheckShadowOf(Mask, &
I);
4856 Value *AShadow = getShadow(
A);
4857 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
4859 if (ANumElements * 2 == MaskNumElements) {
4871 "_ms_mask_bitcast");
4881 getShadowTy(&
I),
"_ms_a_shadow");
4883 Value *WriteThroughShadow = getShadow(WriteThrough);
4885 "_ms_writethru_select");
4887 setShadow(&
I, Shadow);
4888 setOriginForNaryOp(
I);
4896 void handleBmiIntrinsic(IntrinsicInst &
I) {
4898 Type *ShadowTy = getShadowTy(&
I);
4901 Value *SMask = getShadow(&
I, 1);
4906 {getShadow(&I, 0), I.getOperand(1)});
4909 setOriginForNaryOp(
I);
4912 static SmallVector<int, 8> getPclmulMask(
unsigned Width,
bool OddElements) {
4913 SmallVector<int, 8>
Mask;
4914 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
4928 void handlePclmulIntrinsic(IntrinsicInst &
I) {
4933 "pclmul 3rd operand must be a constant");
4936 getPclmulMask(Width, Imm & 0x01));
4938 getPclmulMask(Width, Imm & 0x10));
4939 ShadowAndOriginCombiner SOC(
this, IRB);
4940 SOC.Add(Shuf0, getOrigin(&
I, 0));
4941 SOC.Add(Shuf1, getOrigin(&
I, 1));
4946 void handleUnarySdSsIntrinsic(IntrinsicInst &
I) {
4951 Value *Second = getShadow(&
I, 1);
4953 SmallVector<int, 16>
Mask;
4954 Mask.push_back(Width);
4955 for (
unsigned i = 1; i < Width; i++)
4959 setShadow(&
I, Shadow);
4960 setOriginForNaryOp(
I);
4963 void handleVtestIntrinsic(IntrinsicInst &
I) {
4965 Value *Shadow0 = getShadow(&
I, 0);
4966 Value *Shadow1 = getShadow(&
I, 1);
4972 setShadow(&
I, Shadow);
4973 setOriginForNaryOp(
I);
4976 void handleBinarySdSsIntrinsic(IntrinsicInst &
I) {
4981 Value *Second = getShadow(&
I, 1);
4984 SmallVector<int, 16>
Mask;
4985 Mask.push_back(Width);
4986 for (
unsigned i = 1; i < Width; i++)
4990 setShadow(&
I, Shadow);
4991 setOriginForNaryOp(
I);
4997 void handleRoundPdPsIntrinsic(IntrinsicInst &
I) {
4998 assert(
I.getArgOperand(0)->getType() ==
I.getType());
5003 ShadowAndOriginCombiner SC(
this, IRB);
5004 SC.Add(
I.getArgOperand(0));
5012 void handleAbsIntrinsic(IntrinsicInst &
I) {
5014 Value *Src =
I.getArgOperand(0);
5015 Value *IsIntMinPoison =
I.getArgOperand(1);
5017 assert(
I.getType()->isIntOrIntVectorTy());
5019 assert(Src->getType() ==
I.getType());
5025 Value *SrcShadow = getShadow(Src);
5029 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5032 Value *PoisonedShadow = getPoisonedShadow(Src);
5033 Value *PoisonedIfIntMinShadow =
5036 IRB.
CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5038 setShadow(&
I, Shadow);
5039 setOrigin(&
I, getOrigin(&
I, 0));
5042 void handleIsFpClass(IntrinsicInst &
I) {
5044 Value *Shadow = getShadow(&
I, 0);
5045 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5046 setOrigin(&
I, getOrigin(&
I, 0));
5049 void handleArithmeticWithOverflow(IntrinsicInst &
I) {
5051 Value *Shadow0 = getShadow(&
I, 0);
5052 Value *Shadow1 = getShadow(&
I, 1);
5055 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5061 setShadow(&
I, Shadow);
5062 setOriginForNaryOp(
I);
5068 Value *Shadow = getShadow(V);
5090 void handleAVX512VectorDownConvert(IntrinsicInst &
I) {
5095 Value *WriteThrough =
I.getOperand(1);
5099 assert(isFixedIntVector(WriteThrough));
5101 unsigned ANumElements =
5103 unsigned OutputNumElements =
5105 assert(ANumElements == OutputNumElements ||
5106 ANumElements * 2 == OutputNumElements);
5109 assert(
Mask->getType()->getScalarSizeInBits() == ANumElements);
5110 insertCheckShadowOf(Mask, &
I);
5121 if (ANumElements != OutputNumElements) {
5123 Mask = IRB.
CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5130 Value *AShadow = getShadow(
A);
5134 VectorType *ShadowType = maybeShrinkVectorShadowType(
A,
I);
5144 AShadow = IRB.
CreateTrunc(AShadow, ShadowType,
"_ms_trunc_shadow");
5145 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
5147 Value *WriteThroughShadow = getShadow(WriteThrough);
5150 setShadow(&
I, Shadow);
5151 setOriginForNaryOp(
I);
5185 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &
I,
5186 SmallVector<unsigned, 4> DataIndices,
5187 unsigned WriteThruIndex,
5188 unsigned MaskIndex) {
5191 unsigned NumArgs =
I.arg_size();
5193 assert(WriteThruIndex < NumArgs);
5194 assert(MaskIndex < NumArgs);
5195 assert(WriteThruIndex != MaskIndex);
5196 Value *WriteThru =
I.getOperand(WriteThruIndex);
5198 unsigned OutputNumElements =
5203 bool isData[16] = {
false};
5205 for (
unsigned i : DataIndices) {
5207 assert(i != WriteThruIndex);
5214 [[maybe_unused]]
unsigned ANumElements =
5216 assert(ANumElements == OutputNumElements);
5221 assert(isFixedFPVector(WriteThru));
5223 for (
unsigned i = 0; i < NumArgs; ++i) {
5224 if (!isData[i] && i != WriteThruIndex) {
5227 assert(
I.getOperand(i)->getType()->isIntegerTy());
5228 insertCheckShadowOf(
I.getOperand(i), &
I);
5233 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5234 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5235 assert(
Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5242 Value *DataShadow =
nullptr;
5243 for (
unsigned i : DataIndices) {
5246 DataShadow = IRB.
CreateOr(DataShadow, getShadow(
A));
5248 DataShadow = getShadow(
A);
5256 Value *WriteThruShadow = getShadow(WriteThru);
5259 setShadow(&
I, Shadow);
5261 setOriginForNaryOp(
I);
5271 void visitGenericScalarHalfwordInst(IntrinsicInst &
I) {
5277 Value *WriteThrough =
I.getOperand(2);
5284 insertCheckShadowOf(Mask, &
I);
5288 unsigned NumElements =
5290 assert(NumElements == 8);
5291 assert(
A->getType() ==
B->getType());
5293 assert(
Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5296 Value *ALowerShadow = extractLowerShadow(IRB,
A);
5297 Value *BLowerShadow = extractLowerShadow(IRB,
B);
5299 Value *ABLowerShadow = IRB.
CreateOr(ALowerShadow, BLowerShadow);
5301 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5308 Value *AShadow = getShadow(
A);
5309 Value *DstLowerShadow =
5310 IRB.
CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5312 AShadow, DstLowerShadow, ConstantInt::get(IRB.
getInt32Ty(), 0),
5315 setShadow(&
I, DstShadow);
5316 setOriginForNaryOp(
I);
5346 void handleAVXGF2P8Affine(IntrinsicInst &
I) {
5357 ->getScalarSizeInBits() == 8);
5359 assert(
A->getType() ==
X->getType());
5361 assert(
B->getType()->isIntegerTy());
5362 assert(
B->getType()->getScalarSizeInBits() == 8);
5364 assert(
I.getType() ==
A->getType());
5366 Value *AShadow = getShadow(
A);
5367 Value *XShadow = getShadow(
X);
5368 Value *BZeroShadow = getCleanShadow(
B);
5371 I.getType(),
I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5373 {X, AShadow, BZeroShadow});
5375 {XShadow, A, BZeroShadow});
5378 Value *BShadow = getShadow(
B);
5379 Value *BBroadcastShadow = getCleanShadow(AShadow);
5384 for (
unsigned i = 0; i < NumElements; i++)
5388 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5389 setOriginForNaryOp(
I);
5403 void handleNEONVectorLoad(IntrinsicInst &
I,
bool WithLane) {
5404 unsigned int numArgs =
I.arg_size();
5407 assert(
I.getType()->isStructTy());
5417 assert(4 <= numArgs && numArgs <= 6);
5431 for (
unsigned int i = 0; i < numArgs - 2; i++)
5432 ShadowArgs.
push_back(getShadow(
I.getArgOperand(i)));
5435 Value *LaneNumber =
I.getArgOperand(numArgs - 2);
5439 insertCheckShadowOf(LaneNumber, &
I);
5442 Value *Src =
I.getArgOperand(numArgs - 1);
5443 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
5445 Type *SrcShadowTy = getShadowTy(Src);
5446 auto [SrcShadowPtr, SrcOriginPtr] =
5447 getShadowOriginPtr(Src, IRB, SrcShadowTy,
Align(1),
false);
5457 if (!MS.TrackOrigins)
5461 setOrigin(&
I, PtrSrcOrigin);
5478 void handleNEONVectorStoreIntrinsic(IntrinsicInst &
I,
bool useLane) {
5482 int numArgOperands =
I.arg_size();
5485 assert(numArgOperands >= 1);
5486 Value *Addr =
I.getArgOperand(numArgOperands - 1);
5488 int skipTrailingOperands = 1;
5491 insertCheckShadowOf(Addr, &
I);
5495 skipTrailingOperands++;
5496 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
5498 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5501 SmallVector<Value *, 8> ShadowArgs;
5503 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5505 Value *Shadow = getShadow(&
I, i);
5506 ShadowArgs.
append(1, Shadow);
5523 (numArgOperands - skipTrailingOperands));
5524 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5528 I.getArgOperand(numArgOperands - skipTrailingOperands));
5530 Value *OutputShadowPtr, *OutputOriginPtr;
5532 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5533 Addr, IRB, OutputShadowTy,
Align(1),
true);
5534 ShadowArgs.
append(1, OutputShadowPtr);
5540 if (MS.TrackOrigins) {
5548 OriginCombiner OC(
this, IRB);
5549 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5550 OC.Add(
I.getArgOperand(i));
5552 const DataLayout &
DL =
F.getDataLayout();
5553 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
5586 void handleNEONMatrixMultiply(IntrinsicInst &
I) {
5590 Value *
R =
I.getArgOperand(0);
5591 Value *
A =
I.getArgOperand(1);
5592 Value *
B =
I.getArgOperand(2);
5594 assert(
I.getType() ==
R->getType());
5619 Value *ShadowR = getShadow(&
I, 0);
5620 Value *ShadowA = getShadow(&
I, 1);
5621 Value *ShadowB = getShadow(&
I, 2);
5639 {getCleanShadow(RTy), ShadowA, ShadowB});
5665 {RZeros, ShadowA, ShadowB});
5679 ShadowR = IRB.
CreateICmpNE(ShadowR, getCleanShadow(RTy));
5680 ShadowR = IRB.
CreateOr(ShadowAB, ShadowR);
5682 setShadow(&
I, IRB.
CreateSExt(ShadowR, getShadowTy(RTy)));
5684 setOriginForNaryOp(
I);
5709 void handleIntrinsicByApplyingToShadow(IntrinsicInst &
I,
5711 unsigned int trailingVerbatimArgs) {
5714 assert(trailingVerbatimArgs <
I.arg_size());
5716 SmallVector<Value *, 8> ShadowArgs;
5718 for (
unsigned int i = 0; i <
I.arg_size() - trailingVerbatimArgs; i++) {
5719 Value *Shadow = getShadow(&
I, i);
5727 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5729 Value *Arg =
I.getArgOperand(i);
5735 Value *CombinedShadow = CI;
5738 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5741 CreateShadowCast(IRB, getShadow(&
I, i), CombinedShadow->
getType());
5742 CombinedShadow = IRB.
CreateOr(Shadow, CombinedShadow,
"_msprop");
5747 setOriginForNaryOp(
I);
5753 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &
I) {
5759 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &
I) {
5760 switch (
I.getIntrinsicID()) {
5761 case Intrinsic::uadd_with_overflow:
5762 case Intrinsic::sadd_with_overflow:
5763 case Intrinsic::usub_with_overflow:
5764 case Intrinsic::ssub_with_overflow:
5765 case Intrinsic::umul_with_overflow:
5766 case Intrinsic::smul_with_overflow:
5767 handleArithmeticWithOverflow(
I);
5769 case Intrinsic::abs:
5770 handleAbsIntrinsic(
I);
5772 case Intrinsic::bitreverse:
5773 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
5776 case Intrinsic::is_fpclass:
5779 case Intrinsic::lifetime_start:
5780 handleLifetimeStart(
I);
5782 case Intrinsic::launder_invariant_group:
5783 case Intrinsic::strip_invariant_group:
5784 handleInvariantGroup(
I);
5786 case Intrinsic::bswap:
5789 case Intrinsic::ctlz:
5790 case Intrinsic::cttz:
5791 handleCountLeadingTrailingZeros(
I);
5793 case Intrinsic::masked_compressstore:
5794 handleMaskedCompressStore(
I);
5796 case Intrinsic::masked_expandload:
5797 handleMaskedExpandLoad(
I);
5799 case Intrinsic::masked_gather:
5800 handleMaskedGather(
I);
5802 case Intrinsic::masked_scatter:
5803 handleMaskedScatter(
I);
5805 case Intrinsic::masked_store:
5806 handleMaskedStore(
I);
5808 case Intrinsic::masked_load:
5809 handleMaskedLoad(
I);
5811 case Intrinsic::vector_reduce_and:
5812 handleVectorReduceAndIntrinsic(
I);
5814 case Intrinsic::vector_reduce_or:
5815 handleVectorReduceOrIntrinsic(
I);
5818 case Intrinsic::vector_reduce_add:
5819 case Intrinsic::vector_reduce_xor:
5820 case Intrinsic::vector_reduce_mul:
5823 case Intrinsic::vector_reduce_smax:
5824 case Intrinsic::vector_reduce_smin:
5825 case Intrinsic::vector_reduce_umax:
5826 case Intrinsic::vector_reduce_umin:
5829 case Intrinsic::vector_reduce_fmax:
5830 case Intrinsic::vector_reduce_fmin:
5831 handleVectorReduceIntrinsic(
I,
false);
5834 case Intrinsic::vector_reduce_fadd:
5835 case Intrinsic::vector_reduce_fmul:
5836 handleVectorReduceWithStarterIntrinsic(
I);
5839 case Intrinsic::scmp:
5840 case Intrinsic::ucmp: {
5845 case Intrinsic::fshl:
5846 case Intrinsic::fshr:
5847 handleFunnelShift(
I);
5850 case Intrinsic::is_constant:
5852 setShadow(&
I, getCleanShadow(&
I));
5853 setOrigin(&
I, getCleanOrigin());
5863 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &
I) {
5864 switch (
I.getIntrinsicID()) {
5865 case Intrinsic::x86_sse_stmxcsr:
5868 case Intrinsic::x86_sse_ldmxcsr:
5875 case Intrinsic::x86_avx512_vcvtsd2usi64:
5876 case Intrinsic::x86_avx512_vcvtsd2usi32:
5877 case Intrinsic::x86_avx512_vcvtss2usi64:
5878 case Intrinsic::x86_avx512_vcvtss2usi32:
5879 case Intrinsic::x86_avx512_cvttss2usi64:
5880 case Intrinsic::x86_avx512_cvttss2usi:
5881 case Intrinsic::x86_avx512_cvttsd2usi64:
5882 case Intrinsic::x86_avx512_cvttsd2usi:
5883 case Intrinsic::x86_avx512_cvtusi2ss:
5884 case Intrinsic::x86_avx512_cvtusi642sd:
5885 case Intrinsic::x86_avx512_cvtusi642ss:
5886 handleSSEVectorConvertIntrinsic(
I, 1,
true);
5888 case Intrinsic::x86_sse2_cvtsd2si64:
5889 case Intrinsic::x86_sse2_cvtsd2si:
5890 case Intrinsic::x86_sse2_cvtsd2ss:
5891 case Intrinsic::x86_sse2_cvttsd2si64:
5892 case Intrinsic::x86_sse2_cvttsd2si:
5893 case Intrinsic::x86_sse_cvtss2si64:
5894 case Intrinsic::x86_sse_cvtss2si:
5895 case Intrinsic::x86_sse_cvttss2si64:
5896 case Intrinsic::x86_sse_cvttss2si:
5897 handleSSEVectorConvertIntrinsic(
I, 1);
5899 case Intrinsic::x86_sse_cvtps2pi:
5900 case Intrinsic::x86_sse_cvttps2pi:
5901 handleSSEVectorConvertIntrinsic(
I, 2);
5909 case Intrinsic::x86_vcvtps2ph_128:
5910 case Intrinsic::x86_vcvtps2ph_256: {
5911 handleSSEVectorConvertIntrinsicByProp(
I,
true);
5920 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
5921 handleAVX512VectorConvertFPToInt(
I,
false);
5926 case Intrinsic::x86_sse2_cvtpd2ps:
5927 case Intrinsic::x86_sse2_cvtps2dq:
5928 case Intrinsic::x86_sse2_cvtpd2dq:
5929 case Intrinsic::x86_sse2_cvttps2dq:
5930 case Intrinsic::x86_sse2_cvttpd2dq:
5931 case Intrinsic::x86_avx_cvt_pd2_ps_256:
5932 case Intrinsic::x86_avx_cvt_ps2dq_256:
5933 case Intrinsic::x86_avx_cvt_pd2dq_256:
5934 case Intrinsic::x86_avx_cvtt_ps2dq_256:
5935 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
5936 handleSSEVectorConvertIntrinsicByProp(
I,
false);
5947 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
5948 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
5949 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
5950 handleAVX512VectorConvertFPToInt(
I,
true);
5954 case Intrinsic::x86_avx512_psll_w_512:
5955 case Intrinsic::x86_avx512_psll_d_512:
5956 case Intrinsic::x86_avx512_psll_q_512:
5957 case Intrinsic::x86_avx512_pslli_w_512:
5958 case Intrinsic::x86_avx512_pslli_d_512:
5959 case Intrinsic::x86_avx512_pslli_q_512:
5960 case Intrinsic::x86_avx512_psrl_w_512:
5961 case Intrinsic::x86_avx512_psrl_d_512:
5962 case Intrinsic::x86_avx512_psrl_q_512:
5963 case Intrinsic::x86_avx512_psra_w_512:
5964 case Intrinsic::x86_avx512_psra_d_512:
5965 case Intrinsic::x86_avx512_psra_q_512:
5966 case Intrinsic::x86_avx512_psrli_w_512:
5967 case Intrinsic::x86_avx512_psrli_d_512:
5968 case Intrinsic::x86_avx512_psrli_q_512:
5969 case Intrinsic::x86_avx512_psrai_w_512:
5970 case Intrinsic::x86_avx512_psrai_d_512:
5971 case Intrinsic::x86_avx512_psrai_q_512:
5972 case Intrinsic::x86_avx512_psra_q_256:
5973 case Intrinsic::x86_avx512_psra_q_128:
5974 case Intrinsic::x86_avx512_psrai_q_256:
5975 case Intrinsic::x86_avx512_psrai_q_128:
5976 case Intrinsic::x86_avx2_psll_w:
5977 case Intrinsic::x86_avx2_psll_d:
5978 case Intrinsic::x86_avx2_psll_q:
5979 case Intrinsic::x86_avx2_pslli_w:
5980 case Intrinsic::x86_avx2_pslli_d:
5981 case Intrinsic::x86_avx2_pslli_q:
5982 case Intrinsic::x86_avx2_psrl_w:
5983 case Intrinsic::x86_avx2_psrl_d:
5984 case Intrinsic::x86_avx2_psrl_q:
5985 case Intrinsic::x86_avx2_psra_w:
5986 case Intrinsic::x86_avx2_psra_d:
5987 case Intrinsic::x86_avx2_psrli_w:
5988 case Intrinsic::x86_avx2_psrli_d:
5989 case Intrinsic::x86_avx2_psrli_q:
5990 case Intrinsic::x86_avx2_psrai_w:
5991 case Intrinsic::x86_avx2_psrai_d:
5992 case Intrinsic::x86_sse2_psll_w:
5993 case Intrinsic::x86_sse2_psll_d:
5994 case Intrinsic::x86_sse2_psll_q:
5995 case Intrinsic::x86_sse2_pslli_w:
5996 case Intrinsic::x86_sse2_pslli_d:
5997 case Intrinsic::x86_sse2_pslli_q:
5998 case Intrinsic::x86_sse2_psrl_w:
5999 case Intrinsic::x86_sse2_psrl_d:
6000 case Intrinsic::x86_sse2_psrl_q:
6001 case Intrinsic::x86_sse2_psra_w:
6002 case Intrinsic::x86_sse2_psra_d:
6003 case Intrinsic::x86_sse2_psrli_w:
6004 case Intrinsic::x86_sse2_psrli_d:
6005 case Intrinsic::x86_sse2_psrli_q:
6006 case Intrinsic::x86_sse2_psrai_w:
6007 case Intrinsic::x86_sse2_psrai_d:
6008 case Intrinsic::x86_mmx_psll_w:
6009 case Intrinsic::x86_mmx_psll_d:
6010 case Intrinsic::x86_mmx_psll_q:
6011 case Intrinsic::x86_mmx_pslli_w:
6012 case Intrinsic::x86_mmx_pslli_d:
6013 case Intrinsic::x86_mmx_pslli_q:
6014 case Intrinsic::x86_mmx_psrl_w:
6015 case Intrinsic::x86_mmx_psrl_d:
6016 case Intrinsic::x86_mmx_psrl_q:
6017 case Intrinsic::x86_mmx_psra_w:
6018 case Intrinsic::x86_mmx_psra_d:
6019 case Intrinsic::x86_mmx_psrli_w:
6020 case Intrinsic::x86_mmx_psrli_d:
6021 case Intrinsic::x86_mmx_psrli_q:
6022 case Intrinsic::x86_mmx_psrai_w:
6023 case Intrinsic::x86_mmx_psrai_d:
6024 handleVectorShiftIntrinsic(
I,
false);
6026 case Intrinsic::x86_avx2_psllv_d:
6027 case Intrinsic::x86_avx2_psllv_d_256:
6028 case Intrinsic::x86_avx512_psllv_d_512:
6029 case Intrinsic::x86_avx2_psllv_q:
6030 case Intrinsic::x86_avx2_psllv_q_256:
6031 case Intrinsic::x86_avx512_psllv_q_512:
6032 case Intrinsic::x86_avx2_psrlv_d:
6033 case Intrinsic::x86_avx2_psrlv_d_256:
6034 case Intrinsic::x86_avx512_psrlv_d_512:
6035 case Intrinsic::x86_avx2_psrlv_q:
6036 case Intrinsic::x86_avx2_psrlv_q_256:
6037 case Intrinsic::x86_avx512_psrlv_q_512:
6038 case Intrinsic::x86_avx2_psrav_d:
6039 case Intrinsic::x86_avx2_psrav_d_256:
6040 case Intrinsic::x86_avx512_psrav_d_512:
6041 case Intrinsic::x86_avx512_psrav_q_128:
6042 case Intrinsic::x86_avx512_psrav_q_256:
6043 case Intrinsic::x86_avx512_psrav_q_512:
6044 handleVectorShiftIntrinsic(
I,
true);
6048 case Intrinsic::x86_sse2_packsswb_128:
6049 case Intrinsic::x86_sse2_packssdw_128:
6050 case Intrinsic::x86_sse2_packuswb_128:
6051 case Intrinsic::x86_sse41_packusdw:
6052 case Intrinsic::x86_avx2_packsswb:
6053 case Intrinsic::x86_avx2_packssdw:
6054 case Intrinsic::x86_avx2_packuswb:
6055 case Intrinsic::x86_avx2_packusdw:
6061 case Intrinsic::x86_avx512_packsswb_512:
6062 case Intrinsic::x86_avx512_packssdw_512:
6063 case Intrinsic::x86_avx512_packuswb_512:
6064 case Intrinsic::x86_avx512_packusdw_512:
6065 handleVectorPackIntrinsic(
I);
6068 case Intrinsic::x86_sse41_pblendvb:
6069 case Intrinsic::x86_sse41_blendvpd:
6070 case Intrinsic::x86_sse41_blendvps:
6071 case Intrinsic::x86_avx_blendv_pd_256:
6072 case Intrinsic::x86_avx_blendv_ps_256:
6073 case Intrinsic::x86_avx2_pblendvb:
6074 handleBlendvIntrinsic(
I);
6077 case Intrinsic::x86_avx_dp_ps_256:
6078 case Intrinsic::x86_sse41_dppd:
6079 case Intrinsic::x86_sse41_dpps:
6080 handleDppIntrinsic(
I);
6083 case Intrinsic::x86_mmx_packsswb:
6084 case Intrinsic::x86_mmx_packuswb:
6085 handleVectorPackIntrinsic(
I, 16);
6088 case Intrinsic::x86_mmx_packssdw:
6089 handleVectorPackIntrinsic(
I, 32);
6092 case Intrinsic::x86_mmx_psad_bw:
6093 handleVectorSadIntrinsic(
I,
true);
6095 case Intrinsic::x86_sse2_psad_bw:
6096 case Intrinsic::x86_avx2_psad_bw:
6097 handleVectorSadIntrinsic(
I);
6123 case Intrinsic::x86_sse2_pmadd_wd:
6124 case Intrinsic::x86_avx2_pmadd_wd:
6125 case Intrinsic::x86_avx512_pmaddw_d_512:
6126 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6127 case Intrinsic::x86_avx2_pmadd_ub_sw:
6128 case Intrinsic::x86_avx512_pmaddubs_w_512:
6129 handleVectorDotProductIntrinsic(
I, 2,
6136 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6137 handleVectorDotProductIntrinsic(
I, 2,
6144 case Intrinsic::x86_mmx_pmadd_wd:
6145 handleVectorDotProductIntrinsic(
I, 2,
6154 case Intrinsic::aarch64_neon_bfmlalt:
6155 handleVectorDotProductIntrinsic(
I, 2,
6163 case Intrinsic::aarch64_neon_bfmlalb:
6164 handleVectorDotProductIntrinsic(
I, 2,
6262 case Intrinsic::x86_avx512_vpdpbusd_128:
6263 case Intrinsic::x86_avx512_vpdpbusd_256:
6264 case Intrinsic::x86_avx512_vpdpbusd_512:
6265 case Intrinsic::x86_avx512_vpdpbusds_128:
6266 case Intrinsic::x86_avx512_vpdpbusds_256:
6267 case Intrinsic::x86_avx512_vpdpbusds_512:
6268 case Intrinsic::x86_avx2_vpdpbssd_128:
6269 case Intrinsic::x86_avx2_vpdpbssd_256:
6270 case Intrinsic::x86_avx10_vpdpbssd_512:
6271 case Intrinsic::x86_avx2_vpdpbssds_128:
6272 case Intrinsic::x86_avx2_vpdpbssds_256:
6273 case Intrinsic::x86_avx10_vpdpbssds_512:
6274 case Intrinsic::x86_avx2_vpdpbsud_128:
6275 case Intrinsic::x86_avx2_vpdpbsud_256:
6276 case Intrinsic::x86_avx10_vpdpbsud_512:
6277 case Intrinsic::x86_avx2_vpdpbsuds_128:
6278 case Intrinsic::x86_avx2_vpdpbsuds_256:
6279 case Intrinsic::x86_avx10_vpdpbsuds_512:
6280 case Intrinsic::x86_avx2_vpdpbuud_128:
6281 case Intrinsic::x86_avx2_vpdpbuud_256:
6282 case Intrinsic::x86_avx10_vpdpbuud_512:
6283 case Intrinsic::x86_avx2_vpdpbuuds_128:
6284 case Intrinsic::x86_avx2_vpdpbuuds_256:
6285 case Intrinsic::x86_avx10_vpdpbuuds_512:
6286 handleVectorDotProductIntrinsic(
I, 4,
6384 case Intrinsic::x86_avx512_vpdpwssd_128:
6385 case Intrinsic::x86_avx512_vpdpwssd_256:
6386 case Intrinsic::x86_avx512_vpdpwssd_512:
6387 case Intrinsic::x86_avx512_vpdpwssds_128:
6388 case Intrinsic::x86_avx512_vpdpwssds_256:
6389 case Intrinsic::x86_avx512_vpdpwssds_512:
6390 case Intrinsic::x86_avx2_vpdpwsud_128:
6391 case Intrinsic::x86_avx2_vpdpwsud_256:
6392 case Intrinsic::x86_avx10_vpdpwsud_512:
6393 case Intrinsic::x86_avx2_vpdpwsuds_128:
6394 case Intrinsic::x86_avx2_vpdpwsuds_256:
6395 case Intrinsic::x86_avx10_vpdpwsuds_512:
6396 case Intrinsic::x86_avx2_vpdpwusd_128:
6397 case Intrinsic::x86_avx2_vpdpwusd_256:
6398 case Intrinsic::x86_avx10_vpdpwusd_512:
6399 case Intrinsic::x86_avx2_vpdpwusds_128:
6400 case Intrinsic::x86_avx2_vpdpwusds_256:
6401 case Intrinsic::x86_avx10_vpdpwusds_512:
6402 case Intrinsic::x86_avx2_vpdpwuud_128:
6403 case Intrinsic::x86_avx2_vpdpwuud_256:
6404 case Intrinsic::x86_avx10_vpdpwuud_512:
6405 case Intrinsic::x86_avx2_vpdpwuuds_128:
6406 case Intrinsic::x86_avx2_vpdpwuuds_256:
6407 case Intrinsic::x86_avx10_vpdpwuuds_512:
6408 handleVectorDotProductIntrinsic(
I, 2,
6422 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6423 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6424 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6425 handleVectorDotProductIntrinsic(
I, 2,
6431 case Intrinsic::x86_sse_cmp_ss:
6432 case Intrinsic::x86_sse2_cmp_sd:
6433 case Intrinsic::x86_sse_comieq_ss:
6434 case Intrinsic::x86_sse_comilt_ss:
6435 case Intrinsic::x86_sse_comile_ss:
6436 case Intrinsic::x86_sse_comigt_ss:
6437 case Intrinsic::x86_sse_comige_ss:
6438 case Intrinsic::x86_sse_comineq_ss:
6439 case Intrinsic::x86_sse_ucomieq_ss:
6440 case Intrinsic::x86_sse_ucomilt_ss:
6441 case Intrinsic::x86_sse_ucomile_ss:
6442 case Intrinsic::x86_sse_ucomigt_ss:
6443 case Intrinsic::x86_sse_ucomige_ss:
6444 case Intrinsic::x86_sse_ucomineq_ss:
6445 case Intrinsic::x86_sse2_comieq_sd:
6446 case Intrinsic::x86_sse2_comilt_sd:
6447 case Intrinsic::x86_sse2_comile_sd:
6448 case Intrinsic::x86_sse2_comigt_sd:
6449 case Intrinsic::x86_sse2_comige_sd:
6450 case Intrinsic::x86_sse2_comineq_sd:
6451 case Intrinsic::x86_sse2_ucomieq_sd:
6452 case Intrinsic::x86_sse2_ucomilt_sd:
6453 case Intrinsic::x86_sse2_ucomile_sd:
6454 case Intrinsic::x86_sse2_ucomigt_sd:
6455 case Intrinsic::x86_sse2_ucomige_sd:
6456 case Intrinsic::x86_sse2_ucomineq_sd:
6457 handleVectorCompareScalarIntrinsic(
I);
6460 case Intrinsic::x86_avx_cmp_pd_256:
6461 case Intrinsic::x86_avx_cmp_ps_256:
6462 case Intrinsic::x86_sse2_cmp_pd:
6463 case Intrinsic::x86_sse_cmp_ps:
6464 handleVectorComparePackedIntrinsic(
I,
true);
6467 case Intrinsic::x86_bmi_bextr_32:
6468 case Intrinsic::x86_bmi_bextr_64:
6469 case Intrinsic::x86_bmi_bzhi_32:
6470 case Intrinsic::x86_bmi_bzhi_64:
6471 case Intrinsic::x86_bmi_pdep_32:
6472 case Intrinsic::x86_bmi_pdep_64:
6473 case Intrinsic::x86_bmi_pext_32:
6474 case Intrinsic::x86_bmi_pext_64:
6475 handleBmiIntrinsic(
I);
6478 case Intrinsic::x86_pclmulqdq:
6479 case Intrinsic::x86_pclmulqdq_256:
6480 case Intrinsic::x86_pclmulqdq_512:
6481 handlePclmulIntrinsic(
I);
6484 case Intrinsic::x86_avx_round_pd_256:
6485 case Intrinsic::x86_avx_round_ps_256:
6486 case Intrinsic::x86_sse41_round_pd:
6487 case Intrinsic::x86_sse41_round_ps:
6488 handleRoundPdPsIntrinsic(
I);
6491 case Intrinsic::x86_sse41_round_sd:
6492 case Intrinsic::x86_sse41_round_ss:
6493 handleUnarySdSsIntrinsic(
I);
6496 case Intrinsic::x86_sse2_max_sd:
6497 case Intrinsic::x86_sse_max_ss:
6498 case Intrinsic::x86_sse2_min_sd:
6499 case Intrinsic::x86_sse_min_ss:
6500 handleBinarySdSsIntrinsic(
I);
6503 case Intrinsic::x86_avx_vtestc_pd:
6504 case Intrinsic::x86_avx_vtestc_pd_256:
6505 case Intrinsic::x86_avx_vtestc_ps:
6506 case Intrinsic::x86_avx_vtestc_ps_256:
6507 case Intrinsic::x86_avx_vtestnzc_pd:
6508 case Intrinsic::x86_avx_vtestnzc_pd_256:
6509 case Intrinsic::x86_avx_vtestnzc_ps:
6510 case Intrinsic::x86_avx_vtestnzc_ps_256:
6511 case Intrinsic::x86_avx_vtestz_pd:
6512 case Intrinsic::x86_avx_vtestz_pd_256:
6513 case Intrinsic::x86_avx_vtestz_ps:
6514 case Intrinsic::x86_avx_vtestz_ps_256:
6515 case Intrinsic::x86_avx_ptestc_256:
6516 case Intrinsic::x86_avx_ptestnzc_256:
6517 case Intrinsic::x86_avx_ptestz_256:
6518 case Intrinsic::x86_sse41_ptestc:
6519 case Intrinsic::x86_sse41_ptestnzc:
6520 case Intrinsic::x86_sse41_ptestz:
6521 handleVtestIntrinsic(
I);
6525 case Intrinsic::x86_ssse3_phadd_w:
6526 case Intrinsic::x86_ssse3_phadd_w_128:
6527 case Intrinsic::x86_ssse3_phsub_w:
6528 case Intrinsic::x86_ssse3_phsub_w_128:
6529 handlePairwiseShadowOrIntrinsic(
I, 1,
6533 case Intrinsic::x86_avx2_phadd_w:
6534 case Intrinsic::x86_avx2_phsub_w:
6535 handlePairwiseShadowOrIntrinsic(
I, 2,
6540 case Intrinsic::x86_ssse3_phadd_d:
6541 case Intrinsic::x86_ssse3_phadd_d_128:
6542 case Intrinsic::x86_ssse3_phsub_d:
6543 case Intrinsic::x86_ssse3_phsub_d_128:
6544 handlePairwiseShadowOrIntrinsic(
I, 1,
6548 case Intrinsic::x86_avx2_phadd_d:
6549 case Intrinsic::x86_avx2_phsub_d:
6550 handlePairwiseShadowOrIntrinsic(
I, 2,
6555 case Intrinsic::x86_ssse3_phadd_sw:
6556 case Intrinsic::x86_ssse3_phadd_sw_128:
6557 case Intrinsic::x86_ssse3_phsub_sw:
6558 case Intrinsic::x86_ssse3_phsub_sw_128:
6559 handlePairwiseShadowOrIntrinsic(
I, 1,
6563 case Intrinsic::x86_avx2_phadd_sw:
6564 case Intrinsic::x86_avx2_phsub_sw:
6565 handlePairwiseShadowOrIntrinsic(
I, 2,
6570 case Intrinsic::x86_sse3_hadd_ps:
6571 case Intrinsic::x86_sse3_hadd_pd:
6572 case Intrinsic::x86_sse3_hsub_ps:
6573 case Intrinsic::x86_sse3_hsub_pd:
6574 handlePairwiseShadowOrIntrinsic(
I, 1);
6577 case Intrinsic::x86_avx_hadd_pd_256:
6578 case Intrinsic::x86_avx_hadd_ps_256:
6579 case Intrinsic::x86_avx_hsub_pd_256:
6580 case Intrinsic::x86_avx_hsub_ps_256:
6581 handlePairwiseShadowOrIntrinsic(
I, 2);
6584 case Intrinsic::x86_avx_maskstore_ps:
6585 case Intrinsic::x86_avx_maskstore_pd:
6586 case Intrinsic::x86_avx_maskstore_ps_256:
6587 case Intrinsic::x86_avx_maskstore_pd_256:
6588 case Intrinsic::x86_avx2_maskstore_d:
6589 case Intrinsic::x86_avx2_maskstore_q:
6590 case Intrinsic::x86_avx2_maskstore_d_256:
6591 case Intrinsic::x86_avx2_maskstore_q_256: {
6592 handleAVXMaskedStore(
I);
6596 case Intrinsic::x86_avx_maskload_ps:
6597 case Intrinsic::x86_avx_maskload_pd:
6598 case Intrinsic::x86_avx_maskload_ps_256:
6599 case Intrinsic::x86_avx_maskload_pd_256:
6600 case Intrinsic::x86_avx2_maskload_d:
6601 case Intrinsic::x86_avx2_maskload_q:
6602 case Intrinsic::x86_avx2_maskload_d_256:
6603 case Intrinsic::x86_avx2_maskload_q_256: {
6604 handleAVXMaskedLoad(
I);
6609 case Intrinsic::x86_avx512fp16_add_ph_512:
6610 case Intrinsic::x86_avx512fp16_sub_ph_512:
6611 case Intrinsic::x86_avx512fp16_mul_ph_512:
6612 case Intrinsic::x86_avx512fp16_div_ph_512:
6613 case Intrinsic::x86_avx512fp16_max_ph_512:
6614 case Intrinsic::x86_avx512fp16_min_ph_512:
6615 case Intrinsic::x86_avx512_min_ps_512:
6616 case Intrinsic::x86_avx512_min_pd_512:
6617 case Intrinsic::x86_avx512_max_ps_512:
6618 case Intrinsic::x86_avx512_max_pd_512: {
6623 [[maybe_unused]]
bool Success =
6624 maybeHandleSimpleNomemIntrinsic(
I, 1);
6629 case Intrinsic::x86_avx_vpermilvar_pd:
6630 case Intrinsic::x86_avx_vpermilvar_pd_256:
6631 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6632 case Intrinsic::x86_avx_vpermilvar_ps:
6633 case Intrinsic::x86_avx_vpermilvar_ps_256:
6634 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6635 handleAVXVpermilvar(
I);
6639 case Intrinsic::x86_avx512_vpermi2var_d_128:
6640 case Intrinsic::x86_avx512_vpermi2var_d_256:
6641 case Intrinsic::x86_avx512_vpermi2var_d_512:
6642 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6643 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6644 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6645 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6646 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6647 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6648 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6649 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6650 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6651 case Intrinsic::x86_avx512_vpermi2var_q_128:
6652 case Intrinsic::x86_avx512_vpermi2var_q_256:
6653 case Intrinsic::x86_avx512_vpermi2var_q_512:
6654 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6655 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6656 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6657 handleAVXVpermi2var(
I);
6671 case Intrinsic::x86_avx2_pshuf_b:
6672 case Intrinsic::x86_sse_pshuf_w:
6673 case Intrinsic::x86_ssse3_pshuf_b_128:
6674 case Intrinsic::x86_ssse3_pshuf_b:
6675 case Intrinsic::x86_avx512_pshuf_b_512:
6676 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6682 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6683 case Intrinsic::x86_avx512_mask_pmov_db_512:
6684 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6685 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6688 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6696 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6697 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6698 handleIntrinsicByApplyingToShadow(
I,
6699 Intrinsic::x86_avx512_mask_pmov_dw_512,
6704 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6705 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6706 handleIntrinsicByApplyingToShadow(
I,
6707 Intrinsic::x86_avx512_mask_pmov_db_512,
6712 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
6713 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
6714 handleIntrinsicByApplyingToShadow(
I,
6715 Intrinsic::x86_avx512_mask_pmov_qb_512,
6720 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
6721 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
6722 handleIntrinsicByApplyingToShadow(
I,
6723 Intrinsic::x86_avx512_mask_pmov_qw_512,
6728 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
6729 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
6730 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
6731 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
6735 handleAVX512VectorDownConvert(
I);
6775 case Intrinsic::x86_avx512_rsqrt14_ps_512:
6776 case Intrinsic::x86_avx512_rsqrt14_ps_256:
6777 case Intrinsic::x86_avx512_rsqrt14_ps_128:
6778 case Intrinsic::x86_avx512_rsqrt14_pd_512:
6779 case Intrinsic::x86_avx512_rsqrt14_pd_256:
6780 case Intrinsic::x86_avx512_rsqrt14_pd_128:
6781 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
6782 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
6783 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
6784 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
6785 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
6786 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
6787 handleAVX512VectorGenericMaskedFP(
I, {0},
6828 case Intrinsic::x86_avx512_rcp14_ps_512:
6829 case Intrinsic::x86_avx512_rcp14_ps_256:
6830 case Intrinsic::x86_avx512_rcp14_ps_128:
6831 case Intrinsic::x86_avx512_rcp14_pd_512:
6832 case Intrinsic::x86_avx512_rcp14_pd_256:
6833 case Intrinsic::x86_avx512_rcp14_pd_128:
6834 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
6835 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
6836 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
6837 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
6838 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
6839 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
6840 handleAVX512VectorGenericMaskedFP(
I, {0},
6885 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
6886 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
6887 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
6888 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
6889 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
6890 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
6891 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
6892 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
6893 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
6894 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
6895 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
6896 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
6897 handleAVX512VectorGenericMaskedFP(
I, {0},
6933 case Intrinsic::x86_avx512_mask_scalef_pd_512:
6934 case Intrinsic::x86_avx512_mask_scalef_pd_256:
6935 case Intrinsic::x86_avx512_mask_scalef_pd_128:
6936 case Intrinsic::x86_avx512_mask_scalef_ps_512:
6937 case Intrinsic::x86_avx512_mask_scalef_ps_256:
6938 case Intrinsic::x86_avx512_mask_scalef_ps_128:
6939 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
6940 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
6941 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
6945 handleAVX512VectorGenericMaskedFP(
I, {0, 1},
6965 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
6966 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
6967 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
6968 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
6969 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
6970 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
6971 visitGenericScalarHalfwordInst(
I);
6976 case Intrinsic::x86_vgf2p8affineqb_128:
6977 case Intrinsic::x86_vgf2p8affineqb_256:
6978 case Intrinsic::x86_vgf2p8affineqb_512:
6979 handleAVXGF2P8Affine(
I);
6989 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &
I) {
6990 switch (
I.getIntrinsicID()) {
6994 case Intrinsic::aarch64_neon_rshrn:
6995 case Intrinsic::aarch64_neon_sqrshl:
6996 case Intrinsic::aarch64_neon_sqrshrn:
6997 case Intrinsic::aarch64_neon_sqrshrun:
6998 case Intrinsic::aarch64_neon_sqshl:
6999 case Intrinsic::aarch64_neon_sqshlu:
7000 case Intrinsic::aarch64_neon_sqshrn:
7001 case Intrinsic::aarch64_neon_sqshrun:
7002 case Intrinsic::aarch64_neon_srshl:
7003 case Intrinsic::aarch64_neon_sshl:
7004 case Intrinsic::aarch64_neon_uqrshl:
7005 case Intrinsic::aarch64_neon_uqrshrn:
7006 case Intrinsic::aarch64_neon_uqshl:
7007 case Intrinsic::aarch64_neon_uqshrn:
7008 case Intrinsic::aarch64_neon_urshl:
7009 case Intrinsic::aarch64_neon_ushl:
7010 handleVectorShiftIntrinsic(
I,
false);
7023 case Intrinsic::aarch64_neon_vsli:
7024 case Intrinsic::aarch64_neon_vsri:
7025 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7031 case Intrinsic::aarch64_neon_fmaxp:
7032 case Intrinsic::aarch64_neon_fminp:
7034 case Intrinsic::aarch64_neon_fmaxnmp:
7035 case Intrinsic::aarch64_neon_fminnmp:
7037 case Intrinsic::aarch64_neon_smaxp:
7038 case Intrinsic::aarch64_neon_sminp:
7039 case Intrinsic::aarch64_neon_umaxp:
7040 case Intrinsic::aarch64_neon_uminp:
7042 case Intrinsic::aarch64_neon_addp:
7044 case Intrinsic::aarch64_neon_faddp:
7046 case Intrinsic::aarch64_neon_saddlp:
7047 case Intrinsic::aarch64_neon_uaddlp: {
7048 handlePairwiseShadowOrIntrinsic(
I, 1);
7053 case Intrinsic::aarch64_neon_fcvtas:
7054 case Intrinsic::aarch64_neon_fcvtau:
7056 case Intrinsic::aarch64_neon_fcvtms:
7057 case Intrinsic::aarch64_neon_fcvtmu:
7059 case Intrinsic::aarch64_neon_fcvtns:
7060 case Intrinsic::aarch64_neon_fcvtnu:
7062 case Intrinsic::aarch64_neon_fcvtps:
7063 case Intrinsic::aarch64_neon_fcvtpu:
7065 case Intrinsic::aarch64_neon_fcvtzs:
7066 case Intrinsic::aarch64_neon_fcvtzu:
7068 case Intrinsic::aarch64_neon_fcvtxn:
7070 case Intrinsic::aarch64_neon_vcvthf2fp:
7071 case Intrinsic::aarch64_neon_vcvtfp2hf:
7072 handleNEONVectorConvertIntrinsic(
I,
false);
7076 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7077 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7078 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7079 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7080 handleNEONVectorConvertIntrinsic(
I,
true);
7089 case Intrinsic::aarch64_neon_faddv:
7090 case Intrinsic::aarch64_neon_saddv:
7091 case Intrinsic::aarch64_neon_uaddv:
7094 case Intrinsic::aarch64_neon_smaxv:
7095 case Intrinsic::aarch64_neon_sminv:
7096 case Intrinsic::aarch64_neon_umaxv:
7097 case Intrinsic::aarch64_neon_uminv:
7101 case Intrinsic::aarch64_neon_fmaxv:
7102 case Intrinsic::aarch64_neon_fminv:
7103 case Intrinsic::aarch64_neon_fmaxnmv:
7104 case Intrinsic::aarch64_neon_fminnmv:
7106 case Intrinsic::aarch64_neon_saddlv:
7107 case Intrinsic::aarch64_neon_uaddlv:
7108 handleVectorReduceIntrinsic(
I,
true);
7111 case Intrinsic::aarch64_neon_ld1x2:
7112 case Intrinsic::aarch64_neon_ld1x3:
7113 case Intrinsic::aarch64_neon_ld1x4:
7114 case Intrinsic::aarch64_neon_ld2:
7115 case Intrinsic::aarch64_neon_ld3:
7116 case Intrinsic::aarch64_neon_ld4:
7117 case Intrinsic::aarch64_neon_ld2r:
7118 case Intrinsic::aarch64_neon_ld3r:
7119 case Intrinsic::aarch64_neon_ld4r: {
7120 handleNEONVectorLoad(
I,
false);
7124 case Intrinsic::aarch64_neon_ld2lane:
7125 case Intrinsic::aarch64_neon_ld3lane:
7126 case Intrinsic::aarch64_neon_ld4lane: {
7127 handleNEONVectorLoad(
I,
true);
7132 case Intrinsic::aarch64_neon_sqxtn:
7133 case Intrinsic::aarch64_neon_sqxtun:
7134 case Intrinsic::aarch64_neon_uqxtn:
7141 case Intrinsic::aarch64_neon_st1x2:
7142 case Intrinsic::aarch64_neon_st1x3:
7143 case Intrinsic::aarch64_neon_st1x4:
7144 case Intrinsic::aarch64_neon_st2:
7145 case Intrinsic::aarch64_neon_st3:
7146 case Intrinsic::aarch64_neon_st4: {
7147 handleNEONVectorStoreIntrinsic(
I,
false);
7151 case Intrinsic::aarch64_neon_st2lane:
7152 case Intrinsic::aarch64_neon_st3lane:
7153 case Intrinsic::aarch64_neon_st4lane: {
7154 handleNEONVectorStoreIntrinsic(
I,
true);
7167 case Intrinsic::aarch64_neon_tbl1:
7168 case Intrinsic::aarch64_neon_tbl2:
7169 case Intrinsic::aarch64_neon_tbl3:
7170 case Intrinsic::aarch64_neon_tbl4:
7171 case Intrinsic::aarch64_neon_tbx1:
7172 case Intrinsic::aarch64_neon_tbx2:
7173 case Intrinsic::aarch64_neon_tbx3:
7174 case Intrinsic::aarch64_neon_tbx4: {
7176 handleIntrinsicByApplyingToShadow(
7177 I,
I.getIntrinsicID(),
7182 case Intrinsic::aarch64_neon_fmulx:
7183 case Intrinsic::aarch64_neon_pmul:
7184 case Intrinsic::aarch64_neon_pmull:
7185 case Intrinsic::aarch64_neon_smull:
7186 case Intrinsic::aarch64_neon_pmull64:
7187 case Intrinsic::aarch64_neon_umull: {
7188 handleNEONVectorMultiplyIntrinsic(
I);
7192 case Intrinsic::aarch64_neon_smmla:
7193 case Intrinsic::aarch64_neon_ummla:
7194 case Intrinsic::aarch64_neon_usmmla:
7195 case Intrinsic::aarch64_neon_bfmmla:
7196 handleNEONMatrixMultiply(
I);
7203 case Intrinsic::aarch64_neon_sdot:
7204 case Intrinsic::aarch64_neon_udot:
7205 case Intrinsic::aarch64_neon_usdot:
7206 handleVectorDotProductIntrinsic(
I, 4,
7216 case Intrinsic::aarch64_neon_bfdot:
7217 handleVectorDotProductIntrinsic(
I, 2,
7224 case Intrinsic::aarch64_neon_facge:
7225 case Intrinsic::aarch64_neon_facgt:
7226 handleVectorComparePackedIntrinsic(
I,
false);
7236 void visitIntrinsicInst(IntrinsicInst &
I) {
7237 if (maybeHandleCrossPlatformIntrinsic(
I))
7240 if (maybeHandleX86SIMDIntrinsic(
I))
7243 if (maybeHandleArmSIMDIntrinsic(
I))
7246 if (maybeHandleUnknownIntrinsic(
I))
7249 visitInstruction(
I);
7252 void visitLibAtomicLoad(CallBase &CB) {
7263 Value *NewOrdering =
7267 NextNodeIRBuilder NextIRB(&CB);
7268 Value *SrcShadowPtr, *SrcOriginPtr;
7269 std::tie(SrcShadowPtr, SrcOriginPtr) =
7270 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7272 Value *DstShadowPtr =
7273 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7277 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
7278 if (MS.TrackOrigins) {
7279 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7281 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7282 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7286 void visitLibAtomicStore(CallBase &CB) {
7293 Value *NewOrdering =
7297 Value *DstShadowPtr =
7307 void visitCallBase(CallBase &CB) {
7315 visitAsmInstruction(CB);
7317 visitInstruction(CB);
7326 case LibFunc_atomic_load:
7328 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
7332 visitLibAtomicLoad(CB);
7334 case LibFunc_atomic_store:
7335 visitLibAtomicStore(CB);
7351 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7355 Func->removeFnAttrs(
B);
7361 bool MayCheckCall = MS.EagerChecks;
7365 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
7368 unsigned ArgOffset = 0;
7371 if (!
A->getType()->isSized()) {
7372 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
7376 if (
A->getType()->isScalableTy()) {
7377 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
7379 insertCheckShadowOf(
A, &CB);
7384 const DataLayout &
DL =
F.getDataLayout();
7388 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7391 insertCheckShadowOf(
A, &CB);
7392 Size =
DL.getTypeAllocSize(
A->getType());
7398 Value *ArgShadow = getShadow(
A);
7399 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7401 <<
" Shadow: " << *ArgShadow <<
"\n");
7405 assert(
A->getType()->isPointerTy() &&
7406 "ByVal argument is not a pointer!");
7411 MaybeAlign Alignment = std::nullopt;
7414 Value *AShadowPtr, *AOriginPtr;
7415 std::tie(AShadowPtr, AOriginPtr) =
7416 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
7418 if (!PropagateShadow) {
7425 if (MS.TrackOrigins) {
7426 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7440 Size =
DL.getTypeAllocSize(
A->getType());
7446 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
7448 getOriginPtrForArgument(IRB, ArgOffset));
7451 assert(Store !=
nullptr);
7460 if (FT->isVarArg()) {
7461 VAHelper->visitCallBase(CB, IRB);
7471 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
7472 setShadow(&CB, getCleanShadow(&CB));
7473 setOrigin(&CB, getCleanOrigin());
7479 Value *
Base = getShadowPtrForRetval(IRBBefore);
7480 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
7492 setShadow(&CB, getCleanShadow(&CB));
7493 setOrigin(&CB, getCleanOrigin());
7500 "Could not find insertion point for retval shadow load");
7503 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7506 setShadow(&CB, RetvalShadow);
7507 if (MS.TrackOrigins)
7508 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7513 RetVal =
I->getOperand(0);
7516 return I->isMustTailCall();
7521 void visitReturnInst(ReturnInst &
I) {
7523 Value *RetVal =
I.getReturnValue();
7529 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7530 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
7531 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7534 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
7536 Value *Shadow = getShadow(RetVal);
7537 bool StoreOrigin =
true;
7539 insertCheckShadowOf(RetVal, &
I);
7540 Shadow = getCleanShadow(RetVal);
7541 StoreOrigin =
false;
7548 if (MS.TrackOrigins && StoreOrigin)
7549 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7553 void visitPHINode(PHINode &
I) {
7555 if (!PropagateShadow) {
7556 setShadow(&
I, getCleanShadow(&
I));
7557 setOrigin(&
I, getCleanOrigin());
7561 ShadowPHINodes.push_back(&
I);
7562 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
7564 if (MS.TrackOrigins)
7566 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
7569 Value *getLocalVarIdptr(AllocaInst &
I) {
7570 ConstantInt *IntConst =
7571 ConstantInt::get(Type::getInt32Ty((*
F.getParent()).getContext()), 0);
7572 return new GlobalVariable(*
F.getParent(), IntConst->
getType(),
7577 Value *getLocalVarDescription(AllocaInst &
I) {
7583 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7585 Value *ShadowBase, *OriginBase;
7586 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7590 IRB.
CreateMemSet(ShadowBase, PoisonValue, Len,
I.getAlign());
7593 if (PoisonStack && MS.TrackOrigins) {
7594 Value *Idptr = getLocalVarIdptr(
I);
7596 Value *Descr = getLocalVarDescription(
I);
7597 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
7598 {&I, Len, Idptr, Descr});
7600 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
7606 Value *Descr = getLocalVarDescription(
I);
7608 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
7610 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
7614 void instrumentAlloca(AllocaInst &
I, Instruction *InsPoint =
nullptr) {
7617 NextNodeIRBuilder IRB(InsPoint);
7620 if (MS.CompileKernel)
7621 poisonAllocaKmsan(
I, IRB, Len);
7623 poisonAllocaUserspace(
I, IRB, Len);
7626 void visitAllocaInst(AllocaInst &
I) {
7627 setShadow(&
I, getCleanShadow(&
I));
7628 setOrigin(&
I, getCleanOrigin());
7634 void visitSelectInst(SelectInst &
I) {
7640 handleSelectLikeInst(
I,
B,
C,
D);
7646 Value *Sb = getShadow(
B);
7647 Value *Sc = getShadow(
C);
7648 Value *Sd = getShadow(
D);
7650 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
7651 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
7652 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
7657 if (
I.getType()->isAggregateType()) {
7661 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
7662 }
else if (isScalableNonVectorType(
I.getType())) {
7670 Sa1 = getCleanShadow(getShadowTy(
I.getType()));
7678 C = CreateAppToShadowCast(IRB,
C);
7679 D = CreateAppToShadowCast(IRB,
D);
7686 if (MS.TrackOrigins) {
7689 if (
B->getType()->isVectorTy()) {
7690 B = convertToBool(
B, IRB);
7691 Sb = convertToBool(Sb, IRB);
7699 void visitLandingPadInst(LandingPadInst &
I) {
7702 setShadow(&
I, getCleanShadow(&
I));
7703 setOrigin(&
I, getCleanOrigin());
7706 void visitCatchSwitchInst(CatchSwitchInst &
I) {
7707 setShadow(&
I, getCleanShadow(&
I));
7708 setOrigin(&
I, getCleanOrigin());
7711 void visitFuncletPadInst(FuncletPadInst &
I) {
7712 setShadow(&
I, getCleanShadow(&
I));
7713 setOrigin(&
I, getCleanOrigin());
7716 void visitGetElementPtrInst(GetElementPtrInst &
I) { handleShadowOr(
I); }
7718 void visitExtractValueInst(ExtractValueInst &
I) {
7720 Value *Agg =
I.getAggregateOperand();
7722 Value *AggShadow = getShadow(Agg);
7726 setShadow(&
I, ResShadow);
7727 setOriginForNaryOp(
I);
7730 void visitInsertValueInst(InsertValueInst &
I) {
7733 Value *AggShadow = getShadow(
I.getAggregateOperand());
7734 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
7740 setOriginForNaryOp(
I);
7743 void dumpInst(Instruction &
I,
const Twine &Prefix) {
7752 errs() <<
"ZZZ:" <<
Prefix <<
" " <<
I.getOpcodeName() <<
"\n";
7759 unsigned NumOperands =
I.getNumOperands();
7761 errs() <<
"YYY:" <<
Prefix <<
" call " << *
I.getType() <<
" @";
7773 errs() <<
"YYY:" <<
Prefix <<
" " << *
I.getType() <<
" "
7774 <<
I.getOpcodeName() <<
"(";
7776 for (
size_t i = 0; i < NumOperands; i++) {
7794 void visitResumeInst(ResumeInst &
I) {
7799 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
7804 void visitCatchReturnInst(CatchReturnInst &CRI) {
7809 void instrumentAsmArgument(
Value *Operand,
Type *ElemTy, Instruction &
I,
7818 insertCheckShadowOf(Operand, &
I);
7825 auto Size =
DL.getTypeStoreSize(ElemTy);
7827 if (MS.CompileKernel) {
7828 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
7834 auto [ShadowPtr,
_] =
7835 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
7845 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
7846 int NumRetOutputs = 0;
7853 NumRetOutputs =
ST->getNumElements();
7858 for (
const InlineAsm::ConstraintInfo &Info : Constraints) {
7859 switch (
Info.Type) {
7867 return NumOutputs - NumRetOutputs;
7870 void visitAsmInstruction(Instruction &
I) {
7886 const DataLayout &
DL =
F.getDataLayout();
7890 int OutputArgs = getNumOutputArgs(IA, CB);
7896 for (
int i = OutputArgs; i < NumOperands; i++) {
7904 for (
int i = 0; i < OutputArgs; i++) {
7910 setShadow(&
I, getCleanShadow(&
I));
7911 setOrigin(&
I, getCleanOrigin());
7914 void visitFreezeInst(FreezeInst &
I) {
7916 setShadow(&
I, getCleanShadow(&
I));
7917 setOrigin(&
I, getCleanOrigin());
7920 void visitInstruction(Instruction &
I) {
7923 dumpInst(
I,
"Strict");
7925 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
7926 Value *Operand =
I.getOperand(i);
7928 insertCheckShadowOf(Operand, &
I);
7930 setShadow(&
I, getCleanShadow(&
I));
7931 setOrigin(&
I, getCleanOrigin());
7935struct VarArgHelperBase :
public VarArgHelper {
7937 MemorySanitizer &MS;
7938 MemorySanitizerVisitor &MSV;
7940 const unsigned VAListTagSize;
7942 VarArgHelperBase(Function &
F, MemorySanitizer &MS,
7943 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
7944 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
7948 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
7954 MS.VAArgTLS, ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg_va_s");
7963 return getShadowPtrForVAArgument(IRB, ArgOffset);
7972 ConstantInt::get(MS.IntptrTy, ArgOffset),
7977 unsigned BaseOffset) {
7986 TailSize,
Align(8));
7989 void unpoisonVAListTagForInst(IntrinsicInst &
I) {
7991 Value *VAListTag =
I.getArgOperand(0);
7993 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
7994 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
7997 VAListTagSize, Alignment,
false);
8000 void visitVAStartInst(VAStartInst &
I)
override {
8001 if (
F.getCallingConv() == CallingConv::Win64)
8004 unpoisonVAListTagForInst(
I);
8007 void visitVACopyInst(VACopyInst &
I)
override {
8008 if (
F.getCallingConv() == CallingConv::Win64)
8010 unpoisonVAListTagForInst(
I);
8015struct VarArgAMD64Helper :
public VarArgHelperBase {
8018 static const unsigned AMD64GpEndOffset = 48;
8019 static const unsigned AMD64FpEndOffsetSSE = 176;
8021 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8023 unsigned AMD64FpEndOffset;
8024 AllocaInst *VAArgTLSCopy =
nullptr;
8025 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8026 Value *VAArgOverflowSize =
nullptr;
8028 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8030 VarArgAMD64Helper(Function &
F, MemorySanitizer &MS,
8031 MemorySanitizerVisitor &MSV)
8032 : VarArgHelperBase(
F, MS, MSV, 24) {
8033 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8034 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
8035 if (Attr.isStringAttribute() &&
8036 (Attr.getKindAsString() ==
"target-features")) {
8037 if (Attr.getValueAsString().contains(
"-sse"))
8038 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8044 ArgKind classifyArgument(
Value *arg) {
8047 if (
T->isX86_FP80Ty())
8049 if (
T->isFPOrFPVectorTy())
8050 return AK_FloatingPoint;
8051 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
8052 return AK_GeneralPurpose;
8053 if (
T->isPointerTy())
8054 return AK_GeneralPurpose;
8066 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8067 unsigned GpOffset = 0;
8068 unsigned FpOffset = AMD64GpEndOffset;
8069 unsigned OverflowOffset = AMD64FpEndOffset;
8070 const DataLayout &
DL =
F.getDataLayout();
8074 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
8081 assert(
A->getType()->isPointerTy());
8083 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8084 uint64_t AlignedSize =
alignTo(ArgSize, 8);
8085 unsigned BaseOffset = OverflowOffset;
8086 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8087 Value *OriginBase =
nullptr;
8088 if (MS.TrackOrigins)
8089 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8090 OverflowOffset += AlignedSize;
8093 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8097 Value *ShadowPtr, *OriginPtr;
8098 std::tie(ShadowPtr, OriginPtr) =
8103 if (MS.TrackOrigins)
8107 ArgKind AK = classifyArgument(
A);
8108 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8110 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8112 Value *ShadowBase, *OriginBase =
nullptr;
8114 case AK_GeneralPurpose:
8115 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8116 if (MS.TrackOrigins)
8117 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8121 case AK_FloatingPoint:
8122 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8123 if (MS.TrackOrigins)
8124 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8131 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8132 uint64_t AlignedSize =
alignTo(ArgSize, 8);
8133 unsigned BaseOffset = OverflowOffset;
8134 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8135 if (MS.TrackOrigins) {
8136 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8138 OverflowOffset += AlignedSize;
8141 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8150 Value *Shadow = MSV.getShadow(
A);
8152 if (MS.TrackOrigins) {
8153 Value *Origin = MSV.getOrigin(
A);
8154 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8155 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8161 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8162 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8165 void finalizeInstrumentation()
override {
8166 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8167 "finalizeInstrumentation called twice");
8168 if (!VAStartInstrumentationList.
empty()) {
8175 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8176 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8182 Intrinsic::umin, CopySize,
8186 if (MS.TrackOrigins) {
8187 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8196 for (CallInst *OrigInst : VAStartInstrumentationList) {
8197 NextNodeIRBuilder IRB(OrigInst);
8198 Value *VAListTag = OrigInst->getArgOperand(0);
8200 Value *RegSaveAreaPtrPtr =
8201 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 16));
8203 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8205 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8206 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8208 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8210 if (MS.TrackOrigins)
8211 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8212 Alignment, AMD64FpEndOffset);
8213 Value *OverflowArgAreaPtrPtr =
8214 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 8));
8215 Value *OverflowArgAreaPtr =
8216 IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8217 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8218 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8219 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8223 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8225 if (MS.TrackOrigins) {
8228 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8236struct VarArgAArch64Helper :
public VarArgHelperBase {
8237 static const unsigned kAArch64GrArgSize = 64;
8238 static const unsigned kAArch64VrArgSize = 128;
8240 static const unsigned AArch64GrBegOffset = 0;
8241 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8243 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8244 static const unsigned AArch64VrEndOffset =
8245 AArch64VrBegOffset + kAArch64VrArgSize;
8246 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8248 AllocaInst *VAArgTLSCopy =
nullptr;
8249 Value *VAArgOverflowSize =
nullptr;
8251 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8253 VarArgAArch64Helper(Function &
F, MemorySanitizer &MS,
8254 MemorySanitizerVisitor &MSV)
8255 : VarArgHelperBase(
F, MS, MSV, 32) {}
8258 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
8259 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
8260 return {AK_GeneralPurpose, 1};
8261 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
8262 return {AK_FloatingPoint, 1};
8264 if (
T->isArrayTy()) {
8265 auto R = classifyArgument(
T->getArrayElementType());
8266 R.second *=
T->getScalarType()->getArrayNumElements();
8271 auto R = classifyArgument(FV->getScalarType());
8272 R.second *= FV->getNumElements();
8277 return {AK_Memory, 0};
8289 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8290 unsigned GrOffset = AArch64GrBegOffset;
8291 unsigned VrOffset = AArch64VrBegOffset;
8292 unsigned OverflowOffset = AArch64VAEndOffset;
8294 const DataLayout &
DL =
F.getDataLayout();
8297 auto [AK, RegNum] = classifyArgument(
A->getType());
8298 if (AK == AK_GeneralPurpose &&
8299 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8301 if (AK == AK_FloatingPoint &&
8302 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8306 case AK_GeneralPurpose:
8307 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8308 GrOffset += 8 * RegNum;
8310 case AK_FloatingPoint:
8311 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8312 VrOffset += 16 * RegNum;
8319 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8320 uint64_t AlignedSize =
alignTo(ArgSize, 8);
8321 unsigned BaseOffset = OverflowOffset;
8322 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8323 OverflowOffset += AlignedSize;
8326 CleanUnusedTLS(IRB,
Base, BaseOffset);
8338 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8339 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8344 Value *SaveAreaPtrPtr =
8345 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8346 return IRB.
CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8351 Value *SaveAreaPtr =
8352 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8354 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
8357 void finalizeInstrumentation()
override {
8358 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8359 "finalizeInstrumentation called twice");
8360 if (!VAStartInstrumentationList.empty()) {
8367 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8368 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8374 Intrinsic::umin, CopySize,
8380 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8381 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8385 for (CallInst *OrigInst : VAStartInstrumentationList) {
8386 NextNodeIRBuilder IRB(OrigInst);
8388 Value *VAListTag = OrigInst->getArgOperand(0);
8405 Value *StackSaveAreaPtr =
8406 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8409 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8410 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8413 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8416 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8417 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8420 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8426 Value *GrRegSaveAreaShadowPtrOff =
8427 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
8429 Value *GrRegSaveAreaShadowPtr =
8430 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8436 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8442 Value *VrRegSaveAreaShadowPtrOff =
8443 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
8445 Value *VrRegSaveAreaShadowPtr =
8446 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8453 VrRegSaveAreaShadowPtrOff);
8454 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8460 Value *StackSaveAreaShadowPtr =
8461 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8466 VAArgTLSCopy, IRB.
getInt32(AArch64VAEndOffset));
8469 Align(16), VAArgOverflowSize);
8475struct VarArgPowerPC64Helper :
public VarArgHelperBase {
8476 AllocaInst *VAArgTLSCopy =
nullptr;
8477 Value *VAArgSize =
nullptr;
8479 VarArgPowerPC64Helper(Function &
F, MemorySanitizer &MS,
8480 MemorySanitizerVisitor &MSV)
8481 : VarArgHelperBase(
F, MS, MSV, 8) {}
8483 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8491 Triple TargetTriple(
F.getParent()->getTargetTriple());
8495 if (TargetTriple.isPPC64ELFv2ABI())
8499 unsigned VAArgOffset = VAArgBase;
8500 const DataLayout &
DL =
F.getDataLayout();
8503 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
8505 assert(
A->getType()->isPointerTy());
8507 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8510 ArgAlign =
Align(8);
8511 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8514 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8516 Value *AShadowPtr, *AOriginPtr;
8517 std::tie(AShadowPtr, AOriginPtr) =
8518 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8528 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8530 if (
A->getType()->isArrayTy()) {
8533 Type *ElementTy =
A->getType()->getArrayElementType();
8535 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8536 }
else if (
A->getType()->isVectorTy()) {
8538 ArgAlign =
Align(ArgSize);
8541 ArgAlign =
Align(8);
8542 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8543 if (
DL.isBigEndian()) {
8547 VAArgOffset += (8 - ArgSize);
8551 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8555 VAArgOffset += ArgSize;
8559 VAArgBase = VAArgOffset;
8563 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8566 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8569 void finalizeInstrumentation()
override {
8570 assert(!VAArgSize && !VAArgTLSCopy &&
8571 "finalizeInstrumentation called twice");
8574 Value *CopySize = VAArgSize;
8576 if (!VAStartInstrumentationList.empty()) {
8580 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8586 Intrinsic::umin, CopySize,
8594 for (CallInst *OrigInst : VAStartInstrumentationList) {
8595 NextNodeIRBuilder IRB(OrigInst);
8596 Value *VAListTag = OrigInst->getArgOperand(0);
8599 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8602 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8603 const DataLayout &
DL =
F.getDataLayout();
8604 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8606 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8607 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8609 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8616struct VarArgPowerPC32Helper :
public VarArgHelperBase {
8617 AllocaInst *VAArgTLSCopy =
nullptr;
8618 Value *VAArgSize =
nullptr;
8620 VarArgPowerPC32Helper(Function &
F, MemorySanitizer &MS,
8621 MemorySanitizerVisitor &MSV)
8622 : VarArgHelperBase(
F, MS, MSV, 12) {}
8624 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8628 unsigned VAArgOffset = VAArgBase;
8629 const DataLayout &
DL =
F.getDataLayout();
8630 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8633 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
8635 assert(
A->getType()->isPointerTy());
8637 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8639 if (ArgAlign < IntptrSize)
8640 ArgAlign =
Align(IntptrSize);
8641 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8644 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8646 Value *AShadowPtr, *AOriginPtr;
8647 std::tie(AShadowPtr, AOriginPtr) =
8648 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8658 Type *ArgTy =
A->getType();
8664 uint64_t ArgSize =
DL.getTypeAllocSize(ArgTy);
8671 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8674 ArgAlign =
Align(ArgSize);
8676 if (ArgAlign < IntptrSize)
8677 ArgAlign =
Align(IntptrSize);
8678 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8679 if (
DL.isBigEndian()) {
8682 if (ArgSize < IntptrSize)
8683 VAArgOffset += (IntptrSize - ArgSize);
8686 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
8692 VAArgOffset += ArgSize;
8699 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8702 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8705 void finalizeInstrumentation()
override {
8706 assert(!VAArgSize && !VAArgTLSCopy &&
8707 "finalizeInstrumentation called twice");
8709 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
8710 Value *CopySize = VAArgSize;
8712 if (!VAStartInstrumentationList.empty()) {
8716 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8722 Intrinsic::umin, CopySize,
8730 for (CallInst *OrigInst : VAStartInstrumentationList) {
8731 NextNodeIRBuilder IRB(OrigInst);
8732 Value *VAListTag = OrigInst->getArgOperand(0);
8734 Value *RegSaveAreaSize = CopySize;
8738 IRB.
CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
8742 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
8744 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8747 const DataLayout &
DL =
F.getDataLayout();
8748 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8752 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8753 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8754 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8756 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
8757 Alignment, RegSaveAreaSize);
8759 RegSaveAreaShadowPtr =
8762 ConstantInt::get(MS.IntptrTy, 32));
8767 ConstantInt::get(MS.IntptrTy, 32), Alignment);
8772 Value *OverflowAreaSize = IRB.
CreateSub(CopySize, RegSaveAreaSize);
8775 OverflowAreaPtrPtr =
8776 IRB.
CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
8777 OverflowAreaPtrPtr = IRB.
CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
8779 Value *OverflowAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
8781 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
8782 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
8783 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.
getInt8Ty(),
8786 Value *OverflowVAArgTLSCopyPtr =
8788 OverflowVAArgTLSCopyPtr =
8789 IRB.
CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
8791 OverflowVAArgTLSCopyPtr =
8794 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
8801struct VarArgSystemZHelper :
public VarArgHelperBase {
8802 static const unsigned SystemZGpOffset = 16;
8803 static const unsigned SystemZGpEndOffset = 56;
8804 static const unsigned SystemZFpOffset = 128;
8805 static const unsigned SystemZFpEndOffset = 160;
8806 static const unsigned SystemZMaxVrArgs = 8;
8807 static const unsigned SystemZRegSaveAreaSize = 160;
8808 static const unsigned SystemZOverflowOffset = 160;
8809 static const unsigned SystemZVAListTagSize = 32;
8810 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
8811 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
8813 bool IsSoftFloatABI;
8814 AllocaInst *VAArgTLSCopy =
nullptr;
8815 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8816 Value *VAArgOverflowSize =
nullptr;
8818 enum class ArgKind {
8826 enum class ShadowExtension {
None,
Zero, Sign };
8828 VarArgSystemZHelper(Function &
F, MemorySanitizer &MS,
8829 MemorySanitizerVisitor &MSV)
8830 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
8831 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
8833 ArgKind classifyArgument(
Type *
T) {
8840 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
8841 return ArgKind::Indirect;
8842 if (
T->isFloatingPointTy())
8843 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
8844 if (
T->isIntegerTy() ||
T->isPointerTy())
8845 return ArgKind::GeneralPurpose;
8846 if (
T->isVectorTy())
8847 return ArgKind::Vector;
8848 return ArgKind::Memory;
8851 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
8861 return ShadowExtension::Zero;
8865 return ShadowExtension::Sign;
8867 return ShadowExtension::None;
8870 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8871 unsigned GpOffset = SystemZGpOffset;
8872 unsigned FpOffset = SystemZFpOffset;
8873 unsigned VrIndex = 0;
8874 unsigned OverflowOffset = SystemZOverflowOffset;
8875 const DataLayout &
DL =
F.getDataLayout();
8881 ArgKind AK = classifyArgument(
T);
8882 if (AK == ArgKind::Indirect) {
8884 AK = ArgKind::GeneralPurpose;
8886 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
8887 AK = ArgKind::Memory;
8888 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
8889 AK = ArgKind::Memory;
8890 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
8891 AK = ArgKind::Memory;
8892 Value *ShadowBase =
nullptr;
8893 Value *OriginBase =
nullptr;
8894 ShadowExtension SE = ShadowExtension::None;
8896 case ArgKind::GeneralPurpose: {
8898 uint64_t ArgSize = 8;
8901 SE = getShadowExtension(CB, ArgNo);
8902 uint64_t GapSize = 0;
8903 if (SE == ShadowExtension::None) {
8904 uint64_t ArgAllocSize =
DL.getTypeAllocSize(
T);
8905 assert(ArgAllocSize <= ArgSize);
8906 GapSize = ArgSize - ArgAllocSize;
8908 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
8909 if (MS.TrackOrigins)
8910 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
8912 GpOffset += ArgSize;
8918 case ArgKind::FloatingPoint: {
8920 uint64_t ArgSize = 8;
8927 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
8928 if (MS.TrackOrigins)
8929 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8931 FpOffset += ArgSize;
8937 case ArgKind::Vector: {
8944 case ArgKind::Memory: {
8949 uint64_t ArgAllocSize =
DL.getTypeAllocSize(
T);
8950 uint64_t ArgSize =
alignTo(ArgAllocSize, 8);
8952 SE = getShadowExtension(CB, ArgNo);
8954 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
8956 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
8957 if (MS.TrackOrigins)
8959 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
8960 OverflowOffset += ArgSize;
8967 case ArgKind::Indirect:
8970 if (ShadowBase ==
nullptr)
8972 Value *Shadow = MSV.getShadow(
A);
8973 if (SE != ShadowExtension::None)
8974 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
8975 SE == ShadowExtension::Sign);
8976 ShadowBase = IRB.
CreateIntToPtr(ShadowBase, MS.PtrTy,
"_msarg_va_s");
8978 if (MS.TrackOrigins) {
8979 Value *Origin = MSV.getOrigin(
A);
8980 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8981 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8985 Constant *OverflowSize = ConstantInt::get(
8986 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
8987 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8994 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
8997 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8999 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9000 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
9005 unsigned RegSaveAreaSize =
9006 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9007 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9009 if (MS.TrackOrigins)
9010 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9011 Alignment, RegSaveAreaSize);
9020 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9022 Value *OverflowArgAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9023 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9025 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9026 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
9029 SystemZOverflowOffset);
9030 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9032 if (MS.TrackOrigins) {
9034 SystemZOverflowOffset);
9035 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9040 void finalizeInstrumentation()
override {
9041 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9042 "finalizeInstrumentation called twice");
9043 if (!VAStartInstrumentationList.empty()) {
9050 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9052 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9058 Intrinsic::umin, CopySize,
9062 if (MS.TrackOrigins) {
9063 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9072 for (CallInst *OrigInst : VAStartInstrumentationList) {
9073 NextNodeIRBuilder IRB(OrigInst);
9074 Value *VAListTag = OrigInst->getArgOperand(0);
9075 copyRegSaveArea(IRB, VAListTag);
9076 copyOverflowArea(IRB, VAListTag);
9082struct VarArgI386Helper :
public VarArgHelperBase {
9083 AllocaInst *VAArgTLSCopy =
nullptr;
9084 Value *VAArgSize =
nullptr;
9086 VarArgI386Helper(Function &
F, MemorySanitizer &MS,
9087 MemorySanitizerVisitor &MSV)
9088 : VarArgHelperBase(
F, MS, MSV, 4) {}
9090 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9091 const DataLayout &
DL =
F.getDataLayout();
9092 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9093 unsigned VAArgOffset = 0;
9096 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
9098 assert(
A->getType()->isPointerTy());
9100 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9102 if (ArgAlign < IntptrSize)
9103 ArgAlign =
Align(IntptrSize);
9104 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9106 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9108 Value *AShadowPtr, *AOriginPtr;
9109 std::tie(AShadowPtr, AOriginPtr) =
9110 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9120 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9122 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9123 if (
DL.isBigEndian()) {
9126 if (ArgSize < IntptrSize)
9127 VAArgOffset += (IntptrSize - ArgSize);
9130 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9133 VAArgOffset += ArgSize;
9139 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9142 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9145 void finalizeInstrumentation()
override {
9146 assert(!VAArgSize && !VAArgTLSCopy &&
9147 "finalizeInstrumentation called twice");
9149 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9150 Value *CopySize = VAArgSize;
9152 if (!VAStartInstrumentationList.empty()) {
9155 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9161 Intrinsic::umin, CopySize,
9169 for (CallInst *OrigInst : VAStartInstrumentationList) {
9170 NextNodeIRBuilder IRB(OrigInst);
9171 Value *VAListTag = OrigInst->getArgOperand(0);
9172 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9173 Value *RegSaveAreaPtrPtr =
9175 PointerType::get(*MS.C, 0));
9176 Value *RegSaveAreaPtr =
9177 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9178 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9179 const DataLayout &
DL =
F.getDataLayout();
9180 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9182 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9183 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9185 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9193struct VarArgGenericHelper :
public VarArgHelperBase {
9194 AllocaInst *VAArgTLSCopy =
nullptr;
9195 Value *VAArgSize =
nullptr;
9197 VarArgGenericHelper(Function &
F, MemorySanitizer &MS,
9198 MemorySanitizerVisitor &MSV,
const unsigned VAListTagSize)
9199 : VarArgHelperBase(
F, MS, MSV, VAListTagSize) {}
9201 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9202 unsigned VAArgOffset = 0;
9203 const DataLayout &
DL =
F.getDataLayout();
9204 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9209 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9210 if (
DL.isBigEndian()) {
9213 if (ArgSize < IntptrSize)
9214 VAArgOffset += (IntptrSize - ArgSize);
9216 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9217 VAArgOffset += ArgSize;
9218 VAArgOffset =
alignTo(VAArgOffset, IntptrSize);
9224 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9227 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9230 void finalizeInstrumentation()
override {
9231 assert(!VAArgSize && !VAArgTLSCopy &&
9232 "finalizeInstrumentation called twice");
9234 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9235 Value *CopySize = VAArgSize;
9237 if (!VAStartInstrumentationList.empty()) {
9240 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9246 Intrinsic::umin, CopySize,
9254 for (CallInst *OrigInst : VAStartInstrumentationList) {
9255 NextNodeIRBuilder IRB(OrigInst);
9256 Value *VAListTag = OrigInst->getArgOperand(0);
9257 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9258 Value *RegSaveAreaPtrPtr =
9260 PointerType::get(*MS.C, 0));
9261 Value *RegSaveAreaPtr =
9262 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9263 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9264 const DataLayout &
DL =
F.getDataLayout();
9265 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9267 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9268 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9270 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9278using VarArgARM32Helper = VarArgGenericHelper;
9279using VarArgRISCVHelper = VarArgGenericHelper;
9280using VarArgMIPSHelper = VarArgGenericHelper;
9281using VarArgLoongArch64Helper = VarArgGenericHelper;
9282using VarArgHexagonHelper = VarArgGenericHelper;
9285struct VarArgNoOpHelper :
public VarArgHelper {
9286 VarArgNoOpHelper(Function &
F, MemorySanitizer &MS,
9287 MemorySanitizerVisitor &MSV) {}
9289 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {}
9291 void visitVAStartInst(VAStartInst &
I)
override {}
9293 void visitVACopyInst(VACopyInst &
I)
override {}
9295 void finalizeInstrumentation()
override {}
9301 MemorySanitizerVisitor &Visitor) {
9304 Triple TargetTriple(Func.getParent()->getTargetTriple());
9307 return new VarArgI386Helper(Func, Msan, Visitor);
9310 return new VarArgAMD64Helper(Func, Msan, Visitor);
9312 if (TargetTriple.
isARM())
9313 return new VarArgARM32Helper(Func, Msan, Visitor, 4);
9316 return new VarArgAArch64Helper(Func, Msan, Visitor);
9319 return new VarArgSystemZHelper(Func, Msan, Visitor);
9324 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9327 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9330 return new VarArgRISCVHelper(Func, Msan, Visitor, 4);
9333 return new VarArgRISCVHelper(Func, Msan, Visitor, 8);
9336 return new VarArgMIPSHelper(Func, Msan, Visitor, 4);
9339 return new VarArgMIPSHelper(Func, Msan, Visitor, 8);
9342 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9346 return new VarArgHexagonHelper(Func, Msan, Visitor, 12);
9348 return new VarArgNoOpHelper(Func, Msan, Visitor);
9355 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9358 MemorySanitizerVisitor Visitor(
F, *
this, TLI);
9365 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
static cl::opt< bool > ClWithComdat("asan-with-comdat", cl::desc("Place ASan constructors in comdat sections"), cl::Hidden, cl::init(true))
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< 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...
const MemoryMapParams Linux_LoongArch64_MemoryMapParams
const MemoryMapParams Linux_X86_64_MemoryMapParams
static cl::opt< int > ClTrackOrigins("dfsan-track-origins", cl::desc("Track origins of labels"), cl::Hidden, cl::init(0))
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.
Machine Check Debug Module
static const PlatformMemoryMapParams Linux_S390_MemoryMapParams
static const Align kMinOriginAlignment
static cl::opt< uint64_t > ClShadowBase("msan-shadow-base", cl::desc("Define custom MSan ShadowBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClPoisonUndef("msan-poison-undef", cl::desc("Poison fully undef temporary values. " "Partially undefined constant vectors " "are unaffected by this flag (see " "-msan-poison-undef-vectors)."), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_X86_MemoryMapParams
static cl::opt< uint64_t > ClOriginBase("msan-origin-base", cl::desc("Define custom MSan OriginBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClCheckConstantShadow("msan-check-constant-shadow", cl::desc("Insert checks for constant shadow values"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static const unsigned kOriginSize
static cl::opt< bool > ClWithComdat("msan-with-comdat", cl::desc("Place MSan constructors in comdat sections"), cl::Hidden, cl::init(false))
static cl::opt< int > ClTrackOrigins("msan-track-origins", cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden, cl::init(0))
Track origins of uninitialized values.
static cl::opt< int > ClInstrumentationWithCallThreshold("msan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented requires more than " "this number of checks and origin stores, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500))
static cl::opt< int > ClPoisonStackPattern("msan-poison-stack-pattern", cl::desc("poison uninitialized stack variables with the given pattern"), cl::Hidden, cl::init(0xff))
static const Align kShadowTLSAlignment
static cl::opt< bool > ClHandleICmpExact("msan-handle-icmp-exact", cl::desc("exact handling of relational integer ICmp"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static cl::opt< bool > ClDumpStrictInstructions("msan-dump-strict-instructions", cl::desc("print out instructions with default strict semantics i.e.," "check that all the inputs are fully initialized, and mark " "the output as fully initialized. These semantics are applied " "to instructions that could not be handled explicitly nor " "heuristically."), cl::Hidden, cl::init(false))
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static cl::opt< bool > ClPreciseDisjointOr("msan-precise-disjoint-or", cl::desc("Precisely poison disjoint OR. If false (legacy behavior), " "disjointedness is ignored (i.e., 1|1 is initialized)."), cl::Hidden, cl::init(false))
static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P
static cl::opt< bool > ClPoisonStack("msan-poison-stack", cl::desc("poison uninitialized stack variables"), cl::Hidden, cl::init(true))
static const MemoryMapParams Linux_I386_MemoryMapParams
const char kMsanInitName[]
static cl::opt< bool > ClPoisonUndefVectors("msan-poison-undef-vectors", cl::desc("Precisely poison partially undefined constant vectors. " "If false (legacy behavior), the entire vector is " "considered fully initialized, which may lead to false " "negatives. Fully undefined constant vectors are " "unaffected by this flag (see -msan-poison-undef)."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClPrintStackNames("msan-print-stack-names", cl::desc("Print name of local stack variable"), cl::Hidden, cl::init(true))
static cl::opt< uint64_t > ClAndMask("msan-and-mask", cl::desc("Define custom MSan AndMask"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClHandleLifetimeIntrinsics("msan-handle-lifetime-intrinsics", cl::desc("when possible, poison scoped variables at the beginning of the scope " "(slower, but more precise)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKeepGoing("msan-keep-going", cl::desc("keep going after reporting a UMR"), cl::Hidden, cl::init(false))
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 cl::opt< bool > ClEagerChecks("msan-eager-checks", cl::desc("check arguments and return values at function call boundaries"), cl::Hidden, cl::init(false))
static cl::opt< int > ClDisambiguateWarning("msan-disambiguate-warning-threshold", cl::desc("Define threshold for number of checks per " "debug location to force origin update."), cl::Hidden, cl::init(3))
static VarArgHelper * CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, MemorySanitizerVisitor &Visitor)
static const MemoryMapParams Linux_MIPS64_MemoryMapParams
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
static cl::opt< int > ClSwitchPrecision("msan-switch-precision", cl::desc("Controls the number of cases considered by MSan for LLVM switch " "instructions. 0 means no UUMs detected. Higher values lead to " "fewer false negatives but may impact compiler and/or " "application performance. N.B. LLVM switch instructions do not " "correspond exactly to C++ switch statements."), cl::Hidden, cl::init(99))
static cl::opt< uint64_t > ClXorMask("msan-xor-mask", cl::desc("Define custom MSan XorMask"), cl::Hidden, cl::init(0))
static const MemoryMapParams Linux_Hexagon_MemoryMapParams
static cl::opt< bool > ClHandleAsmConservative("msan-handle-asm-conservative", cl::desc("conservative handling of inline assembly"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams
static const unsigned kParamTLSSize
static cl::opt< bool > ClHandleICmp("msan-handle-icmp", cl::desc("propagate shadow through ICmpEQ and ICmpNE"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClEnableKmsan("msan-kernel", cl::desc("Enable KernelMemorySanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClPoisonStackWithCall("msan-poison-stack-with-call", cl::desc("poison uninitialized stack variables with a call"), cl::Hidden, cl::init(false))
static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
static cl::opt< bool > ClDumpHeuristicInstructions("msan-dump-heuristic-instructions", cl::desc("Prints 'unknown' instructions that were handled heuristically. " "Use -msan-dump-strict-instructions to print instructions that " "could not be handled explicitly nor heuristically."), cl::Hidden, cl::init(false))
static const unsigned kRetvalTLSSize
static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams
const char kMsanModuleCtorName[]
static const MemoryMapParams FreeBSD_I386_MemoryMapParams
static cl::opt< bool > ClCheckAccessAddress("msan-check-access-address", cl::desc("report accesses through a pointer which has poisoned shadow"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClDisableChecks("msan-disable-checks", cl::desc("Apply no_sanitize to the whole file"), cl::Hidden, cl::init(false))
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
front - 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.
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.
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...
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
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.
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.
LLVM_ABI CallInst * CreateAndReduce(Value *Src)
Create a vector int AND reduction intrinsic of the source vector.
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 CallInst * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
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 CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
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="")
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)
StringRef - 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
bool getLibFunc(StringRef funcName, LibFunc &F) 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.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
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.
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.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this 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.
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
int getNumOccurrences() 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.
@ C
The default llvm calling convention, compatible with C.
@ 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....
initializer< Ty > init(const Ty &Val)
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.
FunctionAddr VTableAddr Value
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.
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.
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.
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.
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
@ 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.
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 removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
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)
A CRTP mix-in to automatically provide informational APIs needed for passes.