Skip to content

Commit a1d65a5

Browse files
committed
[Bitcode] Fix incomplete deduplication of PHI entries
1 parent 4ad625b commit a1d65a5

File tree

3 files changed

+54
-6
lines changed

3 files changed

+54
-6
lines changed

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4093,6 +4093,30 @@ GlobalValue::SanitizerMetadata deserializeSanitizerMetadata(unsigned V) {
40934093
return Meta;
40944094
}
40954095

4096+
static void deduplicatePhiUsesOf(BasicBlock *BB, BasicBlock *ToDeduplicateBB) {
4097+
// N.B. This might not be a complete BasicBlock, so don't assume
4098+
// that it ends with a non-phi instruction.
4099+
for (Instruction &I : *BB) {
4100+
PHINode *PN = dyn_cast<PHINode>(&I);
4101+
if (!PN)
4102+
break;
4103+
// Since the order of basic blocks in a PHINode are not generally sorted we
4104+
// have to iterate over all indicies.
4105+
unsigned Idx = 0;
4106+
bool SkippedFirstOccurrence = false;
4107+
while (Idx < PN->getNumIncomingValues()) {
4108+
if (PN->getIncomingBlock(Idx) == ToDeduplicateBB) {
4109+
if (SkippedFirstOccurrence) {
4110+
PN->removeIncomingValue(Idx);
4111+
continue;
4112+
}
4113+
SkippedFirstOccurrence = true;
4114+
}
4115+
++Idx;
4116+
}
4117+
}
4118+
}
4119+
40964120
Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
40974121
// v1: [pointer type, isconst, initid, linkage, alignment, section,
40984122
// visibility, threadlocal, unnamed_addr, externally_initialized,
@@ -6105,18 +6129,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
61056129
// seen value here, to avoid expanding a constant expression multiple
61066130
// times.
61076131
auto It = Args.find(BB);
6108-
BasicBlock *EdgeBB = ConstExprEdgeBBs.lookup({BB, CurBB});
61096132
if (It != Args.end()) {
6110-
// If this predecessor was also replaced with a constexpr basic
6111-
// block, it must be de-duplicated.
6112-
if (!EdgeBB) {
6113-
PN->addIncoming(It->second, BB);
6114-
}
6133+
PN->addIncoming(It->second, BB);
61156134
continue;
61166135
}
61176136

61186137
// If there already is a block for this edge (from a different phi),
61196138
// use it.
6139+
BasicBlock *EdgeBB = ConstExprEdgeBBs.lookup({BB, CurBB});
61206140
if (!EdgeBB) {
61216141
// Otherwise, use a temporary block (that we will discard if it
61226142
// turns out to be unnecessary).
@@ -6944,6 +6964,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
69446964
BranchInst::Create(To, EdgeBB);
69456965
From->getTerminator()->replaceSuccessorWith(To, EdgeBB);
69466966
To->replacePhiUsesWith(From, EdgeBB);
6967+
deduplicatePhiUsesOf(To, EdgeBB);
69476968
EdgeBB->moveBefore(To);
69486969
}
69496970

llvm/test/Bitcode/constexpr-to-instr-dups.ll

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,30 @@ cont:
2828
[1, %nonconst]
2929
ret i32 %res
3030
}
31+
32+
define i32 @test_multiple_phis(i32 %arg) {
33+
entry:
34+
switch i32 %arg, label %cont [
35+
i32 1, label %cont
36+
i32 2, label %nonconst
37+
]
38+
39+
nonconst: ; preds = %entry
40+
%cmp = icmp ne i32 %arg, 2
41+
br i1 %cmp, label %cont, label %cont
42+
43+
; CHECK-LABEL: phi.constexpr:
44+
; CHECK-NEXT: %constexpr = ptrtoint ptr @foo to i32
45+
; CHECK-NEXT: %constexpr1 = or i32 %constexpr, 5
46+
; CHECK-NEXT: br label %cont
47+
48+
49+
; CHECK-LABEL: cont:
50+
; CHECK-NEXT: %phi1 = phi i32 [ 0, %phi.constexpr ], [ 1, %nonconst ], [ 1, %nonconst ]
51+
; CHECK-NEXT: %phi2 = phi i32 [ %constexpr1, %phi.constexpr ], [ 1, %nonconst ], [ 1, %nonconst ]
52+
; CHECK-NEXT: ret i32 %phi2
53+
cont: ; preds = %nonconst, %nonconst, %entry, %entry
54+
%phi1 = phi i32 [ 0, %entry ], [ 0, %entry ], [ 1, %nonconst ], [ 1, %nonconst ]
55+
%phi2 = phi i32 [ or (i32 ptrtoint (ptr @foo to i32), i32 5), %entry ], [ or (i32 ptrtoint (ptr @foo to i32), i32 5), %entry ], [ 1, %nonconst ], [ 1, %nonconst ]
56+
ret i32 %phi2
57+
}
136 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)