@@ -173,11 +173,11 @@ class SelectOptimizeImpl {
173173 return getTrueValue (/* HonorInverts=*/ false );
174174 if (auto *Sel = dyn_cast<SelectInst>(I))
175175 return Sel->getFalseValue ();
176- // Or(zext) case - return the operand which is not the zext.
177- if (auto *BO = dyn_cast<BinaryOperator>(I)) {
178- // Return non-dependant on condition operand
176+ // We are on the branch where the condition is zero, which means BinOp
177+ // does not perform any computation, and we can simply return the operand
178+ // that is not related to the condition
179+ if (auto *BO = dyn_cast<BinaryOperator>(I))
179180 return BO->getOperand (1 - CondIdx);
180- }
181181
182182 llvm_unreachable (" Unhandled case in getFalseValue" );
183183 }
@@ -199,7 +199,7 @@ class SelectOptimizeImpl {
199199 }
200200 // If getTrue(False)Value() return nullptr, it means we are dealing with
201201 // select-like instructions on the branch where the actual computation is
202- // happening In that case the cost is equal to the cost of computation +
202+ // happening. In that case the cost is equal to the cost of computation +
203203 // cost of non-dependant on condition operand
204204 InstructionCost Cost = TTI->getArithmeticInstrCost (
205205 getI ()->getOpcode (), I->getType (), TargetTransformInfo::TCK_Latency,
@@ -208,9 +208,8 @@ class SelectOptimizeImpl {
208208 auto TotalCost = Scaled64::get (*Cost.getValue ());
209209 if (auto *OpI = dyn_cast<Instruction>(I->getOperand (1 - CondIdx))) {
210210 auto It = InstCostMap.find (OpI);
211- if (It != InstCostMap.end ()) {
211+ if (It != InstCostMap.end ())
212212 TotalCost += It->second .NonPredCost ;
213- }
214213 }
215214 return TotalCost;
216215 }
@@ -774,65 +773,69 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
774773 SmallPtrSet<Instruction *, 2 > SeenCmp;
775774 std::map<Value *, SelectLikeInfo> SelectInfo;
776775
777- BasicBlock::iterator BBIt = BB.begin ();
778- while (BBIt != BB.end ()) {
779- Instruction *I = &*BBIt++;
776+ auto ProcessSelectInfo = [&SeenCmp, &SelectInfo](Instruction *I) -> void {
780777 if (auto *Cmp = dyn_cast<CmpInst>(I)) {
781778 SeenCmp.insert (Cmp);
782- continue ;
779+ return ;
783780 }
784781
785782 Value *Cond;
786783 if (match (I, m_OneUse (m_ZExt (m_Value (Cond)))) &&
787784 Cond->getType ()->isIntegerTy (1 )) {
788785 bool Inverted = match (Cond, m_Not (m_Value (Cond)));
789786 SelectInfo[I] = {Cond, true , Inverted, 0 };
790- continue ;
787+ return ;
791788 }
792789
793790 if (match (I, m_Not (m_Value (Cond)))) {
794791 SelectInfo[I] = {Cond, true , true , 0 };
795- continue ;
792+ return ;
796793 }
797794
798795 // Select instruction are what we are usually looking for.
799796 if (match (I, m_Select (m_Value (Cond), m_Value (), m_Value ()))) {
800797 bool Inverted = match (Cond, m_Not (m_Value (Cond)));
801798 SelectInfo[I] = {Cond, false , Inverted, 0 };
802- continue ;
799+ return ;
803800 }
804801
805- // An Or(zext(i1 X), Y) can also be treated like a select, with condition
802+ // An Or(zext(i1 X), Y) can also be treated like a select, with condition X
803+ // and values Y|1 and Y.
806804 if (auto *BO = dyn_cast<BinaryOperator>(I)) {
807805 if (BO->getType ()->isIntegerTy (1 ) || BO->getOpcode () != Instruction::Or)
808- continue ;
806+ return ;
809807
810808 for (unsigned Idx = 0 ; Idx < 2 ; Idx++) {
811809 auto *Op = BO->getOperand (Idx);
812- if (SelectInfo.count (Op) && SelectInfo[Op].IsAuxiliary ) {
813- Cond = SelectInfo[Op].Cond ;
814- bool Inverted = SelectInfo[Op].IsInverted ;
815- SelectInfo[I] = {Cond, false , Inverted, Idx};
810+ auto It = SelectInfo.find (Op);
811+ if (It != SelectInfo.end () && It->second .IsAuxiliary ) {
812+ SelectInfo[I] = {It->second .Cond , false , It->second .IsInverted , Idx};
816813 break ;
817814 }
818815 }
819- continue ;
820816 }
821- }
817+ };
822818
823- BBIt = BB.begin ();
819+ bool AlreadyProcessed = false ;
820+ BasicBlock::iterator BBIt = BB.begin ();
824821 while (BBIt != BB.end ()) {
825822 Instruction *I = &*BBIt++;
826- if (!SelectInfo.count (I) || SelectInfo[I].IsAuxiliary )
823+ if (!AlreadyProcessed)
824+ ProcessSelectInfo (I);
825+ else
826+ AlreadyProcessed = false ;
827+
828+ auto It = SelectInfo.find (I);
829+ if (It == SelectInfo.end () || It->second .IsAuxiliary )
827830 continue ;
828831
829832 if (!TTI->shouldTreatInstructionLikeSelect (I))
830833 continue ;
831834
832- Value *Cond = SelectInfo[I] .Cond ;
835+ Value *Cond = It-> second .Cond ;
833836 SelectGroup SIGroup{Cond};
834- SIGroup.Selects .emplace_back (I, SelectInfo[I] .IsInverted ,
835- SelectInfo[I] .ConditionIdx );
837+ SIGroup.Selects .emplace_back (I, It-> second .IsInverted ,
838+ It-> second .ConditionIdx );
836839
837840 if (!Cond->getType ()->isIntegerTy (1 ))
838841 continue ;
@@ -844,20 +847,26 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
844847
845848 while (BBIt != BB.end ()) {
846849 Instruction *NI = &*BBIt;
850+ ProcessSelectInfo (NI);
847851 // Debug/pseudo instructions should be skipped and not prevent the
848852 // formation of a select group.
849853 if (NI->isDebugOrPseudoInst ()) {
850854 ++BBIt;
851855 continue ;
852856 }
853857
854- if (!SelectInfo.count (NI))
858+ It = SelectInfo.find (NI);
859+ if (It == SelectInfo.end ()) {
860+ AlreadyProcessed = true ;
855861 break ;
862+ }
856863
857864 // Auxiliary with same condition
858- auto [CurrCond, IsAux, IsRev, CondIdx] = SelectInfo[NI];
859- if (Cond != CurrCond)
865+ auto [CurrCond, IsAux, IsRev, CondIdx] = It->second ;
866+ if (Cond != CurrCond) {
867+ AlreadyProcessed = true ;
860868 break ;
869+ }
861870
862871 if (!IsAux)
863872 SIGroup.Selects .emplace_back (NI, IsRev, CondIdx);
0 commit comments