@@ -113,6 +113,10 @@ static cl::opt<bool>
113113 RunSLPVectorization("vectorize-slp", cl::init(true), cl::Hidden,
114114 cl::desc("Run the SLP vectorization passes"));
115115
116+ static cl::opt<bool>
117+ SLPReVec("slp-revec", cl::init(false), cl::Hidden,
118+ cl::desc("Enable vectorization for wider vector utilization"));
119+
116120static cl::opt<int>
117121 SLPCostThreshold("slp-threshold", cl::init(0), cl::Hidden,
118122 cl::desc("Only vectorize if you gain more than this "
@@ -227,13 +231,26 @@ static const unsigned MaxPHINumOperands = 128;
227231/// avoids spending time checking the cost model and realizing that they will
228232/// be inevitably scalarized.
229233static bool isValidElementType(Type *Ty) {
234+ // TODO: Support ScalableVectorType.
235+ if (SLPReVec && isa<FixedVectorType>(Ty))
236+ Ty = Ty->getScalarType();
230237 return VectorType::isValidElementType(Ty) && !Ty->isX86_FP80Ty() &&
231238 !Ty->isPPC_FP128Ty();
232239}
233240
241+ /// \returns the number of elements for Ty.
242+ static unsigned getNumElements(Type *Ty) {
243+ assert(!isa<ScalableVectorType>(Ty) &&
244+ "ScalableVectorType is not supported.");
245+ if (auto *VecTy = dyn_cast<FixedVectorType>(Ty))
246+ return VecTy->getNumElements();
247+ return 1;
248+ }
249+
234250/// \returns the vector type of ScalarTy based on vectorization factor.
235251static FixedVectorType *getWidenedType(Type *ScalarTy, unsigned VF) {
236- return FixedVectorType::get(ScalarTy, VF);
252+ return FixedVectorType::get(ScalarTy->getScalarType(),
253+ VF * getNumElements(ScalarTy));
237254}
238255
239256/// \returns True if the value is a constant (but not globals/constant
@@ -6779,15 +6796,15 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
67796796 }
67806797
67816798 // Don't handle vectors.
6782- if (S.OpValue->getType()->isVectorTy() &&
6799+ if (!SLPReVec && S.OpValue->getType()->isVectorTy() &&
67836800 !isa<InsertElementInst>(S.OpValue)) {
67846801 LLVM_DEBUG(dbgs() << "SLP: Gathering due to vector type.\n");
67856802 newTreeEntry(VL, std::nullopt /*not vectorized*/, S, UserTreeIdx);
67866803 return;
67876804 }
67886805
67896806 if (StoreInst *SI = dyn_cast<StoreInst>(S.OpValue))
6790- if (SI->getValueOperand()->getType()->isVectorTy()) {
6807+ if (!SLPReVec && SI->getValueOperand()->getType()->isVectorTy()) {
67916808 LLVM_DEBUG(dbgs() << "SLP: Gathering due to store vector type.\n");
67926809 newTreeEntry(VL, std::nullopt /*not vectorized*/, S, UserTreeIdx);
67936810 return;
@@ -11833,10 +11850,12 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
1183311850 Value *castToScalarTyElem(Value *V,
1183411851 std::optional<bool> IsSigned = std::nullopt) {
1183511852 auto *VecTy = cast<VectorType>(V->getType());
11836- if (VecTy->getElementType() == ScalarTy)
11853+ assert(getNumElements(ScalarTy) < getNumElements(VecTy) &&
11854+ (getNumElements(VecTy) % getNumElements(ScalarTy) == 0));
11855+ if (VecTy->getElementType() == ScalarTy->getScalarType())
1183711856 return V;
1183811857 return Builder.CreateIntCast(
11839- V, VectorType::get(ScalarTy, VecTy->getElementCount()),
11858+ V, VectorType::get(ScalarTy->getScalarType() , VecTy->getElementCount()),
1184011859 IsSigned.value_or(!isKnownNonNegative(V, SimplifyQuery(*R.DL))));
1184111860 }
1184211861
@@ -12221,7 +12240,8 @@ Value *BoUpSLP::vectorizeOperand(TreeEntry *E, unsigned NodeIdx,
1222112240 return ShuffleBuilder.finalize(std::nullopt);
1222212241 };
1222312242 Value *V = vectorizeTree(VE, PostponedPHIs);
12224- if (VF != cast<FixedVectorType>(V->getType())->getNumElements()) {
12243+ if (VF * getNumElements(VL[0]->getType()) !=
12244+ cast<FixedVectorType>(V->getType())->getNumElements()) {
1222512245 if (!VE->ReuseShuffleIndices.empty()) {
1222612246 // Reshuffle to get only unique values.
1222712247 // If some of the scalars are duplicated in the vectorization
0 commit comments