@@ -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 %to_fold to %identicalPhi.
4870+ // / Here %phi, %to_fold and %phi.next perform the same functionality as
4871+ // / %identicalPhi and hence the select instruction %to_fold 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+ // / %to_fold = select %cmp2, %identicalPhi, %phi
4881+ // / %phi.next = select %cmp, %val, %to_fold
4882+ // / (or select %cmp, %to_fold, %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 %to_fold and %identicalPhi differ
4892+ // / (similar reason for the other "or" case in the bracket).
4893+ // /
4894+ // / The only condition when %to_fold and %identicalPh could differ is when %cmp2
4895+ // / is false and %to_fold 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 isSelectWithIdenticalPHI (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.getIncomingValue (i) !=
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+ return false ;
4927+
4928+ SelectInst *SIOtherVal = nullptr ;
4929+ Value *IdenticalSIOtherVal = nullptr ;
4930+ if (SI->getTrueValue () == IdenticalSI->getTrueValue ()) {
4931+ SIOtherVal = dyn_cast<SelectInst>(SI->getFalseValue ());
4932+ IdenticalSIOtherVal = IdenticalSI->getFalseValue ();
4933+ } else if (SI->getFalseValue () == IdenticalSI->getFalseValue ()) {
4934+ SIOtherVal = dyn_cast<SelectInst>(SI->getTrueValue ());
4935+ IdenticalSIOtherVal = IdenticalSI->getTrueValue ();
4936+ } else {
4937+ return false ;
4938+ }
4939+
4940+ // Now check that the other values in select, i.e., %to_fold and
4941+ // %identicalPhi, are essentially the same value.
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 (isSelectWithIdenticalPHI (*TruePHI, *FalsePHI))
5131+ return FalseVal;
5132+ if (isSelectWithIdenticalPHI (*FalsePHI, *TruePHI))
5133+ return TrueVal;
5134+ }
50455135 return nullptr ;
50465136}
50475137
0 commit comments