@@ -1621,11 +1621,90 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
16211621 // Note that even though we've just canonicalized this PHI, due to the
16221622 // worklist visitation order, there are no guarantess that *every* PHI
16231623 // has been canonicalized, so we can't just compare operands ranges.
1624- if (!PN.isIdenticalToWhenDefined (&IdenticalPN))
1625- continue ;
1626- // Just use that PHI instead then.
1627- ++NumPHICSEs;
1628- return replaceInstUsesWith (PN, &IdenticalPN);
1624+ if (PN.isIdenticalToWhenDefined (&IdenticalPN)) {
1625+ // Just use that PHI instead then.
1626+ ++NumPHICSEs;
1627+ return replaceInstUsesWith (PN, &IdenticalPN);
1628+ }
1629+
1630+ // Look for the following pattern and do PHI CSE to clean up the
1631+ // redundant %phi. Here %phi, %1 and %phi.next perform the same
1632+ // functionality as %identicalPhi and hence %phi can be eliminated.
1633+ //
1634+ // BB1:
1635+ // %identicalPhi = phi [ X, %BB0 ], [ %identicalPhi.next, %BB1 ]
1636+ // %phi = phi [ X, %BB0 ], [ %phi.next, %BB1 ]
1637+ // ...
1638+ // %identicalPhi.next = select %cmp, %val, %identicalPhi
1639+ // %1 = select %cmp2, %identicalPhi, float %phi
1640+ // %phi.next = select %cmp, %val, %1
1641+ //
1642+ // Prove that %phi and %identicalPhi are the same by induction:
1643+ //
1644+ // Base case: Both %phi and %identicalPhi are equal on entry to the loop.
1645+ // Inductive case:
1646+ // Suppose %phi and %identicalPhi are equal at iteration i.
1647+ // We look at their values at iteration i+1 which are %phi.next and
1648+ // %identicalPhi.next. They would have become different only when %cmp is
1649+ // false and the corresponding values %1 and %identicalPhi differ.
1650+ //
1651+ // The only condition when %1 and %identicalPh could differ is when %cmp2
1652+ // is false and %1 is %phi, which contradicts our inductive hypothesis
1653+ // that %phi and %identicalPhi are equal. Thus %phi and %identicalPhi are
1654+ // always equal at iteration i+1.
1655+
1656+ if (PN.getNumIncomingValues () == 2 && PN.getNumUses () == 1 ) {
1657+ unsigned diffVals = 0 ;
1658+ unsigned diffValIdx = 0 ;
1659+ // Check that only the backedge incoming value is different.
1660+ for (unsigned i = 0 ; i < 2 ; i++) {
1661+ if (PN.getIncomingValue (i) != IdenticalPN.getIncomingValue (i)) {
1662+ diffVals++;
1663+ diffValIdx = i;
1664+ }
1665+ }
1666+ BasicBlock *CurBB = PN.getParent ();
1667+ if (diffVals == 2 || PN.getIncomingBlock (diffValIdx) != CurBB)
1668+ continue ;
1669+ // Now check that the backedge incoming values are two select
1670+ // instructions that are in the same BB, and have the same condition,
1671+ // true value.
1672+ auto *Val = PN.getIncomingValue (diffValIdx);
1673+ auto *IdenticalVal = IdenticalPN.getIncomingValue (diffValIdx);
1674+ if (!isa<SelectInst>(Val) || !isa<SelectInst>(IdenticalVal))
1675+ continue ;
1676+
1677+ auto *SI = cast<SelectInst>(Val);
1678+ auto *IdenticalSI = cast<SelectInst>(IdenticalVal);
1679+ if (SI->getParent () != CurBB || IdenticalSI->getParent () != CurBB)
1680+ continue ;
1681+ if (SI->getCondition () != IdenticalSI->getCondition () ||
1682+ SI->getTrueValue () != IdenticalSI->getTrueValue ())
1683+ continue ;
1684+
1685+ // Now check that the false values, i.e., %1 and %identicalPhi,
1686+ // are essentially the same value within the same BB.
1687+ auto SameSelAndPhi = [&](SelectInst *SI, PHINode *IdenticalPN,
1688+ PHINode *PN) {
1689+ if (SI->getTrueValue () == IdenticalPN) {
1690+ return SI->getFalseValue () == PN;
1691+ }
1692+ return false ;
1693+ };
1694+ auto *FalseVal = SI->getFalseValue ();
1695+ auto *IdenticalSIFalseVal =
1696+ dyn_cast<PHINode>(IdenticalSI->getFalseValue ());
1697+ if (!isa<SelectInst>(FalseVal) || !IdenticalSIFalseVal ||
1698+ IdenticalSIFalseVal != &IdenticalPN)
1699+ continue ;
1700+ auto *FalseValSI = cast<SelectInst>(FalseVal);
1701+ if (FalseValSI->getParent () != CurBB ||
1702+ !SameSelAndPhi (FalseValSI, &IdenticalPN, &PN))
1703+ continue ;
1704+
1705+ ++NumPHICSEs;
1706+ return replaceInstUsesWith (PN, &IdenticalPN);
1707+ }
16291708 }
16301709
16311710 // If this is an integer PHI and we know that it has an illegal type, see if
0 commit comments