@@ -500,6 +500,42 @@ static bool isSelect01(const APInt &C1I, const APInt &C2I) {
500500 return C1I.isOne () || C1I.isAllOnes () || C2I.isOne () || C2I.isAllOnes ();
501501}
502502
503+ // / Try to simplify a select instruction when the user of its select user
504+ // / indicates the condition.
505+ static bool simplifySeqSelectWithSameCond (SelectInst &SI,
506+ const SimplifyQuery &SQ,
507+ InstCombinerImpl &IC) {
508+ Value *CondVal = SI.getCondition ();
509+ Type *CondType = CondVal->getType ();
510+
511+ SelectInst *SINext = &SI;
512+ Type *SelType = SINext->getType ();
513+ Value *FalseVal = SINext->getFalseValue ();
514+ Value *CondNext;
515+ Value *FalseNext;
516+ while (match (FalseVal,
517+ m_Select (m_Value (CondNext), m_Value (), m_Value (FalseNext)))) {
518+ // If the type of select is not an integer type or if the condition and
519+ // the selection type are not both scalar nor both vector types, there is no
520+ // point in attempting to match these patterns.
521+ if (!isa<Constant>(CondVal) && SelType->isIntOrIntVectorTy () &&
522+ CondType->isVectorTy () == SelType->isVectorTy ())
523+ if (CondNext == CondVal) {
524+ if (Value *S = simplifyWithOpReplaced (
525+ FalseVal, CondVal, ConstantInt::getFalse (CondType), SQ,
526+ /* AllowRefinement */ true )) {
527+ IC.replaceOperand (*SINext, 2 , S);
528+ return true ;
529+ }
530+ }
531+
532+ SINext = cast<SelectInst>(FalseVal);
533+ FalseVal = SINext->getFalseValue ();
534+ }
535+
536+ return false ;
537+ }
538+
503539// / Try to fold the select into one of the operands to allow further
504540// / optimization.
505541Instruction *InstCombinerImpl::foldSelectIntoOp (SelectInst &SI, Value *TrueVal,
@@ -557,6 +593,9 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
557593 if (Instruction *R = TryFoldSelectIntoOp (SI, FalseVal, TrueVal, true ))
558594 return R;
559595
596+ if (simplifySeqSelectWithSameCond (SI, SQ, *this ))
597+ return &SI;
598+
560599 return nullptr ;
561600}
562601
0 commit comments