Skip to content

Commit e31252b

Browse files
committed
[SLP]Fix PR105120: fix the order of phi nodes vectorization.
The operands of the phi nodes should be vectorized in the same order, in which they were created, otherwise the compiler may crash when trying to correctly build dependency for nodes with non-schedulable instructions for gather/buildvector nodes. Fixes #105120
1 parent 6ec3130 commit e31252b

File tree

2 files changed

+59
-3
lines changed

2 files changed

+59
-3
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7227,6 +7227,22 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
72277227

72287228
unsigned ShuffleOrOp = S.isAltShuffle() ?
72297229
(unsigned) Instruction::ShuffleVector : S.getOpcode();
7230+
auto CreateOperandNodes = [&](TreeEntry *TE, const auto &Operands) {
7231+
// Postpone PHI nodes creation
7232+
SmallVector<unsigned> PHIOps;
7233+
for (unsigned I : seq<unsigned>(Operands.size())) {
7234+
ArrayRef<Value *> Op = Operands[I];
7235+
if (Op.empty())
7236+
continue;
7237+
InstructionsState S = getSameOpcode(Op, *TLI);
7238+
if (S.getOpcode() != Instruction::PHI || S.isAltShuffle())
7239+
buildTree_rec(Op, Depth + 1, {TE, I});
7240+
else
7241+
PHIOps.push_back(I);
7242+
}
7243+
for (unsigned I : PHIOps)
7244+
buildTree_rec(Operands[I], Depth + 1, {TE, I});
7245+
};
72307246
switch (ShuffleOrOp) {
72317247
case Instruction::PHI: {
72327248
auto *PH = cast<PHINode>(VL0);
@@ -7238,10 +7254,12 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
72387254
// Keeps the reordered operands to avoid code duplication.
72397255
PHIHandler Handler(*DT, PH, VL);
72407256
Handler.buildOperands();
7241-
for (unsigned I : seq<unsigned>(0, PH->getNumOperands()))
7257+
for (unsigned I : seq<unsigned>(PH->getNumOperands()))
72427258
TE->setOperand(I, Handler.getOperands(I));
7243-
for (unsigned I : seq<unsigned>(0, PH->getNumOperands()))
7244-
buildTree_rec(Handler.getOperands(I), Depth + 1, {TE, I});
7259+
SmallVector<ArrayRef<Value *>> Operands(PH->getNumOperands());
7260+
for (unsigned I : seq<unsigned>(PH->getNumOperands()))
7261+
Operands[I] = Handler.getOperands(I);
7262+
CreateOperandNodes(TE, Operands);
72457263
return;
72467264
}
72477265
case Instruction::ExtractValue:
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-threshold=-99999 < %s | FileCheck %s
3+
4+
define void @test() {
5+
; CHECK-LABEL: define void @test() {
6+
; CHECK-NEXT: [[BB:.*]]:
7+
; CHECK-NEXT: br label %[[BB1:.*]]
8+
; CHECK: [[BB1]]:
9+
; CHECK-NEXT: [[TMP0:%.*]] = phi <2 x i32> [ zeroinitializer, %[[BB]] ], [ [[TMP3:%.*]], %[[BB3:.*]] ]
10+
; CHECK-NEXT: br i1 false, label %[[BB6:.*]], label %[[BB3]]
11+
; CHECK: [[BB3]]:
12+
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> <i32 0, i32 poison>, <2 x i32> <i32 2, i32 1>
13+
; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i32> zeroinitializer, [[TMP1]]
14+
; CHECK-NEXT: [[TMP3]] = add <2 x i32> zeroinitializer, [[TMP1]]
15+
; CHECK-NEXT: br i1 false, label %[[BB6]], label %[[BB1]]
16+
; CHECK: [[BB6]]:
17+
; CHECK-NEXT: [[TMP4:%.*]] = phi <2 x i32> [ [[TMP0]], %[[BB1]] ], [ [[TMP2]], %[[BB3]] ]
18+
; CHECK-NEXT: ret void
19+
;
20+
bb:
21+
br label %bb1
22+
23+
bb1:
24+
%phi = phi i32 [ 0, %bb ], [ %add5, %bb3 ]
25+
%phi2 = phi i32 [ 0, %bb ], [ %add, %bb3 ]
26+
br i1 false, label %bb6, label %bb3
27+
28+
bb3:
29+
%add = add i32 0, 0
30+
%add4 = add i32 0, 0
31+
%add5 = add i32 %phi, 0
32+
br i1 false, label %bb6, label %bb1
33+
34+
bb6:
35+
%phi7 = phi i32 [ %phi2, %bb1 ], [ %add4, %bb3 ]
36+
%phi8 = phi i32 [ %phi, %bb1 ], [ %add5, %bb3 ]
37+
ret void
38+
}

0 commit comments

Comments
 (0)