diff --git a/lib/Transforms/Scalar/ConstantHoisting.cpp b/lib/Transforms/Scalar/ConstantHoisting.cpp index 28a31a97025..0fca617be7e 100644 --- a/lib/Transforms/Scalar/ConstantHoisting.cpp +++ b/lib/Transforms/Scalar/ConstantHoisting.cpp @@ -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,38 +281,6 @@ static void CollectBasicBlocks(SmallPtrSet &BBs, Function &F, BBs.insert(I->getParent()); } -/// \brief Find an insertion point that dominates all uses. -Instruction *ConstantHoisting:: -FindConstantInsertionPoint(Function &F, const ConstantInfo &CI) const { - BasicBlock *Entry = &F.getEntryBlock(); - - // Collect all basic blocks. - SmallPtrSet BBs; - ConstantInfo::RebasedConstantListType::const_iterator RCI, RCE; - for (RCI = CI.RebasedConstants.begin(), RCE = CI.RebasedConstants.end(); - RCI != RCE; ++RCI) - for (SmallVectorImpl::const_iterator U = RCI->Uses.begin(), - E = RCI->Uses.end(); U != E; ++U) - CollectBasicBlocks(BBs, F, *U); - - if (BBs.count(Entry)) - return Entry->getFirstInsertionPt(); - - while (BBs.size() >= 2) { - BasicBlock *BB, *BB1, *BB2; - BB1 = *BBs.begin(); - BB2 = *llvm::next(BBs.begin()); - BB = DT->findNearestCommonDominator(BB1, BB2); - if (BB == Entry) - return Entry->getFirstInsertionPt(); - 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) { @@ -325,6 +295,39 @@ static Instruction *getMatInsertPt(Instruction *I, const DominatorTree *DT) { return IDom->getTerminator(); } +/// \brief Find an insertion point that dominates all uses. +Instruction *ConstantHoisting:: +FindConstantInsertionPoint(Function &F, const ConstantInfo &CI) const { + BasicBlock *Entry = &F.getEntryBlock(); + + // Collect all basic blocks. + SmallPtrSet BBs; + ConstantInfo::RebasedConstantListType::const_iterator RCI, RCE; + for (RCI = CI.RebasedConstants.begin(), RCE = CI.RebasedConstants.end(); + RCI != RCE; ++RCI) + for (SmallVectorImpl::const_iterator U = RCI->Uses.begin(), + E = RCI->Uses.end(); U != E; ++U) + CollectBasicBlocks(BBs, F, *U); + + if (BBs.count(Entry)) + return getMatInsertPt(&Entry->front(), DT); + + while (BBs.size() >= 2) { + BasicBlock *BB, *BB1, *BB2; + BB1 = *BBs.begin(); + BB2 = *llvm::next(BBs.begin()); + BB = DT->findNearestCommonDominator(BB1, BB2); + if (BB == Entry) + return getMatInsertPt(&Entry->front(), DT); + BBs.erase(BB1); + BBs.erase(BB2); + BBs.insert(BB); + } + assert((BBs.size() == 1) && "Expected only one element."); + Instruction &FirstInst = (*BBs.begin())->front(); + return getMatInsertPt(&FirstInst, DT); +} + /// \brief Emit materialization code for all rebased constants and update their /// users. void ConstantHoisting::EmitBaseConstants(Function &F, User *U, diff --git a/test/Transforms/ConstantHoisting/X86/phi.ll b/test/Transforms/ConstantHoisting/X86/phi.ll index abbba81654a..cc2fdda40e7 100644 --- a/test/Transforms/ConstantHoisting/X86/phi.ll +++ b/test/Transforms/ConstantHoisting/X86/phi.ll @@ -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 +}