//
//===----------------------------------------------------------------------===//
+#include "TaintRelaxedAtomicsUtils.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
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);