@@ -916,24 +916,22 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL,
916916 if (It == VL.end())
917917 return InstructionsState::invalid();
918918
919- Value *V = *It;
919+ Instruction *MainOp = cast<Instruction>( *It) ;
920920 unsigned InstCnt = std::count_if(It, VL.end(), IsaPred<Instruction>);
921- if ((VL.size() > 2 && !isa<PHINode>(V ) && InstCnt < VL.size() / 2) ||
921+ if ((VL.size() > 2 && !isa<PHINode>(MainOp ) && InstCnt < VL.size() / 2) ||
922922 (VL.size() == 2 && InstCnt < 2))
923923 return InstructionsState::invalid();
924924
925- bool IsCastOp = isa<CastInst>(V);
926- bool IsBinOp = isa<BinaryOperator>(V);
927- bool IsCmpOp = isa<CmpInst>(V);
928- CmpInst::Predicate BasePred =
929- IsCmpOp ? cast<CmpInst>(V)->getPredicate() : CmpInst::BAD_ICMP_PREDICATE;
930- unsigned Opcode = cast<Instruction>(V)->getOpcode();
925+ bool IsCastOp = isa<CastInst>(MainOp);
926+ bool IsBinOp = isa<BinaryOperator>(MainOp);
927+ bool IsCmpOp = isa<CmpInst>(MainOp);
928+ CmpInst::Predicate BasePred = IsCmpOp ? cast<CmpInst>(MainOp)->getPredicate()
929+ : CmpInst::BAD_ICMP_PREDICATE;
930+ Instruction *AltOp = MainOp;
931+ unsigned Opcode = MainOp->getOpcode();
931932 unsigned AltOpcode = Opcode;
932- unsigned AltIndex = std::distance(VL.begin(), It);
933933
934- bool SwappedPredsCompatible = [&]() {
935- if (!IsCmpOp)
936- return false;
934+ bool SwappedPredsCompatible = IsCmpOp && [&]() {
937935 SetVector<unsigned> UniquePreds, UniqueNonSwappedPreds;
938936 UniquePreds.insert(BasePred);
939937 UniqueNonSwappedPreds.insert(BasePred);
@@ -956,18 +954,18 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL,
956954 }();
957955 // Check for one alternate opcode from another BinaryOperator.
958956 // TODO - generalize to support all operators (types, calls etc.).
959- auto *IBase = cast<Instruction>(V);
960957 Intrinsic::ID BaseID = 0;
961958 SmallVector<VFInfo> BaseMappings;
962- if (auto *CallBase = dyn_cast<CallInst>(IBase )) {
959+ if (auto *CallBase = dyn_cast<CallInst>(MainOp )) {
963960 BaseID = getVectorIntrinsicIDForCall(CallBase, &TLI);
964961 BaseMappings = VFDatabase(*CallBase).getMappings(*CallBase);
965962 if (!isTriviallyVectorizable(BaseID) && BaseMappings.empty())
966963 return InstructionsState::invalid();
967964 }
968965 bool AnyPoison = InstCnt != VL.size();
969- for (int Cnt = 0, E = VL.size(); Cnt < E; Cnt++) {
970- auto *I = dyn_cast<Instruction>(VL[Cnt]);
966+ // Skip MainOp.
967+ for (Value *V : iterator_range(It + 1, VL.end())) {
968+ auto *I = dyn_cast<Instruction>(V);
971969 if (!I)
972970 continue;
973971
@@ -983,11 +981,11 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL,
983981 if (Opcode == AltOpcode && isValidForAlternation(InstOpcode) &&
984982 isValidForAlternation(Opcode)) {
985983 AltOpcode = InstOpcode;
986- AltIndex = Cnt ;
984+ AltOp = I ;
987985 continue;
988986 }
989987 } else if (IsCastOp && isa<CastInst>(I)) {
990- Value *Op0 = IBase ->getOperand(0);
988+ Value *Op0 = MainOp ->getOperand(0);
991989 Type *Ty0 = Op0->getType();
992990 Value *Op1 = I->getOperand(0);
993991 Type *Ty1 = Op1->getType();
@@ -999,12 +997,12 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL,
999997 isValidForAlternation(InstOpcode) &&
1000998 "Cast isn't safe for alternation, logic needs to be updated!");
1001999 AltOpcode = InstOpcode;
1002- AltIndex = Cnt ;
1000+ AltOp = I ;
10031001 continue;
10041002 }
10051003 }
1006- } else if (auto *Inst = dyn_cast<CmpInst>(VL[Cnt] ); Inst && IsCmpOp) {
1007- auto *BaseInst = cast<CmpInst>(V );
1004+ } else if (auto *Inst = dyn_cast<CmpInst>(I ); Inst && IsCmpOp) {
1005+ auto *BaseInst = cast<CmpInst>(MainOp );
10081006 Type *Ty0 = BaseInst->getOperand(0)->getType();
10091007 Type *Ty1 = Inst->getOperand(0)->getType();
10101008 if (Ty0 == Ty1) {
@@ -1018,21 +1016,21 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL,
10181016 CmpInst::Predicate SwappedCurrentPred =
10191017 CmpInst::getSwappedPredicate(CurrentPred);
10201018
1021- if ((E == 2 || SwappedPredsCompatible) &&
1019+ if ((VL.size() == 2 || SwappedPredsCompatible) &&
10221020 (BasePred == CurrentPred || BasePred == SwappedCurrentPred))
10231021 continue;
10241022
10251023 if (isCmpSameOrSwapped(BaseInst, Inst, TLI))
10261024 continue;
1027- auto *AltInst = cast<CmpInst>(VL[AltIndex] );
1028- if (AltIndex ) {
1025+ auto *AltInst = cast<CmpInst>(AltOp );
1026+ if (MainOp != AltOp ) {
10291027 if (isCmpSameOrSwapped(AltInst, Inst, TLI))
10301028 continue;
10311029 } else if (BasePred != CurrentPred) {
10321030 assert(
10331031 isValidForAlternation(InstOpcode) &&
10341032 "CmpInst isn't safe for alternation, logic needs to be updated!");
1035- AltIndex = Cnt ;
1033+ AltOp = I ;
10361034 continue;
10371035 }
10381036 CmpInst::Predicate AltPred = AltInst->getPredicate();
@@ -1046,17 +1044,17 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL,
10461044 "CastInst.");
10471045 if (auto *Gep = dyn_cast<GetElementPtrInst>(I)) {
10481046 if (Gep->getNumOperands() != 2 ||
1049- Gep->getOperand(0)->getType() != IBase ->getOperand(0)->getType())
1047+ Gep->getOperand(0)->getType() != MainOp ->getOperand(0)->getType())
10501048 return InstructionsState::invalid();
10511049 } else if (auto *EI = dyn_cast<ExtractElementInst>(I)) {
10521050 if (!isVectorLikeInstWithConstOps(EI))
10531051 return InstructionsState::invalid();
10541052 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
1055- auto *BaseLI = cast<LoadInst>(IBase );
1053+ auto *BaseLI = cast<LoadInst>(MainOp );
10561054 if (!LI->isSimple() || !BaseLI->isSimple())
10571055 return InstructionsState::invalid();
10581056 } else if (auto *Call = dyn_cast<CallInst>(I)) {
1059- auto *CallBase = cast<CallInst>(IBase );
1057+ auto *CallBase = cast<CallInst>(MainOp );
10601058 if (Call->getCalledFunction() != CallBase->getCalledFunction())
10611059 return InstructionsState::invalid();
10621060 if (Call->hasOperandBundles() &&
@@ -1086,8 +1084,7 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL,
10861084 return InstructionsState::invalid();
10871085 }
10881086
1089- return InstructionsState(cast<Instruction>(V),
1090- cast<Instruction>(VL[AltIndex]));
1087+ return InstructionsState(MainOp, AltOp);
10911088}
10921089
10931090/// \returns true if all of the values in \p VL have the same type or false
0 commit comments