184#include "llvm/IR/IntrinsicsAArch64.h"
185#include "llvm/IR/IntrinsicsX86.h"
215#define DEBUG_TYPE "msan"
218 "Controls which checks to insert");
221 "Controls which instruction to instrument");
239 "msan-track-origins",
244 cl::desc(
"keep going after reporting a UMR"),
253 "msan-poison-stack-with-call",
258 "msan-poison-stack-pattern",
259 cl::desc(
"poison uninitialized stack variables with the given pattern"),
264 cl::desc(
"Print name of local stack variable"),
273 cl::desc(
"propagate shadow through ICmpEQ and ICmpNE"),
278 cl::desc(
"exact handling of relational integer ICmp"),
282 "msan-handle-lifetime-intrinsics",
284 "when possible, poison scoped variables at the beginning of the scope "
285 "(slower, but more precise)"),
296 "msan-handle-asm-conservative",
307 "msan-check-access-address",
308 cl::desc(
"report accesses through a pointer which has poisoned shadow"),
313 cl::desc(
"check arguments and return values at function call boundaries"),
317 "msan-dump-strict-instructions",
318 cl::desc(
"print out instructions with default strict semantics"),
322 "msan-instrumentation-with-call-threshold",
324 "If the function being instrumented requires more than "
325 "this number of checks and origin stores, use callbacks instead of "
326 "inline checks (-1 means never use callbacks)."),
331 cl::desc(
"Enable KernelMemorySanitizer instrumentation"),
341 cl::desc(
"Insert checks for constant shadow values"),
348 cl::desc(
"Place MSan constructors in comdat sections"),
354 cl::desc(
"Define custom MSan AndMask"),
358 cl::desc(
"Define custom MSan XorMask"),
362 cl::desc(
"Define custom MSan ShadowBase"),
366 cl::desc(
"Define custom MSan OriginBase"),
371 cl::desc(
"Define threshold for number of checks per "
372 "debug location to force origin update."),
384struct MemoryMapParams {
391struct PlatformMemoryMapParams {
392 const MemoryMapParams *bits32;
393 const MemoryMapParams *bits64;
539class MemorySanitizer {
548 MemorySanitizer(MemorySanitizer &&) =
delete;
549 MemorySanitizer &operator=(MemorySanitizer &&) =
delete;
550 MemorySanitizer(
const MemorySanitizer &) =
delete;
551 MemorySanitizer &operator=(
const MemorySanitizer &) =
delete;
556 friend struct MemorySanitizerVisitor;
557 friend struct VarArgHelperBase;
558 friend struct VarArgAMD64Helper;
559 friend struct VarArgMIPS64Helper;
560 friend struct VarArgAArch64Helper;
561 friend struct VarArgPowerPC64Helper;
562 friend struct VarArgSystemZHelper;
564 void initializeModule(
Module &M);
569 template <
typename... ArgsTy>
596 Value *ParamOriginTLS;
602 Value *RetvalOriginTLS;
608 Value *VAArgOriginTLS;
611 Value *VAArgOverflowSizeTLS;
614 bool CallbacksInitialized =
false;
659 Value *MsanMetadataAlloca;
665 const MemoryMapParams *MapParams;
669 MemoryMapParams CustomMapParams;
674 MDNode *OriginStoreWeights;
677void insertModuleCtor(
Module &M) {
705 Recover(getOptOrDefault(
ClKeepGoing, Kernel || R)),
723 MemorySanitizer Msan(*
F.getParent(),
Options);
742 OS, MapClassName2PassName);
749 OS <<
"eager-checks;";
750 OS <<
"track-origins=" <<
Options.TrackOrigins;
766template <
typename... ArgsTy>
774 std::forward<ArgsTy>(Args)...);
777 return M.getOrInsertFunction(
Name, MsanMetadata,
778 std::forward<ArgsTy>(Args)...);
787 RetvalOriginTLS =
nullptr;
789 ParamOriginTLS =
nullptr;
791 VAArgOriginTLS =
nullptr;
792 VAArgOverflowSizeTLS =
nullptr;
794 WarningFn =
M.getOrInsertFunction(
"__msan_warning",
796 IRB.getVoidTy(), IRB.getInt32Ty());
807 MsanGetContextStateFn =
M.getOrInsertFunction(
813 for (
int ind = 0, size = 1; ind < 4; ind++,
size <<= 1) {
814 std::string name_load =
815 "__msan_metadata_ptr_for_load_" + std::to_string(size);
816 std::string name_store =
817 "__msan_metadata_ptr_for_store_" + std::to_string(size);
818 MsanMetadataPtrForLoad_1_8[ind] = getOrInsertMsanMetadataFunction(
820 MsanMetadataPtrForStore_1_8[ind] = getOrInsertMsanMetadataFunction(
824 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
827 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
828 M,
"__msan_metadata_ptr_for_store_n",
832 MsanPoisonAllocaFn =
M.getOrInsertFunction(
833 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
834 MsanUnpoisonAllocaFn =
M.getOrInsertFunction(
835 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
839 return M.getOrInsertGlobal(
Name, Ty, [&] {
841 nullptr,
Name,
nullptr,
854 StringRef WarningFnName = Recover ?
"__msan_warning_with_origin"
855 :
"__msan_warning_with_origin_noreturn";
856 WarningFn =
M.getOrInsertFunction(WarningFnName,
858 IRB.getVoidTy(), IRB.getInt32Ty());
861 Recover ?
"__msan_warning" :
"__msan_warning_noreturn";
862 WarningFn =
M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
888 VAArgOverflowSizeTLS =
893 unsigned AccessSize = 1 << AccessSizeIndex;
894 std::string FunctionName =
"__msan_maybe_warning_" + itostr(AccessSize);
895 MaybeWarningFn[AccessSizeIndex] =
M.getOrInsertFunction(
897 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
899 FunctionName =
"__msan_maybe_store_origin_" + itostr(AccessSize);
900 MaybeStoreOriginFn[AccessSizeIndex] =
M.getOrInsertFunction(
902 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
906 MsanSetAllocaOriginWithDescriptionFn =
907 M.getOrInsertFunction(
"__msan_set_alloca_origin_with_descr",
908 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
909 MsanSetAllocaOriginNoDescriptionFn =
910 M.getOrInsertFunction(
"__msan_set_alloca_origin_no_descr",
911 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
912 MsanPoisonStackFn =
M.getOrInsertFunction(
"__msan_poison_stack",
913 IRB.getVoidTy(), PtrTy, IntptrTy);
919 if (CallbacksInitialized)
925 MsanChainOriginFn =
M.getOrInsertFunction(
926 "__msan_chain_origin",
929 MsanSetOriginFn =
M.getOrInsertFunction(
931 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
933 M.getOrInsertFunction(
"__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
935 M.getOrInsertFunction(
"__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
936 MemsetFn =
M.getOrInsertFunction(
"__msan_memset",
938 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
940 MsanInstrumentAsmStoreFn =
941 M.getOrInsertFunction(
"__msan_instrument_asm_store", IRB.getVoidTy(),
945 createKernelApi(M, TLI);
947 createUserspaceApi(M, TLI);
949 CallbacksInitialized =
true;
955 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
973void MemorySanitizer::initializeModule(
Module &M) {
974 auto &
DL =
M.getDataLayout();
976 TargetTriple =
Triple(
M.getTargetTriple());
978 bool ShadowPassed =
ClShadowBase.getNumOccurrences() > 0;
979 bool OriginPassed =
ClOriginBase.getNumOccurrences() > 0;
981 if (ShadowPassed || OriginPassed) {
986 MapParams = &CustomMapParams;
988 switch (TargetTriple.getOS()) {
990 switch (TargetTriple.getArch()) {
1005 switch (TargetTriple.getArch()) {
1014 switch (TargetTriple.getArch()) {
1048 C = &(
M.getContext());
1050 IntptrTy = IRB.getIntPtrTy(
DL);
1051 OriginTy = IRB.getInt32Ty();
1052 PtrTy = IRB.getPtrTy();
1057 if (!CompileKernel) {
1059 M.getOrInsertGlobal(
"__msan_track_origins", IRB.getInt32Ty(), [&] {
1060 return new GlobalVariable(
1061 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
1062 IRB.getInt32(TrackOrigins),
"__msan_track_origins");
1066 M.getOrInsertGlobal(
"__msan_keep_going", IRB.getInt32Ty(), [&] {
1067 return new GlobalVariable(M, IRB.getInt32Ty(), true,
1068 GlobalValue::WeakODRLinkage,
1069 IRB.getInt32(Recover),
"__msan_keep_going");
1084struct VarArgHelper {
1085 virtual ~VarArgHelper() =
default;
1100 virtual void finalizeInstrumentation() = 0;
1103struct MemorySanitizerVisitor;
1108 MemorySanitizerVisitor &Visitor);
1115 if (TypeSizeFixed <= 8)
1124class NextNodeIRBuilder :
public IRBuilder<> {
1137struct MemorySanitizerVisitor :
public InstVisitor<MemorySanitizerVisitor> {
1139 MemorySanitizer &MS;
1142 std::unique_ptr<VarArgHelper> VAHelper;
1150 bool PropagateShadow;
1154 struct ShadowOriginAndInsertPoint {
1160 : Shadow(S), Origin(
O), OrigIns(
I) {}
1168 int64_t SplittableBlocksCount = 0;
1170 MemorySanitizerVisitor(
Function &
F, MemorySanitizer &MS,
1173 bool SanitizeFunction =
1175 InsertChecks = SanitizeFunction;
1176 PropagateShadow = SanitizeFunction;
1186 MS.initializeCallbacks(*
F.getParent(), TLI);
1187 FnPrologueEnd =
IRBuilder<>(
F.getEntryBlock().getFirstNonPHI())
1190 if (MS.CompileKernel) {
1192 insertKmsanPrologue(IRB);
1196 <<
"MemorySanitizer is not inserting checks into '"
1197 <<
F.getName() <<
"'\n");
1200 bool instrumentWithCalls(
Value *V) {
1202 if (isa<Constant>(V))
1205 ++SplittableBlocksCount;
1211 return I.getParent() == FnPrologueEnd->
getParent() &&
1212 (&
I == FnPrologueEnd ||
I.comesBefore(FnPrologueEnd));
1220 if (MS.TrackOrigins <= 1)
1222 return IRB.
CreateCall(MS.MsanChainOriginFn, V);
1227 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1239 const Align IntptrAlignment =
DL.getABITypeAlign(MS.IntptrTy);
1240 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1252 auto [InsertPt,
Index] =
1264 Align CurrentAlignment = Alignment;
1265 if (Alignment >= IntptrAlignment && IntptrSize >
kOriginSize) {
1266 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1267 Value *IntptrOriginPtr =
1269 for (
unsigned i = 0; i <
Size / IntptrSize; ++i) {
1274 CurrentAlignment = IntptrAlignment;
1292 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1293 if (
auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1301 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1310 if (instrumentWithCalls(ConvertedShadow) &&
1313 Value *ConvertedShadow2 =
1319 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1323 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1328 void materializeStores() {
1331 Value *Val =
SI->getValueOperand();
1333 Value *Shadow =
SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1334 Value *ShadowPtr, *OriginPtr;
1336 const Align Alignment =
SI->getAlign();
1338 std::tie(ShadowPtr, OriginPtr) =
1339 getShadowOriginPtr(
Addr, IRB, ShadowTy, Alignment,
true);
1348 if (MS.TrackOrigins && !
SI->isAtomic())
1349 storeOrigin(IRB,
Addr, Shadow, getOrigin(Val), OriginPtr,
1356 if (MS.TrackOrigins < 2)
1359 if (LazyWarningDebugLocationCount.
empty())
1360 for (
const auto &
I : InstrumentationList)
1361 ++LazyWarningDebugLocationCount[
I.OrigIns->getDebugLoc()];
1375 if (
Instruction *OI = dyn_cast_or_null<Instruction>(Origin)) {
1377 auto NewDebugLoc = OI->getDebugLoc();
1384 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1385 Origin = updateOrigin(Origin, IRBOrigin);
1390 if (MS.CompileKernel || MS.TrackOrigins)
1404 if (instrumentWithCalls(ConvertedShadow) &&
1408 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1409 Value *ConvertedShadow2 =
1412 Fn, {ConvertedShadow2,
1413 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1417 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1420 !MS.Recover, MS.ColdCallWeights);
1423 insertWarningFn(IRB, Origin);
1428 void materializeInstructionChecks(
1433 bool Combine = !MS.TrackOrigins;
1435 Value *Shadow =
nullptr;
1436 for (
const auto &ShadowData : InstructionChecks) {
1440 Value *ConvertedShadow = ShadowData.Shadow;
1442 if (
auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1449 insertWarningFn(IRB, ShadowData.Origin);
1459 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1464 Shadow = ConvertedShadow;
1468 Shadow = convertToBool(Shadow, IRB,
"_mscmp");
1469 ConvertedShadow = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1470 Shadow = IRB.
CreateOr(Shadow, ConvertedShadow,
"_msor");
1476 materializeOneCheck(IRB, Shadow,
nullptr);
1480 void materializeChecks() {
1486 for (
auto I = InstrumentationList.begin();
1487 I != InstrumentationList.end();) {
1488 auto OrigIns =
I->OrigIns;
1492 auto J = std::find_if(
I + 1, InstrumentationList.end(),
1493 [OrigIns](
const ShadowOriginAndInsertPoint &R) {
1494 return OrigIns != R.OrigIns;
1508 MS.ParamTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1509 {Zero, IRB.getInt32(0)},
"param_shadow");
1510 MS.RetvalTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1511 {Zero, IRB.getInt32(1)},
"retval_shadow");
1512 MS.VAArgTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1513 {Zero, IRB.getInt32(2)},
"va_arg_shadow");
1514 MS.VAArgOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1515 {Zero, IRB.getInt32(3)},
"va_arg_origin");
1516 MS.VAArgOverflowSizeTLS =
1517 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1518 {Zero, IRB.getInt32(4)},
"va_arg_overflow_size");
1519 MS.ParamOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1520 {Zero, IRB.getInt32(5)},
"param_origin");
1521 MS.RetvalOriginTLS =
1522 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1523 {Zero, IRB.getInt32(6)},
"retval_origin");
1525 MS.MsanMetadataAlloca = IRB.
CreateAlloca(MS.MsanMetadata, 0u);
1542 for (
PHINode *PN : ShadowPHINodes) {
1543 PHINode *PNS = cast<PHINode>(getShadow(PN));
1544 PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr;
1545 size_t NumValues = PN->getNumIncomingValues();
1546 for (
size_t v = 0;
v < NumValues;
v++) {
1547 PNS->
addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1549 PNO->
addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1553 VAHelper->finalizeInstrumentation();
1557 if (InstrumentLifetimeStart) {
1558 for (
auto Item : LifetimeStartList) {
1559 instrumentAlloca(*Item.second, Item.first);
1560 AllocaSet.
remove(Item.second);
1566 instrumentAlloca(*AI);
1569 materializeChecks();
1573 materializeStores();
1579 Type *getShadowTy(
Value *V) {
return getShadowTy(
V->getType()); }
1591 if (
VectorType *VT = dyn_cast<VectorType>(OrigTy)) {
1592 uint32_t EltSize =
DL.getTypeSizeInBits(VT->getElementType());
1594 VT->getElementCount());
1596 if (
ArrayType *AT = dyn_cast<ArrayType>(OrigTy)) {
1597 return ArrayType::get(getShadowTy(AT->getElementType()),
1598 AT->getNumElements());
1600 if (
StructType *ST = dyn_cast<StructType>(OrigTy)) {
1602 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1603 Elements.push_back(getShadowTy(
ST->getElementType(i)));
1605 LLVM_DEBUG(
dbgs() <<
"getShadowTy: " << *ST <<
" ===> " << *Res <<
"\n");
1621 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1623 if (Aggregator != FalseVal)
1624 Aggregator = IRB.
CreateOr(Aggregator, ShadowBool);
1626 Aggregator = ShadowBool;
1635 if (!
Array->getNumElements())
1639 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1643 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1644 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
1654 return collapseStructShadow(
Struct, V, IRB);
1655 if (
ArrayType *Array = dyn_cast<ArrayType>(
V->getType()))
1656 return collapseArrayShadow(Array, V, IRB);
1657 if (isa<VectorType>(
V->getType())) {
1658 if (isa<ScalableVectorType>(
V->getType()))
1661 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1669 Type *VTy =
V->getType();
1671 return convertToBool(convertShadowToScalar(V, IRB), IRB,
name);
1678 Type *ptrToIntPtrType(
Type *PtrTy)
const {
1679 if (
VectorType *VectTy = dyn_cast<VectorType>(PtrTy)) {
1680 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1681 VectTy->getElementCount());
1687 Type *getPtrToShadowPtrType(
Type *IntPtrTy,
Type *ShadowTy)
const {
1688 if (
VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1689 return VectorType::get(
1690 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1691 VectTy->getElementCount());
1693 assert(IntPtrTy == MS.IntptrTy);
1694 return PointerType::get(*MS.C, 0);
1698 if (
VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1700 VectTy->getElementCount(), constToIntPtr(VectTy->getElementType(),
C));
1702 assert(IntPtrTy == MS.IntptrTy);
1703 return ConstantInt::get(MS.IntptrTy,
C);
1714 Type *IntptrTy = ptrToIntPtrType(
Addr->getType());
1717 if (
uint64_t AndMask = MS.MapParams->AndMask)
1718 OffsetLong = IRB.
CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1720 if (
uint64_t XorMask = MS.MapParams->XorMask)
1721 OffsetLong = IRB.
CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1733 std::pair<Value *, Value *>
1740 assert(VectTy->getElementType()->isPointerTy());
1742 Type *IntptrTy = ptrToIntPtrType(
Addr->getType());
1743 Value *ShadowOffset = getShadowPtrOffset(
Addr, IRB);
1744 Value *ShadowLong = ShadowOffset;
1745 if (
uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1747 IRB.
CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1750 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1752 Value *OriginPtr =
nullptr;
1753 if (MS.TrackOrigins) {
1754 Value *OriginLong = ShadowOffset;
1755 uint64_t OriginBase = MS.MapParams->OriginBase;
1756 if (OriginBase != 0)
1758 IRB.
CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1761 OriginLong = IRB.
CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1764 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1766 return std::make_pair(ShadowPtr, OriginPtr);
1769 template <
typename... ArgsTy>
1774 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1775 return IRB.
CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1778 return IRB.
CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1781 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(
Value *
Addr,
1785 Value *ShadowOriginPtrs;
1793 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1795 Value *SizeVal = ConstantInt::get(MS.IntptrTy,
Size);
1796 ShadowOriginPtrs = createMetadataCall(
1798 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1805 return std::make_pair(ShadowPtr, OriginPtr);
1811 std::pair<Value *, Value *> getShadowOriginPtrKernel(
Value *
Addr,
1818 return getShadowOriginPtrKernelNoVec(
Addr, IRB, ShadowTy,
isStore);
1822 unsigned NumElements = cast<FixedVectorType>(VectTy)->getNumElements();
1823 Value *ShadowPtrs = ConstantInt::getNullValue(
1825 Value *OriginPtrs =
nullptr;
1826 if (MS.TrackOrigins)
1827 OriginPtrs = ConstantInt::getNullValue(
1829 for (
unsigned i = 0; i < NumElements; ++i) {
1832 auto [ShadowPtr, OriginPtr] =
1833 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy,
isStore);
1836 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1837 if (MS.TrackOrigins)
1839 OriginPtrs, OriginPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1841 return {ShadowPtrs, OriginPtrs};
1848 if (MS.CompileKernel)
1849 return getShadowOriginPtrKernel(
Addr, IRB, ShadowTy,
isStore);
1850 return getShadowOriginPtrUserspace(
Addr, IRB, ShadowTy, Alignment);
1865 if (!MS.TrackOrigins)
1879 Value *getOriginPtrForRetval() {
1881 return MS.RetvalOriginTLS;
1886 assert(!ShadowMap.
count(V) &&
"Values may only have one shadow");
1887 ShadowMap[
V] = PropagateShadow ? SV : getCleanShadow(V);
1892 if (!MS.TrackOrigins)
1894 assert(!OriginMap.
count(V) &&
"Values may only have one origin");
1895 LLVM_DEBUG(
dbgs() <<
"ORIGIN: " << *V <<
" ==> " << *Origin <<
"\n");
1896 OriginMap[
V] = Origin;
1900 Type *ShadowTy = getShadowTy(OrigTy);
1910 Constant *getCleanShadow(
Value *V) {
return getCleanShadow(
V->getType()); }
1915 if (isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy))
1917 if (
ArrayType *AT = dyn_cast<ArrayType>(ShadowTy)) {
1919 getPoisonedShadow(AT->getElementType()));
1922 if (
StructType *ST = dyn_cast<StructType>(ShadowTy)) {
1924 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1925 Vals.
push_back(getPoisonedShadow(
ST->getElementType(i)));
1933 Type *ShadowTy = getShadowTy(V);
1936 return getPoisonedShadow(ShadowTy);
1948 if (!PropagateShadow ||
I->getMetadata(LLVMContext::MD_nosanitize))
1949 return getCleanShadow(V);
1951 Value *Shadow = ShadowMap[
V];
1953 LLVM_DEBUG(
dbgs() <<
"No shadow: " << *V <<
"\n" << *(
I->getParent()));
1955 assert(Shadow &&
"No shadow for a value");
1959 if (
UndefValue *U = dyn_cast<UndefValue>(V)) {
1960 Value *
AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
1961 : getCleanShadow(V);
1966 if (
Argument *
A = dyn_cast<Argument>(V)) {
1968 Value *&ShadowPtr = ShadowMap[
V];
1973 unsigned ArgOffset = 0;
1975 for (
auto &FArg :
F->args()) {
1976 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
1978 ?
"vscale not fully supported\n"
1979 :
"Arg is not sized\n"));
1981 ShadowPtr = getCleanShadow(V);
1982 setOrigin(
A, getCleanOrigin());
1988 unsigned Size = FArg.hasByValAttr()
1989 ?
DL.getTypeAllocSize(FArg.getParamByValType())
1990 :
DL.getTypeAllocSize(FArg.getType());
1994 if (FArg.hasByValAttr()) {
1998 const Align ArgAlign =
DL.getValueOrABITypeAlignment(
1999 FArg.getParamAlign(), FArg.getParamByValType());
2000 Value *CpShadowPtr, *CpOriginPtr;
2001 std::tie(CpShadowPtr, CpOriginPtr) =
2002 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
2004 if (!PropagateShadow || Overflow) {
2006 EntryIRB.CreateMemSet(
2010 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2012 Value *Cpy = EntryIRB.CreateMemCpy(CpShadowPtr, CopyAlign,
Base,
2017 if (MS.TrackOrigins) {
2019 getOriginPtrForArgument(EntryIRB, ArgOffset);
2023 EntryIRB.CreateMemCpy(
2032 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
2033 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
2034 ShadowPtr = getCleanShadow(V);
2035 setOrigin(
A, getCleanOrigin());
2038 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2039 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg),
Base,
2041 if (MS.TrackOrigins) {
2043 getOriginPtrForArgument(EntryIRB, ArgOffset);
2044 setOrigin(
A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
2048 <<
" ARG: " << FArg <<
" ==> " << *ShadowPtr <<
"\n");
2054 assert(ShadowPtr &&
"Could not find shadow for an argument");
2058 return getCleanShadow(V);
2063 return getShadow(
I->getOperand(i));
2068 if (!MS.TrackOrigins)
2070 if (!PropagateShadow || isa<Constant>(V) || isa<InlineAsm>(V))
2071 return getCleanOrigin();
2072 assert((isa<Instruction>(V) || isa<Argument>(V)) &&
2073 "Unexpected value type in getOrigin()");
2075 if (
I->getMetadata(LLVMContext::MD_nosanitize))
2076 return getCleanOrigin();
2078 Value *Origin = OriginMap[
V];
2079 assert(Origin &&
"Missing origin");
2085 return getOrigin(
I->getOperand(i));
2098 LLVM_DEBUG(
dbgs() <<
"Skipping check of " << *Shadow <<
" before "
2099 << *OrigIns <<
"\n");
2104 assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy) ||
2105 isa<StructType>(ShadowTy) || isa<ArrayType>(ShadowTy)) &&
2106 "Can only insert checks for integer, vector, and aggregate shadow "
2109 InstrumentationList.push_back(
2110 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2119 Value *Shadow, *Origin;
2121 Shadow = getShadow(Val);
2124 Origin = getOrigin(Val);
2126 Shadow = dyn_cast_or_null<Instruction>(getShadow(Val));
2129 Origin = dyn_cast_or_null<Instruction>(getOrigin(Val));
2131 insertShadowCheck(Shadow, Origin, OrigIns);
2136 case AtomicOrdering::NotAtomic:
2137 return AtomicOrdering::NotAtomic;
2138 case AtomicOrdering::Unordered:
2139 case AtomicOrdering::Monotonic:
2140 case AtomicOrdering::Release:
2141 return AtomicOrdering::Release;
2142 case AtomicOrdering::Acquire:
2143 case AtomicOrdering::AcquireRelease:
2144 return AtomicOrdering::AcquireRelease;
2145 case AtomicOrdering::SequentiallyConsistent:
2146 return AtomicOrdering::SequentiallyConsistent;
2152 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2153 uint32_t OrderingTable[NumOrderings] = {};
2155 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2156 OrderingTable[(
int)AtomicOrderingCABI::release] =
2157 (int)AtomicOrderingCABI::release;
2158 OrderingTable[(int)AtomicOrderingCABI::consume] =
2159 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2160 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2161 (
int)AtomicOrderingCABI::acq_rel;
2162 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2163 (
int)AtomicOrderingCABI::seq_cst;
2170 case AtomicOrdering::NotAtomic:
2171 return AtomicOrdering::NotAtomic;
2172 case AtomicOrdering::Unordered:
2173 case AtomicOrdering::Monotonic:
2174 case AtomicOrdering::Acquire:
2175 return AtomicOrdering::Acquire;
2176 case AtomicOrdering::Release:
2177 case AtomicOrdering::AcquireRelease:
2178 return AtomicOrdering::AcquireRelease;
2179 case AtomicOrdering::SequentiallyConsistent:
2180 return AtomicOrdering::SequentiallyConsistent;
2186 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2187 uint32_t OrderingTable[NumOrderings] = {};
2189 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2190 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2191 OrderingTable[(int)AtomicOrderingCABI::consume] =
2192 (
int)AtomicOrderingCABI::acquire;
2193 OrderingTable[(int)AtomicOrderingCABI::release] =
2194 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
2195 (int)AtomicOrderingCABI::acq_rel;
2196 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2197 (
int)AtomicOrderingCABI::seq_cst;
2205 if (
I.getMetadata(LLVMContext::MD_nosanitize))
2208 if (isInPrologue(
I))
2213 setShadow(&
I, getCleanShadow(&
I));
2214 setOrigin(&
I, getCleanOrigin());
2226 assert(
I.getType()->isSized() &&
"Load type must have size");
2227 assert(!
I.getMetadata(LLVMContext::MD_nosanitize));
2228 NextNodeIRBuilder IRB(&
I);
2229 Type *ShadowTy = getShadowTy(&
I);
2231 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
2232 const Align Alignment =
I.getAlign();
2233 if (PropagateShadow) {
2234 std::tie(ShadowPtr, OriginPtr) =
2235 getShadowOriginPtr(
Addr, IRB, ShadowTy, Alignment,
false);
2239 setShadow(&
I, getCleanShadow(&
I));
2243 insertShadowCheck(
I.getPointerOperand(), &
I);
2248 if (MS.TrackOrigins) {
2249 if (PropagateShadow) {
2254 setOrigin(&
I, getCleanOrigin());
2264 StoreList.push_back(&
I);
2266 insertShadowCheck(
I.getPointerOperand(), &
I);
2270 assert(isa<AtomicRMWInst>(
I) || isa<AtomicCmpXchgInst>(
I));
2274 Value *Val =
I.getOperand(1);
2275 Value *ShadowPtr = getShadowOriginPtr(
Addr, IRB, getShadowTy(Val),
Align(1),
2280 insertShadowCheck(
Addr, &
I);
2285 if (isa<AtomicCmpXchgInst>(
I))
2286 insertShadowCheck(Val, &
I);
2290 setShadow(&
I, getCleanShadow(&
I));
2291 setOrigin(&
I, getCleanOrigin());
2306 insertShadowCheck(
I.getOperand(1), &
I);
2310 setOrigin(&
I, getOrigin(&
I, 0));
2314 insertShadowCheck(
I.getOperand(2), &
I);
2316 auto *Shadow0 = getShadow(&
I, 0);
2317 auto *Shadow1 = getShadow(&
I, 1);
2320 setOriginForNaryOp(
I);
2325 auto *Shadow0 = getShadow(&
I, 0);
2326 auto *Shadow1 = getShadow(&
I, 1);
2329 setOriginForNaryOp(
I);
2335 setShadow(&
I, IRB.
CreateSExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2336 setOrigin(&
I, getOrigin(&
I, 0));
2341 setShadow(&
I, IRB.
CreateZExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2342 setOrigin(&
I, getOrigin(&
I, 0));
2347 setShadow(&
I, IRB.
CreateTrunc(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2348 setOrigin(&
I, getOrigin(&
I, 0));
2355 if (
auto *CI = dyn_cast<CallInst>(
I.getOperand(0)))
2356 if (CI->isMustTailCall())
2360 setOrigin(&
I, getOrigin(&
I, 0));
2366 "_msprop_ptrtoint"));
2367 setOrigin(&
I, getOrigin(&
I, 0));
2373 "_msprop_inttoptr"));
2374 setOrigin(&
I, getOrigin(&
I, 0));
2377 void visitFPToSIInst(
CastInst &
I) { handleShadowOr(
I); }
2378 void visitFPToUIInst(
CastInst &
I) { handleShadowOr(
I); }
2379 void visitSIToFPInst(
CastInst &
I) { handleShadowOr(
I); }
2380 void visitUIToFPInst(
CastInst &
I) { handleShadowOr(
I); }
2381 void visitFPExtInst(
CastInst &
I) { handleShadowOr(
I); }
2382 void visitFPTruncInst(
CastInst &
I) { handleShadowOr(
I); }
2397 Value *S2 = getShadow(&
I, 1);
2398 Value *V1 =
I.getOperand(0);
2407 setShadow(&
I, IRB.
CreateOr({S1S2, V1S2, S1V2}));
2408 setOriginForNaryOp(
I);
2419 Value *S2 = getShadow(&
I, 1);
2429 setShadow(&
I, IRB.
CreateOr({S1S2, V1S2, S1V2}));
2430 setOriginForNaryOp(
I);
2448 template <
bool CombineShadow>
class Combiner {
2449 Value *Shadow =
nullptr;
2450 Value *Origin =
nullptr;
2452 MemorySanitizerVisitor *MSV;
2456 : IRB(IRB), MSV(MSV) {}
2460 if (CombineShadow) {
2465 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2466 Shadow = IRB.
CreateOr(Shadow, OpShadow,
"_msprop");
2470 if (MSV->MS.TrackOrigins) {
2475 Constant *ConstOrigin = dyn_cast<Constant>(OpOrigin);
2477 if (!ConstOrigin || !ConstOrigin->
isNullValue()) {
2478 Value *
Cond = MSV->convertToBool(OpShadow, IRB);
2488 Value *OpShadow = MSV->getShadow(V);
2489 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) :
nullptr;
2490 return Add(OpShadow, OpOrigin);
2496 if (CombineShadow) {
2498 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(
I));
2499 MSV->setShadow(
I, Shadow);
2501 if (MSV->MS.TrackOrigins) {
2503 MSV->setOrigin(
I, Origin);
2510 if (MSV->MS.TrackOrigins) {
2522 if (!MS.TrackOrigins)
2525 OriginCombiner
OC(
this, IRB);
2526 for (
Use &
Op :
I.operands())
2531 size_t VectorOrPrimitiveTypeSizeInBits(
Type *Ty) {
2533 "Vector of pointers is not a valid shadow type");
2534 return Ty->
isVectorTy() ? cast<FixedVectorType>(Ty)->getNumElements() *
2543 Type *srcTy =
V->getType();
2546 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2547 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2548 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2554 cast<VectorType>(dstTy)->getElementCount() ==
2555 cast<VectorType>(srcTy)->getElementCount())
2566 Type *ShadowTy = getShadowTy(V);
2567 if (
V->getType() == ShadowTy)
2569 if (
V->getType()->isPtrOrPtrVectorTy())
2578 ShadowAndOriginCombiner
SC(
this, IRB);
2579 for (
Use &
Op :
I.operands())
2599 if (
auto *VTy = dyn_cast<VectorType>(Ty)) {
2600 unsigned NumElements = cast<FixedVectorType>(VTy)->getNumElements();
2601 Type *EltTy = VTy->getElementType();
2603 for (
unsigned Idx = 0;
Idx < NumElements; ++
Idx) {
2606 const APInt &
V = Elt->getValue();
2608 Elements.push_back(ConstantInt::get(EltTy, V2));
2610 Elements.push_back(ConstantInt::get(EltTy, 1));
2615 if (
ConstantInt *Elt = dyn_cast<ConstantInt>(ConstArg)) {
2616 const APInt &
V = Elt->getValue();
2618 ShadowMul = ConstantInt::get(Ty, V2);
2620 ShadowMul = ConstantInt::get(Ty, 1);
2626 IRB.
CreateMul(getShadow(OtherArg), ShadowMul,
"msprop_mul_cst"));
2627 setOrigin(&
I, getOrigin(OtherArg));
2631 Constant *constOp0 = dyn_cast<Constant>(
I.getOperand(0));
2632 Constant *constOp1 = dyn_cast<Constant>(
I.getOperand(1));
2633 if (constOp0 && !constOp1)
2634 handleMulByConstant(
I, constOp0,
I.getOperand(1));
2635 else if (constOp1 && !constOp0)
2636 handleMulByConstant(
I, constOp1,
I.getOperand(0));
2651 insertShadowCheck(
I.getOperand(1), &
I);
2652 setShadow(&
I, getShadow(&
I, 0));
2653 setOrigin(&
I, getOrigin(&
I, 0));
2670 void handleEqualityComparison(
ICmpInst &
I) {
2674 Value *Sa = getShadow(
A);
2675 Value *Sb = getShadow(
B);
2701 setOriginForNaryOp(
I);
2743 void handleRelationalComparisonExact(
ICmpInst &
I) {
2747 Value *Sa = getShadow(
A);
2748 Value *Sb = getShadow(
B);
2759 bool IsSigned =
I.isSigned();
2761 getLowestPossibleValue(IRB,
A, Sa, IsSigned),
2762 getHighestPossibleValue(IRB,
B, Sb, IsSigned));
2764 getHighestPossibleValue(IRB,
A, Sa, IsSigned),
2765 getLowestPossibleValue(IRB,
B, Sb, IsSigned));
2768 setOriginForNaryOp(
I);
2775 void handleSignedRelationalComparison(
ICmpInst &
I) {
2779 if ((constOp = dyn_cast<Constant>(
I.getOperand(1)))) {
2780 op =
I.getOperand(0);
2781 pre =
I.getPredicate();
2782 }
else if ((constOp = dyn_cast<Constant>(
I.getOperand(0)))) {
2783 op =
I.getOperand(1);
2784 pre =
I.getSwappedPredicate();
2797 setShadow(&
I, Shadow);
2798 setOrigin(&
I, getOrigin(
op));
2809 if (
I.isEquality()) {
2810 handleEqualityComparison(
I);
2816 handleRelationalComparisonExact(
I);
2820 handleSignedRelationalComparison(
I);
2825 if ((isa<Constant>(
I.getOperand(0)) || isa<Constant>(
I.getOperand(1)))) {
2826 handleRelationalComparisonExact(
I);
2833 void visitFCmpInst(
FCmpInst &
I) { handleShadowOr(
I); }
2840 Value *S2 = getShadow(&
I, 1);
2845 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
2846 setOriginForNaryOp(
I);
2857 Value *S0 = getShadow(&
I, 0);
2859 Value *S2 = getShadow(&
I, 2);
2864 I.getModule(),
I.getIntrinsicID(), S2Conv->
getType());
2866 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
2867 setOriginForNaryOp(
I);
2881 getShadow(
I.getArgOperand(1));
2884 {I.getArgOperand(0), I.getArgOperand(1),
2885 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
2886 I.eraseFromParent();
2904 getShadow(
I.getArgOperand(1));
2907 {I.getArgOperand(0), I.getArgOperand(1),
2908 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
2909 I.eraseFromParent();
2917 {I.getArgOperand(0),
2918 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
2919 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
2920 I.eraseFromParent();
2923 void visitVAStartInst(
VAStartInst &
I) { VAHelper->visitVAStartInst(
I); }
2925 void visitVACopyInst(
VACopyInst &
I) { VAHelper->visitVACopyInst(
I); }
2934 Value *Shadow = getShadow(&
I, 1);
2935 Value *ShadowPtr, *OriginPtr;
2939 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
2944 insertShadowCheck(
Addr, &
I);
2947 if (MS.TrackOrigins)
2960 Type *ShadowTy = getShadowTy(&
I);
2961 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
2962 if (PropagateShadow) {
2966 std::tie(ShadowPtr, OriginPtr) =
2967 getShadowOriginPtr(
Addr, IRB, ShadowTy, Alignment,
false);
2971 setShadow(&
I, getCleanShadow(&
I));
2975 insertShadowCheck(
Addr, &
I);
2977 if (MS.TrackOrigins) {
2978 if (PropagateShadow)
2979 setOrigin(&
I, IRB.
CreateLoad(MS.OriginTy, OriginPtr));
2981 setOrigin(&
I, getCleanOrigin());
2994 if (!(
RetTy->isIntOrIntVectorTy() ||
RetTy->isFPOrFPVectorTy()))
2997 unsigned NumArgOperands =
I.arg_size();
2998 for (
unsigned i = 0; i < NumArgOperands; ++i) {
2999 Type *Ty =
I.getArgOperand(i)->getType();
3005 ShadowAndOriginCombiner
SC(
this, IRB);
3006 for (
unsigned i = 0; i < NumArgOperands; ++i)
3007 SC.Add(
I.getArgOperand(i));
3024 unsigned NumArgOperands =
I.arg_size();
3025 if (NumArgOperands == 0)
3028 if (NumArgOperands == 2 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3029 I.getArgOperand(1)->getType()->isVectorTy() &&
3030 I.getType()->isVoidTy() && !
I.onlyReadsMemory()) {
3032 return handleVectorStoreIntrinsic(
I);
3035 if (NumArgOperands == 1 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3036 I.getType()->isVectorTy() &&
I.onlyReadsMemory()) {
3038 return handleVectorLoadIntrinsic(
I);
3041 if (
I.doesNotAccessMemory())
3042 if (maybeHandleSimpleNomemIntrinsic(
I))
3050 setShadow(&
I, getShadow(&
I, 0));
3051 setOrigin(&
I, getOrigin(&
I, 0));
3059 InstrumentLifetimeStart =
false;
3060 LifetimeStartList.push_back(std::make_pair(&
I, AI));
3066 Type *OpType =
Op->getType();
3068 F.getParent(), Intrinsic::bswap,
ArrayRef(&OpType, 1));
3070 setOrigin(&
I, getOrigin(
Op));
3075 Value *Src =
I.getArgOperand(0);
3081 Constant *IsZeroPoison = cast<Constant>(
I.getOperand(1));
3084 BoolShadow = IRB.
CreateOr(BoolShadow, BoolZeroPoison,
"_mscz_bs");
3087 Value *OutputShadow =
3088 IRB.
CreateSExt(BoolShadow, getShadowTy(Src),
"_mscz_os");
3090 setShadow(&
I, OutputShadow);
3091 setOriginForNaryOp(
I);
3109 void handleVectorConvertIntrinsic(
IntrinsicInst &
I,
int NumUsedElements,
3110 bool HasRoundingMode =
false) {
3112 Value *CopyOp, *ConvertOp;
3114 assert((!HasRoundingMode ||
3115 isa<ConstantInt>(
I.getArgOperand(
I.arg_size() - 1))) &&
3116 "Invalid rounding mode");
3118 switch (
I.arg_size() - HasRoundingMode) {
3120 CopyOp =
I.getArgOperand(0);
3121 ConvertOp =
I.getArgOperand(1);
3124 ConvertOp =
I.getArgOperand(0);
3138 Value *ConvertShadow = getShadow(ConvertOp);
3139 Value *AggShadow =
nullptr;
3142 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
3143 for (
int i = 1; i < NumUsedElements; ++i) {
3145 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
3146 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
3149 AggShadow = ConvertShadow;
3152 insertShadowCheck(AggShadow, getOrigin(ConvertOp), &
I);
3159 Value *ResultShadow = getShadow(CopyOp);
3160 Type *EltTy = cast<VectorType>(ResultShadow->
getType())->getElementType();
3161 for (
int i = 0; i < NumUsedElements; ++i) {
3163 ResultShadow, ConstantInt::getNullValue(EltTy),
3166 setShadow(&
I, ResultShadow);
3167 setOrigin(&
I, getOrigin(CopyOp));
3169 setShadow(&
I, getCleanShadow(&
I));
3170 setOrigin(&
I, getCleanOrigin());
3178 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
3181 return CreateShadowCast(IRB, S2,
T,
true);
3189 return CreateShadowCast(IRB, S2,
T,
true);
3206 void handleVectorShiftIntrinsic(
IntrinsicInst &
I,
bool Variable) {
3212 Value *S2 = getShadow(&
I, 1);
3213 Value *S2Conv = Variable ? VariableShadowExtend(IRB, S2)
3214 : Lower64ShadowExtend(IRB, S2, getShadowTy(&
I));
3215 Value *V1 =
I.getOperand(0);
3218 {IRB.CreateBitCast(S1, V1->getType()), V2});
3220 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3221 setOriginForNaryOp(
I);
3225 Type *getMMXVectorTy(
unsigned EltSizeInBits) {
3226 const unsigned X86_MMXSizeInBits = 64;
3227 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3228 "Illegal MMX vector element size");
3230 X86_MMXSizeInBits / EltSizeInBits);
3237 case Intrinsic::x86_sse2_packsswb_128:
3238 case Intrinsic::x86_sse2_packuswb_128:
3239 return Intrinsic::x86_sse2_packsswb_128;
3241 case Intrinsic::x86_sse2_packssdw_128:
3242 case Intrinsic::x86_sse41_packusdw:
3243 return Intrinsic::x86_sse2_packssdw_128;
3245 case Intrinsic::x86_avx2_packsswb:
3246 case Intrinsic::x86_avx2_packuswb:
3247 return Intrinsic::x86_avx2_packsswb;
3249 case Intrinsic::x86_avx2_packssdw:
3250 case Intrinsic::x86_avx2_packusdw:
3251 return Intrinsic::x86_avx2_packssdw;
3253 case Intrinsic::x86_mmx_packsswb:
3254 case Intrinsic::x86_mmx_packuswb:
3255 return Intrinsic::x86_mmx_packsswb;
3257 case Intrinsic::x86_mmx_packssdw:
3258 return Intrinsic::x86_mmx_packssdw;
3272 unsigned MMXEltSizeInBits = 0) {
3276 Value *S2 = getShadow(&
I, 1);
3277 assert(
S1->getType()->isVectorTy());
3283 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) :
S1->
getType();
3284 if (MMXEltSizeInBits) {
3292 if (MMXEltSizeInBits) {
3298 F.getParent(), getSignedPackIntrinsic(
I.getIntrinsicID()));
3301 IRB.
CreateCall(ShadowFn, {S1_ext, S2_ext},
"_msprop_vector_pack");
3302 if (MMXEltSizeInBits)
3305 setOriginForNaryOp(
I);
3309 Constant *createDppMask(
unsigned Width,
unsigned Mask) {
3322 const unsigned Width =
3323 cast<FixedVectorType>(S->
getType())->getNumElements();
3329 Value *DstMaskV = createDppMask(Width, DstMask);
3349 Value *S0 = getShadow(&
I, 0);
3353 const unsigned Width =
3354 cast<FixedVectorType>(S->
getType())->getNumElements();
3355 assert(Width == 2 || Width == 4 || Width == 8);
3357 const unsigned Mask = cast<ConstantInt>(
I.getArgOperand(2))->getZExtValue();
3358 const unsigned SrcMask =
Mask >> 4;
3359 const unsigned DstMask =
Mask & 0xf;
3362 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3367 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3374 setOriginForNaryOp(
I);
3378 C = CreateAppToShadowCast(IRB,
C);
3392 Value *Sc = getShadow(&
I, 2);
3393 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
3398 C = convertBlendvToSelectMask(IRB,
C);
3399 Sc = convertBlendvToSelectMask(IRB, Sc);
3405 handleSelectLikeInst(
I,
C,
T,
F);
3409 void handleVectorSadIntrinsic(
IntrinsicInst &
I,
bool IsMMX =
false) {
3410 const unsigned SignificantBitsPerResultElement = 16;
3412 unsigned ZeroBitsPerResultElement =
3416 auto *Shadow0 = getShadow(&
I, 0);
3417 auto *Shadow1 = getShadow(&
I, 1);
3422 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
3425 setOriginForNaryOp(
I);
3430 unsigned MMXEltSizeInBits = 0) {
3432 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits * 2) :
I.
getType();
3434 auto *Shadow0 = getShadow(&
I, 0);
3435 auto *Shadow1 = getShadow(&
I, 1);
3442 setOriginForNaryOp(
I);
3450 Type *ResTy = getShadowTy(&
I);
3451 auto *Shadow0 = getShadow(&
I, 0);
3452 auto *Shadow1 = getShadow(&
I, 1);
3457 setOriginForNaryOp(
I);
3465 auto *Shadow0 = getShadow(&
I, 0);
3466 auto *Shadow1 = getShadow(&
I, 1);
3468 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&
I));
3470 setOriginForNaryOp(
I);
3479 setOrigin(&
I, getOrigin(&
I, 0));
3487 Value *OperandShadow = getShadow(&
I, 0);
3489 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
3497 setOrigin(&
I, getOrigin(&
I, 0));
3505 Value *OperandShadow = getShadow(&
I, 0);
3506 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
3514 setOrigin(&
I, getOrigin(&
I, 0));
3522 getShadowOriginPtr(
Addr, IRB, Ty,
Align(1),
true).first;
3527 insertShadowCheck(
Addr, &
I);
3538 Value *ShadowPtr, *OriginPtr;
3539 std::tie(ShadowPtr, OriginPtr) =
3540 getShadowOriginPtr(
Addr, IRB, Ty, Alignment,
false);
3543 insertShadowCheck(
Addr, &
I);
3546 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
3548 insertShadowCheck(Shadow, Origin, &
I);
3555 Value *PassThru =
I.getArgOperand(2);
3558 insertShadowCheck(
Ptr, &
I);
3559 insertShadowCheck(Mask, &
I);
3562 if (!PropagateShadow) {
3563 setShadow(&
I, getCleanShadow(&
I));
3564 setOrigin(&
I, getCleanOrigin());
3568 Type *ShadowTy = getShadowTy(&
I);
3569 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
3570 auto [ShadowPtr, OriginPtr] =
3571 getShadowOriginPtr(
Ptr, IRB, ElementShadowTy, {},
false);
3574 ShadowTy, ShadowPtr, Mask, getShadow(PassThru),
"_msmaskedexpload");
3576 setShadow(&
I, Shadow);
3579 setOrigin(&
I, getCleanOrigin());
3584 Value *Values =
I.getArgOperand(0);
3589 insertShadowCheck(
Ptr, &
I);
3590 insertShadowCheck(Mask, &
I);
3593 Value *Shadow = getShadow(Values);
3594 Type *ElementShadowTy =
3595 getShadowTy(cast<VectorType>(Values->
getType())->getElementType());
3596 auto [ShadowPtr, OriginPtrs] =
3597 getShadowOriginPtr(
Ptr, IRB, ElementShadowTy, {},
true);
3606 Value *Ptrs =
I.getArgOperand(0);
3607 const Align Alignment(
3608 cast<ConstantInt>(
I.getArgOperand(1))->getZExtValue());
3610 Value *PassThru =
I.getArgOperand(3);
3612 Type *PtrsShadowTy = getShadowTy(Ptrs);
3614 insertShadowCheck(Mask, &
I);
3618 insertShadowCheck(MaskedPtrShadow, getOrigin(Ptrs), &
I);
3621 if (!PropagateShadow) {
3622 setShadow(&
I, getCleanShadow(&
I));
3623 setOrigin(&
I, getCleanOrigin());
3627 Type *ShadowTy = getShadowTy(&
I);
3628 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
3629 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
3630 Ptrs, IRB, ElementShadowTy, Alignment,
false);
3634 getShadow(PassThru),
"_msmaskedgather");
3636 setShadow(&
I, Shadow);
3639 setOrigin(&
I, getCleanOrigin());
3644 Value *Values =
I.getArgOperand(0);
3645 Value *Ptrs =
I.getArgOperand(1);
3646 const Align Alignment(
3647 cast<ConstantInt>(
I.getArgOperand(2))->getZExtValue());
3650 Type *PtrsShadowTy = getShadowTy(Ptrs);
3652 insertShadowCheck(Mask, &
I);
3656 insertShadowCheck(MaskedPtrShadow, getOrigin(Ptrs), &
I);
3659 Value *Shadow = getShadow(Values);
3660 Type *ElementShadowTy =
3661 getShadowTy(cast<VectorType>(Values->
getType())->getElementType());
3662 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
3663 Ptrs, IRB, ElementShadowTy, Alignment,
true);
3672 Value *
V =
I.getArgOperand(0);
3674 const Align Alignment(
3675 cast<ConstantInt>(
I.getArgOperand(2))->getZExtValue());
3677 Value *Shadow = getShadow(V);
3680 insertShadowCheck(
Ptr, &
I);
3681 insertShadowCheck(Mask, &
I);
3686 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3687 Ptr, IRB, Shadow->
getType(), Alignment,
true);
3691 if (!MS.TrackOrigins)
3694 auto &
DL =
F.getDataLayout();
3695 paintOrigin(IRB, getOrigin(V), OriginPtr,
3703 const Align Alignment(
3704 cast<ConstantInt>(
I.getArgOperand(1))->getZExtValue());
3706 Value *PassThru =
I.getArgOperand(3);
3709 insertShadowCheck(
Ptr, &
I);
3710 insertShadowCheck(Mask, &
I);
3713 if (!PropagateShadow) {
3714 setShadow(&
I, getCleanShadow(&
I));
3715 setOrigin(&
I, getCleanOrigin());
3719 Type *ShadowTy = getShadowTy(&
I);
3720 Value *ShadowPtr, *OriginPtr;
3721 std::tie(ShadowPtr, OriginPtr) =
3722 getShadowOriginPtr(
Ptr, IRB, ShadowTy, Alignment,
false);
3724 getShadow(PassThru),
"_msmaskedld"));
3726 if (!MS.TrackOrigins)
3733 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
3738 setOrigin(&
I, Origin);
3748 Type *ShadowTy = getShadowTy(&
I);
3751 Value *SMask = getShadow(&
I, 1);
3756 {getShadow(&I, 0), I.getOperand(1)});
3759 setOriginForNaryOp(
I);
3764 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
3781 cast<FixedVectorType>(
I.getArgOperand(0)->getType())->getNumElements();
3782 assert(isa<ConstantInt>(
I.getArgOperand(2)) &&
3783 "pclmul 3rd operand must be a constant");
3784 unsigned Imm = cast<ConstantInt>(
I.getArgOperand(2))->getZExtValue();
3786 getPclmulMask(Width, Imm & 0x01));
3788 getPclmulMask(Width, Imm & 0x10));
3789 ShadowAndOriginCombiner SOC(
this, IRB);
3790 SOC.Add(Shuf0, getOrigin(&
I, 0));
3791 SOC.Add(Shuf1, getOrigin(&
I, 1));
3799 cast<FixedVectorType>(
I.getArgOperand(0)->getType())->getNumElements();
3801 Value *Second = getShadow(&
I, 1);
3804 Mask.push_back(Width);
3805 for (
unsigned i = 1; i < Width; i++)
3809 setShadow(&
I, Shadow);
3810 setOriginForNaryOp(
I);
3815 Value *Shadow0 = getShadow(&
I, 0);
3816 Value *Shadow1 = getShadow(&
I, 1);
3822 setShadow(&
I, Shadow);
3823 setOriginForNaryOp(
I);
3829 cast<FixedVectorType>(
I.getArgOperand(0)->getType())->getNumElements();
3831 Value *Second = getShadow(&
I, 1);
3835 Mask.push_back(Width);
3836 for (
unsigned i = 1; i < Width; i++)
3840 setShadow(&
I, Shadow);
3841 setOriginForNaryOp(
I);
3848 assert(
I.getType()->isIntOrIntVectorTy());
3849 assert(
I.getArgOperand(0)->getType() ==
I.getType());
3853 setShadow(&
I, getShadow(&
I, 0));
3854 setOrigin(&
I, getOrigin(&
I, 0));
3859 Value *Shadow = getShadow(&
I, 0);
3860 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
3861 setOrigin(&
I, getOrigin(&
I, 0));
3866 Value *Shadow0 = getShadow(&
I, 0);
3867 Value *Shadow1 = getShadow(&
I, 1);
3870 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
3876 setShadow(&
I, Shadow);
3877 setOriginForNaryOp(
I);
3894 void handleNEONVectorStoreIntrinsic(
IntrinsicInst &
I,
bool useLane) {
3898 int numArgOperands =
I.arg_size();
3901 assert(numArgOperands >= 1);
3902 Value *
Addr =
I.getArgOperand(numArgOperands - 1);
3904 int skipTrailingOperands = 1;
3907 insertShadowCheck(
Addr, &
I);
3911 skipTrailingOperands++;
3912 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
3914 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
3919 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
3920 assert(isa<FixedVectorType>(
I.getArgOperand(i)->getType()));
3921 Value *Shadow = getShadow(&
I, i);
3922 ShadowArgs.
append(1, Shadow);
3937 cast<FixedVectorType>(
I.getArgOperand(0)->getType())->getElementType(),
3938 cast<FixedVectorType>(
I.getArgOperand(0)->getType())->getNumElements() *
3939 (numArgOperands - skipTrailingOperands));
3940 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
3944 I.getArgOperand(numArgOperands - skipTrailingOperands));
3946 Value *OutputShadowPtr, *OutputOriginPtr;
3948 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
3949 Addr, IRB, OutputShadowTy,
Align(1),
true);
3950 ShadowArgs.
append(1, OutputShadowPtr);
3956 if (MS.TrackOrigins) {
3964 OriginCombiner
OC(
this, IRB);
3965 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
3966 OC.Add(
I.getArgOperand(i));
3969 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
3975 switch (
I.getIntrinsicID()) {
3976 case Intrinsic::uadd_with_overflow:
3977 case Intrinsic::sadd_with_overflow:
3978 case Intrinsic::usub_with_overflow:
3979 case Intrinsic::ssub_with_overflow:
3980 case Intrinsic::umul_with_overflow:
3981 case Intrinsic::smul_with_overflow:
3982 handleArithmeticWithOverflow(
I);
3984 case Intrinsic::abs:
3985 handleAbsIntrinsic(
I);
3987 case Intrinsic::is_fpclass:
3990 case Intrinsic::lifetime_start:
3991 handleLifetimeStart(
I);
3993 case Intrinsic::launder_invariant_group:
3994 case Intrinsic::strip_invariant_group:
3995 handleInvariantGroup(
I);
3997 case Intrinsic::bswap:
4000 case Intrinsic::ctlz:
4001 case Intrinsic::cttz:
4002 handleCountZeroes(
I);
4004 case Intrinsic::masked_compressstore:
4005 handleMaskedCompressStore(
I);
4007 case Intrinsic::masked_expandload:
4008 handleMaskedExpandLoad(
I);
4010 case Intrinsic::masked_gather:
4011 handleMaskedGather(
I);
4013 case Intrinsic::masked_scatter:
4014 handleMaskedScatter(
I);
4016 case Intrinsic::masked_store:
4017 handleMaskedStore(
I);
4019 case Intrinsic::masked_load:
4020 handleMaskedLoad(
I);
4022 case Intrinsic::vector_reduce_and:
4023 handleVectorReduceAndIntrinsic(
I);
4025 case Intrinsic::vector_reduce_or:
4026 handleVectorReduceOrIntrinsic(
I);
4028 case Intrinsic::vector_reduce_add:
4029 case Intrinsic::vector_reduce_xor:
4030 case Intrinsic::vector_reduce_mul:
4031 handleVectorReduceIntrinsic(
I);
4033 case Intrinsic::x86_sse_stmxcsr:
4036 case Intrinsic::x86_sse_ldmxcsr:
4039 case Intrinsic::x86_avx512_vcvtsd2usi64:
4040 case Intrinsic::x86_avx512_vcvtsd2usi32:
4041 case Intrinsic::x86_avx512_vcvtss2usi64:
4042 case Intrinsic::x86_avx512_vcvtss2usi32:
4043 case Intrinsic::x86_avx512_cvttss2usi64:
4044 case Intrinsic::x86_avx512_cvttss2usi:
4045 case Intrinsic::x86_avx512_cvttsd2usi64:
4046 case Intrinsic::x86_avx512_cvttsd2usi:
4047 case Intrinsic::x86_avx512_cvtusi2ss:
4048 case Intrinsic::x86_avx512_cvtusi642sd:
4049 case Intrinsic::x86_avx512_cvtusi642ss:
4050 handleVectorConvertIntrinsic(
I, 1,
true);
4052 case Intrinsic::x86_sse2_cvtsd2si64:
4053 case Intrinsic::x86_sse2_cvtsd2si:
4054 case Intrinsic::x86_sse2_cvtsd2ss:
4055 case Intrinsic::x86_sse2_cvttsd2si64:
4056 case Intrinsic::x86_sse2_cvttsd2si:
4057 case Intrinsic::x86_sse_cvtss2si64:
4058 case Intrinsic::x86_sse_cvtss2si:
4059 case Intrinsic::x86_sse_cvttss2si64:
4060 case Intrinsic::x86_sse_cvttss2si:
4061 handleVectorConvertIntrinsic(
I, 1);
4063 case Intrinsic::x86_sse_cvtps2pi:
4064 case Intrinsic::x86_sse_cvttps2pi:
4065 handleVectorConvertIntrinsic(
I, 2);
4068 case Intrinsic::x86_avx512_psll_w_512:
4069 case Intrinsic::x86_avx512_psll_d_512:
4070 case Intrinsic::x86_avx512_psll_q_512:
4071 case Intrinsic::x86_avx512_pslli_w_512:
4072 case Intrinsic::x86_avx512_pslli_d_512:
4073 case Intrinsic::x86_avx512_pslli_q_512:
4074 case Intrinsic::x86_avx512_psrl_w_512:
4075 case Intrinsic::x86_avx512_psrl_d_512:
4076 case Intrinsic::x86_avx512_psrl_q_512:
4077 case Intrinsic::x86_avx512_psra_w_512:
4078 case Intrinsic::x86_avx512_psra_d_512:
4079 case Intrinsic::x86_avx512_psra_q_512:
4080 case Intrinsic::x86_avx512_psrli_w_512:
4081 case Intrinsic::x86_avx512_psrli_d_512:
4082 case Intrinsic::x86_avx512_psrli_q_512:
4083 case Intrinsic::x86_avx512_psrai_w_512:
4084 case Intrinsic::x86_avx512_psrai_d_512:
4085 case Intrinsic::x86_avx512_psrai_q_512:
4086 case Intrinsic::x86_avx512_psra_q_256:
4087 case Intrinsic::x86_avx512_psra_q_128:
4088 case Intrinsic::x86_avx512_psrai_q_256:
4089 case Intrinsic::x86_avx512_psrai_q_128:
4090 case Intrinsic::x86_avx2_psll_w:
4091 case Intrinsic::x86_avx2_psll_d:
4092 case Intrinsic::x86_avx2_psll_q:
4093 case Intrinsic::x86_avx2_pslli_w:
4094 case Intrinsic::x86_avx2_pslli_d:
4095 case Intrinsic::x86_avx2_pslli_q:
4096 case Intrinsic::x86_avx2_psrl_w:
4097 case Intrinsic::x86_avx2_psrl_d:
4098 case Intrinsic::x86_avx2_psrl_q:
4099 case Intrinsic::x86_avx2_psra_w:
4100 case Intrinsic::x86_avx2_psra_d:
4101 case Intrinsic::x86_avx2_psrli_w:
4102 case Intrinsic::x86_avx2_psrli_d:
4103 case Intrinsic::x86_avx2_psrli_q:
4104 case Intrinsic::x86_avx2_psrai_w:
4105 case Intrinsic::x86_avx2_psrai_d:
4106 case Intrinsic::x86_sse2_psll_w:
4107 case Intrinsic::x86_sse2_psll_d:
4108 case Intrinsic::x86_sse2_psll_q:
4109 case Intrinsic::x86_sse2_pslli_w:
4110 case Intrinsic::x86_sse2_pslli_d:
4111 case Intrinsic::x86_sse2_pslli_q:
4112 case Intrinsic::x86_sse2_psrl_w:
4113 case Intrinsic::x86_sse2_psrl_d:
4114 case Intrinsic::x86_sse2_psrl_q:
4115 case Intrinsic::x86_sse2_psra_w:
4116 case Intrinsic::x86_sse2_psra_d:
4117 case Intrinsic::x86_sse2_psrli_w:
4118 case Intrinsic::x86_sse2_psrli_d:
4119 case Intrinsic::x86_sse2_psrli_q:
4120 case Intrinsic::x86_sse2_psrai_w:
4121 case Intrinsic::x86_sse2_psrai_d:
4122 case Intrinsic::x86_mmx_psll_w:
4123 case Intrinsic::x86_mmx_psll_d:
4124 case Intrinsic::x86_mmx_psll_q:
4125 case Intrinsic::x86_mmx_pslli_w:
4126 case Intrinsic::x86_mmx_pslli_d:
4127 case Intrinsic::x86_mmx_pslli_q:
4128 case Intrinsic::x86_mmx_psrl_w:
4129 case Intrinsic::x86_mmx_psrl_d:
4130 case Intrinsic::x86_mmx_psrl_q:
4131 case Intrinsic::x86_mmx_psra_w:
4132 case Intrinsic::x86_mmx_psra_d:
4133 case Intrinsic::x86_mmx_psrli_w:
4134 case Intrinsic::x86_mmx_psrli_d:
4135 case Intrinsic::x86_mmx_psrli_q:
4136 case Intrinsic::x86_mmx_psrai_w:
4137 case Intrinsic::x86_mmx_psrai_d:
4138 case Intrinsic::aarch64_neon_rshrn:
4139 case Intrinsic::aarch64_neon_sqrshl:
4140 case Intrinsic::aarch64_neon_sqrshrn:
4141 case Intrinsic::aarch64_neon_sqrshrun:
4142 case Intrinsic::aarch64_neon_sqshl:
4143 case Intrinsic::aarch64_neon_sqshlu:
4144 case Intrinsic::aarch64_neon_sqshrn:
4145 case Intrinsic::aarch64_neon_sqshrun:
4146 case Intrinsic::aarch64_neon_srshl:
4147 case Intrinsic::aarch64_neon_sshl:
4148 case Intrinsic::aarch64_neon_uqrshl:
4149 case Intrinsic::aarch64_neon_uqrshrn:
4150 case Intrinsic::aarch64_neon_uqshl:
4151 case Intrinsic::aarch64_neon_uqshrn:
4152 case Intrinsic::aarch64_neon_urshl:
4153 case Intrinsic::aarch64_neon_ushl:
4155 handleVectorShiftIntrinsic(
I,
false);
4157 case Intrinsic::x86_avx2_psllv_d:
4158 case Intrinsic::x86_avx2_psllv_d_256:
4159 case Intrinsic::x86_avx512_psllv_d_512:
4160 case Intrinsic::x86_avx2_psllv_q:
4161 case Intrinsic::x86_avx2_psllv_q_256:
4162 case Intrinsic::x86_avx512_psllv_q_512:
4163 case Intrinsic::x86_avx2_psrlv_d:
4164 case Intrinsic::x86_avx2_psrlv_d_256:
4165 case Intrinsic::x86_avx512_psrlv_d_512:
4166 case Intrinsic::x86_avx2_psrlv_q:
4167 case Intrinsic::x86_avx2_psrlv_q_256:
4168 case Intrinsic::x86_avx512_psrlv_q_512:
4169 case Intrinsic::x86_avx2_psrav_d:
4170 case Intrinsic::x86_avx2_psrav_d_256:
4171 case Intrinsic::x86_avx512_psrav_d_512:
4172 case Intrinsic::x86_avx512_psrav_q_128:
4173 case Intrinsic::x86_avx512_psrav_q_256:
4174 case Intrinsic::x86_avx512_psrav_q_512:
4175 handleVectorShiftIntrinsic(
I,
true);
4178 case Intrinsic::x86_sse2_packsswb_128:
4179 case Intrinsic::x86_sse2_packssdw_128:
4180 case Intrinsic::x86_sse2_packuswb_128:
4181 case Intrinsic::x86_sse41_packusdw:
4182 case Intrinsic::x86_avx2_packsswb:
4183 case Intrinsic::x86_avx2_packssdw:
4184 case Intrinsic::x86_avx2_packuswb:
4185 case Intrinsic::x86_avx2_packusdw:
4186 handleVectorPackIntrinsic(
I);
4189 case Intrinsic::x86_sse41_pblendvb:
4190 case Intrinsic::x86_sse41_blendvpd:
4191 case Intrinsic::x86_sse41_blendvps:
4192 case Intrinsic::x86_avx_blendv_pd_256:
4193 case Intrinsic::x86_avx_blendv_ps_256:
4194 case Intrinsic::x86_avx2_pblendvb:
4195 handleBlendvIntrinsic(
I);
4198 case Intrinsic::x86_avx_dp_ps_256:
4199 case Intrinsic::x86_sse41_dppd:
4200 case Intrinsic::x86_sse41_dpps:
4201 handleDppIntrinsic(
I);
4204 case Intrinsic::x86_mmx_packsswb:
4205 case Intrinsic::x86_mmx_packuswb:
4206 handleVectorPackIntrinsic(
I, 16);
4209 case Intrinsic::x86_mmx_packssdw:
4210 handleVectorPackIntrinsic(
I, 32);
4213 case Intrinsic::x86_mmx_psad_bw:
4214 handleVectorSadIntrinsic(
I,
true);
4216 case Intrinsic::x86_sse2_psad_bw:
4217 case Intrinsic::x86_avx2_psad_bw:
4218 handleVectorSadIntrinsic(
I);
4221 case Intrinsic::x86_sse2_pmadd_wd:
4222 case Intrinsic::x86_avx2_pmadd_wd:
4223 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
4224 case Intrinsic::x86_avx2_pmadd_ub_sw:
4225 handleVectorPmaddIntrinsic(
I);
4228 case Intrinsic::x86_ssse3_pmadd_ub_sw:
4229 handleVectorPmaddIntrinsic(
I, 8);
4232 case Intrinsic::x86_mmx_pmadd_wd:
4233 handleVectorPmaddIntrinsic(
I, 16);
4236 case Intrinsic::x86_sse_cmp_ss:
4237 case Intrinsic::x86_sse2_cmp_sd:
4238 case Intrinsic::x86_sse_comieq_ss:
4239 case Intrinsic::x86_sse_comilt_ss:
4240 case Intrinsic::x86_sse_comile_ss:
4241 case Intrinsic::x86_sse_comigt_ss:
4242 case Intrinsic::x86_sse_comige_ss:
4243 case Intrinsic::x86_sse_comineq_ss:
4244 case Intrinsic::x86_sse_ucomieq_ss:
4245 case Intrinsic::x86_sse_ucomilt_ss:
4246 case Intrinsic::x86_sse_ucomile_ss:
4247 case Intrinsic::x86_sse_ucomigt_ss:
4248 case Intrinsic::x86_sse_ucomige_ss:
4249 case Intrinsic::x86_sse_ucomineq_ss:
4250 case Intrinsic::x86_sse2_comieq_sd:
4251 case Intrinsic::x86_sse2_comilt_sd:
4252 case Intrinsic::x86_sse2_comile_sd:
4253 case Intrinsic::x86_sse2_comigt_sd:
4254 case Intrinsic::x86_sse2_comige_sd:
4255 case Intrinsic::x86_sse2_comineq_sd:
4256 case Intrinsic::x86_sse2_ucomieq_sd:
4257 case Intrinsic::x86_sse2_ucomilt_sd:
4258 case Intrinsic::x86_sse2_ucomile_sd:
4259 case Intrinsic::x86_sse2_ucomigt_sd:
4260 case Intrinsic::x86_sse2_ucomige_sd:
4261 case Intrinsic::x86_sse2_ucomineq_sd:
4262 handleVectorCompareScalarIntrinsic(
I);
4265 case Intrinsic::x86_avx_cmp_pd_256:
4266 case Intrinsic::x86_avx_cmp_ps_256:
4267 case Intrinsic::x86_sse2_cmp_pd:
4268 case Intrinsic::x86_sse_cmp_ps:
4269 handleVectorComparePackedIntrinsic(
I);
4272 case Intrinsic::x86_bmi_bextr_32:
4273 case Intrinsic::x86_bmi_bextr_64:
4274 case Intrinsic::x86_bmi_bzhi_32:
4275 case Intrinsic::x86_bmi_bzhi_64:
4276 case Intrinsic::x86_bmi_pdep_32:
4277 case Intrinsic::x86_bmi_pdep_64:
4278 case Intrinsic::x86_bmi_pext_32:
4279 case Intrinsic::x86_bmi_pext_64:
4280 handleBmiIntrinsic(
I);
4283 case Intrinsic::x86_pclmulqdq:
4284 case Intrinsic::x86_pclmulqdq_256:
4285 case Intrinsic::x86_pclmulqdq_512:
4286 handlePclmulIntrinsic(
I);
4289 case Intrinsic::x86_sse41_round_sd:
4290 case Intrinsic::x86_sse41_round_ss:
4291 handleUnarySdSsIntrinsic(
I);
4293 case Intrinsic::x86_sse2_max_sd:
4294 case Intrinsic::x86_sse_max_ss:
4295 case Intrinsic::x86_sse2_min_sd:
4296 case Intrinsic::x86_sse_min_ss:
4297 handleBinarySdSsIntrinsic(
I);
4300 case Intrinsic::x86_avx_vtestc_pd:
4301 case Intrinsic::x86_avx_vtestc_pd_256:
4302 case Intrinsic::x86_avx_vtestc_ps:
4303 case Intrinsic::x86_avx_vtestc_ps_256:
4304 case Intrinsic::x86_avx_vtestnzc_pd:
4305 case Intrinsic::x86_avx_vtestnzc_pd_256:
4306 case Intrinsic::x86_avx_vtestnzc_ps:
4307 case Intrinsic::x86_avx_vtestnzc_ps_256:
4308 case Intrinsic::x86_avx_vtestz_pd:
4309 case Intrinsic::x86_avx_vtestz_pd_256:
4310 case Intrinsic::x86_avx_vtestz_ps:
4311 case Intrinsic::x86_avx_vtestz_ps_256:
4312 case Intrinsic::x86_avx_ptestc_256:
4313 case Intrinsic::x86_avx_ptestnzc_256:
4314 case Intrinsic::x86_avx_ptestz_256:
4315 case Intrinsic::x86_sse41_ptestc:
4316 case Intrinsic::x86_sse41_ptestnzc:
4317 case Intrinsic::x86_sse41_ptestz:
4318 handleVtestIntrinsic(
I);
4321 case Intrinsic::fshl:
4322 case Intrinsic::fshr:
4323 handleFunnelShift(
I);
4326 case Intrinsic::is_constant:
4328 setShadow(&
I, getCleanShadow(&
I));
4329 setOrigin(&
I, getCleanOrigin());
4332 case Intrinsic::aarch64_neon_st1x2:
4333 case Intrinsic::aarch64_neon_st1x3:
4334 case Intrinsic::aarch64_neon_st1x4:
4335 case Intrinsic::aarch64_neon_st2:
4336 case Intrinsic::aarch64_neon_st3:
4337 case Intrinsic::aarch64_neon_st4: {
4338 handleNEONVectorStoreIntrinsic(
I,
false);
4342 case Intrinsic::aarch64_neon_st2lane:
4343 case Intrinsic::aarch64_neon_st3lane:
4344 case Intrinsic::aarch64_neon_st4lane: {
4345 handleNEONVectorStoreIntrinsic(
I,
true);
4350 if (!handleUnknownIntrinsic(
I))
4351 visitInstruction(
I);
4356 void visitLibAtomicLoad(
CallBase &CB) {
4358 assert(isa<CallInst>(CB));
4367 Value *NewOrdering =
4371 NextNodeIRBuilder NextIRB(&CB);
4372 Value *SrcShadowPtr, *SrcOriginPtr;
4373 std::tie(SrcShadowPtr, SrcOriginPtr) =
4374 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
4376 Value *DstShadowPtr =
4377 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
4381 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
4382 if (MS.TrackOrigins) {
4383 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
4385 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
4386 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
4390 void visitLibAtomicStore(
CallBase &CB) {
4397 Value *NewOrdering =
4401 Value *DstShadowPtr =
4419 visitAsmInstruction(CB);
4421 visitInstruction(CB);
4430 case LibFunc_atomic_load:
4431 if (!isa<CallInst>(CB)) {
4432 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
4436 visitLibAtomicLoad(CB);
4438 case LibFunc_atomic_store:
4439 visitLibAtomicStore(CB);
4446 if (
auto *Call = dyn_cast<CallInst>(&CB)) {
4447 assert(!isa<IntrinsicInst>(Call) &&
"intrinsics are handled elsewhere");
4455 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
4457 Call->removeFnAttrs(
B);
4459 Func->removeFnAttrs(
B);
4465 bool MayCheckCall = MS.EagerChecks;
4469 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
4472 unsigned ArgOffset = 0;
4475 if (!
A->getType()->isSized()) {
4476 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
4480 if (
A->getType()->isScalableTy()) {
4481 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
4483 insertShadowCheck(
A, &CB);
4492 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
4495 insertShadowCheck(
A, &CB);
4496 Size =
DL.getTypeAllocSize(
A->getType());
4502 Value *ArgShadow = getShadow(
A);
4503 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
4505 <<
" Shadow: " << *ArgShadow <<
"\n");
4509 assert(
A->getType()->isPointerTy() &&
4510 "ByVal argument is not a pointer!");
4518 Value *AShadowPtr, *AOriginPtr;
4519 std::tie(AShadowPtr, AOriginPtr) =
4520 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
4522 if (!PropagateShadow) {
4529 if (MS.TrackOrigins) {
4530 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
4544 Size =
DL.getTypeAllocSize(
A->getType());
4549 Constant *Cst = dyn_cast<Constant>(ArgShadow);
4550 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
4552 getOriginPtrForArgument(IRB, ArgOffset));
4556 assert(Store !=
nullptr);
4565 if (FT->isVarArg()) {
4566 VAHelper->visitCallBase(CB, IRB);
4573 if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
4576 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
4577 setShadow(&CB, getCleanShadow(&CB));
4578 setOrigin(&CB, getCleanOrigin());
4584 Value *
Base = getShadowPtrForRetval(IRBBefore);
4585 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
4588 if (isa<CallInst>(CB)) {
4592 BasicBlock *NormalDest = cast<InvokeInst>(CB).getNormalDest();
4597 setShadow(&CB, getCleanShadow(&CB));
4598 setOrigin(&CB, getCleanOrigin());
4605 "Could not find insertion point for retval shadow load");
4608 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
4609 getShadowTy(&CB), getShadowPtrForRetval(IRBAfter),
4611 setShadow(&CB, RetvalShadow);
4612 if (MS.TrackOrigins)
4613 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy,
4614 getOriginPtrForRetval()));
4618 if (
auto *
I = dyn_cast<BitCastInst>(RetVal)) {
4619 RetVal =
I->getOperand(0);
4621 if (
auto *
I = dyn_cast<CallInst>(RetVal)) {
4622 return I->isMustTailCall();
4629 Value *RetVal =
I.getReturnValue();
4635 Value *ShadowPtr = getShadowPtrForRetval(IRB);
4636 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
4637 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
4640 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
4642 Value *Shadow = getShadow(RetVal);
4643 bool StoreOrigin =
true;
4645 insertShadowCheck(RetVal, &
I);
4646 Shadow = getCleanShadow(RetVal);
4647 StoreOrigin =
false;
4654 if (MS.TrackOrigins && StoreOrigin)
4655 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
4661 if (!PropagateShadow) {
4662 setShadow(&
I, getCleanShadow(&
I));
4663 setOrigin(&
I, getCleanOrigin());
4667 ShadowPHINodes.push_back(&
I);
4668 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
4670 if (MS.TrackOrigins)
4672 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
4689 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
4691 Value *ShadowBase, *OriginBase;
4692 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
4699 if (PoisonStack && MS.TrackOrigins) {
4700 Value *Idptr = getLocalVarIdptr(
I);
4702 Value *Descr = getLocalVarDescription(
I);
4703 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
4704 {&I, Len, Idptr, Descr});
4706 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
4712 Value *Descr = getLocalVarDescription(
I);
4714 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
4716 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
4723 NextNodeIRBuilder IRB(InsPoint);
4725 TypeSize TS =
DL.getTypeAllocSize(
I.getAllocatedType());
4727 if (
I.isArrayAllocation())
4731 if (MS.CompileKernel)
4732 poisonAllocaKmsan(
I, IRB, Len);
4734 poisonAllocaUserspace(
I, IRB, Len);
4738 setShadow(&
I, getCleanShadow(&
I));
4739 setOrigin(&
I, getCleanOrigin());
4751 handleSelectLikeInst(
I,
B,
C,
D);
4757 Value *Sb = getShadow(
B);
4758 Value *Sc = getShadow(
C);
4759 Value *Sd = getShadow(
D);
4761 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
4762 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
4763 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
4768 if (
I.getType()->isAggregateType()) {
4772 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
4780 C = CreateAppToShadowCast(IRB,
C);
4781 D = CreateAppToShadowCast(IRB,
D);
4788 if (MS.TrackOrigins) {
4791 if (
B->getType()->isVectorTy()) {
4792 B = convertToBool(
B, IRB);
4793 Sb = convertToBool(Sb, IRB);
4804 setShadow(&
I, getCleanShadow(&
I));
4805 setOrigin(&
I, getCleanOrigin());
4809 setShadow(&
I, getCleanShadow(&
I));
4810 setOrigin(&
I, getCleanOrigin());
4814 setShadow(&
I, getCleanShadow(&
I));
4815 setOrigin(&
I, getCleanOrigin());
4822 Value *Agg =
I.getAggregateOperand();
4824 Value *AggShadow = getShadow(Agg);
4828 setShadow(&
I, ResShadow);
4829 setOriginForNaryOp(
I);
4835 Value *AggShadow = getShadow(
I.getAggregateOperand());
4836 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
4842 setOriginForNaryOp(
I);
4846 if (
CallInst *CI = dyn_cast<CallInst>(&
I)) {
4849 errs() <<
"ZZZ " <<
I.getOpcodeName() <<
"\n";
4851 errs() <<
"QQQ " <<
I <<
"\n";
4878 insertShadowCheck(Operand, &
I);
4885 auto Size =
DL.getTypeStoreSize(ElemTy);
4887 if (MS.CompileKernel) {
4888 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
4894 auto [ShadowPtr,
_] =
4895 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
4906 int NumRetOutputs = 0;
4908 Type *
RetTy = cast<Value>(CB)->getType();
4909 if (!
RetTy->isVoidTy()) {
4911 auto *
ST = dyn_cast<StructType>(
RetTy);
4913 NumRetOutputs =
ST->getNumElements();
4919 switch (
Info.Type) {
4927 return NumOutputs - NumRetOutputs;
4950 int OutputArgs = getNumOutputArgs(IA, CB);
4956 for (
int i = OutputArgs; i < NumOperands; i++) {
4964 for (
int i = 0; i < OutputArgs; i++) {
4970 setShadow(&
I, getCleanShadow(&
I));
4971 setOrigin(&
I, getCleanOrigin());
4976 setShadow(&
I, getCleanShadow(&
I));
4977 setOrigin(&
I, getCleanOrigin());
4985 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
4986 Value *Operand =
I.getOperand(i);
4988 insertShadowCheck(Operand, &
I);
4990 setShadow(&
I, getCleanShadow(&
I));
4991 setOrigin(&
I, getCleanOrigin());
4995struct VarArgHelperBase :
public VarArgHelper {
4997 MemorySanitizer &MS;
4998 MemorySanitizerVisitor &MSV;
5000 const unsigned VAListTagSize;
5002 VarArgHelperBase(
Function &
F, MemorySanitizer &MS,
5003 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
5004 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
5008 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
5013 unsigned ArgOffset) {
5022 unsigned ArgOffset,
unsigned ArgSize) {
5026 return getShadowPtrForVAArgument(Ty, IRB, ArgOffset);
5041 unsigned BaseOffset) {
5050 TailSize,
Align(8));
5055 Value *VAListTag =
I.getArgOperand(0);
5057 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
5058 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
5061 VAListTagSize, Alignment,
false);
5068 unpoisonVAListTagForInst(
I);
5074 unpoisonVAListTagForInst(
I);
5079struct VarArgAMD64Helper :
public VarArgHelperBase {
5082 static const unsigned AMD64GpEndOffset = 48;
5083 static const unsigned AMD64FpEndOffsetSSE = 176;
5085 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
5087 unsigned AMD64FpEndOffset;
5090 Value *VAArgOverflowSize =
nullptr;
5092 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
5094 VarArgAMD64Helper(
Function &
F, MemorySanitizer &MS,
5095 MemorySanitizerVisitor &MSV)
5096 : VarArgHelperBase(
F, MS, MSV, 24) {
5097 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
5098 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
5099 if (Attr.isStringAttribute() &&
5100 (Attr.getKindAsString() ==
"target-features")) {
5101 if (Attr.getValueAsString().contains(
"-sse"))
5102 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
5108 ArgKind classifyArgument(
Value *arg) {
5111 if (
T->isX86_FP80Ty())
5113 if (
T->isFPOrFPVectorTy())
5114 return AK_FloatingPoint;
5115 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
5116 return AK_GeneralPurpose;
5117 if (
T->isPointerTy())
5118 return AK_GeneralPurpose;
5131 unsigned GpOffset = 0;
5132 unsigned FpOffset = AMD64GpEndOffset;
5133 unsigned OverflowOffset = AMD64FpEndOffset;
5138 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
5145 assert(
A->getType()->isPointerTy());
5147 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
5149 unsigned BaseOffset = OverflowOffset;
5151 getShadowPtrForVAArgument(RealTy, IRB, OverflowOffset);
5152 Value *OriginBase =
nullptr;
5153 if (MS.TrackOrigins)
5154 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
5155 OverflowOffset += AlignedSize;
5158 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
5162 Value *ShadowPtr, *OriginPtr;
5163 std::tie(ShadowPtr, OriginPtr) =
5168 if (MS.TrackOrigins)
5172 ArgKind AK = classifyArgument(
A);
5173 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
5175 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
5177 Value *ShadowBase, *OriginBase =
nullptr;
5179 case AK_GeneralPurpose:
5180 ShadowBase = getShadowPtrForVAArgument(
A->getType(), IRB, GpOffset);
5181 if (MS.TrackOrigins)
5182 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
5186 case AK_FloatingPoint:
5187 ShadowBase = getShadowPtrForVAArgument(
A->getType(), IRB, FpOffset);
5188 if (MS.TrackOrigins)
5189 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
5196 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
5198 unsigned BaseOffset = OverflowOffset;
5200 getShadowPtrForVAArgument(
A->getType(), IRB, OverflowOffset);
5201 if (MS.TrackOrigins) {
5202 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
5204 OverflowOffset += AlignedSize;
5207 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
5216 Value *Shadow = MSV.getShadow(
A);
5218 if (MS.TrackOrigins) {
5219 Value *Origin = MSV.getOrigin(
A);
5221 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
5227 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
5228 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
5231 void finalizeInstrumentation()
override {
5232 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
5233 "finalizeInstrumentation called twice");
5234 if (!VAStartInstrumentationList.
empty()) {
5241 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
5248 Intrinsic::umin, CopySize,
5252 if (MS.TrackOrigins) {
5262 for (
CallInst *OrigInst : VAStartInstrumentationList) {
5263 NextNodeIRBuilder IRB(OrigInst);
5264 Value *VAListTag = OrigInst->getArgOperand(0);
5266 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
5269 ConstantInt::get(MS.IntptrTy, 16)),
5270 PointerType::get(RegSaveAreaPtrTy, 0));
5271 Value *RegSaveAreaPtr =
5272 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5273 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5275 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5276 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
5278 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5280 if (MS.TrackOrigins)
5281 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
5282 Alignment, AMD64FpEndOffset);
5283 Type *OverflowArgAreaPtrTy = PointerType::getUnqual(*MS.C);
5286 ConstantInt::get(MS.IntptrTy, 8)),
5287 PointerType::get(OverflowArgAreaPtrTy, 0));
5288 Value *OverflowArgAreaPtr =
5289 IRB.
CreateLoad(OverflowArgAreaPtrTy, OverflowArgAreaPtrPtr);
5290 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
5291 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
5292 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
5296 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
5298 if (MS.TrackOrigins) {
5301 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
5310struct VarArgMIPS64Helper :
public VarArgHelperBase {
5312 Value *VAArgSize =
nullptr;
5314 VarArgMIPS64Helper(
Function &
F, MemorySanitizer &MS,
5315 MemorySanitizerVisitor &MSV)
5316 : VarArgHelperBase(
F, MS, MSV, 8) {}
5319 unsigned VAArgOffset = 0;
5323 Triple TargetTriple(
F.getParent()->getTargetTriple());
5325 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
5330 VAArgOffset += (8 - ArgSize);
5332 Base = getShadowPtrForVAArgument(
A->getType(), IRB, VAArgOffset, ArgSize);
5333 VAArgOffset += ArgSize;
5334 VAArgOffset =
alignTo(VAArgOffset, 8);
5343 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
5346 void finalizeInstrumentation()
override {
5347 assert(!VAArgSize && !VAArgTLSCopy &&
5348 "finalizeInstrumentation called twice");
5352 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize);
5354 if (!VAStartInstrumentationList.empty()) {
5363 Intrinsic::umin, CopySize,
5371 for (
CallInst *OrigInst : VAStartInstrumentationList) {
5372 NextNodeIRBuilder IRB(OrigInst);
5373 Value *VAListTag = OrigInst->getArgOperand(0);
5374 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
5375 Value *RegSaveAreaPtrPtr =
5377 PointerType::get(RegSaveAreaPtrTy, 0));
5378 Value *RegSaveAreaPtr =
5379 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5380 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5382 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5383 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
5385 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5392struct VarArgAArch64Helper :
public VarArgHelperBase {
5393 static const unsigned kAArch64GrArgSize = 64;
5394 static const unsigned kAArch64VrArgSize = 128;
5396 static const unsigned AArch64GrBegOffset = 0;
5397 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
5399 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
5400 static const unsigned AArch64VrEndOffset =
5401 AArch64VrBegOffset + kAArch64VrArgSize;
5402 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
5405 Value *VAArgOverflowSize =
nullptr;
5407 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
5409 VarArgAArch64Helper(
Function &
F, MemorySanitizer &MS,
5410 MemorySanitizerVisitor &MSV)
5411 : VarArgHelperBase(
F, MS, MSV, 32) {}
5414 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
5415 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
5416 return {AK_GeneralPurpose, 1};
5417 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
5418 return {AK_FloatingPoint, 1};
5420 if (
T->isArrayTy()) {
5421 auto R = classifyArgument(
T->getArrayElementType());
5422 R.second *=
T->getScalarType()->getArrayNumElements();
5427 auto R = classifyArgument(FV->getScalarType());
5428 R.second *= FV->getNumElements();
5433 return {AK_Memory, 0};
5446 unsigned GrOffset = AArch64GrBegOffset;
5447 unsigned VrOffset = AArch64VrBegOffset;
5448 unsigned OverflowOffset = AArch64VAEndOffset;
5453 auto [AK, RegNum] = classifyArgument(
A->getType());
5454 if (AK == AK_GeneralPurpose &&
5455 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
5457 if (AK == AK_FloatingPoint &&
5458 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
5462 case AK_GeneralPurpose:
5463 Base = getShadowPtrForVAArgument(
A->getType(), IRB, GrOffset);
5464 GrOffset += 8 * RegNum;
5466 case AK_FloatingPoint:
5467 Base = getShadowPtrForVAArgument(
A->getType(), IRB, VrOffset);
5468 VrOffset += 16 * RegNum;
5475 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
5477 unsigned BaseOffset = OverflowOffset;
5478 Base = getShadowPtrForVAArgument(
A->getType(), IRB, BaseOffset);
5479 OverflowOffset += AlignedSize;
5482 CleanUnusedTLS(IRB,
Base, BaseOffset);
5494 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
5495 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
5502 ConstantInt::get(MS.IntptrTy, offset)),
5503 PointerType::get(*MS.C, 0));
5511 ConstantInt::get(MS.IntptrTy, offset)),
5512 PointerType::get(*MS.C, 0));
5514 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
5517 void finalizeInstrumentation()
override {
5518 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
5519 "finalizeInstrumentation called twice");
5520 if (!VAStartInstrumentationList.empty()) {
5527 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
5534 Intrinsic::umin, CopySize,
5540 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
5541 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
5545 for (
CallInst *OrigInst : VAStartInstrumentationList) {
5546 NextNodeIRBuilder IRB(OrigInst);
5548 Value *VAListTag = OrigInst->getArgOperand(0);
5565 Value *StackSaveAreaPtr =
5566 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
5569 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
5570 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
5573 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
5576 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
5577 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
5580 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
5586 Value *GrRegSaveAreaShadowPtrOff =
5587 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
5589 Value *GrRegSaveAreaShadowPtr =
5590 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
5596 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
5602 Value *VrRegSaveAreaShadowPtrOff =
5603 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
5605 Value *VrRegSaveAreaShadowPtr =
5606 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
5613 VrRegSaveAreaShadowPtrOff);
5614 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
5620 Value *StackSaveAreaShadowPtr =
5621 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
5626 VAArgTLSCopy, IRB.
getInt32(AArch64VAEndOffset));
5629 Align(16), VAArgOverflowSize);
5635struct VarArgPowerPC64Helper :
public VarArgHelperBase {
5637 Value *VAArgSize =
nullptr;
5639 VarArgPowerPC64Helper(
Function &
F, MemorySanitizer &MS,
5640 MemorySanitizerVisitor &MSV)
5641 : VarArgHelperBase(
F, MS, MSV, 8) {}
5651 Triple TargetTriple(
F.getParent()->getTargetTriple());
5659 unsigned VAArgOffset = VAArgBase;
5663 bool IsByVal = CB.
paramHasAttr(ArgNo, Attribute::ByVal);
5665 assert(
A->getType()->isPointerTy());
5667 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
5670 ArgAlign =
Align(8);
5671 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
5673 Value *
Base = getShadowPtrForVAArgument(
5674 RealTy, IRB, VAArgOffset - VAArgBase, ArgSize);
5676 Value *AShadowPtr, *AOriginPtr;
5677 std::tie(AShadowPtr, AOriginPtr) =
5678 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
5688 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
5690 if (
A->getType()->isArrayTy()) {
5693 Type *ElementTy =
A->getType()->getArrayElementType();
5695 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
5696 }
else if (
A->getType()->isVectorTy()) {
5698 ArgAlign =
Align(ArgSize);
5701 ArgAlign =
Align(8);
5702 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
5703 if (
DL.isBigEndian()) {
5707 VAArgOffset += (8 - ArgSize);
5710 Base = getShadowPtrForVAArgument(
A->getType(), IRB,
5711 VAArgOffset - VAArgBase, ArgSize);
5715 VAArgOffset += ArgSize;
5719 VAArgBase = VAArgOffset;
5723 ConstantInt::get(IRB.
getInt64Ty(), VAArgOffset - VAArgBase);
5726 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
5729 void finalizeInstrumentation()
override {
5730 assert(!VAArgSize && !VAArgTLSCopy &&
5731 "finalizeInstrumentation called twice");
5735 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize);
5737 if (!VAStartInstrumentationList.empty()) {
5747 Intrinsic::umin, CopySize,
5755 for (
CallInst *OrigInst : VAStartInstrumentationList) {
5756 NextNodeIRBuilder IRB(OrigInst);
5757 Value *VAListTag = OrigInst->getArgOperand(0);
5758 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
5759 Value *RegSaveAreaPtrPtr =
5761 PointerType::get(RegSaveAreaPtrTy, 0));
5762 Value *RegSaveAreaPtr =
5763 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5764 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5766 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5767 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
5769 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5776struct VarArgSystemZHelper :
public VarArgHelperBase {
5777 static const unsigned SystemZGpOffset = 16;
5778 static const unsigned SystemZGpEndOffset = 56;
5779 static const unsigned SystemZFpOffset = 128;
5780 static const unsigned SystemZFpEndOffset = 160;
5781 static const unsigned SystemZMaxVrArgs = 8;
5782 static const unsigned SystemZRegSaveAreaSize = 160;
5783 static const unsigned SystemZOverflowOffset = 160;
5784 static const unsigned SystemZVAListTagSize = 32;
5785 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
5786 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
5788 bool IsSoftFloatABI;
5791 Value *VAArgOverflowSize =
nullptr;
5793 enum class ArgKind {
5801 enum class ShadowExtension {
None,
Zero, Sign };
5803 VarArgSystemZHelper(
Function &
F, MemorySanitizer &MS,
5804 MemorySanitizerVisitor &MSV)
5805 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
5806 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
5808 ArgKind classifyArgument(
Type *
T) {
5815 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
5816 return ArgKind::Indirect;
5817 if (
T->isFloatingPointTy())
5818 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
5819 if (
T->isIntegerTy() ||
T->isPointerTy())
5820 return ArgKind::GeneralPurpose;
5821 if (
T->isVectorTy())
5822 return ArgKind::Vector;
5823 return ArgKind::Memory;
5826 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
5836 return ShadowExtension::Zero;
5840 return ShadowExtension::Sign;
5842 return ShadowExtension::None;
5846 unsigned GpOffset = SystemZGpOffset;
5847 unsigned FpOffset = SystemZFpOffset;
5848 unsigned VrIndex = 0;
5849 unsigned OverflowOffset = SystemZOverflowOffset;
5856 ArgKind AK = classifyArgument(
T);
5857 if (AK == ArgKind::Indirect) {
5858 T = PointerType::get(
T, 0);
5859 AK = ArgKind::GeneralPurpose;
5861 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
5862 AK = ArgKind::Memory;
5863 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
5864 AK = ArgKind::Memory;
5865 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
5866 AK = ArgKind::Memory;
5867 Value *ShadowBase =
nullptr;
5868 Value *OriginBase =
nullptr;
5869 ShadowExtension SE = ShadowExtension::None;
5871 case ArgKind::GeneralPurpose: {
5876 SE = getShadowExtension(CB, ArgNo);
5878 if (SE == ShadowExtension::None) {
5880 assert(ArgAllocSize <= ArgSize);
5881 GapSize = ArgSize - ArgAllocSize;
5883 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
5884 if (MS.TrackOrigins)
5885 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
5887 GpOffset += ArgSize;
5893 case ArgKind::FloatingPoint: {
5902 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
5903 if (MS.TrackOrigins)
5904 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
5906 FpOffset += ArgSize;
5912 case ArgKind::Vector: {
5919 case ArgKind::Memory: {
5927 SE = getShadowExtension(CB, ArgNo);
5929 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
5931 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
5932 if (MS.TrackOrigins)
5934 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
5935 OverflowOffset += ArgSize;
5942 case ArgKind::Indirect:
5945 if (ShadowBase ==
nullptr)
5947 Value *Shadow = MSV.getShadow(
A);
5948 if (SE != ShadowExtension::None)
5949 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
5950 SE == ShadowExtension::Sign);
5952 ShadowBase, PointerType::get(Shadow->
getType(), 0),
"_msarg_va_s");
5954 if (MS.TrackOrigins) {
5955 Value *Origin = MSV.getOrigin(
A);
5957 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
5961 Constant *OverflowSize = ConstantInt::get(
5962 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
5963 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
5967 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
5971 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
5972 PointerType::get(RegSaveAreaPtrTy, 0));
5973 Value *RegSaveAreaPtr = IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5974 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5976 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5977 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
5982 unsigned RegSaveAreaSize =
5983 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
5984 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5986 if (MS.TrackOrigins)
5987 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
5988 Alignment, RegSaveAreaSize);
5994 Type *OverflowArgAreaPtrTy = PointerType::getUnqual(*MS.C);
5998 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
5999 PointerType::get(OverflowArgAreaPtrTy, 0));
6000 Value *OverflowArgAreaPtr =
6001 IRB.
CreateLoad(OverflowArgAreaPtrTy, OverflowArgAreaPtrPtr);
6002 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
6004 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
6005 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
6008 SystemZOverflowOffset);
6009 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
6011 if (MS.TrackOrigins) {
6013 SystemZOverflowOffset);
6014 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
6019 void finalizeInstrumentation()
override {
6020 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
6021 "finalizeInstrumentation called twice");
6022 if (!VAStartInstrumentationList.empty()) {
6029 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
6037 Intrinsic::umin, CopySize,
6041 if (MS.TrackOrigins) {
6051 for (
CallInst *OrigInst : VAStartInstrumentationList) {
6052 NextNodeIRBuilder IRB(OrigInst);
6053 Value *VAListTag = OrigInst->getArgOperand(0);
6054 copyRegSaveArea(IRB, VAListTag);
6055 copyOverflowArea(IRB, VAListTag);
6062using VarArgLoongArch64Helper = VarArgMIPS64Helper;
6065struct VarArgNoOpHelper :
public VarArgHelper {
6066 VarArgNoOpHelper(
Function &
F, MemorySanitizer &MS,
6067 MemorySanitizerVisitor &MSV) {}
6075 void finalizeInstrumentation()
override {}
6081 MemorySanitizerVisitor &Visitor) {
6084 Triple TargetTriple(Func.getParent()->getTargetTriple());
6086 return new VarArgAMD64Helper(Func, Msan, Visitor);
6088 return new VarArgMIPS64Helper(Func, Msan, Visitor);
6090 return new VarArgAArch64Helper(Func, Msan, Visitor);
6093 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
6095 return new VarArgSystemZHelper(Func, Msan, Visitor);
6097 return new VarArgLoongArch64Helper(Func, Msan, Visitor);
6099 return new VarArgNoOpHelper(Func, Msan, Visitor);
6106 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
6109 MemorySanitizerVisitor Visitor(
F, *
this, TLI);
6113 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
6116 return Visitor.runOnFunction();
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isStore(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static const size_t kNumberOfAccessSizes
VarLocInsertPt getNextNode(const DbgRecord *DVR)
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
static bool isAMustTailRetVal(Value *RetVal)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
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)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isSigned(unsigned int Opcode)
This is the interface for a simple mod/ref and alias analysis over globals.
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
static const MemoryMapParams Linux_LoongArch64_MemoryMapParams
static const PlatformMemoryMapParams Linux_S390_MemoryMapParams
static const Align kMinOriginAlignment
static const MemoryMapParams Linux_X86_64_MemoryMapParams
static cl::opt< uint64_t > ClShadowBase("msan-shadow-base", cl::desc("Define custom MSan ShadowBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClDumpStrictInstructions("msan-dump-strict-instructions", cl::desc("print out instructions with default strict semantics"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClHandleICmpExact("msan-handle-icmp-exact", cl::desc("exact handling of relational integer ICmp"), cl::Hidden, cl::init(false))
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 const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static const MemoryMapParams Linux_S390X_MemoryMapParams
static cl::opt< bool > ClPoisonUndef("msan-poison-undef", cl::desc("poison undef temps"), cl::Hidden, cl::init(true))
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 > ClPrintStackNames("msan-print-stack-names", cl::desc("Print name of local stack variable"), cl::Hidden, cl::init(true))
static const MemoryMapParams Linux_AArch64_MemoryMapParams
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< 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 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))
Module.h This file contains the declarations for the Module class.
FunctionAnalysisManager FAM
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
Class for arbitrary precision integers.
an instruction to allocate memory on the stack
void setAlignment(Align Align)
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
This class represents a no-op cast from one type to another.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
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.
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
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.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
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 Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
static Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
This is the shared class of boolean and integer constants.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static ConstantInt * getBool(LLVMContext &Context, bool V)
static Constant * get(StructType *T, ArrayRef< Constant * > V)
static Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static Constant * getAllOnesValue(Type *Ty)
bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
bool isZeroValue() const
Return true if the value is negative zero or null value.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
static bool shouldExecute(unsigned CounterName)
This instruction compares its operands according to the predicate given to the constructor.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
This class represents a freeze function that returns random concrete value if an operand is either a ...
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.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
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.
This instruction compares its operands according to the predicate given to the constructor.
CallInst * CreateMaskedCompressStore(Value *Val, Value *Ptr, Value *Mask=nullptr)
Create a call to Masked Compress Store intrinsic.
CallInst * CreateMaskedExpandLoad(Type *Ty, Value *Ptr, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Expand Load intrinsic.
Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
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.
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
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)
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
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="")
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memset to the specified pointer and the specified value.
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 * CreateTypeSize(Type *DstType, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
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.
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)
CallInst * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
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 or truncated 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)
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)
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.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
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="")
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)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
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="")
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *TBAAStructTag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memcpy between the specified pointers.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment, Value *Mask=nullptr)
Create a call to Masked Scatter intrinsic.
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
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
This instruction inserts a single (scalar) element into a VectorType value.
This instruction inserts a struct field of array element value into an aggregate value.
Base class for instruction visitors.
void visit(Iterator Start, Iterator End)
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
This class represents a cast from an integer to a pointer.
Class to represent integer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
The landingpad instruction holds all of the information necessary to generate correct exception handl...
An instruction for reading from memory.
MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
This class wraps the llvm.memcpy intrinsic.
This class wraps the llvm.memmove intrinsic.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
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 PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...
static 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.
void abandon()
Mark an analysis as abandoned.
This class represents a cast from a pointer to an integer.
Resume the propagation of an exception.
Return a value (possibly void), from a function.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
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.
This instruction constructs a fixed permutation of two input vectors.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
Class to represent struct types.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
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).
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
This class represents a truncation of integer types.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
static IntegerType * getInt8Ty(LLVMContext &C)
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
'undef' values are things that do not have specified contents.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
This represents the llvm.va_copy intrinsic.
This represents the llvm.va_start intrinsic.
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void setName(const Twine &Name)
Change the name of the value.
StringRef getName() const
Return a constant reference to the value's name.
Type * getElementType() const
This class represents zero extension of integer types.
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.
This class provides various memory handling functions that manipulate MemoryBlock instances.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
initializer< Ty > init(const Ty &Val)
Function * Kernel
Summary of a kernel (=entry point for target offloading).
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ Or
Bitwise or logical OR of integers.
std::pair< Instruction *, Value * > SplitBlockAndInsertSimpleForLoop(Value *End, Instruction *SplitBefore)
Insert a for (int i = 0; i < End; i++) loop structure (with the exception that End is assumed > 0,...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr unsigned BitWidth
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.
iterator_range< df_iterator< T > > depth_first(const T &G)
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 ...
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...
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
A CRTP mix-in to automatically provide informational APIs needed for passes.