Skip to content

Commit 8ea8dd9

Browse files
committed
[SLP] Fix crash on trying to reshuffle a scalar that was vectorized.
If the buildvector node contains extractelement, which vector operand depends on vector node, need to check if the node is ready and use vectorized value instead of the original vector operation.
1 parent 7e9f76d commit 8ea8dd9

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10149,6 +10149,9 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
1014910149
continue;
1015010150
auto *EI = cast<ExtractElementInst>(E->Scalars[I]);
1015110151
VecBase = EI->getVectorOperand();
10152+
if (const TreeEntry *TE = R.getTreeEntry(VecBase))
10153+
VecBase = TE->VectorizedValue;
10154+
assert(VecBase && "Expected vectorized value.");
1015210155
UniqueBases.insert(VecBase);
1015310156
// If the only one use is vectorized - can delete the extractelement
1015410157
// itself.
@@ -10186,6 +10189,9 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
1018610189
if (SubMask[I] == PoisonMaskElem)
1018710190
continue;
1018810191
Value *VecOp = cast<ExtractElementInst>(V)->getVectorOperand();
10192+
if (const TreeEntry *TE = R.getTreeEntry(VecOp))
10193+
VecOp = TE->VectorizedValue;
10194+
assert(VecOp && "Expected vectorized value.");
1018910195
const int Size =
1019010196
cast<FixedVectorType>(VecOp->getType())->getNumElements();
1019110197
#ifndef NDEBUG
@@ -10593,6 +10599,21 @@ ResTy BoUpSLP::processBuildVector(const TreeEntry *E, Args &...Params) {
1059310599
ExtractShuffles =
1059410600
tryToGatherExtractElements(GatheredScalars, ExtractMask, NumParts);
1059510601
if (!ExtractShuffles.empty()) {
10602+
SmallVector<const TreeEntry *> ExtractEntries;
10603+
for (auto [Idx, I] : enumerate(ExtractMask)) {
10604+
if (I == PoisonMaskElem)
10605+
continue;
10606+
if (const auto *TE = getTreeEntry(
10607+
cast<ExtractElementInst>(E->Scalars[Idx])->getVectorOperand()))
10608+
ExtractEntries.push_back(TE);
10609+
}
10610+
if (Value *Delayed = ShuffleBuilder.needToDelay(E, ExtractEntries)) {
10611+
// Delay emission of gathers which are not ready yet.
10612+
PostponedGathers.insert(E);
10613+
// Postpone gather emission, will be emitted after the end of the
10614+
// process to keep correct order.
10615+
return Delayed;
10616+
}
1059610617
if (Value *VecBase = ShuffleBuilder.adjustExtracts(
1059710618
E, ExtractMask, NumParts, UseVecBaseAsInput)) {
1059810619
ExtractVecBase = VecBase;
@@ -10779,12 +10800,16 @@ ResTy BoUpSLP::processBuildVector(const TreeEntry *E, Args &...Params) {
1077910800
if (isa<UndefValue>(E->Scalars[I]))
1078010801
continue;
1078110802
auto *EI = cast<ExtractElementInst>(E->Scalars[I]);
10803+
Value *VecOp = EI->getVectorOperand();
10804+
if (const auto *TE = getTreeEntry(VecOp))
10805+
if (TE->VectorizedValue)
10806+
VecOp = TE->VectorizedValue;
1078210807
if (!Vec1) {
10783-
Vec1 = EI->getVectorOperand();
10808+
Vec1 = VecOp;
1078410809
} else if (Vec1 != EI->getVectorOperand()) {
1078510810
assert((!Vec2 || Vec2 == EI->getVectorOperand()) &&
1078610811
"Expected only 1 or 2 vectors shuffle.");
10787-
Vec2 = EI->getVectorOperand();
10812+
Vec2 = VecOp;
1078810813
}
1078910814
}
1079010815
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2+
; RUN: opt -passes=slp-vectorizer -S -mtriple=x86_64 < %s | FileCheck %s
3+
; Vectorization tree roots at vector build sequence (insertelement),
4+
; SLP crashed on generating vector code for pair {%i4, 0.0} trying to produce
5+
; a shuffle with %ins1 as a source because it was marked deleted
6+
; due to vectorization.
7+
8+
define void @test() {
9+
; CHECK-LABEL: define void @test() {
10+
; CHECK-NEXT: entry:
11+
; CHECK-NEXT: br label [[LOOP:%.*]]
12+
; CHECK: loop:
13+
; CHECK-NEXT: [[TMP0:%.*]] = phi <2 x float> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[TMP3:%.*]], [[LOOP]] ]
14+
; CHECK-NEXT: [[TMP1:%.*]] = fadd <2 x float> zeroinitializer, [[TMP0]]
15+
; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> zeroinitializer, <2 x float> [[TMP1]], <2 x float> zeroinitializer
16+
; CHECK-NEXT: [[TMP3]] = shufflevector <2 x float> [[TMP2]], <2 x float> <float poison, float 0.000000e+00>, <2 x i32> <i32 0, i32 3>
17+
; CHECK-NEXT: br label [[LOOP]]
18+
;
19+
entry:
20+
br label %loop
21+
22+
loop:
23+
%ph0 = phi float [ 0.000000e+00, %entry ], [ %i4, %loop ]
24+
%ph1 = phi float [ 0.000000e+00, %entry ], [ 0.000000e+00, %loop ]
25+
%i = fadd float 0.000000e+00, %ph0
26+
%i1 = fadd float 0.000000e+00, %ph1
27+
%i2 = select i1 false, float %i, float 0.000000e+00
28+
%i3 = select i1 false, float %i1, float 0.000000e+00
29+
%ins0 = insertelement <2 x float> zeroinitializer, float %i2, i64 0
30+
%ins1 = insertelement <2 x float> %ins0, float %i3, i64 1
31+
%i4 = extractelement <2 x float> %ins1, i64 0
32+
br label %loop
33+
}

0 commit comments

Comments
 (0)