Index: cfe/trunk/lib/CodeGen/BackendUtil.cpp =================================================================== --- cfe/trunk/lib/CodeGen/BackendUtil.cpp +++ cfe/trunk/lib/CodeGen/BackendUtil.cpp @@ -53,6 +53,7 @@ #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/MemorySanitizer.h" #include "llvm/Transforms/Instrumentation/BoundsChecking.h" #include "llvm/Transforms/Instrumentation/GCOVProfiler.h" #include "llvm/Transforms/ObjCARC.h" @@ -276,7 +277,7 @@ const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); int TrackOrigins = CGOpts.SanitizeMemoryTrackOrigins; bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Memory); - PM.add(createMemorySanitizerPass(TrackOrigins, Recover, CompileKernel)); + PM.add(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover, CompileKernel)); // MemorySanitizer inserts complex instrumentation that mostly follows // the logic of the original code, but operates on "shadow" values. Index: llvm/trunk/bindings/go/llvm/InstrumentationBindings.h =================================================================== --- llvm/trunk/bindings/go/llvm/InstrumentationBindings.h +++ llvm/trunk/bindings/go/llvm/InstrumentationBindings.h @@ -27,7 +27,7 @@ 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); Index: llvm/trunk/bindings/go/llvm/InstrumentationBindings.cpp =================================================================== --- llvm/trunk/bindings/go/llvm/InstrumentationBindings.cpp +++ llvm/trunk/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 @@ unwrap(PM)->add(createThreadSanitizerPass()); } -void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createMemorySanitizerPass()); +void LLVMAddMemorySanitizerLegacyPassPass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createMemorySanitizerLegacyPassPass()); } void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, Index: llvm/trunk/bindings/go/llvm/transforms_instrumentation.go =================================================================== --- llvm/trunk/bindings/go/llvm/transforms_instrumentation.go +++ llvm/trunk/bindings/go/llvm/transforms_instrumentation.go @@ -32,8 +32,8 @@ 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) { Index: llvm/trunk/include/llvm/InitializePasses.h =================================================================== --- llvm/trunk/include/llvm/InitializePasses.h +++ llvm/trunk/include/llvm/InitializePasses.h @@ -273,7 +273,7 @@ void initializeMemoryDependenceWrapperPassPass(PassRegistry&); void initializeMemorySSAPrinterLegacyPassPass(PassRegistry&); void initializeMemorySSAWrapperPassPass(PassRegistry&); -void initializeMemorySanitizerPass(PassRegistry&); +void initializeMemorySanitizerLegacyPassPass(PassRegistry&); void initializeMergeFunctionsPass(PassRegistry&); void initializeMergeICmpsPass(PassRegistry&); void initializeMergedLoadStoreMotionLegacyPassPass(PassRegistry&); Index: llvm/trunk/include/llvm/Transforms/Instrumentation.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Instrumentation.h +++ llvm/trunk/include/llvm/Transforms/Instrumentation.h @@ -152,11 +152,6 @@ 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 @@ assert(Scaled <= std::numeric_limits::max() && "overflow 32-bits"); return Scaled; } - } // end namespace llvm #endif // LLVM_TRANSFORMS_INSTRUMENTATION_H Index: llvm/trunk/include/llvm/Transforms/Instrumentation/MemorySanitizer.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Instrumentation/MemorySanitizer.h +++ llvm/trunk/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 */ Index: llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h +++ llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h @@ -58,6 +58,11 @@ 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); Index: llvm/trunk/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/trunk/lib/Passes/PassBuilder.cpp +++ llvm/trunk/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" Index: llvm/trunk/lib/Passes/PassRegistry.def =================================================================== --- llvm/trunk/lib/Passes/PassRegistry.def +++ llvm/trunk/lib/Passes/PassRegistry.def @@ -231,6 +231,7 @@ 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 Index: llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -111,7 +111,7 @@ initializePGOIndirectCallPromotionLegacyPassPass(Registry); initializePGOMemOPSizeOptLegacyPassPass(Registry); initializeInstrProfilingLegacyPassPass(Registry); - initializeMemorySanitizerPass(Registry); + initializeMemorySanitizerLegacyPassPass(Registry); initializeHWAddressSanitizerPass(Registry); initializeThreadSanitizerPass(Registry); initializeSanitizerCoverageModulePass(Registry); Index: llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ llvm/trunk/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 @@ 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 @@ 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 @@ this->Recover = ClKeepGoing.getNumOccurrences() > 0 ? ClKeepGoing : (this->CompileKernel | Recover); + initializeModule(M); } - StringRef getPassName() const override { return "MemorySanitizer"; } - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); - } + // 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 runOnFunction(Function &F) override; - bool doInitialization(Module &M) override; + bool sanitizeFunction(Function &F, TargetLibraryInfo &TLI); private: friend struct MemorySanitizerVisitor; @@ -485,13 +483,13 @@ 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 @@ /// An empty volatile inline asm that prevents callback merge. InlineAsm *EmptyAsm; +}; + +/// 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; - Function *MsanCtorFunction; + 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) - -FunctionPass *llvm::createMemorySanitizerPass(int TrackOrigins, bool Recover, - bool CompileKernel) { - return new MemorySanitizer(TrackOrigins, Recover, CompileKernel); +INITIALIZE_PASS_END(MemorySanitizerLegacyPass, "msan", + "MemorySanitizer: detects uninitialized reads.", false, + false) + +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 @@ "__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 @@ 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); - - RetvalOriginTLS = new GlobalVariable( - M, OriginTy, false, GlobalVariable::ExternalLinkage, nullptr, - "__msan_retval_origin_tls", nullptr, GlobalVariable::InitialExecTLSModel); - - ParamTLS = new GlobalVariable( - M, ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), false, - GlobalVariable::ExternalLinkage, nullptr, "__msan_param_tls", nullptr, - GlobalVariable::InitialExecTLSModel); - - ParamOriginTLS = new GlobalVariable( - M, ArrayType::get(OriginTy, kParamTLSSize / 4), false, - GlobalVariable::ExternalLinkage, nullptr, "__msan_param_origin_tls", - nullptr, GlobalVariable::InitialExecTLSModel); - - VAArgTLS = new GlobalVariable( - M, ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), false, - GlobalVariable::ExternalLinkage, nullptr, "__msan_va_arg_tls", nullptr, - GlobalVariable::InitialExecTLSModel); - - VAArgOriginTLS = new GlobalVariable( - M, ArrayType::get(OriginTy, kParamTLSSize / 4), false, - GlobalVariable::ExternalLinkage, nullptr, "__msan_va_arg_origin_tls", - nullptr, GlobalVariable::InitialExecTLSModel); - - 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); + RetvalTLS = + getOrInsertGlobal(M, "__msan_retval_tls", + ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8)); + + RetvalOriginTLS = getOrInsertGlobal(M, "__msan_retval_origin_tls", OriginTy); + + ParamTLS = + getOrInsertGlobal(M, "__msan_param_tls", + ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8)); + + ParamOriginTLS = + getOrInsertGlobal(M, "__msan_param_origin_tls", + ArrayType::get(OriginTy, kParamTLSSize / 4)); + + VAArgTLS = + getOrInsertGlobal(M, "__msan_va_arg_tls", + ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8)); + + VAArgOriginTLS = + getOrInsertGlobal(M, "__msan_va_arg_origin_tls", + ArrayType::get(OriginTy, kParamTLSSize / 4)); + + 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 @@ } /// 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 @@ 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 @@ 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 @@ // 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 @@ 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; Index: llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp +++ llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp @@ -174,6 +174,27 @@ 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 Index: llvm/trunk/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64el.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/Mips/vararg-mips64el.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64le.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/PowerPC/vararg-ppc64le.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/X86/vararg-too-large.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/X86/vararg-too-large.ll +++ llvm/trunk/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 Index: llvm/trunk/test/Instrumentation/MemorySanitizer/X86/vararg.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/X86/vararg.ll +++ llvm/trunk/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. Index: llvm/trunk/test/Instrumentation/MemorySanitizer/X86/vararg_call.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/X86/vararg_call.ll +++ llvm/trunk/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. Index: llvm/trunk/test/Instrumentation/MemorySanitizer/alloca.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/alloca.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/array_types.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/array_types.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/atomics.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/atomics.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/byval-alignment.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/byval-alignment.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/check_access_address.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/check_access_address.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/csr.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/csr.ll +++ llvm/trunk/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 Index: llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll +++ llvm/trunk/test/Instrumentation/MemorySanitizer/global_ctors_2to3.ll @@ -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 { Index: llvm/trunk/test/Instrumentation/MemorySanitizer/instrumentation-with-call-threshold.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/instrumentation-with-call-threshold.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/manual-shadow.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/manual-shadow.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/masked-store-load.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/masked-store-load.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/missing_origin.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/missing_origin.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_asm_conservative.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_basic.ll +++ llvm/trunk/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 @@ ; CHECK-NEXT: ret i8* -; CHECK-LABEL: define internal void @msan.module_ctor() { -; CHECK: call void @__msan_init() +; CHECK: declare void @__msan_init() Index: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_kernel_basic.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_kernel_basic.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_x86_bts_asm.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/msan_x86intrinsics.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/msan_x86intrinsics.ll +++ llvm/trunk/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 Index: llvm/trunk/test/Instrumentation/MemorySanitizer/mul_by_constant.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/mul_by_constant.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/nosanitize.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/nosanitize.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/origin-alignment.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/origin-alignment.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/origin-array.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/origin-array.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/pr32842.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/pr32842.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/return_from_main.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/return_from_main.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/store-long-origin.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/store-long-origin.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/store-origin.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/store-origin.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/str-nobuiltin.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/str-nobuiltin.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/unreachable.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/unreachable.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/unsized_type.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/unsized_type.ll +++ llvm/trunk/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" Index: llvm/trunk/test/Instrumentation/MemorySanitizer/vector_arith.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/vector_arith.ll +++ llvm/trunk/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 Index: llvm/trunk/test/Instrumentation/MemorySanitizer/vector_cmp.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/vector_cmp.ll +++ llvm/trunk/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 Index: llvm/trunk/test/Instrumentation/MemorySanitizer/vector_cvt.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/vector_cvt.ll +++ llvm/trunk/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 Index: llvm/trunk/test/Instrumentation/MemorySanitizer/vector_pack.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/vector_pack.ll +++ llvm/trunk/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 Index: llvm/trunk/test/Instrumentation/MemorySanitizer/vector_shift.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/vector_shift.ll +++ llvm/trunk/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 Index: llvm/trunk/test/Instrumentation/MemorySanitizer/with-call-type-size.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/with-call-type-size.ll +++ llvm/trunk/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 @@ ; 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>