[Constant Hoisting] Fix insertion point for constant materialization.
authorJuergen Ributzka <juergen@apple.com>
Sat, 8 Feb 2014 00:20:49 +0000 (00:20 +0000)
committerJuergen Ributzka <juergen@apple.com>
Sat, 8 Feb 2014 00:20:49 +0000 (00:20 +0000)
The bitcast instruction during constant materialization was not placed correcly
in the presence of phi nodes. This commit fixes the insertion point to be in the
idom instead.

This fixes PR18768

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201009 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/ConstantHoisting.cpp
test/Transforms/ConstantHoisting/X86/phi.ll

index 28a31a970252493e921b43ab2e2a2f94191d95c8..0fca617be7ed4080a341f059e7aebe9f70db05f3 100644 (file)
@@ -148,6 +148,8 @@ void ConstantHoisting::CollectConstant(User * U, unsigned Opcode,
     ConstantCandidate &CC = ConstantMap[C];
     CC.CumulativeCost += Cost;
     CC.Uses.push_back(U);
+    DEBUG(dbgs() << "Collect constant " << *C << " with cost " << Cost
+                 << " from " << *U << '\n');
   }
 }
 
@@ -279,6 +281,20 @@ static void CollectBasicBlocks(SmallPtrSet<BasicBlock *, 4> &BBs, Function &F,
           BBs.insert(I->getParent());
 }
 
+/// \brief Find the instruction we should insert the constant materialization
+/// before.
+static Instruction *getMatInsertPt(Instruction *I, const DominatorTree *DT) {
+  if (!isa<PHINode>(I) && !isa<LandingPadInst>(I)) // Simple case.
+    return I;
+
+  // We can't insert directly before a phi node or landing pad. Insert before
+  // the terminator of the dominating block.
+  assert(&I->getParent()->getParent()->getEntryBlock() != I->getParent() &&
+         "PHI or landing pad in entry block!");
+  BasicBlock *IDom = DT->getNode(I->getParent())->getIDom()->getBlock();
+  return IDom->getTerminator();
+}
+
 /// \brief Find an insertion point that dominates all uses.
 Instruction *ConstantHoisting::
 FindConstantInsertionPoint(Function &F, const ConstantInfo &CI) const {
@@ -291,10 +307,10 @@ FindConstantInsertionPoint(Function &F, const ConstantInfo &CI) const {
        RCI != RCE; ++RCI)
     for (SmallVectorImpl<User *>::const_iterator U = RCI->Uses.begin(),
          E = RCI->Uses.end(); U != E; ++U)
-        CollectBasicBlocks(BBs, F, *U);
+      CollectBasicBlocks(BBs, F, *U);
 
   if (BBs.count(Entry))
-    return Entry->getFirstInsertionPt();
+    return getMatInsertPt(&Entry->front(), DT);
 
   while (BBs.size() >= 2) {
     BasicBlock *BB, *BB1, *BB2;
@@ -302,27 +318,14 @@ FindConstantInsertionPoint(Function &F, const ConstantInfo &CI) const {
     BB2 = *llvm::next(BBs.begin());
     BB = DT->findNearestCommonDominator(BB1, BB2);
     if (BB == Entry)
-      return Entry->getFirstInsertionPt();
+      return getMatInsertPt(&Entry->front(), DT);
     BBs.erase(BB1);
     BBs.erase(BB2);
     BBs.insert(BB);
   }
   assert((BBs.size() == 1) && "Expected only one element.");
-  return (*BBs.begin())->getFirstInsertionPt();
-}
-
-/// \brief Find the instruction we should insert the constant materialization
-/// before.
-static Instruction *getMatInsertPt(Instruction *I, const DominatorTree *DT) {
-  if (!isa<PHINode>(I) && !isa<LandingPadInst>(I)) // Simple case.
-    return I;
-
-  // We can't insert directly before a phi node or landing pad. Insert before
-  // the terminator of the dominating block.
-  assert(&I->getParent()->getParent()->getEntryBlock() != I->getParent() &&
-         "PHI or landing pad in entry block!");
-  BasicBlock *IDom = DT->getNode(I->getParent())->getIDom()->getBlock();
-  return IDom->getTerminator();
+  Instruction &FirstInst = (*BBs.begin())->front();
+  return getMatInsertPt(&FirstInst, DT);
 }
 
 /// \brief Emit materialization code for all rebased constants and update their
index abbba81654a657860579dca1e5348bd228e82352..cc2fdda40e7b7d0477ca9c5559f84614a1f57c3f 100644 (file)
@@ -46,3 +46,25 @@ return:
 }
 
 declare void @foo(i8*)
+
+; PR18768
+define i32 @test3(i1 %c) {
+entry:
+  br i1 %c, label %if.then, label %if.end3
+
+if.then:                                          ; preds = %entry
+  br label %if.end3
+
+if.end3:                                          ; preds = %if.then, %entry
+  %d.0 = phi i32* [ inttoptr (i64 985162435264511 to i32*), %entry ], [ null, %if.then ]
+  %cmp4 = icmp eq i32* %d.0, inttoptr (i64 985162435264511 to i32*)
+  %cmp6 = icmp eq i32* %d.0, inttoptr (i64 985162418487296 to i32*)
+  %or = or i1 %cmp4, %cmp6
+  br i1 %or, label %if.then8, label %if.end9
+
+if.then8:                                         ; preds = %if.end3
+  ret i32 1
+
+if.end9:                                          ; preds = %if.then8, %if.end3
+  ret i32 undef
+}