Taints the non-acquire RMW's store address with the load part
[oota-llvm.git] / lib / CodeGen / AtomicExpandPass.cpp
index 077c52b..045c807 100644 (file)
@@ -15,6 +15,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "TaintRelaxedAtomicsUtils.h"
 #include "llvm/ADT/SetOperations.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -516,10 +517,25 @@ bool AtomicExpand::expandAtomicOpToLLSC(
   Builder.SetInsertPoint(LoopBB);
   Value *Loaded = TLI->emitLoadLinked(Builder, Addr, MemOpOrder);
 
+  // XXX-update: For relaxed RMWs (i.e., fetch_* operations), we still need to
+  // taint the load part. However, we only need to taint those whose results are
+  // not immediately used by a conditional branch or a store address.
+  Value* StoreAddr = Addr;
+  auto* LoadedPartInst = dyn_cast<Instruction>(Loaded);
+  assert(LoadedPartInst && "Load part of RMW should be an instruction!");
+  if (MemOpOrder != Acquire && MemOpOrder != AcquireRelease &&
+      MemOpOrder != SequentiallyConsistent) {
+    // Also check whether the result is used immediately. If so, taint the
+    // address of the upcoming store-exclusive.
+    if (NeedExtraConstraints(I)) {
+      StoreAddr = taintRMWStoreAddressWithLoadPart(Builder, Addr, LoadedPartInst);
+    }
+  }
+
   Value *NewVal = PerformOp(Builder, Loaded);
 
   Value *StoreSuccess =
-      TLI->emitStoreConditional(Builder, NewVal, Addr, MemOpOrder);
+      TLI->emitStoreConditional(Builder, NewVal, StoreAddr, MemOpOrder);
   Value *TryAgain = Builder.CreateICmpNE(
       StoreSuccess, ConstantInt::get(IntegerType::get(Ctx, 32), 0), "tryagain");
   Builder.CreateCondBr(TryAgain, LoopBB, ExitBB);