aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
+}