Skip to content

Commit a8e486b

Browse files
authored
[Bitcode] Fix constexpr expansion creating invalid PHIs (#141560)
Fixes errors about duplicate PHI edges when the input had duplicates with constexprs in them. The constexpr translation makes new basic blocks, causing the verifier to complain about duplicate entries in PHI nodes.
1 parent 904d0c2 commit a8e486b

File tree

4 files changed

+38
-4
lines changed

4 files changed

+38
-4
lines changed

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6095,14 +6095,18 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
60956095
// seen value here, to avoid expanding a constant expression multiple
60966096
// times.
60976097
auto It = Args.find(BB);
6098+
BasicBlock *EdgeBB = ConstExprEdgeBBs.lookup({BB, CurBB});
60986099
if (It != Args.end()) {
6099-
PN->addIncoming(It->second, BB);
6100+
// If this predecessor was also replaced with a constexpr basic
6101+
// block, it must be de-duplicated.
6102+
if (!EdgeBB) {
6103+
PN->addIncoming(It->second, BB);
6104+
}
61006105
continue;
61016106
}
61026107

61036108
// If there already is a block for this edge (from a different phi),
61046109
// use it.
6105-
BasicBlock *EdgeBB = ConstExprEdgeBBs.lookup({BB, CurBB});
61066110
if (!EdgeBB) {
61076111
// Otherwise, use a temporary block (that we will discard if it
61086112
// turns out to be unnecessary).
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; RUN: opt -expand-constant-exprs %s.bc -S | FileCheck %s
2+
@foo = external constant i32
3+
4+
define i32 @test(i32 %arg) {
5+
entry:
6+
switch i32 %arg, label %cont [
7+
i32 1, label %cont
8+
i32 2, label %nonconst
9+
]
10+
11+
nonconst:
12+
%cmp = icmp ne i32 %arg, 2
13+
br i1 %cmp, label %cont, label %cont
14+
15+
; CHECK-LABEL: phi.constexpr:
16+
; CHECK-NEXT: %constexpr = ptrtoint ptr @foo to i32
17+
; CHECK-NEXT: %constexpr1 = or i32 %constexpr, 5
18+
; CHECK-NEXT: br label %cont
19+
20+
21+
; CHECK-LABEL: cont:
22+
; CHECK-NEXT: %res = phi i32 [ %constexpr1, %phi.constexpr ], [ 1, %nonconst ], [ 1, %nonconst ]
23+
; CHECK-NEXT: ret i32 %res
24+
cont:
25+
%res = phi i32 [or (i32 5, i32 ptrtoint (ptr @foo to i32)), %entry],
26+
[or (i32 5, i32 ptrtoint (ptr @foo to i32)), %entry],
27+
[1, %nonconst],
28+
[1, %nonconst]
29+
ret i32 %res
30+
}
Binary file not shown.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: llvm-dis -expand-constant-exprs < %s.bc | FileCheck %s
1+
; RUN: opt -expand-constant-exprs -S %s.bc | FileCheck %s
22

33
@g = extern_weak global i32
44
@g2 = extern_weak global i32
@@ -225,7 +225,7 @@ define i64 @test_phi_multiple_identical_predecessors(i32 %x) {
225225
; CHECK-NEXT: %constexpr = ptrtoint ptr @g to i64
226226
; CHECK-NEXT: br label %join
227227
; CHECK: join:
228-
; CHECK-NEXT: %phi = phi i64 [ %constexpr, %phi.constexpr ], [ %constexpr, %phi.constexpr ], [ 0, %default ]
228+
; CHECK-NEXT: %phi = phi i64 [ %constexpr, %phi.constexpr ], [ 0, %default ]
229229
; CHECK-NEXT: ret i64 %phi
230230
entry:
231231
switch i32 %x, label %default [

0 commit comments

Comments
 (0)