Taints load part of RMWs unconditionally
authorPeizhao Ou <peizhaoo@uci.edu>
Tue, 22 May 2018 04:09:57 +0000 (21:09 -0700)
committerPeizhao Ou <peizhaoo@uci.edu>
Tue, 22 May 2018 04:09:57 +0000 (21:09 -0700)
include/llvm/IR/Instruction.h
lib/CodeGen/AtomicExpandPass.cpp
lib/CodeGen/CodeGenPrepare.cpp
lib/IR/Instruction.cpp

index 03c45497fa9538956b071573a2f7345abc38f746..c9de9e20055f645798ea2c2413e885c183bf20ae 100644 (file)
@@ -41,11 +41,16 @@ class Instruction : public User,
   BasicBlock *Parent;
   DebugLoc DbgLoc;                         // 'dbg' Metadata cache.
 
+  // XXX-modified: Indicate whether this instruction should be tainted. Used for
+  // tainting the load parts of RMW.
+  bool NeedTainted;
+
   enum {
     /// HasMetadataBit - This is a bit stored in the SubClassData field which
     /// indicates whether this instruction has metadata attached to it or not.
     HasMetadataBit = 1 << 15
   };
+
 public:
   // Out of line virtual method, so the vtable, etc has a home.
   ~Instruction() override;
@@ -288,6 +293,16 @@ public:
   /// Copy I's fast-math flags
   void copyFastMathFlags(const Instruction *I);
 
+  // XXX-modified: Indicate whether this instruction should be tainted. Used for
+  // tainting the load parts of RMW.
+  bool getNeedTainted() {
+    return NeedTainted;
+  }
+
+  bool setNeedTainted() {
+    NeedTainted = true;
+  }
+
 private:
   /// hasMetadataHashEntry - Return true if we have an entry in the on-the-side
   /// metadata hash.
index 077c52b19a7a3d1907cdd3dcda9eb967ccaf0f51..eed71cb5ecf5df8e808dee3cbd13b3a57681ab3f 100644 (file)
@@ -515,6 +515,12 @@ bool AtomicExpand::expandAtomicOpToLLSC(
   // Start the main loop block now that we've taken care of the preliminaries.
   Builder.SetInsertPoint(LoopBB);
   Value *Loaded = TLI->emitLoadLinked(Builder, Addr, MemOpOrder);
+  auto* LoadedPartInst = dyn_cast<Instruction>(Loaded);
+  assert(LoadedPartInst && "Load part of RMW should be an instruction!");
+  if (MemOpOrder != Acquire && MemOpOrder != AcquireRelease &&
+      MemOpOrder != SequentiallyConsistent) {
+    LoadedPartInst->setNeedTainted();
+  }
 
   Value *NewVal = PerformOp(Builder, Loaded);
 
index 7674e5cff9296e882ee27fe46ebffe1065c3f35d..abaa07cdf7b8f79cc71f4b124791b9e64d18c17c 100644 (file)
@@ -1438,6 +1438,8 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
           break;
         }
       }
+    } else if (I->getNeedTainted()) {
+      TaintRelaxedLoads(&*I, I->getNextNode());
     }
   }
   EverMadeChange |=
index 4b33d2e66ea193d43649f33131f6f02ee3da54c4..226f0d62d11301a133212c94f7a336cf3754e104 100644 (file)
@@ -22,7 +22,8 @@ using namespace llvm;
 
 Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
                          Instruction *InsertBefore)
-  : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr) {
+  : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr),
+    NeedTainted(false) {
 
   // If requested, insert this instruction into a basic block...
   if (InsertBefore) {
@@ -34,7 +35,8 @@ Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
 
 Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
                          BasicBlock *InsertAtEnd)
-  : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr) {
+  : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr),
+    NeedTainted(false) {
 
   // append this instruction into the basic block
   assert(InsertAtEnd && "Basic block to append to may not be NULL!");