@@ -702,7 +702,8 @@ static SmallBitVector isUndefVector(const Value *V,
702702/// TODO: Can we split off and reuse the shuffle mask detection from
703703/// ShuffleVectorInst/getShuffleCost?
704704static std::optional<TargetTransformInfo::ShuffleKind>
705- isFixedVectorShuffle(ArrayRef<Value *> VL, SmallVectorImpl<int> &Mask) {
705+ isFixedVectorShuffle(ArrayRef<Value *> VL, SmallVectorImpl<int> &Mask,
706+ AssumptionCache *AC) {
706707 const auto *It = find_if(VL, IsaPred<ExtractElementInst>);
707708 if (It == VL.end())
708709 return std::nullopt;
@@ -719,14 +720,14 @@ isFixedVectorShuffle(ArrayRef<Value *> VL, SmallVectorImpl<int> &Mask) {
719720
720721 Value *Vec1 = nullptr;
721722 Value *Vec2 = nullptr;
722- bool HasNonUndefVec = any_of(VL, [](Value *V) {
723+ bool HasNonUndefVec = any_of(VL, [& ](Value *V) {
723724 auto *EE = dyn_cast<ExtractElementInst>(V);
724725 if (!EE)
725726 return false;
726727 Value *Vec = EE->getVectorOperand();
727728 if (isa<UndefValue>(Vec))
728729 return false;
729- return isGuaranteedNotToBePoison(Vec);
730+ return isGuaranteedNotToBePoison(Vec, AC );
730731 });
731732 enum ShuffleMode { Unknown, Select, Permute };
732733 ShuffleMode CommonShuffleMode = Unknown;
@@ -11875,7 +11876,7 @@ bool BoUpSLP::isFullyVectorizableTinyTree(bool ForReduction) const {
1187511876 TE->Scalars.size() < Limit ||
1187611877 ((TE->getOpcode() == Instruction::ExtractElement ||
1187711878 all_of(TE->Scalars, IsaPred<ExtractElementInst, UndefValue>)) &&
11878- isFixedVectorShuffle(TE->Scalars, Mask)) ||
11879+ isFixedVectorShuffle(TE->Scalars, Mask, AC )) ||
1187911880 (TE->getOpcode() == Instruction::Load && !TE->isAltShuffle()) ||
1188011881 any_of(TE->Scalars, IsaPred<LoadInst>));
1188111882 };
@@ -12940,7 +12941,7 @@ BoUpSLP::tryToGatherSingleRegisterExtractElements(
1294012941 // Check that gather of extractelements can be represented as just a
1294112942 // shuffle of a single/two vectors the scalars are extracted from.
1294212943 std::optional<TTI::ShuffleKind> Res =
12943- isFixedVectorShuffle(GatheredExtracts, Mask);
12944+ isFixedVectorShuffle(GatheredExtracts, Mask, AC );
1294412945 if (!Res || all_of(Mask, [](int Idx) { return Idx == PoisonMaskElem; })) {
1294512946 // TODO: try to check other subsets if possible.
1294612947 // Restore the original VL if attempt was not successful.
@@ -14828,7 +14829,7 @@ ResTy BoUpSLP::processBuildVector(const TreeEntry *E, Type *ScalarTy,
1482814829 // non-poisonous, or by freezing the incoming scalar value first.
1482914830 auto *It = find_if(Scalars, [this, E](Value *V) {
1483014831 return !isa<UndefValue>(V) &&
14831- (getTreeEntry(V) || isGuaranteedNotToBePoison(V) ||
14832+ (getTreeEntry(V) || isGuaranteedNotToBePoison(V, AC ) ||
1483214833 (E->UserTreeIndices.size() == 1 &&
1483314834 any_of(V->uses(), [E](const Use &U) {
1483414835 // Check if the value already used in the same operation in
@@ -14900,11 +14901,11 @@ ResTy BoUpSLP::processBuildVector(const TreeEntry *E, Type *ScalarTy,
1490014901 }
1490114902 if (Vec2) {
1490214903 IsUsedInExpr = false;
14903- IsNonPoisoned &=
14904- isGuaranteedNotToBePoison(Vec1) && isGuaranteedNotToBePoison(Vec2);
14904+ IsNonPoisoned &= isGuaranteedNotToBePoison(Vec1, AC) &&
14905+ isGuaranteedNotToBePoison(Vec2, AC );
1490514906 ShuffleBuilder.add(Vec1, Vec2, ExtractMask);
1490614907 } else if (Vec1) {
14907- bool IsNotPoisonedVec = isGuaranteedNotToBePoison(Vec1);
14908+ bool IsNotPoisonedVec = isGuaranteedNotToBePoison(Vec1, AC );
1490814909 IsUsedInExpr &= FindReusedSplat(
1490914910 ExtractMask,
1491014911 cast<FixedVectorType>(Vec1->getType())->getNumElements(), 0,
@@ -14935,7 +14936,7 @@ ResTy BoUpSLP::processBuildVector(const TreeEntry *E, Type *ScalarTy,
1493514936 if (TEs.size() == 1) {
1493614937 bool IsNotPoisonedVec =
1493714938 TEs.front()->VectorizedValue
14938- ? isGuaranteedNotToBePoison(TEs.front()->VectorizedValue)
14939+ ? isGuaranteedNotToBePoison(TEs.front()->VectorizedValue, AC )
1493914940 : true;
1494014941 IsUsedInExpr &=
1494114942 FindReusedSplat(VecMask, TEs.front()->getVectorFactor(), I,
@@ -14947,8 +14948,8 @@ ResTy BoUpSLP::processBuildVector(const TreeEntry *E, Type *ScalarTy,
1494714948 ShuffleBuilder.add(*TEs.front(), *TEs.back(), VecMask);
1494814949 if (TEs.front()->VectorizedValue && TEs.back()->VectorizedValue)
1494914950 IsNonPoisoned &=
14950- isGuaranteedNotToBePoison(TEs.front()->VectorizedValue) &&
14951- isGuaranteedNotToBePoison(TEs.back()->VectorizedValue);
14951+ isGuaranteedNotToBePoison(TEs.front()->VectorizedValue, AC ) &&
14952+ isGuaranteedNotToBePoison(TEs.back()->VectorizedValue, AC );
1495214953 }
1495314954 }
1495414955 }
@@ -15283,7 +15284,8 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
1528315284 }
1528415285 if (!IsIdentity || NumElts != NumScalars) {
1528515286 Value *V2 = nullptr;
15286- bool IsVNonPoisonous = isGuaranteedNotToBePoison(V) && !isConstant(V);
15287+ bool IsVNonPoisonous =
15288+ !isConstant(V) && isGuaranteedNotToBePoison(V, AC);
1528715289 SmallVector<int> InsertMask(Mask);
1528815290 if (NumElts != NumScalars && Offset == 0) {
1528915291 // Follow all insert element instructions from the current buildvector
@@ -19638,7 +19640,7 @@ class HorizontalReduction {
1963819640
1963919641 /// Attempt to vectorize the tree found by matchAssociativeReduction.
1964019642 Value *tryToReduce(BoUpSLP &V, const DataLayout &DL, TargetTransformInfo *TTI,
19641- const TargetLibraryInfo &TLI) {
19643+ const TargetLibraryInfo &TLI, AssumptionCache *AC ) {
1964219644 const unsigned ReductionLimit = VectorizeNonPowerOf2 ? 3 : 4;
1964319645 constexpr unsigned RegMaxNumber = 4;
1964419646 constexpr unsigned RedValsMaxNumber = 128;
@@ -19695,15 +19697,15 @@ class HorizontalReduction {
1969519697
1969619698 if (auto It = ReducedValsToOps.find(VectorizedTree);
1969719699 It == ReducedValsToOps.end() ||
19698- isGuaranteedNotToBePoison(VectorizedTree) ||
19700+ isGuaranteedNotToBePoison(VectorizedTree, AC ) ||
1969919701 any_of(It->getSecond(), [&](Instruction *I) {
1970019702 return isBoolLogicOp(I) &&
1970119703 getRdxOperand(I, 0) == VectorizedTree;
1970219704 })) {
1970319705 ;
1970419706 } else if (auto It = ReducedValsToOps.find(Res);
1970519707 It == ReducedValsToOps.end() ||
19706- isGuaranteedNotToBePoison(Res) ||
19708+ isGuaranteedNotToBePoison(Res, AC ) ||
1970719709 any_of(It->getSecond(), [&](Instruction *I) {
1970819710 return isBoolLogicOp(I) && getRdxOperand(I, 0) == Res;
1970919711 })) {
@@ -19795,7 +19797,7 @@ class HorizontalReduction {
1979519797 TrackedToOrig.try_emplace(RdxVal, RV);
1979619798 }
1979719799 SmallVector<int> Mask;
19798- if (isFixedVectorShuffle(CommonCandidates, Mask)) {
19800+ if (isFixedVectorShuffle(CommonCandidates, Mask, AC )) {
1979919801 ++I;
1980019802 Candidates.swap(CommonCandidates);
1980119803 ShuffledExtracts = true;
@@ -20110,7 +20112,7 @@ class HorizontalReduction {
2011020112 // To prevent poison from leaking across what used to be sequential,
2011120113 // safe, scalar boolean logic operations, the reduction operand must be
2011220114 // frozen.
20113- if (AnyBoolLogicOp && !isGuaranteedNotToBePoison(VectorizedRoot))
20115+ if (AnyBoolLogicOp && !isGuaranteedNotToBePoison(VectorizedRoot, AC ))
2011420116 VectorizedRoot = Builder.CreateFreeze(VectorizedRoot);
2011520117
2011620118 // Emit code to correctly handle reused reduced values, if required.
@@ -20217,13 +20219,13 @@ class HorizontalReduction {
2021720219 bool InitStep) {
2021820220 if (!AnyBoolLogicOp)
2021920221 return;
20220- if (isBoolLogicOp(RedOp1) &&
20221- ((!InitStep && LHS == VectorizedTree) ||
20222- getRdxOperand(RedOp1, 0) == LHS || isGuaranteedNotToBePoison(LHS)))
20222+ if (isBoolLogicOp(RedOp1) && ((!InitStep && LHS == VectorizedTree) ||
20223+ getRdxOperand(RedOp1, 0) == LHS ||
20224+ isGuaranteedNotToBePoison(LHS, AC )))
2022320225 return;
2022420226 if (isBoolLogicOp(RedOp2) && ((!InitStep && RHS == VectorizedTree) ||
2022520227 getRdxOperand(RedOp2, 0) == RHS ||
20226- isGuaranteedNotToBePoison(RHS))) {
20228+ isGuaranteedNotToBePoison(RHS, AC ))) {
2022720229 std::swap(LHS, RHS);
2022820230 return;
2022920231 }
@@ -20871,7 +20873,7 @@ bool SLPVectorizerPass::vectorizeHorReduction(
2087120873 HorizontalReduction HorRdx;
2087220874 if (!HorRdx.matchAssociativeReduction(R, Inst, *SE, *DL, *TLI))
2087320875 return nullptr;
20874- return HorRdx.tryToReduce(R, *DL, TTI, *TLI);
20876+ return HorRdx.tryToReduce(R, *DL, TTI, *TLI, AC );
2087520877 };
2087620878 auto TryAppendToPostponedInsts = [&](Instruction *FutureSeed) {
2087720879 if (TryOperandsAsNewSeeds && FutureSeed == Root) {
@@ -20977,8 +20979,8 @@ bool SLPVectorizerPass::vectorizeInsertElementInst(InsertElementInst *IEI,
2097720979 SmallVector<Value *, 16> BuildVectorOpds;
2097820980 SmallVector<int> Mask;
2097920981 if (!findBuildAggregate(IEI, TTI, BuildVectorOpds, BuildVectorInsts, R) ||
20980- (llvm:: all_of(BuildVectorOpds, IsaPred<ExtractElementInst, UndefValue>) &&
20981- isFixedVectorShuffle(BuildVectorOpds, Mask)))
20982+ (all_of(BuildVectorOpds, IsaPred<ExtractElementInst, UndefValue>) &&
20983+ isFixedVectorShuffle(BuildVectorOpds, Mask, AC )))
2098220984 return false;
2098320985
2098420986 if (MaxVFOnly && BuildVectorInsts.size() == 2) {
0 commit comments