diff options
| author | Alexey Bataev <a.bataev@outlook.com> | 2024-08-21 11:47:00 -0700 |
|---|---|---|
| committer | Alexey Bataev <a.bataev@outlook.com> | 2024-08-21 12:22:01 -0700 |
| commit | e31252bf54dedadfe78b36d07ea6084156faa38a (patch) | |
| tree | fc132d663c09b07eb0ec424c9790acb1815db38a | |
| parent | 6ec3130a38e6982a61e7fa74bd5223c95c0bb918 (diff) | |
| download | llvm-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.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 +} |
