From: weiyu Date: Tue, 26 Nov 2019 23:21:09 +0000 (-0800) Subject: Fix the false negative of ThreadSanitizer mentioned in https://github.com/google... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f60e865f2e548a5ab85a1003fc7fa73f3739ff94;p=c11llvm.git Fix the false negative of ThreadSanitizer mentioned in https://github.com/google/sanitizers/issues/968 --- diff --git a/CDSPass.cpp b/CDSPass.cpp index cd5c892..da29495 100644 --- a/CDSPass.cpp +++ b/CDSPass.cpp @@ -177,6 +177,7 @@ namespace { bool isAtomicCall(Instruction *I); bool instrumentAtomic(Instruction *I, const DataLayout &DL); bool instrumentAtomicCall(CallInst *CI, const DataLayout &DL); + bool shouldInstrumentBeforeAtomics(Instruction *I); void chooseInstructionsToInstrument(SmallVectorImpl &Local, SmallVectorImpl &All, const DataLayout &DL); @@ -412,6 +413,32 @@ bool CDSPass::addrPointsToConstantData(Value *Addr) { return false; } +bool CDSPass::shouldInstrumentBeforeAtomics(Instruction * Inst) { + if (LoadInst *LI = dyn_cast(Inst)) { + AtomicOrdering ordering = LI->getOrdering(); + if ( isAtLeastOrStrongerThan(ordering, AtomicOrdering::Acquire) ) + return true; + } else if (StoreInst *SI = dyn_cast(Inst)) { + AtomicOrdering ordering = SI->getOrdering(); + if ( isAtLeastOrStrongerThan(ordering, AtomicOrdering::Acquire) ) + return true; + } else if (AtomicRMWInst *RMWI = dyn_cast(Inst)) { + AtomicOrdering ordering = RMWI->getOrdering(); + if ( isAtLeastOrStrongerThan(ordering, AtomicOrdering::Acquire) ) + return true; + } else if (AtomicCmpXchgInst *CASI = dyn_cast(Inst)) { + AtomicOrdering ordering = CASI->getSuccessOrdering(); + if ( isAtLeastOrStrongerThan(ordering, AtomicOrdering::Acquire) ) + return true; + } else if (FenceInst *FI = dyn_cast(Inst)) { + AtomicOrdering ordering = FI->getOrdering(); + if ( isAtLeastOrStrongerThan(ordering, AtomicOrdering::Acquire) ) + return true; + } + + return false; +} + void CDSPass::chooseInstructionsToInstrument( SmallVectorImpl &Local, SmallVectorImpl &All, const DataLayout &DL) { @@ -484,9 +511,19 @@ bool CDSPass::runOnFunction(Function &F) { for (auto &BB : F) { for (auto &Inst : BB) { - if ( (&Inst)->isAtomic() || isAtomicCall(&Inst) ) { + if ( (&Inst)->isAtomic() ) { AtomicAccesses.push_back(&Inst); HasAtomic = true; + + if (shouldInstrumentBeforeAtomics(&Inst)) { + chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, + DL); + } + } else if (isAtomicCall(&Inst) ) { + AtomicAccesses.push_back(&Inst); + HasAtomic = true; + chooseInstructionsToInstrument(LocalLoadsAndStores, AllLoadsAndStores, + DL); } else if (isa(Inst) || isa(Inst)) { LoadInst *LI = dyn_cast(&Inst); StoreInst *SI = dyn_cast(&Inst);