Don't taint relaxed loads that immediately comes before an AcqRel read-modify-write op
[oota-llvm.git] / lib / CodeGen / AtomicExpandPass.cpp
index c8308af..077c52b 100644 (file)
@@ -71,6 +71,33 @@ namespace {
     bool isIdempotentRMW(AtomicRMWInst *AI);
     bool simplifyIdempotentRMW(AtomicRMWInst *AI);
   };
+
+
+  // If 'LI' is a relaxed load, and it is immediately followed by a
+// atomic read-modify-write that has acq_rel parameter, we don't have to do
+// anything since the rmw serves as a natural barrier.
+void MarkRelaxedLoadBeforeAcqrelRMW(LoadInst* LI) {
+  auto* BB = LI->getParent();
+  auto BBI = LI->getIterator();
+  for (BBI++; BBI != BB->end(); BBI++) {
+    Instruction* CurInst = &*BBI;
+    if (!CurInst) {
+      return;
+    }
+    if (!CurInst->isAtomic()) {
+      continue;
+    }
+    auto* RMW = dyn_cast<AtomicRMWInst>(CurInst);
+    if (!RMW) {
+      return;
+    }
+    if (RMW->getOrdering() == AcquireRelease ||
+        RMW->getOrdering() == SequentiallyConsistent) {
+      LI->setHasSubsequentAcqlRMW(true);
+    }
+  }
+}
+
 }
 
 char AtomicExpand::ID = 0;
@@ -133,7 +160,8 @@ bool AtomicExpand::runOnFunction(Function &F) {
                          << *LI << '\n');
             LI->setOrdering(Acquire);
             */
-            MonotonicLoadInsts.push_back(LI);
+//            MonotonicLoadInsts.push_back(LI);
+            MarkRelaxedLoadBeforeAcqrelRMW(LI);
           }
           break;
         }