Nick pointed out on IRC that GVN's propagateEquality wasn't propagating

equalities into phi node operands for which the equality is known to
hold in the incoming basic block.  That's because replaceAllDominatedUsesWith
wasn't handling phi nodes correctly in general (that this didn't give wrong
results was just luck: the specific way GVN uses replaceAllDominatedUsesWith
precluded wrong changes to phi nodes).

llvm-svn: 152006
This commit is contained in:
Duncan Sands 2012-03-04 13:25:19 +00:00
parent a93fbd8fff
commit ccc56e1071
2 changed files with 28 additions and 1 deletions

View File

@ -1953,7 +1953,17 @@ unsigned GVN::replaceAllDominatedUsesWith(Value *From, Value *To,
for (Value::use_iterator UI = From->use_begin(), UE = From->use_end();
UI != UE; ) {
Use &U = (UI++).getUse();
if (DT->dominates(Root, cast<Instruction>(U.getUser())->getParent())) {
// If From occurs as a phi node operand then the use implicitly lives in the
// corresponding incoming block. Otherwise it is the block containing the
// user that must be dominated by Root.
BasicBlock *UsingBlock;
if (PHINode *PN = dyn_cast<PHINode>(U.getUser()))
UsingBlock = PN->getIncomingBlock(U);
else
UsingBlock = cast<Instruction>(U.getUser())->getParent();
if (DT->dominates(Root, UsingBlock)) {
U.set(To);
++Count;
}

View File

@ -232,3 +232,20 @@ cond_true2:
next2:
ret i32 0
}
; CHECK: @test12
define i32 @test12(i32 %x) {
%cmp = icmp eq i32 %x, 0
br i1 %cmp, label %cond_true, label %cond_false
cond_true:
br label %ret
cond_false:
br label %ret
ret:
%res = phi i32 [ %x, %cond_true ], [ %x, %cond_false ]
; CHECK: %res = phi i32 [ 0, %cond_true ], [ %x, %cond_false ]
ret i32 %res
}