Implement PR1777 by detecting dependent phis that

all compute the same value.

llvm-svn: 43777
This commit is contained in:
Chris Lattner 2007-11-06 21:52:06 +00:00
parent dd71a5c37b
commit d8515f8e80
2 changed files with 93 additions and 0 deletions

View File

@ -8551,6 +8551,34 @@ static bool DeadPHICycle(PHINode *PN,
return false;
}
/// PHIsEqualValue - Return true if this phi node is always equal to
/// NonPhiInVal. This happens with mutually cyclic phi nodes like:
/// z = some value; x = phi (y, z); y = phi (x, z)
static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
SmallPtrSet<PHINode*, 16> &ValueEqualPHIs) {
// See if we already saw this PHI node.
if (!ValueEqualPHIs.insert(PN))
return true;
// Don't scan crazily complex things.
if (ValueEqualPHIs.size() == 16)
return false;
// Scan the operands to see if they are either phi nodes or are equal to
// the value.
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
Value *Op = PN->getIncomingValue(i);
if (PHINode *OpPN = dyn_cast<PHINode>(Op)) {
if (!PHIsEqualValue(OpPN, NonPhiInVal, ValueEqualPHIs))
return false;
} else if (Op != NonPhiInVal)
return false;
}
return true;
}
// PHINode simplification
//
Instruction *InstCombiner::visitPHINode(PHINode &PN) {
@ -8592,6 +8620,40 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
}
}
// We sometimes end up with phi cycles that non-obviously end up being the
// same value, for example:
// z = some value; x = phi (y, z); y = phi (x, z)
// where the phi nodes don't necessarily need to be in the same block. Do a
// quick check to see if the PHI node only contains a single non-phi value, if
// so, scan to see if the phi cycle is actually equal to that value.
{
unsigned InValNo = 0, NumOperandVals = PN.getNumIncomingValues();
// Scan for the first non-phi operand.
while (InValNo != NumOperandVals &&
isa<PHINode>(PN.getIncomingValue(InValNo)))
++InValNo;
if (InValNo != NumOperandVals) {
Value *NonPhiInVal = PN.getOperand(InValNo);
// Scan the rest of the operands to see if there are any conflicts, if so
// there is no need to recursively scan other phis.
for (++InValNo; InValNo != NumOperandVals; ++InValNo) {
Value *OpVal = PN.getIncomingValue(InValNo);
if (OpVal != NonPhiInVal && !isa<PHINode>(OpVal))
break;
}
// If we scanned over all operands, then we have one unique value plus
// phi values. Scan PHI nodes to see if they all merge in each other or
// the value.
if (InValNo == NumOperandVals) {
SmallPtrSet<PHINode*, 16> ValueEqualPHIs;
if (PHIsEqualValue(&PN, NonPhiInVal, ValueEqualPHIs))
return ReplaceInstUsesWith(PN, NonPhiInVal);
}
}
}
return 0;
}

View File

@ -0,0 +1,31 @@
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep {phi i32}
; PR1777
declare i1 @rrr()
define i1 @zxcv() {
entry:
%a = alloca i32
%i = ptrtoint i32* %a to i32
%b = call i1 @rrr()
br i1 %b, label %one, label %two
one:
%x = phi i32 [%i, %entry], [%y, %two]
%c = call i1 @rrr()
br i1 %c, label %two, label %end
two:
%y = phi i32 [%i, %entry], [%x, %one]
%d = call i1 @rrr()
br i1 %d, label %one, label %end
end:
%f = phi i32 [ %x, %one], [%y, %two]
; Change the %f to %i, and the optimizer suddenly becomes a lot smarter
; even though %f must equal %i at this point
%g = inttoptr i32 %f to i32*
store i32 10, i32* %g
%z = call i1 @rrr()
ret i1 %z
}