Skip to content

Commit ee823bc

Browse files
Re-implemented in InstSimplify.
1 parent 4cfc7bf commit ee823bc

File tree

4 files changed

+339
-217
lines changed

4 files changed

+339
-217
lines changed

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4866,6 +4866,89 @@ static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F,
48664866
return nullptr;
48674867
}
48684868

4869+
// Look for the following pattern and simplify %1 to %identicalPhi.
4870+
// Here %phi, %1 and %phi.next perform the same functionality as
4871+
// %identicalPhi and hence the select instruction %1 can be folded
4872+
// into %identicalPhi.
4873+
//
4874+
// BB1:
4875+
// %identicalPhi = phi [ X, %BB0 ], [ %identicalPhi.next, %BB1 ]
4876+
// %phi = phi [ X, %BB0 ], [ %phi.next, %BB1 ]
4877+
// ...
4878+
// %identicalPhi.next = select %cmp, %val, %identicalPhi
4879+
// (or select %cmp, %identicalPhi, %val)
4880+
// %1 = select %cmp2, %identicalPhi, %phi
4881+
// %phi.next = select %cmp, %val, %1
4882+
// (or select %cmp, %1, %val)
4883+
//
4884+
// Prove that %phi and %identicalPhi are the same by induction:
4885+
//
4886+
// Base case: Both %phi and %identicalPhi are equal on entry to the loop.
4887+
// Inductive case:
4888+
// Suppose %phi and %identicalPhi are equal at iteration i.
4889+
// We look at their values at iteration i+1 which are %phi.next and
4890+
// %identicalPhi.next. They would have become different only when %cmp is
4891+
// false and the corresponding values %1 and %identicalPhi differ
4892+
// (similar reason for the other "or" case in the bracket).
4893+
//
4894+
// The only condition when %1 and %identicalPh could differ is when %cmp2
4895+
// is false and %1 is %phi, which contradicts our inductive hypothesis
4896+
// that %phi and %identicalPhi are equal. Thus %phi and %identicalPhi are
4897+
// always equal at iteration i+1.
4898+
bool isSimplifierIdenticalPHI(PHINode &PN, PHINode &IdenticalPN) {
4899+
if (PN.getParent() != IdenticalPN.getParent())
4900+
return false;
4901+
if (PN.getNumIncomingValues() != 2)
4902+
return false;
4903+
4904+
// Check that only the backedge incoming value is different.
4905+
unsigned DiffVals = 0;
4906+
BasicBlock *DiffValBB = nullptr;
4907+
for (unsigned i = 0; i < 2; i++) {
4908+
BasicBlock *PredBB = PN.getIncomingBlock(i);
4909+
if (PN.getIncomingValueForBlock(PredBB) !=
4910+
IdenticalPN.getIncomingValueForBlock(PredBB)) {
4911+
DiffVals++;
4912+
DiffValBB = PredBB;
4913+
}
4914+
}
4915+
if (DiffVals != 1)
4916+
return false;
4917+
// Now check that the backedge incoming values are two select
4918+
// instructions with the same condition. Either their true
4919+
// values are the same, or their false values are the same.
4920+
auto *SI = dyn_cast<SelectInst>(PN.getIncomingValueForBlock(DiffValBB));
4921+
auto *IdenticalSI =
4922+
dyn_cast<SelectInst>(IdenticalPN.getIncomingValueForBlock(DiffValBB));
4923+
if (!SI || !IdenticalSI)
4924+
return false;
4925+
if (SI->getCondition() != IdenticalSI->getCondition() ||
4926+
(SI->getTrueValue() != IdenticalSI->getTrueValue() &&
4927+
SI->getFalseValue() != IdenticalSI->getFalseValue()))
4928+
return false;
4929+
4930+
SelectInst *SIOtherVal = nullptr;
4931+
Value *IdenticalSIOtherVal = nullptr;
4932+
if (SI->getTrueValue() == IdenticalSI->getTrueValue()) {
4933+
SIOtherVal = dyn_cast<SelectInst>(SI->getFalseValue());
4934+
IdenticalSIOtherVal = IdenticalSI->getFalseValue();
4935+
} else {
4936+
SIOtherVal = dyn_cast<SelectInst>(SI->getTrueValue());
4937+
IdenticalSIOtherVal = IdenticalSI->getTrueValue();
4938+
}
4939+
4940+
// Now check that the other values in select, i.e., %1 and %identicalPhi,
4941+
// are essentially the same value within the same BB.
4942+
if (!SIOtherVal || IdenticalSIOtherVal != &IdenticalPN)
4943+
return false;
4944+
if (!(SIOtherVal->getTrueValue() == &IdenticalPN &&
4945+
SIOtherVal->getFalseValue() == &PN) &&
4946+
!(SIOtherVal->getTrueValue() == &PN &&
4947+
SIOtherVal->getFalseValue() == &IdenticalPN))
4948+
return false;
4949+
return true;
4950+
}
4951+
48694952
/// Given operands for a SelectInst, see if we can fold the result.
48704953
/// If not, this returns null.
48714954
static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
@@ -5041,7 +5124,14 @@ static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
50415124
std::optional<bool> Imp = isImpliedByDomCondition(Cond, Q.CxtI, Q.DL);
50425125
if (Imp)
50435126
return *Imp ? TrueVal : FalseVal;
5044-
5127+
// Look for same PHIs in the true and false values.
5128+
if (auto *TruePHI = dyn_cast<PHINode>(TrueVal))
5129+
if (auto *FalsePHI = dyn_cast<PHINode>(FalseVal)) {
5130+
if (isSimplifierIdenticalPHI(*TruePHI, *FalsePHI))
5131+
return FalseVal;
5132+
if (isSimplifierIdenticalPHI(*FalsePHI, *TruePHI))
5133+
return TrueVal;
5134+
}
50455135
return nullptr;
50465136
}
50475137

llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp

Lines changed: 5 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,101 +1621,11 @@ 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-
// 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-
// (or select %cmp, %identicalPhi, %val)
1640-
// %1 = select %cmp2, %identicalPhi, %phi
1641-
// %phi.next = select %cmp, %val, %1
1642-
// (or select %cmp, %1, %val)
1643-
//
1644-
// Prove that %phi and %identicalPhi are the same by induction:
1645-
//
1646-
// Base case: Both %phi and %identicalPhi are equal on entry to the loop.
1647-
// Inductive case:
1648-
// Suppose %phi and %identicalPhi are equal at iteration i.
1649-
// We look at their values at iteration i+1 which are %phi.next and
1650-
// %identicalPhi.next. They would have become different only when %cmp is
1651-
// false and the corresponding values %1 and %identicalPhi differ
1652-
// (similar reason for the other "or" case in the bracket).
1653-
//
1654-
// The only condition when %1 and %identicalPh could differ is when %cmp2
1655-
// is false and %1 is %phi, which contradicts our inductive hypothesis
1656-
// that %phi and %identicalPhi are equal. Thus %phi and %identicalPhi are
1657-
// always equal at iteration i+1.
1658-
1659-
if (PN.getNumIncomingValues() == 2) {
1660-
unsigned DiffVals = 0;
1661-
BasicBlock *DiffValBB = nullptr;
1662-
// Check that only the backedge incoming value is different.
1663-
for (unsigned i = 0; i < 2; i++) {
1664-
BasicBlock *PredBB = PN.getIncomingBlock(i);
1665-
if (PN.getIncomingValueForBlock(PredBB) !=
1666-
IdenticalPN.getIncomingValueForBlock(PredBB)) {
1667-
DiffVals++;
1668-
DiffValBB = PredBB;
1669-
}
1670-
}
1671-
1672-
if (DiffVals != 1)
1673-
continue;
1674-
// Now check that the backedge incoming values are two select
1675-
// instructions that are in the same BB, and have the same condition.
1676-
// Either their true values are the same, or their false values are
1677-
// the same.
1678-
auto *Val = PN.getIncomingValueForBlock(DiffValBB);
1679-
auto *IdenticalVal = IdenticalPN.getIncomingValueForBlock(DiffValBB);
1680-
if (!isa<SelectInst>(Val) || !isa<SelectInst>(IdenticalVal))
1681-
continue;
1682-
1683-
auto *SI = cast<SelectInst>(Val);
1684-
auto *IdenticalSI = cast<SelectInst>(IdenticalVal);
1685-
if (SI->getCondition() != IdenticalSI->getCondition() ||
1686-
(SI->getTrueValue() != IdenticalSI->getTrueValue() &&
1687-
SI->getFalseValue() != IdenticalSI->getFalseValue()))
1688-
continue;
1689-
Value *SIOtherVal = nullptr;
1690-
Value *IdenticalSIOtherVal = nullptr;
1691-
if (SI->getTrueValue() == IdenticalSI->getTrueValue()) {
1692-
SIOtherVal = SI->getFalseValue();
1693-
IdenticalSIOtherVal = IdenticalSI->getFalseValue();
1694-
} else {
1695-
SIOtherVal = SI->getTrueValue();
1696-
IdenticalSIOtherVal = IdenticalSI->getTrueValue();
1697-
}
1698-
1699-
// Now check that the other values in select, i.e., %1 and %identicalPhi,
1700-
// are essentially the same value within the same BB.
1701-
auto SameSelAndPhi = [&](SelectInst *SI, PHINode *IdenticalPN,
1702-
PHINode *PN) {
1703-
if (SI->getTrueValue() == IdenticalPN) {
1704-
return SI->getFalseValue() == PN;
1705-
}
1706-
return false;
1707-
};
1708-
if (!isa<SelectInst>(SIOtherVal) || !isa<PHINode>(IdenticalSIOtherVal))
1709-
continue;
1710-
if (cast<PHINode>(IdenticalSIOtherVal) != &IdenticalPN)
1711-
continue;
1712-
auto *SIOtherValAsSel = cast<SelectInst>(SIOtherVal);
1713-
if (!SameSelAndPhi(SIOtherValAsSel, &IdenticalPN, &PN))
1714-
continue;
1715-
1716-
++NumPHICSEs;
1717-
return replaceInstUsesWith(PN, &IdenticalPN);
1718-
}
1624+
if (!PN.isIdenticalToWhenDefined(&IdenticalPN))
1625+
continue;
1626+
// Just use that PHI instead then.
1627+
++NumPHICSEs;
1628+
return replaceInstUsesWith(PN, &IdenticalPN);
17191629
}
17201630

17211631
// If this is an integer PHI and we know that it has an illegal type, see if

llvm/test/Transforms/InstCombine/enhanced-phi-cse.ll

Lines changed: 0 additions & 121 deletions
This file was deleted.

0 commit comments

Comments
 (0)