Skip to content

Commit 3158525

Browse files
committed
[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
1 parent 92dfc0f commit 3158525

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3801,7 +3801,7 @@ class BoUpSLP {
38013801
SetVector<const TreeEntry *> PostponedGathers;
38023802

38033803
using ValueToGatherNodesMap =
3804-
DenseMap<Value *, SmallPtrSet<const TreeEntry *, 4>>;
3804+
DenseMap<Value *, SmallSetVector<const TreeEntry *, 4>>;
38053805
ValueToGatherNodesMap ValueToGatherNodes;
38063806

38073807
/// A list of the load entries (node indices), which can be vectorized using
@@ -8328,14 +8328,15 @@ class PHIHandler {
83288328
}
83298329
return;
83308330
}
8331-
SmallDenseMap<BasicBlock *, SmallVector<unsigned>, 4> Blocks;
8332-
for (unsigned I : seq<unsigned>(0, Main->getNumIncomingValues())) {
8331+
SmallMapVector<std::pair<BasicBlock *, unsigned>, SmallVector<unsigned>, 4>
8332+
Blocks;
8333+
for (unsigned I : seq<unsigned>(Main->getNumIncomingValues())) {
83338334
BasicBlock *InBB = Main->getIncomingBlock(I);
83348335
if (!DT.isReachableFromEntry(InBB)) {
83358336
Operands[I].assign(Phis.size(), PoisonValue::get(Main->getType()));
83368337
continue;
83378338
}
8338-
Blocks.try_emplace(InBB).first->second.push_back(I);
8339+
Blocks.try_emplace(std::make_pair(InBB, I)).first->second.push_back(I);
83398340
}
83408341
for (auto [Idx, V] : enumerate(Phis)) {
83418342
if (isa<PoisonValue>(V)) {
@@ -8344,25 +8345,26 @@ class PHIHandler {
83448345
continue;
83458346
}
83468347
auto *P = cast<PHINode>(V);
8347-
for (unsigned I : seq<unsigned>(0, P->getNumIncomingValues())) {
8348+
for (unsigned I : seq<unsigned>(P->getNumIncomingValues())) {
83488349
BasicBlock *InBB = P->getIncomingBlock(I);
83498350
if (InBB == Main->getIncomingBlock(I)) {
83508351
if (isa_and_nonnull<PoisonValue>(Operands[I][Idx]))
83518352
continue;
83528353
Operands[I][Idx] = P->getIncomingValue(I);
83538354
continue;
83548355
}
8355-
auto It = Blocks.find(InBB);
8356+
auto *It = Blocks.find(std::make_pair(InBB, I));
83568357
if (It == Blocks.end())
83578358
continue;
83588359
Operands[It->second.front()][Idx] = P->getIncomingValue(I);
83598360
}
83608361
}
83618362
for (const auto &P : Blocks) {
8362-
if (P.getSecond().size() <= 1)
8363+
ArrayRef<unsigned> IncomingValues = P.second;
8364+
if (IncomingValues.size() <= 1)
83638365
continue;
8364-
unsigned BasicI = P.getSecond().front();
8365-
for (unsigned I : ArrayRef(P.getSecond()).drop_front()) {
8366+
unsigned BasicI = IncomingValues.front();
8367+
for (unsigned I : IncomingValues.drop_front()) {
83668368
assert(all_of(enumerate(Operands[I]),
83678369
[&](const auto &Data) {
83688370
return !Data.value() ||
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-threshold=-99999 < %s | FileCheck %s
3+
4+
define i32 @test(i32 %0) {
5+
; CHECK-LABEL: define i32 @test(
6+
; CHECK-SAME: i32 [[TMP0:%.*]]) {
7+
; CHECK-NEXT: [[ENTRY:.*]]:
8+
; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> <i32 0, i32 poison>, i32 [[TMP0]], i32 1
9+
; CHECK-NEXT: switch i32 0, label %[[BCI_130:.*]] [
10+
; CHECK-NEXT: i32 -4, label %[[BCI_96:.*]]
11+
; CHECK-NEXT: i32 3, label %[[BCI_130]]
12+
; CHECK-NEXT: i32 1, label %[[BCI_130]]
13+
; CHECK-NEXT: i32 9, label %[[BCI_108:.*]]
14+
; CHECK-NEXT: i32 0, label %[[BCI_130]]
15+
; CHECK-NEXT: ]
16+
; CHECK: [[BCI_130]]:
17+
; CHECK-NEXT: [[TMP2:%.*]] = phi <2 x i32> [ zeroinitializer, %[[BCI_108]] ], [ [[TMP1]], %[[BCI_96]] ], [ [[TMP1]], %[[ENTRY]] ], [ [[TMP1]], %[[ENTRY]] ], [ [[TMP1]], %[[ENTRY]] ], [ [[TMP1]], %[[ENTRY]] ]
18+
; CHECK-NEXT: ret i32 0
19+
; CHECK: [[BCI_108]]:
20+
; CHECK-NEXT: br label %[[BCI_130]]
21+
; CHECK: [[BCI_96]]:
22+
; CHECK-NEXT: br label %[[BCI_130]]
23+
;
24+
entry:
25+
switch i32 0, label %bci_130 [
26+
i32 -4, label %bci_96
27+
i32 3, label %bci_130
28+
i32 1, label %bci_130
29+
i32 9, label %bci_108
30+
i32 0, label %bci_130
31+
]
32+
33+
bci_130:
34+
%1 = phi i32 [ 0, %bci_108 ], [ %0, %bci_96 ], [ %0, %entry ], [ %0, %entry ], [ %0, %entry ], [ %0, %entry ]
35+
%local_2_10 = phi i32 [ 0, %bci_108 ], [ 0, %bci_96 ], [ 0, %entry ], [ 0, %entry ], [ 0, %entry ], [ 0, %entry ]
36+
ret i32 0
37+
38+
bci_108:
39+
br label %bci_130
40+
41+
bci_96:
42+
br label %bci_130
43+
}

0 commit comments

Comments
 (0)