[LLVMdev] memory scopes in atomic instructions

Sahasrabuddhe, Sameer sameer.sahasrabuddhe at amd.com
Mon Nov 24 01:54:24 PST 2014


On 11/21/2014 9:01 AM, Sahasrabuddhe, Sameer wrote:
> Meanwhile, I will start working on the required changes. The only 
> decision required right now is whether to use "1" for SingleThread, or 
> the largest integer value.

I am currently trying to understand how the bitcode reader and writer 
work, and it will certainly take some time. Besides, that the SDNode 
class needs to be updated to use a separate unsigned field for the 
synchronization scope.

Meanwhile, here's a patch that shows the immediate effect of allowing 
more than two scopes. There seem to be only two users for now --- the 
X86 target and tsan. The patch attempts to fix them in slightly 
different ways:

 1. The X86 target understands only two scopes --- SingleThread or
    CrossThread (to be renamed later). All other "not SingleThread"
    scopes will be treated as CrossThread. I am not sure if this needs
    an assertion instead ... other scopes should not occur in the
    program anyway!

    Interestingly, this sort of "scope promotion" is supposed to be okay
    for OpenCL and will not introduce any new data races. The frontend
    can do this explicitly when translating OpenCL programs to targets
    with just two scopes.

 2. tsan has a similar problem, but it should definitely assert for
    unknown scopes. If it attempted to promote them instead, then it
    will hide data races that it was supposed to find! The assertion can
    be replaced if/when tsan learns how to model other scopes for a
    given target.

Sameer.

-------------- next part --------------
commit 847121c1ba4b49f459a7f72c7527b82435b377f9
Author: Sameer Sahasrabuddhe <sameer.sahasrabuddhe at amd.com>
Date:   Mon Nov 24 12:03:21 2014 +0530

    replace check for "CrossThread" with "not SingleThread"

diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 47c8ce0..022a6e2 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -18736,7 +18736,7 @@ static SDValue LowerATOMIC_FENCE(SDValue Op, const X86Subtarget *Subtarget,
 
   // The only fence that needs an instruction is a sequentially-consistent
   // cross-thread fence.
-  if (FenceOrdering == SequentiallyConsistent && FenceScope == CrossThread) {
+  if (FenceOrdering == SequentiallyConsistent && FenceScope != SingleThread) {
     if (hasMFENCE(*Subtarget))
       return DAG.getNode(X86ISD::MFENCE, dl, MVT::Other, Op.getOperand(0));
 
diff --git a/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
index 417f2a1..f4cd8bd 100644
--- a/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
+++ b/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
@@ -298,9 +298,9 @@ void ThreadSanitizer::chooseInstructionsToInstrument(
 
 static bool isAtomic(Instruction *I) {
   if (LoadInst *LI = dyn_cast<LoadInst>(I))
-    return LI->isAtomic() && LI->getSynchScope() == CrossThread;
+    return LI->isAtomic() && LI->getSynchScope() != SingleThread;
   if (StoreInst *SI = dyn_cast<StoreInst>(I))
-    return SI->isAtomic() && SI->getSynchScope() == CrossThread;
+    return SI->isAtomic() && SI->getSynchScope() != SingleThread;
   if (isa<AtomicRMWInst>(I))
     return true;
   if (isa<AtomicCmpXchgInst>(I))
@@ -539,8 +539,14 @@ bool ThreadSanitizer::instrumentAtomic(Instruction *I) {
     I->eraseFromParent();
   } else if (FenceInst *FI = dyn_cast<FenceInst>(I)) {
     Value *Args[] = {createOrdering(&IRB, FI->getOrdering())};
-    Function *F = FI->getSynchScope() == SingleThread ?
-        TsanAtomicSignalFence : TsanAtomicThreadFence;
+    unsigned SynchScope = FI->getSynchScope();
+    Function *F = NULL;
+    switch (SynchScope) {
+      case SingleThread: F = TsanAtomicSignalFence; break;
+      case CrossThread: F = TsanAtomicThreadFence; break;
+      default:
+        llvm_unreachable("unsupported synchronization scope");
+    }
     CallInst *C = CallInst::Create(F, Args);
     ReplaceInstWithInst(I, C);
   }


More information about the llvm-dev mailing list