@@ -113,6 +113,10 @@ static cl::opt<bool>
113
113
RunSLPVectorization("vectorize-slp", cl::init(true), cl::Hidden,
114
114
cl::desc("Run the SLP vectorization passes"));
115
115
116
+ static cl::opt<bool>
117
+ SLPReVec("slp-revec", cl::init(false), cl::Hidden,
118
+ cl::desc("Enable vectorization for wider vector utilization"));
119
+
116
120
static cl::opt<int>
117
121
SLPCostThreshold("slp-threshold", cl::init(0), cl::Hidden,
118
122
cl::desc("Only vectorize if you gain more than this "
@@ -227,13 +231,26 @@ static const unsigned MaxPHINumOperands = 128;
227
231
/// avoids spending time checking the cost model and realizing that they will
228
232
/// be inevitably scalarized.
229
233
static bool isValidElementType(Type *Ty) {
234
+ // TODO: Support ScalableVectorType.
235
+ if (SLPReVec && isa<FixedVectorType>(Ty))
236
+ Ty = Ty->getScalarType();
230
237
return VectorType::isValidElementType(Ty) && !Ty->isX86_FP80Ty() &&
231
238
!Ty->isPPC_FP128Ty();
232
239
}
233
240
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
+
234
250
/// \returns the vector type of ScalarTy based on vectorization factor.
235
251
static FixedVectorType *getWidenedType(Type *ScalarTy, unsigned VF) {
236
- return FixedVectorType::get(ScalarTy, VF);
252
+ return FixedVectorType::get(ScalarTy->getScalarType(),
253
+ VF * getNumElements(ScalarTy));
237
254
}
238
255
239
256
/// \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,
6779
6796
}
6780
6797
6781
6798
// Don't handle vectors.
6782
- if (S.OpValue->getType()->isVectorTy() &&
6799
+ if (!SLPReVec && S.OpValue->getType()->isVectorTy() &&
6783
6800
!isa<InsertElementInst>(S.OpValue)) {
6784
6801
LLVM_DEBUG(dbgs() << "SLP: Gathering due to vector type.\n");
6785
6802
newTreeEntry(VL, std::nullopt /*not vectorized*/, S, UserTreeIdx);
6786
6803
return;
6787
6804
}
6788
6805
6789
6806
if (StoreInst *SI = dyn_cast<StoreInst>(S.OpValue))
6790
- if (SI->getValueOperand()->getType()->isVectorTy()) {
6807
+ if (!SLPReVec && SI->getValueOperand()->getType()->isVectorTy()) {
6791
6808
LLVM_DEBUG(dbgs() << "SLP: Gathering due to store vector type.\n");
6792
6809
newTreeEntry(VL, std::nullopt /*not vectorized*/, S, UserTreeIdx);
6793
6810
return;
@@ -11833,10 +11850,12 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
11833
11850
Value *castToScalarTyElem(Value *V,
11834
11851
std::optional<bool> IsSigned = std::nullopt) {
11835
11852
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())
11837
11856
return V;
11838
11857
return Builder.CreateIntCast(
11839
- V, VectorType::get(ScalarTy, VecTy->getElementCount()),
11858
+ V, VectorType::get(ScalarTy->getScalarType() , VecTy->getElementCount()),
11840
11859
IsSigned.value_or(!isKnownNonNegative(V, SimplifyQuery(*R.DL))));
11841
11860
}
11842
11861
@@ -12221,7 +12240,8 @@ Value *BoUpSLP::vectorizeOperand(TreeEntry *E, unsigned NodeIdx,
12221
12240
return ShuffleBuilder.finalize(std::nullopt);
12222
12241
};
12223
12242
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()) {
12225
12245
if (!VE->ReuseShuffleIndices.empty()) {
12226
12246
// Reshuffle to get only unique values.
12227
12247
// If some of the scalars are duplicated in the vectorization
0 commit comments