184#include "llvm/IR/IntrinsicsAArch64.h"
185#include "llvm/IR/IntrinsicsX86.h"
216#define DEBUG_TYPE "msan"
219 "Controls which checks to insert");
222 "Controls which instruction to instrument");
241 "msan-track-origins",
246 cl::desc(
"keep going after reporting a UMR"),
255 "msan-poison-stack-with-call",
260 "msan-poison-stack-pattern",
261 cl::desc(
"poison uninitialized stack variables with the given pattern"),
266 cl::desc(
"Print name of local stack variable"),
271 cl::desc(
"Poison fully undef temporary values. "
272 "Partially undefined constant vectors "
273 "are unaffected by this flag (see "
274 "-msan-poison-undef-vectors)."),
278 "msan-poison-undef-vectors",
279 cl::desc(
"Precisely poison partially undefined constant vectors. "
280 "If false (legacy behavior), the entire vector is "
281 "considered fully initialized, which may lead to false "
282 "negatives. Fully undefined constant vectors are "
283 "unaffected by this flag (see -msan-poison-undef)."),
287 "msan-precise-disjoint-or",
288 cl::desc(
"Precisely poison disjoint OR. If false (legacy behavior), "
289 "disjointedness is ignored (i.e., 1|1 is initialized)."),
294 cl::desc(
"propagate shadow through ICmpEQ and ICmpNE"),
299 cl::desc(
"exact handling of relational integer ICmp"),
303 "msan-switch-precision",
304 cl::desc(
"Controls the number of cases considered by MSan for LLVM switch "
305 "instructions. 0 means no UUMs detected. Higher values lead to "
306 "fewer false negatives but may impact compiler and/or "
307 "application performance. N.B. LLVM switch instructions do not "
308 "correspond exactly to C++ switch statements."),
312 "msan-handle-lifetime-intrinsics",
314 "when possible, poison scoped variables at the beginning of the scope "
315 "(slower, but more precise)"),
326 "msan-handle-asm-conservative",
337 "msan-check-access-address",
338 cl::desc(
"report accesses through a pointer which has poisoned shadow"),
343 cl::desc(
"check arguments and return values at function call boundaries"),
347 "msan-dump-strict-instructions",
348 cl::desc(
"print out instructions with default strict semantics i.e.,"
349 "check that all the inputs are fully initialized, and mark "
350 "the output as fully initialized. These semantics are applied "
351 "to instructions that could not be handled explicitly nor "
360 "msan-dump-heuristic-instructions",
361 cl::desc(
"Prints 'unknown' instructions that were handled heuristically. "
362 "Use -msan-dump-strict-instructions to print instructions that "
363 "could not be handled explicitly nor heuristically."),
367 "msan-instrumentation-with-call-threshold",
369 "If the function being instrumented requires more than "
370 "this number of checks and origin stores, use callbacks instead of "
371 "inline checks (-1 means never use callbacks)."),
376 cl::desc(
"Enable KernelMemorySanitizer instrumentation"),
386 cl::desc(
"Insert checks for constant shadow values"),
393 cl::desc(
"Place MSan constructors in comdat sections"),
399 cl::desc(
"Define custom MSan AndMask"),
403 cl::desc(
"Define custom MSan XorMask"),
407 cl::desc(
"Define custom MSan ShadowBase"),
411 cl::desc(
"Define custom MSan OriginBase"),
416 cl::desc(
"Define threshold for number of checks per "
417 "debug location to force origin update."),
429struct MemoryMapParams {
436struct PlatformMemoryMapParams {
437 const MemoryMapParams *bits32;
438 const MemoryMapParams *bits64;
615class MemorySanitizer {
624 MemorySanitizer(MemorySanitizer &&) =
delete;
625 MemorySanitizer &operator=(MemorySanitizer &&) =
delete;
626 MemorySanitizer(
const MemorySanitizer &) =
delete;
627 MemorySanitizer &operator=(
const MemorySanitizer &) =
delete;
629 bool sanitizeFunction(
Function &
F, TargetLibraryInfo &TLI);
632 friend struct MemorySanitizerVisitor;
633 friend struct VarArgHelperBase;
634 friend struct VarArgAMD64Helper;
635 friend struct VarArgAArch64Helper;
636 friend struct VarArgPowerPC64Helper;
637 friend struct VarArgPowerPC32Helper;
638 friend struct VarArgSystemZHelper;
639 friend struct VarArgI386Helper;
640 friend struct VarArgGenericHelper;
642 void initializeModule(
Module &M);
643 void initializeCallbacks(
Module &M,
const TargetLibraryInfo &TLI);
644 void createKernelApi(
Module &M,
const TargetLibraryInfo &TLI);
645 void createUserspaceApi(
Module &M,
const TargetLibraryInfo &TLI);
647 template <
typename... ArgsTy>
648 FunctionCallee getOrInsertMsanMetadataFunction(
Module &M, StringRef Name,
674 Value *ParamOriginTLS;
680 Value *RetvalOriginTLS;
686 Value *VAArgOriginTLS;
689 Value *VAArgOverflowSizeTLS;
692 bool CallbacksInitialized =
false;
695 FunctionCallee WarningFn;
699 FunctionCallee MaybeWarningVarSizeFn;
704 FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
706 FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
709 FunctionCallee MsanPoisonStackFn;
713 FunctionCallee MsanChainOriginFn;
716 FunctionCallee MsanSetOriginFn;
719 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
722 StructType *MsanContextStateTy;
723 FunctionCallee MsanGetContextStateFn;
726 FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
732 FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
733 FunctionCallee MsanMetadataPtrForLoad_1_8[4];
734 FunctionCallee MsanMetadataPtrForStore_1_8[4];
735 FunctionCallee MsanInstrumentAsmStoreFn;
738 Value *MsanMetadataAlloca;
741 FunctionCallee getKmsanShadowOriginAccessFn(
bool isStore,
int size);
744 const MemoryMapParams *MapParams;
748 MemoryMapParams CustomMapParams;
750 MDNode *ColdCallWeights;
753 MDNode *OriginStoreWeights;
793 if (!Options.Kernel) {
802 MemorySanitizer Msan(*
F.getParent(), Options);
820 static_cast<PassInfoMixin<MemorySanitizerPass> *
>(
this)->
printPipeline(
821 OS, MapClassName2PassName);
827 if (Options.EagerChecks)
828 OS <<
"eager-checks;";
829 OS <<
"track-origins=" << Options.TrackOrigins;
845template <
typename... ArgsTy>
847MemorySanitizer::getOrInsertMsanMetadataFunction(
Module &M,
StringRef Name,
852 std::forward<ArgsTy>(Args)...);
855 return M.getOrInsertFunction(Name, MsanMetadata,
856 std::forward<ArgsTy>(Args)...);
865 RetvalOriginTLS =
nullptr;
867 ParamOriginTLS =
nullptr;
869 VAArgOriginTLS =
nullptr;
870 VAArgOverflowSizeTLS =
nullptr;
872 WarningFn =
M.getOrInsertFunction(
"__msan_warning",
874 IRB.getVoidTy(), IRB.getInt32Ty());
885 MsanGetContextStateFn =
886 M.getOrInsertFunction(
"__msan_get_context_state", PtrTy);
890 for (
int ind = 0,
size = 1; ind < 4; ind++,
size <<= 1) {
891 std::string name_load =
892 "__msan_metadata_ptr_for_load_" + std::to_string(
size);
893 std::string name_store =
894 "__msan_metadata_ptr_for_store_" + std::to_string(
size);
895 MsanMetadataPtrForLoad_1_8[ind] =
896 getOrInsertMsanMetadataFunction(M, name_load, PtrTy);
897 MsanMetadataPtrForStore_1_8[ind] =
898 getOrInsertMsanMetadataFunction(M, name_store, PtrTy);
901 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
902 M,
"__msan_metadata_ptr_for_load_n", PtrTy, IntptrTy);
903 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
904 M,
"__msan_metadata_ptr_for_store_n", PtrTy, IntptrTy);
907 MsanPoisonAllocaFn =
M.getOrInsertFunction(
908 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
909 MsanUnpoisonAllocaFn =
M.getOrInsertFunction(
910 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
914 return M.getOrInsertGlobal(Name, Ty, [&] {
916 nullptr, Name,
nullptr,
922void MemorySanitizer::createUserspaceApi(
Module &M,
930 StringRef WarningFnName = Recover ?
"__msan_warning_with_origin"
931 :
"__msan_warning_with_origin_noreturn";
932 WarningFn =
M.getOrInsertFunction(WarningFnName,
934 IRB.getVoidTy(), IRB.getInt32Ty());
937 Recover ?
"__msan_warning" :
"__msan_warning_noreturn";
938 WarningFn =
M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
965 IRB.getIntPtrTy(
M.getDataLayout()));
969 unsigned AccessSize = 1 << AccessSizeIndex;
970 std::string FunctionName =
"__msan_maybe_warning_" +
itostr(AccessSize);
971 MaybeWarningFn[AccessSizeIndex] =
M.getOrInsertFunction(
973 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
974 MaybeWarningVarSizeFn =
M.getOrInsertFunction(
975 "__msan_maybe_warning_N", TLI.
getAttrList(
C, {},
false),
976 IRB.getVoidTy(), PtrTy, IRB.getInt64Ty(), IRB.getInt32Ty());
977 FunctionName =
"__msan_maybe_store_origin_" +
itostr(AccessSize);
978 MaybeStoreOriginFn[AccessSizeIndex] =
M.getOrInsertFunction(
980 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
984 MsanSetAllocaOriginWithDescriptionFn =
985 M.getOrInsertFunction(
"__msan_set_alloca_origin_with_descr",
986 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
987 MsanSetAllocaOriginNoDescriptionFn =
988 M.getOrInsertFunction(
"__msan_set_alloca_origin_no_descr",
989 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
990 MsanPoisonStackFn =
M.getOrInsertFunction(
"__msan_poison_stack",
991 IRB.getVoidTy(), PtrTy, IntptrTy);
995void MemorySanitizer::initializeCallbacks(
Module &M,
998 if (CallbacksInitialized)
1004 MsanChainOriginFn =
M.getOrInsertFunction(
1005 "__msan_chain_origin",
1006 TLI.
getAttrList(
C, {0},
false,
true), IRB.getInt32Ty(),
1008 MsanSetOriginFn =
M.getOrInsertFunction(
1010 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
1012 M.getOrInsertFunction(
"__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
1014 M.getOrInsertFunction(
"__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
1015 MemsetFn =
M.getOrInsertFunction(
"__msan_memset",
1017 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
1019 MsanInstrumentAsmStoreFn =
M.getOrInsertFunction(
1020 "__msan_instrument_asm_store", IRB.getVoidTy(), PtrTy, IntptrTy);
1022 if (CompileKernel) {
1023 createKernelApi(M, TLI);
1025 createUserspaceApi(M, TLI);
1027 CallbacksInitialized =
true;
1033 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
1051void MemorySanitizer::initializeModule(
Module &M) {
1052 auto &
DL =
M.getDataLayout();
1054 TargetTriple =
M.getTargetTriple();
1056 bool ShadowPassed =
ClShadowBase.getNumOccurrences() > 0;
1057 bool OriginPassed =
ClOriginBase.getNumOccurrences() > 0;
1059 if (ShadowPassed || OriginPassed) {
1064 MapParams = &CustomMapParams;
1066 switch (TargetTriple.getOS()) {
1068 switch (TargetTriple.getArch()) {
1083 switch (TargetTriple.getArch()) {
1092 switch (TargetTriple.getArch()) {
1129 C = &(
M.getContext());
1131 IntptrTy = IRB.getIntPtrTy(
DL);
1132 OriginTy = IRB.getInt32Ty();
1133 PtrTy = IRB.getPtrTy();
1138 if (!CompileKernel) {
1140 M.getOrInsertGlobal(
"__msan_track_origins", IRB.getInt32Ty(), [&] {
1141 return new GlobalVariable(
1142 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
1143 IRB.getInt32(TrackOrigins),
"__msan_track_origins");
1147 M.getOrInsertGlobal(
"__msan_keep_going", IRB.getInt32Ty(), [&] {
1148 return new GlobalVariable(M, IRB.getInt32Ty(), true,
1149 GlobalValue::WeakODRLinkage,
1150 IRB.getInt32(Recover),
"__msan_keep_going");
1165struct VarArgHelper {
1166 virtual ~VarArgHelper() =
default;
1169 virtual void visitCallBase(CallBase &CB,
IRBuilder<> &IRB) = 0;
1172 virtual void visitVAStartInst(VAStartInst &
I) = 0;
1175 virtual void visitVACopyInst(VACopyInst &
I) = 0;
1181 virtual void finalizeInstrumentation() = 0;
1184struct MemorySanitizerVisitor;
1189 MemorySanitizerVisitor &Visitor);
1196 if (TypeSizeFixed <= 8)
1205class NextNodeIRBuilder :
public IRBuilder<> {
1218struct MemorySanitizerVisitor :
public InstVisitor<MemorySanitizerVisitor> {
1220 MemorySanitizer &MS;
1222 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1223 std::unique_ptr<VarArgHelper> VAHelper;
1224 const TargetLibraryInfo *TLI;
1231 bool PropagateShadow;
1234 bool PoisonUndefVectors;
1236 struct ShadowOriginAndInsertPoint {
1241 ShadowOriginAndInsertPoint(
Value *S,
Value *O, Instruction *
I)
1242 : Shadow(S), Origin(
O), OrigIns(
I) {}
1245 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1246 SmallSetVector<AllocaInst *, 16> AllocaSet;
1249 int64_t SplittableBlocksCount = 0;
1251 MemorySanitizerVisitor(
Function &
F, MemorySanitizer &MS,
1252 const TargetLibraryInfo &TLI)
1254 bool SanitizeFunction =
1256 InsertChecks = SanitizeFunction;
1257 PropagateShadow = SanitizeFunction;
1268 MS.initializeCallbacks(*
F.getParent(), TLI);
1270 IRBuilder<>(&
F.getEntryBlock(),
F.getEntryBlock().getFirstNonPHIIt())
1271 .CreateIntrinsicWithoutFolding(Intrinsic::donothing, {});
1273 if (MS.CompileKernel) {
1275 insertKmsanPrologue(IRB);
1279 <<
"MemorySanitizer is not inserting checks into '"
1280 <<
F.getName() <<
"'\n");
1283 bool instrumentWithCalls(
Value *V) {
1287 ++SplittableBlocksCount;
1292 bool isInPrologue(Instruction &
I) {
1293 return I.getParent() == FnPrologueEnd->
getParent() &&
1302 if (MS.TrackOrigins <= 1)
1304 return IRB.
CreateCall(MS.MsanChainOriginFn, V);
1308 const DataLayout &
DL =
F.getDataLayout();
1309 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1319 TypeSize TS, Align Alignment) {
1320 const DataLayout &
DL =
F.getDataLayout();
1321 const Align IntptrAlignment =
DL.getABITypeAlign(MS.IntptrTy);
1322 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
1334 auto [InsertPt,
Index] =
1347 if (Alignment >= IntptrAlignment && IntptrSize >
kOriginSize) {
1348 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1350 for (
unsigned i = 0; i <
Size / IntptrSize; ++i) {
1355 CurrentAlignment = IntptrAlignment;
1368 Value *OriginPtr, Align Alignment) {
1369 const DataLayout &
DL =
F.getDataLayout();
1371 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
1373 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1382 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1389 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1391 if (instrumentWithCalls(ConvertedShadow) &&
1393 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1394 Value *ConvertedShadow2 =
1396 CallBase *CB = IRB.
CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1400 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1404 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1409 void materializeStores() {
1410 for (StoreInst *SI : StoreList) {
1412 Value *Val =
SI->getValueOperand();
1413 Value *Addr =
SI->getPointerOperand();
1414 Value *Shadow =
SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1415 Value *ShadowPtr, *OriginPtr;
1419 std::tie(ShadowPtr, OriginPtr) =
1420 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
true);
1422 [[maybe_unused]] StoreInst *NewSI =
1429 if (MS.TrackOrigins && !
SI->isAtomic())
1430 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1437 if (MS.TrackOrigins < 2)
1440 if (LazyWarningDebugLocationCount.
empty())
1441 for (
const auto &
I : InstrumentationList)
1442 ++LazyWarningDebugLocationCount[
I.OrigIns->getDebugLoc()];
1458 auto NewDebugLoc = OI->getDebugLoc();
1465 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1466 Origin = updateOrigin(Origin, IRBOrigin);
1471 if (MS.CompileKernel || MS.TrackOrigins)
1482 const DataLayout &
DL =
F.getDataLayout();
1483 TypeSize TypeSizeInBits =
DL.getTypeSizeInBits(ConvertedShadow->
getType());
1485 if (instrumentWithCalls(ConvertedShadow) && !MS.CompileKernel) {
1487 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1488 Value *ConvertedShadow2 =
1492 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1496 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1500 FunctionCallee Fn = MS.MaybeWarningVarSizeFn;
1503 unsigned ShadowSize =
DL.getTypeAllocSize(ConvertedShadow2->
getType());
1506 {ShadowAlloca, ConstantInt::get(IRB.
getInt64Ty(), ShadowSize),
1507 MS.TrackOrigins && Origin ? Origin : (
Value *)IRB.
getInt32(0)});
1512 Value *
Cmp = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1515 !MS.Recover, MS.ColdCallWeights);
1518 insertWarningFn(IRB, Origin);
1523 void materializeInstructionChecks(
1525 const DataLayout &
DL =
F.getDataLayout();
1528 bool Combine = !MS.TrackOrigins;
1530 Value *Shadow =
nullptr;
1531 for (
const auto &ShadowData : InstructionChecks) {
1532 assert(ShadowData.OrigIns == Instruction);
1535 Value *ConvertedShadow = ShadowData.Shadow;
1544 insertWarningFn(IRB, ShadowData.Origin);
1554 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1559 Shadow = ConvertedShadow;
1563 Shadow = convertToBool(Shadow, IRB,
"_mscmp");
1564 ConvertedShadow = convertToBool(ConvertedShadow, IRB,
"_mscmp");
1565 Shadow = IRB.
CreateOr(Shadow, ConvertedShadow,
"_msor");
1571 materializeOneCheck(IRB, Shadow,
nullptr);
1575 static bool isAArch64SVCount(
Type *Ty) {
1577 return TTy->
getName() ==
"aarch64.svcount";
1583 static bool isScalableNonVectorType(
Type *Ty) {
1584 if (!isAArch64SVCount(Ty))
1585 LLVM_DEBUG(
dbgs() <<
"isScalableNonVectorType: Unexpected type " << *Ty
1591 void materializeChecks() {
1594 SmallPtrSet<Instruction *, 16>
Done;
1597 for (
auto I = InstrumentationList.begin();
1598 I != InstrumentationList.end();) {
1599 auto OrigIns =
I->OrigIns;
1603 auto J = std::find_if(
I + 1, InstrumentationList.end(),
1604 [OrigIns](
const ShadowOriginAndInsertPoint &R) {
1605 return OrigIns != R.OrigIns;
1619 MS.ParamTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1620 {Zero, IRB.getInt32(0)},
"param_shadow");
1621 MS.RetvalTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1622 {Zero, IRB.getInt32(1)},
"retval_shadow");
1623 MS.VAArgTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1624 {Zero, IRB.getInt32(2)},
"va_arg_shadow");
1625 MS.VAArgOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1626 {Zero, IRB.getInt32(3)},
"va_arg_origin");
1627 MS.VAArgOverflowSizeTLS =
1628 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1629 {Zero, IRB.getInt32(4)},
"va_arg_overflow_size");
1630 MS.ParamOriginTLS = IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1631 {Zero, IRB.getInt32(5)},
"param_origin");
1632 MS.RetvalOriginTLS =
1633 IRB.
CreateGEP(MS.MsanContextStateTy, ContextState,
1634 {Zero, IRB.getInt32(6)},
"retval_origin");
1636 MS.MsanMetadataAlloca = IRB.
CreateAlloca(MS.MsanMetadata, 0u);
1649 for (Instruction *
I : Instructions)
1653 for (PHINode *PN : ShadowPHINodes) {
1655 PHINode *PNO = MS.TrackOrigins ?
cast<PHINode>(getOrigin(PN)) : nullptr;
1656 size_t NumValues = PN->getNumIncomingValues();
1657 for (
size_t v = 0;
v < NumValues;
v++) {
1658 PNS->
addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1660 PNO->
addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1664 VAHelper->finalizeInstrumentation();
1669 for (
auto Item : LifetimeStartList) {
1670 instrumentAlloca(*Item.second, Item.first);
1671 AllocaSet.
remove(Item.second);
1676 for (AllocaInst *AI : AllocaSet)
1677 instrumentAlloca(*AI);
1680 materializeChecks();
1684 materializeStores();
1690 Type *getShadowTy(
Value *V) {
return getShadowTy(
V->getType()); }
1701 const DataLayout &
DL =
F.getDataLayout();
1703 uint32_t EltSize =
DL.getTypeSizeInBits(VT->getElementType());
1705 VT->getElementCount());
1708 return ArrayType::get(getShadowTy(AT->getElementType()),
1709 AT->getNumElements());
1713 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1714 Elements.push_back(getShadowTy(
ST->getElementType(i)));
1716 LLVM_DEBUG(
dbgs() <<
"getShadowTy: " << *ST <<
" ===> " << *Res <<
"\n");
1719 if (isScalableNonVectorType(OrigTy)) {
1720 LLVM_DEBUG(
dbgs() <<
"getShadowTy: Scalable non-vector type: " << *OrigTy
1725 uint32_t TypeSize =
DL.getTypeSizeInBits(OrigTy);
1730 Value *collapseStructShadow(StructType *Struct,
Value *Shadow,
1735 for (
unsigned Idx = 0; Idx <
Struct->getNumElements(); Idx++) {
1738 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1740 if (Aggregator != FalseVal)
1741 Aggregator = IRB.
CreateOr(Aggregator, ShadowBool);
1743 Aggregator = ShadowBool;
1750 Value *collapseArrayShadow(ArrayType *Array,
Value *Shadow,
1752 if (!
Array->getNumElements())
1756 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1758 for (
unsigned Idx = 1; Idx <
Array->getNumElements(); Idx++) {
1760 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1761 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
1771 return collapseStructShadow(Struct, V, IRB);
1773 return collapseArrayShadow(Array, V, IRB);
1778 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1786 Type *VTy =
V->getType();
1788 return convertToBool(convertShadowToScalar(V, IRB), IRB,
name);
1795 Type *ptrToIntPtrType(
Type *PtrTy)
const {
1797 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1798 VectTy->getElementCount());
1806 return VectorType::get(
1807 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1808 VectTy->getElementCount());
1817 VectTy->getElementCount(),
1818 constToIntPtr(VectTy->getElementType(),
C));
1823 return ConstantInt::get(MS.IntptrTy,
C,
false,
1837 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1840 if (
uint64_t AndMask = MS.MapParams->AndMask)
1841 OffsetLong = IRB.
CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1843 if (
uint64_t XorMask = MS.MapParams->XorMask)
1844 OffsetLong = IRB.
CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1856 std::pair<Value *, Value *>
1858 MaybeAlign Alignment) {
1863 assert(VectTy->getElementType()->isPointerTy());
1865 Type *IntptrTy = ptrToIntPtrType(Addr->
getType());
1866 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1867 Value *ShadowLong = ShadowOffset;
1868 if (
uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1870 IRB.
CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1873 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1875 Value *OriginPtr =
nullptr;
1876 if (MS.TrackOrigins) {
1877 Value *OriginLong = ShadowOffset;
1878 uint64_t OriginBase = MS.MapParams->OriginBase;
1879 if (OriginBase != 0)
1881 IRB.
CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1884 OriginLong = IRB.
CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1887 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1889 return std::make_pair(ShadowPtr, OriginPtr);
1892 template <
typename... ArgsTy>
1897 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1898 return IRB.
CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1901 return IRB.
CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1904 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(
Value *Addr,
1908 Value *ShadowOriginPtrs;
1909 const DataLayout &
DL =
F.getDataLayout();
1910 TypeSize
Size =
DL.getTypeStoreSize(ShadowTy);
1912 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(
isStore,
Size);
1915 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1917 Value *SizeVal = ConstantInt::get(MS.IntptrTy,
Size);
1918 ShadowOriginPtrs = createMetadataCall(
1920 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1927 return std::make_pair(ShadowPtr, OriginPtr);
1933 std::pair<Value *, Value *> getShadowOriginPtrKernel(
Value *Addr,
1940 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy,
isStore);
1945 Value *ShadowPtrs = ConstantInt::getNullValue(
1947 Value *OriginPtrs =
nullptr;
1948 if (MS.TrackOrigins)
1949 OriginPtrs = ConstantInt::getNullValue(
1951 for (
unsigned i = 0; i < NumElements; ++i) {
1954 auto [ShadowPtr, OriginPtr] =
1955 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy,
isStore);
1958 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1959 if (MS.TrackOrigins)
1961 OriginPtrs, OriginPtr, ConstantInt::get(IRB.
getInt32Ty(), i));
1963 return {ShadowPtrs, OriginPtrs};
1966 std::pair<Value *, Value *> getShadowOriginPtr(
Value *Addr,
IRBuilder<> &IRB,
1968 MaybeAlign Alignment,
1970 if (MS.CompileKernel)
1971 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy,
isStore);
1972 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1980 ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg");
1985 if (!MS.TrackOrigins)
1988 ConstantInt::get(MS.IntptrTy, ArgOffset),
1998 Value *getOriginPtrForRetval() {
2000 return MS.RetvalOriginTLS;
2005 assert(!ShadowMap.
count(V) &&
"Values may only have one shadow");
2006 ShadowMap[
V] = PropagateShadow ?
SV : getCleanShadow(V);
2011 if (!MS.TrackOrigins)
2013 assert(!OriginMap.
count(V) &&
"Values may only have one origin");
2014 LLVM_DEBUG(
dbgs() <<
"ORIGIN: " << *V <<
" ==> " << *Origin <<
"\n");
2015 OriginMap[
V] = Origin;
2019 Type *ShadowTy = getShadowTy(OrigTy);
2029 Constant *getCleanShadow(
Value *V) {
return getCleanShadow(
V->getType()); }
2037 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
2038 getPoisonedShadow(AT->getElementType()));
2042 SmallVector<Constant *, 4> Vals;
2043 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
2044 Vals.
push_back(getPoisonedShadow(
ST->getElementType(i)));
2052 Type *ShadowTy = getShadowTy(V);
2055 return getPoisonedShadow(ShadowTy);
2067 if (!PropagateShadow ||
I->getMetadata(LLVMContext::MD_nosanitize))
2068 return getCleanShadow(V);
2070 Value *Shadow = ShadowMap[
V];
2072 LLVM_DEBUG(
dbgs() <<
"No shadow: " << *V <<
"\n" << *(
I->getParent()));
2073 assert(Shadow &&
"No shadow for a value");
2080 Value *
AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
2081 : getCleanShadow(V);
2087 Value *&ShadowPtr = ShadowMap[
V];
2092 unsigned ArgOffset = 0;
2093 const DataLayout &
DL =
F->getDataLayout();
2094 for (
auto &FArg :
F->args()) {
2095 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
2097 ?
"vscale not fully supported\n"
2098 :
"Arg is not sized\n"));
2100 ShadowPtr = getCleanShadow(V);
2101 setOrigin(
A, getCleanOrigin());
2107 unsigned Size = FArg.hasByValAttr()
2108 ?
DL.getTypeAllocSize(FArg.getParamByValType())
2109 :
DL.getTypeAllocSize(FArg.getType());
2113 if (FArg.hasByValAttr()) {
2117 const Align ArgAlign =
DL.getValueOrABITypeAlignment(
2118 FArg.getParamAlign(), FArg.getParamByValType());
2119 Value *CpShadowPtr, *CpOriginPtr;
2120 std::tie(CpShadowPtr, CpOriginPtr) =
2121 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
2123 if (!PropagateShadow || Overflow) {
2125 EntryIRB.CreateMemSet(
2129 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2131 [[maybe_unused]]
Value *Cpy = EntryIRB.CreateMemCpy(
2132 CpShadowPtr, CopyAlign,
Base, CopyAlign,
Size);
2135 if (MS.TrackOrigins) {
2136 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
2140 EntryIRB.CreateMemCpy(
2149 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
2150 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
2151 ShadowPtr = getCleanShadow(V);
2152 setOrigin(
A, getCleanOrigin());
2155 Value *
Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2156 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg),
Base,
2158 if (MS.TrackOrigins) {
2159 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
2160 setOrigin(
A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
2164 <<
" ARG: " << FArg <<
" ==> " << *ShadowPtr <<
"\n");
2170 assert(ShadowPtr &&
"Could not find shadow for an argument");
2177 cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
2178 PoisonUndefVectors) {
2181 for (
unsigned i = 0; i != NumElems; ++i) {
2184 : getCleanShadow(Elem);
2188 LLVM_DEBUG(
dbgs() <<
"Partial undef constant vector: " << *V <<
" ==> "
2189 << *ShadowConstant <<
"\n");
2191 return ShadowConstant;
2197 return getCleanShadow(V);
2201 Value *getShadow(Instruction *
I,
int i) {
2202 return getShadow(
I->getOperand(i));
2207 if (!MS.TrackOrigins)
2210 return getCleanOrigin();
2212 "Unexpected value type in getOrigin()");
2214 if (
I->getMetadata(LLVMContext::MD_nosanitize))
2215 return getCleanOrigin();
2217 Value *Origin = OriginMap[
V];
2218 assert(Origin &&
"Missing origin");
2223 Value *getOrigin(Instruction *
I,
int i) {
2224 return getOrigin(
I->getOperand(i));
2231 void insertCheckShadow(
Value *Shadow,
Value *Origin, Instruction *OrigIns) {
2237 LLVM_DEBUG(
dbgs() <<
"Skipping check of " << *Shadow <<
" before "
2238 << *OrigIns <<
"\n");
2243 if (isScalableNonVectorType(ShadowTy)) {
2244 LLVM_DEBUG(
dbgs() <<
"Skipping check of scalable non-vector " << *Shadow
2245 <<
" before " << *OrigIns <<
"\n");
2251 "Can only insert checks for integer, vector, and aggregate shadow "
2254 InstrumentationList.push_back(
2255 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2263 void insertCheckShadowOf(
Value *Val, Instruction *OrigIns) {
2265 Value *Shadow, *Origin;
2267 Shadow = getShadow(Val);
2270 Origin = getOrigin(Val);
2277 insertCheckShadow(Shadow, Origin, OrigIns);
2282 case AtomicOrdering::NotAtomic:
2283 return AtomicOrdering::NotAtomic;
2284 case AtomicOrdering::Unordered:
2285 case AtomicOrdering::Monotonic:
2286 case AtomicOrdering::Release:
2287 return AtomicOrdering::Release;
2288 case AtomicOrdering::Acquire:
2289 case AtomicOrdering::AcquireRelease:
2290 return AtomicOrdering::AcquireRelease;
2291 case AtomicOrdering::SequentiallyConsistent:
2292 return AtomicOrdering::SequentiallyConsistent;
2298 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2299 uint32_t OrderingTable[NumOrderings] = {};
2301 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2302 OrderingTable[(
int)AtomicOrderingCABI::release] =
2303 (int)AtomicOrderingCABI::release;
2304 OrderingTable[(int)AtomicOrderingCABI::consume] =
2305 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2306 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2307 (
int)AtomicOrderingCABI::acq_rel;
2308 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2309 (
int)AtomicOrderingCABI::seq_cst;
2316 case AtomicOrdering::NotAtomic:
2317 return AtomicOrdering::NotAtomic;
2318 case AtomicOrdering::Unordered:
2319 case AtomicOrdering::Monotonic:
2320 case AtomicOrdering::Acquire:
2321 return AtomicOrdering::Acquire;
2322 case AtomicOrdering::Release:
2323 case AtomicOrdering::AcquireRelease:
2324 return AtomicOrdering::AcquireRelease;
2325 case AtomicOrdering::SequentiallyConsistent:
2326 return AtomicOrdering::SequentiallyConsistent;
2332 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2333 uint32_t OrderingTable[NumOrderings] = {};
2335 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2336 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
2337 OrderingTable[(int)AtomicOrderingCABI::consume] =
2338 (
int)AtomicOrderingCABI::acquire;
2339 OrderingTable[(int)AtomicOrderingCABI::release] =
2340 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
2341 (int)AtomicOrderingCABI::acq_rel;
2342 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2343 (
int)AtomicOrderingCABI::seq_cst;
2349 using InstVisitor<MemorySanitizerVisitor>
::visit;
2350 void visit(Instruction &
I) {
2351 if (
I.getMetadata(LLVMContext::MD_nosanitize))
2354 if (isInPrologue(
I))
2359 setShadow(&
I, getCleanShadow(&
I));
2360 setOrigin(&
I, getCleanOrigin());
2371 void visitLoadInst(LoadInst &
I) {
2372 assert(
I.getType()->isSized() &&
"Load type must have size");
2373 assert(!
I.getMetadata(LLVMContext::MD_nosanitize));
2374 NextNodeIRBuilder IRB(&
I);
2375 Type *ShadowTy = getShadowTy(&
I);
2376 Value *Addr =
I.getPointerOperand();
2377 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
2379 if (PropagateShadow) {
2380 std::tie(ShadowPtr, OriginPtr) =
2381 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
2385 setShadow(&
I, getCleanShadow(&
I));
2389 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2394 if (MS.TrackOrigins) {
2395 if (PropagateShadow) {
2400 setOrigin(&
I, getCleanOrigin());
2409 void visitStoreInst(StoreInst &
I) {
2410 StoreList.push_back(&
I);
2412 insertCheckShadowOf(
I.getPointerOperand(), &
I);
2415 void handleCASOrRMW(Instruction &
I) {
2419 Value *Addr =
I.getOperand(0);
2420 Value *Val =
I.getOperand(1);
2421 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val),
Align(1),
2426 insertCheckShadowOf(Addr, &
I);
2432 insertCheckShadowOf(Val, &
I);
2436 setShadow(&
I, getCleanShadow(&
I));
2437 setOrigin(&
I, getCleanOrigin());
2440 void visitAtomicRMWInst(AtomicRMWInst &
I) {
2445 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2507 void visitSwitchInst(SwitchInst &SI) {
2510 Value *Val =
SI.getCondition();
2511 Value *ShadowVal = getShadow(Val);
2523 Value *ShadowCases =
nullptr;
2524 for (
auto Case :
SI.cases()) {
2525 if (casesToConsider <= 0)
2528 Value *Comparator = Case.getCaseValue();
2531 Value *ComparisonShadow = propagateEqualityComparison(
2532 IRB, Val, Comparator, ShadowVal, getShadow(Comparator));
2535 ShadowCases = IRB.
CreateOr(ShadowCases, ComparisonShadow);
2537 ShadowCases = ComparisonShadow;
2543 insertCheckShadow(ShadowCases, getOrigin(Val), &SI);
2547 void visitExtractElementInst(ExtractElementInst &
I) {
2548 insertCheckShadowOf(
I.getOperand(1), &
I);
2552 setOrigin(&
I, getOrigin(&
I, 0));
2555 void visitInsertElementInst(InsertElementInst &
I) {
2556 insertCheckShadowOf(
I.getOperand(2), &
I);
2558 auto *Shadow0 = getShadow(&
I, 0);
2559 auto *Shadow1 = getShadow(&
I, 1);
2562 setOriginForNaryOp(
I);
2565 void visitShuffleVectorInst(ShuffleVectorInst &
I) {
2567 auto *Shadow0 = getShadow(&
I, 0);
2568 auto *Shadow1 = getShadow(&
I, 1);
2571 setOriginForNaryOp(
I);
2575 void visitSExtInst(SExtInst &
I) {
2577 setShadow(&
I, IRB.
CreateSExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2578 setOrigin(&
I, getOrigin(&
I, 0));
2581 void visitZExtInst(ZExtInst &
I) {
2583 setShadow(&
I, IRB.
CreateZExt(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2584 setOrigin(&
I, getOrigin(&
I, 0));
2587 void visitTruncInst(TruncInst &
I) {
2589 setShadow(&
I, IRB.
CreateTrunc(getShadow(&
I, 0),
I.getType(),
"_msprop"));
2590 setOrigin(&
I, getOrigin(&
I, 0));
2593 void visitBitCastInst(BitCastInst &
I) {
2598 if (CI->isMustTailCall())
2602 setOrigin(&
I, getOrigin(&
I, 0));
2605 void visitPtrToIntInst(PtrToIntInst &
I) {
2608 "_msprop_ptrtoint"));
2609 setOrigin(&
I, getOrigin(&
I, 0));
2612 void visitPtrToAddrInst(PtrToAddrInst &
I) {
2615 "_msprop_ptrtoaddr"));
2616 setOrigin(&
I, getOrigin(&
I, 0));
2619 void visitIntToPtrInst(IntToPtrInst &
I) {
2622 "_msprop_inttoptr"));
2623 setOrigin(&
I, getOrigin(&
I, 0));
2644 void handleGenericVectorConvertIntrinsic(Instruction &
I,
bool FixedPoint) {
2645 [[maybe_unused]]
unsigned NumArgs =
I.getNumOperands();
2647 NumArgs = CI->arg_size();
2651 Value *Precision =
I.getOperand(1);
2652 insertCheckShadowOf(Precision, &
I);
2658 Value *S0 = getShadow(&
I, 0);
2668 setShadow(&
I, OutShadow);
2669 setOriginForNaryOp(
I);
2672 void visitFPToSIInst(CastInst &
I) {
2673 handleGenericVectorConvertIntrinsic(
I,
false);
2675 void visitFPToUIInst(CastInst &
I) {
2676 handleGenericVectorConvertIntrinsic(
I,
false);
2678 void visitSIToFPInst(CastInst &
I) {
2679 handleGenericVectorConvertIntrinsic(
I,
false);
2681 void visitUIToFPInst(CastInst &
I) {
2682 handleGenericVectorConvertIntrinsic(
I,
false);
2685 void visitFPExtInst(CastInst &
I) {
2686 handleGenericVectorConvertIntrinsic(
I,
false);
2688 void visitFPTruncInst(CastInst &
I) {
2689 handleGenericVectorConvertIntrinsic(
I,
false);
2710 assert(
V1->getType()->isIntOrIntVectorTy());
2721 return IRB.
CreateOr({S1S2, V1S2, S1V2});
2725 void visitAnd(BinaryOperator &
I) {
2728 Value *V2 =
I.getOperand(1);
2730 Value *S2 = getShadow(&
I, 1);
2732 Value *OutShadow = handleBitwiseAnd(IRB,
V1, V2,
S1, S2);
2734 setShadow(&
I, OutShadow);
2735 setOriginForNaryOp(
I);
2738 void visitOr(BinaryOperator &
I) {
2751 Value *S2 = getShadow(&
I, 1);
2753 Value *V2 =
I.getOperand(1);
2757 assert(
V1->getType()->isIntOrIntVectorTy());
2777 S = IRB.
CreateOr(S, DisjointOrShadow,
"_ms_disjoint");
2781 setOriginForNaryOp(
I);
2799 template <
bool CombineShadow>
class Combiner {
2800 Value *Shadow =
nullptr;
2801 Value *Origin =
nullptr;
2803 MemorySanitizerVisitor *MSV;
2806 Combiner(MemorySanitizerVisitor *MSV,
IRBuilder<> &IRB)
2807 : IRB(IRB), MSV(MSV) {}
2811 if (CombineShadow) {
2816 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2817 Shadow = IRB.
CreateOr(Shadow, OpShadow,
"_msprop");
2821 if (MSV->MS.TrackOrigins) {
2828 if (!ConstOrigin || !ConstOrigin->
isNullValue()) {
2829 Value *
Cond = MSV->convertToBool(OpShadow, IRB);
2839 Value *OpShadow = MSV->getShadow(V);
2840 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) :
nullptr;
2841 return Add(OpShadow, OpOrigin);
2846 void Done(Instruction *
I) {
2847 if (CombineShadow) {
2849 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(
I));
2850 MSV->setShadow(
I, Shadow);
2852 if (MSV->MS.TrackOrigins) {
2854 MSV->setOrigin(
I, Origin);
2860 void DoneAndStoreOrigin(TypeSize TS,
Value *OriginPtr) {
2861 if (MSV->MS.TrackOrigins) {
2868 using ShadowAndOriginCombiner = Combiner<true>;
2869 using OriginCombiner = Combiner<false>;
2872 void setOriginForNaryOp(Instruction &
I) {
2873 if (!MS.TrackOrigins)
2876 OriginCombiner OC(
this, IRB);
2877 for (Use &
Op :
I.operands())
2882 size_t VectorOrPrimitiveTypeSizeInBits(
Type *Ty) {
2884 "Vector of pointers is not a valid shadow type");
2894 Type *srcTy =
V->getType();
2897 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2898 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2899 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2917 Type *ShadowTy = getShadowTy(V);
2918 if (
V->getType() == ShadowTy)
2920 if (
V->getType()->isPtrOrPtrVectorTy())
2927 void handleShadowOr(Instruction &
I) {
2929 ShadowAndOriginCombiner SC(
this, IRB);
2930 for (Use &
Op :
I.operands())
2957 Value *horizontalReduce(IntrinsicInst &
I,
unsigned ReductionFactor,
2958 unsigned Shards,
Value *VectorA,
Value *VectorB) {
2963 [[maybe_unused]]
unsigned TotalNumElems = NumElems;
2969 assert(NumElems % (ReductionFactor * Shards) == 0);
2974 for (
unsigned i = 0; i < ReductionFactor; i++) {
2975 SmallVector<int, 16>
Mask;
2977 for (
unsigned j = 0;
j < Shards;
j++) {
2978 unsigned Offset = NumElems / Shards *
j;
2980 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
2984 for (
unsigned X = 0;
X < NumElems / Shards;
X += ReductionFactor)
3009 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards) {
3010 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
3012 assert(
I.getType()->isVectorTy());
3013 assert(
I.getArgOperand(0)->getType()->isVectorTy());
3015 [[maybe_unused]] FixedVectorType *ParamType =
3019 [[maybe_unused]] FixedVectorType *
ReturnType =
3027 Value *FirstArgShadow = getShadow(&
I, 0);
3028 Value *SecondArgShadow =
nullptr;
3029 if (
I.arg_size() == 2)
3030 SecondArgShadow = getShadow(&
I, 1);
3032 Value *OrShadow = horizontalReduce(
I, 2, Shards,
3033 FirstArgShadow, SecondArgShadow);
3035 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
3037 setShadow(&
I, OrShadow);
3038 setOriginForNaryOp(
I);
3048 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &
I,
unsigned Shards,
3049 int ReinterpretElemWidth) {
3050 assert(
I.arg_size() == 1 ||
I.arg_size() == 2);
3052 assert(
I.getType()->isVectorTy());
3053 assert(
I.getArgOperand(0)->getType()->isVectorTy());
3055 FixedVectorType *ParamType =
3060 [[maybe_unused]] FixedVectorType *
ReturnType =
3067 FixedVectorType *ReinterpretShadowTy =
nullptr;
3075 Value *FirstArgShadow = getShadow(&
I, 0);
3076 FirstArgShadow = IRB.
CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
3086 Value *SecondArgShadow =
nullptr;
3087 if (
I.arg_size() == 2) {
3088 SecondArgShadow = getShadow(&
I, 1);
3089 SecondArgShadow = IRB.
CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
3092 Value *OrShadow = horizontalReduce(
I, 2, Shards,
3093 FirstArgShadow, SecondArgShadow);
3095 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&
I));
3097 setShadow(&
I, OrShadow);
3098 setOriginForNaryOp(
I);
3101 void visitFNeg(UnaryOperator &
I) { handleShadowOr(
I); }
3112 void handleMulByConstant(BinaryOperator &
I, Constant *ConstArg,
3118 Type *EltTy = VTy->getElementType();
3120 for (
unsigned Idx = 0; Idx < NumElements; ++Idx) {
3121 if (ConstantInt *Elt =
3123 const APInt &
V = Elt->getValue();
3124 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
3125 Elements.push_back(ConstantInt::get(EltTy, V2));
3127 Elements.push_back(ConstantInt::get(EltTy, 1));
3133 const APInt &
V = Elt->getValue();
3134 APInt V2 = APInt(
V.getBitWidth(), 1) <<
V.countr_zero();
3135 ShadowMul = ConstantInt::get(Ty, V2);
3137 ShadowMul = ConstantInt::get(Ty, 1);
3143 IRB.
CreateMul(getShadow(OtherArg), ShadowMul,
"msprop_mul_cst"));
3144 setOrigin(&
I, getOrigin(OtherArg));
3147 void visitMul(BinaryOperator &
I) {
3150 if (constOp0 && !constOp1)
3151 handleMulByConstant(
I, constOp0,
I.getOperand(1));
3152 else if (constOp1 && !constOp0)
3153 handleMulByConstant(
I, constOp1,
I.getOperand(0));
3158 void visitFAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3159 void visitFSub(BinaryOperator &
I) { handleShadowOr(
I); }
3160 void visitFMul(BinaryOperator &
I) { handleShadowOr(
I); }
3161 void visitAdd(BinaryOperator &
I) { handleShadowOr(
I); }
3162 void visitSub(BinaryOperator &
I) { handleShadowOr(
I); }
3163 void visitXor(BinaryOperator &
I) { handleShadowOr(
I); }
3165 void handleIntegerDiv(Instruction &
I) {
3168 insertCheckShadowOf(
I.getOperand(1), &
I);
3169 setShadow(&
I, getShadow(&
I, 0));
3170 setOrigin(&
I, getOrigin(&
I, 0));
3173 void visitUDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3174 void visitSDiv(BinaryOperator &
I) { handleIntegerDiv(
I); }
3175 void visitURem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3176 void visitSRem(BinaryOperator &
I) { handleIntegerDiv(
I); }
3180 void visitFDiv(BinaryOperator &
I) { handleShadowOr(
I); }
3181 void visitFRem(BinaryOperator &
I) { handleShadowOr(
I); }
3187 void handleEqualityComparison(ICmpInst &
I) {
3191 Value *Sa = getShadow(
A);
3192 Value *Sb = getShadow(
B);
3194 Value *Si = propagateEqualityComparison(IRB,
A,
B, Sa, Sb);
3197 setOriginForNaryOp(
I);
3205 void handleRelationalComparisonExact(ICmpInst &
I) {
3209 Value *Sa = getShadow(
A);
3210 Value *Sb = getShadow(
B);
3221 bool IsSigned =
I.isSigned();
3223 auto GetMinMaxUnsigned = [&](
Value *
V,
Value *S) {
3233 V = IRB.
CreateXor(V, ConstantInt::get(
V->getType(), MinVal));
3238 return std::make_pair(Min, Max);
3241 auto [Amin, Amax] = GetMinMaxUnsigned(
A, Sa);
3242 auto [Bmin, Bmax] = GetMinMaxUnsigned(
B, Sb);
3248 setOriginForNaryOp(
I);
3255 void handleSignedRelationalComparison(ICmpInst &
I) {
3260 op =
I.getOperand(0);
3261 pre =
I.getPredicate();
3263 op =
I.getOperand(1);
3264 pre =
I.getSwappedPredicate();
3277 setShadow(&
I, Shadow);
3278 setOrigin(&
I, getOrigin(
op));
3284 void visitICmpInst(ICmpInst &
I) {
3289 if (
I.isEquality()) {
3290 handleEqualityComparison(
I);
3296 handleRelationalComparisonExact(
I);
3300 handleSignedRelationalComparison(
I);
3306 handleRelationalComparisonExact(
I);
3313 void visitFCmpInst(FCmpInst &
I) { handleShadowOr(
I); }
3315 void handleShift(BinaryOperator &
I) {
3320 Value *S2 = getShadow(&
I, 1);
3323 Value *V2 =
I.getOperand(1);
3325 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3326 setOriginForNaryOp(
I);
3329 void visitShl(BinaryOperator &
I) { handleShift(
I); }
3330 void visitAShr(BinaryOperator &
I) { handleShift(
I); }
3331 void visitLShr(BinaryOperator &
I) { handleShift(
I); }
3333 void handleFunnelShift(IntrinsicInst &
I) {
3337 Value *S0 = getShadow(&
I, 0);
3339 Value *S2 = getShadow(&
I, 2);
3342 Value *V2 =
I.getOperand(2);
3345 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3346 setOriginForNaryOp(
I);
3354 void handleGenericBitManipulation(IntrinsicInst &
I) {
3356 Type *ShadowTy = getShadowTy(&
I);
3359 Value *SMask = getShadow(&
I, 1);
3364 if (
Function *Func =
I.getCalledFunction())
3365 S = IRB.
CreateCall(Func, {getShadow(&
I, 0),
I.getOperand(1)});
3368 {getShadow(&I, 0), I.getOperand(1)});
3371 setOriginForNaryOp(
I);
3384 void visitMemMoveInst(MemMoveInst &
I) {
3385 getShadow(
I.getArgOperand(1));
3388 {I.getArgOperand(0), I.getArgOperand(1),
3389 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3407 void visitMemCpyInst(MemCpyInst &
I) {
3408 getShadow(
I.getArgOperand(1));
3411 {I.getArgOperand(0), I.getArgOperand(1),
3412 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3417 void visitMemSetInst(MemSetInst &
I) {
3421 {I.getArgOperand(0),
3422 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3423 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3427 void visitVAStartInst(VAStartInst &
I) { VAHelper->visitVAStartInst(
I); }
3429 void visitVACopyInst(VACopyInst &
I) { VAHelper->visitVACopyInst(
I); }
3435 bool handleVectorStoreIntrinsic(IntrinsicInst &
I) {
3439 Value *Addr =
I.getArgOperand(0);
3440 Value *Shadow = getShadow(&
I, 1);
3441 Value *ShadowPtr, *OriginPtr;
3445 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3450 insertCheckShadowOf(Addr, &
I);
3453 if (MS.TrackOrigins)
3462 bool handleVectorLoadIntrinsic(IntrinsicInst &
I) {
3466 Value *Addr =
I.getArgOperand(0);
3468 Type *ShadowTy = getShadowTy(&
I);
3469 Value *ShadowPtr =
nullptr, *OriginPtr =
nullptr;
3470 if (PropagateShadow) {
3474 std::tie(ShadowPtr, OriginPtr) =
3475 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment,
false);
3479 setShadow(&
I, getCleanShadow(&
I));
3483 insertCheckShadowOf(Addr, &
I);
3485 if (MS.TrackOrigins) {
3486 if (PropagateShadow)
3487 setOrigin(&
I, IRB.
CreateLoad(MS.OriginTy, OriginPtr));
3489 setOrigin(&
I, getCleanOrigin());
3509 [[maybe_unused]]
bool
3510 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &
I,
3511 unsigned int trailingFlags) {
3512 Type *RetTy =
I.getType();
3516 unsigned NumArgOperands =
I.arg_size();
3517 assert(NumArgOperands >= trailingFlags);
3518 for (
unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3519 Type *Ty =
I.getArgOperand(i)->getType();
3525 ShadowAndOriginCombiner SC(
this, IRB);
3526 for (
unsigned i = 0; i < NumArgOperands; ++i)
3527 SC.Add(
I.getArgOperand(i));
3544 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &
I) {
3545 unsigned NumArgOperands =
I.arg_size();
3546 if (NumArgOperands == 0)
3549 if (NumArgOperands == 2 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3550 I.getArgOperand(1)->getType()->isVectorTy() &&
3551 I.getType()->isVoidTy() && !
I.onlyReadsMemory()) {
3553 return handleVectorStoreIntrinsic(
I);
3556 if (NumArgOperands == 1 &&
I.getArgOperand(0)->getType()->isPointerTy() &&
3557 I.getType()->isVectorTy() &&
I.onlyReadsMemory()) {
3559 return handleVectorLoadIntrinsic(
I);
3562 if (
I.doesNotAccessMemory())
3563 if (maybeHandleSimpleNomemIntrinsic(
I, 0))
3571 bool maybeHandleUnknownIntrinsic(IntrinsicInst &
I) {
3572 if (maybeHandleUnknownIntrinsicUnlogged(
I)) {
3574 dumpInst(
I,
"Heuristic");
3576 LLVM_DEBUG(
dbgs() <<
"UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " <<
I
3583 void handleInvariantGroup(IntrinsicInst &
I) {
3584 setShadow(&
I, getShadow(&
I, 0));
3585 setOrigin(&
I, getOrigin(&
I, 0));
3588 void handleLifetimeStart(IntrinsicInst &
I) {
3593 LifetimeStartList.push_back(std::make_pair(&
I, AI));
3596 void handleBswap(IntrinsicInst &
I) {
3599 Type *OpType =
Op->getType();
3602 setOrigin(&
I, getOrigin(
Op));
3623 void handleCountLeadingTrailingZeros(IntrinsicInst &
I) {
3625 Value *Src =
I.getArgOperand(0);
3626 Value *SrcShadow = getShadow(Src);
3630 I.getType(),
I.getIntrinsicID(), {Src, False});
3632 I.getType(),
I.getIntrinsicID(), {SrcShadow, False});
3635 ConcreteZerosCount, ShadowZerosCount,
"_mscz_cmp_zeros");
3637 Value *NotAllZeroShadow =
3639 Value *OutputShadow =
3640 IRB.
CreateAnd(CompareConcreteZeros, NotAllZeroShadow,
"_mscz_main");
3646 OutputShadow = IRB.
CreateOr(OutputShadow, BoolZeroPoison,
"_mscz_bs");
3649 OutputShadow = IRB.
CreateSExt(OutputShadow, getShadowTy(Src),
"_mscz_os");
3651 setShadow(&
I, OutputShadow);
3652 setOriginForNaryOp(
I);
3661 FixedVectorType *maybeShrinkVectorShadowType(
Value *Src, IntrinsicInst &
I) {
3681 Value *maybeExtendVectorShadowWithZeros(
Value *Shadow, IntrinsicInst &
I) {
3686 Value *FullShadow = getCleanShadow(&
I);
3687 unsigned ShadowNumElems =
3689 unsigned FullShadowNumElems =
3692 assert((ShadowNumElems == FullShadowNumElems) ||
3693 (ShadowNumElems * 2 == FullShadowNumElems));
3695 if (ShadowNumElems == FullShadowNumElems) {
3696 FullShadow = Shadow;
3700 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3725 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &
I,
3726 bool HasRoundingMode) {
3727 if (HasRoundingMode) {
3735 Value *Src =
I.getArgOperand(0);
3736 assert(Src->getType()->isVectorTy());
3740 VectorType *ShadowType = maybeShrinkVectorShadowType(Src,
I);
3743 Value *S0 = getShadow(&
I, 0);
3755 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow,
I);
3757 setShadow(&
I, FullShadow);
3758 setOriginForNaryOp(
I);
3779 void handleSSEVectorConvertIntrinsic(IntrinsicInst &
I,
int NumUsedElements,
3780 bool HasRoundingMode =
false) {
3782 Value *CopyOp, *ConvertOp;
3784 assert((!HasRoundingMode ||
3786 "Invalid rounding mode");
3788 switch (
I.arg_size() - HasRoundingMode) {
3790 CopyOp =
I.getArgOperand(0);
3791 ConvertOp =
I.getArgOperand(1);
3794 ConvertOp =
I.getArgOperand(0);
3808 Value *ConvertShadow = getShadow(ConvertOp);
3809 Value *AggShadow =
nullptr;
3812 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
3813 for (
int i = 1; i < NumUsedElements; ++i) {
3815 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
3816 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
3819 AggShadow = ConvertShadow;
3822 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &
I);
3829 Value *ResultShadow = getShadow(CopyOp);
3831 for (
int i = 0; i < NumUsedElements; ++i) {
3833 ResultShadow, ConstantInt::getNullValue(EltTy),
3836 setShadow(&
I, ResultShadow);
3837 setOrigin(&
I, getOrigin(CopyOp));
3839 setShadow(&
I, getCleanShadow(&
I));
3840 setOrigin(&
I, getCleanOrigin());
3848 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
3851 return CreateShadowCast(IRB, S2,
T,
true);
3859 return CreateShadowCast(IRB, S2,
T,
true);
3876 void handleVectorShiftIntrinsic(IntrinsicInst &
I,
bool Variable) {
3882 Value *S2 = getShadow(&
I, 1);
3884 : Lower64ShadowExtend(IRB, S2, getShadowTy(&
I));
3886 Value *V2 =
I.getOperand(1);
3888 {IRB.CreateBitCast(S1, V1->getType()), V2});
3890 setShadow(&
I, IRB.
CreateOr(Shift, S2Conv));
3891 setOriginForNaryOp(
I);
3896 Type *getMMXVectorTy(
unsigned EltSizeInBits,
3897 unsigned X86_MMXSizeInBits = 64) {
3898 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3899 "Illegal MMX vector element size");
3901 X86_MMXSizeInBits / EltSizeInBits);
3908 case Intrinsic::x86_sse2_packsswb_128:
3909 case Intrinsic::x86_sse2_packuswb_128:
3910 return Intrinsic::x86_sse2_packsswb_128;
3912 case Intrinsic::x86_sse2_packssdw_128:
3913 case Intrinsic::x86_sse41_packusdw:
3914 return Intrinsic::x86_sse2_packssdw_128;
3916 case Intrinsic::x86_avx2_packsswb:
3917 case Intrinsic::x86_avx2_packuswb:
3918 return Intrinsic::x86_avx2_packsswb;
3920 case Intrinsic::x86_avx2_packssdw:
3921 case Intrinsic::x86_avx2_packusdw:
3922 return Intrinsic::x86_avx2_packssdw;
3924 case Intrinsic::x86_mmx_packsswb:
3925 case Intrinsic::x86_mmx_packuswb:
3926 return Intrinsic::x86_mmx_packsswb;
3928 case Intrinsic::x86_mmx_packssdw:
3929 return Intrinsic::x86_mmx_packssdw;
3931 case Intrinsic::x86_avx512_packssdw_512:
3932 case Intrinsic::x86_avx512_packusdw_512:
3933 return Intrinsic::x86_avx512_packssdw_512;
3935 case Intrinsic::x86_avx512_packsswb_512:
3936 case Intrinsic::x86_avx512_packuswb_512:
3937 return Intrinsic::x86_avx512_packsswb_512;
3953 void handleVectorPackIntrinsic(IntrinsicInst &
I,
3954 unsigned MMXEltSizeInBits = 0) {
3958 Value *S2 = getShadow(&
I, 1);
3959 assert(
S1->getType()->isVectorTy());
3965 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) :
S1->
getType();
3966 if (MMXEltSizeInBits) {
3974 if (MMXEltSizeInBits) {
3980 {S1_ext, S2_ext},
nullptr,
3981 "_msprop_vector_pack");
3982 if (MMXEltSizeInBits)
3985 setOriginForNaryOp(
I);
3989 Constant *createDppMask(
unsigned Width,
unsigned Mask) {
3990 SmallVector<Constant *, 4>
R(Width);
4002 const unsigned Width =
4009 Value *DstMaskV = createDppMask(Width, DstMask);
4026 void handleDppIntrinsic(IntrinsicInst &
I) {
4029 Value *S0 = getShadow(&
I, 0);
4033 const unsigned Width =
4035 assert(Width == 2 || Width == 4 || Width == 8);
4038 const unsigned SrcMask =
Mask >> 4;
4039 const unsigned DstMask =
Mask & 0xf;
4042 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
4047 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
4054 setOriginForNaryOp(
I);
4058 C = CreateAppToShadowCast(IRB,
C);
4067 void handleBlendvIntrinsic(IntrinsicInst &
I) {
4072 Value *Sc = getShadow(&
I, 2);
4073 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
4078 C = convertBlendvToSelectMask(IRB,
C);
4079 Sc = convertBlendvToSelectMask(IRB, Sc);
4085 handleSelectLikeInst(
I,
C,
T,
F);
4089 void handleVectorSadIntrinsic(IntrinsicInst &
I,
bool IsMMX =
false) {
4090 const unsigned SignificantBitsPerResultElement = 16;
4092 unsigned ZeroBitsPerResultElement =
4096 auto *Shadow0 = getShadow(&
I, 0);
4097 auto *Shadow1 = getShadow(&
I, 1);
4102 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
4105 setOriginForNaryOp(
I);
4129 void handleVectorDotProductIntrinsic(IntrinsicInst &
I,
4130 unsigned ReductionFactor,
4132 unsigned EltSizeInBits,
4136 [[maybe_unused]] FixedVectorType *
ReturnType =
4141 Value *Va =
nullptr;
4142 Value *Vb =
nullptr;
4143 Value *Sa =
nullptr;
4144 Value *Sb =
nullptr;
4146 assert(
I.arg_size() == 2 ||
I.arg_size() == 3);
4147 if (
I.arg_size() == 2) {
4150 Va =
I.getOperand(0);
4151 Vb =
I.getOperand(1);
4153 Sa = getShadow(&
I, 0);
4154 Sb = getShadow(&
I, 1);
4155 }
else if (
I.arg_size() == 3) {
4157 Va =
I.getOperand(1);
4158 Vb =
I.getOperand(2);
4160 Sa = getShadow(&
I, 1);
4161 Sb = getShadow(&
I, 2);
4178 Sa, getPclmulMask(Width, Lanes ==
kOddLanes));
4180 Sb, getPclmulMask(Width, Lanes ==
kOddLanes));
4190 if (
I.arg_size() == 3) {
4191 [[maybe_unused]]
auto *AccumulatorType =
4193 assert(AccumulatorType == ReturnType);
4196 FixedVectorType *ImplicitReturnType =
4199 if (EltSizeInBits) {
4201 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4213 ReturnType->getNumElements() * ReductionFactor);
4230 VaInt = CreateAppToShadowCast(IRB, Va);
4231 VbInt = CreateAppToShadowCast(IRB, Vb);
4238 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4260 ImplicitReturnType);
4265 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&
I));
4268 if (
I.arg_size() == 3)
4269 OutShadow = IRB.
CreateOr(OutShadow, getShadow(&
I, 0));
4271 setShadow(&
I, OutShadow);
4272 setOriginForNaryOp(
I);
4289 void handleVectorComparePackedIntrinsic(IntrinsicInst &
I,
4290 bool PredicateAsOperand) {
4291 if (PredicateAsOperand) {
4293 assert(
I.paramHasAttr(2, Attribute::ImmArg));
4301 Type *ResTy = getShadowTy(&
I);
4302 auto *Shadow0 = getShadow(&
I, 0);
4303 auto *Shadow1 = getShadow(&
I, 1);
4308 setOriginForNaryOp(
I);
4314 void handleVectorCompareScalarIntrinsic(IntrinsicInst &
I) {
4316 auto *Shadow0 = getShadow(&
I, 0);
4317 auto *Shadow1 = getShadow(&
I, 1);
4319 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&
I));
4321 setOriginForNaryOp(
I);
4330 void handleVectorReduceIntrinsic(IntrinsicInst &
I,
bool AllowShadowCast) {
4335 if (AllowShadowCast)
4336 S = CreateShadowCast(IRB, S, getShadowTy(&
I));
4340 setOriginForNaryOp(
I);
4350 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &
I) {
4354 Value *Shadow0 = getShadow(&
I, 0);
4360 setOriginForNaryOp(
I);
4366 void handleVectorReduceOrIntrinsic(IntrinsicInst &
I) {
4370 Value *OperandShadow = getShadow(&
I, 0);
4372 Value *OperandUnsetOrPoison = IRB.
CreateOr(OperandUnsetBits, OperandShadow);
4380 setOrigin(&
I, getOrigin(&
I, 0));
4386 void handleVectorReduceAndIntrinsic(IntrinsicInst &
I) {
4390 Value *OperandShadow = getShadow(&
I, 0);
4391 Value *OperandSetOrPoison = IRB.
CreateOr(
I.getOperand(0), OperandShadow);
4399 setOrigin(&
I, getOrigin(&
I, 0));
4402 void handleStmxcsr(IntrinsicInst &
I) {
4404 Value *Addr =
I.getArgOperand(0);
4407 getShadowOriginPtr(Addr, IRB, Ty,
Align(1),
true).first;
4412 insertCheckShadowOf(Addr, &
I);
4415 void handleLdmxcsr(IntrinsicInst &
I) {
4420 Value *Addr =
I.getArgOperand(0);
4423 Value *ShadowPtr, *OriginPtr;
4424 std::tie(ShadowPtr, OriginPtr) =
4425 getShadowOriginPtr(Addr, IRB, Ty, Alignment,
false);
4428 insertCheckShadowOf(Addr, &
I);
4431 Value *Origin = MS.TrackOrigins ? IRB.
CreateLoad(MS.OriginTy, OriginPtr)
4433 insertCheckShadow(Shadow, Origin, &
I);
4436 void handleMaskedExpandLoad(IntrinsicInst &
I) {
4438 Value *Ptr =
I.getArgOperand(0);
4439 MaybeAlign
Align =
I.getParamAlign(0);
4441 Value *PassThru =
I.getArgOperand(2);
4444 insertCheckShadowOf(Ptr, &
I);
4445 insertCheckShadowOf(Mask, &
I);
4448 if (!PropagateShadow) {
4449 setShadow(&
I, getCleanShadow(&
I));
4450 setOrigin(&
I, getCleanOrigin());
4454 Type *ShadowTy = getShadowTy(&
I);
4456 auto [ShadowPtr, OriginPtr] =
4457 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
false);
4461 getShadow(PassThru),
"_msmaskedexpload");
4463 setShadow(&
I, Shadow);
4466 setOrigin(&
I, getCleanOrigin());
4469 void handleMaskedCompressStore(IntrinsicInst &
I) {
4472 Value *Ptr =
I.getArgOperand(1);
4473 MaybeAlign
Align =
I.getParamAlign(1);
4477 insertCheckShadowOf(Ptr, &
I);
4478 insertCheckShadowOf(Mask, &
I);
4482 Type *ElementShadowTy =
4484 auto [ShadowPtr, OriginPtrs] =
4485 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align,
true);
4492 void handleMaskedGather(IntrinsicInst &
I) {
4494 Value *Ptrs =
I.getArgOperand(0);
4497 Value *PassThru =
I.getArgOperand(2);
4499 Type *PtrsShadowTy = getShadowTy(Ptrs);
4501 insertCheckShadowOf(Mask, &
I);
4505 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4508 if (!PropagateShadow) {
4509 setShadow(&
I, getCleanShadow(&
I));
4510 setOrigin(&
I, getCleanOrigin());
4514 Type *ShadowTy = getShadowTy(&
I);
4516 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4517 Ptrs, IRB, ElementShadowTy, Alignment,
false);
4521 getShadow(PassThru),
"_msmaskedgather");
4523 setShadow(&
I, Shadow);
4526 setOrigin(&
I, getCleanOrigin());
4529 void handleMaskedScatter(IntrinsicInst &
I) {
4532 Value *Ptrs =
I.getArgOperand(1);
4536 Type *PtrsShadowTy = getShadowTy(Ptrs);
4538 insertCheckShadowOf(Mask, &
I);
4542 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &
I);
4546 Type *ElementShadowTy =
4548 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4549 Ptrs, IRB, ElementShadowTy, Alignment,
true);
4560 void handleMaskedStore(IntrinsicInst &
I) {
4562 Value *
V =
I.getArgOperand(0);
4563 Value *Ptr =
I.getArgOperand(1);
4566 Value *Shadow = getShadow(V);
4569 insertCheckShadowOf(Ptr, &
I);
4570 insertCheckShadowOf(Mask, &
I);
4575 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4576 Ptr, IRB, Shadow->
getType(), Alignment,
true);
4580 if (!MS.TrackOrigins)
4583 auto &
DL =
F.getDataLayout();
4584 paintOrigin(IRB, getOrigin(V), OriginPtr,
4593 void handleMaskedLoad(IntrinsicInst &
I) {
4595 Value *Ptr =
I.getArgOperand(0);
4598 Value *PassThru =
I.getArgOperand(2);
4601 insertCheckShadowOf(Ptr, &
I);
4602 insertCheckShadowOf(Mask, &
I);
4605 if (!PropagateShadow) {
4606 setShadow(&
I, getCleanShadow(&
I));
4607 setOrigin(&
I, getCleanOrigin());
4611 Type *ShadowTy = getShadowTy(&
I);
4612 Value *ShadowPtr, *OriginPtr;
4613 std::tie(ShadowPtr, OriginPtr) =
4614 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment,
false);
4616 getShadow(PassThru),
"_msmaskedld"));
4618 if (!MS.TrackOrigins)
4625 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB,
"_mscmp");
4630 setOrigin(&
I, Origin);
4646 void handleAVXMaskedStore(IntrinsicInst &
I) {
4651 Value *Dst =
I.getArgOperand(0);
4652 assert(Dst->getType()->isPointerTy() &&
"Destination is not a pointer!");
4657 Value *Src =
I.getArgOperand(2);
4662 Value *SrcShadow = getShadow(Src);
4665 insertCheckShadowOf(Dst, &
I);
4666 insertCheckShadowOf(Mask, &
I);
4669 Value *DstShadowPtr;
4670 Value *DstOriginPtr;
4671 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4672 Dst, IRB, SrcShadow->
getType(), Alignment,
true);
4674 SmallVector<Value *, 2> ShadowArgs;
4675 ShadowArgs.
append(1, DstShadowPtr);
4676 ShadowArgs.
append(1, Mask);
4684 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
4687 if (!MS.TrackOrigins)
4691 auto &
DL =
F.getDataLayout();
4692 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4693 DL.getTypeStoreSize(SrcShadow->
getType()),
4712 void handleAVXMaskedLoad(IntrinsicInst &
I) {
4717 Value *Src =
I.getArgOperand(0);
4718 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
4726 insertCheckShadowOf(Mask, &
I);
4729 Type *SrcShadowTy = getShadowTy(Src);
4730 Value *SrcShadowPtr, *SrcOriginPtr;
4731 std::tie(SrcShadowPtr, SrcOriginPtr) =
4732 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment,
false);
4734 SmallVector<Value *, 2> ShadowArgs;
4735 ShadowArgs.
append(1, SrcShadowPtr);
4736 ShadowArgs.
append(1, Mask);
4739 I.getType(),
I.getIntrinsicID(), ShadowArgs);
4745 if (!MS.TrackOrigins)
4752 setOrigin(&
I, PtrSrcOrigin);
4761 assert(isFixedIntVector(Idx));
4762 auto IdxVectorSize =
4770 auto *IdxShadow = getShadow(Idx);
4775 insertCheckShadow(Truncated, getOrigin(Idx),
I);
4780 void handleAVXVpermilvar(IntrinsicInst &
I) {
4782 Value *Shadow = getShadow(&
I, 0);
4783 maskedCheckAVXIndexShadow(IRB,
I.getArgOperand(1), &
I);
4787 Shadow = IRB.
CreateBitCast(Shadow,
I.getArgOperand(0)->getType());
4789 I.getType(),
I.getIntrinsicID(), {Shadow, I.getArgOperand(1)});
4792 setOriginForNaryOp(
I);
4797 void handleAVXVpermi2var(IntrinsicInst &
I) {
4802 [[maybe_unused]]
auto ArgVectorSize =
4805 ->getNumElements() == ArgVectorSize);
4807 ->getNumElements() == ArgVectorSize);
4808 assert(
I.getArgOperand(0)->getType() ==
I.getArgOperand(2)->getType());
4809 assert(
I.getType() ==
I.getArgOperand(0)->getType());
4810 assert(
I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4812 Value *AShadow = getShadow(&
I, 0);
4813 Value *Idx =
I.getArgOperand(1);
4814 Value *BShadow = getShadow(&
I, 2);
4816 maskedCheckAVXIndexShadow(IRB, Idx, &
I);
4820 AShadow = IRB.
CreateBitCast(AShadow,
I.getArgOperand(0)->getType());
4821 BShadow = IRB.
CreateBitCast(BShadow,
I.getArgOperand(2)->getType());
4823 I.getType(),
I.getIntrinsicID(), {AShadow, Idx, BShadow});
4825 setOriginForNaryOp(
I);
4828 [[maybe_unused]]
static bool isFixedIntVectorTy(
const Type *
T) {
4832 [[maybe_unused]]
static bool isFixedFPVectorTy(
const Type *
T) {
4836 [[maybe_unused]]
static bool isFixedIntVector(
const Value *V) {
4837 return isFixedIntVectorTy(
V->getType());
4840 [[maybe_unused]]
static bool isFixedFPVector(
const Value *V) {
4841 return isFixedFPVectorTy(
V->getType());
4863 void handleAVX512VectorConvertFPToInt(IntrinsicInst &
I,
bool LastMask) {
4868 Value *WriteThrough;
4872 WriteThrough =
I.getOperand(2);
4873 Mask =
I.getOperand(3);
4876 WriteThrough =
I.getOperand(1);
4877 Mask =
I.getOperand(2);
4882 assert(isFixedIntVector(WriteThrough));
4884 unsigned ANumElements =
4886 [[maybe_unused]]
unsigned WriteThruNumElements =
4888 assert(ANumElements == WriteThruNumElements ||
4889 ANumElements * 2 == WriteThruNumElements);
4892 unsigned MaskNumElements =
Mask->getType()->getScalarSizeInBits();
4893 assert(ANumElements == MaskNumElements ||
4894 ANumElements * 2 == MaskNumElements);
4896 assert(WriteThruNumElements == MaskNumElements);
4900 insertCheckShadowOf(Mask, &
I);
4910 Value *AShadow = getShadow(
A);
4911 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
4913 if (ANumElements * 2 == MaskNumElements) {
4925 "_ms_mask_bitcast");
4935 getShadowTy(&
I),
"_ms_a_shadow");
4937 Value *WriteThroughShadow = getShadow(WriteThrough);
4939 "_ms_writethru_select");
4941 setShadow(&
I, Shadow);
4942 setOriginForNaryOp(
I);
4945 static SmallVector<int, 8> getPclmulMask(
unsigned Width,
bool OddElements) {
4946 SmallVector<int, 8>
Mask;
4947 for (
unsigned X = OddElements ? 1 : 0;
X < Width;
X += 2) {
4961 void handlePclmulIntrinsic(IntrinsicInst &
I) {
4966 "pclmul 3rd operand must be a constant");
4969 getPclmulMask(Width,
Imm & 0x01));
4971 getPclmulMask(Width,
Imm & 0x10));
4972 ShadowAndOriginCombiner SOC(
this, IRB);
4973 SOC.Add(Shuf0, getOrigin(&
I, 0));
4974 SOC.Add(Shuf1, getOrigin(&
I, 1));
4979 void handleUnarySdSsIntrinsic(IntrinsicInst &
I) {
4984 Value *Second = getShadow(&
I, 1);
4986 SmallVector<int, 16>
Mask;
4987 Mask.push_back(Width);
4988 for (
unsigned i = 1; i < Width; i++)
4992 setShadow(&
I, Shadow);
4993 setOriginForNaryOp(
I);
4996 void handleVtestIntrinsic(IntrinsicInst &
I) {
4998 Value *Shadow0 = getShadow(&
I, 0);
4999 Value *Shadow1 = getShadow(&
I, 1);
5005 setShadow(&
I, Shadow);
5006 setOriginForNaryOp(
I);
5009 void handleBinarySdSsIntrinsic(IntrinsicInst &
I) {
5014 Value *Second = getShadow(&
I, 1);
5017 SmallVector<int, 16>
Mask;
5018 Mask.push_back(Width);
5019 for (
unsigned i = 1; i < Width; i++)
5023 setShadow(&
I, Shadow);
5024 setOriginForNaryOp(
I);
5030 void handleRoundPdPsIntrinsic(IntrinsicInst &
I) {
5031 assert(
I.getArgOperand(0)->getType() ==
I.getType());
5036 ShadowAndOriginCombiner SC(
this, IRB);
5037 SC.Add(
I.getArgOperand(0));
5045 void handleAbsIntrinsic(IntrinsicInst &
I) {
5047 Value *Src =
I.getArgOperand(0);
5048 Value *IsIntMinPoison =
I.getArgOperand(1);
5050 assert(
I.getType()->isIntOrIntVectorTy());
5052 assert(Src->getType() ==
I.getType());
5058 Value *SrcShadow = getShadow(Src);
5062 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5065 Value *PoisonedShadow = getPoisonedShadow(Src);
5066 Value *PoisonedIfIntMinShadow =
5069 IRB.
CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5071 setShadow(&
I, Shadow);
5072 setOrigin(&
I, getOrigin(&
I, 0));
5075 void handleIsFpClass(IntrinsicInst &
I) {
5077 Value *Shadow = getShadow(&
I, 0);
5078 setShadow(&
I, IRB.
CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5079 setOrigin(&
I, getOrigin(&
I, 0));
5082 void handleArithmeticWithOverflow(IntrinsicInst &
I) {
5084 Value *Shadow0 = getShadow(&
I, 0);
5085 Value *Shadow1 = getShadow(&
I, 1);
5088 IRB.
CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5094 setShadow(&
I, Shadow);
5095 setOriginForNaryOp(
I);
5098 void handleModfOrSincos(IntrinsicInst &
I) {
5100 Value *ArgShadow = getShadow(&
I, 0);
5104 setShadow(&
I, Shadow);
5105 setOrigin(&
I, getOrigin(&
I, 0));
5111 Value *Shadow = getShadow(V);
5133 void handleAVX512VectorDownConvert(IntrinsicInst &
I) {
5138 Value *WriteThrough =
I.getOperand(1);
5142 assert(isFixedIntVector(WriteThrough));
5144 unsigned ANumElements =
5146 unsigned OutputNumElements =
5148 assert(ANumElements == OutputNumElements ||
5149 ANumElements * 2 == OutputNumElements);
5159 insertCheckShadowOf(Mask, &
I);
5162 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5163 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5164 assert(
Mask->getType()->getScalarSizeInBits() == ANumElements);
5175 if (ANumElements != OutputNumElements) {
5177 Mask = IRB.
CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5184 Value *AShadow = getShadow(
A);
5188 VectorType *ShadowType = maybeShrinkVectorShadowType(
A,
I);
5198 AShadow = IRB.
CreateTrunc(AShadow, ShadowType,
"_ms_trunc_shadow");
5199 AShadow = maybeExtendVectorShadowWithZeros(AShadow,
I);
5201 Value *WriteThroughShadow = getShadow(WriteThrough);
5204 setShadow(&
I, Shadow);
5205 setOriginForNaryOp(
I);
5239 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &
I,
5240 SmallVector<unsigned, 4> DataIndices,
5241 unsigned WriteThruIndex,
5242 unsigned MaskIndex) {
5245 unsigned NumArgs =
I.arg_size();
5247 assert(WriteThruIndex < NumArgs);
5248 assert(MaskIndex < NumArgs);
5249 assert(WriteThruIndex != MaskIndex);
5250 Value *WriteThru =
I.getOperand(WriteThruIndex);
5252 unsigned OutputNumElements =
5257 bool isData[16] = {
false};
5259 for (
unsigned i : DataIndices) {
5261 assert(i != WriteThruIndex);
5268 [[maybe_unused]]
unsigned ANumElements =
5270 assert(ANumElements == OutputNumElements);
5275 assert(isFixedFPVector(WriteThru));
5277 for (
unsigned i = 0; i < NumArgs; ++i) {
5278 if (!isData[i] && i != WriteThruIndex) {
5281 assert(
I.getOperand(i)->getType()->isIntegerTy());
5282 insertCheckShadowOf(
I.getOperand(i), &
I);
5287 if (
Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5288 Mask = IRB.
CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5289 assert(
Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5296 Value *DataShadow =
nullptr;
5297 for (
unsigned i : DataIndices) {
5300 DataShadow = IRB.
CreateOr(DataShadow, getShadow(
A));
5302 DataShadow = getShadow(
A);
5310 Value *WriteThruShadow = getShadow(WriteThru);
5313 setShadow(&
I, Shadow);
5315 setOriginForNaryOp(
I);
5325 void handleAVX512FPClass(IntrinsicInst &
I) {
5330 Value *Input =
I.getOperand(0);
5331 assert(isFixedFPVector(Input));
5334 Value *Classifiers =
I.getOperand(1);
5338 assert(isFixedIntVectorTy(
I.getType()));
5344 Value *OutputShadow;
5349 OutputShadow = getCleanShadow(OutputType);
5355 OutputShadow = IRB.
CreateICmpNE(getShadow(Input), getCleanShadow(Input));
5357 setShadow(&
I, OutputShadow);
5359 setOriginForNaryOp(
I);
5369 void visitGenericScalarHalfwordInst(IntrinsicInst &
I) {
5375 Value *WriteThrough =
I.getOperand(2);
5382 insertCheckShadowOf(Mask, &
I);
5386 unsigned NumElements =
5388 assert(NumElements == 8);
5389 assert(
A->getType() ==
B->getType());
5391 assert(
Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5394 Value *ALowerShadow = extractLowerShadow(IRB,
A);
5395 Value *BLowerShadow = extractLowerShadow(IRB,
B);
5397 Value *ABLowerShadow = IRB.
CreateOr(ALowerShadow, BLowerShadow);
5399 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5406 Value *AShadow = getShadow(
A);
5407 Value *DstLowerShadow =
5408 IRB.
CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5410 AShadow, DstLowerShadow, ConstantInt::get(IRB.
getInt32Ty(), 0),
5413 setShadow(&
I, DstShadow);
5414 setOriginForNaryOp(
I);
5444 void handleAVXGF2P8Affine(IntrinsicInst &
I) {
5455 ->getScalarSizeInBits() == 8);
5457 assert(
A->getType() ==
X->getType());
5459 assert(
B->getType()->isIntegerTy());
5460 assert(
B->getType()->getScalarSizeInBits() == 8);
5462 assert(
I.getType() ==
A->getType());
5464 Value *AShadow = getShadow(
A);
5465 Value *XShadow = getShadow(
X);
5466 Value *BZeroShadow = getCleanShadow(
B);
5469 I.getType(),
I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5471 {X, AShadow, BZeroShadow});
5473 {XShadow, A, BZeroShadow});
5476 Value *BShadow = getShadow(
B);
5477 Value *BBroadcastShadow = getCleanShadow(AShadow);
5482 for (
unsigned i = 0; i < NumElements; i++)
5486 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5487 setOriginForNaryOp(
I);
5501 void handleNEONVectorLoad(IntrinsicInst &
I,
bool WithLane) {
5502 unsigned int numArgs =
I.arg_size();
5505 assert(
I.getType()->isStructTy());
5515 assert(4 <= numArgs && numArgs <= 6);
5529 for (
unsigned int i = 0; i < numArgs - 2; i++)
5530 ShadowArgs.
push_back(getShadow(
I.getArgOperand(i)));
5533 Value *LaneNumber =
I.getArgOperand(numArgs - 2);
5537 insertCheckShadowOf(LaneNumber, &
I);
5540 Value *Src =
I.getArgOperand(numArgs - 1);
5541 assert(Src->getType()->isPointerTy() &&
"Source is not a pointer!");
5543 Type *SrcShadowTy = getShadowTy(Src);
5544 auto [SrcShadowPtr, SrcOriginPtr] =
5545 getShadowOriginPtr(Src, IRB, SrcShadowTy,
Align(1),
false);
5552 getShadowTy(&
I),
I.getIntrinsicID(), ShadowArgs);
5555 if (!MS.TrackOrigins)
5559 setOrigin(&
I, PtrSrcOrigin);
5576 void handleNEONVectorStoreIntrinsic(IntrinsicInst &
I,
bool useLane) {
5580 int numArgOperands =
I.arg_size();
5583 assert(numArgOperands >= 1);
5584 Value *Addr =
I.getArgOperand(numArgOperands - 1);
5586 int skipTrailingOperands = 1;
5589 insertCheckShadowOf(Addr, &
I);
5593 skipTrailingOperands++;
5594 assert(numArgOperands >=
static_cast<int>(skipTrailingOperands));
5596 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5599 SmallVector<Value *, 8> ShadowArgs;
5601 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5603 Value *Shadow = getShadow(&
I, i);
5604 ShadowArgs.
append(1, Shadow);
5621 (numArgOperands - skipTrailingOperands));
5622 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5626 I.getArgOperand(numArgOperands - skipTrailingOperands));
5628 Value *OutputShadowPtr, *OutputOriginPtr;
5630 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5631 Addr, IRB, OutputShadowTy,
Align(1),
true);
5632 ShadowArgs.
append(1, OutputShadowPtr);
5635 IRB.
getVoidTy(),
I.getIntrinsicID(), ShadowArgs);
5638 if (MS.TrackOrigins) {
5646 OriginCombiner OC(
this, IRB);
5647 for (
int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5648 OC.Add(
I.getArgOperand(i));
5650 const DataLayout &
DL =
F.getDataLayout();
5651 OC.DoneAndStoreOrigin(
DL.getTypeStoreSize(OutputVectorTy),
5684 void handleNEONMatrixMultiply(IntrinsicInst &
I) {
5688 Value *
R =
I.getArgOperand(0);
5689 Value *
A =
I.getArgOperand(1);
5690 Value *
B =
I.getArgOperand(2);
5692 assert(
I.getType() ==
R->getType());
5717 Value *ShadowR = getShadow(&
I, 0);
5718 Value *ShadowA = getShadow(&
I, 1);
5719 Value *ShadowB = getShadow(&
I, 2);
5737 {getCleanShadow(RTy), ShadowA, ShadowB});
5763 {RZeros, ShadowA, ShadowB});
5777 ShadowR = IRB.
CreateICmpNE(ShadowR, getCleanShadow(RTy));
5778 ShadowR = IRB.
CreateOr(ShadowAB, ShadowR);
5780 setShadow(&
I, IRB.
CreateSExt(ShadowR, getShadowTy(RTy)));
5782 setOriginForNaryOp(
I);
5822 void handleIntrinsicByApplyingToShadow(IntrinsicInst &
I,
5824 unsigned int trailingVerbatimArgs,
5825 bool forceIntegerIntrinsic) {
5828 assert(trailingVerbatimArgs <
I.arg_size());
5830 SmallVector<Value *, 8> ShadowArgs;
5832 for (
unsigned int i = 0; i <
I.arg_size() - trailingVerbatimArgs; i++) {
5833 Value *Shadow = getShadow(&
I, i);
5835 if (forceIntegerIntrinsic)
5842 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5844 Value *Arg =
I.getArgOperand(i);
5845 if (forceIntegerIntrinsic)
5850 Value *CombinedShadow;
5851 if (forceIntegerIntrinsic) {
5861 for (
unsigned int i =
I.arg_size() - trailingVerbatimArgs; i <
I.arg_size();
5864 CreateShadowCast(IRB, getShadow(&
I, i), CombinedShadow->
getType());
5865 CombinedShadow = IRB.
CreateOr(Shadow, CombinedShadow,
"_msprop");
5868 setShadow(&
I, CombinedShadow);
5870 setOriginForNaryOp(
I);
5876 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &
I) {
5882 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &
I) {
5883 switch (
I.getIntrinsicID()) {
5884 case Intrinsic::uadd_with_overflow:
5885 case Intrinsic::sadd_with_overflow:
5886 case Intrinsic::usub_with_overflow:
5887 case Intrinsic::ssub_with_overflow:
5888 case Intrinsic::umul_with_overflow:
5889 case Intrinsic::smul_with_overflow:
5890 handleArithmeticWithOverflow(
I);
5892 case Intrinsic::modf:
5893 case Intrinsic::sincos:
5894 case Intrinsic::sincospi:
5895 handleModfOrSincos(
I);
5897 case Intrinsic::abs:
5898 handleAbsIntrinsic(
I);
5900 case Intrinsic::bitreverse:
5901 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
5905 case Intrinsic::is_fpclass:
5908 case Intrinsic::lifetime_start:
5909 handleLifetimeStart(
I);
5911 case Intrinsic::launder_invariant_group:
5912 handleInvariantGroup(
I);
5914 case Intrinsic::bswap:
5917 case Intrinsic::ctlz:
5918 case Intrinsic::cttz:
5919 handleCountLeadingTrailingZeros(
I);
5921 case Intrinsic::masked_compressstore:
5922 handleMaskedCompressStore(
I);
5924 case Intrinsic::masked_expandload:
5925 handleMaskedExpandLoad(
I);
5927 case Intrinsic::masked_gather:
5928 handleMaskedGather(
I);
5930 case Intrinsic::masked_scatter:
5931 handleMaskedScatter(
I);
5933 case Intrinsic::masked_store:
5934 handleMaskedStore(
I);
5936 case Intrinsic::masked_load:
5937 handleMaskedLoad(
I);
5939 case Intrinsic::vector_reduce_and:
5940 handleVectorReduceAndIntrinsic(
I);
5942 case Intrinsic::vector_reduce_or:
5943 handleVectorReduceOrIntrinsic(
I);
5946 case Intrinsic::vector_reduce_add:
5947 case Intrinsic::vector_reduce_xor:
5948 case Intrinsic::vector_reduce_mul:
5951 case Intrinsic::vector_reduce_smax:
5952 case Intrinsic::vector_reduce_smin:
5953 case Intrinsic::vector_reduce_umax:
5954 case Intrinsic::vector_reduce_umin:
5957 case Intrinsic::vector_reduce_fmax:
5958 case Intrinsic::vector_reduce_fmin:
5959 handleVectorReduceIntrinsic(
I,
false);
5962 case Intrinsic::vector_reduce_fadd:
5963 case Intrinsic::vector_reduce_fmul:
5964 handleVectorReduceWithStarterIntrinsic(
I);
5967 case Intrinsic::scmp:
5968 case Intrinsic::ucmp: {
5973 case Intrinsic::fshl:
5974 case Intrinsic::fshr:
5975 handleFunnelShift(
I);
5978 case Intrinsic::pdep:
5979 case Intrinsic::pext:
5980 handleGenericBitManipulation(
I);
5983 case Intrinsic::is_constant:
5985 setShadow(&
I, getCleanShadow(&
I));
5986 setOrigin(&
I, getCleanOrigin());
5993 case Intrinsic::fptosi_sat:
5994 case Intrinsic::fptoui_sat:
5995 handleGenericVectorConvertIntrinsic(
I,
false);
6005 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &
I) {
6006 switch (
I.getIntrinsicID()) {
6007 case Intrinsic::x86_sse_stmxcsr:
6010 case Intrinsic::x86_sse_ldmxcsr:
6017 case Intrinsic::x86_avx512_vcvtsd2usi64:
6018 case Intrinsic::x86_avx512_vcvtsd2usi32:
6019 case Intrinsic::x86_avx512_vcvtss2usi64:
6020 case Intrinsic::x86_avx512_vcvtss2usi32:
6021 case Intrinsic::x86_avx512_cvttss2usi64:
6022 case Intrinsic::x86_avx512_cvttss2usi:
6023 case Intrinsic::x86_avx512_cvttsd2usi64:
6024 case Intrinsic::x86_avx512_cvttsd2usi:
6025 case Intrinsic::x86_avx512_cvtusi2ss:
6026 case Intrinsic::x86_avx512_cvtusi642sd:
6027 case Intrinsic::x86_avx512_cvtusi642ss:
6028 handleSSEVectorConvertIntrinsic(
I, 1,
true);
6030 case Intrinsic::x86_sse2_cvtsd2si64:
6031 case Intrinsic::x86_sse2_cvtsd2si:
6032 case Intrinsic::x86_sse2_cvtsd2ss:
6033 case Intrinsic::x86_sse2_cvttsd2si64:
6034 case Intrinsic::x86_sse2_cvttsd2si:
6035 case Intrinsic::x86_sse_cvtss2si64:
6036 case Intrinsic::x86_sse_cvtss2si:
6037 case Intrinsic::x86_sse_cvttss2si64:
6038 case Intrinsic::x86_sse_cvttss2si:
6039 handleSSEVectorConvertIntrinsic(
I, 1);
6041 case Intrinsic::x86_sse_cvtps2pi:
6042 case Intrinsic::x86_sse_cvttps2pi:
6043 handleSSEVectorConvertIntrinsic(
I, 2);
6051 case Intrinsic::x86_vcvtps2ph_128:
6052 case Intrinsic::x86_vcvtps2ph_256: {
6053 handleSSEVectorConvertIntrinsicByProp(
I,
true);
6062 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
6063 handleAVX512VectorConvertFPToInt(
I,
false);
6068 case Intrinsic::x86_sse2_cvtpd2ps:
6069 case Intrinsic::x86_sse2_cvtps2dq:
6070 case Intrinsic::x86_sse2_cvtpd2dq:
6071 case Intrinsic::x86_sse2_cvttps2dq:
6072 case Intrinsic::x86_sse2_cvttpd2dq:
6073 case Intrinsic::x86_avx_cvt_pd2_ps_256:
6074 case Intrinsic::x86_avx_cvt_ps2dq_256:
6075 case Intrinsic::x86_avx_cvt_pd2dq_256:
6076 case Intrinsic::x86_avx_cvtt_ps2dq_256:
6077 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
6078 handleSSEVectorConvertIntrinsicByProp(
I,
false);
6089 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
6090 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
6091 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
6092 handleAVX512VectorConvertFPToInt(
I,
true);
6096 case Intrinsic::x86_avx512_psll_w_512:
6097 case Intrinsic::x86_avx512_psll_d_512:
6098 case Intrinsic::x86_avx512_psll_q_512:
6099 case Intrinsic::x86_avx512_pslli_w_512:
6100 case Intrinsic::x86_avx512_pslli_d_512:
6101 case Intrinsic::x86_avx512_pslli_q_512:
6102 case Intrinsic::x86_avx512_psrl_w_512:
6103 case Intrinsic::x86_avx512_psrl_d_512:
6104 case Intrinsic::x86_avx512_psrl_q_512:
6105 case Intrinsic::x86_avx512_psra_w_512:
6106 case Intrinsic::x86_avx512_psra_d_512:
6107 case Intrinsic::x86_avx512_psra_q_512:
6108 case Intrinsic::x86_avx512_psrli_w_512:
6109 case Intrinsic::x86_avx512_psrli_d_512:
6110 case Intrinsic::x86_avx512_psrli_q_512:
6111 case Intrinsic::x86_avx512_psrai_w_512:
6112 case Intrinsic::x86_avx512_psrai_d_512:
6113 case Intrinsic::x86_avx512_psrai_q_512:
6114 case Intrinsic::x86_avx512_psra_q_256:
6115 case Intrinsic::x86_avx512_psra_q_128:
6116 case Intrinsic::x86_avx512_psrai_q_256:
6117 case Intrinsic::x86_avx512_psrai_q_128:
6118 case Intrinsic::x86_avx2_psll_w:
6119 case Intrinsic::x86_avx2_psll_d:
6120 case Intrinsic::x86_avx2_psll_q:
6121 case Intrinsic::x86_avx2_pslli_w:
6122 case Intrinsic::x86_avx2_pslli_d:
6123 case Intrinsic::x86_avx2_pslli_q:
6124 case Intrinsic::x86_avx2_psrl_w:
6125 case Intrinsic::x86_avx2_psrl_d:
6126 case Intrinsic::x86_avx2_psrl_q:
6127 case Intrinsic::x86_avx2_psra_w:
6128 case Intrinsic::x86_avx2_psra_d:
6129 case Intrinsic::x86_avx2_psrli_w:
6130 case Intrinsic::x86_avx2_psrli_d:
6131 case Intrinsic::x86_avx2_psrli_q:
6132 case Intrinsic::x86_avx2_psrai_w:
6133 case Intrinsic::x86_avx2_psrai_d:
6134 case Intrinsic::x86_sse2_psll_w:
6135 case Intrinsic::x86_sse2_psll_d:
6136 case Intrinsic::x86_sse2_psll_q:
6137 case Intrinsic::x86_sse2_pslli_w:
6138 case Intrinsic::x86_sse2_pslli_d:
6139 case Intrinsic::x86_sse2_pslli_q:
6140 case Intrinsic::x86_sse2_psrl_w:
6141 case Intrinsic::x86_sse2_psrl_d:
6142 case Intrinsic::x86_sse2_psrl_q:
6143 case Intrinsic::x86_sse2_psra_w:
6144 case Intrinsic::x86_sse2_psra_d:
6145 case Intrinsic::x86_sse2_psrli_w:
6146 case Intrinsic::x86_sse2_psrli_d:
6147 case Intrinsic::x86_sse2_psrli_q:
6148 case Intrinsic::x86_sse2_psrai_w:
6149 case Intrinsic::x86_sse2_psrai_d:
6150 case Intrinsic::x86_mmx_psll_w:
6151 case Intrinsic::x86_mmx_psll_d:
6152 case Intrinsic::x86_mmx_psll_q:
6153 case Intrinsic::x86_mmx_pslli_w:
6154 case Intrinsic::x86_mmx_pslli_d:
6155 case Intrinsic::x86_mmx_pslli_q:
6156 case Intrinsic::x86_mmx_psrl_w:
6157 case Intrinsic::x86_mmx_psrl_d:
6158 case Intrinsic::x86_mmx_psrl_q:
6159 case Intrinsic::x86_mmx_psra_w:
6160 case Intrinsic::x86_mmx_psra_d:
6161 case Intrinsic::x86_mmx_psrli_w:
6162 case Intrinsic::x86_mmx_psrli_d:
6163 case Intrinsic::x86_mmx_psrli_q:
6164 case Intrinsic::x86_mmx_psrai_w:
6165 case Intrinsic::x86_mmx_psrai_d:
6166 handleVectorShiftIntrinsic(
I,
false);
6168 case Intrinsic::x86_avx2_psllv_d:
6169 case Intrinsic::x86_avx2_psllv_d_256:
6170 case Intrinsic::x86_avx512_psllv_d_512:
6171 case Intrinsic::x86_avx2_psllv_q:
6172 case Intrinsic::x86_avx2_psllv_q_256:
6173 case Intrinsic::x86_avx512_psllv_q_512:
6174 case Intrinsic::x86_avx2_psrlv_d:
6175 case Intrinsic::x86_avx2_psrlv_d_256:
6176 case Intrinsic::x86_avx512_psrlv_d_512:
6177 case Intrinsic::x86_avx2_psrlv_q:
6178 case Intrinsic::x86_avx2_psrlv_q_256:
6179 case Intrinsic::x86_avx512_psrlv_q_512:
6180 case Intrinsic::x86_avx2_psrav_d:
6181 case Intrinsic::x86_avx2_psrav_d_256:
6182 case Intrinsic::x86_avx512_psrav_d_512:
6183 case Intrinsic::x86_avx512_psrav_q_128:
6184 case Intrinsic::x86_avx512_psrav_q_256:
6185 case Intrinsic::x86_avx512_psrav_q_512:
6186 handleVectorShiftIntrinsic(
I,
true);
6190 case Intrinsic::x86_sse2_packsswb_128:
6191 case Intrinsic::x86_sse2_packssdw_128:
6192 case Intrinsic::x86_sse2_packuswb_128:
6193 case Intrinsic::x86_sse41_packusdw:
6194 case Intrinsic::x86_avx2_packsswb:
6195 case Intrinsic::x86_avx2_packssdw:
6196 case Intrinsic::x86_avx2_packuswb:
6197 case Intrinsic::x86_avx2_packusdw:
6203 case Intrinsic::x86_avx512_packsswb_512:
6204 case Intrinsic::x86_avx512_packssdw_512:
6205 case Intrinsic::x86_avx512_packuswb_512:
6206 case Intrinsic::x86_avx512_packusdw_512:
6207 handleVectorPackIntrinsic(
I);
6210 case Intrinsic::x86_sse41_pblendvb:
6211 case Intrinsic::x86_sse41_blendvpd:
6212 case Intrinsic::x86_sse41_blendvps:
6213 case Intrinsic::x86_avx_blendv_pd_256:
6214 case Intrinsic::x86_avx_blendv_ps_256:
6215 case Intrinsic::x86_avx2_pblendvb:
6216 handleBlendvIntrinsic(
I);
6219 case Intrinsic::x86_avx_dp_ps_256:
6220 case Intrinsic::x86_sse41_dppd:
6221 case Intrinsic::x86_sse41_dpps:
6222 handleDppIntrinsic(
I);
6225 case Intrinsic::x86_mmx_packsswb:
6226 case Intrinsic::x86_mmx_packuswb:
6227 handleVectorPackIntrinsic(
I, 16);
6230 case Intrinsic::x86_mmx_packssdw:
6231 handleVectorPackIntrinsic(
I, 32);
6234 case Intrinsic::x86_mmx_psad_bw:
6235 handleVectorSadIntrinsic(
I,
true);
6237 case Intrinsic::x86_sse2_psad_bw:
6238 case Intrinsic::x86_avx2_psad_bw:
6239 handleVectorSadIntrinsic(
I);
6265 case Intrinsic::x86_sse2_pmadd_wd:
6266 case Intrinsic::x86_avx2_pmadd_wd:
6267 case Intrinsic::x86_avx512_pmaddw_d_512:
6268 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6269 case Intrinsic::x86_avx2_pmadd_ub_sw:
6270 case Intrinsic::x86_avx512_pmaddubs_w_512:
6271 handleVectorDotProductIntrinsic(
I, 2,
6278 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6279 handleVectorDotProductIntrinsic(
I, 2,
6286 case Intrinsic::x86_mmx_pmadd_wd:
6287 handleVectorDotProductIntrinsic(
I, 2,
6296 case Intrinsic::aarch64_neon_bfmlalt:
6297 handleVectorDotProductIntrinsic(
I, 2,
6305 case Intrinsic::aarch64_neon_bfmlalb:
6306 handleVectorDotProductIntrinsic(
I, 2,
6404 case Intrinsic::x86_avx512_vpdpbusd_128:
6405 case Intrinsic::x86_avx512_vpdpbusd_256:
6406 case Intrinsic::x86_avx512_vpdpbusd_512:
6407 case Intrinsic::x86_avx512_vpdpbusds_128:
6408 case Intrinsic::x86_avx512_vpdpbusds_256:
6409 case Intrinsic::x86_avx512_vpdpbusds_512:
6410 case Intrinsic::x86_avx2_vpdpbssd_128:
6411 case Intrinsic::x86_avx2_vpdpbssd_256:
6412 case Intrinsic::x86_avx10_vpdpbssd_512:
6413 case Intrinsic::x86_avx2_vpdpbssds_128:
6414 case Intrinsic::x86_avx2_vpdpbssds_256:
6415 case Intrinsic::x86_avx10_vpdpbssds_512:
6416 case Intrinsic::x86_avx2_vpdpbsud_128:
6417 case Intrinsic::x86_avx2_vpdpbsud_256:
6418 case Intrinsic::x86_avx10_vpdpbsud_512:
6419 case Intrinsic::x86_avx2_vpdpbsuds_128:
6420 case Intrinsic::x86_avx2_vpdpbsuds_256:
6421 case Intrinsic::x86_avx10_vpdpbsuds_512:
6422 case Intrinsic::x86_avx2_vpdpbuud_128:
6423 case Intrinsic::x86_avx2_vpdpbuud_256:
6424 case Intrinsic::x86_avx10_vpdpbuud_512:
6425 case Intrinsic::x86_avx2_vpdpbuuds_128:
6426 case Intrinsic::x86_avx2_vpdpbuuds_256:
6427 case Intrinsic::x86_avx10_vpdpbuuds_512:
6428 handleVectorDotProductIntrinsic(
I, 4,
6526 case Intrinsic::x86_avx512_vpdpwssd_128:
6527 case Intrinsic::x86_avx512_vpdpwssd_256:
6528 case Intrinsic::x86_avx512_vpdpwssd_512:
6529 case Intrinsic::x86_avx512_vpdpwssds_128:
6530 case Intrinsic::x86_avx512_vpdpwssds_256:
6531 case Intrinsic::x86_avx512_vpdpwssds_512:
6532 case Intrinsic::x86_avx2_vpdpwsud_128:
6533 case Intrinsic::x86_avx2_vpdpwsud_256:
6534 case Intrinsic::x86_avx10_vpdpwsud_512:
6535 case Intrinsic::x86_avx2_vpdpwsuds_128:
6536 case Intrinsic::x86_avx2_vpdpwsuds_256:
6537 case Intrinsic::x86_avx10_vpdpwsuds_512:
6538 case Intrinsic::x86_avx2_vpdpwusd_128:
6539 case Intrinsic::x86_avx2_vpdpwusd_256:
6540 case Intrinsic::x86_avx10_vpdpwusd_512:
6541 case Intrinsic::x86_avx2_vpdpwusds_128:
6542 case Intrinsic::x86_avx2_vpdpwusds_256:
6543 case Intrinsic::x86_avx10_vpdpwusds_512:
6544 case Intrinsic::x86_avx2_vpdpwuud_128:
6545 case Intrinsic::x86_avx2_vpdpwuud_256:
6546 case Intrinsic::x86_avx10_vpdpwuud_512:
6547 case Intrinsic::x86_avx2_vpdpwuuds_128:
6548 case Intrinsic::x86_avx2_vpdpwuuds_256:
6549 case Intrinsic::x86_avx10_vpdpwuuds_512:
6550 handleVectorDotProductIntrinsic(
I, 2,
6564 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6565 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6566 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6567 handleVectorDotProductIntrinsic(
I, 2,
6573 case Intrinsic::x86_sse_cmp_ss:
6574 case Intrinsic::x86_sse2_cmp_sd:
6575 case Intrinsic::x86_sse_comieq_ss:
6576 case Intrinsic::x86_sse_comilt_ss:
6577 case Intrinsic::x86_sse_comile_ss:
6578 case Intrinsic::x86_sse_comigt_ss:
6579 case Intrinsic::x86_sse_comige_ss:
6580 case Intrinsic::x86_sse_comineq_ss:
6581 case Intrinsic::x86_sse_ucomieq_ss:
6582 case Intrinsic::x86_sse_ucomilt_ss:
6583 case Intrinsic::x86_sse_ucomile_ss:
6584 case Intrinsic::x86_sse_ucomigt_ss:
6585 case Intrinsic::x86_sse_ucomige_ss:
6586 case Intrinsic::x86_sse_ucomineq_ss:
6587 case Intrinsic::x86_sse2_comieq_sd:
6588 case Intrinsic::x86_sse2_comilt_sd:
6589 case Intrinsic::x86_sse2_comile_sd:
6590 case Intrinsic::x86_sse2_comigt_sd:
6591 case Intrinsic::x86_sse2_comige_sd:
6592 case Intrinsic::x86_sse2_comineq_sd:
6593 case Intrinsic::x86_sse2_ucomieq_sd:
6594 case Intrinsic::x86_sse2_ucomilt_sd:
6595 case Intrinsic::x86_sse2_ucomile_sd:
6596 case Intrinsic::x86_sse2_ucomigt_sd:
6597 case Intrinsic::x86_sse2_ucomige_sd:
6598 case Intrinsic::x86_sse2_ucomineq_sd:
6599 handleVectorCompareScalarIntrinsic(
I);
6602 case Intrinsic::x86_avx_cmp_pd_256:
6603 case Intrinsic::x86_avx_cmp_ps_256:
6604 case Intrinsic::x86_sse2_cmp_pd:
6605 case Intrinsic::x86_sse_cmp_ps:
6606 handleVectorComparePackedIntrinsic(
I,
true);
6609 case Intrinsic::x86_bmi_bextr_32:
6610 case Intrinsic::x86_bmi_bextr_64:
6611 case Intrinsic::x86_bmi_bzhi_32:
6612 case Intrinsic::x86_bmi_bzhi_64:
6613 handleGenericBitManipulation(
I);
6616 case Intrinsic::x86_pclmulqdq:
6617 case Intrinsic::x86_pclmulqdq_256:
6618 case Intrinsic::x86_pclmulqdq_512:
6619 handlePclmulIntrinsic(
I);
6622 case Intrinsic::x86_avx_round_pd_256:
6623 case Intrinsic::x86_avx_round_ps_256:
6624 case Intrinsic::x86_sse41_round_pd:
6625 case Intrinsic::x86_sse41_round_ps:
6626 handleRoundPdPsIntrinsic(
I);
6629 case Intrinsic::x86_sse41_round_sd:
6630 case Intrinsic::x86_sse41_round_ss:
6631 handleUnarySdSsIntrinsic(
I);
6634 case Intrinsic::x86_sse2_max_sd:
6635 case Intrinsic::x86_sse_max_ss:
6636 case Intrinsic::x86_sse2_min_sd:
6637 case Intrinsic::x86_sse_min_ss:
6638 handleBinarySdSsIntrinsic(
I);
6641 case Intrinsic::x86_avx_vtestc_pd:
6642 case Intrinsic::x86_avx_vtestc_pd_256:
6643 case Intrinsic::x86_avx_vtestc_ps:
6644 case Intrinsic::x86_avx_vtestc_ps_256:
6645 case Intrinsic::x86_avx_vtestnzc_pd:
6646 case Intrinsic::x86_avx_vtestnzc_pd_256:
6647 case Intrinsic::x86_avx_vtestnzc_ps:
6648 case Intrinsic::x86_avx_vtestnzc_ps_256:
6649 case Intrinsic::x86_avx_vtestz_pd:
6650 case Intrinsic::x86_avx_vtestz_pd_256:
6651 case Intrinsic::x86_avx_vtestz_ps:
6652 case Intrinsic::x86_avx_vtestz_ps_256:
6653 case Intrinsic::x86_avx_ptestc_256:
6654 case Intrinsic::x86_avx_ptestnzc_256:
6655 case Intrinsic::x86_avx_ptestz_256:
6656 case Intrinsic::x86_sse41_ptestc:
6657 case Intrinsic::x86_sse41_ptestnzc:
6658 case Intrinsic::x86_sse41_ptestz:
6659 handleVtestIntrinsic(
I);
6663 case Intrinsic::x86_ssse3_phadd_w:
6664 case Intrinsic::x86_ssse3_phadd_w_128:
6665 case Intrinsic::x86_ssse3_phsub_w:
6666 case Intrinsic::x86_ssse3_phsub_w_128:
6667 handlePairwiseShadowOrIntrinsic(
I, 1,
6671 case Intrinsic::x86_avx2_phadd_w:
6672 case Intrinsic::x86_avx2_phsub_w:
6673 handlePairwiseShadowOrIntrinsic(
I, 2,
6678 case Intrinsic::x86_ssse3_phadd_d:
6679 case Intrinsic::x86_ssse3_phadd_d_128:
6680 case Intrinsic::x86_ssse3_phsub_d:
6681 case Intrinsic::x86_ssse3_phsub_d_128:
6682 handlePairwiseShadowOrIntrinsic(
I, 1,
6686 case Intrinsic::x86_avx2_phadd_d:
6687 case Intrinsic::x86_avx2_phsub_d:
6688 handlePairwiseShadowOrIntrinsic(
I, 2,
6693 case Intrinsic::x86_ssse3_phadd_sw:
6694 case Intrinsic::x86_ssse3_phadd_sw_128:
6695 case Intrinsic::x86_ssse3_phsub_sw:
6696 case Intrinsic::x86_ssse3_phsub_sw_128:
6697 handlePairwiseShadowOrIntrinsic(
I, 1,
6701 case Intrinsic::x86_avx2_phadd_sw:
6702 case Intrinsic::x86_avx2_phsub_sw:
6703 handlePairwiseShadowOrIntrinsic(
I, 2,
6708 case Intrinsic::x86_sse3_hadd_ps:
6709 case Intrinsic::x86_sse3_hadd_pd:
6710 case Intrinsic::x86_sse3_hsub_ps:
6711 case Intrinsic::x86_sse3_hsub_pd:
6712 handlePairwiseShadowOrIntrinsic(
I, 1);
6715 case Intrinsic::x86_avx_hadd_pd_256:
6716 case Intrinsic::x86_avx_hadd_ps_256:
6717 case Intrinsic::x86_avx_hsub_pd_256:
6718 case Intrinsic::x86_avx_hsub_ps_256:
6719 handlePairwiseShadowOrIntrinsic(
I, 2);
6722 case Intrinsic::x86_avx_maskstore_ps:
6723 case Intrinsic::x86_avx_maskstore_pd:
6724 case Intrinsic::x86_avx_maskstore_ps_256:
6725 case Intrinsic::x86_avx_maskstore_pd_256:
6726 case Intrinsic::x86_avx2_maskstore_d:
6727 case Intrinsic::x86_avx2_maskstore_q:
6728 case Intrinsic::x86_avx2_maskstore_d_256:
6729 case Intrinsic::x86_avx2_maskstore_q_256: {
6730 handleAVXMaskedStore(
I);
6734 case Intrinsic::x86_avx_maskload_ps:
6735 case Intrinsic::x86_avx_maskload_pd:
6736 case Intrinsic::x86_avx_maskload_ps_256:
6737 case Intrinsic::x86_avx_maskload_pd_256:
6738 case Intrinsic::x86_avx2_maskload_d:
6739 case Intrinsic::x86_avx2_maskload_q:
6740 case Intrinsic::x86_avx2_maskload_d_256:
6741 case Intrinsic::x86_avx2_maskload_q_256: {
6742 handleAVXMaskedLoad(
I);
6747 case Intrinsic::x86_avx512fp16_add_ph_512:
6748 case Intrinsic::x86_avx512fp16_sub_ph_512:
6749 case Intrinsic::x86_avx512fp16_mul_ph_512:
6750 case Intrinsic::x86_avx512fp16_div_ph_512:
6751 case Intrinsic::x86_avx512fp16_max_ph_512:
6752 case Intrinsic::x86_avx512fp16_min_ph_512:
6753 case Intrinsic::x86_avx512_min_ps_512:
6754 case Intrinsic::x86_avx512_min_pd_512:
6755 case Intrinsic::x86_avx512_max_ps_512:
6756 case Intrinsic::x86_avx512_max_pd_512: {
6761 [[maybe_unused]]
bool Success =
6762 maybeHandleSimpleNomemIntrinsic(
I, 1);
6767 case Intrinsic::x86_avx_vpermilvar_pd:
6768 case Intrinsic::x86_avx_vpermilvar_pd_256:
6769 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6770 case Intrinsic::x86_avx_vpermilvar_ps:
6771 case Intrinsic::x86_avx_vpermilvar_ps_256:
6772 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6773 handleAVXVpermilvar(
I);
6777 case Intrinsic::x86_avx512_vpermi2var_d_128:
6778 case Intrinsic::x86_avx512_vpermi2var_d_256:
6779 case Intrinsic::x86_avx512_vpermi2var_d_512:
6780 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6781 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6782 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6783 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6784 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6785 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6786 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6787 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6788 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6789 case Intrinsic::x86_avx512_vpermi2var_q_128:
6790 case Intrinsic::x86_avx512_vpermi2var_q_256:
6791 case Intrinsic::x86_avx512_vpermi2var_q_512:
6792 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6793 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6794 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6795 handleAVXVpermi2var(
I);
6809 case Intrinsic::x86_avx2_pshuf_b:
6810 case Intrinsic::x86_sse_pshuf_w:
6811 case Intrinsic::x86_ssse3_pshuf_b_128:
6812 case Intrinsic::x86_ssse3_pshuf_b:
6813 case Intrinsic::x86_avx512_pshuf_b_512:
6814 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6821 case Intrinsic::x86_avx512_mask_pmov_dw_128:
6822 case Intrinsic::x86_avx512_mask_pmov_db_128:
6823 case Intrinsic::x86_avx512_mask_pmov_qb_128:
6824 case Intrinsic::x86_avx512_mask_pmov_qw_128:
6825 case Intrinsic::x86_avx512_mask_pmov_qd_128:
6826 case Intrinsic::x86_avx512_mask_pmov_wb_128:
6827 case Intrinsic::x86_avx512_mask_pmov_dw_256:
6828 case Intrinsic::x86_avx512_mask_pmov_db_256:
6829 case Intrinsic::x86_avx512_mask_pmov_qb_256:
6830 case Intrinsic::x86_avx512_mask_pmov_qw_256:
6831 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6832 case Intrinsic::x86_avx512_mask_pmov_db_512:
6833 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6834 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6837 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
6846 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6847 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6848 handleIntrinsicByApplyingToShadow(
6849 I, Intrinsic::x86_avx512_mask_pmov_dw_512,
6854 case Intrinsic::x86_avx512_mask_pmovs_dw_256:
6855 case Intrinsic::x86_avx512_mask_pmovus_dw_256:
6856 handleIntrinsicByApplyingToShadow(
6857 I, Intrinsic::x86_avx512_mask_pmov_dw_256,
6861 case Intrinsic::x86_avx512_mask_pmovs_dw_128:
6862 case Intrinsic::x86_avx512_mask_pmovus_dw_128:
6863 handleIntrinsicByApplyingToShadow(
6864 I, Intrinsic::x86_avx512_mask_pmov_dw_128,
6868 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6869 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6870 handleIntrinsicByApplyingToShadow(
6871 I, Intrinsic::x86_avx512_mask_pmov_db_512,
6876 case Intrinsic::x86_avx512_mask_pmovs_db_256:
6877 case Intrinsic::x86_avx512_mask_pmovus_db_256:
6878 handleIntrinsicByApplyingToShadow(
6879 I, Intrinsic::x86_avx512_mask_pmov_db_256,
6883 case Intrinsic::x86_avx512_mask_pmovs_db_128:
6884 case Intrinsic::x86_avx512_mask_pmovus_db_128:
6885 handleIntrinsicByApplyingToShadow(
6886 I, Intrinsic::x86_avx512_mask_pmov_db_128,
6890 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
6891 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
6892 handleIntrinsicByApplyingToShadow(
6893 I, Intrinsic::x86_avx512_mask_pmov_qb_512,
6898 case Intrinsic::x86_avx512_mask_pmovs_qb_256:
6899 case Intrinsic::x86_avx512_mask_pmovus_qb_256:
6900 handleIntrinsicByApplyingToShadow(
6901 I, Intrinsic::x86_avx512_mask_pmov_qb_256,
6905 case Intrinsic::x86_avx512_mask_pmovs_qb_128:
6906 case Intrinsic::x86_avx512_mask_pmovus_qb_128:
6907 handleIntrinsicByApplyingToShadow(
6908 I, Intrinsic::x86_avx512_mask_pmov_qb_128,
6912 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
6913 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
6914 handleIntrinsicByApplyingToShadow(
6915 I, Intrinsic::x86_avx512_mask_pmov_qw_512,
6920 case Intrinsic::x86_avx512_mask_pmovs_qw_256:
6921 case Intrinsic::x86_avx512_mask_pmovus_qw_256:
6922 handleIntrinsicByApplyingToShadow(
6923 I, Intrinsic::x86_avx512_mask_pmov_qw_256,
6927 case Intrinsic::x86_avx512_mask_pmovs_qw_128:
6928 case Intrinsic::x86_avx512_mask_pmovus_qw_128:
6929 handleIntrinsicByApplyingToShadow(
6930 I, Intrinsic::x86_avx512_mask_pmov_qw_128,
6934 case Intrinsic::x86_avx512_mask_pmovs_qd_128:
6935 case Intrinsic::x86_avx512_mask_pmovus_qd_128:
6936 handleIntrinsicByApplyingToShadow(
6937 I, Intrinsic::x86_avx512_mask_pmov_qd_128,
6941 case Intrinsic::x86_avx512_mask_pmovs_wb_128:
6942 case Intrinsic::x86_avx512_mask_pmovus_wb_128:
6943 handleIntrinsicByApplyingToShadow(
6944 I, Intrinsic::x86_avx512_mask_pmov_wb_128,
6948 case Intrinsic::x86_avx512_mask_pmovs_qd_256:
6949 case Intrinsic::x86_avx512_mask_pmovus_qd_256:
6950 case Intrinsic::x86_avx512_mask_pmovs_wb_256:
6951 case Intrinsic::x86_avx512_mask_pmovus_wb_256:
6952 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
6953 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
6954 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
6955 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
6959 handleAVX512VectorDownConvert(
I);
6970 case Intrinsic::x86_avx512_mask_compress:
6971 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7012 case Intrinsic::x86_avx512_rsqrt14_ps_512:
7013 case Intrinsic::x86_avx512_rsqrt14_ps_256:
7014 case Intrinsic::x86_avx512_rsqrt14_ps_128:
7015 case Intrinsic::x86_avx512_rsqrt14_pd_512:
7016 case Intrinsic::x86_avx512_rsqrt14_pd_256:
7017 case Intrinsic::x86_avx512_rsqrt14_pd_128:
7018 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
7019 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
7020 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
7021 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
7022 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
7023 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
7024 handleAVX512VectorGenericMaskedFP(
I, {0},
7065 case Intrinsic::x86_avx512_rcp14_ps_512:
7066 case Intrinsic::x86_avx512_rcp14_ps_256:
7067 case Intrinsic::x86_avx512_rcp14_ps_128:
7068 case Intrinsic::x86_avx512_rcp14_pd_512:
7069 case Intrinsic::x86_avx512_rcp14_pd_256:
7070 case Intrinsic::x86_avx512_rcp14_pd_128:
7071 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
7072 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
7073 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
7074 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
7075 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
7076 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
7077 handleAVX512VectorGenericMaskedFP(
I, {0},
7122 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
7123 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
7124 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
7125 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
7126 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
7127 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
7128 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
7129 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
7130 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
7131 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
7132 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
7133 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
7134 handleAVX512VectorGenericMaskedFP(
I, {0},
7170 case Intrinsic::x86_avx512_mask_scalef_pd_512:
7171 case Intrinsic::x86_avx512_mask_scalef_pd_256:
7172 case Intrinsic::x86_avx512_mask_scalef_pd_128:
7173 case Intrinsic::x86_avx512_mask_scalef_ps_512:
7174 case Intrinsic::x86_avx512_mask_scalef_ps_256:
7175 case Intrinsic::x86_avx512_mask_scalef_ps_128:
7176 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
7177 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
7178 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
7182 handleAVX512VectorGenericMaskedFP(
I, {0, 1},
7202 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
7203 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
7204 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
7205 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
7206 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
7207 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
7208 visitGenericScalarHalfwordInst(
I);
7215 case Intrinsic::x86_avx512_fpclass_pd_512:
7216 case Intrinsic::x86_avx512_fpclass_ps_512:
7217 handleAVX512FPClass(
I);
7221 case Intrinsic::x86_vgf2p8affineqb_128:
7222 case Intrinsic::x86_vgf2p8affineqb_256:
7223 case Intrinsic::x86_vgf2p8affineqb_512:
7224 handleAVXGF2P8Affine(
I);
7234 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &
I) {
7235 switch (
I.getIntrinsicID()) {
7239 case Intrinsic::aarch64_neon_rshrn:
7240 case Intrinsic::aarch64_neon_sqrshl:
7241 case Intrinsic::aarch64_neon_sqrshrn:
7242 case Intrinsic::aarch64_neon_sqrshrun:
7243 case Intrinsic::aarch64_neon_sqshl:
7244 case Intrinsic::aarch64_neon_sqshlu:
7245 case Intrinsic::aarch64_neon_sqshrn:
7246 case Intrinsic::aarch64_neon_sqshrun:
7247 case Intrinsic::aarch64_neon_srshl:
7248 case Intrinsic::aarch64_neon_sshl:
7249 case Intrinsic::aarch64_neon_uqrshl:
7250 case Intrinsic::aarch64_neon_uqrshrn:
7251 case Intrinsic::aarch64_neon_uqshl:
7252 case Intrinsic::aarch64_neon_uqshrn:
7253 case Intrinsic::aarch64_neon_urshl:
7254 case Intrinsic::aarch64_neon_ushl:
7255 handleVectorShiftIntrinsic(
I,
false);
7268 case Intrinsic::aarch64_neon_vsli:
7269 case Intrinsic::aarch64_neon_vsri:
7270 handleIntrinsicByApplyingToShadow(
I,
I.getIntrinsicID(),
7277 case Intrinsic::aarch64_neon_fmaxp:
7278 case Intrinsic::aarch64_neon_fminp:
7280 case Intrinsic::aarch64_neon_fmaxnmp:
7281 case Intrinsic::aarch64_neon_fminnmp:
7283 case Intrinsic::aarch64_neon_smaxp:
7284 case Intrinsic::aarch64_neon_sminp:
7285 case Intrinsic::aarch64_neon_umaxp:
7286 case Intrinsic::aarch64_neon_uminp:
7288 case Intrinsic::aarch64_neon_addp:
7290 case Intrinsic::aarch64_neon_faddp:
7292 case Intrinsic::aarch64_neon_saddlp:
7293 case Intrinsic::aarch64_neon_uaddlp: {
7294 handlePairwiseShadowOrIntrinsic(
I, 1);
7299 case Intrinsic::aarch64_neon_fcvtas:
7300 case Intrinsic::aarch64_neon_fcvtau:
7302 case Intrinsic::aarch64_neon_fcvtms:
7303 case Intrinsic::aarch64_neon_fcvtmu:
7305 case Intrinsic::aarch64_neon_fcvtns:
7306 case Intrinsic::aarch64_neon_fcvtnu:
7308 case Intrinsic::aarch64_neon_fcvtps:
7309 case Intrinsic::aarch64_neon_fcvtpu:
7311 case Intrinsic::aarch64_neon_fcvtzs:
7312 case Intrinsic::aarch64_neon_fcvtzu:
7314 case Intrinsic::aarch64_neon_fcvtxn:
7315 handleGenericVectorConvertIntrinsic(
I,
false);
7319 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7320 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7321 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7322 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7323 handleGenericVectorConvertIntrinsic(
I,
true);
7332 case Intrinsic::aarch64_neon_faddv:
7333 case Intrinsic::aarch64_neon_saddv:
7334 case Intrinsic::aarch64_neon_uaddv:
7337 case Intrinsic::aarch64_neon_smaxv:
7338 case Intrinsic::aarch64_neon_sminv:
7339 case Intrinsic::aarch64_neon_umaxv:
7340 case Intrinsic::aarch64_neon_uminv:
7344 case Intrinsic::aarch64_neon_fmaxv:
7345 case Intrinsic::aarch64_neon_fminv:
7346 case Intrinsic::aarch64_neon_fmaxnmv:
7347 case Intrinsic::aarch64_neon_fminnmv:
7349 case Intrinsic::aarch64_neon_saddlv:
7350 case Intrinsic::aarch64_neon_uaddlv:
7351 handleVectorReduceIntrinsic(
I,
true);
7354 case Intrinsic::aarch64_neon_ld1x2:
7355 case Intrinsic::aarch64_neon_ld1x3:
7356 case Intrinsic::aarch64_neon_ld1x4:
7357 case Intrinsic::aarch64_neon_ld2:
7358 case Intrinsic::aarch64_neon_ld3:
7359 case Intrinsic::aarch64_neon_ld4:
7360 case Intrinsic::aarch64_neon_ld2r:
7361 case Intrinsic::aarch64_neon_ld3r:
7362 case Intrinsic::aarch64_neon_ld4r: {
7363 handleNEONVectorLoad(
I,
false);
7367 case Intrinsic::aarch64_neon_ld2lane:
7368 case Intrinsic::aarch64_neon_ld3lane:
7369 case Intrinsic::aarch64_neon_ld4lane: {
7370 handleNEONVectorLoad(
I,
true);
7375 case Intrinsic::aarch64_neon_sqxtn:
7376 case Intrinsic::aarch64_neon_sqxtun:
7377 case Intrinsic::aarch64_neon_uqxtn:
7384 case Intrinsic::aarch64_neon_st1x2:
7385 case Intrinsic::aarch64_neon_st1x3:
7386 case Intrinsic::aarch64_neon_st1x4:
7387 case Intrinsic::aarch64_neon_st2:
7388 case Intrinsic::aarch64_neon_st3:
7389 case Intrinsic::aarch64_neon_st4: {
7390 handleNEONVectorStoreIntrinsic(
I,
false);
7394 case Intrinsic::aarch64_neon_st2lane:
7395 case Intrinsic::aarch64_neon_st3lane:
7396 case Intrinsic::aarch64_neon_st4lane: {
7397 handleNEONVectorStoreIntrinsic(
I,
true);
7410 case Intrinsic::aarch64_neon_tbl1:
7411 case Intrinsic::aarch64_neon_tbl2:
7412 case Intrinsic::aarch64_neon_tbl3:
7413 case Intrinsic::aarch64_neon_tbl4:
7414 case Intrinsic::aarch64_neon_tbx1:
7415 case Intrinsic::aarch64_neon_tbx2:
7416 case Intrinsic::aarch64_neon_tbx3:
7417 case Intrinsic::aarch64_neon_tbx4: {
7419 handleIntrinsicByApplyingToShadow(
7420 I,
I.getIntrinsicID(),
7425 case Intrinsic::aarch64_neon_fmulx:
7426 case Intrinsic::aarch64_neon_pmul:
7427 case Intrinsic::aarch64_neon_pmull:
7428 case Intrinsic::aarch64_neon_smull:
7429 case Intrinsic::aarch64_neon_pmull64:
7430 case Intrinsic::aarch64_neon_umull: {
7431 handleNEONVectorMultiplyIntrinsic(
I);
7435 case Intrinsic::aarch64_neon_smmla:
7436 case Intrinsic::aarch64_neon_ummla:
7437 case Intrinsic::aarch64_neon_usmmla:
7438 case Intrinsic::aarch64_neon_bfmmla:
7439 handleNEONMatrixMultiply(
I);
7446 case Intrinsic::aarch64_neon_sdot:
7447 case Intrinsic::aarch64_neon_udot:
7448 case Intrinsic::aarch64_neon_usdot:
7449 handleVectorDotProductIntrinsic(
I, 4,
7459 case Intrinsic::aarch64_neon_bfdot:
7460 handleVectorDotProductIntrinsic(
I, 2,
7467 case Intrinsic::aarch64_neon_facge:
7468 case Intrinsic::aarch64_neon_facgt:
7469 handleVectorComparePackedIntrinsic(
I,
false);
7479 void visitIntrinsicInst(IntrinsicInst &
I) {
7480 if (maybeHandleCrossPlatformIntrinsic(
I))
7483 if (maybeHandleX86SIMDIntrinsic(
I))
7486 if (maybeHandleArmSIMDIntrinsic(
I))
7489 if (maybeHandleUnknownIntrinsic(
I))
7492 visitInstruction(
I);
7495 void visitLibAtomicLoad(CallBase &CB) {
7506 Value *NewOrdering =
7510 NextNodeIRBuilder NextIRB(&CB);
7511 Value *SrcShadowPtr, *SrcOriginPtr;
7512 std::tie(SrcShadowPtr, SrcOriginPtr) =
7513 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7515 Value *DstShadowPtr =
7516 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(),
Align(1),
7520 NextIRB.CreateMemCpy(DstShadowPtr,
Align(1), SrcShadowPtr,
Align(1),
Size);
7521 if (MS.TrackOrigins) {
7522 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7524 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7525 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7529 void visitLibAtomicStore(CallBase &CB) {
7536 Value *NewOrdering =
7540 Value *DstShadowPtr =
7550 void visitCallBase(CallBase &CB) {
7558 visitAsmInstruction(CB);
7560 visitInstruction(CB);
7564 if (LF != NotLibFunc) {
7569 case LibFunc_atomic_load:
7571 llvm::errs() <<
"MSAN -- cannot instrument invoke of libatomic load."
7575 visitLibAtomicLoad(CB);
7577 case LibFunc_atomic_store:
7578 visitLibAtomicStore(CB);
7594 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7598 Func->removeFnAttrs(
B);
7604 bool MayCheckCall = MS.EagerChecks;
7608 MayCheckCall &= !
Func->getName().starts_with(
"__sanitizer_unaligned_");
7611 unsigned ArgOffset = 0;
7614 if (!
A->getType()->isSized()) {
7615 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << CB <<
"\n");
7619 if (
A->getType()->isScalableTy()) {
7620 LLVM_DEBUG(
dbgs() <<
"Arg " << i <<
" is vscale: " << CB <<
"\n");
7622 insertCheckShadowOf(
A, &CB);
7627 const DataLayout &
DL =
F.getDataLayout();
7631 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7634 insertCheckShadowOf(
A, &CB);
7635 Size =
DL.getTypeAllocSize(
A->getType());
7641 Value *ArgShadow = getShadow(
A);
7642 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7644 <<
" Shadow: " << *ArgShadow <<
"\n");
7648 assert(
A->getType()->isPointerTy() &&
7649 "ByVal argument is not a pointer!");
7657 Value *AShadowPtr, *AOriginPtr;
7658 std::tie(AShadowPtr, AOriginPtr) =
7659 getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(), Alignment,
7661 if (!PropagateShadow) {
7668 if (MS.TrackOrigins) {
7669 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7683 Size =
DL.getTypeAllocSize(
A->getType());
7689 if (MS.TrackOrigins && !(Cst && Cst->
isNullValue())) {
7691 getOriginPtrForArgument(IRB, ArgOffset));
7703 if (FT->isVarArg()) {
7704 VAHelper->visitCallBase(CB, IRB);
7714 if (MayCheckCall && CB.
hasRetAttr(Attribute::NoUndef)) {
7715 setShadow(&CB, getCleanShadow(&CB));
7716 setOrigin(&CB, getCleanOrigin());
7722 Value *
Base = getShadowPtrForRetval(IRBBefore);
7723 IRBBefore.CreateAlignedStore(getCleanShadow(&CB),
Base,
7735 setShadow(&CB, getCleanShadow(&CB));
7736 setOrigin(&CB, getCleanOrigin());
7743 "Could not find insertion point for retval shadow load");
7746 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7749 setShadow(&CB, RetvalShadow);
7750 if (MS.TrackOrigins)
7751 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7756 RetVal =
I->getOperand(0);
7759 return I->isMustTailCall();
7764 void visitReturnInst(ReturnInst &
I) {
7766 Value *RetVal =
I.getReturnValue();
7772 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7773 bool HasNoUndef =
F.hasRetAttribute(Attribute::NoUndef);
7774 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7777 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (
F.getName() ==
"main");
7779 Value *Shadow = getShadow(RetVal);
7780 bool StoreOrigin =
true;
7782 insertCheckShadowOf(RetVal, &
I);
7783 Shadow = getCleanShadow(RetVal);
7784 StoreOrigin =
false;
7791 if (MS.TrackOrigins && StoreOrigin)
7792 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7796 void visitPHINode(PHINode &
I) {
7798 if (!PropagateShadow) {
7799 setShadow(&
I, getCleanShadow(&
I));
7800 setOrigin(&
I, getCleanOrigin());
7804 ShadowPHINodes.push_back(&
I);
7805 setShadow(&
I, IRB.
CreatePHI(getShadowTy(&
I),
I.getNumIncomingValues(),
7807 if (MS.TrackOrigins)
7809 &
I, IRB.
CreatePHI(MS.OriginTy,
I.getNumIncomingValues(),
"_msphi_o"));
7812 Value *getLocalVarIdptr(AllocaInst &
I) {
7813 ConstantInt *IntConst =
7814 ConstantInt::get(Type::getInt32Ty((*
F.getParent()).getContext()), 0);
7815 return new GlobalVariable(*
F.getParent(), IntConst->
getType(),
7820 Value *getLocalVarDescription(AllocaInst &
I) {
7826 IRB.
CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7828 Value *ShadowBase, *OriginBase;
7829 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7833 IRB.
CreateMemSet(ShadowBase, PoisonValue, Len,
I.getAlign());
7836 if (PoisonStack && MS.TrackOrigins) {
7837 Value *Idptr = getLocalVarIdptr(
I);
7839 Value *Descr = getLocalVarDescription(
I);
7840 IRB.
CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
7841 {&I, Len, Idptr, Descr});
7843 IRB.
CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
7849 Value *Descr = getLocalVarDescription(
I);
7851 IRB.
CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
7853 IRB.
CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
7857 void instrumentAlloca(AllocaInst &
I, Instruction *InsPoint =
nullptr) {
7860 NextNodeIRBuilder IRB(InsPoint);
7863 if (MS.CompileKernel)
7864 poisonAllocaKmsan(
I, IRB, Len);
7866 poisonAllocaUserspace(
I, IRB, Len);
7869 void visitAllocaInst(AllocaInst &
I) {
7870 setShadow(&
I, getCleanShadow(&
I));
7871 setOrigin(&
I, getCleanOrigin());
7877 void visitSelectInst(SelectInst &
I) {
7883 handleSelectLikeInst(
I,
B,
C,
D);
7889 Value *Sb = getShadow(
B);
7890 Value *Sc = getShadow(
C);
7891 Value *Sd = getShadow(
D);
7893 Value *Ob = MS.TrackOrigins ? getOrigin(
B) : nullptr;
7894 Value *Oc = MS.TrackOrigins ? getOrigin(
C) : nullptr;
7895 Value *Od = MS.TrackOrigins ? getOrigin(
D) : nullptr;
7900 if (
I.getType()->isAggregateType()) {
7904 Sa1 = getPoisonedShadow(getShadowTy(
I.getType()));
7905 }
else if (isScalableNonVectorType(
I.getType())) {
7913 Sa1 = getCleanShadow(getShadowTy(
I.getType()));
7921 C = CreateAppToShadowCast(IRB,
C);
7922 D = CreateAppToShadowCast(IRB,
D);
7929 if (MS.TrackOrigins) {
7932 if (
B->getType()->isVectorTy()) {
7933 B = convertToBool(
B, IRB);
7934 Sb = convertToBool(Sb, IRB);
7942 void visitLandingPadInst(LandingPadInst &
I) {
7945 setShadow(&
I, getCleanShadow(&
I));
7946 setOrigin(&
I, getCleanOrigin());
7949 void visitCatchSwitchInst(CatchSwitchInst &
I) {
7950 setShadow(&
I, getCleanShadow(&
I));
7951 setOrigin(&
I, getCleanOrigin());
7954 void visitFuncletPadInst(FuncletPadInst &
I) {
7955 setShadow(&
I, getCleanShadow(&
I));
7956 setOrigin(&
I, getCleanOrigin());
7959 void visitGetElementPtrInst(GetElementPtrInst &
I) { handleShadowOr(
I); }
7961 void visitExtractValueInst(ExtractValueInst &
I) {
7963 Value *Agg =
I.getAggregateOperand();
7965 Value *AggShadow = getShadow(Agg);
7969 setShadow(&
I, ResShadow);
7970 setOriginForNaryOp(
I);
7973 void visitInsertValueInst(InsertValueInst &
I) {
7976 Value *AggShadow = getShadow(
I.getAggregateOperand());
7977 Value *InsShadow = getShadow(
I.getInsertedValueOperand());
7983 setOriginForNaryOp(
I);
7986 void dumpInst(Instruction &
I,
const Twine &Prefix) {
7993 << CI->getCalledFunction()->
getName() <<
"\n";
7995 errs() <<
"ZZZ:" <<
Prefix <<
" " <<
I.getOpcodeName() <<
"\n";
8002 unsigned NumOperands =
I.getNumOperands();
8004 errs() <<
"YYY:" <<
Prefix <<
" call " << *
I.getType() <<
" @";
8016 errs() <<
"YYY:" <<
Prefix <<
" " << *
I.getType() <<
" "
8017 <<
I.getOpcodeName() <<
"(";
8019 for (
size_t i = 0; i < NumOperands; i++) {
8037 void visitResumeInst(ResumeInst &
I) {
8042 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
8047 void visitCatchReturnInst(CatchReturnInst &CRI) {
8052 void instrumentAsmArgument(
Value *Operand,
Type *ElemTy, Instruction &
I,
8061 insertCheckShadowOf(Operand, &
I);
8068 auto Size =
DL.getTypeStoreSize(ElemTy);
8070 if (MS.CompileKernel) {
8071 IRB.
CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
8077 auto [ShadowPtr,
_] =
8078 getShadowOriginPtrUserspace(Operand, IRB, IRB.
getInt8Ty(),
Align(1));
8088 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
8089 int NumRetOutputs = 0;
8096 NumRetOutputs =
ST->getNumElements();
8101 for (
const InlineAsm::ConstraintInfo &Info : Constraints) {
8102 switch (
Info.Type) {
8110 return NumOutputs - NumRetOutputs;
8113 void visitAsmInstruction(Instruction &
I) {
8129 const DataLayout &
DL =
F.getDataLayout();
8133 int OutputArgs = getNumOutputArgs(IA, CB);
8139 for (
int i = OutputArgs; i < NumOperands; i++) {
8147 for (
int i = 0; i < OutputArgs; i++) {
8153 setShadow(&
I, getCleanShadow(&
I));
8154 setOrigin(&
I, getCleanOrigin());
8157 void visitFreezeInst(FreezeInst &
I) {
8159 setShadow(&
I, getCleanShadow(&
I));
8160 setOrigin(&
I, getCleanOrigin());
8163 void visitInstruction(Instruction &
I) {
8166 dumpInst(
I,
"Strict");
8168 for (
size_t i = 0, n =
I.getNumOperands(); i < n; i++) {
8169 Value *Operand =
I.getOperand(i);
8171 insertCheckShadowOf(Operand, &
I);
8173 setShadow(&
I, getCleanShadow(&
I));
8174 setOrigin(&
I, getCleanOrigin());
8178struct VarArgHelperBase :
public VarArgHelper {
8180 MemorySanitizer &MS;
8181 MemorySanitizerVisitor &MSV;
8183 const unsigned VAListTagSize;
8185 VarArgHelperBase(
Function &
F, MemorySanitizer &MS,
8186 MemorySanitizerVisitor &MSV,
unsigned VAListTagSize)
8187 :
F(
F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
8191 return IRB.
CreateAdd(
Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
8197 MS.VAArgTLS, ConstantInt::get(MS.IntptrTy, ArgOffset),
"_msarg_va_s");
8206 return getShadowPtrForVAArgument(IRB, ArgOffset);
8215 ConstantInt::get(MS.IntptrTy, ArgOffset),
8220 unsigned BaseOffset) {
8229 TailSize,
Align(8));
8232 void unpoisonVAListTagForInst(IntrinsicInst &
I) {
8234 Value *VAListTag =
I.getArgOperand(0);
8236 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
8237 VAListTag, IRB, IRB.
getInt8Ty(), Alignment,
true);
8240 VAListTagSize, Alignment,
false);
8243 void visitVAStartInst(VAStartInst &
I)
override {
8244 if (
F.getCallingConv() == CallingConv::Win64)
8247 unpoisonVAListTagForInst(
I);
8250 void visitVACopyInst(VACopyInst &
I)
override {
8251 if (
F.getCallingConv() == CallingConv::Win64)
8253 unpoisonVAListTagForInst(
I);
8258struct VarArgAMD64Helper :
public VarArgHelperBase {
8261 static const unsigned AMD64GpEndOffset = 48;
8262 static const unsigned AMD64FpEndOffsetSSE = 176;
8264 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8266 unsigned AMD64FpEndOffset;
8267 AllocaInst *VAArgTLSCopy =
nullptr;
8268 AllocaInst *VAArgTLSOriginCopy =
nullptr;
8269 Value *VAArgOverflowSize =
nullptr;
8271 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8273 VarArgAMD64Helper(
Function &
F, MemorySanitizer &MS,
8274 MemorySanitizerVisitor &MSV)
8275 : VarArgHelperBase(
F, MS, MSV, 24) {
8276 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8277 for (
const auto &Attr :
F.getAttributes().getFnAttrs()) {
8278 if (Attr.isStringAttribute() &&
8279 (Attr.getKindAsString() ==
"target-features")) {
8280 if (Attr.getValueAsString().contains(
"-sse"))
8281 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8287 ArgKind classifyArgument(
Value *arg) {
8290 if (
T->isX86_FP80Ty())
8292 if (
T->isFPOrFPVectorTy())
8293 return AK_FloatingPoint;
8294 if (
T->isIntegerTy() &&
T->getPrimitiveSizeInBits() <= 64)
8295 return AK_GeneralPurpose;
8296 if (
T->isPointerTy())
8297 return AK_GeneralPurpose;
8309 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8310 unsigned GpOffset = 0;
8311 unsigned FpOffset = AMD64GpEndOffset;
8312 unsigned OverflowOffset = AMD64FpEndOffset;
8313 const DataLayout &
DL =
F.getDataLayout();
8324 assert(
A->getType()->isPointerTy());
8326 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8328 unsigned BaseOffset = OverflowOffset;
8329 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8330 Value *OriginBase =
nullptr;
8331 if (MS.TrackOrigins)
8332 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8333 OverflowOffset += AlignedSize;
8336 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8340 Value *ShadowPtr, *OriginPtr;
8341 std::tie(ShadowPtr, OriginPtr) =
8346 if (MS.TrackOrigins)
8350 ArgKind AK = classifyArgument(
A);
8351 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8353 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8355 Value *ShadowBase, *OriginBase =
nullptr;
8357 case AK_GeneralPurpose:
8358 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8359 if (MS.TrackOrigins)
8360 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8364 case AK_FloatingPoint:
8365 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8366 if (MS.TrackOrigins)
8367 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8374 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8376 unsigned BaseOffset = OverflowOffset;
8377 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8378 if (MS.TrackOrigins) {
8379 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8381 OverflowOffset += AlignedSize;
8384 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8393 Value *Shadow = MSV.getShadow(
A);
8395 if (MS.TrackOrigins) {
8396 Value *Origin = MSV.getOrigin(
A);
8397 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
8398 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8404 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8405 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8408 void finalizeInstrumentation()
override {
8409 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8410 "finalizeInstrumentation called twice");
8411 if (!VAStartInstrumentationList.
empty()) {
8418 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8419 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8425 Intrinsic::umin, CopySize,
8429 if (MS.TrackOrigins) {
8430 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8439 for (CallInst *OrigInst : VAStartInstrumentationList) {
8440 NextNodeIRBuilder IRB(OrigInst);
8441 Value *VAListTag = OrigInst->getArgOperand(0);
8443 Value *RegSaveAreaPtrPtr =
8444 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 16));
8446 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8448 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8449 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8451 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8453 if (MS.TrackOrigins)
8454 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8455 Alignment, AMD64FpEndOffset);
8456 Value *OverflowArgAreaPtrPtr =
8457 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 8));
8458 Value *OverflowArgAreaPtr =
8459 IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8460 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8461 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8462 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
8466 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8468 if (MS.TrackOrigins) {
8471 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8479struct VarArgAArch64Helper :
public VarArgHelperBase {
8480 static const unsigned kAArch64GrArgSize = 64;
8481 static const unsigned kAArch64VrArgSize = 128;
8483 static const unsigned AArch64GrBegOffset = 0;
8484 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8486 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8487 static const unsigned AArch64VrEndOffset =
8488 AArch64VrBegOffset + kAArch64VrArgSize;
8489 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8491 AllocaInst *VAArgTLSCopy =
nullptr;
8492 Value *VAArgOverflowSize =
nullptr;
8494 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8496 VarArgAArch64Helper(
Function &
F, MemorySanitizer &MS,
8497 MemorySanitizerVisitor &MSV)
8498 : VarArgHelperBase(
F, MS, MSV, 32) {}
8501 std::pair<ArgKind, uint64_t> classifyArgument(
Type *
T) {
8502 if (
T->isIntOrPtrTy() &&
T->getPrimitiveSizeInBits() <= 64)
8503 return {AK_GeneralPurpose, 1};
8504 if (
T->isFloatingPointTy() &&
T->getPrimitiveSizeInBits() <= 128)
8505 return {AK_FloatingPoint, 1};
8507 if (
T->isArrayTy()) {
8508 auto R = classifyArgument(
T->getArrayElementType());
8509 R.second *=
T->getScalarType()->getArrayNumElements();
8514 auto R = classifyArgument(FV->getScalarType());
8515 R.second *= FV->getNumElements();
8520 return {AK_Memory, 0};
8532 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8533 unsigned GrOffset = AArch64GrBegOffset;
8534 unsigned VrOffset = AArch64VrBegOffset;
8535 unsigned OverflowOffset = AArch64VAEndOffset;
8537 const DataLayout &
DL =
F.getDataLayout();
8540 auto [AK, RegNum] = classifyArgument(
A->getType());
8541 if (AK == AK_GeneralPurpose &&
8542 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8544 if (AK == AK_FloatingPoint &&
8545 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8549 case AK_GeneralPurpose:
8550 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8551 GrOffset += 8 * RegNum;
8553 case AK_FloatingPoint:
8554 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8555 VrOffset += 16 * RegNum;
8562 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8564 unsigned BaseOffset = OverflowOffset;
8565 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8566 OverflowOffset += AlignedSize;
8569 CleanUnusedTLS(IRB,
Base, BaseOffset);
8581 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8582 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8587 Value *SaveAreaPtrPtr =
8588 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8589 return IRB.
CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8594 Value *SaveAreaPtr =
8595 IRB.
CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8597 return IRB.
CreateSExt(SaveArea32, MS.IntptrTy);
8600 void finalizeInstrumentation()
override {
8601 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8602 "finalizeInstrumentation called twice");
8603 if (!VAStartInstrumentationList.empty()) {
8610 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8611 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8617 Intrinsic::umin, CopySize,
8623 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8624 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8628 for (CallInst *OrigInst : VAStartInstrumentationList) {
8629 NextNodeIRBuilder IRB(OrigInst);
8631 Value *VAListTag = OrigInst->getArgOperand(0);
8648 Value *StackSaveAreaPtr =
8649 IRB.
CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8652 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8653 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8656 IRB.
CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8659 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8660 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8663 IRB.
CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8669 Value *GrRegSaveAreaShadowPtrOff =
8670 IRB.
CreateAdd(GrArgSize, GrOffSaveArea);
8672 Value *GrRegSaveAreaShadowPtr =
8673 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8679 Value *GrCopySize = IRB.
CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8685 Value *VrRegSaveAreaShadowPtrOff =
8686 IRB.
CreateAdd(VrArgSize, VrOffSaveArea);
8688 Value *VrRegSaveAreaShadowPtr =
8689 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8696 VrRegSaveAreaShadowPtrOff);
8697 Value *VrCopySize = IRB.
CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8703 Value *StackSaveAreaShadowPtr =
8704 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8709 VAArgTLSCopy, IRB.
getInt32(AArch64VAEndOffset));
8712 Align(16), VAArgOverflowSize);
8718struct VarArgPowerPC64Helper :
public VarArgHelperBase {
8719 AllocaInst *VAArgTLSCopy =
nullptr;
8720 Value *VAArgSize =
nullptr;
8722 VarArgPowerPC64Helper(
Function &
F, MemorySanitizer &MS,
8723 MemorySanitizerVisitor &MSV)
8724 : VarArgHelperBase(
F, MS, MSV, 8) {}
8726 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8734 Triple TargetTriple(
F.getParent()->getTargetTriple());
8738 if (TargetTriple.isPPC64ELFv2ABI())
8742 unsigned VAArgOffset = VAArgBase;
8743 const DataLayout &
DL =
F.getDataLayout();
8748 assert(
A->getType()->isPointerTy());
8750 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8753 ArgAlign =
Align(8);
8754 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8757 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8759 Value *AShadowPtr, *AOriginPtr;
8760 std::tie(AShadowPtr, AOriginPtr) =
8761 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8771 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
8773 if (
A->getType()->isArrayTy()) {
8776 Type *ElementTy =
A->getType()->getArrayElementType();
8778 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8779 }
else if (
A->getType()->isVectorTy()) {
8781 ArgAlign =
Align(ArgSize);
8784 ArgAlign =
Align(8);
8785 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8786 if (
DL.isBigEndian()) {
8790 VAArgOffset += (8 - ArgSize);
8794 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8798 VAArgOffset += ArgSize;
8802 VAArgBase = VAArgOffset;
8806 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8809 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8812 void finalizeInstrumentation()
override {
8813 assert(!VAArgSize && !VAArgTLSCopy &&
8814 "finalizeInstrumentation called twice");
8817 Value *CopySize = VAArgSize;
8819 if (!VAStartInstrumentationList.empty()) {
8823 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8829 Intrinsic::umin, CopySize,
8837 for (CallInst *OrigInst : VAStartInstrumentationList) {
8838 NextNodeIRBuilder IRB(OrigInst);
8839 Value *VAListTag = OrigInst->getArgOperand(0);
8842 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8845 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8846 const DataLayout &
DL =
F.getDataLayout();
8847 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8849 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8850 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8852 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8859struct VarArgPowerPC32Helper :
public VarArgHelperBase {
8860 AllocaInst *VAArgTLSCopy =
nullptr;
8861 Value *VAArgSize =
nullptr;
8863 VarArgPowerPC32Helper(
Function &
F, MemorySanitizer &MS,
8864 MemorySanitizerVisitor &MSV)
8865 : VarArgHelperBase(
F, MS, MSV, 12) {}
8867 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
8871 unsigned VAArgOffset = VAArgBase;
8872 const DataLayout &
DL =
F.getDataLayout();
8873 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8878 assert(
A->getType()->isPointerTy());
8880 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
8882 if (ArgAlign < IntptrSize)
8883 ArgAlign =
Align(IntptrSize);
8884 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8887 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8889 Value *AShadowPtr, *AOriginPtr;
8890 std::tie(AShadowPtr, AOriginPtr) =
8891 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
8901 Type *ArgTy =
A->getType();
8907 uint64_t ArgSize =
DL.getTypeAllocSize(ArgTy);
8914 ArgAlign =
Align(
DL.getTypeAllocSize(ElementTy));
8917 ArgAlign =
Align(ArgSize);
8919 if (ArgAlign < IntptrSize)
8920 ArgAlign =
Align(IntptrSize);
8921 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
8922 if (
DL.isBigEndian()) {
8925 if (ArgSize < IntptrSize)
8926 VAArgOffset += (IntptrSize - ArgSize);
8929 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
8935 VAArgOffset += ArgSize;
8942 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8945 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8948 void finalizeInstrumentation()
override {
8949 assert(!VAArgSize && !VAArgTLSCopy &&
8950 "finalizeInstrumentation called twice");
8952 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
8953 Value *CopySize = VAArgSize;
8955 if (!VAStartInstrumentationList.empty()) {
8959 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8965 Intrinsic::umin, CopySize,
8973 for (CallInst *OrigInst : VAStartInstrumentationList) {
8974 NextNodeIRBuilder IRB(OrigInst);
8975 Value *VAListTag = OrigInst->getArgOperand(0);
8977 Value *RegSaveAreaSize = CopySize;
8981 IRB.
CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
8985 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
8987 RegSaveAreaPtrPtr = IRB.
CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8990 const DataLayout &
DL =
F.getDataLayout();
8991 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
8995 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8996 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8997 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
8999 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
9000 Alignment, RegSaveAreaSize);
9002 RegSaveAreaShadowPtr =
9005 ConstantInt::get(MS.IntptrTy, 32));
9010 ConstantInt::get(MS.IntptrTy, 32), Alignment);
9015 Value *OverflowAreaSize = IRB.
CreateSub(CopySize, RegSaveAreaSize);
9018 OverflowAreaPtrPtr =
9019 IRB.
CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
9020 OverflowAreaPtrPtr = IRB.
CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
9022 Value *OverflowAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
9024 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
9025 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
9026 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.
getInt8Ty(),
9029 Value *OverflowVAArgTLSCopyPtr =
9031 OverflowVAArgTLSCopyPtr =
9032 IRB.
CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
9034 OverflowVAArgTLSCopyPtr =
9037 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
9044struct VarArgSystemZHelper :
public VarArgHelperBase {
9045 static const unsigned SystemZGpOffset = 16;
9046 static const unsigned SystemZGpEndOffset = 56;
9047 static const unsigned SystemZFpOffset = 128;
9048 static const unsigned SystemZFpEndOffset = 160;
9049 static const unsigned SystemZMaxVrArgs = 8;
9050 static const unsigned SystemZRegSaveAreaSize = 160;
9051 static const unsigned SystemZOverflowOffset = 160;
9052 static const unsigned SystemZVAListTagSize = 32;
9053 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
9054 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
9056 bool IsSoftFloatABI;
9057 AllocaInst *VAArgTLSCopy =
nullptr;
9058 AllocaInst *VAArgTLSOriginCopy =
nullptr;
9059 Value *VAArgOverflowSize =
nullptr;
9061 enum class ArgKind {
9069 enum class ShadowExtension {
None,
Zero, Sign };
9071 VarArgSystemZHelper(
Function &
F, MemorySanitizer &MS,
9072 MemorySanitizerVisitor &MSV)
9073 : VarArgHelperBase(
F, MS, MSV, SystemZVAListTagSize),
9074 IsSoftFloatABI(
F.getFnAttribute(
"use-soft-float").getValueAsBool()) {}
9076 ArgKind classifyArgument(
Type *
T) {
9083 if (
T->isIntegerTy(128) ||
T->isFP128Ty())
9084 return ArgKind::Indirect;
9085 if (
T->isFloatingPointTy())
9086 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
9087 if (
T->isIntegerTy() ||
T->isPointerTy())
9088 return ArgKind::GeneralPurpose;
9089 if (
T->isVectorTy())
9090 return ArgKind::Vector;
9091 return ArgKind::Memory;
9094 ShadowExtension getShadowExtension(
const CallBase &CB,
unsigned ArgNo) {
9104 return ShadowExtension::Zero;
9108 return ShadowExtension::Sign;
9110 return ShadowExtension::None;
9113 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9114 unsigned GpOffset = SystemZGpOffset;
9115 unsigned FpOffset = SystemZFpOffset;
9116 unsigned VrIndex = 0;
9117 unsigned OverflowOffset = SystemZOverflowOffset;
9118 const DataLayout &
DL =
F.getDataLayout();
9124 ArgKind AK = classifyArgument(
T);
9125 if (AK == ArgKind::Indirect) {
9127 AK = ArgKind::GeneralPurpose;
9129 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
9130 AK = ArgKind::Memory;
9131 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
9132 AK = ArgKind::Memory;
9133 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
9134 AK = ArgKind::Memory;
9135 Value *ShadowBase =
nullptr;
9136 Value *OriginBase =
nullptr;
9137 ShadowExtension SE = ShadowExtension::None;
9139 case ArgKind::GeneralPurpose: {
9144 SE = getShadowExtension(CB, ArgNo);
9146 if (SE == ShadowExtension::None) {
9148 assert(ArgAllocSize <= ArgSize);
9149 GapSize = ArgSize - ArgAllocSize;
9151 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
9152 if (MS.TrackOrigins)
9153 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
9155 GpOffset += ArgSize;
9161 case ArgKind::FloatingPoint: {
9170 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
9171 if (MS.TrackOrigins)
9172 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
9174 FpOffset += ArgSize;
9180 case ArgKind::Vector: {
9187 case ArgKind::Memory: {
9195 SE = getShadowExtension(CB, ArgNo);
9197 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
9199 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
9200 if (MS.TrackOrigins)
9202 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
9203 OverflowOffset += ArgSize;
9210 case ArgKind::Indirect:
9213 if (ShadowBase ==
nullptr)
9215 Value *Shadow = MSV.getShadow(
A);
9216 if (SE != ShadowExtension::None)
9217 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.
getInt64Ty(),
9218 SE == ShadowExtension::Sign);
9219 ShadowBase = IRB.
CreateIntToPtr(ShadowBase, MS.PtrTy,
"_msarg_va_s");
9221 if (MS.TrackOrigins) {
9222 Value *Origin = MSV.getOrigin(
A);
9223 TypeSize StoreSize =
DL.getTypeStoreSize(Shadow->
getType());
9224 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
9228 Constant *OverflowSize = ConstantInt::get(
9229 IRB.
getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
9230 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
9237 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
9240 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9242 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9243 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(), Alignment,
9248 unsigned RegSaveAreaSize =
9249 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9250 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9252 if (MS.TrackOrigins)
9253 IRB.
CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9254 Alignment, RegSaveAreaSize);
9263 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9265 Value *OverflowArgAreaPtr = IRB.
CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9266 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9268 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9269 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.
getInt8Ty(),
9272 SystemZOverflowOffset);
9273 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9275 if (MS.TrackOrigins) {
9277 SystemZOverflowOffset);
9278 IRB.
CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9283 void finalizeInstrumentation()
override {
9284 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9285 "finalizeInstrumentation called twice");
9286 if (!VAStartInstrumentationList.empty()) {
9293 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9295 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9301 Intrinsic::umin, CopySize,
9305 if (MS.TrackOrigins) {
9306 VAArgTLSOriginCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9315 for (CallInst *OrigInst : VAStartInstrumentationList) {
9316 NextNodeIRBuilder IRB(OrigInst);
9317 Value *VAListTag = OrigInst->getArgOperand(0);
9318 copyRegSaveArea(IRB, VAListTag);
9319 copyOverflowArea(IRB, VAListTag);
9325struct VarArgI386Helper :
public VarArgHelperBase {
9326 AllocaInst *VAArgTLSCopy =
nullptr;
9327 Value *VAArgSize =
nullptr;
9329 VarArgI386Helper(
Function &
F, MemorySanitizer &MS,
9330 MemorySanitizerVisitor &MSV)
9331 : VarArgHelperBase(
F, MS, MSV, 4) {}
9333 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9334 const DataLayout &
DL =
F.getDataLayout();
9335 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9336 unsigned VAArgOffset = 0;
9341 assert(
A->getType()->isPointerTy());
9343 uint64_t ArgSize =
DL.getTypeAllocSize(RealTy);
9345 if (ArgAlign < IntptrSize)
9346 ArgAlign =
Align(IntptrSize);
9347 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9349 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9351 Value *AShadowPtr, *AOriginPtr;
9352 std::tie(AShadowPtr, AOriginPtr) =
9353 MSV.getShadowOriginPtr(
A, IRB, IRB.
getInt8Ty(),
9363 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9365 VAArgOffset =
alignTo(VAArgOffset, ArgAlign);
9366 if (
DL.isBigEndian()) {
9369 if (ArgSize < IntptrSize)
9370 VAArgOffset += (IntptrSize - ArgSize);
9373 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9376 VAArgOffset += ArgSize;
9382 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9385 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9388 void finalizeInstrumentation()
override {
9389 assert(!VAArgSize && !VAArgTLSCopy &&
9390 "finalizeInstrumentation called twice");
9392 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9393 Value *CopySize = VAArgSize;
9395 if (!VAStartInstrumentationList.empty()) {
9398 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9404 Intrinsic::umin, CopySize,
9412 for (CallInst *OrigInst : VAStartInstrumentationList) {
9413 NextNodeIRBuilder IRB(OrigInst);
9414 Value *VAListTag = OrigInst->getArgOperand(0);
9415 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9416 Value *RegSaveAreaPtrPtr =
9418 PointerType::get(*MS.C, 0));
9419 Value *RegSaveAreaPtr =
9420 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9421 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9422 const DataLayout &
DL =
F.getDataLayout();
9423 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9425 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9426 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9428 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9436struct VarArgGenericHelper :
public VarArgHelperBase {
9437 AllocaInst *VAArgTLSCopy =
nullptr;
9438 Value *VAArgSize =
nullptr;
9440 VarArgGenericHelper(
Function &
F, MemorySanitizer &MS,
9441 MemorySanitizerVisitor &MSV,
const unsigned VAListTagSize)
9442 : VarArgHelperBase(
F, MS, MSV, VAListTagSize) {}
9444 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {
9445 unsigned VAArgOffset = 0;
9446 const DataLayout &
DL =
F.getDataLayout();
9447 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9452 uint64_t ArgSize =
DL.getTypeAllocSize(
A->getType());
9453 if (
DL.isBigEndian()) {
9456 if (ArgSize < IntptrSize)
9457 VAArgOffset += (IntptrSize - ArgSize);
9459 Value *
Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9460 VAArgOffset += ArgSize;
9461 VAArgOffset =
alignTo(VAArgOffset, IntptrSize);
9467 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9470 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9473 void finalizeInstrumentation()
override {
9474 assert(!VAArgSize && !VAArgTLSCopy &&
9475 "finalizeInstrumentation called twice");
9477 VAArgSize = IRB.
CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9478 Value *CopySize = VAArgSize;
9480 if (!VAStartInstrumentationList.empty()) {
9483 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9489 Intrinsic::umin, CopySize,
9497 for (CallInst *OrigInst : VAStartInstrumentationList) {
9498 NextNodeIRBuilder IRB(OrigInst);
9499 Value *VAListTag = OrigInst->getArgOperand(0);
9500 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9501 Value *RegSaveAreaPtrPtr =
9503 PointerType::get(*MS.C, 0));
9504 Value *RegSaveAreaPtr =
9505 IRB.
CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9506 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9507 const DataLayout &
DL =
F.getDataLayout();
9508 unsigned IntptrSize =
DL.getTypeStoreSize(MS.IntptrTy);
9510 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9511 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.
getInt8Ty(),
9513 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9521using VarArgARM32Helper = VarArgGenericHelper;
9522using VarArgRISCVHelper = VarArgGenericHelper;
9523using VarArgMIPSHelper = VarArgGenericHelper;
9524using VarArgLoongArch64Helper = VarArgGenericHelper;
9525using VarArgHexagonHelper = VarArgGenericHelper;
9528struct VarArgNoOpHelper :
public VarArgHelper {
9529 VarArgNoOpHelper(
Function &
F, MemorySanitizer &MS,
9530 MemorySanitizerVisitor &MSV) {}
9532 void visitCallBase(CallBase &CB,
IRBuilder<> &IRB)
override {}
9534 void visitVAStartInst(VAStartInst &
I)
override {}
9536 void visitVACopyInst(VACopyInst &
I)
override {}
9538 void finalizeInstrumentation()
override {}
9544 MemorySanitizerVisitor &Visitor) {
9547 Triple TargetTriple(Func.getParent()->getTargetTriple());
9550 return new VarArgI386Helper(Func, Msan, Visitor);
9553 return new VarArgAMD64Helper(Func, Msan, Visitor);
9555 if (TargetTriple.
isARM())
9556 return new VarArgARM32Helper(Func, Msan, Visitor, 4);
9559 return new VarArgAArch64Helper(Func, Msan, Visitor);
9562 return new VarArgSystemZHelper(Func, Msan, Visitor);
9567 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9570 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9573 return new VarArgRISCVHelper(Func, Msan, Visitor, 4);
9576 return new VarArgRISCVHelper(Func, Msan, Visitor, 8);
9579 return new VarArgMIPSHelper(Func, Msan, Visitor, 4);
9582 return new VarArgMIPSHelper(Func, Msan, Visitor, 8);
9585 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9589 return new VarArgHexagonHelper(Func, Msan, Visitor, 12);
9591 return new VarArgNoOpHelper(Func, Msan, Visitor);
9598 if (
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9601 MemorySanitizerVisitor Visitor(
F, *
this, TLI);
9608 return Visitor.runOnFunction();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isStore(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static const size_t kNumberOfAccessSizes
static cl::opt< bool > ClWithComdat("asan-with-comdat", cl::desc("Place ASan constructors in comdat sections"), cl::Hidden, cl::init(true))
VarLocInsertPt getNextNode(const DbgRecord *DVR)
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool insertModuleCtor(Module &M)
const MemoryMapParams Linux_LoongArch64_MemoryMapParams
const MemoryMapParams Linux_X86_64_MemoryMapParams
static cl::opt< int > ClTrackOrigins("dfsan-track-origins", cl::desc("Track origins of labels"), cl::Hidden, cl::init(0))
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_S390X_MemoryMapParams
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_AArch64_MemoryMapParams
static bool isAMustTailRetVal(Value *RetVal)
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
Module.h This file contains the declarations for the Module class.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
static const PlatformMemoryMapParams Linux_S390_MemoryMapParams
static const Align kMinOriginAlignment
static cl::opt< uint64_t > ClShadowBase("msan-shadow-base", cl::desc("Define custom MSan ShadowBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClPoisonUndef("msan-poison-undef", cl::desc("Poison fully undef temporary values. " "Partially undefined constant vectors " "are unaffected by this flag (see " "-msan-poison-undef-vectors)."), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_X86_MemoryMapParams
static cl::opt< uint64_t > ClOriginBase("msan-origin-base", cl::desc("Define custom MSan OriginBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClCheckConstantShadow("msan-check-constant-shadow", cl::desc("Insert checks for constant shadow values"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static const unsigned kOriginSize
static cl::opt< bool > ClWithComdat("msan-with-comdat", cl::desc("Place MSan constructors in comdat sections"), cl::Hidden, cl::init(false))
static cl::opt< int > ClTrackOrigins("msan-track-origins", cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden, cl::init(0))
Track origins of uninitialized values.
static cl::opt< int > ClInstrumentationWithCallThreshold("msan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented requires more than " "this number of checks and origin stores, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500))
static cl::opt< int > ClPoisonStackPattern("msan-poison-stack-pattern", cl::desc("poison uninitialized stack variables with the given pattern"), cl::Hidden, cl::init(0xff))
static const Align kShadowTLSAlignment
static cl::opt< bool > ClHandleICmpExact("msan-handle-icmp-exact", cl::desc("exact handling of relational integer ICmp"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static cl::opt< bool > ClDumpStrictInstructions("msan-dump-strict-instructions", cl::desc("print out instructions with default strict semantics i.e.," "check that all the inputs are fully initialized, and mark " "the output as fully initialized. These semantics are applied " "to instructions that could not be handled explicitly nor " "heuristically."), cl::Hidden, cl::init(false))
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static cl::opt< bool > ClPreciseDisjointOr("msan-precise-disjoint-or", cl::desc("Precisely poison disjoint OR. If false (legacy behavior), " "disjointedness is ignored (i.e., 1|1 is initialized)."), cl::Hidden, cl::init(false))
static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P
static cl::opt< bool > ClPoisonStack("msan-poison-stack", cl::desc("poison uninitialized stack variables"), cl::Hidden, cl::init(true))
static const MemoryMapParams Linux_I386_MemoryMapParams
const char kMsanInitName[]
static cl::opt< bool > ClPoisonUndefVectors("msan-poison-undef-vectors", cl::desc("Precisely poison partially undefined constant vectors. " "If false (legacy behavior), the entire vector is " "considered fully initialized, which may lead to false " "negatives. Fully undefined constant vectors are " "unaffected by this flag (see -msan-poison-undef)."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClPrintStackNames("msan-print-stack-names", cl::desc("Print name of local stack variable"), cl::Hidden, cl::init(true))
static cl::opt< uint64_t > ClAndMask("msan-and-mask", cl::desc("Define custom MSan AndMask"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClHandleLifetimeIntrinsics("msan-handle-lifetime-intrinsics", cl::desc("when possible, poison scoped variables at the beginning of the scope " "(slower, but more precise)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKeepGoing("msan-keep-going", cl::desc("keep going after reporting a UMR"), cl::Hidden, cl::init(false))
static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams
static GlobalVariable * createPrivateConstGlobalForString(Module &M, StringRef Str)
Create a non-const global initialized with the given string.
static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams
static const size_t kNumberOfAccessSizes
static cl::opt< bool > ClEagerChecks("msan-eager-checks", cl::desc("check arguments and return values at function call boundaries"), cl::Hidden, cl::init(false))
static cl::opt< int > ClDisambiguateWarning("msan-disambiguate-warning-threshold", cl::desc("Define threshold for number of checks per " "debug location to force origin update."), cl::Hidden, cl::init(3))
static VarArgHelper * CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, MemorySanitizerVisitor &Visitor)
static const MemoryMapParams Linux_MIPS64_MemoryMapParams
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
static cl::opt< int > ClSwitchPrecision("msan-switch-precision", cl::desc("Controls the number of cases considered by MSan for LLVM switch " "instructions. 0 means no UUMs detected. Higher values lead to " "fewer false negatives but may impact compiler and/or " "application performance. N.B. LLVM switch instructions do not " "correspond exactly to C++ switch statements."), cl::Hidden, cl::init(99))
static cl::opt< uint64_t > ClXorMask("msan-xor-mask", cl::desc("Define custom MSan XorMask"), cl::Hidden, cl::init(0))
static const MemoryMapParams Linux_Hexagon_MemoryMapParams
static cl::opt< bool > ClHandleAsmConservative("msan-handle-asm-conservative", cl::desc("conservative handling of inline assembly"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams
static const unsigned kParamTLSSize
static cl::opt< bool > ClHandleICmp("msan-handle-icmp", cl::desc("propagate shadow through ICmpEQ and ICmpNE"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClEnableKmsan("msan-kernel", cl::desc("Enable KernelMemorySanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClPoisonStackWithCall("msan-poison-stack-with-call", cl::desc("poison uninitialized stack variables with a call"), cl::Hidden, cl::init(false))
static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
static cl::opt< bool > ClDumpHeuristicInstructions("msan-dump-heuristic-instructions", cl::desc("Prints 'unknown' instructions that were handled heuristically. " "Use -msan-dump-strict-instructions to print instructions that " "could not be handled explicitly nor heuristically."), cl::Hidden, cl::init(false))
static const unsigned kRetvalTLSSize
static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams
const char kMsanModuleCtorName[]
static const MemoryMapParams FreeBSD_I386_MemoryMapParams
static cl::opt< bool > ClCheckAccessAddress("msan-check-access-address", cl::desc("report accesses through a pointer which has poisoned shadow"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClDisableChecks("msan-disable-checks", cl::desc("Apply no_sanitize to the whole file"), cl::Hidden, cl::init(false))
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
const SmallVectorImpl< MachineOperand > & Cond
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
void setAlignment(Align Align)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
const T & front() const
Get the first element.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
void removeFnAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the function.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Value * getCalledOperand() const
Type * getParamElementType(unsigned ArgNo) const
Extract the elementtype type for a parameter.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_SGT
signed greater than
@ ICMP_SGE
signed greater or equal
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true, bool ByteString=false)
This method constructs a CDS and initializes it with a text string.
static LLVM_ABI Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
static bool shouldExecute(CounterInfo &Counter)
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
static FixedVectorType * getHalfElementsVectorType(FixedVectorType *VTy)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
LLVM_ABI void setComdat(Comdat *C)
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ ExternalLinkage
Externally visible function.
Analysis pass providing a never-invalidated alias analysis result.
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
LLVM_ABI Value * CreateAndReduce(Value *Src)
Create a vector int AND reduction intrinsic of the source vector.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
LLVM_ABI CallInst * CreateMaskedCompressStore(Value *Val, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr)
Create a call to Masked Compress Store intrinsic.
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
LLVM_ABI Value * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI DebugLoc getCurrentDebugLocation() const
Get location information used by debugging information.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memset to the specified pointer and the specified value.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
LLVMContext & getContext() const
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
LLVM_ABI CallInst * CreateMaskedStore(Value *Val, Value *Ptr, Align Alignment, Value *Mask)
Create a call to Masked Store intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Type * getVoidTy()
Fetch the type representing void.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
LLVM_ABI CallInst * CreateMaskedExpandLoad(Type *Ty, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Expand Load intrinsic.
Value * CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name="")
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LLVM_ABI CallInst * CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment, Value *Mask=nullptr)
Create a call to Masked Scatter intrinsic.
LLVM_ABI CallInst * CreateMaskedGather(Type *Ty, Value *Ptrs, Align Alignment, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Gather intrinsic.
Value * CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
std::vector< ConstraintInfo > ConstraintInfoVector
void visit(Iterator Start, Iterator End)
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
A Module instance is used to store all the information related to an LLVM module.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
bool remove(const value_type &X)
Remove an item from the set vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
LibFunc getLibFunc(StringRef funcName) const
Searches for a particular function name.
Triple - Helper class for working with autoconf configuration names.
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
bool isRISCV32() const
Tests whether the target is 32-bit RISC-V.
bool isPPC32() const
Tests whether the target is 32-bit PowerPC (little and big endian).
ArchType getArch() const
Get the parsed architecture type of this triple.
bool isRISCV64() const
Tests whether the target is 64-bit RISC-V.
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
bool isARM() const
Tests whether the target is ARM (little and big endian).
bool isPPC64() const
Tests whether the target is 64-bit PowerPC (little and big endian).
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
bool isSystemZ() const
Tests whether the target is SystemZ.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isArrayTy() const
True if this is an instance of ArrayType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isPointerTy() const
True if this is an instance of PointerType.
Type * getArrayElementType() const
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
bool isVoidTy() const
Return true if this is 'void'.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
LLVM_ABI StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
initializer< Ty > init(const Ty &Val)
Function * Kernel
Summary of a kernel (=entry point for target offloading).
NodeAddr< FuncNode * > Func
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
RelativeUniformCounterPtr Values
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI std::pair< Instruction *, Value * > SplitBlockAndInsertSimpleForLoop(Value *End, BasicBlock::iterator SplitBefore)
Insert a for (int i = 0; i < End; i++) loop structure (with the exception that End is assumed > 0,...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool FoldInstsToUnreachable=true)
Remove all blocks that can not be reached from the function's entry.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function lazily.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
@ Or
Bitwise or logical OR of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
RoundingMode
Rounding mode.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
std::string itostr(int64_t X)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)