Skip to content

Commit 27b1e3b

Browse files
committedNov 30, 2018
[Mem2Reg] Fix nondeterministic corner case
Summary: When mem2reg inserts phi nodes in blocks with unreachable predecessors, it adds undef operands for those incoming edges. When there are multiple such predecessors, the order is currently based on the address of the BasicBlocks. This change fixes that by using the BBNumbers in the sort/search predicates, as is done elsewhere in mem2reg to ensure determinism. Also adds a testcase with a bunch of unreachable preds, which (nodeterministically) fails without the fix. Reviewers: majnemer Reviewed By: majnemer Subscribers: mgrang, llvm-commits Differential Revision: https://reviews.llvm.org/D55077 llvm-svn: 348024
1 parent e024c8b commit 27b1e3b

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed
 

‎llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -751,14 +751,18 @@ void PromoteMem2Reg::run() {
751751
// Ok, now we know that all of the PHI nodes are missing entries for some
752752
// basic blocks. Start by sorting the incoming predecessors for efficient
753753
// access.
754-
llvm::sort(Preds);
754+
auto CompareBBNumbers = [this](BasicBlock *A, BasicBlock *B) {
755+
return BBNumbers.lookup(A) < BBNumbers.lookup(B);
756+
};
757+
llvm::sort(Preds, CompareBBNumbers);
755758

756759
// Now we loop through all BB's which have entries in SomePHI and remove
757760
// them from the Preds list.
758761
for (unsigned i = 0, e = SomePHI->getNumIncomingValues(); i != e; ++i) {
759762
// Do a log(n) search of the Preds list for the entry we want.
760763
SmallVectorImpl<BasicBlock *>::iterator EntIt = std::lower_bound(
761-
Preds.begin(), Preds.end(), SomePHI->getIncomingBlock(i));
764+
Preds.begin(), Preds.end(), SomePHI->getIncomingBlock(i),
765+
CompareBBNumbers);
762766
assert(EntIt != Preds.end() && *EntIt == SomePHI->getIncomingBlock(i) &&
763767
"PHI node has entry for a block which is not a predecessor!");
764768

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
;RUN: opt -mem2reg -S < %s | FileCheck %s
2+
3+
declare i1 @cond()
4+
5+
define i32 @foo() {
6+
Entry:
7+
%val = alloca i32
8+
%c1 = call i1 @cond()
9+
br i1 %c1, label %Store1, label %Store2
10+
Block1:
11+
br label %Join
12+
Block2:
13+
br label %Join
14+
Block3:
15+
br label %Join
16+
Block4:
17+
br label %Join
18+
Block5:
19+
br label %Join
20+
Store1:
21+
store i32 1, i32* %val
22+
br label %Join
23+
Block6:
24+
br label %Join
25+
Block7:
26+
br label %Join
27+
Block8:
28+
br label %Join
29+
Block9:
30+
br label %Join
31+
Block10:
32+
br label %Join
33+
Store2:
34+
store i32 2, i32* %val
35+
br label %Join
36+
Block11:
37+
br label %Join
38+
Block12:
39+
br label %Join
40+
Block13:
41+
br label %Join
42+
Block14:
43+
br label %Join
44+
Block15:
45+
br label %Join
46+
Block16:
47+
br label %Join
48+
Join:
49+
; Phi inserted here should have operands appended deterministically
50+
; CHECK: %val.0 = phi i32 [ 1, %Store1 ], [ 2, %Store2 ], [ undef, %Block1 ], [ undef, %Block2 ], [ undef, %Block3 ], [ undef, %Block4 ], [ undef, %Block5 ], [ undef, %Block6 ], [ undef, %Block7 ], [ undef, %Block8 ], [ undef, %Block9 ], [ undef, %Block10 ], [ undef, %Block11 ], [ undef, %Block12 ], [ undef, %Block13 ], [ undef, %Block14 ], [ undef, %Block15 ], [ undef, %Block16 ]
51+
%result = load i32, i32* %val
52+
ret i32 %result
53+
}

0 commit comments

Comments
 (0)