@@ -592,6 +592,36 @@ static bool cmpExcludesZero(CmpInst::Predicate Pred, const Value *RHS) {
592592 return true ;
593593}
594594
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+
595625static bool isKnownNonZeroFromAssume (const Value *V, const SimplifyQuery &Q) {
596626 // Use of assumptions is context-sensitive. If we don't have a context, we
597627 // cannot use them!
@@ -1641,25 +1671,19 @@ static void computeKnownBitsFromOperator(const Operator *I,
16411671
16421672 Known.Zero .setAllBits ();
16431673 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);
16461678 // 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 ;
16561681
16571682 // Change the context instruction to the "edge" that flows into the
16581683 // phi. This is important because that is where the value is actually
16591684 // "evaluated" even though it is used later somewhere else. (see also
16601685 // D69571).
1661- SimplifyQuery RecQ = Q.getWithoutCondContext ();
1662- RecQ.CxtI = P->getIncomingBlock (u)->getTerminator ();
1686+ SimplifyQuery RecQ = Q.getWithoutCondContext ().getWithInstruction (CxtI);
16631687
16641688 Known2 = KnownBits (BitWidth);
16651689
@@ -6053,30 +6077,13 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
60536077 bool First = true ;
60546078
60556079 for (const Use &U : P->operands ()) {
6056- Value *IncValue = U.get ();
6080+ Value *IncValue;
6081+ Instruction *CxtI;
6082+ breakSelfRecursivePHI (&U, P, IncValue, CxtI);
60576083 // Skip direct self references.
60586084 if (IncValue == P)
60596085 continue ;
60606086
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-
60806087 KnownFPClass KnownSrc;
60816088 // Recurse, but cap the recursion to two levels, because we don't want
60826089 // to waste time spinning around in loops. We need at least depth 2 to
0 commit comments