@@ -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.
48714954static  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
0 commit comments