Skip to content

Commit 4fe93c0

Browse files
bcahoontstellar
authored andcommitted
[SLP] Fix assert from non-constant index in insertelement
A call to getInsertIndex() in getTreeCost() is returning None, which causes an assert because a non-constant index value for insertelement was not expected. This case occurs when the insertelement index value is defined with a PHI. Differential Revision: https://reviews.llvm.org/D120223 (cherry picked from commit 3cc15e2)
1 parent a2398c5 commit 4fe93c0

File tree

2 files changed

+63
-30
lines changed

2 files changed

+63
-30
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5682,39 +5682,41 @@ InstructionCost BoUpSLP::getTreeCost(ArrayRef<Value *> VectorizedVals) {
56825682
// to detect it as a final shuffled/identity match.
56835683
if (auto *VU = dyn_cast_or_null<InsertElementInst>(EU.User)) {
56845684
if (auto *FTy = dyn_cast<FixedVectorType>(VU->getType())) {
5685-
unsigned InsertIdx = *getInsertIndex(VU);
5686-
auto *It = find_if(FirstUsers, [VU](Value *V) {
5687-
return areTwoInsertFromSameBuildVector(VU,
5688-
cast<InsertElementInst>(V));
5689-
});
5690-
int VecId = -1;
5691-
if (It == FirstUsers.end()) {
5692-
VF.push_back(FTy->getNumElements());
5693-
ShuffleMask.emplace_back(VF.back(), UndefMaskElem);
5694-
// Find the insertvector, vectorized in tree, if any.
5695-
Value *Base = VU;
5696-
while (isa<InsertElementInst>(Base)) {
5697-
// Build the mask for the vectorized insertelement instructions.
5698-
if (const TreeEntry *E = getTreeEntry(Base)) {
5699-
VU = cast<InsertElementInst>(Base);
5700-
do {
5701-
int Idx = E->findLaneForValue(Base);
5702-
ShuffleMask.back()[Idx] = Idx;
5703-
Base = cast<InsertElementInst>(Base)->getOperand(0);
5704-
} while (E == getTreeEntry(Base));
5705-
break;
5685+
Optional<unsigned> InsertIdx = getInsertIndex(VU);
5686+
if (InsertIdx) {
5687+
auto *It = find_if(FirstUsers, [VU](Value *V) {
5688+
return areTwoInsertFromSameBuildVector(VU,
5689+
cast<InsertElementInst>(V));
5690+
});
5691+
int VecId = -1;
5692+
if (It == FirstUsers.end()) {
5693+
VF.push_back(FTy->getNumElements());
5694+
ShuffleMask.emplace_back(VF.back(), UndefMaskElem);
5695+
// Find the insertvector, vectorized in tree, if any.
5696+
Value *Base = VU;
5697+
while (isa<InsertElementInst>(Base)) {
5698+
// Build the mask for the vectorized insertelement instructions.
5699+
if (const TreeEntry *E = getTreeEntry(Base)) {
5700+
VU = cast<InsertElementInst>(Base);
5701+
do {
5702+
int Idx = E->findLaneForValue(Base);
5703+
ShuffleMask.back()[Idx] = Idx;
5704+
Base = cast<InsertElementInst>(Base)->getOperand(0);
5705+
} while (E == getTreeEntry(Base));
5706+
break;
5707+
}
5708+
Base = cast<InsertElementInst>(Base)->getOperand(0);
57065709
}
5707-
Base = cast<InsertElementInst>(Base)->getOperand(0);
5710+
FirstUsers.push_back(VU);
5711+
DemandedElts.push_back(APInt::getZero(VF.back()));
5712+
VecId = FirstUsers.size() - 1;
5713+
} else {
5714+
VecId = std::distance(FirstUsers.begin(), It);
57085715
}
5709-
FirstUsers.push_back(VU);
5710-
DemandedElts.push_back(APInt::getZero(VF.back()));
5711-
VecId = FirstUsers.size() - 1;
5712-
} else {
5713-
VecId = std::distance(FirstUsers.begin(), It);
5716+
ShuffleMask[VecId][*InsertIdx] = EU.Lane;
5717+
DemandedElts[VecId].setBit(*InsertIdx);
5718+
continue;
57145719
}
5715-
ShuffleMask[VecId][InsertIdx] = EU.Lane;
5716-
DemandedElts[VecId].setBit(InsertIdx);
5717-
continue;
57185720
}
57195721
}
57205722

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -slp-vectorizer -slp-max-vf=2 -slp-min-reg-size=32 -S < %s | FileCheck %s
3+
4+
; It is possible to compute the tree cost for an insertelement that does not
5+
; have a constant index when the index is a PHI. Check if getInsertIndex
6+
; returns None.
7+
8+
define void @test() local_unnamed_addr {
9+
; CHECK-LABEL: @test(
10+
; CHECK-NEXT: entry:
11+
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
12+
; CHECK: for.cond.cleanup:
13+
; CHECK-NEXT: unreachable
14+
; CHECK: for.body:
15+
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ poison, [[FOR_BODY]] ]
16+
; CHECK-NEXT: [[J:%.*]] = phi i32 [ poison, [[ENTRY]] ], [ 0, [[FOR_BODY]] ]
17+
; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 poison, i32 [[I]]
18+
; CHECK-NEXT: br i1 poison, label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
19+
;
20+
entry:
21+
br label %for.body
22+
23+
for.cond.cleanup:
24+
unreachable
25+
26+
for.body:
27+
%i = phi i32 [ 0, %entry ], [ poison, %for.body ]
28+
%j = phi i32 [ poison, %entry ], [ 0, %for.body ]
29+
%0 = insertelement <4 x i32> poison, i32 poison, i32 %i
30+
br i1 poison, label %for.cond.cleanup, label %for.body
31+
}

0 commit comments

Comments
 (0)