<div dir="ltr"><div dir="ltr">Yup, fixed in r351386. Cheers!</div><div dir="ltr"><br></div><div>Best,</div><div>Philip</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jan 16, 2019 at 7:35 PM Davide Italiano <<a href="mailto:davide@freebsd.org">davide@freebsd.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I think there's a typo in the new header you added (should say<br>
ThreadSanitizer instead of MemorySanitizer).<br>
<br>
Thanks,<br>
<br>
--<br>
Davide<br>
<br>
On Wed, Jan 16, 2019 at 1:31 AM Philip Pfaffe via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br>
><br>
> Author: pfaffe<br>
> Date: Wed Jan 16 01:28:01 2019<br>
> New Revision: 351314<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=351314&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=351314&view=rev</a><br>
> Log:<br>
> [NewPM][TSan] Reiterate the TSan port<br>
><br>
> Summary:<br>
> Second iteration of D56433 which got reverted in rL350719. The problem<br>
> in the previous version was that we dropped the thunk calling the tsan init<br>
> function. The new version keeps the thunk which should appease dyld, but is not<br>
> actually OK wrt. the current semantics of function passes. Hence, add a<br>
> helper to insert the functions only on the first time. The helper<br>
> allows hooking into the insertion to be able to append them to the<br>
> global ctors list.<br>
><br>
> Reviewers: chandlerc, vitalybuka, fedor.sergeev, leonardchan<br>
><br>
> Subscribers: hiraditya, bollu, llvm-commits<br>
><br>
> Differential Revision: <a href="https://reviews.llvm.org/D56538" rel="noreferrer" target="_blank">https://reviews.llvm.org/D56538</a><br>
><br>
> Added:<br>
>     llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h<br>
> Modified:<br>
>     llvm/trunk/bindings/go/llvm/InstrumentationBindings.cpp<br>
>     llvm/trunk/include/llvm/InitializePasses.h<br>
>     llvm/trunk/include/llvm/Transforms/Instrumentation.h<br>
>     llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h<br>
>     llvm/trunk/lib/Passes/PassBuilder.cpp<br>
>     llvm/trunk/lib/Passes/PassRegistry.def<br>
>     llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp<br>
>     llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp<br>
>     llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp<br>
>     llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll<br>
><br>
> Modified: llvm/trunk/bindings/go/llvm/InstrumentationBindings.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/go/llvm/InstrumentationBindings.cpp?rev=351314&r1=351313&r2=351314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/go/llvm/InstrumentationBindings.cpp?rev=351314&r1=351313&r2=351314&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/bindings/go/llvm/InstrumentationBindings.cpp (original)<br>
> +++ llvm/trunk/bindings/go/llvm/InstrumentationBindings.cpp Wed Jan 16 01:28:01 2019<br>
> @@ -17,6 +17,7 @@<br>
>  #include "llvm/IR/Module.h"<br>
>  #include "llvm/Transforms/Instrumentation.h"<br>
>  #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"<br>
> +#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"<br>
><br>
>  using namespace llvm;<br>
><br>
> @@ -29,7 +30,7 @@ void LLVMAddAddressSanitizerModulePass(L<br>
>  }<br>
><br>
>  void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM) {<br>
> -  unwrap(PM)->add(createThreadSanitizerPass());<br>
> +  unwrap(PM)->add(createThreadSanitizerLegacyPassPass());<br>
>  }<br>
><br>
>  void LLVMAddMemorySanitizerLegacyPassPass(LLVMPassManagerRef PM) {<br>
><br>
> Modified: llvm/trunk/include/llvm/InitializePasses.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=351314&r1=351313&r2=351314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=351314&r1=351313&r2=351314&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/InitializePasses.h (original)<br>
> +++ llvm/trunk/include/llvm/InitializePasses.h Wed Jan 16 01:28:01 2019<br>
> @@ -392,7 +392,7 @@ void initializeTailDuplicatePass(PassReg<br>
>  void initializeTargetLibraryInfoWrapperPassPass(PassRegistry&);<br>
>  void initializeTargetPassConfigPass(PassRegistry&);<br>
>  void initializeTargetTransformInfoWrapperPassPass(PassRegistry&);<br>
> -void initializeThreadSanitizerPass(PassRegistry&);<br>
> +void initializeThreadSanitizerLegacyPassPass(PassRegistry&);<br>
>  void initializeTwoAddressInstructionPassPass(PassRegistry&);<br>
>  void initializeTypeBasedAAWrapperPassPass(PassRegistry&);<br>
>  void initializeUnifyFunctionExitNodesPass(PassRegistry&);<br>
><br>
> Modified: llvm/trunk/include/llvm/Transforms/Instrumentation.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=351314&r1=351313&r2=351314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation.h?rev=351314&r1=351313&r2=351314&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/Transforms/Instrumentation.h (original)<br>
> +++ llvm/trunk/include/llvm/Transforms/Instrumentation.h Wed Jan 16 01:28:01 2019<br>
> @@ -155,9 +155,6 @@ ModulePass *createAddressSanitizerModule<br>
>  FunctionPass *createHWAddressSanitizerPass(bool CompileKernel = false,<br>
>                                             bool Recover = false);<br>
><br>
> -// Insert ThreadSanitizer (race detection) instrumentation<br>
> -FunctionPass *createThreadSanitizerPass();<br>
> -<br>
>  // Insert DataFlowSanitizer (dynamic data flow analysis) instrumentation<br>
>  ModulePass *createDataFlowSanitizerPass(<br>
>      const std::vector<std::string> &ABIListFiles = std::vector<std::string>(),<br>
><br>
> Added: llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h?rev=351314&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h?rev=351314&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h (added)<br>
> +++ llvm/trunk/include/llvm/Transforms/Instrumentation/ThreadSanitizer.h Wed Jan 16 01:28:01 2019<br>
> @@ -0,0 +1,33 @@<br>
> +//===- Transforms/Instrumentation/MemorySanitizer.h - TSan Pass -----------===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// This file defines the thread sanitizer pass.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H<br>
> +#define LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H<br>
> +<br>
> +#include "llvm/IR/PassManager.h"<br>
> +#include "llvm/Pass.h"<br>
> +<br>
> +namespace llvm {<br>
> +// Insert ThreadSanitizer (race detection) instrumentation<br>
> +FunctionPass *createThreadSanitizerLegacyPassPass();<br>
> +<br>
> +/// A function pass for tsan instrumentation.<br>
> +///<br>
> +/// Instruments functions to detect race conditions reads. This function pass<br>
> +/// inserts calls to runtime library functions. If the functions aren't declared<br>
> +/// yet, the pass inserts the declarations. Otherwise the existing globals are<br>
> +struct ThreadSanitizerPass : public PassInfoMixin<ThreadSanitizerPass> {<br>
> +  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);<br>
> +};<br>
> +} // namespace llvm<br>
> +#endif /* LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H */<br>
><br>
> Modified: llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h?rev=351314&r1=351313&r2=351314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h?rev=351314&r1=351313&r2=351314&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h (original)<br>
> +++ llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h Wed Jan 16 01:28:01 2019<br>
> @@ -58,6 +58,19 @@ std::pair<Function *, Function *> create<br>
>      ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,<br>
>      StringRef VersionCheckName = StringRef());<br>
><br>
> +/// Creates sanitizer constructor function lazily. If a constructor and init<br>
> +/// function already exist, this function returns it. Otherwise it calls \c<br>
> +/// createSanitizerCtorAndInitFunctions. The FunctionsCreatedCallback is invoked<br>
> +/// in that case, passing the new Ctor and Init function.<br>
> +///<br>
> +/// \return Returns pair of pointers to constructor, and init functions<br>
> +/// respectively.<br>
> +std::pair<Function *, Function *> getOrCreateSanitizerCtorAndInitFunctions(<br>
> +    Module &M, StringRef CtorName, StringRef InitName,<br>
> +    ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,<br>
> +    function_ref<void(Function *, Function *)> FunctionsCreatedCallback,<br>
> +    StringRef VersionCheckName = StringRef());<br>
> +<br>
>  // Creates and returns a sanitizer init function without argument if it doesn't<br>
>  // exist, and adds it to the global constructors list. Otherwise it returns the<br>
>  // existing function.<br>
><br>
> Modified: llvm/trunk/lib/Passes/PassBuilder.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=351314&r1=351313&r2=351314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=351314&r1=351313&r2=351314&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Passes/PassBuilder.cpp (original)<br>
> +++ llvm/trunk/lib/Passes/PassBuilder.cpp Wed Jan 16 01:28:01 2019<br>
> @@ -95,6 +95,7 @@<br>
>  #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"<br>
>  #include "llvm/Transforms/Instrumentation/InstrProfiling.h"<br>
>  #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"<br>
> +#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"<br>
>  #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h"<br>
>  #include "llvm/Transforms/Scalar/ADCE.h"<br>
>  #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"<br>
><br>
> Modified: llvm/trunk/lib/Passes/PassRegistry.def<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=351314&r1=351313&r2=351314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassRegistry.def?rev=351314&r1=351313&r2=351314&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Passes/PassRegistry.def (original)<br>
> +++ llvm/trunk/lib/Passes/PassRegistry.def Wed Jan 16 01:28:01 2019<br>
> @@ -232,6 +232,7 @@ FUNCTION_PASS("view-cfg", CFGViewerPass(<br>
>  FUNCTION_PASS("view-cfg-only", CFGOnlyViewerPass())<br>
>  FUNCTION_PASS("transform-warning", WarnMissedTransformationsPass())<br>
>  FUNCTION_PASS("msan", MemorySanitizerPass())<br>
> +FUNCTION_PASS("tsan", ThreadSanitizerPass())<br>
>  #undef FUNCTION_PASS<br>
><br>
>  #ifndef FUNCTION_PASS_WITH_PARAMS<br>
><br>
> Modified: llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp?rev=351314&r1=351313&r2=351314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp?rev=351314&r1=351313&r2=351314&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp (original)<br>
> +++ llvm/trunk/lib/Transforms/Instrumentation/Instrumentation.cpp Wed Jan 16 01:28:01 2019<br>
> @@ -113,7 +113,7 @@ void llvm::initializeInstrumentation(Pas<br>
>    initializeInstrProfilingLegacyPassPass(Registry);<br>
>    initializeMemorySanitizerLegacyPassPass(Registry);<br>
>    initializeHWAddressSanitizerPass(Registry);<br>
> -  initializeThreadSanitizerPass(Registry);<br>
> +  initializeThreadSanitizerLegacyPassPass(Registry);<br>
>    initializeSanitizerCoverageModulePass(Registry);<br>
>    initializeDataFlowSanitizerPass(Registry);<br>
>    initializeEfficiencySanitizerPass(Registry);<br>
><br>
> Modified: llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp?rev=351314&r1=351313&r2=351314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp?rev=351314&r1=351313&r2=351314&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp (original)<br>
> +++ llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp Wed Jan 16 01:28:01 2019<br>
> @@ -19,6 +19,7 @@<br>
>  // The rest is handled by the run-time library.<br>
>  //===----------------------------------------------------------------------===//<br>
><br>
> +#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"<br>
>  #include "llvm/ADT/SmallPtrSet.h"<br>
>  #include "llvm/ADT/SmallString.h"<br>
>  #include "llvm/ADT/SmallVector.h"<br>
> @@ -86,15 +87,16 @@ static const char *const kTsanInitName =<br>
>  namespace {<br>
><br>
>  /// ThreadSanitizer: instrument the code in module to find races.<br>
> -struct ThreadSanitizer : public FunctionPass {<br>
> -  ThreadSanitizer() : FunctionPass(ID) {}<br>
> -  StringRef getPassName() const override;<br>
> -  void getAnalysisUsage(AnalysisUsage &AU) const override;<br>
> -  bool runOnFunction(Function &F) override;<br>
> -  bool doInitialization(Module &M) override;<br>
> -  static char ID;  // Pass identification, replacement for typeid.<br>
> +///<br>
> +/// Instantiating ThreadSanitizer inserts the tsan runtime library API function<br>
> +/// declarations into the module if they don't exist already. Instantiating<br>
> +/// ensures the __tsan_init function is in the list of global constructors for<br>
> +/// the module.<br>
> +struct ThreadSanitizer {<br>
> +  ThreadSanitizer(Module &M);<br>
> +  bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI);<br>
><br>
> - private:<br>
> +private:<br>
>    void initializeCallbacks(Module &M);<br>
>    bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);<br>
>    bool instrumentAtomic(Instruction *I, const DataLayout &DL);<br>
> @@ -130,27 +132,55 @@ struct ThreadSanitizer : public Function<br>
>    Function *MemmoveFn, *MemcpyFn, *MemsetFn;<br>
>    Function *TsanCtorFunction;<br>
>  };<br>
> +<br>
> +struct ThreadSanitizerLegacyPass : FunctionPass {<br>
> +  ThreadSanitizerLegacyPass() : FunctionPass(ID) {}<br>
> +  StringRef getPassName() const override;<br>
> +  void getAnalysisUsage(AnalysisUsage &AU) const override;<br>
> +  bool runOnFunction(Function &F) override;<br>
> +  bool doInitialization(Module &M) override;<br>
> +  static char ID; // Pass identification, replacement for typeid.<br>
> +private:<br>
> +  Optional<ThreadSanitizer> TSan;<br>
> +};<br>
>  }  // namespace<br>
><br>
> -char ThreadSanitizer::ID = 0;<br>
> -INITIALIZE_PASS_BEGIN(<br>
> -    ThreadSanitizer, "tsan",<br>
> -    "ThreadSanitizer: detects data races.",<br>
> -    false, false)<br>
> +PreservedAnalyses ThreadSanitizerPass::run(Function &F,<br>
> +                                           FunctionAnalysisManager &FAM) {<br>
> +  ThreadSanitizer TSan(*F.getParent());<br>
> +  if (TSan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)))<br>
> +    return PreservedAnalyses::none();<br>
> +  return PreservedAnalyses::all();<br>
> +}<br>
> +<br>
> +char ThreadSanitizerLegacyPass::ID = 0;<br>
> +INITIALIZE_PASS_BEGIN(ThreadSanitizerLegacyPass, "tsan",<br>
> +                      "ThreadSanitizer: detects data races.", false, false)<br>
>  INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)<br>
> -INITIALIZE_PASS_END(<br>
> -    ThreadSanitizer, "tsan",<br>
> -    "ThreadSanitizer: detects data races.",<br>
> -    false, false)<br>
> +INITIALIZE_PASS_END(ThreadSanitizerLegacyPass, "tsan",<br>
> +                    "ThreadSanitizer: detects data races.", false, false)<br>
><br>
> -StringRef ThreadSanitizer::getPassName() const { return "ThreadSanitizer"; }<br>
> +StringRef ThreadSanitizerLegacyPass::getPassName() const {<br>
> +  return "ThreadSanitizerLegacyPass";<br>
> +}<br>
><br>
> -void ThreadSanitizer::getAnalysisUsage(AnalysisUsage &AU) const {<br>
> +void ThreadSanitizerLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {<br>
>    AU.addRequired<TargetLibraryInfoWrapperPass>();<br>
>  }<br>
><br>
> -FunctionPass *llvm::createThreadSanitizerPass() {<br>
> -  return new ThreadSanitizer();<br>
> +bool ThreadSanitizerLegacyPass::doInitialization(Module &M) {<br>
> +  TSan.emplace(M);<br>
> +  return true;<br>
> +}<br>
> +<br>
> +bool ThreadSanitizerLegacyPass::runOnFunction(Function &F) {<br>
> +  auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();<br>
> +  TSan->sanitizeFunction(F, TLI);<br>
> +  return true;<br>
> +}<br>
> +<br>
> +FunctionPass *llvm::createThreadSanitizerLegacyPassPass() {<br>
> +  return new ThreadSanitizerLegacyPass();<br>
>  }<br>
><br>
>  void ThreadSanitizer::initializeCallbacks(Module &M) {<br>
> @@ -252,16 +282,16 @@ void ThreadSanitizer::initializeCallback<br>
>                              IRB.getInt32Ty(), IntptrTy));<br>
>  }<br>
><br>
> -bool ThreadSanitizer::doInitialization(Module &M) {<br>
> +ThreadSanitizer::ThreadSanitizer(Module &M) {<br>
>    const DataLayout &DL = M.getDataLayout();<br>
>    IntptrTy = DL.getIntPtrType(M.getContext());<br>
> -  std::tie(TsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions(<br>
> -      M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},<br>
> -      /*InitArgs=*/{});<br>
> -<br>
> -  appendToGlobalCtors(M, TsanCtorFunction, 0);<br>
> -<br>
> -  return true;<br>
> +  std::tie(TsanCtorFunction, std::ignore) =<br>
> +      getOrCreateSanitizerCtorAndInitFunctions(<br>
> +          M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},<br>
> +          /*InitArgs=*/{},<br>
> +          // This callback is invoked when the functions are created the first<br>
> +          // time. Hook them into the global ctors list in that case:<br>
> +          [&](Function *Ctor, Function *) { appendToGlobalCtors(M, Ctor, 0); });<br>
>  }<br>
><br>
>  static bool isVtableAccess(Instruction *I) {<br>
> @@ -402,7 +432,8 @@ void ThreadSanitizer::InsertRuntimeIgnor<br>
>    }<br>
>  }<br>
><br>
> -bool ThreadSanitizer::runOnFunction(Function &F) {<br>
> +bool ThreadSanitizer::sanitizeFunction(Function &F,<br>
> +                                       const TargetLibraryInfo &TLI) {<br>
>    // This is required to prevent instrumenting call to __tsan_init from within<br>
>    // the module constructor.<br>
>    if (&F == TsanCtorFunction)<br>
> @@ -416,8 +447,6 @@ bool ThreadSanitizer::runOnFunction(Func<br>
>    bool HasCalls = false;<br>
>    bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeThread);<br>
>    const DataLayout &DL = F.getParent()->getDataLayout();<br>
> -  const TargetLibraryInfo *TLI =<br>
> -      &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();<br>
><br>
>    // Traverse all instructions, collect loads/stores/returns, check for calls.<br>
>    for (auto &BB : F) {<br>
> @@ -428,7 +457,7 @@ bool ThreadSanitizer::runOnFunction(Func<br>
>          LocalLoadsAndStores.push_back(&Inst);<br>
>        else if (isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) {<br>
>          if (CallInst *CI = dyn_cast<CallInst>(&Inst))<br>
> -          maybeMarkSanitizerLibraryCallNoBuiltin(CI, TLI);<br>
> +          maybeMarkSanitizerLibraryCallNoBuiltin(CI, &TLI);<br>
>          if (isa<MemIntrinsic>(Inst))<br>
>            MemIntrinCalls.push_back(&Inst);<br>
>          HasCalls = true;<br>
><br>
> Modified: llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp?rev=351314&r1=351313&r2=351314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp?rev=351314&r1=351313&r2=351314&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp (original)<br>
> +++ llvm/trunk/lib/Transforms/Utils/ModuleUtils.cpp Wed Jan 16 01:28:01 2019<br>
> @@ -174,6 +174,28 @@ std::pair<Function *, Function *> llvm::<br>
>    return std::make_pair(Ctor, InitFunction);<br>
>  }<br>
><br>
> +std::pair<Function *, Function *><br>
> +llvm::getOrCreateSanitizerCtorAndInitFunctions(<br>
> +    Module &M, StringRef CtorName, StringRef InitName,<br>
> +    ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,<br>
> +    function_ref<void(Function *, Function *)> FunctionsCreatedCallback,<br>
> +    StringRef VersionCheckName) {<br>
> +  assert(!CtorName.empty() && "Expected ctor function name");<br>
> +<br>
> +  if (Function *Ctor = M.getFunction(CtorName))<br>
> +    // FIXME: Sink this logic into the module, similar to the handling of<br>
> +    // globals. This will make moving to a concurrent model much easier.<br>
> +    if (Ctor->arg_size() == 0 ||<br>
> +        Ctor->getReturnType() == Type::getVoidTy(M.getContext()))<br>
> +      return {Ctor, declareSanitizerInitFunction(M, InitName, InitArgTypes)};<br>
> +<br>
> +  Function *Ctor, *InitFunction;<br>
> +  std::tie(Ctor, InitFunction) = llvm::createSanitizerCtorAndInitFunctions(<br>
> +      M, CtorName, InitName, InitArgTypes, InitArgs, VersionCheckName);<br>
> +  FunctionsCreatedCallback(Ctor, InitFunction);<br>
> +  return std::make_pair(Ctor, InitFunction);<br>
> +}<br>
> +<br>
>  Function *llvm::getOrCreateInitFunction(Module &M, StringRef Name) {<br>
>    assert(!Name.empty() && "Expected init function name");<br>
>    if (Function *F = M.getFunction(Name)) {<br>
><br>
> Modified: llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll?rev=351314&r1=351313&r2=351314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll?rev=351314&r1=351313&r2=351314&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll (original)<br>
> +++ llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll Wed Jan 16 01:28:01 2019<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt < %s -tsan -S | FileCheck %s<br>
> +; RUN: opt < %s -passes=tsan -S | FileCheck %s<br>
><br>
>  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"<br>
>  target triple = "x86_64-unknown-linux-gnu"<br>
> @@ -77,6 +78,5 @@ define void @SwiftErrorCall(i8** swifter<br>
>    call void @SwiftError(i8** %0)<br>
>    ret void<br>
>  }<br>
> -<br>
>  ; CHECK: define internal void @tsan.module_ctor()<br>
>  ; CHECK: call void @__tsan_init()<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
<br>
<br>
<br>
-- <br>
Davide<br>
<br>
"There are no solved problems; there are only problems that are more<br>
or less solved" -- Henri Poincare<br>
</blockquote></div>