diff options
| -rw-r--r-- | llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 24 | ||||
| -rw-r--r-- | llvm/test/Transforms/SLPVectorizer/X86/phi-nodes-as-operand-reorder.ll | 38 |
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 +} |
