@@ -592,6 +592,36 @@ static bool cmpExcludesZero(CmpInst::Predicate Pred, const Value *RHS) {
592
592
return true ;
593
593
}
594
594
595
+ static void breakSelfRecursivePHI (const Use *U, const PHINode *PHI,
596
+ Value *&ValOut, Instruction *&CtxIOut) {
597
+ ValOut = U->get ();
598
+ if (ValOut == PHI)
599
+ return ;
600
+ CtxIOut = PHI->getIncomingBlock (*U)->getTerminator ();
601
+ Value *V;
602
+ // If the Use is a select of this phi, compute analysis on other arm to break
603
+ // recursion.
604
+ // TODO: Min/Max
605
+ if (match (ValOut, m_Select (m_Value (), m_Specific (PHI), m_Value (V))) ||
606
+ match (ValOut, m_Select (m_Value (), m_Value (V), m_Specific (PHI))))
607
+ ValOut = V;
608
+
609
+ // Same for select, if this phi is 2-operand phi, compute analysis on other
610
+ // incoming value to break recursion.
611
+ // TODO: We could handle any number of incoming edges as long as we only have
612
+ // two unique values.
613
+ else if (auto *IncPhi = dyn_cast<PHINode>(ValOut);
614
+ IncPhi && IncPhi->getNumIncomingValues () == 2 ) {
615
+ for (int Idx = 0 ; Idx < 2 ; ++Idx) {
616
+ if (IncPhi->getIncomingValue (Idx) == PHI) {
617
+ ValOut = IncPhi->getIncomingValue (1 - Idx);
618
+ CtxIOut = IncPhi->getIncomingBlock (1 - Idx)->getTerminator ();
619
+ break ;
620
+ }
621
+ }
622
+ }
623
+ }
624
+
595
625
static bool isKnownNonZeroFromAssume (const Value *V, const SimplifyQuery &Q) {
596
626
// Use of assumptions is context-sensitive. If we don't have a context, we
597
627
// cannot use them!
@@ -1641,25 +1671,19 @@ static void computeKnownBitsFromOperator(const Operator *I,
1641
1671
1642
1672
Known.Zero .setAllBits ();
1643
1673
Known.One .setAllBits ();
1644
- for (unsigned u = 0 , e = P->getNumIncomingValues (); u < e; ++u) {
1645
- Value *IncValue = P->getIncomingValue (u);
1674
+ for (const Use &U : P->operands ()) {
1675
+ Value *IncValue;
1676
+ Instruction *CxtI;
1677
+ breakSelfRecursivePHI (&U, P, IncValue, CxtI);
1646
1678
// Skip direct self references.
1647
- if (IncValue == P) continue ;
1648
-
1649
- // If the Use is a select of this phi, use the knownbit of the other
1650
- // operand to break the recursion.
1651
- if (auto *SI = dyn_cast<SelectInst>(IncValue)) {
1652
- if (SI->getTrueValue () == P || SI->getFalseValue () == P)
1653
- IncValue = SI->getTrueValue () == P ? SI->getFalseValue ()
1654
- : SI->getTrueValue ();
1655
- }
1679
+ if (IncValue == P)
1680
+ continue ;
1656
1681
1657
1682
// Change the context instruction to the "edge" that flows into the
1658
1683
// phi. This is important because that is where the value is actually
1659
1684
// "evaluated" even though it is used later somewhere else. (see also
1660
1685
// D69571).
1661
- SimplifyQuery RecQ = Q.getWithoutCondContext ();
1662
- RecQ.CxtI = P->getIncomingBlock (u)->getTerminator ();
1686
+ SimplifyQuery RecQ = Q.getWithoutCondContext ().getWithInstruction (CxtI);
1663
1687
1664
1688
Known2 = KnownBits (BitWidth);
1665
1689
@@ -6053,30 +6077,13 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
6053
6077
bool First = true ;
6054
6078
6055
6079
for (const Use &U : P->operands ()) {
6056
- Value *IncValue = U.get ();
6080
+ Value *IncValue;
6081
+ Instruction *CxtI;
6082
+ breakSelfRecursivePHI (&U, P, IncValue, CxtI);
6057
6083
// Skip direct self references.
6058
6084
if (IncValue == P)
6059
6085
continue ;
6060
6086
6061
- Instruction *CxtI = P->getIncomingBlock (U)->getTerminator ();
6062
-
6063
- // If the Use is a select of this phi, use the fp class of the other
6064
- // operand to break the recursion. Same around 2-operand phi nodes
6065
- Value *V;
6066
- if (match (IncValue, m_Select (m_Value (), m_Specific (P), m_Value (V))) ||
6067
- match (IncValue, m_Select (m_Value (), m_Value (V), m_Specific (P)))) {
6068
- IncValue = V;
6069
- } else if (auto *IncPhi = dyn_cast<PHINode>(IncValue);
6070
- IncPhi && IncPhi->getNumIncomingValues () == 2 ) {
6071
- for (int Idx = 0 ; Idx < 2 ; ++Idx) {
6072
- if (IncPhi->getIncomingValue (Idx) == P) {
6073
- IncValue = IncPhi->getIncomingValue (1 - Idx);
6074
- CxtI = IncPhi->getIncomingBlock (1 - Idx)->getTerminator ();
6075
- break ;
6076
- }
6077
- }
6078
- }
6079
-
6080
6087
KnownFPClass KnownSrc;
6081
6088
// Recurse, but cap the recursion to two levels, because we don't want
6082
6089
// to waste time spinning around in loops. We need at least depth 2 to
0 commit comments