//
//===----------------------------------------------------------------------===//
+#include "TaintRelaxedAtomicsUtils.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
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;
<< *LI << '\n');
LI->setOrdering(Acquire);
*/
- MonotonicLoadInsts.push_back(LI);
+// MonotonicLoadInsts.push_back(LI);
+ MarkRelaxedLoadBeforeAcqrelRMW(LI);
}
break;
}
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);