Skip to content

Commit e30780b

Browse files
alexey-bataevkieroxide
authored andcommitted
[SLP]Fix narrow-tree gate width and extract miscount
Measure the narrowness of in-loop trees by the actual vectorization width instead of the feeder-load width, and skip vector-typed scalars in the instruction count check to match the cost model. Fixes llvm#216715 Reviewers: efriedma-quic, bababuck, RKSimon, kartcq Pull Request: llvm#216797
1 parent 2d77d6a commit e30780b

3 files changed

Lines changed: 36 additions & 17 deletions

File tree

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13773,6 +13773,12 @@ uint64_t BoUpSLP::getNumVectorInsts(bool HasTreeLoop) {
1377313773
continue;
1377413774
if (EU.User && EphValues.count(EU.User))
1377513775
continue;
13776+
// Vector-typed scalars are consumed as whole vectors, no extract
13777+
// instruction is emitted for them.
13778+
if (isVectorizedTy(EU.Scalar->getType()) &&
13779+
(!SLPReVec ||
13780+
(EU.E.hasState() && EU.E.getOpcode() == Instruction::InsertElement)))
13781+
continue;
1377613782
if (ExternalUsesAsOriginalScalar.contains(EU.Scalar))
1377713783
continue;
1377813784
if (!CountedExtracts.insert(EU.Scalar).second)
@@ -19289,7 +19295,17 @@ BoUpSLP::calculateTreeCostAndTrimNonProfitable(ArrayRef<Value *> VectorizedVals,
1928919295
return Cost;
1929019296
// The narrow non-profitable tree in loop? Skip, may cause regressions.
1929119297
constexpr unsigned PartLimit = 2;
19292-
const unsigned Sz = getVectorElementSize(getRootNodeScalars().front());
19298+
// Measure the narrowness by the width the tree is vectorized at.
19299+
const TreeEntry *RootTE = &getRootNode();
19300+
unsigned Sz;
19301+
if (auto It = MinBWs.find(RootTE); It != MinBWs.end()) {
19302+
Sz = It->second.first;
19303+
} else {
19304+
Sz = std::max<unsigned>(
19305+
getVectorElementSize(RootTE->Scalars.front()),
19306+
DL->getTypeSizeInBits(
19307+
getValueType(RootTE->Scalars.front())->getScalarType()));
19308+
}
1929319309
const unsigned MinVF = getMinVF(Sz);
1929419310
if (Cost >= -SLPCostThreshold &&
1929519311
getRootNodeScalars().size() * PartLimit <= MinVF &&

llvm/test/Transforms/SLPVectorizer/AArch64/abs-mul-buildvector-in-loop.ll

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,35 @@ define void @test(ptr noalias %src, ptr noalias %descriptor, i32 %N) {
1717
; CHECK-NEXT: [[I_033:%.*]] = phi i32 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
1818
; CHECK-NEXT: [[ARRAYIDX]] = getelementptr inbounds nuw i8, ptr [[SRC_ADDR_035]], i64 1
1919
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
20-
; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[TMP0]] to i32
2120
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[SRC_ADDR_035]], i64 -1
2221
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
23-
; CHECK-NEXT: [[CONV2:%.*]] = zext i8 [[TMP1]] to i32
24-
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV2]]
2522
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw i8, ptr [[SRC_ADDR_035]], i64 17
2623
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[ARRAYIDX3]], align 1
27-
; CHECK-NEXT: [[CONV4:%.*]] = zext i8 [[TMP2]] to i32
2824
; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i8, ptr [[SRC_ADDR_035]], i64 -17
2925
; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX5]], align 1
30-
; CHECK-NEXT: [[CONV6:%.*]] = zext i8 [[TMP3]] to i32
31-
; CHECK-NEXT: [[SUB7:%.*]] = sub nsw i32 [[CONV4]], [[CONV6]]
3226
; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr [[P_034]], align 1
3327
; CHECK-NEXT: [[CONV9:%.*]] = zext i8 [[TMP4]] to i32
3428
; CHECK-NEXT: [[INCDEC_PTR10]] = getelementptr inbounds nuw i8, ptr [[P_034]], i64 2
3529
; CHECK-NEXT: [[BIN:%.*]] = getelementptr inbounds nuw i8, ptr [[P_034]], i64 1
3630
; CHECK-NEXT: [[TMP5:%.*]] = load i8, ptr [[BIN]], align 1
3731
; CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[TMP5]] to i64
3832
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[DESCRIPTOR]], i64 [[IDX_EXT]]
39-
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[SUB]], [[CONV9]]
40-
; CHECK-NEXT: [[MUL12:%.*]] = mul nsw i32 [[SUB7]], [[CONV9]]
41-
; CHECK-NEXT: [[TMP6:%.*]] = tail call i32 @llvm.abs.i32(i32 [[MUL]], i1 true)
42-
; CHECK-NEXT: [[TMP7:%.*]] = tail call i32 @llvm.abs.i32(i32 [[MUL12]], i1 true)
33+
; CHECK-NEXT: [[CONV4:%.*]] = zext i8 [[TMP2]] to i32
34+
; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[TMP0]] to i32
35+
; CHECK-NEXT: [[CONV6:%.*]] = zext i8 [[TMP3]] to i32
36+
; CHECK-NEXT: [[CONV2:%.*]] = zext i8 [[TMP1]] to i32
37+
; CHECK-NEXT: [[SUB7:%.*]] = sub nsw i32 [[CONV4]], [[CONV6]]
38+
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[CONV]], [[CONV2]]
39+
; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> poison, i32 [[SUB]], i64 0
40+
; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> [[TMP6]], i32 [[SUB7]], i64 1
41+
; CHECK-NEXT: [[TMP15:%.*]] = insertelement <2 x i32> poison, i32 [[CONV9]], i64 0
42+
; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <2 x i32> [[TMP15]], <2 x i32> poison, <2 x i32> zeroinitializer
43+
; CHECK-NEXT: [[TMP10:%.*]] = mul nsw <2 x i32> [[TMP7]], [[TMP9]]
44+
; CHECK-NEXT: [[TMP11:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[TMP10]], i1 true)
4345
; CHECK-NEXT: [[TMP8:%.*]] = load <4 x i32>, ptr [[ADD_PTR]], align 4
44-
; CHECK-NEXT: [[TMP9:%.*]] = insertelement <4 x i32> poison, i32 [[MUL]], i64 0
45-
; CHECK-NEXT: [[TMP10:%.*]] = insertelement <4 x i32> [[TMP9]], i32 [[MUL12]], i64 1
46-
; CHECK-NEXT: [[TMP11:%.*]] = insertelement <4 x i32> [[TMP10]], i32 [[TMP6]], i64 2
47-
; CHECK-NEXT: [[TMP12:%.*]] = insertelement <4 x i32> [[TMP11]], i32 [[TMP7]], i64 3
46+
; CHECK-NEXT: [[TMP16:%.*]] = shufflevector <2 x i32> [[TMP10]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
47+
; CHECK-NEXT: [[TMP14:%.*]] = shufflevector <2 x i32> [[TMP11]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
48+
; CHECK-NEXT: [[TMP12:%.*]] = shufflevector <4 x i32> [[TMP16]], <4 x i32> [[TMP14]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
4849
; CHECK-NEXT: [[TMP13:%.*]] = add nsw <4 x i32> [[TMP8]], [[TMP12]]
4950
; CHECK-NEXT: store <4 x i32> [[TMP13]], ptr [[ADD_PTR]], align 4
5051
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_033]], 1

llvm/test/Transforms/SLPVectorizer/AArch64/long-non-power-of-2.ll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ define i1 @test(ptr %arg, ptr %arg1, i64 %arg2, ptr %arg3) {
77
; CHECK-NEXT: [[BB:.*:]]
88
; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr i8, ptr [[ARG1]], i64 [[ARG2]]
99
; CHECK-NEXT: [[GETELEMENTPTR4:%.*]] = getelementptr i8, ptr null, i64 0
10+
; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x ptr> <ptr null, ptr poison>, ptr [[ARG3]], i64 1
11+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, <2 x ptr> [[TMP2]], <2 x i64> <i64 -32, i64 -432>
1012
; CHECK-NEXT: [[GETELEMENTPTR5:%.*]] = getelementptr i8, ptr null, i64 -32
1113
; CHECK-NEXT: [[TMP32:%.*]] = getelementptr i8, ptr [[ARG3]], i64 -440
1214
; CHECK-NEXT: [[GETELEMENTPTR7:%.*]] = getelementptr i8, ptr [[ARG1]], i64 0
@@ -28,8 +30,8 @@ define i1 @test(ptr %arg, ptr %arg1, i64 %arg2, ptr %arg3) {
2830
; CHECK-NEXT: [[AND25:%.*]] = and i1 false, [[ICMP24]]
2931
; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x ptr> <ptr poison, ptr poison, ptr null, ptr null>, ptr [[ARG]], i64 1
3032
; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x ptr> [[TMP0]], ptr [[GETELEMENTPTR7]], i64 0
31-
; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x ptr> <ptr poison, ptr poison, ptr null, ptr null>, ptr [[GETELEMENTPTR5]], i64 0
32-
; CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x ptr> [[TMP2]], ptr [[GETELEMENTPTR8]], i64 1
33+
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <2 x ptr> [[TMP1]], <2 x ptr> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
34+
; CHECK-NEXT: [[TMP7:%.*]] = shufflevector <4 x ptr> <ptr poison, ptr poison, ptr null, ptr null>, <4 x ptr> [[TMP4]], <4 x i32> <i32 4, i32 5, i32 2, i32 3>
3335
; CHECK-NEXT: [[TMP20:%.*]] = icmp ult <4 x ptr> [[TMP19]], [[TMP7]]
3436
; CHECK-NEXT: [[ICMP58:%.*]] = icmp ult ptr [[GETELEMENTPTR]], null
3537
; CHECK-NEXT: [[ICMP62:%.*]] = icmp ult ptr [[GETELEMENTPTR]], null

0 commit comments

Comments
 (0)