From 6f1819f2e6465d9a29b25b49a4d60864e50946f6 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Sat, 8 Feb 2014 00:20:49 +0000 Subject: [PATCH] [Constant Hoisting] Fix insertion point for constant materialization. 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 | 67 +++++++++++---------- test/Transforms/ConstantHoisting/X86/phi.ll | 22 +++++++ 2 files changed, 57 insertions(+), 32 deletions(-) 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 +}