[llvm] r295200 - Revert "[JumpThreading] Thread through guards"

Anna Thomas via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 15 09:08:29 PST 2017


Author: annat
Date: Wed Feb 15 11:08:29 2017
New Revision: 295200

URL: http://llvm.org/viewvc/llvm-project?rev=295200&view=rev
Log:
Revert "[JumpThreading] Thread through guards"

This reverts commit r294617.

We fail on an assert while trying to get a condition from an
unconditional branch.

Removed:
    llvm/trunk/test/Transforms/JumpThreading/guards.ll
Modified:
    llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h
    llvm/trunk/include/llvm/Transforms/Utils/Cloning.h
    llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
    llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
    llvm/trunk/unittests/Transforms/Utils/Cloning.cpp

Modified: llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h?rev=295200&r1=295199&r2=295200&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h (original)
+++ llvm/trunk/include/llvm/Transforms/Scalar/JumpThreading.h Wed Feb 15 11:08:29 2017
@@ -23,7 +23,6 @@
 #include "llvm/Analysis/LazyValueInfo.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/ValueHandle.h"
 
 namespace llvm {
@@ -63,7 +62,6 @@ class JumpThreadingPass : public PassInf
   std::unique_ptr<BlockFrequencyInfo> BFI;
   std::unique_ptr<BranchProbabilityInfo> BPI;
   bool HasProfileData = false;
-  bool HasGuards = false;
 #ifdef NDEBUG
   SmallPtrSet<const BasicBlock *, 16> LoopHeaders;
 #else
@@ -124,9 +122,6 @@ public:
   bool TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);
   bool TryToUnfoldSelectInCurrBB(BasicBlock *BB);
 
-  bool ProcessGuards(BasicBlock *BB);
-  bool ThreadGuard(BasicBlock *BB, IntrinsicInst *Guard, BranchInst *BI);
-
 private:
   BasicBlock *SplitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
                               const char *Suffix);

Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=295200&r1=295199&r2=295200&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/Cloning.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Wed Feb 15 11:08:29 2017
@@ -245,16 +245,6 @@ Loop *cloneLoopWithPreheader(BasicBlock
 void remapInstructionsInBlocks(const SmallVectorImpl<BasicBlock *> &Blocks,
                                ValueToValueMapTy &VMap);
 
-/// Split edge between BB and PredBB and duplicate all non-Phi instructions
-/// from BB between its beginning and the StopAt instruction into the split
-/// block. Phi nodes are not duplicated, but their uses are handled correctly:
-/// we replace them with the uses of corresponding Phi inputs. ValueMapping
-/// is used to map the original instructions from BB to their newly-created
-/// copies. Returns the split block.
-BasicBlock *
-DuplicateInstructionsInSplitBetween(BasicBlock *BB, BasicBlock *PredBB,
-                                    Instruction *StopAt,
-                                    ValueToValueMapTy &ValueMapping);
 } // end namespace llvm
 
 #endif // LLVM_TRANSFORMS_UTILS_CLONING_H

Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=295200&r1=295199&r2=295200&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Wed Feb 15 11:08:29 2017
@@ -30,13 +30,11 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/MDBuilder.h"
 #include "llvm/IR/Metadata.h"
-#include "llvm/IR/PatternMatch.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/Cloning.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/SSAUpdater.h"
 #include <algorithm>
