@@ -6861,7 +6861,7 @@ BoUpSLP::getReorderingData(const TreeEntry &TE, bool TopToBottom,
6861
6861
return std::move(ResOrder);
6862
6862
}
6863
6863
if (TE.State == TreeEntry::StridedVectorize && !TopToBottom &&
6864
- (!TE.UserTreeIndex ||
6864
+ (!TE.UserTreeIndex || !TE.UserTreeIndex.UserTE->hasState() ||
6865
6865
!Instruction::isBinaryOp(TE.UserTreeIndex.UserTE->getOpcode())) &&
6866
6866
(TE.ReorderIndices.empty() || isReverseOrder(TE.ReorderIndices)))
6867
6867
return std::nullopt;
@@ -15704,7 +15704,8 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
15704
15704
const BasicBlock *TEInsertBlock = nullptr;
15705
15705
// Main node of PHI entries keeps the correct order of operands/incoming
15706
15706
// 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);
15708
15709
PHI && TEUseEI.UserTE->State != TreeEntry::SplitVectorize) {
15709
15710
TEInsertBlock = PHI->getIncomingBlock(TEUseEI.EdgeIdx);
15710
15711
TEInsertPt = TEInsertBlock->getTerminator();
@@ -15803,7 +15804,8 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
15803
15804
"Expected only single user of a gather node.");
15804
15805
const EdgeInfo &UseEI = TEPtr->UserTreeIndex;
15805
15806
15806
- PHINode *UserPHI = UseEI.UserTE->State != TreeEntry::SplitVectorize
15807
+ PHINode *UserPHI = (UseEI.UserTE->State != TreeEntry::SplitVectorize &&
15808
+ UseEI.UserTE->hasState())
15807
15809
? dyn_cast<PHINode>(UseEI.UserTE->getMainOp())
15808
15810
: nullptr;
15809
15811
Instruction *InsertPt =
@@ -15816,7 +15818,8 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
15816
15818
TEUseEI.UserTE->isAltShuffle()) &&
15817
15819
all_of(TEUseEI.UserTE->Scalars, isUsedOutsideBlock)) {
15818
15820
if (UseEI.UserTE->State != TreeEntry::Vectorize ||
15819
- (UseEI.UserTE->getOpcode() == Instruction::PHI &&
15821
+ (UseEI.UserTE->hasState() &&
15822
+ UseEI.UserTE->getOpcode() == Instruction::PHI &&
15820
15823
!UseEI.UserTE->isAltShuffle()) ||
15821
15824
!all_of(UseEI.UserTE->Scalars, isUsedOutsideBlock))
15822
15825
continue;
@@ -16438,24 +16441,31 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
16438
16441
// Get the basic block this bundle is in. All instructions in the bundle
16439
16442
// should be in this block (except for extractelement-like instructions with
16440
16443
// 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
+ }
16442
16453
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.");
16459
16469
16460
16470
auto FindLastInst = [&]() {
16461
16471
Instruction *LastInst = Front;
@@ -16470,13 +16480,13 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
16470
16480
LastInst = I;
16471
16481
continue;
16472
16482
}
16473
- assert(((E->getOpcode() == Instruction::GetElementPtr &&
16483
+ assert(((Opcode == Instruction::GetElementPtr &&
16474
16484
!isa<GetElementPtrInst>(I)) ||
16475
16485
E->State == TreeEntry::SplitVectorize ||
16476
16486
(isVectorLikeInstWithConstOps(LastInst) &&
16477
16487
isVectorLikeInstWithConstOps(I)) ||
16478
16488
(GatheredLoadsEntriesFirst.has_value() &&
16479
- E->getOpcode() == Instruction::Load && E->isGather() &&
16489
+ Opcode == Instruction::Load && E->isGather() &&
16480
16490
E->Idx < *GatheredLoadsEntriesFirst)) &&
16481
16491
"Expected vector-like or non-GEP in GEP node insts only.");
16482
16492
if (!DT->isReachableFromEntry(LastInst->getParent())) {
@@ -16512,11 +16522,11 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
16512
16522
FirstInst = I;
16513
16523
continue;
16514
16524
}
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.");
16520
16530
if (!DT->isReachableFromEntry(FirstInst->getParent())) {
16521
16531
FirstInst = I;
16522
16532
continue;
@@ -16554,7 +16564,7 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
16554
16564
// Set insertpoint for gathered loads to the very first load.
16555
16565
if (GatheredLoadsEntriesFirst.has_value() &&
16556
16566
E->Idx >= *GatheredLoadsEntriesFirst && !E->isGather() &&
16557
- E->getOpcode() == Instruction::Load) {
16567
+ Opcode == Instruction::Load) {
16558
16568
Res = FindFirstInst();
16559
16569
EntryToLastInstruction.try_emplace(E, Res);
16560
16570
return *Res;
@@ -16586,7 +16596,7 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
16586
16596
};
16587
16597
const ScheduleBundle *Bundle = FindScheduleBundle(E);
16588
16598
if (!E->isGather() && !Bundle) {
16589
- if ((E->getOpcode() == Instruction::GetElementPtr &&
16599
+ if ((Opcode == Instruction::GetElementPtr &&
16590
16600
any_of(E->Scalars,
16591
16601
[](Value *V) {
16592
16602
return !isa<GetElementPtrInst>(V) && isa<Instruction>(V);
@@ -21001,9 +21011,10 @@ void BoUpSLP::computeMinimumValueSizes() {
21001
21011
if (!isa<CastInst, BinaryOperator, FreezeInst, PHINode,
21002
21012
SelectInst>(U) ||
21003
21013
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()))))
21007
21018
return true;
21008
21019
unsigned UserTESz = DL->getTypeSizeInBits(
21009
21020
UserTE->Scalars.front()->getType());
@@ -21253,6 +21264,7 @@ void BoUpSLP::computeMinimumValueSizes() {
21253
21264
NodeIdx < VectorizableTree.size() &&
21254
21265
VectorizableTree[NodeIdx]->UserTreeIndex &&
21255
21266
VectorizableTree[NodeIdx]->UserTreeIndex.EdgeIdx == 0 &&
21267
+ VectorizableTree[NodeIdx]->UserTreeIndex.UserTE->hasState() &&
21256
21268
VectorizableTree[NodeIdx]->UserTreeIndex.UserTE->getOpcode() ==
21257
21269
Instruction::Trunc &&
21258
21270
!VectorizableTree[NodeIdx]->UserTreeIndex.UserTE->isAltShuffle();
0 commit comments