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