@@ -500,6 +500,41 @@ static bool isSelect01(const APInt &C1I, const APInt &C2I) {
500
500
return C1I.isOne () || C1I.isAllOnes () || C2I.isOne () || C2I.isAllOnes ();
501
501
}
502
502
503
+ // / Try to simplify seletion chain with partially identical conditions, eg:
504
+ // / %s1 = select i1 %c1, i32 23, i32 45
505
+ // / %s2 = select i1 %c2, i32 666, i32 %s1
506
+ // / %s3 = select i1 %c1, i32 789, i32 %s2
507
+ // / -->
508
+ // / %s2 = select i1 %c2, i32 666, i32 45
509
+ // / %s3 = select i1 %c1, i32 789, i32 %s2
510
+ static bool simplifySeqSelectWithSameCond (SelectInst &SI,
511
+ const SimplifyQuery &SQ,
512
+ InstCombinerImpl &IC) {
513
+ Value *CondVal = SI.getCondition ();
514
+ Type *CondType = CondVal->getType ();
515
+ SelectInst *SINext = &SI;
516
+ Type *SelType = SINext->getType ();
517
+ Value *FalseVal = SINext->getFalseValue ();
518
+ Value *CondNext;
519
+ Value *FalseNext;
520
+ while (match (FalseVal,
521
+ m_Select (m_Value (CondNext), m_Value (), m_Value (FalseNext)))) {
522
+ // Only support the type of select is an integer type as float type need
523
+ // address FMF flag.
524
+ if (CondNext == CondVal && SelType->isIntOrIntVectorTy () &&
525
+ SINext->hasOneUse ()) {
526
+ IC.replaceOperand (*SINext, 2 , FalseNext);
527
+ return true ;
528
+ }
529
+
530
+ SINext = cast<SelectInst>(FalseVal);
531
+ SelType = SINext->getType ();
532
+ FalseVal = SINext->getFalseValue ();
533
+ }
534
+
535
+ return false ;
536
+ }
537
+
503
538
// / Try to fold the select into one of the operands to allow further
504
539
// / optimization.
505
540
Instruction *InstCombinerImpl::foldSelectIntoOp (SelectInst &SI, Value *TrueVal,
@@ -567,6 +602,9 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
567
602
if (Instruction *R = TryFoldSelectIntoOp (SI, FalseVal, TrueVal, true ))
568
603
return R;
569
604
605
+ if (simplifySeqSelectWithSameCond (SI, SQ, *this ))
606
+ return &SI;
607
+
570
608
return nullptr ;
571
609
}
572
610
0 commit comments