From: Chris Lattner Date: Tue, 6 Nov 2007 21:52:06 +0000 (+0000) Subject: Implement PR1777 by detecting dependent phis that X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=cf5008a792ee6315e14ae76c2b7823213fd88146;p=oota-llvm.git Implement PR1777 by detecting dependent phis that all compute the same value. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43777 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 1a638c30884..41485b203ec 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -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 &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(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(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(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 ValueEqualPHIs; + if (PHIsEqualValue(&PN, NonPhiInVal, ValueEqualPHIs)) + return ReplaceInstUsesWith(PN, NonPhiInVal); + } + } + } return 0; } diff --git a/test/Transforms/InstCombine/phi-merge.ll b/test/Transforms/InstCombine/phi-merge.ll new file mode 100644 index 00000000000..daac41274cd --- /dev/null +++ b/test/Transforms/InstCombine/phi-merge.ll @@ -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 +}