Fixes a bug in finding the upcoming store/conditional branch instruction
[oota-llvm.git] / lib / CodeGen / CodeGenPrepare.cpp
index 1a07bfc0c3577f71585153b63635d87173c47479..d7037a9320013c7b5d427ff189558832a2ac0136 100644 (file)
@@ -518,6 +518,8 @@ Value* getRootDependence(Value* DepVal) {
 bool taintStoreAddress(StoreInst* SI, Value* DepVal,
                        const char* calling_func = __builtin_FUNCTION()) {
   DEBUG(dbgs() << "Called from " << calling_func << '\n');
+  // Set the insertion point right after the 'DepVal'.
+  Instruction* Inst = nullptr;
   IRBuilder<true, NoFolder> Builder(SI);
   BasicBlock* BB = SI->getParent();
   Value* Address = SI->getPointerOperand();
@@ -665,32 +667,23 @@ Instruction* findFirstStoreCondBranchInst(LoadInst* LI) {
   auto BE = BB->end();
   auto BBI = BasicBlock::iterator(LI);
   BBI++;
-  while (true) {
-    for (; BBI != BE; BBI++) {
-      auto* Inst = dyn_cast<Instruction>(&*BBI);
-      if (Inst == nullptr) {
-        continue;
-      }
-      if (Inst->getOpcode() == Instruction::Store) {
+  for (; BBI != BE; BBI++) {
+    auto* Inst = dyn_cast<Instruction>(&*BBI);
+    if (Inst == nullptr) {
+      continue;
+    }
+    if (Inst->getOpcode() == Instruction::Store) {
+      return Inst;
+    } else if (Inst->getOpcode() == Instruction::Br) {
+      auto* BrInst = dyn_cast<BranchInst>(Inst);
+      if (BrInst->isConditional()) {
         return Inst;
-      } else if (Inst->getOpcode() == Instruction::Br) {
-        auto* BrInst = dyn_cast<BranchInst>(Inst);
-        if (BrInst->isConditional()) {
-          return Inst;
-        } else {
-          // Reinitialize iterators with the destination of the unconditional
-          // branch.
-          BB = BrInst->getSuccessor(0);
-          BBI = BB->begin();
-          BE = BB->end();
-          break;
-        }
+      } else {
+        return nullptr;
       }
     }
-    if (BBI == BE) {
-      return nullptr;
-    }
   }
+  return nullptr;
 }
 
 // XXX-comment: Returns whether the code has been changed.
@@ -749,9 +742,21 @@ void AddFakeConditionalBranch(Instruction* SplitInst, Value* Condition) {
 
 // Returns true if the code is changed, and false otherwise.
 void TaintRelaxedLoads(LoadInst* LI) {
-  IRBuilder<true, NoFolder> Builder(LI->getNextNode());
+  // For better performance, we can add a "AND X 0" instruction before the
+  // condition.
+  auto* FirstInst = findFirstStoreCondBranchInst(LI);
+  Instruction* InsertPoint = nullptr;
+  if (FirstInst == nullptr) {
+    InsertPoint = LI->getParent()->getTerminator();
+    InsertPoint = LI->getNextNode();
+  } else {
+    InsertPoint = LI->getNextNode();
+  }
+  IRBuilder<true, NoFolder> Builder(InsertPoint);
+  auto* AndZero = dyn_cast<Instruction>(
+      Builder.CreateAnd(LI, Constant::getNullValue(LI->getType())));
   auto* FakeCondition = dyn_cast<Instruction>(Builder.CreateICmp(
-      CmpInst::ICMP_EQ, LI, Constant::getNullValue(LI->getType())));
+      CmpInst::ICMP_NE, AndZero, Constant::getNullValue(LI->getType())));
   AddFakeConditionalBranch(FakeCondition->getNextNode(), FakeCondition);
 }
 
@@ -766,7 +771,8 @@ bool AddFakeConditionalBranchAfterMonotonicLoads(
         if (StoreAddressDependOnValue(dyn_cast<StoreInst>(FirstInst), LI)) {
           continue;
         }
-      } else if (FirstInst->getOpcode() == Instruction::Br) {
+      } else if (FirstInst->getOpcode() == Instruction::Br &&
+                 isa<BranchInst>(FirstInst)) {
         if (ConditionalBranchDependsOnValue(dyn_cast<BranchInst>(FirstInst),
                                             LI)) {
           continue;
@@ -779,8 +785,15 @@ bool AddFakeConditionalBranchAfterMonotonicLoads(
     }
 
     // We really need to process the relaxed load now.
-    TaintRelaxedLoads(LI);
-    Changed = true;
+    StoreInst* SI = nullptr;;
+    if (FirstInst && (SI = dyn_cast<StoreInst>(FirstInst))) {
+      // For immediately coming stores, taint the address of the store.
+      taintStoreAddress(SI, LI);
+    } else {
+      // For immediately coming branch, directly add a fake branch.
+      TaintRelaxedLoads(LI);
+      Changed = true;
+    }
   }
   return Changed;
 }