@@ -6861,7 +6861,7 @@ BoUpSLP::getReorderingData(const TreeEntry &TE, bool TopToBottom,
68616861 return std::move(ResOrder);
68626862 }
68636863 if (TE.State == TreeEntry::StridedVectorize && !TopToBottom &&
6864- (!TE.UserTreeIndex ||
6864+ (!TE.UserTreeIndex || !TE.UserTreeIndex.UserTE->hasState() ||
68656865 !Instruction::isBinaryOp(TE.UserTreeIndex.UserTE->getOpcode())) &&
68666866 (TE.ReorderIndices.empty() || isReverseOrder(TE.ReorderIndices)))
68676867 return std::nullopt;
@@ -15704,7 +15704,8 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
1570415704 const BasicBlock *TEInsertBlock = nullptr;
1570515705 // Main node of PHI entries keeps the correct order of operands/incoming
1570615706 // blocks.
15707- if (auto *PHI = dyn_cast<PHINode>(TEUseEI.UserTE->getMainOp());
15707+ if (auto *PHI = dyn_cast_or_null<PHINode>(
15708+ TEUseEI.UserTE->hasState() ? TEUseEI.UserTE->getMainOp() : nullptr);
1570815709 PHI && TEUseEI.UserTE->State != TreeEntry::SplitVectorize) {
1570915710 TEInsertBlock = PHI->getIncomingBlock(TEUseEI.EdgeIdx);
1571015711 TEInsertPt = TEInsertBlock->getTerminator();
@@ -15803,7 +15804,8 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
1580315804 "Expected only single user of a gather node.");
1580415805 const EdgeInfo &UseEI = TEPtr->UserTreeIndex;
1580515806
15806- PHINode *UserPHI = UseEI.UserTE->State != TreeEntry::SplitVectorize
15807+ PHINode *UserPHI = (UseEI.UserTE->State != TreeEntry::SplitVectorize &&
15808+ UseEI.UserTE->hasState())
1580715809 ? dyn_cast<PHINode>(UseEI.UserTE->getMainOp())
1580815810 : nullptr;
1580915811 Instruction *InsertPt =
@@ -15816,7 +15818,8 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
1581615818 TEUseEI.UserTE->isAltShuffle()) &&
1581715819 all_of(TEUseEI.UserTE->Scalars, isUsedOutsideBlock)) {
1581815820 if (UseEI.UserTE->State != TreeEntry::Vectorize ||
15819- (UseEI.UserTE->getOpcode() == Instruction::PHI &&
15821+ (UseEI.UserTE->hasState() &&
15822+ UseEI.UserTE->getOpcode() == Instruction::PHI &&
1582015823 !UseEI.UserTE->isAltShuffle()) ||
1582115824 !all_of(UseEI.UserTE->Scalars, isUsedOutsideBlock))
1582215825 continue;
@@ -16438,24 +16441,31 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
1643816441 // Get the basic block this bundle is in. All instructions in the bundle
1643916442 // should be in this block (except for extractelement-like instructions with
1644016443 // constant indices or gathered loads or copyables).
16441- auto *Front = E->getMainOp();
16444+ Instruction *Front;
16445+ unsigned Opcode;
16446+ if (E->hasState()) {
16447+ Front = E->getMainOp();
16448+ Opcode = E->getOpcode();
16449+ } else {
16450+ Front = cast<Instruction>(*find_if(E->Scalars, IsaPred<Instruction>));
16451+ Opcode = Front->getOpcode();
16452+ }
1644216453 auto *BB = Front->getParent();
16443- assert(((GatheredLoadsEntriesFirst.has_value() &&
16444- E->getOpcode() == Instruction::Load && E->isGather() &&
16445- E->Idx < *GatheredLoadsEntriesFirst) ||
16446- E->State == TreeEntry::SplitVectorize || E->hasCopyableElements() ||
16447- all_of(E->Scalars,
16448- [=](Value *V) -> bool {
16449- if (E->getOpcode() == Instruction::GetElementPtr &&
16450- !isa<GetElementPtrInst>(V))
16451- return true;
16452- auto *I = dyn_cast<Instruction>(V);
16453- return !I || !E->getMatchingMainOpOrAltOp(I) ||
16454- I->getParent() == BB ||
16455- isVectorLikeInstWithConstOps(I);
16456- })) &&
16457- "Expected gathered loads or GEPs or instructions from same basic "
16458- "block.");
16454+ assert(
16455+ ((GatheredLoadsEntriesFirst.has_value() && Opcode == Instruction::Load &&
16456+ E->isGather() && E->Idx < *GatheredLoadsEntriesFirst) ||
16457+ E->State == TreeEntry::SplitVectorize || E->hasCopyableElements() ||
16458+ all_of(E->Scalars,
16459+ [=](Value *V) -> bool {
16460+ if (Opcode == Instruction::GetElementPtr &&
16461+ !isa<GetElementPtrInst>(V))
16462+ return true;
16463+ auto *I = dyn_cast<Instruction>(V);
16464+ return !I || !E->getMatchingMainOpOrAltOp(I) ||
16465+ I->getParent() == BB || isVectorLikeInstWithConstOps(I);
16466+ })) &&
16467+ "Expected gathered loads or GEPs or instructions from same basic "
16468+ "block.");
1645916469
1646016470 auto FindLastInst = [&]() {
1646116471 Instruction *LastInst = Front;
@@ -16470,13 +16480,13 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
1647016480 LastInst = I;
1647116481 continue;
1647216482 }
16473- assert(((E->getOpcode() == Instruction::GetElementPtr &&
16483+ assert(((Opcode == Instruction::GetElementPtr &&
1647416484 !isa<GetElementPtrInst>(I)) ||
1647516485 E->State == TreeEntry::SplitVectorize ||
1647616486 (isVectorLikeInstWithConstOps(LastInst) &&
1647716487 isVectorLikeInstWithConstOps(I)) ||
1647816488 (GatheredLoadsEntriesFirst.has_value() &&
16479- E->getOpcode() == Instruction::Load && E->isGather() &&
16489+ Opcode == Instruction::Load && E->isGather() &&
1648016490 E->Idx < *GatheredLoadsEntriesFirst)) &&
1648116491 "Expected vector-like or non-GEP in GEP node insts only.");
1648216492 if (!DT->isReachableFromEntry(LastInst->getParent())) {
@@ -16512,11 +16522,11 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
1651216522 FirstInst = I;
1651316523 continue;
1651416524 }
16515- assert(((E->getOpcode() == Instruction::GetElementPtr &&
16516- !isa<GetElementPtrInst>(I)) ||
16517- (isVectorLikeInstWithConstOps(FirstInst) &&
16518- isVectorLikeInstWithConstOps(I))) &&
16519- "Expected vector-like or non-GEP in GEP node insts only.");
16525+ assert(((Opcode == Instruction::GetElementPtr &&
16526+ !isa<GetElementPtrInst>(I)) ||
16527+ (isVectorLikeInstWithConstOps(FirstInst) &&
16528+ isVectorLikeInstWithConstOps(I))) &&
16529+ "Expected vector-like or non-GEP in GEP node insts only.");
1652016530 if (!DT->isReachableFromEntry(FirstInst->getParent())) {
1652116531 FirstInst = I;
1652216532 continue;
@@ -16554,7 +16564,7 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
1655416564 // Set insertpoint for gathered loads to the very first load.
1655516565 if (GatheredLoadsEntriesFirst.has_value() &&
1655616566 E->Idx >= *GatheredLoadsEntriesFirst && !E->isGather() &&
16557- E->getOpcode() == Instruction::Load) {
16567+ Opcode == Instruction::Load) {
1655816568 Res = FindFirstInst();
1655916569 EntryToLastInstruction.try_emplace(E, Res);
1656016570 return *Res;
@@ -16586,7 +16596,7 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
1658616596 };
1658716597 const ScheduleBundle *Bundle = FindScheduleBundle(E);
1658816598 if (!E->isGather() && !Bundle) {
16589- if ((E->getOpcode() == Instruction::GetElementPtr &&
16599+ if ((Opcode == Instruction::GetElementPtr &&
1659016600 any_of(E->Scalars,
1659116601 [](Value *V) {
1659216602 return !isa<GetElementPtrInst>(V) && isa<Instruction>(V);
@@ -21001,9 +21011,10 @@ void BoUpSLP::computeMinimumValueSizes() {
2100121011 if (!isa<CastInst, BinaryOperator, FreezeInst, PHINode,
2100221012 SelectInst>(U) ||
2100321013 isa<SIToFPInst, UIToFPInst>(U) ||
21004- !isa<CastInst, BinaryOperator, FreezeInst, PHINode,
21005- SelectInst>(UserTE->getMainOp()) ||
21006- isa<SIToFPInst, UIToFPInst>(UserTE->getMainOp()))
21014+ (UserTE->hasState() &&
21015+ (!isa<CastInst, BinaryOperator, FreezeInst, PHINode,
21016+ SelectInst>(UserTE->getMainOp()) ||
21017+ isa<SIToFPInst, UIToFPInst>(UserTE->getMainOp()))))
2100721018 return true;
2100821019 unsigned UserTESz = DL->getTypeSizeInBits(
2100921020 UserTE->Scalars.front()->getType());
@@ -21253,6 +21264,7 @@ void BoUpSLP::computeMinimumValueSizes() {
2125321264 NodeIdx < VectorizableTree.size() &&
2125421265 VectorizableTree[NodeIdx]->UserTreeIndex &&
2125521266 VectorizableTree[NodeIdx]->UserTreeIndex.EdgeIdx == 0 &&
21267+ VectorizableTree[NodeIdx]->UserTreeIndex.UserTE->hasState() &&
2125621268 VectorizableTree[NodeIdx]->UserTreeIndex.UserTE->getOpcode() ==
2125721269 Instruction::Trunc &&
2125821270 !VectorizableTree[NodeIdx]->UserTreeIndex.UserTE->isAltShuffle();
0 commit comments