@@ -171,9 +169,6 @@ bool JumpThreadingPass::runImpl(Function
   // When profile data is available, we need to update edge weights after
   // successful jump threading, which requires both BPI and BFI being available.
   HasProfileData = HasProfileData_;
-  auto *GuardDecl = F.getParent()->getFunction(
-      Intrinsic::getName(Intrinsic::experimental_guard));
-  HasGuards = GuardDecl && !GuardDecl->use_empty();
   if (HasProfileData) {
     BPI = std::move(BPI_);
     BFI = std::move(BFI_);
@@ -243,13 +238,10 @@ bool JumpThreadingPass::runImpl(Function
   return EverChanged;
 }
 
-/// Return the cost of duplicating a piece of this block from first non-phi
-/// and before StopAt instruction to thread across it. Stop scanning the block
-/// when exceeding the threshold. If duplication is impossible, returns ~0U.
-static unsigned getJumpThreadDuplicationCost(BasicBlock *BB,
-                                             Instruction *StopAt,
+/// getJumpThreadDuplicationCost - Return the cost of duplicating this block to
+/// thread across it. Stop scanning the block when passing the threshold.
+static unsigned getJumpThreadDuplicationCost(const BasicBlock *BB,
                                              unsigned Threshold) {
-  assert(StopAt->getParent() == BB && "Not an instruction from proper BB?");
   /// Ignore PHI nodes, these will be flattened when duplication happens.
   BasicBlock::const_iterator I(BB->getFirstNonPHI());
 
@@ -257,17 +249,15 @@ static unsigned getJumpThreadDuplication
   // branch, so they shouldn't count against the duplication cost.
 
   unsigned Bonus = 0;
-  if (BB->getTerminator() == StopAt) {
-    // Threading through a switch statement is particularly profitable.  If this
-    // block ends in a switch, decrease its cost to make it more likely to
-    // happen.
-    if (isa<SwitchInst>(StopAt))
-      Bonus = 6;
-
-    // The same holds for indirect branches, but slightly more so.
-    if (isa<IndirectBrInst>(StopAt))
-      Bonus = 8;
-  }
+  const TerminatorInst *BBTerm = BB->getTerminator();
+  // Threading through a switch statement is particularly profitable.  If this
+  // block ends in a switch, decrease its cost to make it more likely to happen.
+  if (isa<SwitchInst>(BBTerm))
+    Bonus = 6;
+
+  // The same holds for indirect branches, but slightly more so.
+  if (isa<IndirectBrInst>(BBTerm))
+    Bonus = 8;
 
   // Bump the threshold up so the early exit from the loop doesn't skip the
   // terminator-based Size adjustment at the end.
@@ -276,7 +266,7 @@ static unsigned getJumpThreadDuplication
   // Sum up the cost of each instruction until we get to the terminator.  Don't
   // include the terminator because the copy won't include it.
   unsigned Size = 0;
-  for (; &*I != StopAt; ++I) {
+  for (; !isa<TerminatorInst>(I); ++I) {
 
     // Stop scanning the block if we've reached the threshold.
     if (Size > Threshold)
@@ -722,10 +712,6 @@ bool JumpThreadingPass::ProcessBlock(Bas
   if (TryToUnfoldSelectInCurrBB(BB))
     return true;
 
-  // Look if we can propagate guards to predecessors.
-  if (HasGuards && ProcessGuards(BB))
-    return true;
-
   // What kind of constant we're looking for.
   ConstantPreference Preference = WantInteger;
 
@@ -1480,8 +1466,7 @@ bool JumpThreadingPass::ThreadEdge(Basic
     return false;
   }
 
-  unsigned JumpThreadCost =
-      getJumpThreadDuplicationCost(BB, BB->getTerminator(), BBDupThreshold);
+  unsigned JumpThreadCost = getJumpThreadDuplicationCost(BB, BBDupThreshold);
   if (JumpThreadCost > BBDupThreshold) {
     DEBUG(dbgs() << "  Not threading BB '" << BB->getName()
           << "' - Cost is too high: " << JumpThreadCost << "\n");
@@ -1769,8 +1754,7 @@ bool JumpThreadingPass::DuplicateCondBra
     return false;
   }
 
-  unsigned DuplicationCost =
-      getJumpThreadDuplicationCost(BB, BB->getTerminator(), BBDupThreshold);
+  unsigned DuplicationCost = getJumpThreadDuplicationCost(BB, BBDupThreshold);
   if (DuplicationCost > BBDupThreshold) {
     DEBUG(dbgs() << "  Not duplicating BB '" << BB->getName()
           << "' - Cost is too high: " << DuplicationCost << "\n");
@@ -2035,124 +2019,3 @@ bool JumpThreadingPass::TryToUnfoldSelec
   
   return false;
 }
-
-/// Try to propagate a guard from the current BB into one of its predecessors
-/// in case if another branch of execution implies that the condition of this
-/// guard is always true. Currently we only process the simplest case that
-/// looks like:
-///
-/// Start:
-///   %cond = ...
-///   br i1 %cond, label %T1, label %F1
-/// T1:
-///   br label %Merge
-/// F1:
-///   br label %Merge
-/// Merge:
-///   %condGuard = ...
-///   call void(i1, ...) @llvm.experimental.guard( i1 %condGuard )[ "deopt"() ]
-///
-/// And cond either implies condGuard or !condGuard. In this case all the
-/// instructions before the guard can be duplicated in both branches, and the
-/// guard is then threaded to one of them.
-bool JumpThreadingPass::ProcessGuards(BasicBlock *BB) {
-  using namespace PatternMatch;
-  // We only want to deal with two predecessors.
-  BasicBlock *Pred1, *Pred2;
-  auto PI = pred_begin(BB), PE = pred_end(BB);
-  if (PI == PE)
-    return false;
-  Pred1 = *PI++;
-  if (PI == PE)
-    return false;
-  Pred2 = *PI++;
-  if (PI != PE)
-    return false;
-
-  // Try to thread one of the guards of the block.
-  // TODO: Look up deeper than to immediate predecessor?
-  if (auto Parent = Pred1->getSinglePredecessor())
-    if (Parent == Pred2->getSinglePredecessor())
-      if (BranchInst *BI = dyn_cast<BranchInst>(Parent->getTerminator()))
-        for (auto &I : *BB)
-          if (match(&I, m_Intrinsic<Intrinsic::experimental_guard>()))
-            if (ThreadGuard(BB, cast<IntrinsicInst>(&I), BI))
-              return true;
-
-  return false;
-}
-
-/// Try to propagate the guard from BB which is the lower block of a diamond
-/// to one of its branches, in case if diamond's condition implies guard's
-/// condition.
-bool JumpThreadingPass::ThreadGuard(BasicBlock *BB, IntrinsicInst *Guard,
-                                    BranchInst *BI) {
-  Value *GuardCond = Guard->getArgOperand(0);
-  Value *BranchCond = BI->getCondition();
-  BasicBlock *TrueDest = BI->getSuccessor(0);
-  BasicBlock *FalseDest = BI->getSuccessor(1);
-
-  auto &DL = BB->getModule()->getDataLayout();
-  bool TrueDestIsSafe = false;
-  bool FalseDestIsSafe = false;
-
-  // True dest is safe if BranchCond => GuardCond.
-  auto Impl = isImpliedCondition(BranchCond, GuardCond, DL);
-  if (Impl && *Impl)
-    TrueDestIsSafe = true;
-  else {
-    // False dest is safe if !BranchCond => GuardCond.
-    Impl =
-        isImpliedCondition(BranchCond, GuardCond, DL, /* InvertAPred */ true);
-    if (Impl && *Impl)
-      FalseDestIsSafe = true;
-  }
-
-  if (!TrueDestIsSafe && !FalseDestIsSafe)
-    return false;
-
-  BasicBlock *UnguardedBlock = TrueDestIsSafe ? TrueDest : FalseDest;
-  BasicBlock *GuardedBlock = FalseDestIsSafe ? TrueDest : FalseDest;
-
-  ValueToValueMapTy UnguardedMapping, GuardedMapping;
-  Instruction *AfterGuard = Guard->getNextNode();
-  unsigned Cost = getJumpThreadDuplicationCost(BB, AfterGuard, BBDupThreshold);
-  if (Cost > BBDupThreshold)
-    return false;
-  // Duplicate all instructions before the guard and the guard itself to the
-  // branch where implication is not proved.
-  GuardedBlock = DuplicateInstructionsInSplitBetween(
-      BB, GuardedBlock, AfterGuard, GuardedMapping);
-  assert(GuardedBlock && "Could not create the guarded block?");
-  // Duplicate all instructions before the guard in the unguarded branch.
-  // Since we have successfully duplicated the guarded block and this block
-  // has fewer instructions, we expect it to succeed.
-  UnguardedBlock = DuplicateInstructionsInSplitBetween(BB, UnguardedBlock,
-                                                       Guard, UnguardedMapping);
-  assert(UnguardedBlock && "Could not create the unguarded block?");
-  DEBUG(dbgs() << "Moved guard " << *Guard << " to block "
-               << GuardedBlock->getName() << "\n");
-
-  // Some instructions before the guard may still have uses. For them, we need
-  // to create Phi nodes merging their copies in both guarded and unguarded
-  // branches. Those instructions that have no uses can be just removed.
-  SmallVector<Instruction *, 4> ToRemove;
-  for (auto BI = BB->begin(); &*BI != AfterGuard; ++BI)
-    if (!isa<PHINode>(&*BI))
-      ToRemove.push_back(&*BI);
-
-  Instruction *InsertionPoint = &*BB->getFirstInsertionPt();
-  assert(InsertionPoint && "Empty block?");
-  // Substitute with Phis & remove.
-  for (auto *Inst : reverse(ToRemove)) {
-    if (!Inst->use_empty()) {
-      PHINode *NewPN = PHINode::Create(Inst->getType(), 2);
-      NewPN->addIncoming(UnguardedMapping[Inst], UnguardedBlock);
-      NewPN->addIncoming(GuardedMapping[Inst], GuardedBlock);
-      NewPN->insertBefore(InsertionPoint);
-      Inst->replaceAllUsesWith(NewPN);
-    }
-    Inst->eraseFromParent();
-  }
-  return true;
-}

Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=295200&r1=295199&r2=295200&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Wed Feb 15 11:08:29 2017
@@ -747,40 +747,3 @@ Loop *llvm::cloneLoopWithPreheader(Basic
 
   return NewLoop;
 }
-
-/// \brief Duplicate non-Phi instructions from the beginning of block up to
-/// StopAt instruction into a split block between BB and its predecessor.
-BasicBlock *
-llvm::DuplicateInstructionsInSplitBetween(BasicBlock *BB, BasicBlock *PredBB,
-                                          Instruction *StopAt,
-                                          ValueToValueMapTy &ValueMapping) {
-  // We are going to have to map operands from the original BB block to the new
-  // copy of the block 'NewBB'.  If there are PHI nodes in BB, evaluate them to
-  // account for entry from PredBB.
-  BasicBlock::iterator BI = BB->begin();
-  for (; PHINode *PN = dyn_cast<PHINode>(BI); ++BI)
-    ValueMapping[PN] = PN->getIncomingValueForBlock(PredBB);
-
-  BasicBlock *NewBB = SplitEdge(PredBB, BB);
-  NewBB->setName(PredBB->getName() + ".split");
-  Instruction *NewTerm = NewBB->getTerminator();
-
-  // Clone the non-phi instructions of BB into NewBB, keeping track of the
-  // mapping and using it to remap operands in the cloned instructions.
-  for (; StopAt != &*BI; ++BI) {
-    Instruction *New = BI->clone();
-    New->setName(BI->getName());
-    New->insertBefore(NewTerm);
-    ValueMapping[&*BI] = New;
-
-    // Remap operands to patch up intra-block references.
-    for (unsigned i = 0, e = New->getNumOperands(); i != e; ++i)
-      if (Instruction *Inst = dyn_cast<Instruction>(New->getOperand(i))) {
-        auto I = ValueMapping.find(Inst);
-        if (I != ValueMapping.end())
-          New->setOperand(i, I->second);
-      }
-  }
-
-  return NewBB;
-}

Removed: llvm/trunk/test/Transforms/JumpThreading/guards.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/guards.ll?rev=295199&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/JumpThreading/guards.ll (original)
+++ llvm/trunk/test/Transforms/JumpThreading/guards.ll (removed)
@@ -1,132 +0,0 @@
-; RUN: opt < %s -jump-threading -dce -S | FileCheck %s
-
-declare void @llvm.experimental.guard(i1, ...)
-
-declare i32 @f1()
-declare i32 @f2()
-
-define i32 @branch_implies_guard(i32 %a) {
-; CHECK-LABEL: @branch_implies_guard(
-  %cond = icmp slt i32 %a, 10
-  br i1 %cond, label %T1, label %F1
-
-T1:
-; CHECK:       T1.split
-; CHECK:         %v1 = call i32 @f1()
-; CHECK-NEXT:    %retVal
-; CHECK-NEXT:    br label %Merge
-  %v1 = call i32 @f1()
-  br label %Merge
-
-F1:
-; CHECK:       F1.split
-; CHECK:         %v2 = call i32 @f2()
-; CHECK-NEXT:    %retVal
-; CHECK-NEXT:    %condGuard
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 %condGuard
-; CHECK-NEXT:    br label %Merge
-  %v2 = call i32 @f2()
-  br label %Merge
-
-Merge:
-; CHECK:       Merge
-; CHECK-NOT:     call void(i1, ...) @llvm.experimental.guard(
-  %retPhi = phi i32 [ %v1, %T1 ], [ %v2, %F1 ]
-  %retVal = add i32 %retPhi, 10
-  %condGuard = icmp slt i32 %a, 20
-  call void(i1, ...) @llvm.experimental.guard( i1 %condGuard )[ "deopt"() ]
-  ret i32 %retVal
-}
-
-define i32 @not_branch_implies_guard(i32 %a) {
-; CHECK-LABEL: @not_branch_implies_guard(
-  %cond = icmp slt i32 %a, 20
-  br i1 %cond, label %T1, label %F1
-
-T1:
-; CHECK:       T1.split:
-; CHECK-NEXT:    %v1 = call i32 @f1()
-; CHECK-NEXT:    %retVal
-; CHECK-NEXT:    %condGuard
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 %condGuard
-; CHECK-NEXT:    br label %Merge
-  %v1 = call i32 @f1()
-  br label %Merge
-
-F1:
-; CHECK:       F1.split:
-; CHECK-NEXT:   %v2 = call i32 @f2()
-; CHECK-NEXT:   %retVal
-; CHECK-NEXT:   br label %Merge
-  %v2 = call i32 @f2()
-  br label %Merge
-
-Merge:
-; CHECK:       Merge
-; CHECK-NOT:     call void(i1, ...) @llvm.experimental.guard(
-  %retPhi = phi i32 [ %v1, %T1 ], [ %v2, %F1 ]
-  %retVal = add i32 %retPhi, 10
-  %condGuard = icmp sgt i32 %a, 10
-  call void(i1, ...) @llvm.experimental.guard( i1 %condGuard )[ "deopt"() ]
-  ret i32 %retVal
-}
-
-define i32 @branch_overlaps_guard(i32 %a) {
-; CHECK-LABEL: @branch_overlaps_guard(
-  %cond = icmp slt i32 %a, 20
-  br i1 %cond, label %T1, label %F1
-
-T1:
-; CHECK:        T1:
-; CHECK-NEXT:      %v1 = call i32 @f1()
-; CHECK-NEXT:      br label %Merge
-  %v1 = call i32 @f1()
-  br label %Merge
-
-F1:
-; CHECK:        F1:
-; CHECK-NEXT:     %v2 = call i32 @f2()
-; CHECK-NEXT:     br label %Merge
-  %v2 = call i32 @f2()
-  br label %Merge
-
-Merge:
-; CHECK:       Merge
-; CHECK:         %condGuard = icmp slt i32 %a, 10
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 %condGuard) [ "deopt"() ]
-  %retPhi = phi i32 [ %v1, %T1 ], [ %v2, %F1 ]
-  %retVal = add i32 %retPhi, 10
-  %condGuard = icmp slt i32 %a, 10
-  call void(i1, ...) @llvm.experimental.guard( i1 %condGuard )[ "deopt"() ]
-  ret i32 %retVal
-}
-
-define i32 @branch_doesnt_overlap_guard(i32 %a) {
-; CHECK-LABEL: @branch_doesnt_overlap_guard(
-  %cond = icmp slt i32 %a, 10
-  br i1 %cond, label %T1, label %F1
-
-T1:
-; CHECK:        T1:
-; CHECK-NEXT:      %v1 = call i32 @f1()
-; CHECK-NEXT:      br label %Merge
-  %v1 = call i32 @f1()
-  br label %Merge
-
-F1:
-; CHECK:        F1:
-; CHECK-NEXT:     %v2 = call i32 @f2()
-; CHECK-NEXT:     br label %Merge
-  %v2 = call i32 @f2()
-  br label %Merge
-
-Merge:
-; CHECK:       Merge
-; CHECK:         %condGuard = icmp sgt i32 %a, 20
-; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 %condGuard) [ "deopt"() ]
-  %retPhi = phi i32 [ %v1, %T1 ], [ %v2, %F1 ]
-  %retVal = add i32 %retPhi, 10
-  %condGuard = icmp sgt i32 %a, 20
-  call void(i1, ...) @llvm.experimental.guard( i1 %condGuard )[ "deopt"() ]
-  ret i32 %retVal
-}

Modified: llvm/trunk/unittests/Transforms/Utils/Cloning.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/Cloning.cpp?rev=295200&r1=295199&r2=295200&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/Cloning.cpp (original)
+++ llvm/trunk/unittests/Transforms/Utils/Cloning.cpp Wed Feb 15 11:08:29 2017
@@ -201,53 +201,6 @@ TEST_F(CloneInstruction, CallingConventi
   delete F2;
 }
 
-TEST_F(CloneInstruction, DuplicateInstructionsToSplit) {
-  Type *ArgTy1[] = {Type::getInt32PtrTy(context)};
-  FunctionType *FT = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
-  V = new Argument(Type::getInt32Ty(context));
-
-  Function *F = Function::Create(FT, Function::ExternalLinkage);
-
-  BasicBlock *BB1 = BasicBlock::Create(context, "", F);
-  IRBuilder<> Builder1(BB1);
-
-  BasicBlock *BB2 = BasicBlock::Create(context, "", F);
-  IRBuilder<> Builder2(BB2);
-
-  Builder1.CreateBr(BB2);
-
-  Instruction *AddInst = cast<Instruction>(Builder2.CreateAdd(V, V));
-  Instruction *MulInst = cast<Instruction>(Builder2.CreateMul(AddInst, V));
-  Instruction *SubInst = cast<Instruction>(Builder2.CreateSub(MulInst, V));
-  Builder2.CreateRetVoid();
-
-  ValueToValueMapTy Mapping;
-
-  auto Split = DuplicateInstructionsInSplitBetween(BB2, BB1, SubInst, Mapping);
-
-  EXPECT_TRUE(Split);
-  EXPECT_EQ(Mapping.size(), 2u);
-  EXPECT_TRUE(Mapping.find(AddInst) != Mapping.end());
-  EXPECT_TRUE(Mapping.find(MulInst) != Mapping.end());
-
-  auto AddSplit = dyn_cast<Instruction>(Mapping[AddInst]);
-  EXPECT_TRUE(AddSplit);
-  EXPECT_EQ(AddSplit->getOperand(0), V);
-  EXPECT_EQ(AddSplit->getOperand(1), V);
-  EXPECT_EQ(AddSplit->getParent(), Split);
-
-  auto MulSplit = dyn_cast<Instruction>(Mapping[MulInst]);
-  EXPECT_TRUE(MulSplit);
-  EXPECT_EQ(MulSplit->getOperand(0), AddSplit);
-  EXPECT_EQ(MulSplit->getOperand(1), V);
-  EXPECT_EQ(MulSplit->getParent(), Split);
-
-  EXPECT_EQ(AddSplit->getNextNode(), MulSplit);
-  EXPECT_EQ(MulSplit->getNextNode(), Split->getTerminator());
-
-  delete F;
-}
-
 class CloneFunc : public ::testing::Test {
 protected:
   void SetUp() override {




More information about the llvm-commits mailing list