@@ -1847,6 +1847,34 @@ static bool isVectorPromotionViableForSlice(Partition &P, const Slice &S,
1847
1847
return true ;
1848
1848
}
1849
1849
1850
+ // / Test whether a vector type is viable for promotion.
1851
+ // /
1852
+ // / This implements the necessary checking for \c isVectorPromotionViable over
1853
+ // / all slices of the alloca for the given VectorType.
1854
+ static bool checkVectorTypeForPromotion (Partition &P, VectorType *VTy,
1855
+ const DataLayout &DL) {
1856
+ uint64_t ElementSize =
1857
+ DL.getTypeSizeInBits (VTy->getElementType ()).getFixedSize ();
1858
+
1859
+ // While the definition of LLVM vectors is bitpacked, we don't support sizes
1860
+ // that aren't byte sized.
1861
+ if (ElementSize % 8 )
1862
+ return false ;
1863
+ assert ((DL.getTypeSizeInBits (VTy).getFixedSize () % 8 ) == 0 &&
1864
+ " vector size not a multiple of element size?" );
1865
+ ElementSize /= 8 ;
1866
+
1867
+ for (const Slice &S : P)
1868
+ if (!isVectorPromotionViableForSlice (P, S, VTy, ElementSize, DL))
1869
+ return false ;
1870
+
1871
+ for (const Slice *S : P.splitSliceTails ())
1872
+ if (!isVectorPromotionViableForSlice (P, *S, VTy, ElementSize, DL))
1873
+ return false ;
1874
+
1875
+ return true ;
1876
+ }
1877
+
1850
1878
// / Test whether the given alloca partitioning and range of slices can be
1851
1879
// / promoted to a vector.
1852
1880
// /
@@ -1939,31 +1967,8 @@ static VectorType *isVectorPromotionViable(Partition &P, const DataLayout &DL) {
1939
1967
CandidateTys.resize (1 );
1940
1968
}
1941
1969
1942
- // Try each vector type, and return the one which works.
1943
- auto CheckVectorTypeForPromotion = [&](VectorType *VTy) {
1944
- uint64_t ElementSize =
1945
- DL.getTypeSizeInBits (VTy->getElementType ()).getFixedSize ();
1946
-
1947
- // While the definition of LLVM vectors is bitpacked, we don't support sizes
1948
- // that aren't byte sized.
1949
- if (ElementSize % 8 )
1950
- return false ;
1951
- assert ((DL.getTypeSizeInBits (VTy).getFixedSize () % 8 ) == 0 &&
1952
- " vector size not a multiple of element size?" );
1953
- ElementSize /= 8 ;
1954
-
1955
- for (const Slice &S : P)
1956
- if (!isVectorPromotionViableForSlice (P, S, VTy, ElementSize, DL))
1957
- return false ;
1958
-
1959
- for (const Slice *S : P.splitSliceTails ())
1960
- if (!isVectorPromotionViableForSlice (P, *S, VTy, ElementSize, DL))
1961
- return false ;
1962
-
1963
- return true ;
1964
- };
1965
1970
for (VectorType *VTy : CandidateTys)
1966
- if (CheckVectorTypeForPromotion ( VTy))
1971
+ if (checkVectorTypeForPromotion (P, VTy, DL ))
1967
1972
return VTy;
1968
1973
1969
1974
return nullptr ;
@@ -4246,26 +4251,45 @@ AllocaInst *SROAPass::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
4246
4251
// won't always succeed, in which case we fall back to a legal integer type
4247
4252
// or an i8 array of an appropriate size.
4248
4253
Type *SliceTy = nullptr ;
4254
+ VectorType *SliceVecTy = nullptr ;
4249
4255
const DataLayout &DL = AI.getModule ()->getDataLayout ();
4250
4256
std::pair<Type *, IntegerType *> CommonUseTy =
4251
4257
findCommonType (P.begin (), P.end (), P.endOffset ());
4252
4258
// Do all uses operate on the same type?
4253
4259
if (CommonUseTy.first )
4254
- if (DL.getTypeAllocSize (CommonUseTy.first ).getFixedSize () >= P.size ())
4260
+ if (DL.getTypeAllocSize (CommonUseTy.first ).getFixedSize () >= P.size ()) {
4255
4261
SliceTy = CommonUseTy.first ;
4262
+ SliceVecTy = dyn_cast<VectorType>(SliceTy);
4263
+ }
4256
4264
// If not, can we find an appropriate subtype in the original allocated type?
4257
4265
if (!SliceTy)
4258
4266
if (Type *TypePartitionTy = getTypePartition (DL, AI.getAllocatedType (),
4259
4267
P.beginOffset (), P.size ()))
4260
4268
SliceTy = TypePartitionTy;
4269
+
4261
4270
// If still not, can we use the largest bitwidth integer type used?
4262
4271
if (!SliceTy && CommonUseTy.second )
4263
- if (DL.getTypeAllocSize (CommonUseTy.second ).getFixedSize () >= P.size ())
4272
+ if (DL.getTypeAllocSize (CommonUseTy.second ).getFixedSize () >= P.size ()) {
4264
4273
SliceTy = CommonUseTy.second ;
4274
+ SliceVecTy = dyn_cast<VectorType>(SliceTy);
4275
+ }
4265
4276
if ((!SliceTy || (SliceTy->isArrayTy () &&
4266
4277
SliceTy->getArrayElementType ()->isIntegerTy ())) &&
4267
- DL.isLegalInteger (P.size () * 8 ))
4278
+ DL.isLegalInteger (P.size () * 8 )) {
4268
4279
SliceTy = Type::getIntNTy (*C, P.size () * 8 );
4280
+ }
4281
+
4282
+ // If the common use types are not viable for promotion then attempt to find
4283
+ // another type that is viable.
4284
+ if (SliceVecTy && !checkVectorTypeForPromotion (P, SliceVecTy, DL))
4285
+ if (Type *TypePartitionTy = getTypePartition (DL, AI.getAllocatedType (),
4286
+ P.beginOffset (), P.size ())) {
4287
+ VectorType *TypePartitionVecTy = dyn_cast<VectorType>(TypePartitionTy);
4288
+ if (TypePartitionVecTy &&
4289
+ checkVectorTypeForPromotion (P, TypePartitionVecTy, DL))
4290
+ SliceTy = TypePartitionTy;
4291
+ }
4292
+
4269
4293
if (!SliceTy)
4270
4294
SliceTy = ArrayType::get (Type::getInt8Ty (*C), P.size ());
4271
4295
assert (DL.getTypeAllocSize (SliceTy).getFixedSize () >= P.size ());
0 commit comments