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;
602class MemorySanitizer {
611 MemorySanitizer(MemorySanitizer &&) =
delete;
612 MemorySanitizer &operator=(MemorySanitizer &&) =
delete;
613 MemorySanitizer(
const MemorySanitizer &) =
delete;
614 MemorySanitizer &operator=(
const MemorySanitizer &) =
delete;
616 bool sanitizeFunction(Function &
F, TargetLibraryInfo &TLI);
619 friend struct MemorySanitizerVisitor;
620 friend struct VarArgHelperBase;
621 friend struct VarArgAMD64Helper;
622 friend struct VarArgAArch64Helper;
623 friend struct VarArgPowerPC64Helper;
624 friend struct VarArgPowerPC32Helper;
625 friend struct VarArgSystemZHelper;
626 friend struct VarArgI386Helper;
627 friend struct VarArgGenericHelper;
629 void initializeModule(
Module &M);
630 void initializeCallbacks(
Module &M,
const TargetLibraryInfo &TLI);
631 void createKernelApi(
Module &M,
const TargetLibraryInfo &TLI);
632 void createUserspaceApi(
Module &M,
const TargetLibraryInfo &TLI);
634 template <
typename... ArgsTy>
635 FunctionCallee getOrInsertMsanMetadataFunction(
Module &M, StringRef Name,
661 Value *ParamOriginTLS;
667 Value *RetvalOriginTLS;
673 Value *VAArgOriginTLS;
676 Value *VAArgOverflowSizeTLS;
679 bool CallbacksInitialized =
false;
682 FunctionCallee WarningFn;
686 FunctionCallee MaybeWarningVarSizeFn;
691 FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
693 FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
696 FunctionCallee MsanPoisonStackFn;
700 FunctionCallee MsanChainOriginFn;
703 FunctionCallee MsanSetOriginFn;
706 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
709 StructType *MsanContextStateTy;
710 FunctionCallee MsanGetContextStateFn;
713 FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
719 FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
720 FunctionCallee MsanMetadataPtrForLoad_1_8[4];
721 FunctionCallee MsanMetadataPtrForStore_1_8[4];
722 FunctionCallee MsanInstrumentAsmStoreFn;
725 Value *MsanMetadataAlloca;
728 FunctionCallee getKmsanShadowOriginAccessFn(
bool isStore,
int size);
731 const MemoryMapParams *MapParams;
735 MemoryMapParams CustomMapParams;
737 MDNode *ColdCallWeights;
740 MDNode *OriginStoreWeights;
743void insertModuleCtor(
Module &M) {
780 if (!Options.Kernel) {
789 MemorySanitizer Msan(*
F.getParent(), Options);
808 OS, MapClassName2PassName);
814 if (Options.EagerChecks)
815 OS <<
"eager-checks;";
816 OS <<
"track-origins=" << Options.TrackOrigins;
832template <
typename... ArgsTy>
834MemorySanitizer::getOrInsertMsanMetadataFunction(
Module &M,
StringRef Name,
839 std::forward<ArgsTy>(Args)...);
842 return M.getOrInsertFunction(Name, MsanMetadata,
843 std::forward<ArgsTy>(Args)...);
852 RetvalOriginTLS =
nullptr;
854 ParamOriginTLS =
nullptr;
856 VAArgOriginTLS =
nullptr;
857 VAArgOverflowSizeTLS =
nullptr;
859 WarningFn =
M.getOrInsertFunction(
"__msan_warning",
861 IRB.getVoidTy(), IRB.getInt32Ty());
872 MsanGetContextStateFn =
873 M.getOrInsertFunction(
"__msan_get_context_state", PtrTy);
877 for (
int ind = 0,
size = 1; ind < 4; ind++,
size <<= 1) {
878 std::string name_load =
879 "__msan_metadata_ptr_for_load_" + std::to_string(
size);
880 std::string name_store =
881 "__msan_metadata_ptr_for_store_" + std::to_string(
size);
882 MsanMetadataPtrForLoad_1_8[ind] =
883 getOrInsertMsanMetadataFunction(M, name_load, PtrTy);
884 MsanMetadataPtrForStore_1_8[ind] =
885 getOrInsertMsanMetadataFunction(M, name_store, PtrTy);
888 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
889 M,
"__msan_metadata_ptr_for_load_n", PtrTy, IntptrTy);
890 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
891 M,
"__msan_metadata_ptr_for_store_n", PtrTy, IntptrTy);
894 MsanPoisonAllocaFn =
M.getOrInsertFunction(
895 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
896 MsanUnpoisonAllocaFn =
M.getOrInsertFunction(
897 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
901 return M.getOrInsertGlobal(Name, Ty, [&] {
903 nullptr, Name,
nullptr,
909void MemorySanitizer::createUserspaceApi(
Module &M,
917 StringRef WarningFnName = Recover ?
"__msan_warning_with_origin"
918 :
"__msan_warning_with_origin_noreturn";
919 WarningFn =
M.getOrInsertFunction(WarningFnName,
921 IRB.getVoidTy(), IRB.getInt32Ty());
924 Recover ?
"__msan_warning" :
"__msan_warning_noreturn";
925 WarningFn =
M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
952 IRB.getIntPtrTy(
M.getDataLayout()));
956 unsigned AccessSize = 1 << AccessSizeIndex;
957 std::string FunctionName =
"__msan_maybe_warning_" +
itostr(AccessSize);
958 MaybeWarningFn[AccessSizeIndex] =
M.getOrInsertFunction(
960 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
961 MaybeWarningVarSizeFn =
M.getOrInsertFunction(
962 "__msan_maybe_warning_N", TLI.
getAttrList(
C, {},
false),
963 IRB.getVoidTy(), PtrTy, IRB.getInt64Ty(), IRB.getInt32Ty());
964 FunctionName =
"__msan_maybe_store_origin_" +
itostr(AccessSize);
965 MaybeStoreOriginFn[AccessSizeIndex] =
M.getOrInsertFunction(
967 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
971 MsanSetAllocaOriginWithDescriptionFn =
972 M.getOrInsertFunction(
"__msan_set_alloca_origin_with_descr",
973 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
974 MsanSetAllocaOriginNoDescriptionFn =
975 M.getOrInsertFunction(
"__msan_set_alloca_origin_no_descr",
976 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
977 MsanPoisonStackFn =
M.getOrInsertFunction(
"__msan_poison_stack",
978 IRB.getVoidTy(), PtrTy, IntptrTy);
982void MemorySanitizer::initializeCallbacks(
Module &M,
985 if (CallbacksInitialized)
991 MsanChainOriginFn =
M.getOrInsertFunction(
992 "__msan_chain_origin",
995 MsanSetOriginFn =
M.getOrInsertFunction(
997 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
999 M.getOrInsertFunction(
"__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
1001 M.getOrInsertFunction(
"__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
1002 MemsetFn =
M.getOrInsertFunction(
"__msan_memset",
1004 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
1006 MsanInstrumentAsmStoreFn =
M.getOrInsertFunction(
1007 "__msan_instrument_asm_store", IRB.getVoidTy(), PtrTy, IntptrTy);
1009 if (CompileKernel) {
1010 createKernelApi(M, TLI);
1012 createUserspaceApi(M, TLI);
1014 CallbacksInitialized =
true;
1020 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
1038void MemorySanitizer::initializeModule(
Module &M) {
1039 auto &
DL =
M.getDataLayout();
1041 TargetTriple =
M.getTargetTriple();
1043 bool ShadowPassed =
ClShadowBase.getNumOccurrences() > 0;
1044 bool OriginPassed =
ClOriginBase.getNumOccurrences() > 0;
1046 if (ShadowPassed || OriginPassed) {
1051 MapParams = &CustomMapParams;
1053 switch (TargetTriple.getOS()) {
1055 switch (TargetTriple.getArch()) {
1070 switch (TargetTriple.getArch()) {
1079 switch (TargetTriple.getArch()) {
1113 C = &(
M.getContext());
1115 IntptrTy = IRB.getIntPtrTy(
DL);
1116 OriginTy = IRB.getInt32Ty();
1117 PtrTy = IRB.getPtrTy();
1122 if (!CompileKernel) {
1124 M.getOrInsertGlobal(
"__msan_track_origins", IRB.getInt32Ty(), [&] {
1125 return new GlobalVariable(
1126 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
1127 IRB.getInt32(TrackOrigins),
"__msan_track_origins");
1131 M.getOrInsertGlobal(
"__msan_keep_going", IRB.getInt32Ty(), [&] {
1132 return new GlobalVariable(M, IRB.getInt32Ty(), true,
1133 GlobalValue::WeakODRLinkage,
1134 IRB.getInt32(Recover),
"__msan_keep_going");
1149struct VarArgHelper {
1150 virtual ~VarArgHelper() =
default;
1153 virtual void visitCallBase(CallBase &CB,
IRBuilder<> &IRB) = 0;
1156 virtual void visitVAStartInst(VAStartInst &
I) = 0;
1159 virtual void visitVACopyInst(VACopyInst &
I) = 0;
1165 virtual void finalizeInstrumentation() = 0;
1168struct MemorySanitizerVisitor;
1173 MemorySanitizerVisitor &Visitor);
1180 if (TypeSizeFixed <= 8)
1189class NextNodeIRBuilder :
public IRBuilder<> {
1202struct MemorySanitizerVisitor :
public InstVisitor<MemorySanitizerVisitor> {
1204 MemorySanitizer &MS;
1206 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1207 std::unique_ptr<VarArgHelper> VAHelper;
1208 const TargetLibraryInfo *TLI;
1215 bool PropagateShadow;
1218 bool PoisonUndefVectors;
1220 struct ShadowOriginAndInsertPoint {
1225 ShadowOriginAndInsertPoint(
Value *S,
Value *O, Instruction *
I)
1226 : Shadow(S), Origin(
O), OrigIns(
I) {}
1229 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1230 SmallSetVector<AllocaInst *, 16> AllocaSet;
1233 int64_t SplittableBlocksCount = 0;
1235 MemorySanitizerVisitor(Function &
F, MemorySanitizer &MS,
1236 const TargetLibraryInfo &TLI)
1238 bool SanitizeFunction =
1240 InsertChecks = SanitizeFunction;
1241 PropagateShadow = SanitizeFunction;
1252 MS.initializeCallbacks(*
F.getParent(), TLI);
1254 IRBuilder<>(&
F.getEntryBlock(),
F.getEntryBlock().getFirstNonPHIIt())
1255 .CreateIntrinsic(Intrinsic::donothing, {});
1257 if (MS.CompileKernel) {
1259 insertKmsanPrologue(IRB);
1263 <<
"MemorySanitizer is not inserting checks into '"
1264 <<
F.getName() <<
"'\n");
1267 bool instrumentWithCalls(
Value *V) {
1271 ++SplittableBlocksCount;
1276 bool isInPrologue(Instruction &
I) {
1277 return I.getParent() == FnPrologueEnd->
getParent() &&
1286 if (MS.TrackOrigins <= 1)
1288 return IRB.
CreateCall(MS.MsanChainOriginFn, V);
1292 const DataLayout &
DL =
F.getDataLayout();
1293 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1303 TypeSize TS, Align Alignment) {
1304 const DataLayout &
DL =
F.getDataLayout();
1305 const Align IntptrAlignment =
DL.getABITypeAlign(MS.IntptrTy);
1306 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1318 auto [InsertPt,
Index] =
1330 Align CurrentAlignment = Alignment;
1331 if (Alignment >= IntptrAlignment && IntptrSize >
kOriginSize) {
1332 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1334 for (
unsigned i = 0; i <
Size / IntptrSize; ++i) {
1339 CurrentAlignment = IntptrAlignment;
1352 Value *OriginPtr, Align Alignment) {
1353 const DataLayout &
DL =
F.getDataLayout();
1355 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
1357 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1366 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1373 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1375 if (instrumentWithCalls(ConvertedShadow) &&
1377 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1378 Value *ConvertedShadow2 =
1380 CallBase *CB = IRB.
CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1384 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1388 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1393 void materializeStores() {
1394 for (StoreInst *SI : StoreList) {
1396 Value *Val =
SI->getValueOperand();
1397 Value *Addr =
SI->getPointerOperand();
1398 Value *Shadow =
SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1399 Value *ShadowPtr, *OriginPtr;
1401 const Align Alignment =
SI->getAlign();
1403 std::tie(ShadowPtr, OriginPtr) =
1404 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
true);
1406 [[maybe_unused]] StoreInst *NewSI =
1413 if (MS.TrackOrigins && !
SI->isAtomic())
1414 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1421 if (MS.TrackOrigins < 2)
1424 if (LazyWarningDebugLocationCount.
empty())
1425 for (
const auto &
I : InstrumentationList)
1426 ++LazyWarningDebugLocationCount[
I.OrigIns->getDebugLoc()];
1442 auto NewDebugLoc = OI->getDebugLoc();
1449 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1450 Origin = updateOrigin(Origin, IRBOrigin);
1455 if (MS.CompileKernel || MS.TrackOrigins)
1466 const DataLayout &
DL =
F.getDataLayout();
1467 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1469 if (instrumentWithCalls(ConvertedShadow) && !MS.CompileKernel) {
1471 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1472 Value *ConvertedShadow2 =
1476 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1480 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1484 FunctionCallee Fn = MS.MaybeWarningVarSizeFn;
1487 unsigned ShadowSize =
DL.getTypeAllocSize(ConvertedShadow2->
getType());
1490 {ShadowAlloca, ConstantInt::get(IRB.
getInt64Ty(), ShadowSize),
1491 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1496 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1499 !MS.Recover, MS.ColdCallWeights);
1502 insertWarningFn(IRB, Origin);
1507 void materializeInstructionChecks(
1509 const DataLayout &
DL =
F.getDataLayout();
1512 bool Combine = !MS.TrackOrigins;
1514 Value *Shadow =
nullptr;
1515 for (
const auto &ShadowData : InstructionChecks) {
1516 assert(ShadowData.OrigIns == Instruction);
1519 Value *ConvertedShadow = ShadowData.Shadow;
1528 insertWarningFn(IRB, ShadowData.Origin);
1538 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1543 Shadow = ConvertedShadow;
1547 Shadow = convertToBool(Shadow, IRB,
"_mscmp");
1548 ConvertedShadow = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1549 Shadow = IRB.
CreateOr(Shadow, ConvertedShadow,
"_msor");
1555 materializeOneCheck(IRB, Shadow,
nullptr);
1559 static bool isAArch64SVCount(
Type *Ty) {
1561 return TTy->
getName() ==
"aarch64.svcount";
1567 static bool isScalableNonVectorType(
Type *Ty) {
1568 if (!isAArch64SVCount(Ty))
1569 LLVM_DEBUG(
dbgs() <<
"isScalableNonVectorType: Unexpected type " << *Ty
1575 void materializeChecks() {
1578 SmallPtrSet<Instruction *, 16>
Done;
1581 for (
auto I = InstrumentationList.begin();
1582 I != InstrumentationList.end();) {
1583 auto OrigIns =
I->OrigIns;
1587 auto J = std::find_if(
I + 1, InstrumentationList.end(),
1588 [OrigIns](
const ShadowOriginAndInsertPoint &R) {
1589 return OrigIns != R.OrigIns;
1603 MS.ParamTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1604 {Zero, IRB.getInt32(0)},
"param_shadow");
1605 MS.RetvalTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1606 {Zero, IRB.getInt32(1)},
"retval_shadow");
1607 MS.VAArgTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1608 {Zero, IRB.getInt32(2)},
"va_arg_shadow");
1609 MS.VAArgOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1610 {Zero, IRB.getInt32(3)},
"va_arg_origin");
1611 MS.VAArgOverflowSizeTLS =
1612 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1613 {Zero, IRB.getInt32(4)},
"va_arg_overflow_size");
1614 MS.ParamOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1615 {Zero, IRB.getInt32(5)},
"param_origin");
1616 MS.RetvalOriginTLS =
1617 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1618 {Zero, IRB.getInt32(6)},
"retval_origin");
1620 MS.MsanMetadataAlloca = IRB.
CreateAlloca(MS.MsanMetadata, 0u);
1633 for (Instruction *
I : Instructions)
1637 for (PHINode *PN : ShadowPHINodes) {
1639 PHINode *PNO = MS.TrackOrigins ?
cast<PHINode>(getOrigin(PN)) : nullptr;
1640 size_t NumValues = PN->getNumIncomingValues();
1641 for (
size_t v = 0;
v < NumValues;
v++) {
1642 PNS->
addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1644 PNO->
addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1648 VAHelper->finalizeInstrumentation();
1653 for (
auto Item : LifetimeStartList) {
1654 instrumentAlloca(*Item.second, Item.first);
1655 AllocaSet.
remove(Item.second);
1660 for (AllocaInst *AI : AllocaSet)
1661 instrumentAlloca(*AI);
1664 materializeChecks();
1668 materializeStores();
1674 Type *getShadowTy(
Value *V) {
return getShadowTy(
V->getType()); }
1685 const DataLayout &
DL =
F.getDataLayout();
1687 uint32_t EltSize =
DL.getTypeSizeInBits(VT->getElementType());
1689 VT->getElementCount());
1692 return ArrayType::get(getShadowTy(AT->getElementType()),
1693 AT->getNumElements());
1697 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1698 Elements.push_back(getShadowTy(
ST->getElementType(i)));
1700 LLVM_DEBUG(
dbgs() <<
"getShadowTy: " << *ST <<
" ===> " << *Res <<
"\n");
1703 if (isScalableNonVectorType(OrigTy)) {
1704 LLVM_DEBUG(
dbgs() <<
"getShadowTy: Scalable non-vector type: " << *OrigTy
1709 uint32_t TypeSize =
DL.getTypeSizeInBits(OrigTy);
1714 Value *collapseStructShadow(StructType *Struct,
Value *Shadow,
1719 for (
unsigned Idx = 0; Idx <
Struct->getNumElements(); Idx++) {
1722 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1724 if (Aggregator != FalseVal)
1725 Aggregator = IRB.
CreateOr(Aggregator, ShadowBool);
1727 Aggregator = ShadowBool;
1734 Value *collapseArrayShadow(ArrayType *Array,
Value *Shadow,
1736 if (!
Array->getNumElements())
1740 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1742 for (
unsigned Idx = 1; Idx <
Array->getNumElements(); Idx++) {
1744 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1745 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
1755 return collapseStructShadow(Struct, V, IRB);
1757 return collapseArrayShadow(Array, V, IRB);
1762 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1770 Type *VTy =
V->getType();
1772 return convertToBool(convertShadowToScalar(V, IRB), IRB,
name);
1779 Type *ptrToIntPtrType(
Type *PtrTy)
const {
1781 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1782 VectTy->getElementCount());
1788 Type *getPtrToShadowPtrType(
Type *IntPtrTy,
Type *ShadowTy)
const {
1790 return VectorType::get(
1791 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1792 VectTy->getElementCount());
1794 assert(IntPtrTy == MS.IntptrTy);
1801 VectTy->getElementCount(),
1802 constToIntPtr(VectTy->getElementType(),
C));
1804 assert(IntPtrTy == MS.IntptrTy);
1807 return ConstantInt::get(MS.IntptrTy,
C,
false,
1821 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1824 if (uint64_t AndMask = MS.MapParams->AndMask)
1825 OffsetLong = IRB.
CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1827 if (uint64_t XorMask = MS.MapParams->XorMask)
1828 OffsetLong = IRB.
CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1840 std::pair<Value *, Value *>
1842 MaybeAlign Alignment) {
1847 assert(VectTy->getElementType()->isPointerTy());
1849 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1850 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1851 Value *ShadowLong = ShadowOffset;
1852 if (uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1854 IRB.
CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1857 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1859 Value *OriginPtr =
nullptr;
1860 if (MS.TrackOrigins) {
1861 Value *OriginLong = ShadowOffset;
1862 uint64_t OriginBase = MS.MapParams->OriginBase;
1863 if (OriginBase != 0)
1865 IRB.
CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1868 OriginLong = IRB.
CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1871 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1873 return std::make_pair(ShadowPtr, OriginPtr);
1876 template <
typename... ArgsTy>
1881 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1882 return IRB.
CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1885 return IRB.
CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1888 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(
Value *Addr,
1892 Value *ShadowOriginPtrs;
1893 const DataLayout &
DL =
F.getDataLayout();
1894 TypeSize
Size =
DL.getTypeStoreSize(ShadowTy);
1896 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(
isStore,
Size);
1899 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1901 Value *SizeVal = ConstantInt::get(MS.IntptrTy,
Size);
1902 ShadowOriginPtrs = createMetadataCall(
1904 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1911 return std::make_pair(ShadowPtr, OriginPtr);
1917 std::pair<Value *, Value *> getShadowOriginPtrKernel(
Value *Addr,
1924 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy,
isStore);
1929 Value *ShadowPtrs = ConstantInt::getNullValue(
1931 Value *OriginPtrs =
nullptr;
1932 if (MS.TrackOrigins)
1933 OriginPtrs = ConstantInt::getNullValue(
1935 for (
unsigned i = 0; i < NumElements; ++i) {
1938 auto [ShadowPtr, OriginPtr] =
1939 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy,
isStore);
1942 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1943 if (MS.TrackOrigins)
1945 OriginPtrs, OriginPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1947 return {ShadowPtrs, OriginPtrs};
1950 std::pair<Value *, Value *> getShadowOriginPtr(
Value *Addr,
IRBuilder<> &IRB,
1952 MaybeAlign Alignment,
1954 if (MS.CompileKernel)
1955 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy,
isStore);
1956 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1964 ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg");
1969 if (!MS.TrackOrigins)
1972 ConstantInt::get(MS.IntptrTy, ArgOffset),
1982 Value *getOriginPtrForRetval() {
1984 return MS.RetvalOriginTLS;
1989 assert(!ShadowMap.
count(V) &&
"Values may only have one shadow");
1990 ShadowMap[
V] = PropagateShadow ? SV : getCleanShadow(V);
1995 if (!MS.TrackOrigins)
1997 assert(!OriginMap.
count(V) &&
"Values may only have one origin");
1998 LLVM_DEBUG(
dbgs() <<
"ORIGIN: " << *V <<
" ==> " << *Origin <<
"\n");
1999 OriginMap[
V] = Origin;
2003 Type *ShadowTy = getShadowTy(OrigTy);
2013 Constant *getCleanShadow(
Value *V) {
return getCleanShadow(
V->getType()); }
2021 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
2022 getPoisonedShadow(AT->getElementType()));
2026 SmallVector<Constant *, 4> Vals;
2027 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
2028 Vals.
push_back(getPoisonedShadow(
ST->getElementType(i)));
2036 Type *ShadowTy = getShadowTy(V);
2039 return getPoisonedShadow(ShadowTy);
2051 if (!PropagateShadow ||
I->getMetadata(LLVMContext::MD_nosanitize))
2052 return getCleanShadow(V);
2054 Value *Shadow = ShadowMap[
V];
2056 LLVM_DEBUG(
dbgs() <<
"No shadow: " << *V <<
"\n" << *(
I->getParent()));
2057 assert(Shadow &&
"No shadow for a value");
2064 Value *
AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
2065 : getCleanShadow(V);
2071 Value *&ShadowPtr = ShadowMap[
V];
2076 unsigned ArgOffset = 0;
2077 const DataLayout &
DL =
F->getDataLayout();
2078 for (
auto &FArg :
F->args()) {
2079 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
2081 ?
"vscale not fully supported\n"
2082 :
"Arg is not sized\n"));
2084 ShadowPtr = getCleanShadow(V);
2085 setOrigin(
A, getCleanOrigin());
2091 unsigned Size = FArg.hasByValAttr()
2092 ?
DL.getTypeAllocSize(FArg.getParamByValType())
2093 :
DL.getTypeAllocSize(FArg.getType());
2097 if (FArg.hasByValAttr()) {
2101 const Align ArgAlign =
DL.getValueOrABITypeAlignment(
2102 FArg.getParamAlign(), FArg.getParamByValType());
2103 Value *CpShadowPtr, *CpOriginPtr;
2104 std::tie(CpShadowPtr, CpOriginPtr) =
2105 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
2107 if (!PropagateShadow || Overflow) {
2109 EntryIRB.CreateMemSet(
2113 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2115 [[maybe_unused]]
Value *Cpy = EntryIRB.CreateMemCpy(
2116 CpShadowPtr, CopyAlign,
Base, CopyAlign,
Size);
2119 if (MS.TrackOrigins) {
2120 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
2124 EntryIRB.CreateMemCpy(
2133 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
2134 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
2135 ShadowPtr = getCleanShadow(V);
2136 setOrigin(
A, getCleanOrigin());
2139 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2140 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg),
Base,
2142 if (MS.TrackOrigins) {
2143 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
2144 setOrigin(
A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
2148 <<
" ARG: " << FArg <<
" ==> " << *ShadowPtr <<
"\n");
2154 assert(ShadowPtr &&
"Could not find shadow for an argument");
2161 cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
2162 PoisonUndefVectors) {
2165 for (
unsigned i = 0; i != NumElems; ++i) {
2168 : getCleanShadow(Elem);
2172 LLVM_DEBUG(
dbgs() <<
"Partial undef constant vector: " << *V <<
" ==> "
2173 << *ShadowConstant <<
"\n");
2175 return ShadowConstant;
2181 return getCleanShadow(V);
2185 Value *getShadow(Instruction *
I,
int i) {
2186 return getShadow(
I->getOperand(i));
2191 if (!MS.TrackOrigins)
2194 return getCleanOrigin();
2196 "Unexpected value type in getOrigin()");
2198 if (
I->getMetadata(LLVMContext::MD_nosanitize))
2199 return getCleanOrigin();
2201 Value *Origin = OriginMap[
V];
2202 assert(Origin &&
"Missing origin");
2207 Value *getOrigin(Instruction *
I,
int i) {
2208 return getOrigin(
I->getOperand(i));
2215 void insertCheckShadow(
Value *Shadow,
Value *Origin, Instruction *OrigIns) {
2221 LLVM_DEBUG(
dbgs() <<
"Skipping check of " << *Shadow <<
" before "
2222 << *OrigIns <<
"\n");
2227 if (isScalableNonVectorType(ShadowTy)) {
2228 LLVM_DEBUG(
dbgs() <<
"Skipping check of scalable non-vector " << *Shadow
2229 <<
" before " << *OrigIns <<
"\n");
2235 "Can only insert checks for integer, vector, and aggregate shadow "
2238 InstrumentationList.push_back(
2239 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2247 void insertCheckShadowOf(
Value *Val, Instruction *OrigIns) {
2249 Value *Shadow, *Origin;
2251 Shadow = getShadow(Val);
2254 Origin = getOrigin(Val);
2261 insertCheckShadow(Shadow, Origin, OrigIns);
2266 case AtomicOrdering::NotAtomic:
2267 return AtomicOrdering::NotAtomic;
2268 case AtomicOrdering::Unordered:
2269 case AtomicOrdering::Monotonic:
2270 case AtomicOrdering::Release:
2271 return AtomicOrdering::Release;
2272 case AtomicOrdering::Acquire:
2273 case AtomicOrdering::AcquireRelease:
2274 return AtomicOrdering::AcquireRelease;
2275 case AtomicOrdering::SequentiallyConsistent:
2276 return AtomicOrdering::SequentiallyConsistent;
2282 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2283 uint32_t OrderingTable[NumOrderings] = {};
2285 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2286 OrderingTable[(
int)AtomicOrderingCABI::release] =
2287 (int)AtomicOrderingCABI::release;
2288 OrderingTable[(int)AtomicOrderingCABI::consume] =
2289 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2290 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2291 (
int)AtomicOrderingCABI::acq_rel;
2292 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2293 (
int)AtomicOrderingCABI::seq_cst;
2300 case AtomicOrdering::NotAtomic:
2301 return AtomicOrdering::NotAtomic;
2302 case AtomicOrdering::Unordered:
2303 case AtomicOrdering::Monotonic:
2304 case AtomicOrdering::Acquire:
2305 return AtomicOrdering::Acquire;
2306 case AtomicOrdering::Release:
2307 case AtomicOrdering::AcquireRelease:
2308 return AtomicOrdering::AcquireRelease;
2309 case AtomicOrdering::SequentiallyConsistent:
2310 return AtomicOrdering::SequentiallyConsistent;
2316 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2317 uint32_t OrderingTable[NumOrderings] = {};
2319 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2320 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2321 OrderingTable[(int)AtomicOrderingCABI::consume] =
2322 (
int)AtomicOrderingCABI::acquire;
2323 OrderingTable[(int)AtomicOrderingCABI::release] =
2324 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
2325 (int)AtomicOrderingCABI::acq_rel;
2326 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2327 (
int)AtomicOrderingCABI::seq_cst;
2333 using InstVisitor<MemorySanitizerVisitor>
::visit;
2334 void visit(Instruction &
I) {
2335 if (
I.getMetadata(LLVMContext::MD_nosanitize))
2338 if (isInPrologue(
I))
2343 setShadow(&
I, getCleanShadow(&
I));
2344 setOrigin(&
I, getCleanOrigin());
2355 void visitLoadInst(LoadInst &
I) {
2356 assert(
I.getType()->isSized() &&
"Load type must have size");
2357 assert(!
I.getMetadata(LLVMContext::MD_nosanitize));
2358 NextNodeIRBuilder IRB(&
I);
2359 Type *ShadowTy = getShadowTy(&
I);
2360 Value *Addr =
I.getPointerOperand();
2361 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
2362 const Align Alignment =
I.getAlign();
2363 if (PropagateShadow) {
2364 std::tie(ShadowPtr, OriginPtr) =
2365 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
2369 setShadow(&
I, getCleanShadow(&
I));
2373 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2378 if (MS.TrackOrigins) {
2379 if (PropagateShadow) {
2384 setOrigin(&
I, getCleanOrigin());
2393 void visitStoreInst(StoreInst &
I) {
2394 StoreList.push_back(&
I);
2396 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2399 void handleCASOrRMW(Instruction &
I) {
2403 Value *Addr =
I.getOperand(0);
2404 Value *Val =
I.getOperand(1);
2405 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val),
Align(1),
2410 insertCheckShadowOf(Addr, &
I);
2416 insertCheckShadowOf(Val, &
I);
2420 setShadow(&
I, getCleanShadow(&
I));
2421 setOrigin(&
I, getCleanOrigin());
2424 void visitAtomicRMWInst(AtomicRMWInst &
I) {
2429 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2491 void visitSwitchInst(SwitchInst &SI) {
2494 Value *Val =
SI.getCondition();
2495 Value *ShadowVal = getShadow(Val);
2507 Value *ShadowCases =
nullptr;
2508 for (
auto Case :
SI.cases()) {
2509 if (casesToConsider <= 0)
2512 Value *Comparator = Case.getCaseValue();
2515 Value *ComparisonShadow = propagateEqualityComparison(
2516 IRB, Val, Comparator, ShadowVal, getShadow(Comparator));
2519 ShadowCases = IRB.
CreateOr(ShadowCases, ComparisonShadow);
2521 ShadowCases = ComparisonShadow;
2527 insertCheckShadow(ShadowCases, getOrigin(Val), &SI);
2531 void visitExtractElementInst(ExtractElementInst &
I) {
2532 insertCheckShadowOf(
I.getOperand(1), &
I);
2536 setOrigin(&
I, getOrigin(&
I, 0));
2539 void visitInsertElementInst(InsertElementInst &
I) {
2540 insertCheckShadowOf(
I.getOperand(2), &
I);
2542 auto *Shadow0 = getShadow(&
I, 0);
2543 auto *Shadow1 = getShadow(&
I, 1);
2546 setOriginForNaryOp(
I);
2549 void visitShuffleVectorInst(ShuffleVectorInst &
I) {
2551 auto *Shadow0 = getShadow(&
I, 0);
2552 auto *Shadow1 = getShadow(&
I, 1);
2555 setOriginForNaryOp(
I);
2559 void visitSExtInst(SExtInst &
I) {
2561 setShadow(&
I, IRB.
CreateSExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2562 setOrigin(&
I, getOrigin(&
I, 0));
2565 void visitZExtInst(ZExtInst &
I) {
2567 setShadow(&
I, IRB.
CreateZExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2568 setOrigin(&
I, getOrigin(&
I, 0));
2571 void visitTruncInst(TruncInst &
I) {
2573 setShadow(&
I, IRB.
CreateTrunc(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2574 setOrigin(&
I, getOrigin(&
I, 0));
2577 void visitBitCastInst(BitCastInst &
I) {
2582 if (CI->isMustTailCall())
2586 setOrigin(&
I, getOrigin(&
I, 0));
2589 void visitPtrToIntInst(PtrToIntInst &
I) {
2592 "_msprop_ptrtoint"));
2593 setOrigin(&
I, getOrigin(&
I, 0));
2596 void visitIntToPtrInst(IntToPtrInst &
I) {
2599 "_msprop_inttoptr"));
2600 setOrigin(&
I, getOrigin(&
I, 0));
2603 void visitFPToSIInst(CastInst &
I) { handleShadowOr(
I); }
2604 void visitFPToUIInst(CastInst &
I) { handleShadowOr(
I); }
2605 void visitSIToFPInst(CastInst &
I) { handleShadowOr(
I); }
2606 void visitUIToFPInst(CastInst &
I) { handleShadowOr(
I); }
2607 void visitFPExtInst(CastInst &
I) { handleShadowOr(
I); }
2608 void visitFPTruncInst(CastInst &
I) { handleShadowOr(
I); }
2632 return IRB.
CreateOr({S1S2, V1S2, S1V2});
2636 void visitAnd(BinaryOperator &
I) {
2638 Value *V1 =
I.getOperand(0);
2639 Value *V2 =
I.getOperand(1);
2641 Value *S2 = getShadow(&
I, 1);
2643 Value *OutShadow = handleBitwiseAnd(IRB, V1, V2,
S1, S2);
2645 setShadow(&
I, OutShadow);
2646 setOriginForNaryOp(
I);
2649 void visitOr(BinaryOperator &
I) {
2662 Value *S2 = getShadow(&
I, 1);
2663 Value *V1 =
I.getOperand(0);
2664 Value *V2 =
I.getOperand(1);
2683 S = IRB.
CreateOr(S, DisjointOrShadow,
"_ms_disjoint");
2687 setOriginForNaryOp(
I);
2705 template <
bool CombineShadow>
class Combiner {
2706 Value *Shadow =
nullptr;
2707 Value *Origin =
nullptr;
2709 MemorySanitizerVisitor *MSV;
2712 Combiner(MemorySanitizerVisitor *MSV,
IRBuilder<> &IRB)
2713 : IRB(IRB), MSV(MSV) {}
2717 if (CombineShadow) {
2722 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2723 Shadow = IRB.
CreateOr(Shadow, OpShadow,
"_msprop");
2727 if (MSV->MS.TrackOrigins) {
2734 if (!ConstOrigin || !ConstOrigin->
isNullValue()) {
2735 Value *
Cond = MSV->convertToBool(OpShadow, IRB);
2745 Value *OpShadow = MSV->getShadow(V);
2746 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) :
nullptr;
2747 return Add(OpShadow, OpOrigin);
2752 void Done(Instruction *
I) {
2753 if (CombineShadow) {
2755 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(
I));
2756 MSV->setShadow(
I, Shadow);
2758 if (MSV->MS.TrackOrigins) {
2760 MSV->setOrigin(
I, Origin);
2766 void DoneAndStoreOrigin(TypeSize TS,
Value *OriginPtr) {
2767 if (MSV->MS.TrackOrigins) {
2774 using ShadowAndOriginCombiner = Combiner<true>;
2775 using OriginCombiner = Combiner<false>;
2778 void setOriginForNaryOp(Instruction &
I) {
2779 if (!MS.TrackOrigins)
2782 OriginCombiner OC(
this, IRB);
2783 for (Use &
Op :
I.operands())
2788 size_t VectorOrPrimitiveTypeSizeInBits(
Type *Ty) {
2790 "Vector of pointers is not a valid shadow type");
2800 Type *srcTy =
V->getType();
2803 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2804 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2805 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2823 Type *ShadowTy = getShadowTy(V);
2824 if (
V->getType() == ShadowTy)
2826 if (
V->getType()->isPtrOrPtrVectorTy())
2833 void handleShadowOr(Instruction &
I) {
2835 ShadowAndOriginCombiner SC(
this, IRB);
2836 for (Use &
Op :
I.operands())
2863 Value *horizontalReduce(IntrinsicInst &
I,
unsigned ReductionFactor,
2864 unsigned Shards,
Value *VectorA,
Value *VectorB) {
2869 [[maybe_unused]]
unsigned TotalNumElems = NumElems;
2875 assert(NumElems % (ReductionFactor * Shards) == 0);
2880 for (
unsigned i = 0; i < ReductionFactor; i++) {
2881 SmallVector<int, 16>
Mask;
2883 for (
unsigned j = 0;
j < Shards;
j++) {
2884 unsigned Offset = NumElems / Shards *
j;
2886 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2890 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2915 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards) {
2916 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2918 assert(
I.getType()->isVectorTy());
2919 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2921 [[maybe_unused]] FixedVectorType *ParamType =
2925 [[maybe_unused]] FixedVectorType *
ReturnType =
2933 Value *FirstArgShadow = getShadow(&
I, 0);
2934 Value *SecondArgShadow =
nullptr;
2935 if (
I.arg_size() == 2)
2936 SecondArgShadow = getShadow(&
I, 1);
2938 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2939 FirstArgShadow, SecondArgShadow);
2941 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2943 setShadow(&
I, OrShadow);
2944 setOriginForNaryOp(
I);
2954 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards,
2955 int ReinterpretElemWidth) {
2956 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2958 assert(
I.getType()->isVectorTy());
2959 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2961 FixedVectorType *ParamType =
2966 [[maybe_unused]] FixedVectorType *
ReturnType =
2973 FixedVectorType *ReinterpretShadowTy =
nullptr;
2981 Value *FirstArgShadow = getShadow(&
I, 0);
2982 FirstArgShadow = IRB.
CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
2992 Value *SecondArgShadow =
nullptr;
2993 if (
I.arg_size() == 2) {
2994 SecondArgShadow = getShadow(&
I, 1);
2995 SecondArgShadow = IRB.
CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
2998 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2999 FirstArgShadow, SecondArgShadow);
3001 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
3003 setShadow(&
I, OrShadow);
3004 setOriginForNaryOp(
I);
3007 void visitFNeg(UnaryOperator &
I) { handleShadowOr(
I); }
3018 void handleMulByConstant(BinaryOperator &
I, Constant *ConstArg,
3024 Type *EltTy = VTy->getElementType();
3026 for (
unsigned Idx = 0; Idx < NumElements; ++Idx) {
3027 if (ConstantInt *Elt =
3029 const APInt &
V = Elt->getValue();
3030 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
3031 Elements.push_back(ConstantInt::get(EltTy, V2));
3033 Elements.push_back(ConstantInt::get(EltTy, 1));
3039 const APInt &
V = Elt->getValue();
3040 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
3041 ShadowMul = ConstantInt::get(Ty, V2);
3043 ShadowMul = ConstantInt::get(Ty, 1);
3049 IRB.
CreateMul(getShadow(OtherArg), ShadowMul,
"msprop_mul_cst"));
3050 setOrigin(&
I, getOrigin(OtherArg));
3053 void visitMul(BinaryOperator &
I) {
3056 if (constOp0 && !constOp1)
3057 handleMulByConstant(
I, constOp0,
I.getOperand(1));
3058 else if (constOp1 && !constOp0)
3059 handleMulByConstant(
I, constOp1,
I.getOperand(0));
3064 void visitFAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3065 void visitFSub(BinaryOperator &
I) { handleShadowOr(
I); }
3066 void visitFMul(BinaryOperator &
I) { handleShadowOr(
I); }
3067 void visitAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3068 void visitSub(BinaryOperator &
I) { handleShadowOr(
I); }
3069 void visitXor(BinaryOperator &
I) { handleShadowOr(
I); }
3071 void handleIntegerDiv(Instruction &
I) {
3074 insertCheckShadowOf(
I.getOperand(1), &
I);
3075 setShadow(&
I, getShadow(&
I, 0));
3076 setOrigin(&
I, getOrigin(&
I, 0));
3079 void visitUDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3080 void visitSDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3081 void visitURem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3082 void visitSRem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3086 void visitFDiv(BinaryOperator &
I) { handleShadowOr(
I); }
3087 void visitFRem(BinaryOperator &
I) { handleShadowOr(
I); }
3093 void handleEqualityComparison(ICmpInst &
I) {
3097 Value *Sa = getShadow(
A);
3098 Value *Sb = getShadow(
B);
3100 Value *Si = propagateEqualityComparison(IRB,
A,
B, Sa, Sb);
3103 setOriginForNaryOp(
I);
3111 void handleRelationalComparisonExact(ICmpInst &
I) {
3115 Value *Sa = getShadow(
A);
3116 Value *Sb = getShadow(
B);
3127 bool IsSigned =
I.isSigned();
3129 auto GetMinMaxUnsigned = [&](
Value *
V,
Value *S) {
3139 V = IRB.
CreateXor(V, ConstantInt::get(
V->getType(), MinVal));
3144 return std::make_pair(Min, Max);
3147 auto [Amin, Amax] = GetMinMaxUnsigned(
A, Sa);
3148 auto [Bmin, Bmax] = GetMinMaxUnsigned(
B, Sb);
3154 setOriginForNaryOp(
I);
3161 void handleSignedRelationalComparison(ICmpInst &
I) {
3166 op =
I.getOperand(0);
3167 pre =
I.getPredicate();
3169 op =
I.getOperand(1);
3170 pre =
I.getSwappedPredicate();
3183 setShadow(&
I, Shadow);
3184 setOrigin(&
I, getOrigin(
op));
3190 void visitICmpInst(ICmpInst &
I) {
3195 if (
I.isEquality()) {
3196 handleEqualityComparison(
I);
3202 handleRelationalComparisonExact(
I);
3206 handleSignedRelationalComparison(
I);
3212 handleRelationalComparisonExact(
I);
3219 void visitFCmpInst(FCmpInst &
I) { handleShadowOr(
I); }
3221 void handleShift(BinaryOperator &
I) {
3226 Value *S2 = getShadow(&
I, 1);
3229 Value *V2 =
I.getOperand(1);
3231 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3232 setOriginForNaryOp(
I);
3235 void visitShl(BinaryOperator &
I) { handleShift(
I); }
3236 void visitAShr(BinaryOperator &
I) { handleShift(
I); }
3237 void visitLShr(BinaryOperator &
I) { handleShift(
I); }
3239 void handleFunnelShift(IntrinsicInst &
I) {
3243 Value *S0 = getShadow(&
I, 0);
3245 Value *S2 = getShadow(&
I, 2);
3248 Value *V2 =
I.getOperand(2);
3251 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3252 setOriginForNaryOp(
I);
3265 void visitMemMoveInst(MemMoveInst &
I) {
3266 getShadow(
I.getArgOperand(1));
3269 {I.getArgOperand(0), I.getArgOperand(1),
3270 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3288 void visitMemCpyInst(MemCpyInst &
I) {
3289 getShadow(
I.getArgOperand(1));
3292 {I.getArgOperand(0), I.getArgOperand(1),
3293 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3298 void visitMemSetInst(MemSetInst &
I) {
3302 {I.getArgOperand(0),
3303 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3304 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3308 void visitVAStartInst(VAStartInst &
I) { VAHelper->visitVAStartInst(
I); }
3310 void visitVACopyInst(VACopyInst &
I) { VAHelper->visitVACopyInst(
I); }
3316 bool handleVectorStoreIntrinsic(IntrinsicInst &
I) {
3320 Value *Addr =
I.getArgOperand(0);
3321 Value *Shadow = getShadow(&
I, 1);
3322 Value *ShadowPtr, *OriginPtr;
3326 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3331 insertCheckShadowOf(Addr, &
I);
3334 if (MS.TrackOrigins)
3343 bool handleVectorLoadIntrinsic(IntrinsicInst &
I) {
3347 Value *Addr =
I.getArgOperand(0);
3349 Type *ShadowTy = getShadowTy(&
I);
3350 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
3351 if (PropagateShadow) {
3355 std::tie(ShadowPtr, OriginPtr) =
3356 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
3360 setShadow(&
I, getCleanShadow(&
I));
3364 insertCheckShadowOf(Addr, &
I);
3366 if (MS.TrackOrigins) {
3367 if (PropagateShadow)
3368 setOrigin(&
I, IRB.
CreateLoad(MS.OriginTy, OriginPtr));
3370 setOrigin(&
I, getCleanOrigin());
3390 [[maybe_unused]]
bool
3391 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &
I,
3392 unsigned int trailingFlags) {
3393 Type *RetTy =
I.getType();
3397 unsigned NumArgOperands =
I.arg_size();
3398 assert(NumArgOperands >= trailingFlags);
3399 for (
unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3400 Type *Ty =
I.getArgOperand(i)->getType();
3406 ShadowAndOriginCombiner SC(
this, IRB);
3407 for (
unsigned i = 0; i < NumArgOperands; ++i)
3408 SC.Add(
I.getArgOperand(i));
3425 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &
I) {
3426 unsigned NumArgOperands =
I.arg_size();
3427 if (NumArgOperands == 0)
3430 if (NumArgOperands == 2 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3431 I.getArgOperand(1)->getType()->isVectorTy() &&
3432 I.getType()->isVoidTy() && !
I.onlyReadsMemory()) {
3434 return handleVectorStoreIntrinsic(
I);
3437 if (NumArgOperands == 1 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3438 I.getType()->isVectorTy() &&
I.onlyReadsMemory()) {
3440 return handleVectorLoadIntrinsic(
I);
3443 if (
I.doesNotAccessMemory())
3444 if (maybeHandleSimpleNomemIntrinsic(
I, 0))
3452 bool maybeHandleUnknownIntrinsic(IntrinsicInst &
I) {
3453 if (maybeHandleUnknownIntrinsicUnlogged(
I)) {
3457 LLVM_DEBUG(
dbgs() <<
"UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " <<
I
3464 void handleInvariantGroup(IntrinsicInst &
I) {
3465 setShadow(&
I, getShadow(&
I, 0));
3466 setOrigin(&
I, getOrigin(&
I, 0));
3469 void handleLifetimeStart(IntrinsicInst &
I) {
3474 LifetimeStartList.push_back(std::make_pair(&
I, AI));
3477 void handleBswap(IntrinsicInst &
I) {
3480 Type *OpType =
Op->getType();
3483 setOrigin(&
I, getOrigin(
Op));
3504 void handleCountLeadingTrailingZeros(IntrinsicInst &
I) {
3506 Value *Src =
I.getArgOperand(0);
3507 Value *SrcShadow = getShadow(Src);
3511 I.getType(),
I.getIntrinsicID(), {Src, False});
3513 I.getType(),
I.getIntrinsicID(), {SrcShadow, False});
3516 ConcreteZerosCount, ShadowZerosCount,
"_mscz_cmp_zeros");
3518 Value *NotAllZeroShadow =
3520 Value *OutputShadow =
3521 IRB.
CreateAnd(CompareConcreteZeros, NotAllZeroShadow,
"_mscz_main");
3527 OutputShadow = IRB.
CreateOr(OutputShadow, BoolZeroPoison,
"_mscz_bs");
3530 OutputShadow = IRB.
CreateSExt(OutputShadow, getShadowTy(Src),
"_mscz_os");
3532 setShadow(&
I, OutputShadow);
3533 setOriginForNaryOp(
I);
3548 void handleNEONVectorConvertIntrinsic(IntrinsicInst &
I,
bool FixedPoint) {
3555 Value *S0 = getShadow(&
I, 0);
3558 Value *Precision =
I.getOperand(1);
3559 insertCheckShadowOf(Precision, &
I);
3569 setShadow(&
I, OutShadow);
3570 setOriginForNaryOp(
I);
3579 FixedVectorType *maybeShrinkVectorShadowType(
Value *Src, IntrinsicInst &
I) {
3599 Value *maybeExtendVectorShadowWithZeros(
Value *Shadow, IntrinsicInst &
I) {
3604 Value *FullShadow = getCleanShadow(&
I);
3605 unsigned ShadowNumElems =
3607 unsigned FullShadowNumElems =
3610 assert((ShadowNumElems == FullShadowNumElems) ||
3611 (ShadowNumElems * 2 == FullShadowNumElems));
3613 if (ShadowNumElems == FullShadowNumElems) {
3614 FullShadow = Shadow;
3618 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3643 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &
I,
3644 bool HasRoundingMode) {
3645 if (HasRoundingMode) {
3653 Value *Src =
I.getArgOperand(0);
3654 assert(Src->getType()->isVectorTy());
3658 VectorType *ShadowType = maybeShrinkVectorShadowType(Src,
I);
3661 Value *S0 = getShadow(&
I, 0);
3673 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow,
I);
3675 setShadow(&
I, FullShadow);
3676 setOriginForNaryOp(
I);
3697 void handleSSEVectorConvertIntrinsic(IntrinsicInst &
I,
int NumUsedElements,
3698 bool HasRoundingMode =
false) {
3700 Value *CopyOp, *ConvertOp;
3702 assert((!HasRoundingMode ||
3704 "Invalid rounding mode");
3706 switch (
I.arg_size() - HasRoundingMode) {
3708 CopyOp =
I.getArgOperand(0);
3709 ConvertOp =
I.getArgOperand(1);
3712 ConvertOp =
I.getArgOperand(0);
3726 Value *ConvertShadow = getShadow(ConvertOp);
3727 Value *AggShadow =
nullptr;
3730 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
3731 for (
int i = 1; i < NumUsedElements; ++i) {
3733 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
3734 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
3737 AggShadow = ConvertShadow;
3740 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &
I);
3747 Value *ResultShadow = getShadow(CopyOp);
3749 for (
int i = 0; i < NumUsedElements; ++i) {
3751 ResultShadow, ConstantInt::getNullValue(EltTy),
3754 setShadow(&
I, ResultShadow);
3755 setOrigin(&
I, getOrigin(CopyOp));
3757 setShadow(&
I, getCleanShadow(&
I));
3758 setOrigin(&
I, getCleanOrigin());
3766 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
3769 return CreateShadowCast(IRB, S2,
T,
true);
3777 return CreateShadowCast(IRB, S2,
T,
true);
3794 void handleVectorShiftIntrinsic(IntrinsicInst &
I,
bool Variable) {
3800 Value *S2 = getShadow(&
I, 1);
3802 : Lower64ShadowExtend(IRB, S2, getShadowTy(&
I));
3803 Value *V1 =
I.getOperand(0);
3804 Value *V2 =
I.getOperand(1);
3806 {IRB.CreateBitCast(S1, V1->getType()), V2});
3808 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3809 setOriginForNaryOp(
I);
3814 Type *getMMXVectorTy(
unsigned EltSizeInBits,
3815 unsigned X86_MMXSizeInBits = 64) {
3816 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3817 "Illegal MMX vector element size");
3819 X86_MMXSizeInBits / EltSizeInBits);
3826 case Intrinsic::x86_sse2_packsswb_128:
3827 case Intrinsic::x86_sse2_packuswb_128:
3828 return Intrinsic::x86_sse2_packsswb_128;
3830 case Intrinsic::x86_sse2_packssdw_128:
3831 case Intrinsic::x86_sse41_packusdw:
3832 return Intrinsic::x86_sse2_packssdw_128;
3834 case Intrinsic::x86_avx2_packsswb:
3835 case Intrinsic::x86_avx2_packuswb:
3836 return Intrinsic::x86_avx2_packsswb;
3838 case Intrinsic::x86_avx2_packssdw:
3839 case Intrinsic::x86_avx2_packusdw:
3840 return Intrinsic::x86_avx2_packssdw;
3842 case Intrinsic::x86_mmx_packsswb:
3843 case Intrinsic::x86_mmx_packuswb:
3844 return Intrinsic::x86_mmx_packsswb;
3846 case Intrinsic::x86_mmx_packssdw:
3847 return Intrinsic::x86_mmx_packssdw;
3849 case Intrinsic::x86_avx512_packssdw_512:
3850 case Intrinsic::x86_avx512_packusdw_512:
3851 return Intrinsic::x86_avx512_packssdw_512;
3853 case Intrinsic::x86_avx512_packsswb_512:
3854 case Intrinsic::x86_avx512_packuswb_512:
3855 return Intrinsic::x86_avx512_packsswb_512;
3871 void handleVectorPackIntrinsic(IntrinsicInst &
I,
3872 unsigned MMXEltSizeInBits = 0) {
3876 Value *S2 = getShadow(&
I, 1);
3877 assert(
S1->getType()->isVectorTy());
3883 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) :
S1->
getType();
3884 if (MMXEltSizeInBits) {
3892 if (MMXEltSizeInBits) {
3898 {S1_ext, S2_ext},
nullptr,
3899 "_msprop_vector_pack");
3900 if (MMXEltSizeInBits)
3903 setOriginForNaryOp(
I);
3907 Constant *createDppMask(
unsigned Width,
unsigned Mask) {
3908 SmallVector<Constant *, 4>
R(Width);
3920 const unsigned Width =
3927 Value *DstMaskV = createDppMask(Width, DstMask);
3944 void handleDppIntrinsic(IntrinsicInst &
I) {
3947 Value *S0 = getShadow(&
I, 0);
3951 const unsigned Width =
3953 assert(Width == 2 || Width == 4 || Width == 8);
3956 const unsigned SrcMask =
Mask >> 4;
3957 const unsigned DstMask =
Mask & 0xf;
3960 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3965 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3972 setOriginForNaryOp(
I);
3976 C = CreateAppToShadowCast(IRB,
C);
3985 void handleBlendvIntrinsic(IntrinsicInst &
I) {
3990 Value *Sc = getShadow(&
I, 2);
3991 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
3996 C = convertBlendvToSelectMask(IRB,
C);
3997 Sc = convertBlendvToSelectMask(IRB, Sc);
4003 handleSelectLikeInst(
I,
C,
T,
F);
4007 void handleVectorSadIntrinsic(IntrinsicInst &
I,
bool IsMMX =
false) {
4008 const unsigned SignificantBitsPerResultElement = 16;
4010 unsigned ZeroBitsPerResultElement =
4014 auto *Shadow0 = getShadow(&
I, 0);
4015 auto *Shadow1 = getShadow(&
I, 1);
4020 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
4023 setOriginForNaryOp(
I);
4047 void handleVectorDotProductIntrinsic(IntrinsicInst &
I,
4048 unsigned ReductionFactor,
4050 unsigned EltSizeInBits,
4054 [[maybe_unused]] FixedVectorType *
ReturnType =
4059 Value *Va =
nullptr;
4060 Value *Vb =
nullptr;
4061 Value *Sa =
nullptr;
4062 Value *Sb =
nullptr;
4064 assert(
I.arg_size() == 2 ||
I.arg_size() == 3);
4065 if (
I.arg_size() == 2) {
4068 Va =
I.getOperand(0);
4069 Vb =
I.getOperand(1);
4071 Sa = getShadow(&
I, 0);
4072 Sb = getShadow(&
I, 1);
4073 }
else if (
I.arg_size() == 3) {
4075 Va =
I.getOperand(1);
4076 Vb =
I.getOperand(2);
4078 Sa = getShadow(&
I, 1);
4079 Sb = getShadow(&
I, 2);
4096 Sa, getPclmulMask(Width, Lanes ==
kOddLanes));
4098 Sb, getPclmulMask(Width, Lanes ==
kOddLanes));
4108 if (
I.arg_size() == 3) {
4109 [[maybe_unused]]
auto *AccumulatorType =
4111 assert(AccumulatorType == ReturnType);
4114 FixedVectorType *ImplicitReturnType =
4117 if (EltSizeInBits) {
4119 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4131 ReturnType->getNumElements() * ReductionFactor);
4148 VaInt = CreateAppToShadowCast(IRB, Va);
4149 VbInt = CreateAppToShadowCast(IRB, Vb);
4156 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4178 ImplicitReturnType);
4183 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&
I));
4186 if (
I.arg_size() == 3)
4187 OutShadow = IRB.
CreateOr(OutShadow, getShadow(&
I, 0));
4189 setShadow(&
I, OutShadow);
4190 setOriginForNaryOp(
I);
4207 void handleVectorComparePackedIntrinsic(IntrinsicInst &
I,
4208 bool PredicateAsOperand) {
4209 if (PredicateAsOperand) {
4211 assert(
I.paramHasAttr(2, Attribute::ImmArg));
4219 Type *ResTy = getShadowTy(&
I);
4220 auto *Shadow0 = getShadow(&
I, 0);
4221 auto *Shadow1 = getShadow(&
I, 1);
4226 setOriginForNaryOp(
I);
4232 void handleVectorCompareScalarIntrinsic(IntrinsicInst &
I) {
4234 auto *Shadow0 = getShadow(&
I, 0);
4235 auto *Shadow1 = getShadow(&
I, 1);
4237 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&
I));
4239 setOriginForNaryOp(
I);
4248 void handleVectorReduceIntrinsic(IntrinsicInst &
I,
bool AllowShadowCast) {
4253 if (AllowShadowCast)
4254 S = CreateShadowCast(IRB, S, getShadowTy(&
I));
4258 setOriginForNaryOp(
I);
4268 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &
I) {
4272 Value *Shadow0 = getShadow(&
I, 0);
4278 setOriginForNaryOp(
I);
4284 void handleVectorReduceOrIntrinsic(IntrinsicInst &
I) {
4288 Value *OperandShadow = getShadow(&
I, 0);
4290 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
4298 setOrigin(&
I, getOrigin(&
I, 0));
4304 void handleVectorReduceAndIntrinsic(IntrinsicInst &
I) {
4308 Value *OperandShadow = getShadow(&
I, 0);
4309 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
4317 setOrigin(&
I, getOrigin(&
I, 0));
4320 void handleStmxcsr(IntrinsicInst &
I) {
4322 Value *Addr =
I.getArgOperand(0);
4325 getShadowOriginPtr(Addr, IRB, Ty,
Align(1),
true).first;
4330 insertCheckShadowOf(Addr, &
I);
4333 void handleLdmxcsr(IntrinsicInst &
I) {
4338 Value *Addr =
I.getArgOperand(0);
4341 Value *ShadowPtr, *OriginPtr;
4342 std::tie(ShadowPtr, OriginPtr) =
4343 getShadowOriginPtr(Addr, IRB, Ty, Alignment,
false);
4346 insertCheckShadowOf(Addr, &
I);
4349 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
4351 insertCheckShadow(Shadow, Origin, &
I);
4354 void handleMaskedExpandLoad(IntrinsicInst &
I) {
4356 Value *Ptr =
I.getArgOperand(0);
4357 MaybeAlign
Align =
I.getParamAlign(0);
4359 Value *PassThru =
I.getArgOperand(2);
4362 insertCheckShadowOf(Ptr, &
I);
4363 insertCheckShadowOf(Mask, &
I);
4366 if (!PropagateShadow) {
4367 setShadow(&
I, getCleanShadow(&
I));
4368 setOrigin(&
I, getCleanOrigin());
4372 Type *ShadowTy = getShadowTy(&
I);
4374 auto [ShadowPtr, OriginPtr] =
4375 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
false);
4379 getShadow(PassThru),
"_msmaskedexpload");
4381 setShadow(&
I, Shadow);
4384 setOrigin(&
I, getCleanOrigin());
4387 void handleMaskedCompressStore(IntrinsicInst &
I) {
4389 Value *Values =
I.getArgOperand(0);
4390 Value *Ptr =
I.getArgOperand(1);
4391 MaybeAlign
Align =
I.getParamAlign(1);
4395 insertCheckShadowOf(Ptr, &
I);
4396 insertCheckShadowOf(Mask, &
I);
4399 Value *Shadow = getShadow(Values);
4400 Type *ElementShadowTy =
4402 auto [ShadowPtr, OriginPtrs] =
4403 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
true);
4410 void handleMaskedGather(IntrinsicInst &
I) {
4412 Value *Ptrs =
I.getArgOperand(0);
4413 const Align Alignment =
I.getParamAlign(0).valueOrOne();
4415 Value *PassThru =
I.getArgOperand(2);
4417 Type *PtrsShadowTy = getShadowTy(Ptrs);
4419 insertCheckShadowOf(Mask, &
I);
4423 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4426 if (!PropagateShadow) {
4427 setShadow(&
I, getCleanShadow(&
I));
4428 setOrigin(&
I, getCleanOrigin());
4432 Type *ShadowTy = getShadowTy(&
I);
4434 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4435 Ptrs, IRB, ElementShadowTy, Alignment,
false);
4439 getShadow(PassThru),
"_msmaskedgather");
4441 setShadow(&
I, Shadow);
4444 setOrigin(&
I, getCleanOrigin());
4447 void handleMaskedScatter(IntrinsicInst &
I) {
4449 Value *Values =
I.getArgOperand(0);
4450 Value *Ptrs =
I.getArgOperand(1);
4451 const Align Alignment =
I.getParamAlign(1).valueOrOne();
4454 Type *PtrsShadowTy = getShadowTy(Ptrs);
4456 insertCheckShadowOf(Mask, &
I);
4460 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4463 Value *Shadow = getShadow(Values);
4464 Type *ElementShadowTy =
4466 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4467 Ptrs, IRB, ElementShadowTy, Alignment,
true);
4478 void handleMaskedStore(IntrinsicInst &
I) {
4480 Value *
V =
I.getArgOperand(0);
4481 Value *Ptr =
I.getArgOperand(1);
4482 const Align Alignment =
I.getParamAlign(1).valueOrOne();
4484 Value *Shadow = getShadow(V);
4487 insertCheckShadowOf(Ptr, &
I);
4488 insertCheckShadowOf(Mask, &
I);
4493 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4494 Ptr, IRB, Shadow->
getType(), Alignment,
true);
4498 if (!MS.TrackOrigins)
4501 auto &
DL =
F.getDataLayout();
4502 paintOrigin(IRB, getOrigin(V), OriginPtr,
4511 void handleMaskedLoad(IntrinsicInst &
I) {
4513 Value *Ptr =
I.getArgOperand(0);
4514 const Align Alignment =
I.getParamAlign(0).valueOrOne();
4516 Value *PassThru =
I.getArgOperand(2);
4519 insertCheckShadowOf(Ptr, &
I);
4520 insertCheckShadowOf(Mask, &
I);
4523 if (!PropagateShadow) {
4524 setShadow(&
I, getCleanShadow(&
I));
4525 setOrigin(&
I, getCleanOrigin());
4529 Type *ShadowTy = getShadowTy(&
I);
4530 Value *ShadowPtr, *OriginPtr;
4531 std::tie(ShadowPtr, OriginPtr) =
4532 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment,
false);
4534 getShadow(PassThru),
"_msmaskedld"));
4536 if (!MS.TrackOrigins)
4543 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
4548 setOrigin(&
I, Origin);
4564 void handleAVXMaskedStore(IntrinsicInst &
I) {
4569 Value *Dst =
I.getArgOperand(0);
4570 assert(Dst->getType()->isPointerTy() &&
"Destination is not a pointer!");
4575 Value *Src =
I.getArgOperand(2);
4580 Value *SrcShadow = getShadow(Src);
4583 insertCheckShadowOf(Dst, &
I);
4584 insertCheckShadowOf(Mask, &
I);
4587 Value *DstShadowPtr;
4588 Value *DstOriginPtr;
4589 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4590 Dst, IRB, SrcShadow->
getType(), Alignment,
true);
4592 SmallVector<Value *, 2> ShadowArgs;
4593 ShadowArgs.
append(1, DstShadowPtr);
4594 ShadowArgs.
append(1, Mask);
4605 if (!MS.TrackOrigins)
4609 auto &
DL =
F.getDataLayout();
4610 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4611 DL.getTypeStoreSize(SrcShadow->
getType()),
4630 void handleAVXMaskedLoad(IntrinsicInst &
I) {
4635 Value *Src =
I.getArgOperand(0);
4636 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
4644 insertCheckShadowOf(Mask, &
I);
4647 Type *SrcShadowTy = getShadowTy(Src);
4648 Value *SrcShadowPtr, *SrcOriginPtr;
4649 std::tie(SrcShadowPtr, SrcOriginPtr) =
4650 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment,
false);
4652 SmallVector<Value *, 2> ShadowArgs;
4653 ShadowArgs.
append(1, SrcShadowPtr);
4654 ShadowArgs.
append(1, Mask);
4663 if (!MS.TrackOrigins)
4670 setOrigin(&
I, PtrSrcOrigin);
4679 assert(isFixedIntVector(Idx));
4680 auto IdxVectorSize =
4688 auto *IdxShadow = getShadow(Idx);
4693 insertCheckShadow(Truncated, getOrigin(Idx),
I);
4698 void handleAVXVpermilvar(IntrinsicInst &
I) {
4700 Value *Shadow = getShadow(&
I, 0);
4701 maskedCheckAVXIndexShadow(IRB,
I.getArgOperand(1), &
I);
4705 Shadow = IRB.
CreateBitCast(Shadow,
I.getArgOperand(0)->getType());
4707 {Shadow, I.getArgOperand(1)});
4710 setOriginForNaryOp(
I);
4715 void handleAVXVpermi2var(IntrinsicInst &
I) {
4720 [[maybe_unused]]
auto ArgVectorSize =
4723 ->getNumElements() == ArgVectorSize);
4725 ->getNumElements() == ArgVectorSize);
4726 assert(
I.getArgOperand(0)->getType() ==
I.getArgOperand(2)->getType());
4727 assert(
I.getType() ==
I.getArgOperand(0)->getType());
4728 assert(
I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4730 Value *AShadow = getShadow(&
I, 0);
4731 Value *Idx =
I.getArgOperand(1);
4732 Value *BShadow = getShadow(&
I, 2);
4734 maskedCheckAVXIndexShadow(IRB, Idx, &
I);
4738 AShadow = IRB.
CreateBitCast(AShadow,
I.getArgOperand(0)->getType());
4739 BShadow = IRB.
CreateBitCast(BShadow,
I.getArgOperand(2)->getType());
4741 {AShadow, Idx, BShadow});
4743 setOriginForNaryOp(
I);
4746 [[maybe_unused]]
static bool isFixedIntVectorTy(
const Type *
T) {
4750 [[maybe_unused]]
static bool isFixedFPVectorTy(
const Type *
T) {
4754 [[maybe_unused]]
static bool isFixedIntVector(
const Value *V) {
4755 return isFixedIntVectorTy(
V->getType());
4758 [[maybe_unused]]
static bool isFixedFPVector(
const Value *V) {
4759 return isFixedFPVectorTy(
V->getType());
4781 void handleAVX512VectorConvertFPToInt(IntrinsicInst &
I,
bool LastMask) {
4786 Value *WriteThrough;
4790 WriteThrough =
I.getOperand(2);
4791 Mask =
I.getOperand(3);
4794 WriteThrough =
I.getOperand(1);
4795 Mask =
I.getOperand(2);
4800 assert(isFixedIntVector(WriteThrough));
4802 unsigned ANumElements =
4804 [[maybe_unused]]
unsigned WriteThruNumElements =
4806 assert(ANumElements == WriteThruNumElements ||
4807 ANumElements * 2 == WriteThruNumElements);
4810 unsigned MaskNumElements =
Mask->getType()->getScalarSizeInBits();
4811 assert(ANumElements == MaskNumElements ||
4812 ANumElements * 2 == MaskNumElements);
4814 assert(WriteThruNumElements == MaskNumElements);
4818 insertCheckShadowOf(Mask, &
I);
4828 Value *AShadow = getShadow(
A);
4829 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
4831 if (ANumElements * 2 == MaskNumElements) {
4843 "_ms_mask_bitcast");
4853 getShadowTy(&
I),
"_ms_a_shadow");
4855 Value *WriteThroughShadow = getShadow(WriteThrough);
4857 "_ms_writethru_select");
4859 setShadow(&
I, Shadow);
4860 setOriginForNaryOp(
I);
4868 void handleBmiIntrinsic(IntrinsicInst &
I) {
4870 Type *ShadowTy = getShadowTy(&
I);
4873 Value *SMask = getShadow(&
I, 1);
4878 {getShadow(&I, 0), I.getOperand(1)});
4881 setOriginForNaryOp(
I);
4884 static SmallVector<int, 8> getPclmulMask(
unsigned Width,
bool OddElements) {
4885 SmallVector<int, 8>
Mask;
4886 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
4900 void handlePclmulIntrinsic(IntrinsicInst &
I) {
4905 "pclmul 3rd operand must be a constant");
4908 getPclmulMask(Width, Imm & 0x01));
4910 getPclmulMask(Width, Imm & 0x10));
4911 ShadowAndOriginCombiner SOC(
this, IRB);
4912 SOC.Add(Shuf0, getOrigin(&
I, 0));
4913 SOC.Add(Shuf1, getOrigin(&
I, 1));
4918 void handleUnarySdSsIntrinsic(IntrinsicInst &
I) {
4923 Value *Second = getShadow(&
I, 1);
4925 SmallVector<int, 16>
Mask;
4926 Mask.push_back(Width);
4927 for (
unsigned i = 1; i < Width; i++)
4931 setShadow(&
I, Shadow);
4932 setOriginForNaryOp(
I);
4935 void handleVtestIntrinsic(IntrinsicInst &
I) {
4937 Value *Shadow0 = getShadow(&
I, 0);
4938 Value *Shadow1 = getShadow(&
I, 1);
4944 setShadow(&
I, Shadow);
4945 setOriginForNaryOp(
I);
4948 void handleBinarySdSsIntrinsic(IntrinsicInst &
I) {
4953 Value *Second = getShadow(&
I, 1);
4956 SmallVector<int, 16>
Mask;
4957 Mask.push_back(Width);
4958 for (
unsigned i = 1; i < Width; i++)
4962 setShadow(&
I, Shadow);
4963 setOriginForNaryOp(
I);
4969 void handleRoundPdPsIntrinsic(IntrinsicInst &
I) {
4970 assert(
I.getArgOperand(0)->getType() ==
I.getType());
4975 ShadowAndOriginCombiner SC(
this, IRB);
4976 SC.Add(
I.getArgOperand(0));
4984 void handleAbsIntrinsic(IntrinsicInst &
I) {
4986 Value *Src =
I.getArgOperand(0);
4987 Value *IsIntMinPoison =
I.getArgOperand(1);
4989 assert(
I.getType()->isIntOrIntVectorTy());
4991 assert(Src->getType() ==
I.getType());
4997 Value *SrcShadow = getShadow(Src);
5001 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5004 Value *PoisonedShadow = getPoisonedShadow(Src);
5005 Value *PoisonedIfIntMinShadow =
5008 IRB.
CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5010 setShadow(&
I, Shadow);
5011 setOrigin(&
I, getOrigin(&
I, 0));
5014 void handleIsFpClass(IntrinsicInst &
I) {
5016 Value *Shadow = getShadow(&
I, 0);
5017 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5018 setOrigin(&
I, getOrigin(&
I, 0));
5021 void handleArithmeticWithOverflow(IntrinsicInst &
I) {
5023 Value *Shadow0 = getShadow(&
I, 0);
5024 Value *Shadow1 = getShadow(&
I, 1);
5027 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5033 setShadow(&
I, Shadow);
5034 setOriginForNaryOp(
I);
5040 Value *Shadow = getShadow(V);
5062 void handleAVX512VectorDownConvert(IntrinsicInst &
I) {
5067 Value *WriteThrough =
I.getOperand(1);
5071 assert(isFixedIntVector(WriteThrough));
5073 unsigned ANumElements =
5075 unsigned OutputNumElements =
5077 assert(ANumElements == OutputNumElements ||
5078 ANumElements * 2 == OutputNumElements);
5081 assert(
Mask->getType()->getScalarSizeInBits() == ANumElements);
5082 insertCheckShadowOf(Mask, &
I);
5093 if (ANumElements != OutputNumElements) {
5095 Mask = IRB.
CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5102 Value *AShadow = getShadow(
A);
5106 VectorType *ShadowType = maybeShrinkVectorShadowType(
A,
I);
5116 AShadow = IRB.
CreateTrunc(AShadow, ShadowType,
"_ms_trunc_shadow");
5117 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
5119 Value *WriteThroughShadow = getShadow(WriteThrough);
5122 setShadow(&
I, Shadow);
5123 setOriginForNaryOp(
I);
5157 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &
I,
5158 SmallVector<unsigned, 4> DataIndices,
5159 unsigned WriteThruIndex,
5160 unsigned MaskIndex) {
5163 unsigned NumArgs =
I.arg_size();
5165 assert(WriteThruIndex < NumArgs);
5166 assert(MaskIndex < NumArgs);
5167 assert(WriteThruIndex != MaskIndex);
5168 Value *WriteThru =
I.getOperand(WriteThruIndex);
5170 unsigned OutputNumElements =
5175 bool isData[16] = {
false};
5177 for (
unsigned i : DataIndices) {
5179 assert(i != WriteThruIndex);
5186 [[maybe_unused]]
unsigned ANumElements =
5188 assert(ANumElements == OutputNumElements);
5193 assert(isFixedFPVector(WriteThru));
5195 for (
unsigned i = 0; i < NumArgs; ++i) {
5196 if (!isData[i] && i != WriteThruIndex) {
5199 assert(
I.getOperand(i)->getType()->isIntegerTy());
5200 insertCheckShadowOf(
I.getOperand(i), &
I);
5205 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5206 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5207 assert(
Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5214 Value *DataShadow =
nullptr;
5215 for (
unsigned i : DataIndices) {
5218 DataShadow = IRB.
CreateOr(DataShadow, getShadow(
A));
5220 DataShadow = getShadow(
A);
5228 Value *WriteThruShadow = getShadow(WriteThru);
5231 setShadow(&
I, Shadow);
5233 setOriginForNaryOp(
I);
5243 void visitGenericScalarHalfwordInst(IntrinsicInst &
I) {
5249 Value *WriteThrough =
I.getOperand(2);
5256 insertCheckShadowOf(Mask, &
I);
5260 unsigned NumElements =
5262 assert(NumElements == 8);
5263 assert(
A->getType() ==
B->getType());
5265 assert(
Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5268 Value *ALowerShadow = extractLowerShadow(IRB,
A);
5269 Value *BLowerShadow = extractLowerShadow(IRB,
B);
5271 Value *ABLowerShadow = IRB.
CreateOr(ALowerShadow, BLowerShadow);
5273 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5280 Value *AShadow = getShadow(
A);
5281 Value *DstLowerShadow =
5282 IRB.
CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5284 AShadow, DstLowerShadow, ConstantInt::get(IRB.
getInt32Ty(), 0),
5287 setShadow(&
I, DstShadow);
5288 setOriginForNaryOp(
I);
5318 void handleAVXGF2P8Affine(IntrinsicInst &
I) {
5329 ->getScalarSizeInBits() == 8);
5331 assert(
A->getType() ==
X->getType());
5333 assert(
B->getType()->isIntegerTy());
5334 assert(
B->getType()->getScalarSizeInBits() == 8);
5336 assert(
I.getType() ==
A->getType());
5338 Value *AShadow = getShadow(
A);
5339 Value *XShadow = getShadow(
X);
5340 Value *BZeroShadow = getCleanShadow(
B);
5343 I.getType(),
I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5345 {X, AShadow, BZeroShadow});
5347 {XShadow, A, BZeroShadow});
5350 Value *BShadow = getShadow(
B);
5351 Value *BBroadcastShadow = getCleanShadow(AShadow);
5356 for (
unsigned i = 0; i < NumElements; i++)
5360 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5361 setOriginForNaryOp(
I);
5375 void handleNEONVectorLoad(IntrinsicInst &
I,
bool WithLane) {
5376 unsigned int numArgs =
I.arg_size();
5379 assert(
I.getType()->isStructTy());
5389 assert(4 <= numArgs && numArgs <= 6);
5403 for (
unsigned int i = 0; i < numArgs - 2; i++)
5404 ShadowArgs.
push_back(getShadow(
I.getArgOperand(i)));
5407 Value *LaneNumber =
I.getArgOperand(numArgs - 2);
5411 insertCheckShadowOf(LaneNumber, &
I);
5414 Value *Src =
I.getArgOperand(numArgs - 1);
5415 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
5417 Type *SrcShadowTy = getShadowTy(Src);
5418 auto [SrcShadowPtr, SrcOriginPtr] =
5419 getShadowOriginPtr(Src, IRB, SrcShadowTy,
Align(1),
false);
5429 if (!MS.TrackOrigins)
5433 setOrigin(&
I, PtrSrcOrigin);
5450 void handleNEONVectorStoreIntrinsic(IntrinsicInst &
I,
bool useLane) {
5454 int numArgOperands =
I.arg_size();
5457 assert(numArgOperands >= 1);
5458 Value *Addr =
I.getArgOperand(numArgOperands - 1);
5460 int skipTrailingOperands = 1;
5463 insertCheckShadowOf(Addr, &
I);
5467 skipTrailingOperands++;
5468 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
5470 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5473 SmallVector<Value *, 8> ShadowArgs;
5475 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5477 Value *Shadow = getShadow(&
I, i);
5478 ShadowArgs.
append(1, Shadow);
5495 (numArgOperands - skipTrailingOperands));
5496 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5500 I.getArgOperand(numArgOperands - skipTrailingOperands));
5502 Value *OutputShadowPtr, *OutputOriginPtr;
5504 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5505 Addr, IRB, OutputShadowTy,
Align(1),
true);
5506 ShadowArgs.
append(1, OutputShadowPtr);
5512 if (MS.TrackOrigins) {
5520 OriginCombiner OC(
this, IRB);
5521 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5522 OC.Add(
I.getArgOperand(i));
5524 const DataLayout &
DL =
F.getDataLayout();
5525 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
5587 void handleNEONMatrixMultiply(IntrinsicInst &
I) {
5591 Value *
R =
I.getArgOperand(0);
5592 Value *
A =
I.getArgOperand(1);
5593 Value *
B =
I.getArgOperand(2);
5595 assert(
I.getType() ==
R->getType());
5605 Value *ShadowR = getShadow(&
I, 0);
5606 Value *ShadowA = getShadow(&
I, 1);
5607 Value *ShadowB = getShadow(&
I, 2);
5611 FixedVectorType *ExpectedRTy =
5613 FixedVectorType *ExpectedATy =
5615 FixedVectorType *ExpectedBTy =
5622 assert(RTy == ExpectedRTy);
5623 assert(ATy == ExpectedATy);
5624 assert(BTy == ExpectedBTy);
5636 ShadowA = IRB.
CreateBitCast(ShadowA, getShadowTy(ExpectedATy));
5637 ShadowB = IRB.
CreateBitCast(ShadowB, getShadowTy(ExpectedBTy));
5648 getShadowTy(ExpectedATy));
5651 getShadowTy(ExpectedBTy));
5655 {getCleanShadow(ExpectedRTy), ShadowA, ShadowB});
5668 IRB.
CreateICmpNE(ShadowR, getCleanShadow(ExpectedRTy)), ExpectedRTy);
5670 setShadow(&
I, IRB.
CreateOr(ShadowAB, ShadowR));
5671 setOriginForNaryOp(
I);
5696 void handleIntrinsicByApplyingToShadow(IntrinsicInst &
I,
5698 unsigned int trailingVerbatimArgs) {
5701 assert(trailingVerbatimArgs <
I.arg_size());
5703 SmallVector<Value *, 8> ShadowArgs;
5705 for (
unsigned int i = 0; i <
I.arg_size() - trailingVerbatimArgs; i++) {
5706 Value *Shadow = getShadow(&
I, i);
5714 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5716 Value *Arg =
I.getArgOperand(i);
5722 Value *CombinedShadow = CI;
5725 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5728 CreateShadowCast(IRB, getShadow(&
I, i), CombinedShadow->
getType());
5729 CombinedShadow = IRB.
CreateOr(Shadow, CombinedShadow,
"_msprop");
5734 setOriginForNaryOp(
I);
5740 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &
I) {
5746 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &
I) {
5747 switch (
I.getIntrinsicID()) {
5748 case Intrinsic::uadd_with_overflow:
5749 case Intrinsic::sadd_with_overflow:
5750 case Intrinsic::usub_with_overflow:
5751 case Intrinsic::ssub_with_overflow:
5752 case Intrinsic::umul_with_overflow:
5753 case Intrinsic::smul_with_overflow:
5754 handleArithmeticWithOverflow(
I);
5756 case Intrinsic::abs:
5757 handleAbsIntrinsic(
I);
5759 case Intrinsic::bitreverse:
5760 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
5763 case Intrinsic::is_fpclass:
5766 case Intrinsic::lifetime_start:
5767 handleLifetimeStart(
I);
5769 case Intrinsic::launder_invariant_group:
5770 case Intrinsic::strip_invariant_group:
5771 handleInvariantGroup(
I);
5773 case Intrinsic::bswap:
5776 case Intrinsic::ctlz:
5777 case Intrinsic::cttz:
5778 handleCountLeadingTrailingZeros(
I);
5780 case Intrinsic::masked_compressstore:
5781 handleMaskedCompressStore(
I);
5783 case Intrinsic::masked_expandload:
5784 handleMaskedExpandLoad(
I);
5786 case Intrinsic::masked_gather:
5787 handleMaskedGather(
I);
5789 case Intrinsic::masked_scatter:
5790 handleMaskedScatter(
I);
5792 case Intrinsic::masked_store:
5793 handleMaskedStore(
I);
5795 case Intrinsic::masked_load:
5796 handleMaskedLoad(
I);
5798 case Intrinsic::vector_reduce_and:
5799 handleVectorReduceAndIntrinsic(
I);
5801 case Intrinsic::vector_reduce_or:
5802 handleVectorReduceOrIntrinsic(
I);
5805 case Intrinsic::vector_reduce_add:
5806 case Intrinsic::vector_reduce_xor:
5807 case Intrinsic::vector_reduce_mul:
5810 case Intrinsic::vector_reduce_smax:
5811 case Intrinsic::vector_reduce_smin:
5812 case Intrinsic::vector_reduce_umax:
5813 case Intrinsic::vector_reduce_umin:
5816 case Intrinsic::vector_reduce_fmax:
5817 case Intrinsic::vector_reduce_fmin:
5818 handleVectorReduceIntrinsic(
I,
false);
5821 case Intrinsic::vector_reduce_fadd:
5822 case Intrinsic::vector_reduce_fmul:
5823 handleVectorReduceWithStarterIntrinsic(
I);
5826 case Intrinsic::scmp:
5827 case Intrinsic::ucmp: {
5832 case Intrinsic::fshl:
5833 case Intrinsic::fshr:
5834 handleFunnelShift(
I);
5837 case Intrinsic::is_constant:
5839 setShadow(&
I, getCleanShadow(&
I));
5840 setOrigin(&
I, getCleanOrigin());
5850 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &
I) {
5851 switch (
I.getIntrinsicID()) {
5852 case Intrinsic::x86_sse_stmxcsr:
5855 case Intrinsic::x86_sse_ldmxcsr:
5862 case Intrinsic::x86_avx512_vcvtsd2usi64:
5863 case Intrinsic::x86_avx512_vcvtsd2usi32:
5864 case Intrinsic::x86_avx512_vcvtss2usi64:
5865 case Intrinsic::x86_avx512_vcvtss2usi32:
5866 case Intrinsic::x86_avx512_cvttss2usi64:
5867 case Intrinsic::x86_avx512_cvttss2usi:
5868 case Intrinsic::x86_avx512_cvttsd2usi64:
5869 case Intrinsic::x86_avx512_cvttsd2usi:
5870 case Intrinsic::x86_avx512_cvtusi2ss:
5871 case Intrinsic::x86_avx512_cvtusi642sd:
5872 case Intrinsic::x86_avx512_cvtusi642ss:
5873 handleSSEVectorConvertIntrinsic(
I, 1,
true);
5875 case Intrinsic::x86_sse2_cvtsd2si64:
5876 case Intrinsic::x86_sse2_cvtsd2si:
5877 case Intrinsic::x86_sse2_cvtsd2ss:
5878 case Intrinsic::x86_sse2_cvttsd2si64:
5879 case Intrinsic::x86_sse2_cvttsd2si:
5880 case Intrinsic::x86_sse_cvtss2si64:
5881 case Intrinsic::x86_sse_cvtss2si:
5882 case Intrinsic::x86_sse_cvttss2si64:
5883 case Intrinsic::x86_sse_cvttss2si:
5884 handleSSEVectorConvertIntrinsic(
I, 1);
5886 case Intrinsic::x86_sse_cvtps2pi:
5887 case Intrinsic::x86_sse_cvttps2pi:
5888 handleSSEVectorConvertIntrinsic(
I, 2);
5896 case Intrinsic::x86_vcvtps2ph_128:
5897 case Intrinsic::x86_vcvtps2ph_256: {
5898 handleSSEVectorConvertIntrinsicByProp(
I,
true);
5907 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
5908 handleAVX512VectorConvertFPToInt(
I,
false);
5913 case Intrinsic::x86_sse2_cvtpd2ps:
5914 case Intrinsic::x86_sse2_cvtps2dq:
5915 case Intrinsic::x86_sse2_cvtpd2dq:
5916 case Intrinsic::x86_sse2_cvttps2dq:
5917 case Intrinsic::x86_sse2_cvttpd2dq:
5918 case Intrinsic::x86_avx_cvt_pd2_ps_256:
5919 case Intrinsic::x86_avx_cvt_ps2dq_256:
5920 case Intrinsic::x86_avx_cvt_pd2dq_256:
5921 case Intrinsic::x86_avx_cvtt_ps2dq_256:
5922 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
5923 handleSSEVectorConvertIntrinsicByProp(
I,
false);
5934 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
5935 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
5936 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
5937 handleAVX512VectorConvertFPToInt(
I,
true);
5941 case Intrinsic::x86_avx512_psll_w_512:
5942 case Intrinsic::x86_avx512_psll_d_512:
5943 case Intrinsic::x86_avx512_psll_q_512:
5944 case Intrinsic::x86_avx512_pslli_w_512:
5945 case Intrinsic::x86_avx512_pslli_d_512:
5946 case Intrinsic::x86_avx512_pslli_q_512:
5947 case Intrinsic::x86_avx512_psrl_w_512:
5948 case Intrinsic::x86_avx512_psrl_d_512:
5949 case Intrinsic::x86_avx512_psrl_q_512:
5950 case Intrinsic::x86_avx512_psra_w_512:
5951 case Intrinsic::x86_avx512_psra_d_512:
5952 case Intrinsic::x86_avx512_psra_q_512:
5953 case Intrinsic::x86_avx512_psrli_w_512:
5954 case Intrinsic::x86_avx512_psrli_d_512:
5955 case Intrinsic::x86_avx512_psrli_q_512:
5956 case Intrinsic::x86_avx512_psrai_w_512:
5957 case Intrinsic::x86_avx512_psrai_d_512:
5958 case Intrinsic::x86_avx512_psrai_q_512:
5959 case Intrinsic::x86_avx512_psra_q_256:
5960 case Intrinsic::x86_avx512_psra_q_128:
5961 case Intrinsic::x86_avx512_psrai_q_256:
5962 case Intrinsic::x86_avx512_psrai_q_128:
5963 case Intrinsic::x86_avx2_psll_w:
5964 case Intrinsic::x86_avx2_psll_d:
5965 case Intrinsic::x86_avx2_psll_q:
5966 case Intrinsic::x86_avx2_pslli_w:
5967 case Intrinsic::x86_avx2_pslli_d:
5968 case Intrinsic::x86_avx2_pslli_q:
5969 case Intrinsic::x86_avx2_psrl_w:
5970 case Intrinsic::x86_avx2_psrl_d:
5971 case Intrinsic::x86_avx2_psrl_q:
5972 case Intrinsic::x86_avx2_psra_w:
5973 case Intrinsic::x86_avx2_psra_d:
5974 case Intrinsic::x86_avx2_psrli_w:
5975 case Intrinsic::x86_avx2_psrli_d:
5976 case Intrinsic::x86_avx2_psrli_q:
5977 case Intrinsic::x86_avx2_psrai_w:
5978 case Intrinsic::x86_avx2_psrai_d:
5979 case Intrinsic::x86_sse2_psll_w:
5980 case Intrinsic::x86_sse2_psll_d:
5981 case Intrinsic::x86_sse2_psll_q:
5982 case Intrinsic::x86_sse2_pslli_w:
5983 case Intrinsic::x86_sse2_pslli_d:
5984 case Intrinsic::x86_sse2_pslli_q:
5985 case Intrinsic::x86_sse2_psrl_w:
5986 case Intrinsic::x86_sse2_psrl_d:
5987 case Intrinsic::x86_sse2_psrl_q:
5988 case Intrinsic::x86_sse2_psra_w:
5989 case Intrinsic::x86_sse2_psra_d:
5990 case Intrinsic::x86_sse2_psrli_w:
5991 case Intrinsic::x86_sse2_psrli_d:
5992 case Intrinsic::x86_sse2_psrli_q:
5993 case Intrinsic::x86_sse2_psrai_w:
5994 case Intrinsic::x86_sse2_psrai_d:
5995 case Intrinsic::x86_mmx_psll_w:
5996 case Intrinsic::x86_mmx_psll_d:
5997 case Intrinsic::x86_mmx_psll_q:
5998 case Intrinsic::x86_mmx_pslli_w:
5999 case Intrinsic::x86_mmx_pslli_d:
6000 case Intrinsic::x86_mmx_pslli_q:
6001 case Intrinsic::x86_mmx_psrl_w:
6002 case Intrinsic::x86_mmx_psrl_d:
6003 case Intrinsic::x86_mmx_psrl_q:
6004 case Intrinsic::x86_mmx_psra_w:
6005 case Intrinsic::x86_mmx_psra_d:
6006 case Intrinsic::x86_mmx_psrli_w:
6007 case Intrinsic::x86_mmx_psrli_d:
6008 case Intrinsic::x86_mmx_psrli_q:
6009 case Intrinsic::x86_mmx_psrai_w:
6010 case Intrinsic::x86_mmx_psrai_d:
6011 handleVectorShiftIntrinsic(
I,
false);
6013 case Intrinsic::x86_avx2_psllv_d:
6014 case Intrinsic::x86_avx2_psllv_d_256:
6015 case Intrinsic::x86_avx512_psllv_d_512:
6016 case Intrinsic::x86_avx2_psllv_q:
6017 case Intrinsic::x86_avx2_psllv_q_256:
6018 case Intrinsic::x86_avx512_psllv_q_512:
6019 case Intrinsic::x86_avx2_psrlv_d:
6020 case Intrinsic::x86_avx2_psrlv_d_256:
6021 case Intrinsic::x86_avx512_psrlv_d_512:
6022 case Intrinsic::x86_avx2_psrlv_q:
6023 case Intrinsic::x86_avx2_psrlv_q_256:
6024 case Intrinsic::x86_avx512_psrlv_q_512:
6025 case Intrinsic::x86_avx2_psrav_d:
6026 case Intrinsic::x86_avx2_psrav_d_256:
6027 case Intrinsic::x86_avx512_psrav_d_512:
6028 case Intrinsic::x86_avx512_psrav_q_128:
6029 case Intrinsic::x86_avx512_psrav_q_256:
6030 case Intrinsic::x86_avx512_psrav_q_512:
6031 handleVectorShiftIntrinsic(
I,
true);
6035 case Intrinsic::x86_sse2_packsswb_128:
6036 case Intrinsic::x86_sse2_packssdw_128:
6037 case Intrinsic::x86_sse2_packuswb_128:
6038 case Intrinsic::x86_sse41_packusdw:
6039 case Intrinsic::x86_avx2_packsswb:
6040 case Intrinsic::x86_avx2_packssdw:
6041 case Intrinsic::x86_avx2_packuswb:
6042 case Intrinsic::x86_avx2_packusdw:
6048 case Intrinsic::x86_avx512_packsswb_512:
6049 case Intrinsic::x86_avx512_packssdw_512:
6050 case Intrinsic::x86_avx512_packuswb_512:
6051 case Intrinsic::x86_avx512_packusdw_512:
6052 handleVectorPackIntrinsic(
I);
6055 case Intrinsic::x86_sse41_pblendvb:
6056 case Intrinsic::x86_sse41_blendvpd:
6057 case Intrinsic::x86_sse41_blendvps:
6058 case Intrinsic::x86_avx_blendv_pd_256:
6059 case Intrinsic::x86_avx_blendv_ps_256:
6060 case Intrinsic::x86_avx2_pblendvb:
6061 handleBlendvIntrinsic(
I);
6064 case Intrinsic::x86_avx_dp_ps_256:
6065 case Intrinsic::x86_sse41_dppd:
6066 case Intrinsic::x86_sse41_dpps:
6067 handleDppIntrinsic(
I);
6070 case Intrinsic::x86_mmx_packsswb:
6071 case Intrinsic::x86_mmx_packuswb:
6072 handleVectorPackIntrinsic(
I, 16);
6075 case Intrinsic::x86_mmx_packssdw:
6076 handleVectorPackIntrinsic(
I, 32);
6079 case Intrinsic::x86_mmx_psad_bw:
6080 handleVectorSadIntrinsic(
I,
true);
6082 case Intrinsic::x86_sse2_psad_bw:
6083 case Intrinsic::x86_avx2_psad_bw:
6084 handleVectorSadIntrinsic(
I);
6110 case Intrinsic::x86_sse2_pmadd_wd:
6111 case Intrinsic::x86_avx2_pmadd_wd:
6112 case Intrinsic::x86_avx512_pmaddw_d_512:
6113 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6114 case Intrinsic::x86_avx2_pmadd_ub_sw:
6115 case Intrinsic::x86_avx512_pmaddubs_w_512:
6116 handleVectorDotProductIntrinsic(
I, 2,
6123 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6124 handleVectorDotProductIntrinsic(
I, 2,
6131 case Intrinsic::x86_mmx_pmadd_wd:
6132 handleVectorDotProductIntrinsic(
I, 2,
6141 case Intrinsic::aarch64_neon_bfmlalt:
6142 handleVectorDotProductIntrinsic(
I, 2,
6150 case Intrinsic::aarch64_neon_bfmlalb:
6151 handleVectorDotProductIntrinsic(
I, 2,
6249 case Intrinsic::x86_avx512_vpdpbusd_128:
6250 case Intrinsic::x86_avx512_vpdpbusd_256:
6251 case Intrinsic::x86_avx512_vpdpbusd_512:
6252 case Intrinsic::x86_avx512_vpdpbusds_128:
6253 case Intrinsic::x86_avx512_vpdpbusds_256:
6254 case Intrinsic::x86_avx512_vpdpbusds_512:
6255 case Intrinsic::x86_avx2_vpdpbssd_128:
6256 case Intrinsic::x86_avx2_vpdpbssd_256:
6257 case Intrinsic::x86_avx10_vpdpbssd_512:
6258 case Intrinsic::x86_avx2_vpdpbssds_128:
6259 case Intrinsic::x86_avx2_vpdpbssds_256:
6260 case Intrinsic::x86_avx10_vpdpbssds_512:
6261 case Intrinsic::x86_avx2_vpdpbsud_128:
6262 case Intrinsic::x86_avx2_vpdpbsud_256:
6263 case Intrinsic::x86_avx10_vpdpbsud_512:
6264 case Intrinsic::x86_avx2_vpdpbsuds_128:
6265 case Intrinsic::x86_avx2_vpdpbsuds_256:
6266 case Intrinsic::x86_avx10_vpdpbsuds_512:
6267 case Intrinsic::x86_avx2_vpdpbuud_128:
6268 case Intrinsic::x86_avx2_vpdpbuud_256:
6269 case Intrinsic::x86_avx10_vpdpbuud_512:
6270 case Intrinsic::x86_avx2_vpdpbuuds_128:
6271 case Intrinsic::x86_avx2_vpdpbuuds_256:
6272 case Intrinsic::x86_avx10_vpdpbuuds_512:
6273 handleVectorDotProductIntrinsic(
I, 4,
6371 case Intrinsic::x86_avx512_vpdpwssd_128:
6372 case Intrinsic::x86_avx512_vpdpwssd_256:
6373 case Intrinsic::x86_avx512_vpdpwssd_512:
6374 case Intrinsic::x86_avx512_vpdpwssds_128:
6375 case Intrinsic::x86_avx512_vpdpwssds_256:
6376 case Intrinsic::x86_avx512_vpdpwssds_512:
6377 case Intrinsic::x86_avx2_vpdpwsud_128:
6378 case Intrinsic::x86_avx2_vpdpwsud_256:
6379 case Intrinsic::x86_avx10_vpdpwsud_512:
6380 case Intrinsic::x86_avx2_vpdpwsuds_128:
6381 case Intrinsic::x86_avx2_vpdpwsuds_256:
6382 case Intrinsic::x86_avx10_vpdpwsuds_512:
6383 case Intrinsic::x86_avx2_vpdpwusd_128:
6384 case Intrinsic::x86_avx2_vpdpwusd_256:
6385 case Intrinsic::x86_avx10_vpdpwusd_512:
6386 case Intrinsic::x86_avx2_vpdpwusds_128:
6387 case Intrinsic::x86_avx2_vpdpwusds_256:
6388 case Intrinsic::x86_avx10_vpdpwusds_512:
6389 case Intrinsic::x86_avx2_vpdpwuud_128:
6390 case Intrinsic::x86_avx2_vpdpwuud_256:
6391 case Intrinsic::x86_avx10_vpdpwuud_512:
6392 case Intrinsic::x86_avx2_vpdpwuuds_128:
6393 case Intrinsic::x86_avx2_vpdpwuuds_256:
6394 case Intrinsic::x86_avx10_vpdpwuuds_512:
6395 handleVectorDotProductIntrinsic(
I, 2,
6409 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6410 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6411 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6412 handleVectorDotProductIntrinsic(
I, 2,
6418 case Intrinsic::x86_sse_cmp_ss:
6419 case Intrinsic::x86_sse2_cmp_sd:
6420 case Intrinsic::x86_sse_comieq_ss:
6421 case Intrinsic::x86_sse_comilt_ss:
6422 case Intrinsic::x86_sse_comile_ss:
6423 case Intrinsic::x86_sse_comigt_ss:
6424 case Intrinsic::x86_sse_comige_ss:
6425 case Intrinsic::x86_sse_comineq_ss:
6426 case Intrinsic::x86_sse_ucomieq_ss:
6427 case Intrinsic::x86_sse_ucomilt_ss:
6428 case Intrinsic::x86_sse_ucomile_ss:
6429 case Intrinsic::x86_sse_ucomigt_ss:
6430 case Intrinsic::x86_sse_ucomige_ss:
6431 case Intrinsic::x86_sse_ucomineq_ss:
6432 case Intrinsic::x86_sse2_comieq_sd:
6433 case Intrinsic::x86_sse2_comilt_sd:
6434 case Intrinsic::x86_sse2_comile_sd:
6435 case Intrinsic::x86_sse2_comigt_sd:
6436 case Intrinsic::x86_sse2_comige_sd:
6437 case Intrinsic::x86_sse2_comineq_sd:
6438 case Intrinsic::x86_sse2_ucomieq_sd:
6439 case Intrinsic::x86_sse2_ucomilt_sd:
6440 case Intrinsic::x86_sse2_ucomile_sd:
6441 case Intrinsic::x86_sse2_ucomigt_sd:
6442 case Intrinsic::x86_sse2_ucomige_sd:
6443 case Intrinsic::x86_sse2_ucomineq_sd:
6444 handleVectorCompareScalarIntrinsic(
I);
6447 case Intrinsic::x86_avx_cmp_pd_256:
6448 case Intrinsic::x86_avx_cmp_ps_256:
6449 case Intrinsic::x86_sse2_cmp_pd:
6450 case Intrinsic::x86_sse_cmp_ps:
6451 handleVectorComparePackedIntrinsic(
I,
true);
6454 case Intrinsic::x86_bmi_bextr_32:
6455 case Intrinsic::x86_bmi_bextr_64:
6456 case Intrinsic::x86_bmi_bzhi_32:
6457 case Intrinsic::x86_bmi_bzhi_64:
6458 case Intrinsic::x86_bmi_pdep_32:
6459 case Intrinsic::x86_bmi_pdep_64:
6460 case Intrinsic::x86_bmi_pext_32:
6461 case Intrinsic::x86_bmi_pext_64:
6462 handleBmiIntrinsic(
I);
6465 case Intrinsic::x86_pclmulqdq:
6466 case Intrinsic::x86_pclmulqdq_256:
6467 case Intrinsic::x86_pclmulqdq_512:
6468 handlePclmulIntrinsic(
I);
6471 case Intrinsic::x86_avx_round_pd_256:
6472 case Intrinsic::x86_avx_round_ps_256:
6473 case Intrinsic::x86_sse41_round_pd:
6474 case Intrinsic::x86_sse41_round_ps:
6475 handleRoundPdPsIntrinsic(
I);
6478 case Intrinsic::x86_sse41_round_sd:
6479 case Intrinsic::x86_sse41_round_ss:
6480 handleUnarySdSsIntrinsic(
I);
6483 case Intrinsic::x86_sse2_max_sd:
6484 case Intrinsic::x86_sse_max_ss:
6485 case Intrinsic::x86_sse2_min_sd:
6486 case Intrinsic::x86_sse_min_ss:
6487 handleBinarySdSsIntrinsic(
I);
6490 case Intrinsic::x86_avx_vtestc_pd:
6491 case Intrinsic::x86_avx_vtestc_pd_256:
6492 case Intrinsic::x86_avx_vtestc_ps:
6493 case Intrinsic::x86_avx_vtestc_ps_256:
6494 case Intrinsic::x86_avx_vtestnzc_pd:
6495 case Intrinsic::x86_avx_vtestnzc_pd_256:
6496 case Intrinsic::x86_avx_vtestnzc_ps:
6497 case Intrinsic::x86_avx_vtestnzc_ps_256:
6498 case Intrinsic::x86_avx_vtestz_pd:
6499 case Intrinsic::x86_avx_vtestz_pd_256:
6500 case Intrinsic::x86_avx_vtestz_ps:
6501 case Intrinsic::x86_avx_vtestz_ps_256:
6502 case Intrinsic::x86_avx_ptestc_256:
6503 case Intrinsic::x86_avx_ptestnzc_256:
6504 case Intrinsic::x86_avx_ptestz_256:
6505 case Intrinsic::x86_sse41_ptestc:
6506 case Intrinsic::x86_sse41_ptestnzc:
6507 case Intrinsic::x86_sse41_ptestz:
6508 handleVtestIntrinsic(
I);
6512 case Intrinsic::x86_ssse3_phadd_w:
6513 case Intrinsic::x86_ssse3_phadd_w_128:
6514 case Intrinsic::x86_ssse3_phsub_w:
6515 case Intrinsic::x86_ssse3_phsub_w_128:
6516 handlePairwiseShadowOrIntrinsic(
I, 1,
6520 case Intrinsic::x86_avx2_phadd_w:
6521 case Intrinsic::x86_avx2_phsub_w:
6522 handlePairwiseShadowOrIntrinsic(
I, 2,
6527 case Intrinsic::x86_ssse3_phadd_d:
6528 case Intrinsic::x86_ssse3_phadd_d_128:
6529 case Intrinsic::x86_ssse3_phsub_d:
6530 case Intrinsic::x86_ssse3_phsub_d_128:
6531 handlePairwiseShadowOrIntrinsic(
I, 1,
6535 case Intrinsic::x86_avx2_phadd_d:
6536 case Intrinsic::x86_avx2_phsub_d:
6537 handlePairwiseShadowOrIntrinsic(
I, 2,
6542 case Intrinsic::x86_ssse3_phadd_sw:
6543 case Intrinsic::x86_ssse3_phadd_sw_128:
6544 case Intrinsic::x86_ssse3_phsub_sw:
6545 case Intrinsic::x86_ssse3_phsub_sw_128:
6546 handlePairwiseShadowOrIntrinsic(
I, 1,
6550 case Intrinsic::x86_avx2_phadd_sw:
6551 case Intrinsic::x86_avx2_phsub_sw:
6552 handlePairwiseShadowOrIntrinsic(
I, 2,
6557 case Intrinsic::x86_sse3_hadd_ps:
6558 case Intrinsic::x86_sse3_hadd_pd:
6559 case Intrinsic::x86_sse3_hsub_ps:
6560 case Intrinsic::x86_sse3_hsub_pd:
6561 handlePairwiseShadowOrIntrinsic(
I, 1);
6564 case Intrinsic::x86_avx_hadd_pd_256:
6565 case Intrinsic::x86_avx_hadd_ps_256:
6566 case Intrinsic::x86_avx_hsub_pd_256:
6567 case Intrinsic::x86_avx_hsub_ps_256:
6568 handlePairwiseShadowOrIntrinsic(
I, 2);
6571 case Intrinsic::x86_avx_maskstore_ps:
6572 case Intrinsic::x86_avx_maskstore_pd:
6573 case Intrinsic::x86_avx_maskstore_ps_256:
6574 case Intrinsic::x86_avx_maskstore_pd_256:
6575 case Intrinsic::x86_avx2_maskstore_d:
6576 case Intrinsic::x86_avx2_maskstore_q:
6577 case Intrinsic::x86_avx2_maskstore_d_256:
6578 case Intrinsic::x86_avx2_maskstore_q_256: {
6579 handleAVXMaskedStore(
I);
6583 case Intrinsic::x86_avx_maskload_ps:
6584 case Intrinsic::x86_avx_maskload_pd:
6585 case Intrinsic::x86_avx_maskload_ps_256:
6586 case Intrinsic::x86_avx_maskload_pd_256:
6587 case Intrinsic::x86_avx2_maskload_d:
6588 case Intrinsic::x86_avx2_maskload_q:
6589 case Intrinsic::x86_avx2_maskload_d_256:
6590 case Intrinsic::x86_avx2_maskload_q_256: {
6591 handleAVXMaskedLoad(
I);
6596 case Intrinsic::x86_avx512fp16_add_ph_512:
6597 case Intrinsic::x86_avx512fp16_sub_ph_512:
6598 case Intrinsic::x86_avx512fp16_mul_ph_512:
6599 case Intrinsic::x86_avx512fp16_div_ph_512:
6600 case Intrinsic::x86_avx512fp16_max_ph_512:
6601 case Intrinsic::x86_avx512fp16_min_ph_512:
6602 case Intrinsic::x86_avx512_min_ps_512:
6603 case Intrinsic::x86_avx512_min_pd_512:
6604 case Intrinsic::x86_avx512_max_ps_512:
6605 case Intrinsic::x86_avx512_max_pd_512: {
6610 [[maybe_unused]]
bool Success =
6611 maybeHandleSimpleNomemIntrinsic(
I, 1);
6616 case Intrinsic::x86_avx_vpermilvar_pd:
6617 case Intrinsic::x86_avx_vpermilvar_pd_256:
6618 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6619 case Intrinsic::x86_avx_vpermilvar_ps:
6620 case Intrinsic::x86_avx_vpermilvar_ps_256:
6621 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6622 handleAVXVpermilvar(
I);
6626 case Intrinsic::x86_avx512_vpermi2var_d_128:
6627 case Intrinsic::x86_avx512_vpermi2var_d_256:
6628 case Intrinsic::x86_avx512_vpermi2var_d_512:
6629 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6630 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6631 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6632 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6633 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6634 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6635 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6636 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6637 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6638 case Intrinsic::x86_avx512_vpermi2var_q_128:
6639 case Intrinsic::x86_avx512_vpermi2var_q_256:
6640 case Intrinsic::x86_avx512_vpermi2var_q_512:
6641 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6642 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6643 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6644 handleAVXVpermi2var(
I);
6658 case Intrinsic::x86_avx2_pshuf_b:
6659 case Intrinsic::x86_sse_pshuf_w:
6660 case Intrinsic::x86_ssse3_pshuf_b_128:
6661 case Intrinsic::x86_ssse3_pshuf_b:
6662 case Intrinsic::x86_avx512_pshuf_b_512:
6663 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6669 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6670 case Intrinsic::x86_avx512_mask_pmov_db_512:
6671 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6672 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6675 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6683 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6684 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6685 handleIntrinsicByApplyingToShadow(
I,
6686 Intrinsic::x86_avx512_mask_pmov_dw_512,
6691 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6692 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6693 handleIntrinsicByApplyingToShadow(
I,
6694 Intrinsic::x86_avx512_mask_pmov_db_512,
6699 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
6700 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
6701 handleIntrinsicByApplyingToShadow(
I,
6702 Intrinsic::x86_avx512_mask_pmov_qb_512,
6707 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
6708 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
6709 handleIntrinsicByApplyingToShadow(
I,
6710 Intrinsic::x86_avx512_mask_pmov_qw_512,
6715 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
6716 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
6717 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
6718 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
6722 handleAVX512VectorDownConvert(
I);
6762 case Intrinsic::x86_avx512_rsqrt14_ps_512:
6763 case Intrinsic::x86_avx512_rsqrt14_ps_256:
6764 case Intrinsic::x86_avx512_rsqrt14_ps_128:
6765 case Intrinsic::x86_avx512_rsqrt14_pd_512:
6766 case Intrinsic::x86_avx512_rsqrt14_pd_256:
6767 case Intrinsic::x86_avx512_rsqrt14_pd_128:
6768 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
6769 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
6770 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
6771 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
6772 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
6773 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
6774 handleAVX512VectorGenericMaskedFP(
I, {0},
6815 case Intrinsic::x86_avx512_rcp14_ps_512:
6816 case Intrinsic::x86_avx512_rcp14_ps_256:
6817 case Intrinsic::x86_avx512_rcp14_ps_128:
6818 case Intrinsic::x86_avx512_rcp14_pd_512:
6819 case Intrinsic::x86_avx512_rcp14_pd_256:
6820 case Intrinsic::x86_avx512_rcp14_pd_128:
6821 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
6822 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
6823 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
6824 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
6825 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
6826 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
6827 handleAVX512VectorGenericMaskedFP(
I, {0},
6872 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
6873 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
6874 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
6875 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
6876 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
6877 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
6878 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
6879 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
6880 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
6881 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
6882 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
6883 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
6884 handleAVX512VectorGenericMaskedFP(
I, {0},
6890 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
6891 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
6892 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
6893 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
6894 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
6895 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
6896 visitGenericScalarHalfwordInst(
I);
6901 case Intrinsic::x86_vgf2p8affineqb_128:
6902 case Intrinsic::x86_vgf2p8affineqb_256:
6903 case Intrinsic::x86_vgf2p8affineqb_512:
6904 handleAVXGF2P8Affine(
I);
6914 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &
I) {
6915 switch (
I.getIntrinsicID()) {
6919 case Intrinsic::aarch64_neon_rshrn:
6920 case Intrinsic::aarch64_neon_sqrshl:
6921 case Intrinsic::aarch64_neon_sqrshrn:
6922 case Intrinsic::aarch64_neon_sqrshrun:
6923 case Intrinsic::aarch64_neon_sqshl:
6924 case Intrinsic::aarch64_neon_sqshlu:
6925 case Intrinsic::aarch64_neon_sqshrn:
6926 case Intrinsic::aarch64_neon_sqshrun:
6927 case Intrinsic::aarch64_neon_srshl:
6928 case Intrinsic::aarch64_neon_sshl:
6929 case Intrinsic::aarch64_neon_uqrshl:
6930 case Intrinsic::aarch64_neon_uqrshrn:
6931 case Intrinsic::aarch64_neon_uqshl:
6932 case Intrinsic::aarch64_neon_uqshrn:
6933 case Intrinsic::aarch64_neon_urshl:
6934 case Intrinsic::aarch64_neon_ushl:
6935 handleVectorShiftIntrinsic(
I,
false);
6948 case Intrinsic::aarch64_neon_vsli:
6949 case Intrinsic::aarch64_neon_vsri:
6950 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6956 case Intrinsic::aarch64_neon_fmaxp:
6957 case Intrinsic::aarch64_neon_fminp:
6959 case Intrinsic::aarch64_neon_fmaxnmp:
6960 case Intrinsic::aarch64_neon_fminnmp:
6962 case Intrinsic::aarch64_neon_smaxp:
6963 case Intrinsic::aarch64_neon_sminp:
6964 case Intrinsic::aarch64_neon_umaxp:
6965 case Intrinsic::aarch64_neon_uminp:
6967 case Intrinsic::aarch64_neon_addp:
6969 case Intrinsic::aarch64_neon_faddp:
6971 case Intrinsic::aarch64_neon_saddlp:
6972 case Intrinsic::aarch64_neon_uaddlp: {
6973 handlePairwiseShadowOrIntrinsic(
I, 1);
6978 case Intrinsic::aarch64_neon_fcvtas:
6979 case Intrinsic::aarch64_neon_fcvtau:
6981 case Intrinsic::aarch64_neon_fcvtms:
6982 case Intrinsic::aarch64_neon_fcvtmu:
6984 case Intrinsic::aarch64_neon_fcvtns:
6985 case Intrinsic::aarch64_neon_fcvtnu:
6987 case Intrinsic::aarch64_neon_fcvtps:
6988 case Intrinsic::aarch64_neon_fcvtpu:
6990 case Intrinsic::aarch64_neon_fcvtzs:
6991 case Intrinsic::aarch64_neon_fcvtzu:
6993 case Intrinsic::aarch64_neon_fcvtxn:
6995 case Intrinsic::aarch64_neon_vcvthf2fp:
6996 case Intrinsic::aarch64_neon_vcvtfp2hf:
6997 handleNEONVectorConvertIntrinsic(
I,
false);
7001 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7002 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7003 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7004 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7005 handleNEONVectorConvertIntrinsic(
I,
true);
7014 case Intrinsic::aarch64_neon_faddv:
7015 case Intrinsic::aarch64_neon_saddv:
7016 case Intrinsic::aarch64_neon_uaddv:
7019 case Intrinsic::aarch64_neon_smaxv:
7020 case Intrinsic::aarch64_neon_sminv:
7021 case Intrinsic::aarch64_neon_umaxv:
7022 case Intrinsic::aarch64_neon_uminv:
7026 case Intrinsic::aarch64_neon_fmaxv:
7027 case Intrinsic::aarch64_neon_fminv:
7028 case Intrinsic::aarch64_neon_fmaxnmv:
7029 case Intrinsic::aarch64_neon_fminnmv:
7031 case Intrinsic::aarch64_neon_saddlv:
7032 case Intrinsic::aarch64_neon_uaddlv:
7033 handleVectorReduceIntrinsic(
I,
true);
7036 case Intrinsic::aarch64_neon_ld1x2:
7037 case Intrinsic::aarch64_neon_ld1x3:
7038 case Intrinsic::aarch64_neon_ld1x4:
7039 case Intrinsic::aarch64_neon_ld2:
7040 case Intrinsic::aarch64_neon_ld3:
7041 case Intrinsic::aarch64_neon_ld4:
7042 case Intrinsic::aarch64_neon_ld2r:
7043 case Intrinsic::aarch64_neon_ld3r:
7044 case Intrinsic::aarch64_neon_ld4r: {
7045 handleNEONVectorLoad(
I,
false);
7049 case Intrinsic::aarch64_neon_ld2lane:
7050 case Intrinsic::aarch64_neon_ld3lane:
7051 case Intrinsic::aarch64_neon_ld4lane: {
7052 handleNEONVectorLoad(
I,
true);
7057 case Intrinsic::aarch64_neon_sqxtn:
7058 case Intrinsic::aarch64_neon_sqxtun:
7059 case Intrinsic::aarch64_neon_uqxtn:
7066 case Intrinsic::aarch64_neon_st1x2:
7067 case Intrinsic::aarch64_neon_st1x3:
7068 case Intrinsic::aarch64_neon_st1x4:
7069 case Intrinsic::aarch64_neon_st2:
7070 case Intrinsic::aarch64_neon_st3:
7071 case Intrinsic::aarch64_neon_st4: {
7072 handleNEONVectorStoreIntrinsic(
I,
false);
7076 case Intrinsic::aarch64_neon_st2lane:
7077 case Intrinsic::aarch64_neon_st3lane:
7078 case Intrinsic::aarch64_neon_st4lane: {
7079 handleNEONVectorStoreIntrinsic(
I,
true);
7092 case Intrinsic::aarch64_neon_tbl1:
7093 case Intrinsic::aarch64_neon_tbl2:
7094 case Intrinsic::aarch64_neon_tbl3:
7095 case Intrinsic::aarch64_neon_tbl4:
7096 case Intrinsic::aarch64_neon_tbx1:
7097 case Intrinsic::aarch64_neon_tbx2:
7098 case Intrinsic::aarch64_neon_tbx3:
7099 case Intrinsic::aarch64_neon_tbx4: {
7101 handleIntrinsicByApplyingToShadow(
7102 I,
I.getIntrinsicID(),
7107 case Intrinsic::aarch64_neon_fmulx:
7108 case Intrinsic::aarch64_neon_pmul:
7109 case Intrinsic::aarch64_neon_pmull:
7110 case Intrinsic::aarch64_neon_smull:
7111 case Intrinsic::aarch64_neon_pmull64:
7112 case Intrinsic::aarch64_neon_umull: {
7113 handleNEONVectorMultiplyIntrinsic(
I);
7117 case Intrinsic::aarch64_neon_smmla:
7118 case Intrinsic::aarch64_neon_ummla:
7119 case Intrinsic::aarch64_neon_usmmla:
7120 case Intrinsic::aarch64_neon_bfmmla:
7121 handleNEONMatrixMultiply(
I);
7128 case Intrinsic::aarch64_neon_sdot:
7129 case Intrinsic::aarch64_neon_udot:
7130 case Intrinsic::aarch64_neon_usdot:
7131 handleVectorDotProductIntrinsic(
I, 4,
7141 case Intrinsic::aarch64_neon_bfdot:
7142 handleVectorDotProductIntrinsic(
I, 2,
7149 case Intrinsic::aarch64_neon_facge:
7150 case Intrinsic::aarch64_neon_facgt:
7151 handleVectorComparePackedIntrinsic(
I,
false);
7161 void visitIntrinsicInst(IntrinsicInst &
I) {
7162 if (maybeHandleCrossPlatformIntrinsic(
I))
7165 if (maybeHandleX86SIMDIntrinsic(
I))
7168 if (maybeHandleArmSIMDIntrinsic(
I))
7171 if (maybeHandleUnknownIntrinsic(
I))
7174 visitInstruction(
I);
7177 void visitLibAtomicLoad(CallBase &CB) {
7188 Value *NewOrdering =
7192 NextNodeIRBuilder NextIRB(&CB);
7193 Value *SrcShadowPtr, *SrcOriginPtr;
7194 std::tie(SrcShadowPtr, SrcOriginPtr) =
7195 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7197 Value *DstShadowPtr =
7198 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7202 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
7203 if (MS.TrackOrigins) {
7204 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7206 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7207 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7211 void visitLibAtomicStore(CallBase &CB) {
7218 Value *NewOrdering =
7222 Value *DstShadowPtr =
7232 void visitCallBase(CallBase &CB) {
7240 visitAsmInstruction(CB);
7242 visitInstruction(CB);
7251 case LibFunc_atomic_load:
7253 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
7257 visitLibAtomicLoad(CB);
7259 case LibFunc_atomic_store:
7260 visitLibAtomicStore(CB);
7276 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7280 Func->removeFnAttrs(
B);
7286 bool MayCheckCall = MS.EagerChecks;
7290 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
7293 unsigned ArgOffset = 0;
7296 if (!
A->getType()->isSized()) {
7297 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
7301 if (
A->getType()->isScalableTy()) {
7302 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
7304 insertCheckShadowOf(
A, &CB);
7309 const DataLayout &
DL =
F.getDataLayout();
7313 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7316 insertCheckShadowOf(
A, &CB);
7317 Size =
DL.getTypeAllocSize(
A->getType());
7323 Value *ArgShadow = getShadow(
A);
7324 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7326 <<
" Shadow: " << *ArgShadow <<
"\n");
7330 assert(
A->getType()->isPointerTy() &&
7331 "ByVal argument is not a pointer!");
7336 MaybeAlign Alignment = std::nullopt;
7339 Value *AShadowPtr, *AOriginPtr;
7340 std::tie(AShadowPtr, AOriginPtr) =
7341 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
7343 if (!PropagateShadow) {
7350 if (MS.TrackOrigins) {
7351 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7365 Size =
DL.getTypeAllocSize(
A->getType());
7371 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
7373 getOriginPtrForArgument(IRB, ArgOffset));
7376 assert(Store !=
nullptr);
7385 if (FT->isVarArg()) {
7386 VAHelper->visitCallBase(CB, IRB);
7396 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
7397 setShadow(&CB, getCleanShadow(&CB));
7398 setOrigin(&CB, getCleanOrigin());
7404 Value *
Base = getShadowPtrForRetval(IRBBefore);
7405 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
7417 setShadow(&CB, getCleanShadow(&CB));
7418 setOrigin(&CB, getCleanOrigin());
7425 "Could not find insertion point for retval shadow load");
7428 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7431 setShadow(&CB, RetvalShadow);
7432 if (MS.TrackOrigins)
7433 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7438 RetVal =
I->getOperand(0);
7441 return I->isMustTailCall();
7446 void visitReturnInst(ReturnInst &
I) {
7448 Value *RetVal =
I.getReturnValue();
7454 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7455 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
7456 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7459 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
7461 Value *Shadow = getShadow(RetVal);
7462 bool StoreOrigin =
true;
7464 insertCheckShadowOf(RetVal, &
I);
7465 Shadow = getCleanShadow(RetVal);
7466 StoreOrigin =
false;
7473 if (MS.TrackOrigins && StoreOrigin)
7474 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7478 void visitPHINode(PHINode &
I) {
7480 if (!PropagateShadow) {
7481 setShadow(&
I, getCleanShadow(&
I));
7482 setOrigin(&
I, getCleanOrigin());
7486 ShadowPHINodes.push_back(&
I);
7487 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
7489 if (MS.TrackOrigins)
7491 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
7494 Value *getLocalVarIdptr(AllocaInst &
I) {
7495 ConstantInt *IntConst =
7496 ConstantInt::get(Type::getInt32Ty((*
F.getParent()).getContext()), 0);
7497 return new GlobalVariable(*
F.getParent(), IntConst->
getType(),
7502 Value *getLocalVarDescription(AllocaInst &
I) {
7508 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7510 Value *ShadowBase, *OriginBase;
7511 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7515 IRB.
CreateMemSet(ShadowBase, PoisonValue, Len,
I.getAlign());
7518 if (PoisonStack && MS.TrackOrigins) {
7519 Value *Idptr = getLocalVarIdptr(
I);
7521 Value *Descr = getLocalVarDescription(
I);
7522 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
7523 {&I, Len, Idptr, Descr});
7525 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
7531 Value *Descr = getLocalVarDescription(
I);
7533 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
7535 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
7539 void instrumentAlloca(AllocaInst &
I, Instruction *InsPoint =
nullptr) {
7542 NextNodeIRBuilder IRB(InsPoint);
7545 if (MS.CompileKernel)
7546 poisonAllocaKmsan(
I, IRB, Len);
7548 poisonAllocaUserspace(
I, IRB, Len);
7551 void visitAllocaInst(AllocaInst &
I) {
7552 setShadow(&
I, getCleanShadow(&
I));
7553 setOrigin(&
I, getCleanOrigin());
7559 void visitSelectInst(SelectInst &
I) {
7565 handleSelectLikeInst(
I,
B,
C,
D);
7571 Value *Sb = getShadow(
B);
7572 Value *Sc = getShadow(
C);
7573 Value *Sd = getShadow(
D);
7575 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
7576 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
7577 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
7582 if (
I.getType()->isAggregateType()) {
7586 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
7587 }
else if (isScalableNonVectorType(
I.getType())) {
7595 Sa1 = getCleanShadow(getShadowTy(
I.getType()));
7603 C = CreateAppToShadowCast(IRB,
C);
7604 D = CreateAppToShadowCast(IRB,
D);
7611 if (MS.TrackOrigins) {
7614 if (
B->getType()->isVectorTy()) {
7615 B = convertToBool(
B, IRB);
7616 Sb = convertToBool(Sb, IRB);
7624 void visitLandingPadInst(LandingPadInst &
I) {
7627 setShadow(&
I, getCleanShadow(&
I));
7628 setOrigin(&
I, getCleanOrigin());
7631 void visitCatchSwitchInst(CatchSwitchInst &
I) {
7632 setShadow(&
I, getCleanShadow(&
I));
7633 setOrigin(&
I, getCleanOrigin());
7636 void visitFuncletPadInst(FuncletPadInst &
I) {
7637 setShadow(&
I, getCleanShadow(&
I));
7638 setOrigin(&
I, getCleanOrigin());
7641 void visitGetElementPtrInst(GetElementPtrInst &
I) { handleShadowOr(
I); }
7643 void visitExtractValueInst(ExtractValueInst &
I) {
7645 Value *Agg =
I.getAggregateOperand();
7647 Value *AggShadow = getShadow(Agg);
7651 setShadow(&
I, ResShadow);
7652 setOriginForNaryOp(
I);
7655 void visitInsertValueInst(InsertValueInst &
I) {
7658 Value *AggShadow = getShadow(
I.getAggregateOperand());
7659 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
7665 setOriginForNaryOp(
I);
7668 void dumpInst(Instruction &
I) {
7676 errs() <<
"ZZZ " <<
I.getOpcodeName() <<
"\n";
7683 unsigned NumOperands =
I.getNumOperands();
7685 errs() <<
"YYY call " << *
I.getType() <<
" @";
7697 errs() <<
"YYY " << *
I.getType() <<
" " <<
I.getOpcodeName() <<
"(";
7699 for (
size_t i = 0; i < NumOperands; i++) {
7714 errs() <<
"QQQ " <<
I <<
"\n";
7717 void visitResumeInst(ResumeInst &
I) {
7722 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
7727 void visitCatchReturnInst(CatchReturnInst &CRI) {
7732 void instrumentAsmArgument(
Value *Operand,
Type *ElemTy, Instruction &
I,
7741 insertCheckShadowOf(Operand, &
I);
7748 auto Size =
DL.getTypeStoreSize(ElemTy);
7750 if (MS.CompileKernel) {
7751 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
7757 auto [ShadowPtr,
_] =
7758 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
7768 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
7769 int NumRetOutputs = 0;
7776 NumRetOutputs =
ST->getNumElements();
7781 for (
const InlineAsm::ConstraintInfo &Info : Constraints) {
7782 switch (
Info.Type) {
7790 return NumOutputs - NumRetOutputs;
7793 void visitAsmInstruction(Instruction &
I) {
7809 const DataLayout &
DL =
F.getDataLayout();
7813 int OutputArgs = getNumOutputArgs(IA, CB);
7819 for (
int i = OutputArgs; i < NumOperands; i++) {
7827 for (
int i = 0; i < OutputArgs; i++) {
7833 setShadow(&
I, getCleanShadow(&
I));
7834 setOrigin(&
I, getCleanOrigin());
7837 void visitFreezeInst(FreezeInst &
I) {
7839 setShadow(&
I, getCleanShadow(&
I));
7840 setOrigin(&
I, getCleanOrigin());
7843 void visitInstruction(Instruction &
I) {
7848 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
7849 Value *Operand =
I.getOperand(i);
7851 insertCheckShadowOf(Operand, &
I);
7853 setShadow(&
I, getCleanShadow(&
I));
7854 setOrigin(&
I, getCleanOrigin());
7858struct VarArgHelperBase :
public VarArgHelper {
7860 MemorySanitizer &MS;
7861 MemorySanitizerVisitor &MSV;
7863 const unsigned VAListTagSize;
7865 VarArgHelperBase(Function &
F, MemorySanitizer &MS,
7866 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
7867 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
7871 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
7877 MS.VAArgTLS, ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg_va_s");
7886 return getShadowPtrForVAArgument(IRB, ArgOffset);
7895 ConstantInt::get(MS.IntptrTy, ArgOffset),
7900 unsigned BaseOffset) {
7909 TailSize,
Align(8));
7912 void unpoisonVAListTagForInst(IntrinsicInst &
I) {
7914 Value *VAListTag =
I.getArgOperand(0);
7916 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
7917 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
7920 VAListTagSize, Alignment,
false);
7923 void visitVAStartInst(VAStartInst &
I)
override {
7924 if (
F.getCallingConv() == CallingConv::Win64)
7927 unpoisonVAListTagForInst(
I);
7930 void visitVACopyInst(VACopyInst &
I)
override {
7931 if (
F.getCallingConv() == CallingConv::Win64)
7933 unpoisonVAListTagForInst(
I);
7938struct VarArgAMD64Helper :
public VarArgHelperBase {
7941 static const unsigned AMD64GpEndOffset = 48;
7942 static const unsigned AMD64FpEndOffsetSSE = 176;
7944 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
7946 unsigned AMD64FpEndOffset;
7947 AllocaInst *VAArgTLSCopy =
nullptr;
7948 AllocaInst *VAArgTLSOriginCopy =
nullptr;
7949 Value *VAArgOverflowSize =
nullptr;
7951 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
7953 VarArgAMD64Helper(Function &
F, MemorySanitizer &MS,
7954 MemorySanitizerVisitor &MSV)
7955 : VarArgHelperBase(
F, MS, MSV, 24) {
7956 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
7957 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
7958 if (Attr.isStringAttribute() &&
7959 (Attr.getKindAsString() ==
"target-features")) {
7960 if (Attr.getValueAsString().contains(
"-sse"))
7961 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
7967 ArgKind classifyArgument(
Value *arg) {
7970 if (
T->isX86_FP80Ty())
7972 if (
T->isFPOrFPVectorTy())
7973 return AK_FloatingPoint;
7974 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
7975 return AK_GeneralPurpose;
7976 if (
T->isPointerTy())
7977 return AK_GeneralPurpose;
7989 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
7990 unsigned GpOffset = 0;
7991 unsigned FpOffset = AMD64GpEndOffset;
7992 unsigned OverflowOffset = AMD64FpEndOffset;
7993 const DataLayout &
DL =
F.getDataLayout();
7997 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
8004 assert(
A->getType()->isPointerTy());
8006 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8007 uint64_t AlignedSize =
alignTo(ArgSize, 8);
8008 unsigned BaseOffset = OverflowOffset;
8009 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8010 Value *OriginBase =
nullptr;
8011 if (MS.TrackOrigins)
8012 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8013 OverflowOffset += AlignedSize;
8016 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8020 Value *ShadowPtr, *OriginPtr;
8021 std::tie(ShadowPtr, OriginPtr) =
8026 if (MS.TrackOrigins)
8030 ArgKind AK = classifyArgument(
A);
8031 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8033 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8035 Value *ShadowBase, *OriginBase =
nullptr;
8037 case AK_GeneralPurpose:
8038 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8039 if (MS.TrackOrigins)
8040 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8044 case AK_FloatingPoint:
8045 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8046 if (MS.TrackOrigins)
8047 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8054 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8055 uint64_t AlignedSize =
alignTo(ArgSize, 8);
8056 unsigned BaseOffset = OverflowOffset;
8057 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8058 if (MS.TrackOrigins) {
8059 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8061 OverflowOffset += AlignedSize;
8064 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8073 Value *Shadow = MSV.getShadow(
A);
8075 if (MS.TrackOrigins) {
8076 Value *Origin = MSV.getOrigin(
A);
8077 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8078 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8084 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8085 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8088 void finalizeInstrumentation()
override {
8089 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8090 "finalizeInstrumentation called twice");
8091 if (!VAStartInstrumentationList.
empty()) {
8098 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8099 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8105 Intrinsic::umin, CopySize,
8109 if (MS.TrackOrigins) {
8110 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8119 for (CallInst *OrigInst : VAStartInstrumentationList) {
8120 NextNodeIRBuilder IRB(OrigInst);
8121 Value *VAListTag = OrigInst->getArgOperand(0);
8123 Value *RegSaveAreaPtrPtr =
8124 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 16));
8126 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8128 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8129 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8131 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8133 if (MS.TrackOrigins)
8134 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8135 Alignment, AMD64FpEndOffset);
8136 Value *OverflowArgAreaPtrPtr =
8137 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 8));
8138 Value *OverflowArgAreaPtr =
8139 IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8140 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8141 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8142 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8146 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8148 if (MS.TrackOrigins) {
8151 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8159struct VarArgAArch64Helper :
public VarArgHelperBase {
8160 static const unsigned kAArch64GrArgSize = 64;
8161 static const unsigned kAArch64VrArgSize = 128;
8163 static const unsigned AArch64GrBegOffset = 0;
8164 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8166 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8167 static const unsigned AArch64VrEndOffset =
8168 AArch64VrBegOffset + kAArch64VrArgSize;
8169 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8171 AllocaInst *VAArgTLSCopy =
nullptr;
8172 Value *VAArgOverflowSize =
nullptr;
8174 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8176 VarArgAArch64Helper(Function &
F, MemorySanitizer &MS,
8177 MemorySanitizerVisitor &MSV)
8178 : VarArgHelperBase(
F, MS, MSV, 32) {}
8181 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
8182 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
8183 return {AK_GeneralPurpose, 1};
8184 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
8185 return {AK_FloatingPoint, 1};
8187 if (
T->isArrayTy()) {
8188 auto R = classifyArgument(
T->getArrayElementType());
8189 R.second *=
T->getScalarType()->getArrayNumElements();
8194 auto R = classifyArgument(FV->getScalarType());
8195 R.second *= FV->getNumElements();
8200 return {AK_Memory, 0};
8212 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8213 unsigned GrOffset = AArch64GrBegOffset;
8214 unsigned VrOffset = AArch64VrBegOffset;
8215 unsigned OverflowOffset = AArch64VAEndOffset;
8217 const DataLayout &
DL =
F.getDataLayout();
8220 auto [AK, RegNum] = classifyArgument(
A->getType());
8221 if (AK == AK_GeneralPurpose &&
8222 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8224 if (AK == AK_FloatingPoint &&
8225 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8229 case AK_GeneralPurpose:
8230 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8231 GrOffset += 8 * RegNum;
8233 case AK_FloatingPoint:
8234 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8235 VrOffset += 16 * RegNum;
8242 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8243 uint64_t AlignedSize =
alignTo(ArgSize, 8);
8244 unsigned BaseOffset = OverflowOffset;
8245 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8246 OverflowOffset += AlignedSize;
8249 CleanUnusedTLS(IRB,
Base, BaseOffset);
8261 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8262 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8267 Value *SaveAreaPtrPtr =
8268 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8269 return IRB.
CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8274 Value *SaveAreaPtr =
8275 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8277 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
8280 void finalizeInstrumentation()
override {
8281 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8282 "finalizeInstrumentation called twice");
8283 if (!VAStartInstrumentationList.empty()) {
8290 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8291 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8297 Intrinsic::umin, CopySize,
8303 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8304 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8308 for (CallInst *OrigInst : VAStartInstrumentationList) {
8309 NextNodeIRBuilder IRB(OrigInst);
8311 Value *VAListTag = OrigInst->getArgOperand(0);
8328 Value *StackSaveAreaPtr =
8329 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8332 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8333 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8336 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8339 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8340 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8343 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8349 Value *GrRegSaveAreaShadowPtrOff =
8350 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
8352 Value *GrRegSaveAreaShadowPtr =
8353 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8359 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8365 Value *VrRegSaveAreaShadowPtrOff =
8366 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
8368 Value *VrRegSaveAreaShadowPtr =
8369 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8376 VrRegSaveAreaShadowPtrOff);
8377 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8383 Value *StackSaveAreaShadowPtr =
8384 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8389 VAArgTLSCopy, IRB.
getInt32(AArch64VAEndOffset));
8392 Align(16), VAArgOverflowSize);
8398struct VarArgPowerPC64Helper :
public VarArgHelperBase {
8399 AllocaInst *VAArgTLSCopy =
nullptr;
8400 Value *VAArgSize =
nullptr;
8402 VarArgPowerPC64Helper(Function &
F, MemorySanitizer &MS,
8403 MemorySanitizerVisitor &MSV)
8404 : VarArgHelperBase(
F, MS, MSV, 8) {}
8406 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8414 Triple TargetTriple(
F.getParent()->getTargetTriple());
8418 if (TargetTriple.isPPC64ELFv2ABI())
8422 unsigned VAArgOffset = VAArgBase;
8423 const DataLayout &
DL =
F.getDataLayout();
8426 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
8428 assert(
A->getType()->isPointerTy());
8430 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8433 ArgAlign =
Align(8);
8434 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8437 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8439 Value *AShadowPtr, *AOriginPtr;
8440 std::tie(AShadowPtr, AOriginPtr) =
8441 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8451 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8453 if (
A->getType()->isArrayTy()) {
8456 Type *ElementTy =
A->getType()->getArrayElementType();
8458 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8459 }
else if (
A->getType()->isVectorTy()) {
8461 ArgAlign =
Align(ArgSize);
8464 ArgAlign =
Align(8);
8465 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8466 if (
DL.isBigEndian()) {
8470 VAArgOffset += (8 - ArgSize);
8474 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8478 VAArgOffset += ArgSize;
8482 VAArgBase = VAArgOffset;
8486 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8489 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8492 void finalizeInstrumentation()
override {
8493 assert(!VAArgSize && !VAArgTLSCopy &&
8494 "finalizeInstrumentation called twice");
8497 Value *CopySize = VAArgSize;
8499 if (!VAStartInstrumentationList.empty()) {
8503 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8509 Intrinsic::umin, CopySize,
8517 for (CallInst *OrigInst : VAStartInstrumentationList) {
8518 NextNodeIRBuilder IRB(OrigInst);
8519 Value *VAListTag = OrigInst->getArgOperand(0);
8522 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8525 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8526 const DataLayout &
DL =
F.getDataLayout();
8527 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8529 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8530 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8532 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8539struct VarArgPowerPC32Helper :
public VarArgHelperBase {
8540 AllocaInst *VAArgTLSCopy =
nullptr;
8541 Value *VAArgSize =
nullptr;
8543 VarArgPowerPC32Helper(Function &
F, MemorySanitizer &MS,
8544 MemorySanitizerVisitor &MSV)
8545 : VarArgHelperBase(
F, MS, MSV, 12) {}
8547 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8551 unsigned VAArgOffset = VAArgBase;
8552 const DataLayout &
DL =
F.getDataLayout();
8553 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8556 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
8558 assert(
A->getType()->isPointerTy());
8560 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8562 if (ArgAlign < IntptrSize)
8563 ArgAlign =
Align(IntptrSize);
8564 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8567 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8569 Value *AShadowPtr, *AOriginPtr;
8570 std::tie(AShadowPtr, AOriginPtr) =
8571 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8581 Type *ArgTy =
A->getType();
8587 uint64_t ArgSize =
DL.getTypeAllocSize(ArgTy);
8594 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8597 ArgAlign =
Align(ArgSize);
8599 if (ArgAlign < IntptrSize)
8600 ArgAlign =
Align(IntptrSize);
8601 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8602 if (
DL.isBigEndian()) {
8605 if (ArgSize < IntptrSize)
8606 VAArgOffset += (IntptrSize - ArgSize);
8609 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
8615 VAArgOffset += ArgSize;
8622 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8625 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8628 void finalizeInstrumentation()
override {
8629 assert(!VAArgSize && !VAArgTLSCopy &&
8630 "finalizeInstrumentation called twice");
8632 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
8633 Value *CopySize = VAArgSize;
8635 if (!VAStartInstrumentationList.empty()) {
8639 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8645 Intrinsic::umin, CopySize,
8653 for (CallInst *OrigInst : VAStartInstrumentationList) {
8654 NextNodeIRBuilder IRB(OrigInst);
8655 Value *VAListTag = OrigInst->getArgOperand(0);
8657 Value *RegSaveAreaSize = CopySize;
8661 IRB.
CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
8665 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
8667 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8670 const DataLayout &
DL =
F.getDataLayout();
8671 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8675 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8676 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8677 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8679 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
8680 Alignment, RegSaveAreaSize);
8682 RegSaveAreaShadowPtr =
8685 ConstantInt::get(MS.IntptrTy, 32));
8690 ConstantInt::get(MS.IntptrTy, 32), Alignment);
8695 Value *OverflowAreaSize = IRB.
CreateSub(CopySize, RegSaveAreaSize);
8698 OverflowAreaPtrPtr =
8699 IRB.
CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
8700 OverflowAreaPtrPtr = IRB.
CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
8702 Value *OverflowAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
8704 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
8705 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
8706 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.
getInt8Ty(),
8709 Value *OverflowVAArgTLSCopyPtr =
8711 OverflowVAArgTLSCopyPtr =
8712 IRB.
CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
8714 OverflowVAArgTLSCopyPtr =
8717 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
8724struct VarArgSystemZHelper :
public VarArgHelperBase {
8725 static const unsigned SystemZGpOffset = 16;
8726 static const unsigned SystemZGpEndOffset = 56;
8727 static const unsigned SystemZFpOffset = 128;
8728 static const unsigned SystemZFpEndOffset = 160;
8729 static const unsigned SystemZMaxVrArgs = 8;
8730 static const unsigned SystemZRegSaveAreaSize = 160;
8731 static const unsigned SystemZOverflowOffset = 160;
8732 static const unsigned SystemZVAListTagSize = 32;
8733 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
8734 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
8736 bool IsSoftFloatABI;
8737 AllocaInst *VAArgTLSCopy =
nullptr;
8738 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8739 Value *VAArgOverflowSize =
nullptr;
8741 enum class ArgKind {
8749 enum class ShadowExtension {
None,
Zero, Sign };
8751 VarArgSystemZHelper(Function &
F, MemorySanitizer &MS,
8752 MemorySanitizerVisitor &MSV)
8753 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
8754 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
8756 ArgKind classifyArgument(
Type *
T) {
8763 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
8764 return ArgKind::Indirect;
8765 if (
T->isFloatingPointTy())
8766 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
8767 if (
T->isIntegerTy() ||
T->isPointerTy())
8768 return ArgKind::GeneralPurpose;
8769 if (
T->isVectorTy())
8770 return ArgKind::Vector;
8771 return ArgKind::Memory;
8774 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
8784 return ShadowExtension::Zero;
8788 return ShadowExtension::Sign;
8790 return ShadowExtension::None;
8793 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8794 unsigned GpOffset = SystemZGpOffset;
8795 unsigned FpOffset = SystemZFpOffset;
8796 unsigned VrIndex = 0;
8797 unsigned OverflowOffset = SystemZOverflowOffset;
8798 const DataLayout &
DL =
F.getDataLayout();
8804 ArgKind AK = classifyArgument(
T);
8805 if (AK == ArgKind::Indirect) {
8807 AK = ArgKind::GeneralPurpose;
8809 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
8810 AK = ArgKind::Memory;
8811 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
8812 AK = ArgKind::Memory;
8813 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
8814 AK = ArgKind::Memory;
8815 Value *ShadowBase =
nullptr;
8816 Value *OriginBase =
nullptr;
8817 ShadowExtension SE = ShadowExtension::None;
8819 case ArgKind::GeneralPurpose: {
8821 uint64_t ArgSize = 8;
8824 SE = getShadowExtension(CB, ArgNo);
8825 uint64_t GapSize = 0;
8826 if (SE == ShadowExtension::None) {
8827 uint64_t ArgAllocSize =
DL.getTypeAllocSize(
T);
8828 assert(ArgAllocSize <= ArgSize);
8829 GapSize = ArgSize - ArgAllocSize;
8831 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
8832 if (MS.TrackOrigins)
8833 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
8835 GpOffset += ArgSize;
8841 case ArgKind::FloatingPoint: {
8843 uint64_t ArgSize = 8;
8850 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
8851 if (MS.TrackOrigins)
8852 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8854 FpOffset += ArgSize;
8860 case ArgKind::Vector: {
8867 case ArgKind::Memory: {
8872 uint64_t ArgAllocSize =
DL.getTypeAllocSize(
T);
8873 uint64_t ArgSize =
alignTo(ArgAllocSize, 8);
8875 SE = getShadowExtension(CB, ArgNo);
8877 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
8879 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
8880 if (MS.TrackOrigins)
8882 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
8883 OverflowOffset += ArgSize;
8890 case ArgKind::Indirect:
8893 if (ShadowBase ==
nullptr)
8895 Value *Shadow = MSV.getShadow(
A);
8896 if (SE != ShadowExtension::None)
8897 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
8898 SE == ShadowExtension::Sign);
8899 ShadowBase = IRB.
CreateIntToPtr(ShadowBase, MS.PtrTy,
"_msarg_va_s");
8901 if (MS.TrackOrigins) {
8902 Value *Origin = MSV.getOrigin(
A);
8903 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8904 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8908 Constant *OverflowSize = ConstantInt::get(
8909 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
8910 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8917 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
8920 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8922 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8923 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
8928 unsigned RegSaveAreaSize =
8929 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
8930 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8932 if (MS.TrackOrigins)
8933 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8934 Alignment, RegSaveAreaSize);
8943 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
8945 Value *OverflowArgAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8946 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8948 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8949 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8952 SystemZOverflowOffset);
8953 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8955 if (MS.TrackOrigins) {
8957 SystemZOverflowOffset);
8958 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8963 void finalizeInstrumentation()
override {
8964 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8965 "finalizeInstrumentation called twice");
8966 if (!VAStartInstrumentationList.empty()) {
8973 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
8975 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8981 Intrinsic::umin, CopySize,
8985 if (MS.TrackOrigins) {
8986 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8995 for (CallInst *OrigInst : VAStartInstrumentationList) {
8996 NextNodeIRBuilder IRB(OrigInst);
8997 Value *VAListTag = OrigInst->getArgOperand(0);
8998 copyRegSaveArea(IRB, VAListTag);
8999 copyOverflowArea(IRB, VAListTag);
9005struct VarArgI386Helper :
public VarArgHelperBase {
9006 AllocaInst *VAArgTLSCopy =
nullptr;
9007 Value *VAArgSize =
nullptr;
9009 VarArgI386Helper(Function &
F, MemorySanitizer &MS,
9010 MemorySanitizerVisitor &MSV)
9011 : VarArgHelperBase(
F, MS, MSV, 4) {}
9013 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9014 const DataLayout &
DL =
F.getDataLayout();
9015 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9016 unsigned VAArgOffset = 0;
9019 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
9021 assert(
A->getType()->isPointerTy());
9023 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9025 if (ArgAlign < IntptrSize)
9026 ArgAlign =
Align(IntptrSize);
9027 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9029 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9031 Value *AShadowPtr, *AOriginPtr;
9032 std::tie(AShadowPtr, AOriginPtr) =
9033 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9043 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9045 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9046 if (
DL.isBigEndian()) {
9049 if (ArgSize < IntptrSize)
9050 VAArgOffset += (IntptrSize - ArgSize);
9053 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9056 VAArgOffset += ArgSize;
9062 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9065 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9068 void finalizeInstrumentation()
override {
9069 assert(!VAArgSize && !VAArgTLSCopy &&
9070 "finalizeInstrumentation called twice");
9072 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9073 Value *CopySize = VAArgSize;
9075 if (!VAStartInstrumentationList.empty()) {
9078 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9084 Intrinsic::umin, CopySize,
9092 for (CallInst *OrigInst : VAStartInstrumentationList) {
9093 NextNodeIRBuilder IRB(OrigInst);
9094 Value *VAListTag = OrigInst->getArgOperand(0);
9095 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9096 Value *RegSaveAreaPtrPtr =
9098 PointerType::get(*MS.C, 0));
9099 Value *RegSaveAreaPtr =
9100 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9101 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9102 const DataLayout &
DL =
F.getDataLayout();
9103 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9105 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9106 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9108 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9116struct VarArgGenericHelper :
public VarArgHelperBase {
9117 AllocaInst *VAArgTLSCopy =
nullptr;
9118 Value *VAArgSize =
nullptr;
9120 VarArgGenericHelper(Function &
F, MemorySanitizer &MS,
9121 MemorySanitizerVisitor &MSV,
const unsigned VAListTagSize)
9122 : VarArgHelperBase(
F, MS, MSV, VAListTagSize) {}
9124 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9125 unsigned VAArgOffset = 0;
9126 const DataLayout &
DL =
F.getDataLayout();
9127 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9132 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9133 if (
DL.isBigEndian()) {
9136 if (ArgSize < IntptrSize)
9137 VAArgOffset += (IntptrSize - ArgSize);
9139 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9140 VAArgOffset += ArgSize;
9141 VAArgOffset =
alignTo(VAArgOffset, IntptrSize);
9147 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9150 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9153 void finalizeInstrumentation()
override {
9154 assert(!VAArgSize && !VAArgTLSCopy &&
9155 "finalizeInstrumentation called twice");
9157 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9158 Value *CopySize = VAArgSize;
9160 if (!VAStartInstrumentationList.empty()) {
9163 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9169 Intrinsic::umin, CopySize,
9177 for (CallInst *OrigInst : VAStartInstrumentationList) {
9178 NextNodeIRBuilder IRB(OrigInst);
9179 Value *VAListTag = OrigInst->getArgOperand(0);
9180 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9181 Value *RegSaveAreaPtrPtr =
9183 PointerType::get(*MS.C, 0));
9184 Value *RegSaveAreaPtr =
9185 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9186 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9187 const DataLayout &
DL =
F.getDataLayout();
9188 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9190 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9191 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9193 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9201using VarArgARM32Helper = VarArgGenericHelper;
9202using VarArgRISCVHelper = VarArgGenericHelper;
9203using VarArgMIPSHelper = VarArgGenericHelper;
9204using VarArgLoongArch64Helper = VarArgGenericHelper;
9207struct VarArgNoOpHelper :
public VarArgHelper {
9208 VarArgNoOpHelper(Function &
F, MemorySanitizer &MS,
9209 MemorySanitizerVisitor &MSV) {}
9211 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {}
9213 void visitVAStartInst(VAStartInst &
I)
override {}
9215 void visitVACopyInst(VACopyInst &
I)
override {}
9217 void finalizeInstrumentation()
override {}
9223 MemorySanitizerVisitor &Visitor) {
9226 Triple TargetTriple(Func.getParent()->getTargetTriple());
9229 return new VarArgI386Helper(Func, Msan, Visitor);
9232 return new VarArgAMD64Helper(Func, Msan, Visitor);
9234 if (TargetTriple.
isARM())
9235 return new VarArgARM32Helper(Func, Msan, Visitor, 4);
9238 return new VarArgAArch64Helper(Func, Msan, Visitor);
9241 return new VarArgSystemZHelper(Func, Msan, Visitor);
9246 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9249 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9252 return new VarArgRISCVHelper(Func, Msan, Visitor, 4);
9255 return new VarArgRISCVHelper(Func, Msan, Visitor, 8);
9258 return new VarArgMIPSHelper(Func, Msan, Visitor, 4);
9261 return new VarArgMIPSHelper(Func, Msan, Visitor, 8);
9264 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9267 return new VarArgNoOpHelper(Func, Msan, Visitor);
9274 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9277 MemorySanitizerVisitor Visitor(
F, *
this, TLI);
9284 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 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 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
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> 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 TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton 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)
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.
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
LLVM_ABI bool canLosslesslyBitCastTo(Type *Ty) const
Return true if this type could be converted with a lossless BitCast to type 'Ty'.
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)
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.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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.