[llvm] 3158525 - [SLP]Fix non-determinism in reused elements analysis
Alexey Bataev via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 6 08:51:41 PST 2025
Author: Alexey Bataev
Date: 2025-03-06T08:51:31-08:00
New Revision: 3158525afdc3677457712963ef45c83f4f8f900f
URL: https://github.com/llvm/llvm-project/commit/3158525afdc3677457712963ef45c83f4f8f900f
DIFF: https://github.com/llvm/llvm-project/commit/3158525afdc3677457712963ef45c83f4f8f900f.diff
LOG: [SLP]Fix non-determinism in reused elements analysis
Need to use consistent storages for unique elements, when going to
iterate over them to avoid non-determinism in reused elements analysis.
Fixes #130082
Added:
llvm/test/Transforms/SLPVectorizer/X86/buildvectors-with-same-parents.ll
Modified:
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 3bb8e38905aae..a44bfe0dfd74a 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -3801,7 +3801,7 @@ class BoUpSLP {
SetVector<const TreeEntry *> PostponedGathers;
using ValueToGatherNodesMap =
- DenseMap<Value *, SmallPtrSet<const TreeEntry *, 4>>;
+ DenseMap<Value *, SmallSetVector<const TreeEntry *, 4>>;
ValueToGatherNodesMap ValueToGatherNodes;
/// A list of the load entries (node indices), which can be vectorized using
@@ -8328,14 +8328,15 @@ class PHIHandler {
}
return;
}
- SmallDenseMap<BasicBlock *, SmallVector<unsigned>, 4> Blocks;
- for (unsigned I : seq<unsigned>(0, Main->getNumIncomingValues())) {
+ SmallMapVector<std::pair<BasicBlock *, unsigned>, SmallVector<unsigned>, 4>
+ Blocks;
+ for (unsigned I : seq<unsigned>(Main->getNumIncomingValues())) {
BasicBlock *InBB = Main->getIncomingBlock(I);
if (!DT.isReachableFromEntry(InBB)) {
Operands[I].assign(Phis.size(), PoisonValue::get(Main->getType()));
continue;
}
- Blocks.try_emplace(InBB).first->second.push_back(I);
+ Blocks.try_emplace(std::make_pair(InBB, I)).first->second.push_back(I);
}
for (auto [Idx, V] : enumerate(Phis)) {
if (isa<PoisonValue>(V)) {
@@ -8344,7 +8345,7 @@ class PHIHandler {
continue;
}
auto *P = cast<PHINode>(V);
- for (unsigned I : seq<unsigned>(0, P->getNumIncomingValues())) {
+ for (unsigned I : seq<unsigned>(P->getNumIncomingValues())) {
BasicBlock *InBB = P->getIncomingBlock(I);
if (InBB == Main->getIncomingBlock(I)) {
if (isa_and_nonnull<PoisonValue>(Operands[I][Idx]))
@@ -8352,17 +8353,18 @@ class PHIHandler {
Operands[I][Idx] = P->getIncomingValue(I);
continue;
}
- auto It = Blocks.find(InBB);
+ auto *It = Blocks.find(std::make_pair(InBB, I));
if (It == Blocks.end())
continue;
Operands[It->second.front()][Idx] = P->getIncomingValue(I);
}
}
for (const auto &P : Blocks) {
- if (P.getSecond().size() <= 1)
+ ArrayRef<unsigned> IncomingValues = P.second;
+ if (IncomingValues.size() <= 1)
continue;
- unsigned BasicI = P.getSecond().front();
- for (unsigned I : ArrayRef(P.getSecond()).drop_front()) {
+ unsigned BasicI = IncomingValues.front();
+ for (unsigned I : IncomingValues.drop_front()) {
assert(all_of(enumerate(Operands[I]),
[&](const auto &Data) {
return !Data.value() ||
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/buildvectors-with-same-parents.ll b/llvm/test/Transforms/SLPVectorizer/X86/buildvectors-with-same-parents.ll
new file mode 100644
index 0000000000000..daf9501f1b4ea
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/buildvectors-with-same-parents.ll
@@ -0,0 +1,43 @@
+; 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 i32 @test(i32 %0) {
+; CHECK-LABEL: define i32 @test(
+; CHECK-SAME: i32 [[TMP0:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> <i32 0, i32 poison>, i32 [[TMP0]], i32 1
+; CHECK-NEXT: switch i32 0, label %[[BCI_130:.*]] [
+; CHECK-NEXT: i32 -4, label %[[BCI_96:.*]]
+; CHECK-NEXT: i32 3, label %[[BCI_130]]
+; CHECK-NEXT: i32 1, label %[[BCI_130]]
+; CHECK-NEXT: i32 9, label %[[BCI_108:.*]]
+; CHECK-NEXT: i32 0, label %[[BCI_130]]
+; CHECK-NEXT: ]
+; CHECK: [[BCI_130]]:
+; CHECK-NEXT: [[TMP2:%.*]] = phi <2 x i32> [ zeroinitializer, %[[BCI_108]] ], [ [[TMP1]], %[[BCI_96]] ], [ [[TMP1]], %[[ENTRY]] ], [ [[TMP1]], %[[ENTRY]] ], [ [[TMP1]], %[[ENTRY]] ], [ [[TMP1]], %[[ENTRY]] ]
+; CHECK-NEXT: ret i32 0
+; CHECK: [[BCI_108]]:
+; CHECK-NEXT: br label %[[BCI_130]]
+; CHECK: [[BCI_96]]:
+; CHECK-NEXT: br label %[[BCI_130]]
+;
+entry:
+ switch i32 0, label %bci_130 [
+ i32 -4, label %bci_96
+ i32 3, label %bci_130
+ i32 1, label %bci_130
+ i32 9, label %bci_108
+ i32 0, label %bci_130
+ ]
+
+bci_130:
+ %1 = phi i32 [ 0, %bci_108 ], [ %0, %bci_96 ], [ %0, %entry ], [ %0, %entry ], [ %0, %entry ], [ %0, %entry ]
+ %local_2_10 = phi i32 [ 0, %bci_108 ], [ 0, %bci_96 ], [ 0, %entry ], [ 0, %entry ], [ 0, %entry ], [ 0, %entry ]
+ ret i32 0
+
+bci_108:
+ br label %bci_130
+
+bci_96:
+ br label %bci_130
+}
More information about the llvm-commits
mailing list