Revert "[SLP] Check if the user node has state before trying getting main instruction/opcode" This reverts commit c9cea24fe68e24750b2d479144f839e1c2ec9d2b. This is being reverted as it is intermixed with another commit (898bba311f180ed54de33dc09e7071c279a4942a) that needs to be reverted.
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 44dc43d..0adad5a 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -6861,7 +6861,7 @@ return std::move(ResOrder); } if (TE.State == TreeEntry::StridedVectorize && !TopToBottom && - (!TE.UserTreeIndex || !TE.UserTreeIndex.UserTE->hasState() || + (!TE.UserTreeIndex || !Instruction::isBinaryOp(TE.UserTreeIndex.UserTE->getOpcode())) && (TE.ReorderIndices.empty() || isReverseOrder(TE.ReorderIndices))) return std::nullopt; @@ -15704,8 +15704,7 @@ const BasicBlock *TEInsertBlock = nullptr; // Main node of PHI entries keeps the correct order of operands/incoming // blocks. - if (auto *PHI = dyn_cast_or_null<PHINode>( - TEUseEI.UserTE->hasState() ? TEUseEI.UserTE->getMainOp() : nullptr); + if (auto *PHI = dyn_cast<PHINode>(TEUseEI.UserTE->getMainOp()); PHI && TEUseEI.UserTE->State != TreeEntry::SplitVectorize) { TEInsertBlock = PHI->getIncomingBlock(TEUseEI.EdgeIdx); TEInsertPt = TEInsertBlock->getTerminator(); @@ -15804,8 +15803,7 @@ "Expected only single user of a gather node."); const EdgeInfo &UseEI = TEPtr->UserTreeIndex; - PHINode *UserPHI = (UseEI.UserTE->State != TreeEntry::SplitVectorize && - UseEI.UserTE->hasState()) + PHINode *UserPHI = UseEI.UserTE->State != TreeEntry::SplitVectorize ? dyn_cast<PHINode>(UseEI.UserTE->getMainOp()) : nullptr; Instruction *InsertPt = @@ -15818,8 +15816,7 @@ TEUseEI.UserTE->isAltShuffle()) && all_of(TEUseEI.UserTE->Scalars, isUsedOutsideBlock)) { if (UseEI.UserTE->State != TreeEntry::Vectorize || - (UseEI.UserTE->hasState() && - UseEI.UserTE->getOpcode() == Instruction::PHI && + (UseEI.UserTE->getOpcode() == Instruction::PHI && !UseEI.UserTE->isAltShuffle()) || !all_of(UseEI.UserTE->Scalars, isUsedOutsideBlock)) continue; @@ -16441,31 +16438,24 @@ // Get the basic block this bundle is in. All instructions in the bundle // should be in this block (except for extractelement-like instructions with // constant indices or gathered loads or copyables). - Instruction *Front; - unsigned Opcode; - if (E->hasState()) { - Front = E->getMainOp(); - Opcode = E->getOpcode(); - } else { - Front = cast<Instruction>(*find_if(E->Scalars, IsaPred<Instruction>)); - Opcode = Front->getOpcode(); - } + auto *Front = E->getMainOp(); auto *BB = Front->getParent(); - assert( - ((GatheredLoadsEntriesFirst.has_value() && Opcode == Instruction::Load && - E->isGather() && E->Idx < *GatheredLoadsEntriesFirst) || - E->State == TreeEntry::SplitVectorize || E->hasCopyableElements() || - all_of(E->Scalars, - [=](Value *V) -> bool { - if (Opcode == Instruction::GetElementPtr && - !isa<GetElementPtrInst>(V)) - return true; - auto *I = dyn_cast<Instruction>(V); - return !I || !E->getMatchingMainOpOrAltOp(I) || - I->getParent() == BB || isVectorLikeInstWithConstOps(I); - })) && - "Expected gathered loads or GEPs or instructions from same basic " - "block."); + assert(((GatheredLoadsEntriesFirst.has_value() && + E->getOpcode() == Instruction::Load && E->isGather() && + E->Idx < *GatheredLoadsEntriesFirst) || + E->State == TreeEntry::SplitVectorize || E->hasCopyableElements() || + all_of(E->Scalars, + [=](Value *V) -> bool { + if (E->getOpcode() == Instruction::GetElementPtr && + !isa<GetElementPtrInst>(V)) + return true; + auto *I = dyn_cast<Instruction>(V); + return !I || !E->getMatchingMainOpOrAltOp(I) || + I->getParent() == BB || + isVectorLikeInstWithConstOps(I); + })) && + "Expected gathered loads or GEPs or instructions from same basic " + "block."); auto FindLastInst = [&]() { Instruction *LastInst = Front; @@ -16480,13 +16470,13 @@ LastInst = I; continue; } - assert(((Opcode == Instruction::GetElementPtr && + assert(((E->getOpcode() == Instruction::GetElementPtr && !isa<GetElementPtrInst>(I)) || E->State == TreeEntry::SplitVectorize || (isVectorLikeInstWithConstOps(LastInst) && isVectorLikeInstWithConstOps(I)) || (GatheredLoadsEntriesFirst.has_value() && - Opcode == Instruction::Load && E->isGather() && + E->getOpcode() == Instruction::Load && E->isGather() && E->Idx < *GatheredLoadsEntriesFirst)) && "Expected vector-like or non-GEP in GEP node insts only."); if (!DT->isReachableFromEntry(LastInst->getParent())) { @@ -16522,11 +16512,11 @@ FirstInst = I; continue; } - assert(((Opcode == Instruction::GetElementPtr && - !isa<GetElementPtrInst>(I)) || - (isVectorLikeInstWithConstOps(FirstInst) && - isVectorLikeInstWithConstOps(I))) && - "Expected vector-like or non-GEP in GEP node insts only."); + assert(((E->getOpcode() == Instruction::GetElementPtr && + !isa<GetElementPtrInst>(I)) || + (isVectorLikeInstWithConstOps(FirstInst) && + isVectorLikeInstWithConstOps(I))) && + "Expected vector-like or non-GEP in GEP node insts only."); if (!DT->isReachableFromEntry(FirstInst->getParent())) { FirstInst = I; continue; @@ -16564,7 +16554,7 @@ // Set insertpoint for gathered loads to the very first load. if (GatheredLoadsEntriesFirst.has_value() && E->Idx >= *GatheredLoadsEntriesFirst && !E->isGather() && - Opcode == Instruction::Load) { + E->getOpcode() == Instruction::Load) { Res = FindFirstInst(); EntryToLastInstruction.try_emplace(E, Res); return *Res; @@ -16596,7 +16586,7 @@ }; const ScheduleBundle *Bundle = FindScheduleBundle(E); if (!E->isGather() && !Bundle) { - if ((Opcode == Instruction::GetElementPtr && + if ((E->getOpcode() == Instruction::GetElementPtr && any_of(E->Scalars, [](Value *V) { return !isa<GetElementPtrInst>(V) && isa<Instruction>(V); @@ -21011,10 +21001,9 @@ if (!isa<CastInst, BinaryOperator, FreezeInst, PHINode, SelectInst>(U) || isa<SIToFPInst, UIToFPInst>(U) || - (UserTE->hasState() && - (!isa<CastInst, BinaryOperator, FreezeInst, PHINode, - SelectInst>(UserTE->getMainOp()) || - isa<SIToFPInst, UIToFPInst>(UserTE->getMainOp())))) + !isa<CastInst, BinaryOperator, FreezeInst, PHINode, + SelectInst>(UserTE->getMainOp()) || + isa<SIToFPInst, UIToFPInst>(UserTE->getMainOp())) return true; unsigned UserTESz = DL->getTypeSizeInBits( UserTE->Scalars.front()->getType()); @@ -21264,7 +21253,6 @@ NodeIdx < VectorizableTree.size() && VectorizableTree[NodeIdx]->UserTreeIndex && VectorizableTree[NodeIdx]->UserTreeIndex.EdgeIdx == 0 && - VectorizableTree[NodeIdx]->UserTreeIndex.UserTE->hasState() && VectorizableTree[NodeIdx]->UserTreeIndex.UserTE->getOpcode() == Instruction::Trunc && !VectorizableTree[NodeIdx]->UserTreeIndex.UserTE->isAltShuffle();
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/user-node-no-state.ll b/llvm/test/Transforms/SLPVectorizer/X86/user-node-no-state.ll deleted file mode 100644 index 237f308..0000000 --- a/llvm/test/Transforms/SLPVectorizer/X86/user-node-no-state.ll +++ /dev/null
@@ -1,48 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s - -@g = global [128 x i8] zeroinitializer, align 16 - -define i64 @test() { -; CHECK-LABEL: define i64 @test() { -; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @g, align 8 -; CHECK-NEXT: br label %[[FUNC_154_EXIT_FUNC_146_EXIT_CRIT_EDGE_I:.*]] -; CHECK: [[FUNC_154_EXIT_FUNC_146_EXIT_CRIT_EDGE_I]]: -; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @g, i64 80), align 16 -; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @g, i64 88), align 8 -; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @g, i64 32), align 16 -; CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @g, align 16 -; CHECK-NEXT: [[TMP5:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @g, i64 8), align 8 -; CHECK-NEXT: [[TMP6:%.*]] = load i64, ptr @g, align 16 -; CHECK-NEXT: [[TMP7:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @g, i64 24), align 8 -; CHECK-NEXT: [[TMP8:%.*]] = xor i64 [[TMP1]], [[TMP2]] -; CHECK-NEXT: [[TMP9:%.*]] = xor i64 [[TMP8]], [[TMP3]] -; CHECK-NEXT: [[TMP10:%.*]] = xor i64 [[TMP9]], [[TMP4]] -; CHECK-NEXT: [[TMP11:%.*]] = xor i64 [[TMP10]], [[TMP5]] -; CHECK-NEXT: [[TMP12:%.*]] = xor i64 [[TMP11]], [[TMP6]] -; CHECK-NEXT: [[TMP13:%.*]] = xor i64 [[TMP12]], [[TMP7]] -; CHECK-NEXT: [[TMP14:%.*]] = xor i64 [[TMP13]], [[TMP0]] -; CHECK-NEXT: ret i64 [[TMP14]] -; -entry: - %0 = load i64, ptr @g, align 8 - br label %func_154.exit.func_146.exit_crit_edge.i - -func_154.exit.func_146.exit_crit_edge.i: - %1 = load i64, ptr getelementptr inbounds nuw (i8, ptr @g, i64 80), align 16 - %2 = load i64, ptr getelementptr inbounds nuw (i8, ptr @g, i64 88), align 8 - %3 = load i64, ptr getelementptr inbounds nuw (i8, ptr @g, i64 32), align 16 - %4 = load i64, ptr @g, align 16 - %5 = load i64, ptr getelementptr inbounds nuw (i8, ptr @g, i64 8), align 8 - %6 = load i64, ptr @g, align 16 - %7 = load i64, ptr getelementptr inbounds nuw (i8, ptr @g, i64 24), align 8 - %8 = xor i64 %1, %2 - %9 = xor i64 %8, %3 - %10 = xor i64 %9, %4 - %11 = xor i64 %10, %5 - %12 = xor i64 %11, %6 - %13 = xor i64 %12, %7 - %14 = xor i64 %13, %0 - ret i64 %14 -}