Fixes issue of nondominating load part of RMWs when taiting outside of RMW loop
authorPeizhao Ou <peizhaoo@uci.edu>
Wed, 23 May 2018 07:24:03 +0000 (00:24 -0700)
committerPeizhao Ou <peizhaoo@uci.edu>
Wed, 23 May 2018 07:24:03 +0000 (00:24 -0700)
lib/CodeGen/CodeGenPrepare.cpp
lib/CodeGen/TaintRelaxedAtomicsUtils.cpp
lib/CodeGen/TaintRelaxedAtomicsUtils.h

index f084a894d743165499260a6df3c6dbe8d7264f2e..878e28271473d62d4f19919e0bbc305305e34cb0 100644 (file)
@@ -356,7 +356,16 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
         }
       }
     } else if (I->getNeedTainted()) {
-      TaintRelaxedLoads(&*I, I->getNextNode());
+      // Adds a fake conditional branch outside of the RMW loop.
+      auto* LoopBB = I->getParent();
+      auto* LoopTerm = LoopBB->getTerminator();
+      auto* BI = dyn_cast<BranchInst>(LoopTerm);
+      assert(BI && BI->isConditional() && "RMW loop ends with unconditional branch?");
+      BasicBlock* EndBB = BI->getSuccessor(1);
+      if (EndBB == LoopBB) {
+        BI->getSuccessor(0);
+      }
+      TaintAtBlockBeginning(&*I, EndBB, DT);
     }
   }
   EverMadeChange |=
index 4ce73698be4c9638f0ee35d9c75b0cb5113f47da..3b1f803938469c13ab4f0df5cfe9c46380e12d42 100644 (file)
@@ -688,6 +688,32 @@ void TaintRelaxedLoads(Instruction* UsageInst, Instruction* InsertPoint) {
   AddFakeConditionalBranch(FakeCondition->getNextNode(), FakeCondition);
 }
 
+// Taints the 'Inst' (i.e., adds a fake conditional block that uses the 'Inst')
+// at the beginning of basic block 'BB'. Note that if 'Inst' does not dominate
+// 'BB', we need to add appropriate an PHI node and taint the PHI node. Returns
+// true if the code is changed, and false otherwise.
+void TaintAtBlockBeginning(Instruction* Inst, BasicBlock* BB, DominatorTree* DT) {
+  auto* CurBB = Inst->getParent();
+  auto* FirstInst = BB->getFirstNonPHI();
+  if (DT->dominates(Inst, FirstInst)) {
+    return TaintRelaxedLoads(&*Inst, FirstInst);
+  }
+  IRBuilder<true, NoFolder> Builder(FirstInst);
+  auto* Phi = Builder.CreatePHI(Inst->getType(), 0, Inst->getName() + ".phi");
+  // Multiple blocks going to BB. We should add a PHI node w.r.t. 'Inst'.
+  for (auto* Pred : predecessors(BB)) {
+    Value* Val = nullptr;
+    if (Pred == CurBB) {
+      Val = Inst;
+    } else {
+      // We don't care what value other paths are.
+      Val = UndefValue::get(Inst->getType());
+    }
+    Phi->addIncoming(Val, Pred);
+  }
+  return TaintRelaxedLoads(Phi, Phi);
+}
+
 // XXX-comment: Finds the appropriate Value derived from an atomic load.
 // 'ChainedBB' contains all the blocks chained together with unconditional
 // branches from LI's parent BB to the block with the first store/cond branch.
index 1784e6f582949488b999b70d7f4c97e34bd57484..1536fd3d880fad5179228ff7588beee5ac08dec6 100644 (file)
@@ -186,6 +186,12 @@ void AddFakeConditionalBranch(Instruction* SplitInst, Value* Condition);
 // Returns true if the code is changed, and false otherwise.
 void TaintRelaxedLoads(Instruction* UsageInst, Instruction* InsertPoint);
 
+// Taints the 'Inst' (i.e., adds a fake conditional block that uses the 'Inst')
+// at the beginning of basic block 'BB'. Note that if 'Inst' does not dominate
+// 'BB', we need to add appropriate an PHI node and taint the PHI node. Returns
+// true if the code is changed, and false otherwise.
+void TaintAtBlockBeginning(Instruction* Inst, BasicBlock* BB, DominatorTree* DT);
+
 // XXX-comment: Finds the appropriate Value derived from an atomic load.
 // 'ChainedBB' contains all the blocks chained together with unconditional
 // branches from LI's parent BB to the block with the first store/cond branch.