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); }
2639 return IRB.
CreateOr({S1S2, V1S2, S1V2});
2643 void visitAnd(BinaryOperator &
I) {
2645 Value *V1 =
I.getOperand(0);
2646 Value *V2 =
I.getOperand(1);
2648 Value *S2 = getShadow(&
I, 1);
2650 Value *OutShadow = handleBitwiseAnd(IRB, V1, V2,
S1, S2);
2652 setShadow(&
I, OutShadow);
2653 setOriginForNaryOp(
I);
2656 void visitOr(BinaryOperator &
I) {
2669 Value *S2 = getShadow(&
I, 1);
2670 Value *V1 =
I.getOperand(0);
2671 Value *V2 =
I.getOperand(1);
2695 S = IRB.
CreateOr(S, DisjointOrShadow,
"_ms_disjoint");
2699 setOriginForNaryOp(
I);
2717 template <
bool CombineShadow>
class Combiner {
2718 Value *Shadow =
nullptr;
2719 Value *Origin =
nullptr;
2721 MemorySanitizerVisitor *MSV;
2724 Combiner(MemorySanitizerVisitor *MSV,
IRBuilder<> &IRB)
2725 : IRB(IRB), MSV(MSV) {}
2729 if (CombineShadow) {
2734 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2735 Shadow = IRB.
CreateOr(Shadow, OpShadow,
"_msprop");
2739 if (MSV->MS.TrackOrigins) {
2746 if (!ConstOrigin || !ConstOrigin->
isNullValue()) {
2747 Value *
Cond = MSV->convertToBool(OpShadow, IRB);
2757 Value *OpShadow = MSV->getShadow(V);
2758 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) :
nullptr;
2759 return Add(OpShadow, OpOrigin);
2764 void Done(Instruction *
I) {
2765 if (CombineShadow) {
2767 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(
I));
2768 MSV->setShadow(
I, Shadow);
2770 if (MSV->MS.TrackOrigins) {
2772 MSV->setOrigin(
I, Origin);
2778 void DoneAndStoreOrigin(TypeSize TS,
Value *OriginPtr) {
2779 if (MSV->MS.TrackOrigins) {
2786 using ShadowAndOriginCombiner = Combiner<true>;
2787 using OriginCombiner = Combiner<false>;
2790 void setOriginForNaryOp(Instruction &
I) {
2791 if (!MS.TrackOrigins)
2794 OriginCombiner OC(
this, IRB);
2795 for (Use &
Op :
I.operands())
2800 size_t VectorOrPrimitiveTypeSizeInBits(
Type *Ty) {
2802 "Vector of pointers is not a valid shadow type");
2812 Type *srcTy =
V->getType();
2815 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2816 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2817 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2835 Type *ShadowTy = getShadowTy(V);
2836 if (
V->getType() == ShadowTy)
2838 if (
V->getType()->isPtrOrPtrVectorTy())
2845 void handleShadowOr(Instruction &
I) {
2847 ShadowAndOriginCombiner SC(
this, IRB);
2848 for (Use &
Op :
I.operands())
2875 Value *horizontalReduce(IntrinsicInst &
I,
unsigned ReductionFactor,
2876 unsigned Shards,
Value *VectorA,
Value *VectorB) {
2881 [[maybe_unused]]
unsigned TotalNumElems = NumElems;
2887 assert(NumElems % (ReductionFactor * Shards) == 0);
2892 for (
unsigned i = 0; i < ReductionFactor; i++) {
2893 SmallVector<int, 16>
Mask;
2895 for (
unsigned j = 0;
j < Shards;
j++) {
2896 unsigned Offset = NumElems / Shards *
j;
2898 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2902 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2927 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards) {
2928 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2930 assert(
I.getType()->isVectorTy());
2931 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2933 [[maybe_unused]] FixedVectorType *ParamType =
2937 [[maybe_unused]] FixedVectorType *
ReturnType =
2945 Value *FirstArgShadow = getShadow(&
I, 0);
2946 Value *SecondArgShadow =
nullptr;
2947 if (
I.arg_size() == 2)
2948 SecondArgShadow = getShadow(&
I, 1);
2950 Value *OrShadow = horizontalReduce(
I, 2, Shards,
2951 FirstArgShadow, SecondArgShadow);
2953 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
2955 setShadow(&
I, OrShadow);
2956 setOriginForNaryOp(
I);
2966 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards,
2967 int ReinterpretElemWidth) {
2968 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
2970 assert(
I.getType()->isVectorTy());
2971 assert(
I.getArgOperand(0)->getType()->isVectorTy());
2973 FixedVectorType *ParamType =
2978 [[maybe_unused]] FixedVectorType *
ReturnType =
2985 FixedVectorType *ReinterpretShadowTy =
nullptr;
2993 Value *FirstArgShadow = getShadow(&
I, 0);
2994 FirstArgShadow = IRB.
CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
3004 Value *SecondArgShadow =
nullptr;
3005 if (
I.arg_size() == 2) {
3006 SecondArgShadow = getShadow(&
I, 1);
3007 SecondArgShadow = IRB.
CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
3010 Value *OrShadow = horizontalReduce(
I, 2, Shards,
3011 FirstArgShadow, SecondArgShadow);
3013 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
3015 setShadow(&
I, OrShadow);
3016 setOriginForNaryOp(
I);
3019 void visitFNeg(UnaryOperator &
I) { handleShadowOr(
I); }
3030 void handleMulByConstant(BinaryOperator &
I, Constant *ConstArg,
3036 Type *EltTy = VTy->getElementType();
3038 for (
unsigned Idx = 0; Idx < NumElements; ++Idx) {
3039 if (ConstantInt *Elt =
3041 const APInt &
V = Elt->getValue();
3042 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
3043 Elements.push_back(ConstantInt::get(EltTy, V2));
3045 Elements.push_back(ConstantInt::get(EltTy, 1));
3051 const APInt &
V = Elt->getValue();
3052 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
3053 ShadowMul = ConstantInt::get(Ty, V2);
3055 ShadowMul = ConstantInt::get(Ty, 1);
3061 IRB.
CreateMul(getShadow(OtherArg), ShadowMul,
"msprop_mul_cst"));
3062 setOrigin(&
I, getOrigin(OtherArg));
3065 void visitMul(BinaryOperator &
I) {
3068 if (constOp0 && !constOp1)
3069 handleMulByConstant(
I, constOp0,
I.getOperand(1));
3070 else if (constOp1 && !constOp0)
3071 handleMulByConstant(
I, constOp1,
I.getOperand(0));
3076 void visitFAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3077 void visitFSub(BinaryOperator &
I) { handleShadowOr(
I); }
3078 void visitFMul(BinaryOperator &
I) { handleShadowOr(
I); }
3079 void visitAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3080 void visitSub(BinaryOperator &
I) { handleShadowOr(
I); }
3081 void visitXor(BinaryOperator &
I) { handleShadowOr(
I); }
3083 void handleIntegerDiv(Instruction &
I) {
3086 insertCheckShadowOf(
I.getOperand(1), &
I);
3087 setShadow(&
I, getShadow(&
I, 0));
3088 setOrigin(&
I, getOrigin(&
I, 0));
3091 void visitUDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3092 void visitSDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3093 void visitURem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3094 void visitSRem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3098 void visitFDiv(BinaryOperator &
I) { handleShadowOr(
I); }
3099 void visitFRem(BinaryOperator &
I) { handleShadowOr(
I); }
3105 void handleEqualityComparison(ICmpInst &
I) {
3109 Value *Sa = getShadow(
A);
3110 Value *Sb = getShadow(
B);
3112 Value *Si = propagateEqualityComparison(IRB,
A,
B, Sa, Sb);
3115 setOriginForNaryOp(
I);
3123 void handleRelationalComparisonExact(ICmpInst &
I) {
3127 Value *Sa = getShadow(
A);
3128 Value *Sb = getShadow(
B);
3139 bool IsSigned =
I.isSigned();
3141 auto GetMinMaxUnsigned = [&](
Value *
V,
Value *S) {
3151 V = IRB.
CreateXor(V, ConstantInt::get(
V->getType(), MinVal));
3156 return std::make_pair(Min, Max);
3159 auto [Amin, Amax] = GetMinMaxUnsigned(
A, Sa);
3160 auto [Bmin, Bmax] = GetMinMaxUnsigned(
B, Sb);
3166 setOriginForNaryOp(
I);
3173 void handleSignedRelationalComparison(ICmpInst &
I) {
3178 op =
I.getOperand(0);
3179 pre =
I.getPredicate();
3181 op =
I.getOperand(1);
3182 pre =
I.getSwappedPredicate();
3195 setShadow(&
I, Shadow);
3196 setOrigin(&
I, getOrigin(
op));
3202 void visitICmpInst(ICmpInst &
I) {
3207 if (
I.isEquality()) {
3208 handleEqualityComparison(
I);
3214 handleRelationalComparisonExact(
I);
3218 handleSignedRelationalComparison(
I);
3224 handleRelationalComparisonExact(
I);
3231 void visitFCmpInst(FCmpInst &
I) { handleShadowOr(
I); }
3233 void handleShift(BinaryOperator &
I) {
3238 Value *S2 = getShadow(&
I, 1);
3241 Value *V2 =
I.getOperand(1);
3243 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3244 setOriginForNaryOp(
I);
3247 void visitShl(BinaryOperator &
I) { handleShift(
I); }
3248 void visitAShr(BinaryOperator &
I) { handleShift(
I); }
3249 void visitLShr(BinaryOperator &
I) { handleShift(
I); }
3251 void handleFunnelShift(IntrinsicInst &
I) {
3255 Value *S0 = getShadow(&
I, 0);
3257 Value *S2 = getShadow(&
I, 2);
3260 Value *V2 =
I.getOperand(2);
3263 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3264 setOriginForNaryOp(
I);
3277 void visitMemMoveInst(MemMoveInst &
I) {
3278 getShadow(
I.getArgOperand(1));
3281 {I.getArgOperand(0), I.getArgOperand(1),
3282 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3300 void visitMemCpyInst(MemCpyInst &
I) {
3301 getShadow(
I.getArgOperand(1));
3304 {I.getArgOperand(0), I.getArgOperand(1),
3305 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3310 void visitMemSetInst(MemSetInst &
I) {
3314 {I.getArgOperand(0),
3315 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3316 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3320 void visitVAStartInst(VAStartInst &
I) { VAHelper->visitVAStartInst(
I); }
3322 void visitVACopyInst(VACopyInst &
I) { VAHelper->visitVACopyInst(
I); }
3328 bool handleVectorStoreIntrinsic(IntrinsicInst &
I) {
3332 Value *Addr =
I.getArgOperand(0);
3333 Value *Shadow = getShadow(&
I, 1);
3334 Value *ShadowPtr, *OriginPtr;
3338 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3343 insertCheckShadowOf(Addr, &
I);
3346 if (MS.TrackOrigins)
3355 bool handleVectorLoadIntrinsic(IntrinsicInst &
I) {
3359 Value *Addr =
I.getArgOperand(0);
3361 Type *ShadowTy = getShadowTy(&
I);
3362 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
3363 if (PropagateShadow) {
3367 std::tie(ShadowPtr, OriginPtr) =
3368 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
3372 setShadow(&
I, getCleanShadow(&
I));
3376 insertCheckShadowOf(Addr, &
I);
3378 if (MS.TrackOrigins) {
3379 if (PropagateShadow)
3380 setOrigin(&
I, IRB.
CreateLoad(MS.OriginTy, OriginPtr));
3382 setOrigin(&
I, getCleanOrigin());
3402 [[maybe_unused]]
bool
3403 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &
I,
3404 unsigned int trailingFlags) {
3405 Type *RetTy =
I.getType();
3409 unsigned NumArgOperands =
I.arg_size();
3410 assert(NumArgOperands >= trailingFlags);
3411 for (
unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3412 Type *Ty =
I.getArgOperand(i)->getType();
3418 ShadowAndOriginCombiner SC(
this, IRB);
3419 for (
unsigned i = 0; i < NumArgOperands; ++i)
3420 SC.Add(
I.getArgOperand(i));
3437 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &
I) {
3438 unsigned NumArgOperands =
I.arg_size();
3439 if (NumArgOperands == 0)
3442 if (NumArgOperands == 2 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3443 I.getArgOperand(1)->getType()->isVectorTy() &&
3444 I.getType()->isVoidTy() && !
I.onlyReadsMemory()) {
3446 return handleVectorStoreIntrinsic(
I);
3449 if (NumArgOperands == 1 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3450 I.getType()->isVectorTy() &&
I.onlyReadsMemory()) {
3452 return handleVectorLoadIntrinsic(
I);
3455 if (
I.doesNotAccessMemory())
3456 if (maybeHandleSimpleNomemIntrinsic(
I, 0))
3464 bool maybeHandleUnknownIntrinsic(IntrinsicInst &
I) {
3465 if (maybeHandleUnknownIntrinsicUnlogged(
I)) {
3469 LLVM_DEBUG(
dbgs() <<
"UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " <<
I
3476 void handleInvariantGroup(IntrinsicInst &
I) {
3477 setShadow(&
I, getShadow(&
I, 0));
3478 setOrigin(&
I, getOrigin(&
I, 0));
3481 void handleLifetimeStart(IntrinsicInst &
I) {
3486 LifetimeStartList.push_back(std::make_pair(&
I, AI));
3489 void handleBswap(IntrinsicInst &
I) {
3492 Type *OpType =
Op->getType();
3495 setOrigin(&
I, getOrigin(
Op));
3516 void handleCountLeadingTrailingZeros(IntrinsicInst &
I) {
3518 Value *Src =
I.getArgOperand(0);
3519 Value *SrcShadow = getShadow(Src);
3523 I.getType(),
I.getIntrinsicID(), {Src, False});
3525 I.getType(),
I.getIntrinsicID(), {SrcShadow, False});
3528 ConcreteZerosCount, ShadowZerosCount,
"_mscz_cmp_zeros");
3530 Value *NotAllZeroShadow =
3532 Value *OutputShadow =
3533 IRB.
CreateAnd(CompareConcreteZeros, NotAllZeroShadow,
"_mscz_main");
3539 OutputShadow = IRB.
CreateOr(OutputShadow, BoolZeroPoison,
"_mscz_bs");
3542 OutputShadow = IRB.
CreateSExt(OutputShadow, getShadowTy(Src),
"_mscz_os");
3544 setShadow(&
I, OutputShadow);
3545 setOriginForNaryOp(
I);
3560 void handleNEONVectorConvertIntrinsic(IntrinsicInst &
I,
bool FixedPoint) {
3567 Value *S0 = getShadow(&
I, 0);
3570 Value *Precision =
I.getOperand(1);
3571 insertCheckShadowOf(Precision, &
I);
3581 setShadow(&
I, OutShadow);
3582 setOriginForNaryOp(
I);
3591 FixedVectorType *maybeShrinkVectorShadowType(
Value *Src, IntrinsicInst &
I) {
3611 Value *maybeExtendVectorShadowWithZeros(
Value *Shadow, IntrinsicInst &
I) {
3616 Value *FullShadow = getCleanShadow(&
I);
3617 unsigned ShadowNumElems =
3619 unsigned FullShadowNumElems =
3622 assert((ShadowNumElems == FullShadowNumElems) ||
3623 (ShadowNumElems * 2 == FullShadowNumElems));
3625 if (ShadowNumElems == FullShadowNumElems) {
3626 FullShadow = Shadow;
3630 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3655 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &
I,
3656 bool HasRoundingMode) {
3657 if (HasRoundingMode) {
3665 Value *Src =
I.getArgOperand(0);
3666 assert(Src->getType()->isVectorTy());
3670 VectorType *ShadowType = maybeShrinkVectorShadowType(Src,
I);
3673 Value *S0 = getShadow(&
I, 0);
3685 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow,
I);
3687 setShadow(&
I, FullShadow);
3688 setOriginForNaryOp(
I);
3709 void handleSSEVectorConvertIntrinsic(IntrinsicInst &
I,
int NumUsedElements,
3710 bool HasRoundingMode =
false) {
3712 Value *CopyOp, *ConvertOp;
3714 assert((!HasRoundingMode ||
3716 "Invalid rounding mode");
3718 switch (
I.arg_size() - HasRoundingMode) {
3720 CopyOp =
I.getArgOperand(0);
3721 ConvertOp =
I.getArgOperand(1);
3724 ConvertOp =
I.getArgOperand(0);
3738 Value *ConvertShadow = getShadow(ConvertOp);
3739 Value *AggShadow =
nullptr;
3742 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
3743 for (
int i = 1; i < NumUsedElements; ++i) {
3745 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
3746 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
3749 AggShadow = ConvertShadow;
3752 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &
I);
3759 Value *ResultShadow = getShadow(CopyOp);
3761 for (
int i = 0; i < NumUsedElements; ++i) {
3763 ResultShadow, ConstantInt::getNullValue(EltTy),
3766 setShadow(&
I, ResultShadow);
3767 setOrigin(&
I, getOrigin(CopyOp));
3769 setShadow(&
I, getCleanShadow(&
I));
3770 setOrigin(&
I, getCleanOrigin());
3778 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
3781 return CreateShadowCast(IRB, S2,
T,
true);
3789 return CreateShadowCast(IRB, S2,
T,
true);
3806 void handleVectorShiftIntrinsic(IntrinsicInst &
I,
bool Variable) {
3812 Value *S2 = getShadow(&
I, 1);
3814 : Lower64ShadowExtend(IRB, S2, getShadowTy(&
I));
3815 Value *V1 =
I.getOperand(0);
3816 Value *V2 =
I.getOperand(1);
3818 {IRB.CreateBitCast(S1, V1->getType()), V2});
3820 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3821 setOriginForNaryOp(
I);
3826 Type *getMMXVectorTy(
unsigned EltSizeInBits,
3827 unsigned X86_MMXSizeInBits = 64) {
3828 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3829 "Illegal MMX vector element size");
3831 X86_MMXSizeInBits / EltSizeInBits);
3838 case Intrinsic::x86_sse2_packsswb_128:
3839 case Intrinsic::x86_sse2_packuswb_128:
3840 return Intrinsic::x86_sse2_packsswb_128;
3842 case Intrinsic::x86_sse2_packssdw_128:
3843 case Intrinsic::x86_sse41_packusdw:
3844 return Intrinsic::x86_sse2_packssdw_128;
3846 case Intrinsic::x86_avx2_packsswb:
3847 case Intrinsic::x86_avx2_packuswb:
3848 return Intrinsic::x86_avx2_packsswb;
3850 case Intrinsic::x86_avx2_packssdw:
3851 case Intrinsic::x86_avx2_packusdw:
3852 return Intrinsic::x86_avx2_packssdw;
3854 case Intrinsic::x86_mmx_packsswb:
3855 case Intrinsic::x86_mmx_packuswb:
3856 return Intrinsic::x86_mmx_packsswb;
3858 case Intrinsic::x86_mmx_packssdw:
3859 return Intrinsic::x86_mmx_packssdw;
3861 case Intrinsic::x86_avx512_packssdw_512:
3862 case Intrinsic::x86_avx512_packusdw_512:
3863 return Intrinsic::x86_avx512_packssdw_512;
3865 case Intrinsic::x86_avx512_packsswb_512:
3866 case Intrinsic::x86_avx512_packuswb_512:
3867 return Intrinsic::x86_avx512_packsswb_512;
3883 void handleVectorPackIntrinsic(IntrinsicInst &
I,
3884 unsigned MMXEltSizeInBits = 0) {
3888 Value *S2 = getShadow(&
I, 1);
3889 assert(
S1->getType()->isVectorTy());
3895 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) :
S1->
getType();
3896 if (MMXEltSizeInBits) {
3904 if (MMXEltSizeInBits) {
3910 {S1_ext, S2_ext},
nullptr,
3911 "_msprop_vector_pack");
3912 if (MMXEltSizeInBits)
3915 setOriginForNaryOp(
I);
3919 Constant *createDppMask(
unsigned Width,
unsigned Mask) {
3920 SmallVector<Constant *, 4>
R(Width);
3932 const unsigned Width =
3939 Value *DstMaskV = createDppMask(Width, DstMask);
3956 void handleDppIntrinsic(IntrinsicInst &
I) {
3959 Value *S0 = getShadow(&
I, 0);
3963 const unsigned Width =
3965 assert(Width == 2 || Width == 4 || Width == 8);
3968 const unsigned SrcMask =
Mask >> 4;
3969 const unsigned DstMask =
Mask & 0xf;
3972 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3977 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3984 setOriginForNaryOp(
I);
3988 C = CreateAppToShadowCast(IRB,
C);
3997 void handleBlendvIntrinsic(IntrinsicInst &
I) {
4002 Value *Sc = getShadow(&
I, 2);
4003 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
4008 C = convertBlendvToSelectMask(IRB,
C);
4009 Sc = convertBlendvToSelectMask(IRB, Sc);
4015 handleSelectLikeInst(
I,
C,
T,
F);
4019 void handleVectorSadIntrinsic(IntrinsicInst &
I,
bool IsMMX =
false) {
4020 const unsigned SignificantBitsPerResultElement = 16;
4022 unsigned ZeroBitsPerResultElement =
4026 auto *Shadow0 = getShadow(&
I, 0);
4027 auto *Shadow1 = getShadow(&
I, 1);
4032 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
4035 setOriginForNaryOp(
I);
4059 void handleVectorDotProductIntrinsic(IntrinsicInst &
I,
4060 unsigned ReductionFactor,
4062 unsigned EltSizeInBits,
4066 [[maybe_unused]] FixedVectorType *
ReturnType =
4071 Value *Va =
nullptr;
4072 Value *Vb =
nullptr;
4073 Value *Sa =
nullptr;
4074 Value *Sb =
nullptr;
4076 assert(
I.arg_size() == 2 ||
I.arg_size() == 3);
4077 if (
I.arg_size() == 2) {
4080 Va =
I.getOperand(0);
4081 Vb =
I.getOperand(1);
4083 Sa = getShadow(&
I, 0);
4084 Sb = getShadow(&
I, 1);
4085 }
else if (
I.arg_size() == 3) {
4087 Va =
I.getOperand(1);
4088 Vb =
I.getOperand(2);
4090 Sa = getShadow(&
I, 1);
4091 Sb = getShadow(&
I, 2);
4108 Sa, getPclmulMask(Width, Lanes ==
kOddLanes));
4110 Sb, getPclmulMask(Width, Lanes ==
kOddLanes));
4120 if (
I.arg_size() == 3) {
4121 [[maybe_unused]]
auto *AccumulatorType =
4123 assert(AccumulatorType == ReturnType);
4126 FixedVectorType *ImplicitReturnType =
4129 if (EltSizeInBits) {
4131 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4143 ReturnType->getNumElements() * ReductionFactor);
4160 VaInt = CreateAppToShadowCast(IRB, Va);
4161 VbInt = CreateAppToShadowCast(IRB, Vb);
4168 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4190 ImplicitReturnType);
4195 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&
I));
4198 if (
I.arg_size() == 3)
4199 OutShadow = IRB.
CreateOr(OutShadow, getShadow(&
I, 0));
4201 setShadow(&
I, OutShadow);
4202 setOriginForNaryOp(
I);
4219 void handleVectorComparePackedIntrinsic(IntrinsicInst &
I,
4220 bool PredicateAsOperand) {
4221 if (PredicateAsOperand) {
4223 assert(
I.paramHasAttr(2, Attribute::ImmArg));
4231 Type *ResTy = getShadowTy(&
I);
4232 auto *Shadow0 = getShadow(&
I, 0);
4233 auto *Shadow1 = getShadow(&
I, 1);
4238 setOriginForNaryOp(
I);
4244 void handleVectorCompareScalarIntrinsic(IntrinsicInst &
I) {
4246 auto *Shadow0 = getShadow(&
I, 0);
4247 auto *Shadow1 = getShadow(&
I, 1);
4249 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&
I));
4251 setOriginForNaryOp(
I);
4260 void handleVectorReduceIntrinsic(IntrinsicInst &
I,
bool AllowShadowCast) {
4265 if (AllowShadowCast)
4266 S = CreateShadowCast(IRB, S, getShadowTy(&
I));
4270 setOriginForNaryOp(
I);
4280 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &
I) {
4284 Value *Shadow0 = getShadow(&
I, 0);
4290 setOriginForNaryOp(
I);
4296 void handleVectorReduceOrIntrinsic(IntrinsicInst &
I) {
4300 Value *OperandShadow = getShadow(&
I, 0);
4302 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
4310 setOrigin(&
I, getOrigin(&
I, 0));
4316 void handleVectorReduceAndIntrinsic(IntrinsicInst &
I) {
4320 Value *OperandShadow = getShadow(&
I, 0);
4321 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
4329 setOrigin(&
I, getOrigin(&
I, 0));
4332 void handleStmxcsr(IntrinsicInst &
I) {
4334 Value *Addr =
I.getArgOperand(0);
4337 getShadowOriginPtr(Addr, IRB, Ty,
Align(1),
true).first;
4342 insertCheckShadowOf(Addr, &
I);
4345 void handleLdmxcsr(IntrinsicInst &
I) {
4350 Value *Addr =
I.getArgOperand(0);
4353 Value *ShadowPtr, *OriginPtr;
4354 std::tie(ShadowPtr, OriginPtr) =
4355 getShadowOriginPtr(Addr, IRB, Ty, Alignment,
false);
4358 insertCheckShadowOf(Addr, &
I);
4361 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
4363 insertCheckShadow(Shadow, Origin, &
I);
4366 void handleMaskedExpandLoad(IntrinsicInst &
I) {
4368 Value *Ptr =
I.getArgOperand(0);
4369 MaybeAlign
Align =
I.getParamAlign(0);
4371 Value *PassThru =
I.getArgOperand(2);
4374 insertCheckShadowOf(Ptr, &
I);
4375 insertCheckShadowOf(Mask, &
I);
4378 if (!PropagateShadow) {
4379 setShadow(&
I, getCleanShadow(&
I));
4380 setOrigin(&
I, getCleanOrigin());
4384 Type *ShadowTy = getShadowTy(&
I);
4386 auto [ShadowPtr, OriginPtr] =
4387 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
false);
4391 getShadow(PassThru),
"_msmaskedexpload");
4393 setShadow(&
I, Shadow);
4396 setOrigin(&
I, getCleanOrigin());
4399 void handleMaskedCompressStore(IntrinsicInst &
I) {
4401 Value *Values =
I.getArgOperand(0);
4402 Value *Ptr =
I.getArgOperand(1);
4403 MaybeAlign
Align =
I.getParamAlign(1);
4407 insertCheckShadowOf(Ptr, &
I);
4408 insertCheckShadowOf(Mask, &
I);
4411 Value *Shadow = getShadow(Values);
4412 Type *ElementShadowTy =
4414 auto [ShadowPtr, OriginPtrs] =
4415 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
true);
4422 void handleMaskedGather(IntrinsicInst &
I) {
4424 Value *Ptrs =
I.getArgOperand(0);
4425 const Align Alignment =
I.getParamAlign(0).valueOrOne();
4427 Value *PassThru =
I.getArgOperand(2);
4429 Type *PtrsShadowTy = getShadowTy(Ptrs);
4431 insertCheckShadowOf(Mask, &
I);
4435 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4438 if (!PropagateShadow) {
4439 setShadow(&
I, getCleanShadow(&
I));
4440 setOrigin(&
I, getCleanOrigin());
4444 Type *ShadowTy = getShadowTy(&
I);
4446 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4447 Ptrs, IRB, ElementShadowTy, Alignment,
false);
4451 getShadow(PassThru),
"_msmaskedgather");
4453 setShadow(&
I, Shadow);
4456 setOrigin(&
I, getCleanOrigin());
4459 void handleMaskedScatter(IntrinsicInst &
I) {
4461 Value *Values =
I.getArgOperand(0);
4462 Value *Ptrs =
I.getArgOperand(1);
4463 const Align Alignment =
I.getParamAlign(1).valueOrOne();
4466 Type *PtrsShadowTy = getShadowTy(Ptrs);
4468 insertCheckShadowOf(Mask, &
I);
4472 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4475 Value *Shadow = getShadow(Values);
4476 Type *ElementShadowTy =
4478 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4479 Ptrs, IRB, ElementShadowTy, Alignment,
true);
4490 void handleMaskedStore(IntrinsicInst &
I) {
4492 Value *
V =
I.getArgOperand(0);
4493 Value *Ptr =
I.getArgOperand(1);
4494 const Align Alignment =
I.getParamAlign(1).valueOrOne();
4496 Value *Shadow = getShadow(V);
4499 insertCheckShadowOf(Ptr, &
I);
4500 insertCheckShadowOf(Mask, &
I);
4505 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4506 Ptr, IRB, Shadow->
getType(), Alignment,
true);
4510 if (!MS.TrackOrigins)
4513 auto &
DL =
F.getDataLayout();
4514 paintOrigin(IRB, getOrigin(V), OriginPtr,
4523 void handleMaskedLoad(IntrinsicInst &
I) {
4525 Value *Ptr =
I.getArgOperand(0);
4526 const Align Alignment =
I.getParamAlign(0).valueOrOne();
4528 Value *PassThru =
I.getArgOperand(2);
4531 insertCheckShadowOf(Ptr, &
I);
4532 insertCheckShadowOf(Mask, &
I);
4535 if (!PropagateShadow) {
4536 setShadow(&
I, getCleanShadow(&
I));
4537 setOrigin(&
I, getCleanOrigin());
4541 Type *ShadowTy = getShadowTy(&
I);
4542 Value *ShadowPtr, *OriginPtr;
4543 std::tie(ShadowPtr, OriginPtr) =
4544 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment,
false);
4546 getShadow(PassThru),
"_msmaskedld"));
4548 if (!MS.TrackOrigins)
4555 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
4560 setOrigin(&
I, Origin);
4576 void handleAVXMaskedStore(IntrinsicInst &
I) {
4581 Value *Dst =
I.getArgOperand(0);
4582 assert(Dst->getType()->isPointerTy() &&
"Destination is not a pointer!");
4587 Value *Src =
I.getArgOperand(2);
4592 Value *SrcShadow = getShadow(Src);
4595 insertCheckShadowOf(Dst, &
I);
4596 insertCheckShadowOf(Mask, &
I);
4599 Value *DstShadowPtr;
4600 Value *DstOriginPtr;
4601 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4602 Dst, IRB, SrcShadow->
getType(), Alignment,
true);
4604 SmallVector<Value *, 2> ShadowArgs;
4605 ShadowArgs.
append(1, DstShadowPtr);
4606 ShadowArgs.
append(1, Mask);
4617 if (!MS.TrackOrigins)
4621 auto &
DL =
F.getDataLayout();
4622 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4623 DL.getTypeStoreSize(SrcShadow->
getType()),
4642 void handleAVXMaskedLoad(IntrinsicInst &
I) {
4647 Value *Src =
I.getArgOperand(0);
4648 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
4656 insertCheckShadowOf(Mask, &
I);
4659 Type *SrcShadowTy = getShadowTy(Src);
4660 Value *SrcShadowPtr, *SrcOriginPtr;
4661 std::tie(SrcShadowPtr, SrcOriginPtr) =
4662 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment,
false);
4664 SmallVector<Value *, 2> ShadowArgs;
4665 ShadowArgs.
append(1, SrcShadowPtr);
4666 ShadowArgs.
append(1, Mask);
4675 if (!MS.TrackOrigins)
4682 setOrigin(&
I, PtrSrcOrigin);
4691 assert(isFixedIntVector(Idx));
4692 auto IdxVectorSize =
4700 auto *IdxShadow = getShadow(Idx);
4705 insertCheckShadow(Truncated, getOrigin(Idx),
I);
4710 void handleAVXVpermilvar(IntrinsicInst &
I) {
4712 Value *Shadow = getShadow(&
I, 0);
4713 maskedCheckAVXIndexShadow(IRB,
I.getArgOperand(1), &
I);
4717 Shadow = IRB.
CreateBitCast(Shadow,
I.getArgOperand(0)->getType());
4719 {Shadow, I.getArgOperand(1)});
4722 setOriginForNaryOp(
I);
4727 void handleAVXVpermi2var(IntrinsicInst &
I) {
4732 [[maybe_unused]]
auto ArgVectorSize =
4735 ->getNumElements() == ArgVectorSize);
4737 ->getNumElements() == ArgVectorSize);
4738 assert(
I.getArgOperand(0)->getType() ==
I.getArgOperand(2)->getType());
4739 assert(
I.getType() ==
I.getArgOperand(0)->getType());
4740 assert(
I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4742 Value *AShadow = getShadow(&
I, 0);
4743 Value *Idx =
I.getArgOperand(1);
4744 Value *BShadow = getShadow(&
I, 2);
4746 maskedCheckAVXIndexShadow(IRB, Idx, &
I);
4750 AShadow = IRB.
CreateBitCast(AShadow,
I.getArgOperand(0)->getType());
4751 BShadow = IRB.
CreateBitCast(BShadow,
I.getArgOperand(2)->getType());
4753 {AShadow, Idx, BShadow});
4755 setOriginForNaryOp(
I);
4758 [[maybe_unused]]
static bool isFixedIntVectorTy(
const Type *
T) {
4762 [[maybe_unused]]
static bool isFixedFPVectorTy(
const Type *
T) {
4766 [[maybe_unused]]
static bool isFixedIntVector(
const Value *V) {
4767 return isFixedIntVectorTy(
V->getType());
4770 [[maybe_unused]]
static bool isFixedFPVector(
const Value *V) {
4771 return isFixedFPVectorTy(
V->getType());
4793 void handleAVX512VectorConvertFPToInt(IntrinsicInst &
I,
bool LastMask) {
4798 Value *WriteThrough;
4802 WriteThrough =
I.getOperand(2);
4803 Mask =
I.getOperand(3);
4806 WriteThrough =
I.getOperand(1);
4807 Mask =
I.getOperand(2);
4812 assert(isFixedIntVector(WriteThrough));
4814 unsigned ANumElements =
4816 [[maybe_unused]]
unsigned WriteThruNumElements =
4818 assert(ANumElements == WriteThruNumElements ||
4819 ANumElements * 2 == WriteThruNumElements);
4822 unsigned MaskNumElements =
Mask->getType()->getScalarSizeInBits();
4823 assert(ANumElements == MaskNumElements ||
4824 ANumElements * 2 == MaskNumElements);
4826 assert(WriteThruNumElements == MaskNumElements);
4830 insertCheckShadowOf(Mask, &
I);
4840 Value *AShadow = getShadow(
A);
4841 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
4843 if (ANumElements * 2 == MaskNumElements) {
4855 "_ms_mask_bitcast");
4865 getShadowTy(&
I),
"_ms_a_shadow");
4867 Value *WriteThroughShadow = getShadow(WriteThrough);
4869 "_ms_writethru_select");
4871 setShadow(&
I, Shadow);
4872 setOriginForNaryOp(
I);
4880 void handleBmiIntrinsic(IntrinsicInst &
I) {
4882 Type *ShadowTy = getShadowTy(&
I);
4885 Value *SMask = getShadow(&
I, 1);
4890 {getShadow(&I, 0), I.getOperand(1)});
4893 setOriginForNaryOp(
I);
4896 static SmallVector<int, 8> getPclmulMask(
unsigned Width,
bool OddElements) {
4897 SmallVector<int, 8>
Mask;
4898 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
4912 void handlePclmulIntrinsic(IntrinsicInst &
I) {
4917 "pclmul 3rd operand must be a constant");
4920 getPclmulMask(Width, Imm & 0x01));
4922 getPclmulMask(Width, Imm & 0x10));
4923 ShadowAndOriginCombiner SOC(
this, IRB);
4924 SOC.Add(Shuf0, getOrigin(&
I, 0));
4925 SOC.Add(Shuf1, getOrigin(&
I, 1));
4930 void handleUnarySdSsIntrinsic(IntrinsicInst &
I) {
4935 Value *Second = getShadow(&
I, 1);
4937 SmallVector<int, 16>
Mask;
4938 Mask.push_back(Width);
4939 for (
unsigned i = 1; i < Width; i++)
4943 setShadow(&
I, Shadow);
4944 setOriginForNaryOp(
I);
4947 void handleVtestIntrinsic(IntrinsicInst &
I) {
4949 Value *Shadow0 = getShadow(&
I, 0);
4950 Value *Shadow1 = getShadow(&
I, 1);
4956 setShadow(&
I, Shadow);
4957 setOriginForNaryOp(
I);
4960 void handleBinarySdSsIntrinsic(IntrinsicInst &
I) {
4965 Value *Second = getShadow(&
I, 1);
4968 SmallVector<int, 16>
Mask;
4969 Mask.push_back(Width);
4970 for (
unsigned i = 1; i < Width; i++)
4974 setShadow(&
I, Shadow);
4975 setOriginForNaryOp(
I);
4981 void handleRoundPdPsIntrinsic(IntrinsicInst &
I) {
4982 assert(
I.getArgOperand(0)->getType() ==
I.getType());
4987 ShadowAndOriginCombiner SC(
this, IRB);
4988 SC.Add(
I.getArgOperand(0));
4996 void handleAbsIntrinsic(IntrinsicInst &
I) {
4998 Value *Src =
I.getArgOperand(0);
4999 Value *IsIntMinPoison =
I.getArgOperand(1);
5001 assert(
I.getType()->isIntOrIntVectorTy());
5003 assert(Src->getType() ==
I.getType());
5009 Value *SrcShadow = getShadow(Src);
5013 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5016 Value *PoisonedShadow = getPoisonedShadow(Src);
5017 Value *PoisonedIfIntMinShadow =
5020 IRB.
CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5022 setShadow(&
I, Shadow);
5023 setOrigin(&
I, getOrigin(&
I, 0));
5026 void handleIsFpClass(IntrinsicInst &
I) {
5028 Value *Shadow = getShadow(&
I, 0);
5029 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5030 setOrigin(&
I, getOrigin(&
I, 0));
5033 void handleArithmeticWithOverflow(IntrinsicInst &
I) {
5035 Value *Shadow0 = getShadow(&
I, 0);
5036 Value *Shadow1 = getShadow(&
I, 1);
5039 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5045 setShadow(&
I, Shadow);
5046 setOriginForNaryOp(
I);
5052 Value *Shadow = getShadow(V);
5074 void handleAVX512VectorDownConvert(IntrinsicInst &
I) {
5079 Value *WriteThrough =
I.getOperand(1);
5083 assert(isFixedIntVector(WriteThrough));
5085 unsigned ANumElements =
5087 unsigned OutputNumElements =
5089 assert(ANumElements == OutputNumElements ||
5090 ANumElements * 2 == OutputNumElements);
5093 assert(
Mask->getType()->getScalarSizeInBits() == ANumElements);
5094 insertCheckShadowOf(Mask, &
I);
5105 if (ANumElements != OutputNumElements) {
5107 Mask = IRB.
CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5114 Value *AShadow = getShadow(
A);
5118 VectorType *ShadowType = maybeShrinkVectorShadowType(
A,
I);
5128 AShadow = IRB.
CreateTrunc(AShadow, ShadowType,
"_ms_trunc_shadow");
5129 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
5131 Value *WriteThroughShadow = getShadow(WriteThrough);
5134 setShadow(&
I, Shadow);
5135 setOriginForNaryOp(
I);
5169 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &
I,
5170 SmallVector<unsigned, 4> DataIndices,
5171 unsigned WriteThruIndex,
5172 unsigned MaskIndex) {
5175 unsigned NumArgs =
I.arg_size();
5177 assert(WriteThruIndex < NumArgs);
5178 assert(MaskIndex < NumArgs);
5179 assert(WriteThruIndex != MaskIndex);
5180 Value *WriteThru =
I.getOperand(WriteThruIndex);
5182 unsigned OutputNumElements =
5187 bool isData[16] = {
false};
5189 for (
unsigned i : DataIndices) {
5191 assert(i != WriteThruIndex);
5198 [[maybe_unused]]
unsigned ANumElements =
5200 assert(ANumElements == OutputNumElements);
5205 assert(isFixedFPVector(WriteThru));
5207 for (
unsigned i = 0; i < NumArgs; ++i) {
5208 if (!isData[i] && i != WriteThruIndex) {
5211 assert(
I.getOperand(i)->getType()->isIntegerTy());
5212 insertCheckShadowOf(
I.getOperand(i), &
I);
5217 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5218 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5219 assert(
Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5226 Value *DataShadow =
nullptr;
5227 for (
unsigned i : DataIndices) {
5230 DataShadow = IRB.
CreateOr(DataShadow, getShadow(
A));
5232 DataShadow = getShadow(
A);
5240 Value *WriteThruShadow = getShadow(WriteThru);
5243 setShadow(&
I, Shadow);
5245 setOriginForNaryOp(
I);
5255 void visitGenericScalarHalfwordInst(IntrinsicInst &
I) {
5261 Value *WriteThrough =
I.getOperand(2);
5268 insertCheckShadowOf(Mask, &
I);
5272 unsigned NumElements =
5274 assert(NumElements == 8);
5275 assert(
A->getType() ==
B->getType());
5277 assert(
Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5280 Value *ALowerShadow = extractLowerShadow(IRB,
A);
5281 Value *BLowerShadow = extractLowerShadow(IRB,
B);
5283 Value *ABLowerShadow = IRB.
CreateOr(ALowerShadow, BLowerShadow);
5285 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5292 Value *AShadow = getShadow(
A);
5293 Value *DstLowerShadow =
5294 IRB.
CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5296 AShadow, DstLowerShadow, ConstantInt::get(IRB.
getInt32Ty(), 0),
5299 setShadow(&
I, DstShadow);
5300 setOriginForNaryOp(
I);
5330 void handleAVXGF2P8Affine(IntrinsicInst &
I) {
5341 ->getScalarSizeInBits() == 8);
5343 assert(
A->getType() ==
X->getType());
5345 assert(
B->getType()->isIntegerTy());
5346 assert(
B->getType()->getScalarSizeInBits() == 8);
5348 assert(
I.getType() ==
A->getType());
5350 Value *AShadow = getShadow(
A);
5351 Value *XShadow = getShadow(
X);
5352 Value *BZeroShadow = getCleanShadow(
B);
5355 I.getType(),
I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5357 {X, AShadow, BZeroShadow});
5359 {XShadow, A, BZeroShadow});
5362 Value *BShadow = getShadow(
B);
5363 Value *BBroadcastShadow = getCleanShadow(AShadow);
5368 for (
unsigned i = 0; i < NumElements; i++)
5372 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5373 setOriginForNaryOp(
I);
5387 void handleNEONVectorLoad(IntrinsicInst &
I,
bool WithLane) {
5388 unsigned int numArgs =
I.arg_size();
5391 assert(
I.getType()->isStructTy());
5401 assert(4 <= numArgs && numArgs <= 6);
5415 for (
unsigned int i = 0; i < numArgs - 2; i++)
5416 ShadowArgs.
push_back(getShadow(
I.getArgOperand(i)));
5419 Value *LaneNumber =
I.getArgOperand(numArgs - 2);
5423 insertCheckShadowOf(LaneNumber, &
I);
5426 Value *Src =
I.getArgOperand(numArgs - 1);
5427 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
5429 Type *SrcShadowTy = getShadowTy(Src);
5430 auto [SrcShadowPtr, SrcOriginPtr] =
5431 getShadowOriginPtr(Src, IRB, SrcShadowTy,
Align(1),
false);
5441 if (!MS.TrackOrigins)
5445 setOrigin(&
I, PtrSrcOrigin);
5462 void handleNEONVectorStoreIntrinsic(IntrinsicInst &
I,
bool useLane) {
5466 int numArgOperands =
I.arg_size();
5469 assert(numArgOperands >= 1);
5470 Value *Addr =
I.getArgOperand(numArgOperands - 1);
5472 int skipTrailingOperands = 1;
5475 insertCheckShadowOf(Addr, &
I);
5479 skipTrailingOperands++;
5480 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
5482 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5485 SmallVector<Value *, 8> ShadowArgs;
5487 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5489 Value *Shadow = getShadow(&
I, i);
5490 ShadowArgs.
append(1, Shadow);
5507 (numArgOperands - skipTrailingOperands));
5508 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5512 I.getArgOperand(numArgOperands - skipTrailingOperands));
5514 Value *OutputShadowPtr, *OutputOriginPtr;
5516 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5517 Addr, IRB, OutputShadowTy,
Align(1),
true);
5518 ShadowArgs.
append(1, OutputShadowPtr);
5524 if (MS.TrackOrigins) {
5532 OriginCombiner OC(
this, IRB);
5533 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5534 OC.Add(
I.getArgOperand(i));
5536 const DataLayout &
DL =
F.getDataLayout();
5537 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
5599 void handleNEONMatrixMultiply(IntrinsicInst &
I) {
5603 Value *
R =
I.getArgOperand(0);
5604 Value *
A =
I.getArgOperand(1);
5605 Value *
B =
I.getArgOperand(2);
5607 assert(
I.getType() ==
R->getType());
5617 Value *ShadowR = getShadow(&
I, 0);
5618 Value *ShadowA = getShadow(&
I, 1);
5619 Value *ShadowB = getShadow(&
I, 2);
5623 FixedVectorType *ExpectedRTy =
5625 FixedVectorType *ExpectedATy =
5627 FixedVectorType *ExpectedBTy =
5634 assert(RTy == ExpectedRTy);
5635 assert(ATy == ExpectedATy);
5636 assert(BTy == ExpectedBTy);
5648 ShadowA = IRB.
CreateBitCast(ShadowA, getShadowTy(ExpectedATy));
5649 ShadowB = IRB.
CreateBitCast(ShadowB, getShadowTy(ExpectedBTy));
5660 getShadowTy(ExpectedATy));
5663 getShadowTy(ExpectedBTy));
5667 {getCleanShadow(ExpectedRTy), ShadowA, ShadowB});
5680 IRB.
CreateICmpNE(ShadowR, getCleanShadow(ExpectedRTy)), ExpectedRTy);
5682 setShadow(&
I, IRB.
CreateOr(ShadowAB, ShadowR));
5683 setOriginForNaryOp(
I);
5708 void handleIntrinsicByApplyingToShadow(IntrinsicInst &
I,
5710 unsigned int trailingVerbatimArgs) {
5713 assert(trailingVerbatimArgs <
I.arg_size());
5715 SmallVector<Value *, 8> ShadowArgs;
5717 for (
unsigned int i = 0; i <
I.arg_size() - trailingVerbatimArgs; i++) {
5718 Value *Shadow = getShadow(&
I, i);
5726 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5728 Value *Arg =
I.getArgOperand(i);
5734 Value *CombinedShadow = CI;
5737 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5740 CreateShadowCast(IRB, getShadow(&
I, i), CombinedShadow->
getType());
5741 CombinedShadow = IRB.
CreateOr(Shadow, CombinedShadow,
"_msprop");
5746 setOriginForNaryOp(
I);
5752 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &
I) {
5758 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &
I) {
5759 switch (
I.getIntrinsicID()) {
5760 case Intrinsic::uadd_with_overflow:
5761 case Intrinsic::sadd_with_overflow:
5762 case Intrinsic::usub_with_overflow:
5763 case Intrinsic::ssub_with_overflow:
5764 case Intrinsic::umul_with_overflow:
5765 case Intrinsic::smul_with_overflow:
5766 handleArithmeticWithOverflow(
I);
5768 case Intrinsic::abs:
5769 handleAbsIntrinsic(
I);
5771 case Intrinsic::bitreverse:
5772 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
5775 case Intrinsic::is_fpclass:
5778 case Intrinsic::lifetime_start:
5779 handleLifetimeStart(
I);
5781 case Intrinsic::launder_invariant_group:
5782 case Intrinsic::strip_invariant_group:
5783 handleInvariantGroup(
I);
5785 case Intrinsic::bswap:
5788 case Intrinsic::ctlz:
5789 case Intrinsic::cttz:
5790 handleCountLeadingTrailingZeros(
I);
5792 case Intrinsic::masked_compressstore:
5793 handleMaskedCompressStore(
I);
5795 case Intrinsic::masked_expandload:
5796 handleMaskedExpandLoad(
I);
5798 case Intrinsic::masked_gather:
5799 handleMaskedGather(
I);
5801 case Intrinsic::masked_scatter:
5802 handleMaskedScatter(
I);
5804 case Intrinsic::masked_store:
5805 handleMaskedStore(
I);
5807 case Intrinsic::masked_load:
5808 handleMaskedLoad(
I);
5810 case Intrinsic::vector_reduce_and:
5811 handleVectorReduceAndIntrinsic(
I);
5813 case Intrinsic::vector_reduce_or:
5814 handleVectorReduceOrIntrinsic(
I);
5817 case Intrinsic::vector_reduce_add:
5818 case Intrinsic::vector_reduce_xor:
5819 case Intrinsic::vector_reduce_mul:
5822 case Intrinsic::vector_reduce_smax:
5823 case Intrinsic::vector_reduce_smin:
5824 case Intrinsic::vector_reduce_umax:
5825 case Intrinsic::vector_reduce_umin:
5828 case Intrinsic::vector_reduce_fmax:
5829 case Intrinsic::vector_reduce_fmin:
5830 handleVectorReduceIntrinsic(
I,
false);
5833 case Intrinsic::vector_reduce_fadd:
5834 case Intrinsic::vector_reduce_fmul:
5835 handleVectorReduceWithStarterIntrinsic(
I);
5838 case Intrinsic::scmp:
5839 case Intrinsic::ucmp: {
5844 case Intrinsic::fshl:
5845 case Intrinsic::fshr:
5846 handleFunnelShift(
I);
5849 case Intrinsic::is_constant:
5851 setShadow(&
I, getCleanShadow(&
I));
5852 setOrigin(&
I, getCleanOrigin());
5862 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &
I) {
5863 switch (
I.getIntrinsicID()) {
5864 case Intrinsic::x86_sse_stmxcsr:
5867 case Intrinsic::x86_sse_ldmxcsr:
5874 case Intrinsic::x86_avx512_vcvtsd2usi64:
5875 case Intrinsic::x86_avx512_vcvtsd2usi32:
5876 case Intrinsic::x86_avx512_vcvtss2usi64:
5877 case Intrinsic::x86_avx512_vcvtss2usi32:
5878 case Intrinsic::x86_avx512_cvttss2usi64:
5879 case Intrinsic::x86_avx512_cvttss2usi:
5880 case Intrinsic::x86_avx512_cvttsd2usi64:
5881 case Intrinsic::x86_avx512_cvttsd2usi:
5882 case Intrinsic::x86_avx512_cvtusi2ss:
5883 case Intrinsic::x86_avx512_cvtusi642sd:
5884 case Intrinsic::x86_avx512_cvtusi642ss:
5885 handleSSEVectorConvertIntrinsic(
I, 1,
true);
5887 case Intrinsic::x86_sse2_cvtsd2si64:
5888 case Intrinsic::x86_sse2_cvtsd2si:
5889 case Intrinsic::x86_sse2_cvtsd2ss:
5890 case Intrinsic::x86_sse2_cvttsd2si64:
5891 case Intrinsic::x86_sse2_cvttsd2si:
5892 case Intrinsic::x86_sse_cvtss2si64:
5893 case Intrinsic::x86_sse_cvtss2si:
5894 case Intrinsic::x86_sse_cvttss2si64:
5895 case Intrinsic::x86_sse_cvttss2si:
5896 handleSSEVectorConvertIntrinsic(
I, 1);
5898 case Intrinsic::x86_sse_cvtps2pi:
5899 case Intrinsic::x86_sse_cvttps2pi:
5900 handleSSEVectorConvertIntrinsic(
I, 2);
5908 case Intrinsic::x86_vcvtps2ph_128:
5909 case Intrinsic::x86_vcvtps2ph_256: {
5910 handleSSEVectorConvertIntrinsicByProp(
I,
true);
5919 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
5920 handleAVX512VectorConvertFPToInt(
I,
false);
5925 case Intrinsic::x86_sse2_cvtpd2ps:
5926 case Intrinsic::x86_sse2_cvtps2dq:
5927 case Intrinsic::x86_sse2_cvtpd2dq:
5928 case Intrinsic::x86_sse2_cvttps2dq:
5929 case Intrinsic::x86_sse2_cvttpd2dq:
5930 case Intrinsic::x86_avx_cvt_pd2_ps_256:
5931 case Intrinsic::x86_avx_cvt_ps2dq_256:
5932 case Intrinsic::x86_avx_cvt_pd2dq_256:
5933 case Intrinsic::x86_avx_cvtt_ps2dq_256:
5934 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
5935 handleSSEVectorConvertIntrinsicByProp(
I,
false);
5946 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
5947 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
5948 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
5949 handleAVX512VectorConvertFPToInt(
I,
true);
5953 case Intrinsic::x86_avx512_psll_w_512:
5954 case Intrinsic::x86_avx512_psll_d_512:
5955 case Intrinsic::x86_avx512_psll_q_512:
5956 case Intrinsic::x86_avx512_pslli_w_512:
5957 case Intrinsic::x86_avx512_pslli_d_512:
5958 case Intrinsic::x86_avx512_pslli_q_512:
5959 case Intrinsic::x86_avx512_psrl_w_512:
5960 case Intrinsic::x86_avx512_psrl_d_512:
5961 case Intrinsic::x86_avx512_psrl_q_512:
5962 case Intrinsic::x86_avx512_psra_w_512:
5963 case Intrinsic::x86_avx512_psra_d_512:
5964 case Intrinsic::x86_avx512_psra_q_512:
5965 case Intrinsic::x86_avx512_psrli_w_512:
5966 case Intrinsic::x86_avx512_psrli_d_512:
5967 case Intrinsic::x86_avx512_psrli_q_512:
5968 case Intrinsic::x86_avx512_psrai_w_512:
5969 case Intrinsic::x86_avx512_psrai_d_512:
5970 case Intrinsic::x86_avx512_psrai_q_512:
5971 case Intrinsic::x86_avx512_psra_q_256:
5972 case Intrinsic::x86_avx512_psra_q_128:
5973 case Intrinsic::x86_avx512_psrai_q_256:
5974 case Intrinsic::x86_avx512_psrai_q_128:
5975 case Intrinsic::x86_avx2_psll_w:
5976 case Intrinsic::x86_avx2_psll_d:
5977 case Intrinsic::x86_avx2_psll_q:
5978 case Intrinsic::x86_avx2_pslli_w:
5979 case Intrinsic::x86_avx2_pslli_d:
5980 case Intrinsic::x86_avx2_pslli_q:
5981 case Intrinsic::x86_avx2_psrl_w:
5982 case Intrinsic::x86_avx2_psrl_d:
5983 case Intrinsic::x86_avx2_psrl_q:
5984 case Intrinsic::x86_avx2_psra_w:
5985 case Intrinsic::x86_avx2_psra_d:
5986 case Intrinsic::x86_avx2_psrli_w:
5987 case Intrinsic::x86_avx2_psrli_d:
5988 case Intrinsic::x86_avx2_psrli_q:
5989 case Intrinsic::x86_avx2_psrai_w:
5990 case Intrinsic::x86_avx2_psrai_d:
5991 case Intrinsic::x86_sse2_psll_w:
5992 case Intrinsic::x86_sse2_psll_d:
5993 case Intrinsic::x86_sse2_psll_q:
5994 case Intrinsic::x86_sse2_pslli_w:
5995 case Intrinsic::x86_sse2_pslli_d:
5996 case Intrinsic::x86_sse2_pslli_q:
5997 case Intrinsic::x86_sse2_psrl_w:
5998 case Intrinsic::x86_sse2_psrl_d:
5999 case Intrinsic::x86_sse2_psrl_q:
6000 case Intrinsic::x86_sse2_psra_w:
6001 case Intrinsic::x86_sse2_psra_d:
6002 case Intrinsic::x86_sse2_psrli_w:
6003 case Intrinsic::x86_sse2_psrli_d:
6004 case Intrinsic::x86_sse2_psrli_q:
6005 case Intrinsic::x86_sse2_psrai_w:
6006 case Intrinsic::x86_sse2_psrai_d:
6007 case Intrinsic::x86_mmx_psll_w:
6008 case Intrinsic::x86_mmx_psll_d:
6009 case Intrinsic::x86_mmx_psll_q:
6010 case Intrinsic::x86_mmx_pslli_w:
6011 case Intrinsic::x86_mmx_pslli_d:
6012 case Intrinsic::x86_mmx_pslli_q:
6013 case Intrinsic::x86_mmx_psrl_w:
6014 case Intrinsic::x86_mmx_psrl_d:
6015 case Intrinsic::x86_mmx_psrl_q:
6016 case Intrinsic::x86_mmx_psra_w:
6017 case Intrinsic::x86_mmx_psra_d:
6018 case Intrinsic::x86_mmx_psrli_w:
6019 case Intrinsic::x86_mmx_psrli_d:
6020 case Intrinsic::x86_mmx_psrli_q:
6021 case Intrinsic::x86_mmx_psrai_w:
6022 case Intrinsic::x86_mmx_psrai_d:
6023 handleVectorShiftIntrinsic(
I,
false);
6025 case Intrinsic::x86_avx2_psllv_d:
6026 case Intrinsic::x86_avx2_psllv_d_256:
6027 case Intrinsic::x86_avx512_psllv_d_512:
6028 case Intrinsic::x86_avx2_psllv_q:
6029 case Intrinsic::x86_avx2_psllv_q_256:
6030 case Intrinsic::x86_avx512_psllv_q_512:
6031 case Intrinsic::x86_avx2_psrlv_d:
6032 case Intrinsic::x86_avx2_psrlv_d_256:
6033 case Intrinsic::x86_avx512_psrlv_d_512:
6034 case Intrinsic::x86_avx2_psrlv_q:
6035 case Intrinsic::x86_avx2_psrlv_q_256:
6036 case Intrinsic::x86_avx512_psrlv_q_512:
6037 case Intrinsic::x86_avx2_psrav_d:
6038 case Intrinsic::x86_avx2_psrav_d_256:
6039 case Intrinsic::x86_avx512_psrav_d_512:
6040 case Intrinsic::x86_avx512_psrav_q_128:
6041 case Intrinsic::x86_avx512_psrav_q_256:
6042 case Intrinsic::x86_avx512_psrav_q_512:
6043 handleVectorShiftIntrinsic(
I,
true);
6047 case Intrinsic::x86_sse2_packsswb_128:
6048 case Intrinsic::x86_sse2_packssdw_128:
6049 case Intrinsic::x86_sse2_packuswb_128:
6050 case Intrinsic::x86_sse41_packusdw:
6051 case Intrinsic::x86_avx2_packsswb:
6052 case Intrinsic::x86_avx2_packssdw:
6053 case Intrinsic::x86_avx2_packuswb:
6054 case Intrinsic::x86_avx2_packusdw:
6060 case Intrinsic::x86_avx512_packsswb_512:
6061 case Intrinsic::x86_avx512_packssdw_512:
6062 case Intrinsic::x86_avx512_packuswb_512:
6063 case Intrinsic::x86_avx512_packusdw_512:
6064 handleVectorPackIntrinsic(
I);
6067 case Intrinsic::x86_sse41_pblendvb:
6068 case Intrinsic::x86_sse41_blendvpd:
6069 case Intrinsic::x86_sse41_blendvps:
6070 case Intrinsic::x86_avx_blendv_pd_256:
6071 case Intrinsic::x86_avx_blendv_ps_256:
6072 case Intrinsic::x86_avx2_pblendvb:
6073 handleBlendvIntrinsic(
I);
6076 case Intrinsic::x86_avx_dp_ps_256:
6077 case Intrinsic::x86_sse41_dppd:
6078 case Intrinsic::x86_sse41_dpps:
6079 handleDppIntrinsic(
I);
6082 case Intrinsic::x86_mmx_packsswb:
6083 case Intrinsic::x86_mmx_packuswb:
6084 handleVectorPackIntrinsic(
I, 16);
6087 case Intrinsic::x86_mmx_packssdw:
6088 handleVectorPackIntrinsic(
I, 32);
6091 case Intrinsic::x86_mmx_psad_bw:
6092 handleVectorSadIntrinsic(
I,
true);
6094 case Intrinsic::x86_sse2_psad_bw:
6095 case Intrinsic::x86_avx2_psad_bw:
6096 handleVectorSadIntrinsic(
I);
6122 case Intrinsic::x86_sse2_pmadd_wd:
6123 case Intrinsic::x86_avx2_pmadd_wd:
6124 case Intrinsic::x86_avx512_pmaddw_d_512:
6125 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6126 case Intrinsic::x86_avx2_pmadd_ub_sw:
6127 case Intrinsic::x86_avx512_pmaddubs_w_512:
6128 handleVectorDotProductIntrinsic(
I, 2,
6135 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6136 handleVectorDotProductIntrinsic(
I, 2,
6143 case Intrinsic::x86_mmx_pmadd_wd:
6144 handleVectorDotProductIntrinsic(
I, 2,
6153 case Intrinsic::aarch64_neon_bfmlalt:
6154 handleVectorDotProductIntrinsic(
I, 2,
6162 case Intrinsic::aarch64_neon_bfmlalb:
6163 handleVectorDotProductIntrinsic(
I, 2,
6261 case Intrinsic::x86_avx512_vpdpbusd_128:
6262 case Intrinsic::x86_avx512_vpdpbusd_256:
6263 case Intrinsic::x86_avx512_vpdpbusd_512:
6264 case Intrinsic::x86_avx512_vpdpbusds_128:
6265 case Intrinsic::x86_avx512_vpdpbusds_256:
6266 case Intrinsic::x86_avx512_vpdpbusds_512:
6267 case Intrinsic::x86_avx2_vpdpbssd_128:
6268 case Intrinsic::x86_avx2_vpdpbssd_256:
6269 case Intrinsic::x86_avx10_vpdpbssd_512:
6270 case Intrinsic::x86_avx2_vpdpbssds_128:
6271 case Intrinsic::x86_avx2_vpdpbssds_256:
6272 case Intrinsic::x86_avx10_vpdpbssds_512:
6273 case Intrinsic::x86_avx2_vpdpbsud_128:
6274 case Intrinsic::x86_avx2_vpdpbsud_256:
6275 case Intrinsic::x86_avx10_vpdpbsud_512:
6276 case Intrinsic::x86_avx2_vpdpbsuds_128:
6277 case Intrinsic::x86_avx2_vpdpbsuds_256:
6278 case Intrinsic::x86_avx10_vpdpbsuds_512:
6279 case Intrinsic::x86_avx2_vpdpbuud_128:
6280 case Intrinsic::x86_avx2_vpdpbuud_256:
6281 case Intrinsic::x86_avx10_vpdpbuud_512:
6282 case Intrinsic::x86_avx2_vpdpbuuds_128:
6283 case Intrinsic::x86_avx2_vpdpbuuds_256:
6284 case Intrinsic::x86_avx10_vpdpbuuds_512:
6285 handleVectorDotProductIntrinsic(
I, 4,
6383 case Intrinsic::x86_avx512_vpdpwssd_128:
6384 case Intrinsic::x86_avx512_vpdpwssd_256:
6385 case Intrinsic::x86_avx512_vpdpwssd_512:
6386 case Intrinsic::x86_avx512_vpdpwssds_128:
6387 case Intrinsic::x86_avx512_vpdpwssds_256:
6388 case Intrinsic::x86_avx512_vpdpwssds_512:
6389 case Intrinsic::x86_avx2_vpdpwsud_128:
6390 case Intrinsic::x86_avx2_vpdpwsud_256:
6391 case Intrinsic::x86_avx10_vpdpwsud_512:
6392 case Intrinsic::x86_avx2_vpdpwsuds_128:
6393 case Intrinsic::x86_avx2_vpdpwsuds_256:
6394 case Intrinsic::x86_avx10_vpdpwsuds_512:
6395 case Intrinsic::x86_avx2_vpdpwusd_128:
6396 case Intrinsic::x86_avx2_vpdpwusd_256:
6397 case Intrinsic::x86_avx10_vpdpwusd_512:
6398 case Intrinsic::x86_avx2_vpdpwusds_128:
6399 case Intrinsic::x86_avx2_vpdpwusds_256:
6400 case Intrinsic::x86_avx10_vpdpwusds_512:
6401 case Intrinsic::x86_avx2_vpdpwuud_128:
6402 case Intrinsic::x86_avx2_vpdpwuud_256:
6403 case Intrinsic::x86_avx10_vpdpwuud_512:
6404 case Intrinsic::x86_avx2_vpdpwuuds_128:
6405 case Intrinsic::x86_avx2_vpdpwuuds_256:
6406 case Intrinsic::x86_avx10_vpdpwuuds_512:
6407 handleVectorDotProductIntrinsic(
I, 2,
6421 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6422 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6423 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6424 handleVectorDotProductIntrinsic(
I, 2,
6430 case Intrinsic::x86_sse_cmp_ss:
6431 case Intrinsic::x86_sse2_cmp_sd:
6432 case Intrinsic::x86_sse_comieq_ss:
6433 case Intrinsic::x86_sse_comilt_ss:
6434 case Intrinsic::x86_sse_comile_ss:
6435 case Intrinsic::x86_sse_comigt_ss:
6436 case Intrinsic::x86_sse_comige_ss:
6437 case Intrinsic::x86_sse_comineq_ss:
6438 case Intrinsic::x86_sse_ucomieq_ss:
6439 case Intrinsic::x86_sse_ucomilt_ss:
6440 case Intrinsic::x86_sse_ucomile_ss:
6441 case Intrinsic::x86_sse_ucomigt_ss:
6442 case Intrinsic::x86_sse_ucomige_ss:
6443 case Intrinsic::x86_sse_ucomineq_ss:
6444 case Intrinsic::x86_sse2_comieq_sd:
6445 case Intrinsic::x86_sse2_comilt_sd:
6446 case Intrinsic::x86_sse2_comile_sd:
6447 case Intrinsic::x86_sse2_comigt_sd:
6448 case Intrinsic::x86_sse2_comige_sd:
6449 case Intrinsic::x86_sse2_comineq_sd:
6450 case Intrinsic::x86_sse2_ucomieq_sd:
6451 case Intrinsic::x86_sse2_ucomilt_sd:
6452 case Intrinsic::x86_sse2_ucomile_sd:
6453 case Intrinsic::x86_sse2_ucomigt_sd:
6454 case Intrinsic::x86_sse2_ucomige_sd:
6455 case Intrinsic::x86_sse2_ucomineq_sd:
6456 handleVectorCompareScalarIntrinsic(
I);
6459 case Intrinsic::x86_avx_cmp_pd_256:
6460 case Intrinsic::x86_avx_cmp_ps_256:
6461 case Intrinsic::x86_sse2_cmp_pd:
6462 case Intrinsic::x86_sse_cmp_ps:
6463 handleVectorComparePackedIntrinsic(
I,
true);
6466 case Intrinsic::x86_bmi_bextr_32:
6467 case Intrinsic::x86_bmi_bextr_64:
6468 case Intrinsic::x86_bmi_bzhi_32:
6469 case Intrinsic::x86_bmi_bzhi_64:
6470 case Intrinsic::x86_bmi_pdep_32:
6471 case Intrinsic::x86_bmi_pdep_64:
6472 case Intrinsic::x86_bmi_pext_32:
6473 case Intrinsic::x86_bmi_pext_64:
6474 handleBmiIntrinsic(
I);
6477 case Intrinsic::x86_pclmulqdq:
6478 case Intrinsic::x86_pclmulqdq_256:
6479 case Intrinsic::x86_pclmulqdq_512:
6480 handlePclmulIntrinsic(
I);
6483 case Intrinsic::x86_avx_round_pd_256:
6484 case Intrinsic::x86_avx_round_ps_256:
6485 case Intrinsic::x86_sse41_round_pd:
6486 case Intrinsic::x86_sse41_round_ps:
6487 handleRoundPdPsIntrinsic(
I);
6490 case Intrinsic::x86_sse41_round_sd:
6491 case Intrinsic::x86_sse41_round_ss:
6492 handleUnarySdSsIntrinsic(
I);
6495 case Intrinsic::x86_sse2_max_sd:
6496 case Intrinsic::x86_sse_max_ss:
6497 case Intrinsic::x86_sse2_min_sd:
6498 case Intrinsic::x86_sse_min_ss:
6499 handleBinarySdSsIntrinsic(
I);
6502 case Intrinsic::x86_avx_vtestc_pd:
6503 case Intrinsic::x86_avx_vtestc_pd_256:
6504 case Intrinsic::x86_avx_vtestc_ps:
6505 case Intrinsic::x86_avx_vtestc_ps_256:
6506 case Intrinsic::x86_avx_vtestnzc_pd:
6507 case Intrinsic::x86_avx_vtestnzc_pd_256:
6508 case Intrinsic::x86_avx_vtestnzc_ps:
6509 case Intrinsic::x86_avx_vtestnzc_ps_256:
6510 case Intrinsic::x86_avx_vtestz_pd:
6511 case Intrinsic::x86_avx_vtestz_pd_256:
6512 case Intrinsic::x86_avx_vtestz_ps:
6513 case Intrinsic::x86_avx_vtestz_ps_256:
6514 case Intrinsic::x86_avx_ptestc_256:
6515 case Intrinsic::x86_avx_ptestnzc_256:
6516 case Intrinsic::x86_avx_ptestz_256:
6517 case Intrinsic::x86_sse41_ptestc:
6518 case Intrinsic::x86_sse41_ptestnzc:
6519 case Intrinsic::x86_sse41_ptestz:
6520 handleVtestIntrinsic(
I);
6524 case Intrinsic::x86_ssse3_phadd_w:
6525 case Intrinsic::x86_ssse3_phadd_w_128:
6526 case Intrinsic::x86_ssse3_phsub_w:
6527 case Intrinsic::x86_ssse3_phsub_w_128:
6528 handlePairwiseShadowOrIntrinsic(
I, 1,
6532 case Intrinsic::x86_avx2_phadd_w:
6533 case Intrinsic::x86_avx2_phsub_w:
6534 handlePairwiseShadowOrIntrinsic(
I, 2,
6539 case Intrinsic::x86_ssse3_phadd_d:
6540 case Intrinsic::x86_ssse3_phadd_d_128:
6541 case Intrinsic::x86_ssse3_phsub_d:
6542 case Intrinsic::x86_ssse3_phsub_d_128:
6543 handlePairwiseShadowOrIntrinsic(
I, 1,
6547 case Intrinsic::x86_avx2_phadd_d:
6548 case Intrinsic::x86_avx2_phsub_d:
6549 handlePairwiseShadowOrIntrinsic(
I, 2,
6554 case Intrinsic::x86_ssse3_phadd_sw:
6555 case Intrinsic::x86_ssse3_phadd_sw_128:
6556 case Intrinsic::x86_ssse3_phsub_sw:
6557 case Intrinsic::x86_ssse3_phsub_sw_128:
6558 handlePairwiseShadowOrIntrinsic(
I, 1,
6562 case Intrinsic::x86_avx2_phadd_sw:
6563 case Intrinsic::x86_avx2_phsub_sw:
6564 handlePairwiseShadowOrIntrinsic(
I, 2,
6569 case Intrinsic::x86_sse3_hadd_ps:
6570 case Intrinsic::x86_sse3_hadd_pd:
6571 case Intrinsic::x86_sse3_hsub_ps:
6572 case Intrinsic::x86_sse3_hsub_pd:
6573 handlePairwiseShadowOrIntrinsic(
I, 1);
6576 case Intrinsic::x86_avx_hadd_pd_256:
6577 case Intrinsic::x86_avx_hadd_ps_256:
6578 case Intrinsic::x86_avx_hsub_pd_256:
6579 case Intrinsic::x86_avx_hsub_ps_256:
6580 handlePairwiseShadowOrIntrinsic(
I, 2);
6583 case Intrinsic::x86_avx_maskstore_ps:
6584 case Intrinsic::x86_avx_maskstore_pd:
6585 case Intrinsic::x86_avx_maskstore_ps_256:
6586 case Intrinsic::x86_avx_maskstore_pd_256:
6587 case Intrinsic::x86_avx2_maskstore_d:
6588 case Intrinsic::x86_avx2_maskstore_q:
6589 case Intrinsic::x86_avx2_maskstore_d_256:
6590 case Intrinsic::x86_avx2_maskstore_q_256: {
6591 handleAVXMaskedStore(
I);
6595 case Intrinsic::x86_avx_maskload_ps:
6596 case Intrinsic::x86_avx_maskload_pd:
6597 case Intrinsic::x86_avx_maskload_ps_256:
6598 case Intrinsic::x86_avx_maskload_pd_256:
6599 case Intrinsic::x86_avx2_maskload_d:
6600 case Intrinsic::x86_avx2_maskload_q:
6601 case Intrinsic::x86_avx2_maskload_d_256:
6602 case Intrinsic::x86_avx2_maskload_q_256: {
6603 handleAVXMaskedLoad(
I);
6608 case Intrinsic::x86_avx512fp16_add_ph_512:
6609 case Intrinsic::x86_avx512fp16_sub_ph_512:
6610 case Intrinsic::x86_avx512fp16_mul_ph_512:
6611 case Intrinsic::x86_avx512fp16_div_ph_512:
6612 case Intrinsic::x86_avx512fp16_max_ph_512:
6613 case Intrinsic::x86_avx512fp16_min_ph_512:
6614 case Intrinsic::x86_avx512_min_ps_512:
6615 case Intrinsic::x86_avx512_min_pd_512:
6616 case Intrinsic::x86_avx512_max_ps_512:
6617 case Intrinsic::x86_avx512_max_pd_512: {
6622 [[maybe_unused]]
bool Success =
6623 maybeHandleSimpleNomemIntrinsic(
I, 1);
6628 case Intrinsic::x86_avx_vpermilvar_pd:
6629 case Intrinsic::x86_avx_vpermilvar_pd_256:
6630 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6631 case Intrinsic::x86_avx_vpermilvar_ps:
6632 case Intrinsic::x86_avx_vpermilvar_ps_256:
6633 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6634 handleAVXVpermilvar(
I);
6638 case Intrinsic::x86_avx512_vpermi2var_d_128:
6639 case Intrinsic::x86_avx512_vpermi2var_d_256:
6640 case Intrinsic::x86_avx512_vpermi2var_d_512:
6641 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6642 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6643 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6644 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6645 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6646 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6647 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6648 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6649 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6650 case Intrinsic::x86_avx512_vpermi2var_q_128:
6651 case Intrinsic::x86_avx512_vpermi2var_q_256:
6652 case Intrinsic::x86_avx512_vpermi2var_q_512:
6653 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6654 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6655 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6656 handleAVXVpermi2var(
I);
6670 case Intrinsic::x86_avx2_pshuf_b:
6671 case Intrinsic::x86_sse_pshuf_w:
6672 case Intrinsic::x86_ssse3_pshuf_b_128:
6673 case Intrinsic::x86_ssse3_pshuf_b:
6674 case Intrinsic::x86_avx512_pshuf_b_512:
6675 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6681 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6682 case Intrinsic::x86_avx512_mask_pmov_db_512:
6683 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6684 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6687 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6695 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6696 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6697 handleIntrinsicByApplyingToShadow(
I,
6698 Intrinsic::x86_avx512_mask_pmov_dw_512,
6703 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6704 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6705 handleIntrinsicByApplyingToShadow(
I,
6706 Intrinsic::x86_avx512_mask_pmov_db_512,
6711 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
6712 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
6713 handleIntrinsicByApplyingToShadow(
I,
6714 Intrinsic::x86_avx512_mask_pmov_qb_512,
6719 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
6720 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
6721 handleIntrinsicByApplyingToShadow(
I,
6722 Intrinsic::x86_avx512_mask_pmov_qw_512,
6727 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
6728 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
6729 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
6730 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
6734 handleAVX512VectorDownConvert(
I);
6774 case Intrinsic::x86_avx512_rsqrt14_ps_512:
6775 case Intrinsic::x86_avx512_rsqrt14_ps_256:
6776 case Intrinsic::x86_avx512_rsqrt14_ps_128:
6777 case Intrinsic::x86_avx512_rsqrt14_pd_512:
6778 case Intrinsic::x86_avx512_rsqrt14_pd_256:
6779 case Intrinsic::x86_avx512_rsqrt14_pd_128:
6780 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
6781 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
6782 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
6783 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
6784 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
6785 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
6786 handleAVX512VectorGenericMaskedFP(
I, {0},
6827 case Intrinsic::x86_avx512_rcp14_ps_512:
6828 case Intrinsic::x86_avx512_rcp14_ps_256:
6829 case Intrinsic::x86_avx512_rcp14_ps_128:
6830 case Intrinsic::x86_avx512_rcp14_pd_512:
6831 case Intrinsic::x86_avx512_rcp14_pd_256:
6832 case Intrinsic::x86_avx512_rcp14_pd_128:
6833 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
6834 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
6835 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
6836 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
6837 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
6838 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
6839 handleAVX512VectorGenericMaskedFP(
I, {0},
6884 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
6885 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
6886 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
6887 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
6888 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
6889 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
6890 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
6891 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
6892 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
6893 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
6894 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
6895 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
6896 handleAVX512VectorGenericMaskedFP(
I, {0},
6932 case Intrinsic::x86_avx512_mask_scalef_pd_512:
6933 case Intrinsic::x86_avx512_mask_scalef_pd_256:
6934 case Intrinsic::x86_avx512_mask_scalef_pd_128:
6935 case Intrinsic::x86_avx512_mask_scalef_ps_512:
6936 case Intrinsic::x86_avx512_mask_scalef_ps_256:
6937 case Intrinsic::x86_avx512_mask_scalef_ps_128:
6938 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
6939 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
6940 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
6944 handleAVX512VectorGenericMaskedFP(
I, {0, 1},
6964 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
6965 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
6966 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
6967 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
6968 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
6969 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
6970 visitGenericScalarHalfwordInst(
I);
6975 case Intrinsic::x86_vgf2p8affineqb_128:
6976 case Intrinsic::x86_vgf2p8affineqb_256:
6977 case Intrinsic::x86_vgf2p8affineqb_512:
6978 handleAVXGF2P8Affine(
I);
6988 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &
I) {
6989 switch (
I.getIntrinsicID()) {
6993 case Intrinsic::aarch64_neon_rshrn:
6994 case Intrinsic::aarch64_neon_sqrshl:
6995 case Intrinsic::aarch64_neon_sqrshrn:
6996 case Intrinsic::aarch64_neon_sqrshrun:
6997 case Intrinsic::aarch64_neon_sqshl:
6998 case Intrinsic::aarch64_neon_sqshlu:
6999 case Intrinsic::aarch64_neon_sqshrn:
7000 case Intrinsic::aarch64_neon_sqshrun:
7001 case Intrinsic::aarch64_neon_srshl:
7002 case Intrinsic::aarch64_neon_sshl:
7003 case Intrinsic::aarch64_neon_uqrshl:
7004 case Intrinsic::aarch64_neon_uqrshrn:
7005 case Intrinsic::aarch64_neon_uqshl:
7006 case Intrinsic::aarch64_neon_uqshrn:
7007 case Intrinsic::aarch64_neon_urshl:
7008 case Intrinsic::aarch64_neon_ushl:
7009 handleVectorShiftIntrinsic(
I,
false);
7022 case Intrinsic::aarch64_neon_vsli:
7023 case Intrinsic::aarch64_neon_vsri:
7024 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7030 case Intrinsic::aarch64_neon_fmaxp:
7031 case Intrinsic::aarch64_neon_fminp:
7033 case Intrinsic::aarch64_neon_fmaxnmp:
7034 case Intrinsic::aarch64_neon_fminnmp:
7036 case Intrinsic::aarch64_neon_smaxp:
7037 case Intrinsic::aarch64_neon_sminp:
7038 case Intrinsic::aarch64_neon_umaxp:
7039 case Intrinsic::aarch64_neon_uminp:
7041 case Intrinsic::aarch64_neon_addp:
7043 case Intrinsic::aarch64_neon_faddp:
7045 case Intrinsic::aarch64_neon_saddlp:
7046 case Intrinsic::aarch64_neon_uaddlp: {
7047 handlePairwiseShadowOrIntrinsic(
I, 1);
7052 case Intrinsic::aarch64_neon_fcvtas:
7053 case Intrinsic::aarch64_neon_fcvtau:
7055 case Intrinsic::aarch64_neon_fcvtms:
7056 case Intrinsic::aarch64_neon_fcvtmu:
7058 case Intrinsic::aarch64_neon_fcvtns:
7059 case Intrinsic::aarch64_neon_fcvtnu:
7061 case Intrinsic::aarch64_neon_fcvtps:
7062 case Intrinsic::aarch64_neon_fcvtpu:
7064 case Intrinsic::aarch64_neon_fcvtzs:
7065 case Intrinsic::aarch64_neon_fcvtzu:
7067 case Intrinsic::aarch64_neon_fcvtxn:
7069 case Intrinsic::aarch64_neon_vcvthf2fp:
7070 case Intrinsic::aarch64_neon_vcvtfp2hf:
7071 handleNEONVectorConvertIntrinsic(
I,
false);
7075 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7076 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7077 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7078 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7079 handleNEONVectorConvertIntrinsic(
I,
true);
7088 case Intrinsic::aarch64_neon_faddv:
7089 case Intrinsic::aarch64_neon_saddv:
7090 case Intrinsic::aarch64_neon_uaddv:
7093 case Intrinsic::aarch64_neon_smaxv:
7094 case Intrinsic::aarch64_neon_sminv:
7095 case Intrinsic::aarch64_neon_umaxv:
7096 case Intrinsic::aarch64_neon_uminv:
7100 case Intrinsic::aarch64_neon_fmaxv:
7101 case Intrinsic::aarch64_neon_fminv:
7102 case Intrinsic::aarch64_neon_fmaxnmv:
7103 case Intrinsic::aarch64_neon_fminnmv:
7105 case Intrinsic::aarch64_neon_saddlv:
7106 case Intrinsic::aarch64_neon_uaddlv:
7107 handleVectorReduceIntrinsic(
I,
true);
7110 case Intrinsic::aarch64_neon_ld1x2:
7111 case Intrinsic::aarch64_neon_ld1x3:
7112 case Intrinsic::aarch64_neon_ld1x4:
7113 case Intrinsic::aarch64_neon_ld2:
7114 case Intrinsic::aarch64_neon_ld3:
7115 case Intrinsic::aarch64_neon_ld4:
7116 case Intrinsic::aarch64_neon_ld2r:
7117 case Intrinsic::aarch64_neon_ld3r:
7118 case Intrinsic::aarch64_neon_ld4r: {
7119 handleNEONVectorLoad(
I,
false);
7123 case Intrinsic::aarch64_neon_ld2lane:
7124 case Intrinsic::aarch64_neon_ld3lane:
7125 case Intrinsic::aarch64_neon_ld4lane: {
7126 handleNEONVectorLoad(
I,
true);
7131 case Intrinsic::aarch64_neon_sqxtn:
7132 case Intrinsic::aarch64_neon_sqxtun:
7133 case Intrinsic::aarch64_neon_uqxtn:
7140 case Intrinsic::aarch64_neon_st1x2:
7141 case Intrinsic::aarch64_neon_st1x3:
7142 case Intrinsic::aarch64_neon_st1x4:
7143 case Intrinsic::aarch64_neon_st2:
7144 case Intrinsic::aarch64_neon_st3:
7145 case Intrinsic::aarch64_neon_st4: {
7146 handleNEONVectorStoreIntrinsic(
I,
false);
7150 case Intrinsic::aarch64_neon_st2lane:
7151 case Intrinsic::aarch64_neon_st3lane:
7152 case Intrinsic::aarch64_neon_st4lane: {
7153 handleNEONVectorStoreIntrinsic(
I,
true);
7166 case Intrinsic::aarch64_neon_tbl1:
7167 case Intrinsic::aarch64_neon_tbl2:
7168 case Intrinsic::aarch64_neon_tbl3:
7169 case Intrinsic::aarch64_neon_tbl4:
7170 case Intrinsic::aarch64_neon_tbx1:
7171 case Intrinsic::aarch64_neon_tbx2:
7172 case Intrinsic::aarch64_neon_tbx3:
7173 case Intrinsic::aarch64_neon_tbx4: {
7175 handleIntrinsicByApplyingToShadow(
7176 I,
I.getIntrinsicID(),
7181 case Intrinsic::aarch64_neon_fmulx:
7182 case Intrinsic::aarch64_neon_pmul:
7183 case Intrinsic::aarch64_neon_pmull:
7184 case Intrinsic::aarch64_neon_smull:
7185 case Intrinsic::aarch64_neon_pmull64:
7186 case Intrinsic::aarch64_neon_umull: {
7187 handleNEONVectorMultiplyIntrinsic(
I);
7191 case Intrinsic::aarch64_neon_smmla:
7192 case Intrinsic::aarch64_neon_ummla:
7193 case Intrinsic::aarch64_neon_usmmla:
7194 case Intrinsic::aarch64_neon_bfmmla:
7195 handleNEONMatrixMultiply(
I);
7202 case Intrinsic::aarch64_neon_sdot:
7203 case Intrinsic::aarch64_neon_udot:
7204 case Intrinsic::aarch64_neon_usdot:
7205 handleVectorDotProductIntrinsic(
I, 4,
7215 case Intrinsic::aarch64_neon_bfdot:
7216 handleVectorDotProductIntrinsic(
I, 2,
7223 case Intrinsic::aarch64_neon_facge:
7224 case Intrinsic::aarch64_neon_facgt:
7225 handleVectorComparePackedIntrinsic(
I,
false);
7235 void visitIntrinsicInst(IntrinsicInst &
I) {
7236 if (maybeHandleCrossPlatformIntrinsic(
I))
7239 if (maybeHandleX86SIMDIntrinsic(
I))
7242 if (maybeHandleArmSIMDIntrinsic(
I))
7245 if (maybeHandleUnknownIntrinsic(
I))
7248 visitInstruction(
I);
7251 void visitLibAtomicLoad(CallBase &CB) {
7262 Value *NewOrdering =
7266 NextNodeIRBuilder NextIRB(&CB);
7267 Value *SrcShadowPtr, *SrcOriginPtr;
7268 std::tie(SrcShadowPtr, SrcOriginPtr) =
7269 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7271 Value *DstShadowPtr =
7272 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7276 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
7277 if (MS.TrackOrigins) {
7278 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7280 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7281 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7285 void visitLibAtomicStore(CallBase &CB) {
7292 Value *NewOrdering =
7296 Value *DstShadowPtr =
7306 void visitCallBase(CallBase &CB) {
7314 visitAsmInstruction(CB);
7316 visitInstruction(CB);
7325 case LibFunc_atomic_load:
7327 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
7331 visitLibAtomicLoad(CB);
7333 case LibFunc_atomic_store:
7334 visitLibAtomicStore(CB);
7350 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7354 Func->removeFnAttrs(
B);
7360 bool MayCheckCall = MS.EagerChecks;
7364 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
7367 unsigned ArgOffset = 0;
7370 if (!
A->getType()->isSized()) {
7371 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
7375 if (
A->getType()->isScalableTy()) {
7376 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
7378 insertCheckShadowOf(
A, &CB);
7383 const DataLayout &
DL =
F.getDataLayout();
7387 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7390 insertCheckShadowOf(
A, &CB);
7391 Size =
DL.getTypeAllocSize(
A->getType());
7397 Value *ArgShadow = getShadow(
A);
7398 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7400 <<
" Shadow: " << *ArgShadow <<
"\n");
7404 assert(
A->getType()->isPointerTy() &&
7405 "ByVal argument is not a pointer!");
7410 MaybeAlign Alignment = std::nullopt;
7413 Value *AShadowPtr, *AOriginPtr;
7414 std::tie(AShadowPtr, AOriginPtr) =
7415 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
7417 if (!PropagateShadow) {
7424 if (MS.TrackOrigins) {
7425 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7439 Size =
DL.getTypeAllocSize(
A->getType());
7445 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
7447 getOriginPtrForArgument(IRB, ArgOffset));
7450 assert(Store !=
nullptr);
7459 if (FT->isVarArg()) {
7460 VAHelper->visitCallBase(CB, IRB);
7470 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
7471 setShadow(&CB, getCleanShadow(&CB));
7472 setOrigin(&CB, getCleanOrigin());
7478 Value *
Base = getShadowPtrForRetval(IRBBefore);
7479 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
7491 setShadow(&CB, getCleanShadow(&CB));
7492 setOrigin(&CB, getCleanOrigin());
7499 "Could not find insertion point for retval shadow load");
7502 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7505 setShadow(&CB, RetvalShadow);
7506 if (MS.TrackOrigins)
7507 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7512 RetVal =
I->getOperand(0);
7515 return I->isMustTailCall();
7520 void visitReturnInst(ReturnInst &
I) {
7522 Value *RetVal =
I.getReturnValue();
7528 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7529 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
7530 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7533 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
7535 Value *Shadow = getShadow(RetVal);
7536 bool StoreOrigin =
true;
7538 insertCheckShadowOf(RetVal, &
I);
7539 Shadow = getCleanShadow(RetVal);
7540 StoreOrigin =
false;
7547 if (MS.TrackOrigins && StoreOrigin)
7548 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7552 void visitPHINode(PHINode &
I) {
7554 if (!PropagateShadow) {
7555 setShadow(&
I, getCleanShadow(&
I));
7556 setOrigin(&
I, getCleanOrigin());
7560 ShadowPHINodes.push_back(&
I);
7561 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
7563 if (MS.TrackOrigins)
7565 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
7568 Value *getLocalVarIdptr(AllocaInst &
I) {
7569 ConstantInt *IntConst =
7570 ConstantInt::get(Type::getInt32Ty((*
F.getParent()).getContext()), 0);
7571 return new GlobalVariable(*
F.getParent(), IntConst->
getType(),
7576 Value *getLocalVarDescription(AllocaInst &
I) {
7582 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7584 Value *ShadowBase, *OriginBase;
7585 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7589 IRB.
CreateMemSet(ShadowBase, PoisonValue, Len,
I.getAlign());
7592 if (PoisonStack && MS.TrackOrigins) {
7593 Value *Idptr = getLocalVarIdptr(
I);
7595 Value *Descr = getLocalVarDescription(
I);
7596 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
7597 {&I, Len, Idptr, Descr});
7599 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
7605 Value *Descr = getLocalVarDescription(
I);
7607 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
7609 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
7613 void instrumentAlloca(AllocaInst &
I, Instruction *InsPoint =
nullptr) {
7616 NextNodeIRBuilder IRB(InsPoint);
7619 if (MS.CompileKernel)
7620 poisonAllocaKmsan(
I, IRB, Len);
7622 poisonAllocaUserspace(
I, IRB, Len);
7625 void visitAllocaInst(AllocaInst &
I) {
7626 setShadow(&
I, getCleanShadow(&
I));
7627 setOrigin(&
I, getCleanOrigin());
7633 void visitSelectInst(SelectInst &
I) {
7639 handleSelectLikeInst(
I,
B,
C,
D);
7645 Value *Sb = getShadow(
B);
7646 Value *Sc = getShadow(
C);
7647 Value *Sd = getShadow(
D);
7649 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
7650 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
7651 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
7656 if (
I.getType()->isAggregateType()) {
7660 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
7661 }
else if (isScalableNonVectorType(
I.getType())) {
7669 Sa1 = getCleanShadow(getShadowTy(
I.getType()));
7677 C = CreateAppToShadowCast(IRB,
C);
7678 D = CreateAppToShadowCast(IRB,
D);
7685 if (MS.TrackOrigins) {
7688 if (
B->getType()->isVectorTy()) {
7689 B = convertToBool(
B, IRB);
7690 Sb = convertToBool(Sb, IRB);
7698 void visitLandingPadInst(LandingPadInst &
I) {
7701 setShadow(&
I, getCleanShadow(&
I));
7702 setOrigin(&
I, getCleanOrigin());
7705 void visitCatchSwitchInst(CatchSwitchInst &
I) {
7706 setShadow(&
I, getCleanShadow(&
I));
7707 setOrigin(&
I, getCleanOrigin());
7710 void visitFuncletPadInst(FuncletPadInst &
I) {
7711 setShadow(&
I, getCleanShadow(&
I));
7712 setOrigin(&
I, getCleanOrigin());
7715 void visitGetElementPtrInst(GetElementPtrInst &
I) { handleShadowOr(
I); }
7717 void visitExtractValueInst(ExtractValueInst &
I) {
7719 Value *Agg =
I.getAggregateOperand();
7721 Value *AggShadow = getShadow(Agg);
7725 setShadow(&
I, ResShadow);
7726 setOriginForNaryOp(
I);
7729 void visitInsertValueInst(InsertValueInst &
I) {
7732 Value *AggShadow = getShadow(
I.getAggregateOperand());
7733 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
7739 setOriginForNaryOp(
I);
7742 void dumpInst(Instruction &
I) {
7750 errs() <<
"ZZZ " <<
I.getOpcodeName() <<
"\n";
7757 unsigned NumOperands =
I.getNumOperands();
7759 errs() <<
"YYY call " << *
I.getType() <<
" @";
7771 errs() <<
"YYY " << *
I.getType() <<
" " <<
I.getOpcodeName() <<
"(";
7773 for (
size_t i = 0; i < NumOperands; i++) {
7788 errs() <<
"QQQ " <<
I <<
"\n";
7791 void visitResumeInst(ResumeInst &
I) {
7796 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
7801 void visitCatchReturnInst(CatchReturnInst &CRI) {
7806 void instrumentAsmArgument(
Value *Operand,
Type *ElemTy, Instruction &
I,
7815 insertCheckShadowOf(Operand, &
I);
7822 auto Size =
DL.getTypeStoreSize(ElemTy);
7824 if (MS.CompileKernel) {
7825 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
7831 auto [ShadowPtr,
_] =
7832 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
7842 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
7843 int NumRetOutputs = 0;
7850 NumRetOutputs =
ST->getNumElements();
7855 for (
const InlineAsm::ConstraintInfo &Info : Constraints) {
7856 switch (
Info.Type) {
7864 return NumOutputs - NumRetOutputs;
7867 void visitAsmInstruction(Instruction &
I) {
7883 const DataLayout &
DL =
F.getDataLayout();
7887 int OutputArgs = getNumOutputArgs(IA, CB);
7893 for (
int i = OutputArgs; i < NumOperands; i++) {
7901 for (
int i = 0; i < OutputArgs; i++) {
7907 setShadow(&
I, getCleanShadow(&
I));
7908 setOrigin(&
I, getCleanOrigin());
7911 void visitFreezeInst(FreezeInst &
I) {
7913 setShadow(&
I, getCleanShadow(&
I));
7914 setOrigin(&
I, getCleanOrigin());
7917 void visitInstruction(Instruction &
I) {
7922 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
7923 Value *Operand =
I.getOperand(i);
7925 insertCheckShadowOf(Operand, &
I);
7927 setShadow(&
I, getCleanShadow(&
I));
7928 setOrigin(&
I, getCleanOrigin());
7932struct VarArgHelperBase :
public VarArgHelper {
7934 MemorySanitizer &MS;
7935 MemorySanitizerVisitor &MSV;
7937 const unsigned VAListTagSize;
7939 VarArgHelperBase(Function &
F, MemorySanitizer &MS,
7940 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
7941 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
7945 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
7951 MS.VAArgTLS, ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg_va_s");
7960 return getShadowPtrForVAArgument(IRB, ArgOffset);
7969 ConstantInt::get(MS.IntptrTy, ArgOffset),
7974 unsigned BaseOffset) {
7983 TailSize,
Align(8));
7986 void unpoisonVAListTagForInst(IntrinsicInst &
I) {
7988 Value *VAListTag =
I.getArgOperand(0);
7990 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
7991 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
7994 VAListTagSize, Alignment,
false);
7997 void visitVAStartInst(VAStartInst &
I)
override {
7998 if (
F.getCallingConv() == CallingConv::Win64)
8001 unpoisonVAListTagForInst(
I);
8004 void visitVACopyInst(VACopyInst &
I)
override {
8005 if (
F.getCallingConv() == CallingConv::Win64)
8007 unpoisonVAListTagForInst(
I);
8012struct VarArgAMD64Helper :
public VarArgHelperBase {
8015 static const unsigned AMD64GpEndOffset = 48;
8016 static const unsigned AMD64FpEndOffsetSSE = 176;
8018 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8020 unsigned AMD64FpEndOffset;
8021 AllocaInst *VAArgTLSCopy =
nullptr;
8022 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8023 Value *VAArgOverflowSize =
nullptr;
8025 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8027 VarArgAMD64Helper(Function &
F, MemorySanitizer &MS,
8028 MemorySanitizerVisitor &MSV)
8029 : VarArgHelperBase(
F, MS, MSV, 24) {
8030 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8031 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
8032 if (Attr.isStringAttribute() &&
8033 (Attr.getKindAsString() ==
"target-features")) {
8034 if (Attr.getValueAsString().contains(
"-sse"))
8035 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8041 ArgKind classifyArgument(
Value *arg) {
8044 if (
T->isX86_FP80Ty())
8046 if (
T->isFPOrFPVectorTy())
8047 return AK_FloatingPoint;
8048 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
8049 return AK_GeneralPurpose;
8050 if (
T->isPointerTy())
8051 return AK_GeneralPurpose;
8063 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8064 unsigned GpOffset = 0;
8065 unsigned FpOffset = AMD64GpEndOffset;
8066 unsigned OverflowOffset = AMD64FpEndOffset;
8067 const DataLayout &
DL =
F.getDataLayout();
8071 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
8078 assert(
A->getType()->isPointerTy());
8080 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8081 uint64_t AlignedSize =
alignTo(ArgSize, 8);
8082 unsigned BaseOffset = OverflowOffset;
8083 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8084 Value *OriginBase =
nullptr;
8085 if (MS.TrackOrigins)
8086 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8087 OverflowOffset += AlignedSize;
8090 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8094 Value *ShadowPtr, *OriginPtr;
8095 std::tie(ShadowPtr, OriginPtr) =
8100 if (MS.TrackOrigins)
8104 ArgKind AK = classifyArgument(
A);
8105 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8107 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8109 Value *ShadowBase, *OriginBase =
nullptr;
8111 case AK_GeneralPurpose:
8112 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8113 if (MS.TrackOrigins)
8114 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8118 case AK_FloatingPoint:
8119 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8120 if (MS.TrackOrigins)
8121 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8128 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8129 uint64_t AlignedSize =
alignTo(ArgSize, 8);
8130 unsigned BaseOffset = OverflowOffset;
8131 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8132 if (MS.TrackOrigins) {
8133 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8135 OverflowOffset += AlignedSize;
8138 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8147 Value *Shadow = MSV.getShadow(
A);
8149 if (MS.TrackOrigins) {
8150 Value *Origin = MSV.getOrigin(
A);
8151 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8152 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8158 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8159 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8162 void finalizeInstrumentation()
override {
8163 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8164 "finalizeInstrumentation called twice");
8165 if (!VAStartInstrumentationList.
empty()) {
8172 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8173 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8179 Intrinsic::umin, CopySize,
8183 if (MS.TrackOrigins) {
8184 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8193 for (CallInst *OrigInst : VAStartInstrumentationList) {
8194 NextNodeIRBuilder IRB(OrigInst);
8195 Value *VAListTag = OrigInst->getArgOperand(0);
8197 Value *RegSaveAreaPtrPtr =
8198 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 16));
8200 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8202 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8203 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8205 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8207 if (MS.TrackOrigins)
8208 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8209 Alignment, AMD64FpEndOffset);
8210 Value *OverflowArgAreaPtrPtr =
8211 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 8));
8212 Value *OverflowArgAreaPtr =
8213 IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8214 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8215 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8216 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8220 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8222 if (MS.TrackOrigins) {
8225 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8233struct VarArgAArch64Helper :
public VarArgHelperBase {
8234 static const unsigned kAArch64GrArgSize = 64;
8235 static const unsigned kAArch64VrArgSize = 128;
8237 static const unsigned AArch64GrBegOffset = 0;
8238 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8240 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8241 static const unsigned AArch64VrEndOffset =
8242 AArch64VrBegOffset + kAArch64VrArgSize;
8243 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8245 AllocaInst *VAArgTLSCopy =
nullptr;
8246 Value *VAArgOverflowSize =
nullptr;
8248 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8250 VarArgAArch64Helper(Function &
F, MemorySanitizer &MS,
8251 MemorySanitizerVisitor &MSV)
8252 : VarArgHelperBase(
F, MS, MSV, 32) {}
8255 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
8256 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
8257 return {AK_GeneralPurpose, 1};
8258 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
8259 return {AK_FloatingPoint, 1};
8261 if (
T->isArrayTy()) {
8262 auto R = classifyArgument(
T->getArrayElementType());
8263 R.second *=
T->getScalarType()->getArrayNumElements();
8268 auto R = classifyArgument(FV->getScalarType());
8269 R.second *= FV->getNumElements();
8274 return {AK_Memory, 0};
8286 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8287 unsigned GrOffset = AArch64GrBegOffset;
8288 unsigned VrOffset = AArch64VrBegOffset;
8289 unsigned OverflowOffset = AArch64VAEndOffset;
8291 const DataLayout &
DL =
F.getDataLayout();
8294 auto [AK, RegNum] = classifyArgument(
A->getType());
8295 if (AK == AK_GeneralPurpose &&
8296 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8298 if (AK == AK_FloatingPoint &&
8299 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8303 case AK_GeneralPurpose:
8304 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8305 GrOffset += 8 * RegNum;
8307 case AK_FloatingPoint:
8308 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8309 VrOffset += 16 * RegNum;
8316 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8317 uint64_t AlignedSize =
alignTo(ArgSize, 8);
8318 unsigned BaseOffset = OverflowOffset;
8319 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8320 OverflowOffset += AlignedSize;
8323 CleanUnusedTLS(IRB,
Base, BaseOffset);
8335 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8336 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8341 Value *SaveAreaPtrPtr =
8342 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8343 return IRB.
CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8348 Value *SaveAreaPtr =
8349 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8351 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
8354 void finalizeInstrumentation()
override {
8355 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8356 "finalizeInstrumentation called twice");
8357 if (!VAStartInstrumentationList.empty()) {
8364 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8365 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8371 Intrinsic::umin, CopySize,
8377 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8378 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8382 for (CallInst *OrigInst : VAStartInstrumentationList) {
8383 NextNodeIRBuilder IRB(OrigInst);
8385 Value *VAListTag = OrigInst->getArgOperand(0);
8402 Value *StackSaveAreaPtr =
8403 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8406 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8407 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8410 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8413 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8414 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8417 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8423 Value *GrRegSaveAreaShadowPtrOff =
8424 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
8426 Value *GrRegSaveAreaShadowPtr =
8427 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8433 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8439 Value *VrRegSaveAreaShadowPtrOff =
8440 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
8442 Value *VrRegSaveAreaShadowPtr =
8443 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8450 VrRegSaveAreaShadowPtrOff);
8451 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8457 Value *StackSaveAreaShadowPtr =
8458 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8463 VAArgTLSCopy, IRB.
getInt32(AArch64VAEndOffset));
8466 Align(16), VAArgOverflowSize);
8472struct VarArgPowerPC64Helper :
public VarArgHelperBase {
8473 AllocaInst *VAArgTLSCopy =
nullptr;
8474 Value *VAArgSize =
nullptr;
8476 VarArgPowerPC64Helper(Function &
F, MemorySanitizer &MS,
8477 MemorySanitizerVisitor &MSV)
8478 : VarArgHelperBase(
F, MS, MSV, 8) {}
8480 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8488 Triple TargetTriple(
F.getParent()->getTargetTriple());
8492 if (TargetTriple.isPPC64ELFv2ABI())
8496 unsigned VAArgOffset = VAArgBase;
8497 const DataLayout &
DL =
F.getDataLayout();
8500 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
8502 assert(
A->getType()->isPointerTy());
8504 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8507 ArgAlign =
Align(8);
8508 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8511 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8513 Value *AShadowPtr, *AOriginPtr;
8514 std::tie(AShadowPtr, AOriginPtr) =
8515 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8525 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8527 if (
A->getType()->isArrayTy()) {
8530 Type *ElementTy =
A->getType()->getArrayElementType();
8532 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8533 }
else if (
A->getType()->isVectorTy()) {
8535 ArgAlign =
Align(ArgSize);
8538 ArgAlign =
Align(8);
8539 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8540 if (
DL.isBigEndian()) {
8544 VAArgOffset += (8 - ArgSize);
8548 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8552 VAArgOffset += ArgSize;
8556 VAArgBase = VAArgOffset;
8560 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8563 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8566 void finalizeInstrumentation()
override {
8567 assert(!VAArgSize && !VAArgTLSCopy &&
8568 "finalizeInstrumentation called twice");
8571 Value *CopySize = VAArgSize;
8573 if (!VAStartInstrumentationList.empty()) {
8577 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8583 Intrinsic::umin, CopySize,
8591 for (CallInst *OrigInst : VAStartInstrumentationList) {
8592 NextNodeIRBuilder IRB(OrigInst);
8593 Value *VAListTag = OrigInst->getArgOperand(0);
8596 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8599 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8600 const DataLayout &
DL =
F.getDataLayout();
8601 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8603 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8604 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8606 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8613struct VarArgPowerPC32Helper :
public VarArgHelperBase {
8614 AllocaInst *VAArgTLSCopy =
nullptr;
8615 Value *VAArgSize =
nullptr;
8617 VarArgPowerPC32Helper(Function &
F, MemorySanitizer &MS,
8618 MemorySanitizerVisitor &MSV)
8619 : VarArgHelperBase(
F, MS, MSV, 12) {}
8621 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8625 unsigned VAArgOffset = VAArgBase;
8626 const DataLayout &
DL =
F.getDataLayout();
8627 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8630 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
8632 assert(
A->getType()->isPointerTy());
8634 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8636 if (ArgAlign < IntptrSize)
8637 ArgAlign =
Align(IntptrSize);
8638 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8641 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8643 Value *AShadowPtr, *AOriginPtr;
8644 std::tie(AShadowPtr, AOriginPtr) =
8645 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8655 Type *ArgTy =
A->getType();
8661 uint64_t ArgSize =
DL.getTypeAllocSize(ArgTy);
8668 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8671 ArgAlign =
Align(ArgSize);
8673 if (ArgAlign < IntptrSize)
8674 ArgAlign =
Align(IntptrSize);
8675 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8676 if (
DL.isBigEndian()) {
8679 if (ArgSize < IntptrSize)
8680 VAArgOffset += (IntptrSize - ArgSize);
8683 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
8689 VAArgOffset += ArgSize;
8696 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8699 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8702 void finalizeInstrumentation()
override {
8703 assert(!VAArgSize && !VAArgTLSCopy &&
8704 "finalizeInstrumentation called twice");
8706 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
8707 Value *CopySize = VAArgSize;
8709 if (!VAStartInstrumentationList.empty()) {
8713 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8719 Intrinsic::umin, CopySize,
8727 for (CallInst *OrigInst : VAStartInstrumentationList) {
8728 NextNodeIRBuilder IRB(OrigInst);
8729 Value *VAListTag = OrigInst->getArgOperand(0);
8731 Value *RegSaveAreaSize = CopySize;
8735 IRB.
CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
8739 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
8741 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8744 const DataLayout &
DL =
F.getDataLayout();
8745 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8749 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8750 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8751 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8753 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
8754 Alignment, RegSaveAreaSize);
8756 RegSaveAreaShadowPtr =
8759 ConstantInt::get(MS.IntptrTy, 32));
8764 ConstantInt::get(MS.IntptrTy, 32), Alignment);
8769 Value *OverflowAreaSize = IRB.
CreateSub(CopySize, RegSaveAreaSize);
8772 OverflowAreaPtrPtr =
8773 IRB.
CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
8774 OverflowAreaPtrPtr = IRB.
CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
8776 Value *OverflowAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
8778 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
8779 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
8780 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.
getInt8Ty(),
8783 Value *OverflowVAArgTLSCopyPtr =
8785 OverflowVAArgTLSCopyPtr =
8786 IRB.
CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
8788 OverflowVAArgTLSCopyPtr =
8791 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
8798struct VarArgSystemZHelper :
public VarArgHelperBase {
8799 static const unsigned SystemZGpOffset = 16;
8800 static const unsigned SystemZGpEndOffset = 56;
8801 static const unsigned SystemZFpOffset = 128;
8802 static const unsigned SystemZFpEndOffset = 160;
8803 static const unsigned SystemZMaxVrArgs = 8;
8804 static const unsigned SystemZRegSaveAreaSize = 160;
8805 static const unsigned SystemZOverflowOffset = 160;
8806 static const unsigned SystemZVAListTagSize = 32;
8807 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
8808 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
8810 bool IsSoftFloatABI;
8811 AllocaInst *VAArgTLSCopy =
nullptr;
8812 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8813 Value *VAArgOverflowSize =
nullptr;
8815 enum class ArgKind {
8823 enum class ShadowExtension {
None,
Zero, Sign };
8825 VarArgSystemZHelper(Function &
F, MemorySanitizer &MS,
8826 MemorySanitizerVisitor &MSV)
8827 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
8828 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
8830 ArgKind classifyArgument(
Type *
T) {
8837 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
8838 return ArgKind::Indirect;
8839 if (
T->isFloatingPointTy())
8840 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
8841 if (
T->isIntegerTy() ||
T->isPointerTy())
8842 return ArgKind::GeneralPurpose;
8843 if (
T->isVectorTy())
8844 return ArgKind::Vector;
8845 return ArgKind::Memory;
8848 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
8858 return ShadowExtension::Zero;
8862 return ShadowExtension::Sign;
8864 return ShadowExtension::None;
8867 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8868 unsigned GpOffset = SystemZGpOffset;
8869 unsigned FpOffset = SystemZFpOffset;
8870 unsigned VrIndex = 0;
8871 unsigned OverflowOffset = SystemZOverflowOffset;
8872 const DataLayout &
DL =
F.getDataLayout();
8878 ArgKind AK = classifyArgument(
T);
8879 if (AK == ArgKind::Indirect) {
8881 AK = ArgKind::GeneralPurpose;
8883 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
8884 AK = ArgKind::Memory;
8885 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
8886 AK = ArgKind::Memory;
8887 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
8888 AK = ArgKind::Memory;
8889 Value *ShadowBase =
nullptr;
8890 Value *OriginBase =
nullptr;
8891 ShadowExtension SE = ShadowExtension::None;
8893 case ArgKind::GeneralPurpose: {
8895 uint64_t ArgSize = 8;
8898 SE = getShadowExtension(CB, ArgNo);
8899 uint64_t GapSize = 0;
8900 if (SE == ShadowExtension::None) {
8901 uint64_t ArgAllocSize =
DL.getTypeAllocSize(
T);
8902 assert(ArgAllocSize <= ArgSize);
8903 GapSize = ArgSize - ArgAllocSize;
8905 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
8906 if (MS.TrackOrigins)
8907 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
8909 GpOffset += ArgSize;
8915 case ArgKind::FloatingPoint: {
8917 uint64_t ArgSize = 8;
8924 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
8925 if (MS.TrackOrigins)
8926 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8928 FpOffset += ArgSize;
8934 case ArgKind::Vector: {
8941 case ArgKind::Memory: {
8946 uint64_t ArgAllocSize =
DL.getTypeAllocSize(
T);
8947 uint64_t ArgSize =
alignTo(ArgAllocSize, 8);
8949 SE = getShadowExtension(CB, ArgNo);
8951 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
8953 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
8954 if (MS.TrackOrigins)
8956 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
8957 OverflowOffset += ArgSize;
8964 case ArgKind::Indirect:
8967 if (ShadowBase ==
nullptr)
8969 Value *Shadow = MSV.getShadow(
A);
8970 if (SE != ShadowExtension::None)
8971 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
8972 SE == ShadowExtension::Sign);
8973 ShadowBase = IRB.
CreateIntToPtr(ShadowBase, MS.PtrTy,
"_msarg_va_s");
8975 if (MS.TrackOrigins) {
8976 Value *Origin = MSV.getOrigin(
A);
8977 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8978 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8982 Constant *OverflowSize = ConstantInt::get(
8983 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
8984 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8991 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
8994 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8996 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8997 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
9002 unsigned RegSaveAreaSize =
9003 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9004 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9006 if (MS.TrackOrigins)
9007 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9008 Alignment, RegSaveAreaSize);
9017 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9019 Value *OverflowArgAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9020 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9022 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9023 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
9026 SystemZOverflowOffset);
9027 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9029 if (MS.TrackOrigins) {
9031 SystemZOverflowOffset);
9032 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9037 void finalizeInstrumentation()
override {
9038 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9039 "finalizeInstrumentation called twice");
9040 if (!VAStartInstrumentationList.empty()) {
9047 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9049 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9055 Intrinsic::umin, CopySize,
9059 if (MS.TrackOrigins) {
9060 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9069 for (CallInst *OrigInst : VAStartInstrumentationList) {
9070 NextNodeIRBuilder IRB(OrigInst);
9071 Value *VAListTag = OrigInst->getArgOperand(0);
9072 copyRegSaveArea(IRB, VAListTag);
9073 copyOverflowArea(IRB, VAListTag);
9079struct VarArgI386Helper :
public VarArgHelperBase {
9080 AllocaInst *VAArgTLSCopy =
nullptr;
9081 Value *VAArgSize =
nullptr;
9083 VarArgI386Helper(Function &
F, MemorySanitizer &MS,
9084 MemorySanitizerVisitor &MSV)
9085 : VarArgHelperBase(
F, MS, MSV, 4) {}
9087 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9088 const DataLayout &
DL =
F.getDataLayout();
9089 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9090 unsigned VAArgOffset = 0;
9093 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
9095 assert(
A->getType()->isPointerTy());
9097 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9099 if (ArgAlign < IntptrSize)
9100 ArgAlign =
Align(IntptrSize);
9101 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9103 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9105 Value *AShadowPtr, *AOriginPtr;
9106 std::tie(AShadowPtr, AOriginPtr) =
9107 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9117 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9119 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9120 if (
DL.isBigEndian()) {
9123 if (ArgSize < IntptrSize)
9124 VAArgOffset += (IntptrSize - ArgSize);
9127 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9130 VAArgOffset += ArgSize;
9136 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9139 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9142 void finalizeInstrumentation()
override {
9143 assert(!VAArgSize && !VAArgTLSCopy &&
9144 "finalizeInstrumentation called twice");
9146 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9147 Value *CopySize = VAArgSize;
9149 if (!VAStartInstrumentationList.empty()) {
9152 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9158 Intrinsic::umin, CopySize,
9166 for (CallInst *OrigInst : VAStartInstrumentationList) {
9167 NextNodeIRBuilder IRB(OrigInst);
9168 Value *VAListTag = OrigInst->getArgOperand(0);
9169 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9170 Value *RegSaveAreaPtrPtr =
9172 PointerType::get(*MS.C, 0));
9173 Value *RegSaveAreaPtr =
9174 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9175 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9176 const DataLayout &
DL =
F.getDataLayout();
9177 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9179 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9180 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9182 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9190struct VarArgGenericHelper :
public VarArgHelperBase {
9191 AllocaInst *VAArgTLSCopy =
nullptr;
9192 Value *VAArgSize =
nullptr;
9194 VarArgGenericHelper(Function &
F, MemorySanitizer &MS,
9195 MemorySanitizerVisitor &MSV,
const unsigned VAListTagSize)
9196 : VarArgHelperBase(
F, MS, MSV, VAListTagSize) {}
9198 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9199 unsigned VAArgOffset = 0;
9200 const DataLayout &
DL =
F.getDataLayout();
9201 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9206 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9207 if (
DL.isBigEndian()) {
9210 if (ArgSize < IntptrSize)
9211 VAArgOffset += (IntptrSize - ArgSize);
9213 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9214 VAArgOffset += ArgSize;
9215 VAArgOffset =
alignTo(VAArgOffset, IntptrSize);
9221 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9224 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9227 void finalizeInstrumentation()
override {
9228 assert(!VAArgSize && !VAArgTLSCopy &&
9229 "finalizeInstrumentation called twice");
9231 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9232 Value *CopySize = VAArgSize;
9234 if (!VAStartInstrumentationList.empty()) {
9237 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9243 Intrinsic::umin, CopySize,
9251 for (CallInst *OrigInst : VAStartInstrumentationList) {
9252 NextNodeIRBuilder IRB(OrigInst);
9253 Value *VAListTag = OrigInst->getArgOperand(0);
9254 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9255 Value *RegSaveAreaPtrPtr =
9257 PointerType::get(*MS.C, 0));
9258 Value *RegSaveAreaPtr =
9259 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9260 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9261 const DataLayout &
DL =
F.getDataLayout();
9262 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9264 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9265 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9267 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9275using VarArgARM32Helper = VarArgGenericHelper;
9276using VarArgRISCVHelper = VarArgGenericHelper;
9277using VarArgMIPSHelper = VarArgGenericHelper;
9278using VarArgLoongArch64Helper = VarArgGenericHelper;
9281struct VarArgNoOpHelper :
public VarArgHelper {
9282 VarArgNoOpHelper(Function &
F, MemorySanitizer &MS,
9283 MemorySanitizerVisitor &MSV) {}
9285 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {}
9287 void visitVAStartInst(VAStartInst &
I)
override {}
9289 void visitVACopyInst(VACopyInst &
I)
override {}
9291 void finalizeInstrumentation()
override {}
9297 MemorySanitizerVisitor &Visitor) {
9300 Triple TargetTriple(Func.getParent()->getTargetTriple());
9303 return new VarArgI386Helper(Func, Msan, Visitor);
9306 return new VarArgAMD64Helper(Func, Msan, Visitor);
9308 if (TargetTriple.
isARM())
9309 return new VarArgARM32Helper(Func, Msan, Visitor, 4);
9312 return new VarArgAArch64Helper(Func, Msan, Visitor);
9315 return new VarArgSystemZHelper(Func, Msan, Visitor);
9320 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9323 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9326 return new VarArgRISCVHelper(Func, Msan, Visitor, 4);
9329 return new VarArgRISCVHelper(Func, Msan, Visitor, 8);
9332 return new VarArgMIPSHelper(Func, Msan, Visitor, 4);
9335 return new VarArgMIPSHelper(Func, Msan, Visitor, 8);
9338 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9341 return new VarArgNoOpHelper(Func, Msan, Visitor);
9348 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9351 MemorySanitizerVisitor Visitor(
F, *
this, TLI);
9358 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
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
void setAlignment(Align Align)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
const T & front() const
front - Get the first element.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
void removeFnAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the function.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Value * getCalledOperand() const
Type * getParamElementType(unsigned ArgNo) const
Extract the elementtype type for a parameter.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_SGT
signed greater than
@ ICMP_SGE
signed greater or equal
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true, bool ByteString=false)
This method constructs a CDS and initializes it with a text string.
static LLVM_ABI Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static bool shouldExecute(CounterInfo &Counter)
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
static FixedVectorType * getHalfElementsVectorType(FixedVectorType *VTy)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
LLVM_ABI void setComdat(Comdat *C)
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ ExternalLinkage
Externally visible function.
Analysis pass providing a never-invalidated alias analysis result.
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
LLVM_ABI CallInst * CreateMaskedCompressStore(Value *Val, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr)
Create a call to Masked Compress Store intrinsic.
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
LLVM_ABI CallInst * CreateAndReduce(Value *Src)
Create a vector int AND reduction intrinsic of the source vector.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
LLVM_ABI CallInst * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI DebugLoc getCurrentDebugLocation() const
Get location information used by debugging information.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memset to the specified pointer and the specified value.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
LLVMContext & getContext() const
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
LLVM_ABI CallInst * CreateMaskedStore(Value *Val, Value *Ptr, Align Alignment, Value *Mask)
Create a call to Masked Store intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
LLVM_ABI CallInst * CreateMaskedExpandLoad(Type *Ty, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Expand Load intrinsic.
Value * CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name="")
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LLVM_ABI CallInst * CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment, Value *Mask=nullptr)
Create a call to Masked Scatter intrinsic.
LLVM_ABI CallInst * CreateMaskedGather(Type *Ty, Value *Ptrs, Align Alignment, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Gather intrinsic.
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.