diff --git a/bindings/go/llvm/InstrumentationBindings.cpp b/bindings/go/llvm/InstrumentationBindings.cpp index 8b7bafa77ad..6ce43db620a 100644 --- a/bindings/go/llvm/InstrumentationBindings.cpp +++ b/bindings/go/llvm/InstrumentationBindings.cpp @@ -16,6 +16,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/MemorySanitizer.h" using namespace llvm; @@ -31,8 +32,8 @@ void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createThreadSanitizerPass()); } -void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createMemorySanitizerPass()); +void LLVMAddMemorySanitizerLegacyPassPass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createMemorySanitizerLegacyPassPass()); } void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, diff --git a/bindings/go/llvm/InstrumentationBindings.h b/bindings/go/llvm/InstrumentationBindings.h index 97af2d58c27..5d448fc76d7 100644 --- a/bindings/go/llvm/InstrumentationBindings.h +++ b/bindings/go/llvm/InstrumentationBindings.h @@ -27,7 +27,7 @@ extern "C" { void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM); void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM); void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM); -void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM); +void LLVMAddMemorySanitizerLegacyPassPass(LLVMPassManagerRef PM); void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, int ABIListFilesNum, const char **ABIListFiles); diff --git a/bindings/go/llvm/transforms_instrumentation.go b/bindings/go/llvm/transforms_instrumentation.go index 73e2732cbd9..73d093adad8 100644 --- a/bindings/go/llvm/transforms_instrumentation.go +++ b/bindings/go/llvm/transforms_instrumentation.go @@ -32,8 +32,8 @@ func (pm PassManager) AddThreadSanitizerPass() { C.LLVMAddThreadSanitizerPass(pm.C) } -func (pm PassManager) AddMemorySanitizerPass() { - C.LLVMAddMemorySanitizerPass(pm.C) +func (pm PassManager) AddMemorySanitizerLegacyPassPass() { + C.LLVMAddMemorySanitizerLegacyPassPass(pm.C) } func (pm PassManager) AddDataFlowSanitizerPass(abilist []string) { diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 206089cf3a8..4aa68888940 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -273,7 +273,7 @@ void initializeMemDerefPrinterPass(PassRegistry&); void initializeMemoryDependenceWrapperPassPass(PassRegistry&); void initializeMemorySSAPrinterLegacyPassPass(PassRegistry&); void initializeMemorySSAWrapperPassPass(PassRegistry&); -void initializeMemorySanitizerPass(PassRegistry&); +void initializeMemorySanitizerLegacyPassPass(PassRegistry&); void initializeMergeFunctionsPass(PassRegistry&); void initializeMergeICmpsPass(PassRegistry&); void initializeMergedLoadStoreMotionLegacyPassPass(PassRegistry&); diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 3624cd266af..34b52072012 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -152,11 +152,6 @@ ModulePass *createAddressSanitizerModulePass(bool CompileKernel = false, bool UseGlobalsGC = true, bool UseOdrIndicator = true); -// Insert MemorySanitizer instrumentation (detection of uninitialized reads) -FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0, - bool Recover = false, - bool EnableKmsan = false); - FunctionPass *createHWAddressSanitizerPass(bool CompileKernel = false, bool Recover = false); @@ -230,7 +225,6 @@ static inline uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale) { assert(Scaled <= std::numeric_limits::max() && "overflow 32-bits"); return Scaled; } - } // end namespace llvm #endif // LLVM_TRANSFORMS_INSTRUMENTATION_H diff --git a/include/llvm/Transforms/Instrumentation/MemorySanitizer.h b/include/llvm/Transforms/Instrumentation/MemorySanitizer.h new file mode 100644 index 00000000000..54f0e2f7823 --- /dev/null +++ b/include/llvm/Transforms/Instrumentation/MemorySanitizer.h @@ -0,0 +1,48 @@ +//===- Transforms/Instrumentation/MemorySanitizer.h - MSan Pass -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the memoy sanitizer pass. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_MEMORYSANITIZER_H +#define LLVM_TRANSFORMS_INSTRUMENTATION_MEMORYSANITIZER_H + +#include "llvm/IR/PassManager.h" +#include "llvm/Pass.h" + +namespace llvm { + +// Insert MemorySanitizer instrumentation (detection of uninitialized reads) +FunctionPass *createMemorySanitizerLegacyPassPass(int TrackOrigins = 0, + bool Recover = false, + bool EnableKmsan = false); + +/// A function pass for msan instrumentation. +/// +/// Instruments functions to detect unitialized reads. This function pass +/// inserts calls to runtime library functions. If the functions aren't declared +/// yet, the pass inserts the declarations. Otherwise the existing globals are +/// used. +struct MemorySanitizerPass : public PassInfoMixin { + MemorySanitizerPass(int TrackOrigins = 0, bool Recover = false, + bool EnableKmsan = false) + : TrackOrigins(TrackOrigins), Recover(Recover), EnableKmsan(EnableKmsan) { + } + + PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); + +private: + int TrackOrigins; + bool Recover; + bool EnableKmsan; +}; +} + +#endif /* LLVM_TRANSFORMS_INSTRUMENTATION_MEMORYSANITIZER_H */ diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h index 14615c25d09..f77b3b20a67 100644 --- a/include/llvm/Transforms/Utils/ModuleUtils.h +++ b/include/llvm/Transforms/Utils/ModuleUtils.h @@ -58,6 +58,11 @@ std::pair createSanitizerCtorAndInitFunctions( ArrayRef InitArgTypes, ArrayRef InitArgs, StringRef VersionCheckName = StringRef()); +// Creates and returns a sanitizer init function without argument if it doesn't +// exist, and adds it to the global constructors list. Otherwise it returns the +// existing function. +Function *getOrCreateInitFunction(Module &M, StringRef Name); + /// Rename all the anon globals in the module using a hash computed from /// the list of public globals in the module. bool nameUnamedGlobals(Module &M); diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index 4da8f549d9b..2f567262fbb 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -88,11 +88,13 @@ #include "llvm/Transforms/IPO/SyntheticCountsPropagation.h" #include "llvm/Transforms/IPO/WholeProgramDevirt.h" #include "llvm/Transforms/InstCombine/InstCombine.h" +#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/BoundsChecking.h" #include "llvm/Transforms/Instrumentation/CGProfile.h" #include "llvm/Transforms/Instrumentation/ControlHeightReduction.h" #include "llvm/Transforms/Instrumentation/GCOVProfiler.h" #include "llvm/Transforms/Instrumentation/InstrProfiling.h" +#include "llvm/Transforms/Instrumentation/MemorySanitizer.h" #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h" #include "llvm/Transforms/Scalar/ADCE.h" #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h" diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index 97f0d577b30..2d5fc2e99b1 100644 --- a/lib/Passes/PassRegistry.def +++ b/lib/Passes/PassRegistry.def @@ -231,6 +231,7 @@ FUNCTION_PASS("verify", RegionInfoVerifierPass()) FUNCTION_PASS("view-cfg", CFGViewerPass()) FUNCTION_PASS("view-cfg-only", CFGOnlyViewerPass()) FUNCTION_PASS("transform-warning", WarnMissedTransformationsPass()) +FUNCTION_PASS("msan", MemorySanitizerPass()) #undef FUNCTION_PASS #ifndef LOOP_ANALYSIS diff --git a/lib/Transforms/Instrumentation/Instrumentation.cpp b/lib/Transforms/Instrumentation/Instrumentation.cpp index eb6a3730ad9..5828019a03a 100644 --- a/lib/Transforms/Instrumentation/Instrumentation.cpp +++ b/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -111,7 +111,7 @@ void llvm::initializeInstrumentation(PassRegistry &Registry) { initializePGOIndirectCallPromotionLegacyPassPass(Registry); initializePGOMemOPSizeOptLegacyPassPass(Registry); initializeInstrProfilingLegacyPassPass(Registry); - initializeMemorySanitizerPass(Registry); + initializeMemorySanitizerLegacyPassPass(Registry); initializeHWAddressSanitizerPass(Registry); initializeThreadSanitizerPass(Registry); initializeSanitizerCoverageModulePass(Registry); diff --git a/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 1bac44c3801..493d22aa9fb 100644 --- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -140,6 +140,7 @@ /// //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Instrumentation/MemorySanitizer.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DepthFirstIterator.h" @@ -149,7 +150,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/IR/Argument.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" @@ -187,6 +187,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include #include @@ -320,7 +321,6 @@ static cl::opt ClOriginBase("msan-origin-base", cl::desc("Define custom MSan OriginBase"), cl::Hidden, cl::init(0)); -static const char *const kMsanModuleCtorName = "msan.module_ctor"; static const char *const kMsanInitName = "__msan_init"; namespace { @@ -446,19 +446,16 @@ static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams = { namespace { -/// An instrumentation pass implementing detection of uninitialized -/// reads. +/// Instrument functions of a module to detect uninitialized reads. /// -/// MemorySanitizer: instrument the code in module to find -/// uninitialized reads. -class MemorySanitizer : public FunctionPass { +/// Instantiating MemorySanitizer inserts the msan runtime library API function +/// declarations into the module if they don't exist already. Instantiating +/// ensures the __msan_init function is in the list of global constructors for +/// the module. +class MemorySanitizer { public: - // Pass identification, replacement for typeid. - static char ID; - - MemorySanitizer(int TrackOrigins = 0, bool Recover = false, - bool EnableKmsan = false) - : FunctionPass(ID) { + MemorySanitizer(Module &M, int TrackOrigins = 0, bool Recover = false, + bool EnableKmsan = false) { this->CompileKernel = ClEnableKmsan.getNumOccurrences() > 0 ? ClEnableKmsan : EnableKmsan; if (ClTrackOrigins.getNumOccurrences() > 0) @@ -468,15 +465,16 @@ public: this->Recover = ClKeepGoing.getNumOccurrences() > 0 ? ClKeepGoing : (this->CompileKernel | Recover); - } - StringRef getPassName() const override { return "MemorySanitizer"; } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + initializeModule(M); } - bool runOnFunction(Function &F) override; - bool doInitialization(Module &M) override; + // MSan cannot be moved or copied because of MapParams. + MemorySanitizer(MemorySanitizer &&) = delete; + MemorySanitizer &operator=(MemorySanitizer &&) = delete; + MemorySanitizer(const MemorySanitizer &) = delete; + MemorySanitizer &operator=(const MemorySanitizer &) = delete; + + bool sanitizeFunction(Function &F, TargetLibraryInfo &TLI); private: friend struct MemorySanitizerVisitor; @@ -485,13 +483,13 @@ private: friend struct VarArgAArch64Helper; friend struct VarArgPowerPC64Helper; + void initializeModule(Module &M); void initializeCallbacks(Module &M); void createKernelApi(Module &M); void createUserspaceApi(Module &M); /// True if we're compiling the Linux kernel. bool CompileKernel; - /// Track origins (allocation points) of uninitialized values. int TrackOrigins; bool Recover; @@ -588,25 +586,61 @@ private: /// An empty volatile inline asm that prevents callback merge. InlineAsm *EmptyAsm; +}; - Function *MsanCtorFunction; +/// A legacy function pass for msan instrumentation. +/// +/// Instruments functions to detect unitialized reads. +struct MemorySanitizerLegacyPass : public FunctionPass { + // Pass identification, replacement for typeid. + static char ID; + + MemorySanitizerLegacyPass(int TrackOrigins = 0, bool Recover = false, + bool EnableKmsan = false) + : FunctionPass(ID), TrackOrigins(TrackOrigins), Recover(Recover), + EnableKmsan(EnableKmsan) {} + StringRef getPassName() const override { return "MemorySanitizerLegacyPass"; } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); + } + + bool runOnFunction(Function &F) override { + return MSan->sanitizeFunction( + F, getAnalysis().getTLI()); + } + bool doInitialization(Module &M) override; + + Optional MSan; + int TrackOrigins; + bool Recover; + bool EnableKmsan; }; } // end anonymous namespace -char MemorySanitizer::ID = 0; +PreservedAnalyses MemorySanitizerPass::run(Function &F, + FunctionAnalysisManager &FAM) { + MemorySanitizer Msan(*F.getParent(), TrackOrigins, Recover, EnableKmsan); + if (Msan.sanitizeFunction(F, FAM.getResult(F))) + return PreservedAnalyses::none(); + return PreservedAnalyses::all(); +} -INITIALIZE_PASS_BEGIN( - MemorySanitizer, "msan", - "MemorySanitizer: detects uninitialized reads.", false, false) +char MemorySanitizerLegacyPass::ID = 0; + +INITIALIZE_PASS_BEGIN(MemorySanitizerLegacyPass, "msan", + "MemorySanitizer: detects uninitialized reads.", false, + false) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_END( - MemorySanitizer, "msan", - "MemorySanitizer: detects uninitialized reads.", false, false) +INITIALIZE_PASS_END(MemorySanitizerLegacyPass, "msan", + "MemorySanitizer: detects uninitialized reads.", false, + false) -FunctionPass *llvm::createMemorySanitizerPass(int TrackOrigins, bool Recover, - bool CompileKernel) { - return new MemorySanitizer(TrackOrigins, Recover, CompileKernel); +FunctionPass *llvm::createMemorySanitizerLegacyPassPass(int TrackOrigins, + bool Recover, + bool CompileKernel) { + return new MemorySanitizerLegacyPass(TrackOrigins, Recover, CompileKernel); } /// Create a non-const global initialized with the given string. @@ -683,6 +717,14 @@ void MemorySanitizer::createKernelApi(Module &M) { "__msan_unpoison_alloca", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy); } +static Constant *getOrInsertGlobal(Module &M, StringRef Name, Type *Ty) { + return M.getOrInsertGlobal(Name, Ty, [&] { + return new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, + nullptr, Name, nullptr, + GlobalVariable::InitialExecTLSModel); + }); +} + /// Insert declarations for userspace-specific functions and globals. void MemorySanitizer::createUserspaceApi(Module &M) { IRBuilder<> IRB(*C); @@ -694,42 +736,31 @@ void MemorySanitizer::createUserspaceApi(Module &M) { WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy()); // Create the global TLS variables. - RetvalTLS = new GlobalVariable( - M, ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8), false, - GlobalVariable::ExternalLinkage, nullptr, "__msan_retval_tls", nullptr, - GlobalVariable::InitialExecTLSModel); + RetvalTLS = + getOrInsertGlobal(M, "__msan_retval_tls", + ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8)); - RetvalOriginTLS = new GlobalVariable( - M, OriginTy, false, GlobalVariable::ExternalLinkage, nullptr, - "__msan_retval_origin_tls", nullptr, GlobalVariable::InitialExecTLSModel); + RetvalOriginTLS = getOrInsertGlobal(M, "__msan_retval_origin_tls", OriginTy); - ParamTLS = new GlobalVariable( - M, ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), false, - GlobalVariable::ExternalLinkage, nullptr, "__msan_param_tls", nullptr, - GlobalVariable::InitialExecTLSModel); + ParamTLS = + getOrInsertGlobal(M, "__msan_param_tls", + ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8)); - ParamOriginTLS = new GlobalVariable( - M, ArrayType::get(OriginTy, kParamTLSSize / 4), false, - GlobalVariable::ExternalLinkage, nullptr, "__msan_param_origin_tls", - nullptr, GlobalVariable::InitialExecTLSModel); + ParamOriginTLS = + getOrInsertGlobal(M, "__msan_param_origin_tls", + ArrayType::get(OriginTy, kParamTLSSize / 4)); - VAArgTLS = new GlobalVariable( - M, ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), false, - GlobalVariable::ExternalLinkage, nullptr, "__msan_va_arg_tls", nullptr, - GlobalVariable::InitialExecTLSModel); + VAArgTLS = + getOrInsertGlobal(M, "__msan_va_arg_tls", + ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8)); - VAArgOriginTLS = new GlobalVariable( - M, ArrayType::get(OriginTy, kParamTLSSize / 4), false, - GlobalVariable::ExternalLinkage, nullptr, "__msan_va_arg_origin_tls", - nullptr, GlobalVariable::InitialExecTLSModel); + VAArgOriginTLS = + getOrInsertGlobal(M, "__msan_va_arg_origin_tls", + ArrayType::get(OriginTy, kParamTLSSize / 4)); - VAArgOverflowSizeTLS = new GlobalVariable( - M, IRB.getInt64Ty(), false, GlobalVariable::ExternalLinkage, nullptr, - "__msan_va_arg_overflow_size_tls", nullptr, - GlobalVariable::InitialExecTLSModel); - OriginTLS = new GlobalVariable( - M, IRB.getInt32Ty(), false, GlobalVariable::ExternalLinkage, nullptr, - "__msan_origin_tls", nullptr, GlobalVariable::InitialExecTLSModel); + VAArgOverflowSizeTLS = + getOrInsertGlobal(M, "__msan_va_arg_overflow_size_tls", IRB.getInt64Ty()); + OriginTLS = getOrInsertGlobal(M, "__msan_origin_tls", IRB.getInt32Ty()); for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; AccessSizeIndex++) { @@ -808,9 +839,7 @@ Value *MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore, int size) { } /// Module-level initialization. -/// -/// inserts a call to __msan_init to the module's constructor list. -bool MemorySanitizer::doInitialization(Module &M) { +void MemorySanitizer::initializeModule(Module &M) { auto &DL = M.getDataLayout(); bool ShadowPassed = ClShadowBase.getNumOccurrences() > 0; @@ -884,27 +913,26 @@ bool MemorySanitizer::doInitialization(Module &M) { OriginStoreWeights = MDBuilder(*C).createBranchWeights(1, 1000); if (!CompileKernel) { - std::tie(MsanCtorFunction, std::ignore) = - createSanitizerCtorAndInitFunctions(M, kMsanModuleCtorName, - kMsanInitName, - /*InitArgTypes=*/{}, - /*InitArgs=*/{}); - if (ClWithComdat) { - Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName); - MsanCtorFunction->setComdat(MsanCtorComdat); - appendToGlobalCtors(M, MsanCtorFunction, 0, MsanCtorFunction); - } else { - appendToGlobalCtors(M, MsanCtorFunction, 0); - } + getOrCreateInitFunction(M, kMsanInitName); if (TrackOrigins) - new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage, - IRB.getInt32(TrackOrigins), "__msan_track_origins"); + M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] { + return new GlobalVariable( + M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage, + IRB.getInt32(TrackOrigins), "__msan_track_origins"); + }); if (Recover) - new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage, - IRB.getInt32(Recover), "__msan_keep_going"); - } + M.getOrInsertGlobal("__msan_keep_going", IRB.getInt32Ty(), [&] { + return new GlobalVariable(M, IRB.getInt32Ty(), true, + GlobalValue::WeakODRLinkage, + IRB.getInt32(Recover), "__msan_keep_going"); + }); +} +} + +bool MemorySanitizerLegacyPass::doInitialization(Module &M) { + MSan.emplace(M, TrackOrigins, Recover, EnableKmsan); return true; } @@ -985,8 +1013,9 @@ struct MemorySanitizerVisitor : public InstVisitor { SmallVector InstrumentationList; SmallVector StoreList; - MemorySanitizerVisitor(Function &F, MemorySanitizer &MS) - : F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)) { + MemorySanitizerVisitor(Function &F, MemorySanitizer &MS, + const TargetLibraryInfo &TLI) + : F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)), TLI(&TLI) { bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeMemory); InsertChecks = SanitizeFunction; PropagateShadow = SanitizeFunction; @@ -995,7 +1024,6 @@ struct MemorySanitizerVisitor : public InstVisitor { // FIXME: Consider using SpecialCaseList to specify a list of functions that // must always return fully initialized values. For now, we hardcode "main". CheckReturnValue = SanitizeFunction && (F.getName() == "main"); - TLI = &MS.getAnalysis().getTLI(); MS.initializeCallbacks(*F.getParent()); if (MS.CompileKernel) @@ -4430,10 +4458,8 @@ static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, return new VarArgNoOpHelper(Func, Msan, Visitor); } -bool MemorySanitizer::runOnFunction(Function &F) { - if (!CompileKernel && (&F == MsanCtorFunction)) - return false; - MemorySanitizerVisitor Visitor(F, *this); +bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) { + MemorySanitizerVisitor Visitor(F, *this, TLI); // Clear out readonly/readnone attributes. AttrBuilder B; diff --git a/lib/Transforms/Utils/ModuleUtils.cpp b/lib/Transforms/Utils/ModuleUtils.cpp index ba4b7f3cc26..8040cc7d09c 100644 --- a/lib/Transforms/Utils/ModuleUtils.cpp +++ b/lib/Transforms/Utils/ModuleUtils.cpp @@ -174,6 +174,27 @@ std::pair llvm::createSanitizerCtorAndInitFunctions( return std::make_pair(Ctor, InitFunction); } +Function *llvm::getOrCreateInitFunction(Module &M, StringRef Name) { + assert(!Name.empty() && "Expected init function name"); + if (Function *F = M.getFunction(Name)) { + if (F->arg_size() != 0 || + F->getReturnType() != Type::getVoidTy(M.getContext())) { + std::string Err; + raw_string_ostream Stream(Err); + Stream << "Sanitizer interface function defined with wrong type: " << *F; + report_fatal_error(Err); + } + return F; + } + Function *F = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + Name, AttributeList(), Type::getVoidTy(M.getContext()))); + F->setLinkage(Function::ExternalLinkage); + + appendToGlobalCtors(M, F, 0); + + return F; +} + void llvm::filterDeadComdatFunctions( Module &M, SmallVectorImpl &DeadComdatFunctions) { // Build a map from the comdat to the number of entries in that comdat we diff --git a/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll b/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll index 08387f8d1e9..2f401b0eb8c 100644 --- a/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll +++ b/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll @@ -1,3 +1,4 @@ +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -S | FileCheck %s target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64.ll b/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64.ll index 1463070ad85..03d1fda5eda 100644 --- a/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64.ll +++ b/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64.ll @@ -1,3 +1,4 @@ +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -S | FileCheck %s target datalayout = "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64el.ll b/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64el.ll index 9edcb3666f2..98b1d821102 100644 --- a/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64el.ll +++ b/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64el.ll @@ -1,3 +1,4 @@ +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -S | FileCheck %s target datalayout = "e-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64.ll b/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64.ll index 5a2686900e9..9e74752bcd5 100644 --- a/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64.ll +++ b/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64.ll @@ -1,3 +1,4 @@ +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -S | FileCheck %s target datalayout = "E-m:e-i64:64-n32:64" diff --git a/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64le.ll b/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64le.ll index c139d62c4f2..9d6c43657ed 100644 --- a/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64le.ll +++ b/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64le.ll @@ -1,3 +1,4 @@ +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -S | FileCheck %s target datalayout = "e-m:e-i64:64-n32:64" diff --git a/test/Instrumentation/MemorySanitizer/X86/vararg-too-large.ll b/test/Instrumentation/MemorySanitizer/X86/vararg-too-large.ll index 800bd15f124..cd113a03059 100644 --- a/test/Instrumentation/MemorySanitizer/X86/vararg-too-large.ll +++ b/test/Instrumentation/MemorySanitizer/X86/vararg-too-large.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -S 2>&1 -passes=msan | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S 2>&1 | FileCheck %s ; Test that MSan doesn't generate code overflowing __msan_va_arg_tls when too many arguments are diff --git a/test/Instrumentation/MemorySanitizer/X86/vararg.ll b/test/Instrumentation/MemorySanitizer/X86/vararg.ll index 518c3dbf41d..f384d8fbd90 100644 --- a/test/Instrumentation/MemorySanitizer/X86/vararg.ll +++ b/test/Instrumentation/MemorySanitizer/X86/vararg.ll @@ -1,3 +1,4 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 ; RUN: opt < %s -msan -msan-check-access-address=0 -S ; Test that code using va_start can be compiled on i386. diff --git a/test/Instrumentation/MemorySanitizer/X86/vararg_call.ll b/test/Instrumentation/MemorySanitizer/X86/vararg_call.ll index 3d036d7d853..2836dd2fc4e 100644 --- a/test/Instrumentation/MemorySanitizer/X86/vararg_call.ll +++ b/test/Instrumentation/MemorySanitizer/X86/vararg_call.ll @@ -1,5 +1,11 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,CHECK-ORIGIN" ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK-ORIGIN +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=2 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,CHECK-ORIGIN" ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck %s --check-prefixes=CHECK,CHECK-ORIGIN ; Test that shadow and origin are stored for variadic function params. diff --git a/test/Instrumentation/MemorySanitizer/alloca.ll b/test/Instrumentation/MemorySanitizer/alloca.ll index d1d3bc55a2b..1d28db8b58e 100644 --- a/test/Instrumentation/MemorySanitizer/alloca.ll +++ b/test/Instrumentation/MemorySanitizer/alloca.ll @@ -1,7 +1,17 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s "--check-prefixes=CHECK,INLINE" ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s --check-prefixes=CHECK,INLINE +; RUN: opt < %s -msan-check-access-address=0 -msan-poison-stack-with-call=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,CALL" ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-poison-stack-with-call=1 -S | FileCheck %s --check-prefixes=CHECK,CALL +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,ORIGIN" ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,ORIGIN +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=2 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,ORIGIN" ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck %s --check-prefixes=CHECK,ORIGIN +; RUN: opt < %s -msan-kernel=1 -S -passes=msan 2>&1 | FileCheck %s \ +; RUN: "--check-prefixes=CHECK,KMSAN" ; RUN: opt < %s -msan -msan-kernel=1 -S | FileCheck %s --check-prefixes=CHECK,KMSAN target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/array_types.ll b/test/Instrumentation/MemorySanitizer/array_types.ll index e96716aaa97..d322354188d 100644 --- a/test/Instrumentation/MemorySanitizer/array_types.ll +++ b/test/Instrumentation/MemorySanitizer/array_types.ll @@ -1,4 +1,9 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck -check-prefix=CHECK \ +; RUN: -check-prefix=CHECK-ORIGINS %s --allow-empty ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/atomics.ll b/test/Instrumentation/MemorySanitizer/atomics.ll index 8033ed1e2d4..56f12a1fe6b 100644 --- a/test/Instrumentation/MemorySanitizer/atomics.ll +++ b/test/Instrumentation/MemorySanitizer/atomics.ll @@ -1,5 +1,11 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=2 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/byval-alignment.ll b/test/Instrumentation/MemorySanitizer/byval-alignment.ll index df82a92f743..0d5da362f34 100644 --- a/test/Instrumentation/MemorySanitizer/byval-alignment.ll +++ b/test/Instrumentation/MemorySanitizer/byval-alignment.ll @@ -1,5 +1,7 @@ ; Test that copy alignment for byval arguments is limited by param-tls slot alignment. +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll b/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll index f1479440faf..101107543a6 100644 --- a/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll +++ b/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -msan-check-constant-shadow=1 \ +; RUN: -msan-track-origins=1 -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-check-constant-shadow=1 -msan-track-origins=1 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/check_access_address.ll b/test/Instrumentation/MemorySanitizer/check_access_address.ll index 21bb4125606..8c245fed50c 100644 --- a/test/Instrumentation/MemorySanitizer/check_access_address.ll +++ b/test/Instrumentation/MemorySanitizer/check_access_address.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=1 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=1 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/csr.ll b/test/Instrumentation/MemorySanitizer/csr.ll index a7664d45636..f91888a4335 100644 --- a/test/Instrumentation/MemorySanitizer/csr.ll +++ b/test/Instrumentation/MemorySanitizer/csr.ll @@ -1,4 +1,8 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s +; RUN: opt < %s -msan-check-access-address=1 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s --check-prefix=ADDR ; RUN: opt < %s -msan -msan-check-access-address=1 -S | FileCheck %s --check-prefix=ADDR ; REQUIRES: x86-registered-target diff --git a/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll b/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll deleted file mode 100644 index 8e0ab268301..00000000000 --- a/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll +++ /dev/null @@ -1,17 +0,0 @@ -; MSan converts 2-element global_ctors to 3-element when adding the new entry. -; RUN: opt < %s -msan -msan-with-comdat -S | FileCheck %s - -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -; CHECK: $msan.module_ctor = comdat any -; CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* null }, { i32, void ()*, i8* } { i32 0, void ()* @msan.module_ctor, i8* bitcast (void ()* @msan.module_ctor to i8*) }] - -@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }] - -define internal void @f() { -entry: - ret void -} - -; CHECK: define internal void @msan.module_ctor() comdat { diff --git a/test/Instrumentation/MemorySanitizer/instrumentation-with-call-threshold.ll b/test/Instrumentation/MemorySanitizer/instrumentation-with-call-threshold.ll index 855125a88de..424a5e05ffe 100644 --- a/test/Instrumentation/MemorySanitizer/instrumentation-with-call-threshold.ll +++ b/test/Instrumentation/MemorySanitizer/instrumentation-with-call-threshold.ll @@ -2,8 +2,19 @@ ; Test that in with-calls mode there are no calls to __msan_chain_origin - they ; are done from __msan_maybe_store_origin_*. +; RUN: opt < %s -msan-check-access-address=0 \ +; RUN: -msan-instrumentation-with-call-threshold=0 -S -passes=msan 2>&1 | \ +; RUN: FileCheck %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-instrumentation-with-call-threshold=0 -S | FileCheck %s +; RUN: opt < %s -msan-check-access-address=0 \ +; RUN: -msan-instrumentation-with-call-threshold=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck -check-prefix=CHECK \ +; RUN: -check-prefix=CHECK-ORIGINS %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-instrumentation-with-call-threshold=0 -msan-track-origins=1 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS %s +; RUN: opt < %s -msan-check-access-address=0 \ +; RUN: -msan-instrumentation-with-call-threshold=0 -msan-track-origins=2 -S \ +; RUN: -passes=msan 2>&1 | FileCheck -check-prefix=CHECK \ +; RUN: -check-prefix=CHECK-ORIGINS %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-instrumentation-with-call-threshold=0 -msan-track-origins=2 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/manual-shadow.ll b/test/Instrumentation/MemorySanitizer/manual-shadow.ll index f4664cba37e..ab19f3d9b78 100644 --- a/test/Instrumentation/MemorySanitizer/manual-shadow.ll +++ b/test/Instrumentation/MemorySanitizer/manual-shadow.ll @@ -1,9 +1,20 @@ ; Test that the msan layout customization options work as expected ; +; RUN: opt < %s -msan-shadow-base 3735928559 -S -passes=msan 2>&1 | FileCheck \ +; RUN: --check-prefix=CHECK-BASE %s ; RUN: opt < %s -msan -msan-shadow-base 3735928559 -S | FileCheck --check-prefix=CHECK-BASE %s +; RUN: opt < %s -msan-shadow-base 3735928559 -msan-and-mask 4294901760 -S \ +; RUN: -passes=msan 2>&1 | FileCheck --check-prefix=CHECK-AND %s ; RUN: opt < %s -msan -msan-shadow-base 3735928559 -msan-and-mask 4294901760 -S | FileCheck --check-prefix=CHECK-AND %s +; RUN: opt < %s -msan-shadow-base 3735928559 -msan-xor-mask 48879 -S \ +; RUN: -passes=msan 2>&1 | FileCheck --check-prefix=CHECK-XOR %s ; RUN: opt < %s -msan -msan-shadow-base 3735928559 -msan-xor-mask 48879 -S | FileCheck --check-prefix=CHECK-XOR %s +; RUN: opt < %s -msan-shadow-base 3735928559 -msan-xor-mask 48879 \ +; RUN: -msan-and-mask 4294901760 -S -passes=msan 2>&1 | FileCheck \ +; RUN: --check-prefix=CHECK-XOR-AND %s ; RUN: opt < %s -msan -msan-shadow-base 3735928559 -msan-xor-mask 48879 -msan-and-mask 4294901760 -S | FileCheck --check-prefix=CHECK-XOR-AND %s +; RUN: opt < %s -msan-track-origins 1 -msan-origin-base 1777777 -S -passes=msan\ +; RUN: 2>&1 | FileCheck --check-prefix=CHECK-ORIGIN-BASE %s ; RUN: opt < %s -msan -msan-track-origins 1 -msan-origin-base 1777777 -S | FileCheck --check-prefix=CHECK-ORIGIN-BASE %s target triple = "x86_64-unknown-linux-gnu" diff --git a/test/Instrumentation/MemorySanitizer/masked-store-load.ll b/test/Instrumentation/MemorySanitizer/masked-store-load.ll index 9391c9f8f26..226f66515b6 100644 --- a/test/Instrumentation/MemorySanitizer/masked-store-load.ll +++ b/test/Instrumentation/MemorySanitizer/masked-store-load.ll @@ -1,5 +1,11 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,CHECK-ORIGIN" ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK-ORIGIN +; RUN: opt < %s -msan-check-access-address=1 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s --check-prefix=ADDR ; RUN: opt < %s -msan -msan-check-access-address=1 -S | FileCheck %s --check-prefix=ADDR target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/missing_origin.ll b/test/Instrumentation/MemorySanitizer/missing_origin.ll index 0a18914d42a..f529098627a 100644 --- a/test/Instrumentation/MemorySanitizer/missing_origin.ll +++ b/test/Instrumentation/MemorySanitizer/missing_origin.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll b/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll index 9bcd2f7c42f..c338d049206 100644 --- a/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll +++ b/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll @@ -1,5 +1,11 @@ ; Test for handling of asm constraints in MSan instrumentation. +; RUN: opt < %s -msan-kernel=1 -msan-check-access-address=0 \ +; RUN: -msan-handle-asm-conservative=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: "-check-prefixes=CHECK,CHECK-NONCONS" %s ; RUN: opt < %s -msan -msan-kernel=1 -msan-check-access-address=0 -msan-handle-asm-conservative=0 -S | FileCheck -check-prefixes=CHECK,CHECK-NONCONS %s +; RUN: opt < %s -msan-kernel=1 -msan-check-access-address=0 \ +; RUN: -msan-handle-asm-conservative=1 -S -passes=msan 2>&1 | FileCheck \ +; RUN: "-check-prefixes=CHECK,CHECK-CONS" %s ; RUN: opt < %s -msan -msan-kernel=1 -msan-check-access-address=0 -msan-handle-asm-conservative=1 -S | FileCheck -check-prefixes=CHECK,CHECK-CONS %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/msan_basic.ll b/test/Instrumentation/MemorySanitizer/msan_basic.ll index 78d31dc3434..f4cbc637ef1 100644 --- a/test/Instrumentation/MemorySanitizer/msan_basic.ll +++ b/test/Instrumentation/MemorySanitizer/msan_basic.ll @@ -1,10 +1,15 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: -allow-deprecated-dag-overlap %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck -allow-deprecated-dag-overlap %s +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck -allow-deprecated-dag-overlap \ +; RUN: -check-prefix=CHECK -check-prefix=CHECK-ORIGINS %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -allow-deprecated-dag-overlap -check-prefix=CHECK -check-prefix=CHECK-ORIGINS %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" -; CHECK: @llvm.global_ctors {{.*}} { i32 0, void ()* @msan.module_ctor, i8* null } +; CHECK: @llvm.global_ctors {{.*}} { i32 0, void ()* @__msan_init, i8* null } ; Check the presence and the linkage type of __msan_track_origins and ; other interface symbols. @@ -986,5 +991,4 @@ define i8* @MismatchingCallMustTailCall(i32 %a) sanitize_memory { ; CHECK-NEXT: ret i8* -; CHECK-LABEL: define internal void @msan.module_ctor() { -; CHECK: call void @__msan_init() +; CHECK: declare void @__msan_init() diff --git a/test/Instrumentation/MemorySanitizer/msan_kernel_basic.ll b/test/Instrumentation/MemorySanitizer/msan_kernel_basic.ll index 28bbf3cd708..680a672d12a 100644 --- a/test/Instrumentation/MemorySanitizer/msan_kernel_basic.ll +++ b/test/Instrumentation/MemorySanitizer/msan_kernel_basic.ll @@ -1,4 +1,6 @@ ; KMSAN instrumentation tests +; RUN: opt < %s -msan-kernel=1 -S -passes=msan 2>&1 | FileCheck %s \ +; RUN: -check-prefixes=CHECK ; RUN: opt < %s -msan -msan-kernel=1 -S | FileCheck %s -check-prefixes=CHECK target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll b/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll index c9e6f1afe21..1c0072f5cea 100644 --- a/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll +++ b/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll @@ -1,5 +1,11 @@ ; Test for the conservative assembly handling mode used by KMSAN. +; RUN: opt < %s -msan-kernel=1 -msan-check-access-address=0 \ +; RUN: -msan-handle-asm-conservative=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: "-check-prefixes=CHECK,CHECK-NONCONS" %s ; RUN: opt < %s -msan -msan-kernel=1 -msan-check-access-address=0 -msan-handle-asm-conservative=0 -S | FileCheck -check-prefixes=CHECK,CHECK-NONCONS %s +; RUN: opt < %s -msan-kernel=1 -msan-check-access-address=0 \ +; RUN: -msan-handle-asm-conservative=1 -S -passes=msan 2>&1 | FileCheck \ +; RUN: "-check-prefixes=CHECK,CHECK-CONS" %s ; RUN: opt < %s -msan -msan-kernel=1 -msan-check-access-address=0 -msan-handle-asm-conservative=1 -S | FileCheck -check-prefixes=CHECK,CHECK-CONS %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/msan_x86intrinsics.ll b/test/Instrumentation/MemorySanitizer/msan_x86intrinsics.ll index 14aaec92388..c5bdc2aee5d 100644 --- a/test/Instrumentation/MemorySanitizer/msan_x86intrinsics.ll +++ b/test/Instrumentation/MemorySanitizer/msan_x86intrinsics.ll @@ -1,4 +1,9 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck -check-prefix=CHECK \ +; RUN: -check-prefix=CHECK-ORIGINS %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS %s ; REQUIRES: x86-registered-target diff --git a/test/Instrumentation/MemorySanitizer/mul_by_constant.ll b/test/Instrumentation/MemorySanitizer/mul_by_constant.ll index 7736d94717f..959f0195dc5 100644 --- a/test/Instrumentation/MemorySanitizer/mul_by_constant.ll +++ b/test/Instrumentation/MemorySanitizer/mul_by_constant.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/nosanitize.ll b/test/Instrumentation/MemorySanitizer/nosanitize.ll index 082a6f580e5..d68be085180 100644 --- a/test/Instrumentation/MemorySanitizer/nosanitize.ll +++ b/test/Instrumentation/MemorySanitizer/nosanitize.ll @@ -1,5 +1,7 @@ ; Verify that calls with !nosanitize are not instrumented by MSan. +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -S | FileCheck %s +; RUN: opt < %s -msan-track-origins=1 -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -msan-track-origins=1 -S | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test/Instrumentation/MemorySanitizer/origin-alignment.ll b/test/Instrumentation/MemorySanitizer/origin-alignment.ll index abd8dd0e533..c2afe794c8c 100644 --- a/test/Instrumentation/MemorySanitizer/origin-alignment.ll +++ b/test/Instrumentation/MemorySanitizer/origin-alignment.ll @@ -1,4 +1,10 @@ +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck -check-prefix=CHECK \ +; RUN: -check-prefix=CHECK-ORIGINS1 %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS1 %s +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=2 -S \ +; RUN: -passes=msan 2>&1 | FileCheck -check-prefix=CHECK \ +; RUN: -check-prefix=CHECK-ORIGINS2 %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS2 %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/origin-array.ll b/test/Instrumentation/MemorySanitizer/origin-array.ll index d9936ff8e78..0a647872c0f 100644 --- a/test/Instrumentation/MemorySanitizer/origin-array.ll +++ b/test/Instrumentation/MemorySanitizer/origin-array.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=2 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck %s target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/pr32842.ll b/test/Instrumentation/MemorySanitizer/pr32842.ll index 5d74c9a193b..c342f16bd37 100644 --- a/test/Instrumentation/MemorySanitizer/pr32842.ll +++ b/test/Instrumentation/MemorySanitizer/pr32842.ll @@ -1,5 +1,6 @@ ; Regression test for https://bugs.llvm.org/show_bug.cgi?id=32842 ; +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -S | FileCheck %s ;target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test/Instrumentation/MemorySanitizer/return_from_main.ll b/test/Instrumentation/MemorySanitizer/return_from_main.ll index 82e2d13bc09..0e5d3400de3 100644 --- a/test/Instrumentation/MemorySanitizer/return_from_main.ll +++ b/test/Instrumentation/MemorySanitizer/return_from_main.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test/Instrumentation/MemorySanitizer/store-long-origin.ll b/test/Instrumentation/MemorySanitizer/store-long-origin.ll index 23ba4a18e6b..f8973fc814a 100644 --- a/test/Instrumentation/MemorySanitizer/store-long-origin.ll +++ b/test/Instrumentation/MemorySanitizer/store-long-origin.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/store-origin.ll b/test/Instrumentation/MemorySanitizer/store-origin.ll index 70722c63f29..9a0c01936e7 100644 --- a/test/Instrumentation/MemorySanitizer/store-origin.ll +++ b/test/Instrumentation/MemorySanitizer/store-origin.ll @@ -1,5 +1,13 @@ +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \ +; RUN: -passes=msan 2>&1 | FileCheck \ +; RUN: "-check-prefixes=CHECK,CHECK-MSAN,CHECK-ORIGINS1" %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -check-prefixes=CHECK,CHECK-MSAN,CHECK-ORIGINS1 %s +; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=2 -S \ +; RUN: -passes=msan 2>&1 | FileCheck \ +; RUN: "-check-prefixes=CHECK,CHECK-MSAN,CHECK-ORIGINS2" %s ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck -check-prefixes=CHECK,CHECK-MSAN,CHECK-ORIGINS2 %s +; RUN: opt < %s -msan-kernel=1 -msan-check-access-address=0 -S -passes=msan \ +; RUN: 2>&1 | FileCheck "-check-prefixes=CHECK,CHECK-KMSAN,CHECK-ORIGINS2" %s ; RUN: opt < %s -msan -msan-kernel=1 -msan-check-access-address=0 -S | FileCheck -check-prefixes=CHECK,CHECK-KMSAN,CHECK-ORIGINS2 %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/str-nobuiltin.ll b/test/Instrumentation/MemorySanitizer/str-nobuiltin.ll index 0aa196782ca..96223cd0818 100644 --- a/test/Instrumentation/MemorySanitizer/str-nobuiltin.ll +++ b/test/Instrumentation/MemorySanitizer/str-nobuiltin.ll @@ -1,5 +1,6 @@ ; Test marking string functions as nobuiltin in memory sanitizer. ; +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-unknown-linux-gnu" diff --git a/test/Instrumentation/MemorySanitizer/unreachable.ll b/test/Instrumentation/MemorySanitizer/unreachable.ll index ac5aea9a077..eff7371e123 100644 --- a/test/Instrumentation/MemorySanitizer/unreachable.ll +++ b/test/Instrumentation/MemorySanitizer/unreachable.ll @@ -1,3 +1,4 @@ +; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s ; RUN: opt < %s -msan -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test/Instrumentation/MemorySanitizer/unsized_type.ll b/test/Instrumentation/MemorySanitizer/unsized_type.ll index 94ae92d3354..4bffe808d3a 100644 --- a/test/Instrumentation/MemorySanitizer/unsized_type.ll +++ b/test/Instrumentation/MemorySanitizer/unsized_type.ll @@ -1,5 +1,6 @@ ; Check that unsized token types used by coroutine intrinsics do not cause ; assertion failures. +; RUN: opt < %s -S 2>&1 -passes=msan | FileCheck %s ; RUN: opt < %s -msan -S 2>&1 | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/test/Instrumentation/MemorySanitizer/vector_arith.ll b/test/Instrumentation/MemorySanitizer/vector_arith.ll index 6652fdff89b..4b213d17ee4 100644 --- a/test/Instrumentation/MemorySanitizer/vector_arith.ll +++ b/test/Instrumentation/MemorySanitizer/vector_arith.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s ; REQUIRES: x86-registered-target diff --git a/test/Instrumentation/MemorySanitizer/vector_cmp.ll b/test/Instrumentation/MemorySanitizer/vector_cmp.ll index 910b1351330..6031dddccc4 100644 --- a/test/Instrumentation/MemorySanitizer/vector_cmp.ll +++ b/test/Instrumentation/MemorySanitizer/vector_cmp.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s ; REQUIRES: x86-registered-target diff --git a/test/Instrumentation/MemorySanitizer/vector_cvt.ll b/test/Instrumentation/MemorySanitizer/vector_cvt.ll index b70ef7d6254..abbb0a8c981 100644 --- a/test/Instrumentation/MemorySanitizer/vector_cvt.ll +++ b/test/Instrumentation/MemorySanitizer/vector_cvt.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s ; REQUIRES: x86-registered-target diff --git a/test/Instrumentation/MemorySanitizer/vector_pack.ll b/test/Instrumentation/MemorySanitizer/vector_pack.ll index 574e7b89003..50d9303f4e9 100644 --- a/test/Instrumentation/MemorySanitizer/vector_pack.ll +++ b/test/Instrumentation/MemorySanitizer/vector_pack.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s ; REQUIRES: x86-registered-target diff --git a/test/Instrumentation/MemorySanitizer/vector_shift.ll b/test/Instrumentation/MemorySanitizer/vector_shift.ll index c605c97bba1..9f74869c656 100644 --- a/test/Instrumentation/MemorySanitizer/vector_shift.ll +++ b/test/Instrumentation/MemorySanitizer/vector_shift.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \ +; RUN: %s ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s ; REQUIRES: x86-registered-target diff --git a/test/Instrumentation/MemorySanitizer/with-call-type-size.ll b/test/Instrumentation/MemorySanitizer/with-call-type-size.ll index 2a3cbf70ea5..da5e75b9d2b 100644 --- a/test/Instrumentation/MemorySanitizer/with-call-type-size.ll +++ b/test/Instrumentation/MemorySanitizer/with-call-type-size.ll @@ -1,3 +1,5 @@ +; RUN: opt < %s -msan-instrumentation-with-call-threshold=0 -S -passes=msan \ +; RUN: 2>&1 | FileCheck %s ; RUN: opt < %s -msan -msan-instrumentation-with-call-threshold=0 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" @@ -82,4 +84,4 @@ define <4 x i32> @test65(<4 x i32> %vec, i65 %idx, i32 %x) sanitize_memory { ; CHECK-NOT: call void @__msan_maybe_warning_ ; CHECK: icmp ne i65 %{{.*}}, 0 ; CHECK-NOT: call void @__msan_maybe_warning_ -; CHECK: ret <4 x i32> \ No newline at end of file +; CHECK: ret <4 x i32>