Index: llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -72,6 +72,9 @@ STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads"); STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing"); +static const char *const kTsanModuleCtorName = "tsan.module_ctor"; +static const char *const kTsanInitName = "__tsan_init"; + namespace { /// ThreadSanitizer: instrument the code in module to find races. @@ -113,6 +116,7 @@ Function *TsanVptrUpdate; Function *TsanVptrLoad; Function *MemmoveFn, *MemcpyFn, *MemsetFn; + Function *TsanCtorFunction; }; } // namespace @@ -225,13 +229,12 @@ bool ThreadSanitizer::doInitialization(Module &M) { const DataLayout &DL = M.getDataLayout(); + IntptrTy = DL.getIntPtrType(M.getContext()); + std::tie(TsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions( + M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{}, + /*InitArgs=*/{}); - // Always insert a call to __tsan_init into the module's CTORs. - IRBuilder<> IRB(M.getContext()); - IntptrTy = IRB.getIntPtrTy(DL); - Value *TsanInit = M.getOrInsertFunction("__tsan_init", - IRB.getVoidTy(), nullptr); - appendToGlobalCtors(M, cast(TsanInit), 0); + appendToGlobalCtors(M, TsanCtorFunction, 0); return true; } @@ -329,6 +332,10 @@ } bool ThreadSanitizer::runOnFunction(Function &F) { + // This is required to prevent instrumenting call to __tsan_init from within + // the module constructor. + if (&F == TsanCtorFunction) + return false; initializeCallbacks(*F.getParent()); SmallVector RetVec; SmallVector AllLoadsAndStores; Index: llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll =================================================================== --- llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll +++ llvm/trunk/test/Instrumentation/ThreadSanitizer/tsan_basic.ll @@ -9,7 +9,7 @@ ret i32 %tmp1 } -; CHECK: @llvm.global_ctors = {{.*}}@__tsan_init +; CHECK: @llvm.global_ctors = {{.*}}@tsan.module_ctor ; CHECK: define i32 @read_4_bytes(i32* %a) ; CHECK: call void @__tsan_func_entry(i8* %0) @@ -53,3 +53,6 @@ ; CHECK: call i8* @memset ; CHECK: ret void } + +; CHECK: define internal void @tsan.module_ctor() +; CHECK: call void @__tsan_init()