Generates conditional branch instead of fake ones for Select instruction in some...
[oota-llvm.git] / lib / CodeGen / CodeGenPrepare.cpp
index 1a07bfc0c3577f71585153b63635d87173c47479..5c9858dcec2f3cc2cb0975322800992b670f96a1 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();
@@ -749,9 +751,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);
 }
 
@@ -779,8 +793,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;
 }