aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@outlook.com>2024-08-21 11:47:00 -0700
committerAlexey Bataev <a.bataev@outlook.com>2024-08-21 12:22:01 -0700
commite31252bf54dedadfe78b36d07ea6084156faa38a (patch)
treefc132d663c09b07eb0ec424c9790acb1815db38a
parent6ec3130a38e6982a61e7fa74bd5223c95c0bb918 (diff)
downloadllvm-e31252bf54dedadfe78b36d07ea6084156faa38a.zip
llvm-e31252bf54dedadfe78b36d07ea6084156faa38a.tar.gz
llvm-e31252bf54dedadfe78b36d07ea6084156faa38a.tar.bz2
[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 https://github.com/llvm/llvm-project/issues/105120
-rw-r--r--llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp24
-rw-r--r--llvm/test/Transforms/SLPVectorizer/X86/phi-nodes-as-operand-reorder.ll38
2 files changed, 59 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index dee6d68..848e0de 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -7227,6 +7227,22 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
unsigned ShuffleOrOp = S.isAltShuffle() ?
(unsigned) Instruction::ShuffleVector : S.getOpcode();
+ auto CreateOperandNodes = [&](TreeEntry *TE, const auto &Operands) {
+ // Postpone PHI nodes creation
+ SmallVector<unsigned> PHIOps;
+ for (unsigned I : seq<unsigned>(Operands.size())) {
+ ArrayRef<Value *> Op = Operands[I];
+ if (Op.empty())
+ continue;
+ InstructionsState S = getSameOpcode(Op, *TLI);
+ if (S.getOpcode() != Instruction::PHI || S.isAltShuffle())
+ buildTree_rec(Op, Depth + 1, {TE, I});
+ else
+ PHIOps.push_back(I);
+ }
+ for (unsigned I : PHIOps)
+ buildTree_rec(Operands[I], Depth + 1, {TE, I});
+ };
switch (ShuffleOrOp) {
case Instruction::PHI: {
auto *PH = cast<PHINode>(VL0);
@@ -7238,10 +7254,12 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
// Keeps the reordered operands to avoid code duplication.
PHIHandler Handler(*DT, PH, VL);
Handler.buildOperands();
- for (unsigned I : seq<unsigned>(0, PH->getNumOperands()))
+ for (unsigned I : seq<unsigned>(PH->getNumOperands()))
TE->setOperand(I, Handler.getOperands(I));
- for (unsigned I : seq<unsigned>(0, PH->getNumOperands()))
- buildTree_rec(Handler.getOperands(I), Depth + 1, {TE, I});
+ SmallVector<ArrayRef<Value *>> Operands(PH->getNumOperands());
+ for (unsigned I : seq<unsigned>(PH->getNumOperands()))
+ Operands[I] = Handler.getOperands(I);
+ CreateOperandNodes(TE, Operands);
return;
}
case Instruction::ExtractValue:
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/phi-nodes-as-operand-reorder.ll b/llvm/test/Transforms/SLPVectorizer/X86/phi-nodes-as-operand-reorder.ll
new file mode 100644
index 0000000..51ce970
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/phi-nodes-as-operand-reorder.ll
@@ -0,0 +1,38 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-threshold=-99999 < %s | FileCheck %s
+
+define void @test() {
+; CHECK-LABEL: define void @test() {
+; CHECK-NEXT: [[BB:.*]]:
+; CHECK-NEXT: br label %[[BB1:.*]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: [[TMP0:%.*]] = phi <2 x i32> [ zeroinitializer, %[[BB]] ], [ [[TMP3:%.*]], %[[BB3:.*]] ]
+; CHECK-NEXT: br i1 false, label %[[BB6:.*]], label %[[BB3]]
+; CHECK: [[BB3]]:
+; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i32> [[TMP0]], <2 x i32> <i32 0, i32 poison>, <2 x i32> <i32 2, i32 1>
+; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i32> zeroinitializer, [[TMP1]]
+; CHECK-NEXT: [[TMP3]] = add <2 x i32> zeroinitializer, [[TMP1]]
+; CHECK-NEXT: br i1 false, label %[[BB6]], label %[[BB1]]
+; CHECK: [[BB6]]:
+; CHECK-NEXT: [[TMP4:%.*]] = phi <2 x i32> [ [[TMP0]], %[[BB1]] ], [ [[TMP2]], %[[BB3]] ]
+; CHECK-NEXT: ret void
+;
+bb:
+ br label %bb1
+
+bb1:
+ %phi = phi i32 [ 0, %bb ], [ %add5, %bb3 ]
+ %phi2 = phi i32 [ 0, %bb ], [ %add, %bb3 ]
+ br i1 false, label %bb6, label %bb3
+
+bb3:
+ %add = add i32 0, 0
+ %add4 = add i32 0, 0
+ %add5 = add i32 %phi, 0
+ br i1 false, label %bb6, label %bb1
+
+bb6:
+ %phi7 = phi i32 [ %phi2, %bb1 ], [ %add4, %bb3 ]
+ %phi8 = phi i32 [ %phi, %bb1 ], [ %add5, %bb3 ]
+ ret void
+}