1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[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

llvm-svn: 201009
This commit is contained in:
Juergen Ributzka 2014-02-08 00:20:49 +00:00
parent 5435f3e6f6
commit a44e3756e3
2 changed files with 57 additions and 32 deletions

View 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 {
@ -294,7 +310,7 @@ FindConstantInsertionPoint(Function &F, const ConstantInfo &CI) const {
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

View 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
}