Issue |
139245
|
Summary |
BitcodeReader does not merge same incoming pairs in PHI node when inserts phi constexpr block
|
Labels |
new issue
|
Assignees |
|
Reporter |
edgankin
|
When inserting phi constexpr block it [simply replaces predecessor block with newly created block](https://github.com/llvm/llvm-project/blob/fd8b84ea0fa1eb1da105257f419d926278dc0445/llvm/lib/Bitcode/Reader/BitcodeReader.cpp#L6933), however the phi node may contain multiple entries for the predecessor block, but only one should be left since [there is only one edge from newly create phi constexpr block](https://github.com/llvm/llvm-project/blob/fd8b84ea0fa1eb1da105257f419d926278dc0445/llvm/lib/Bitcode/Reader/BitcodeReader.cpp#L6931) to the successor block.
The problem can be easily reproduced when LLVM18+ tries to read binary bitcode compiled by LLVM17, because in LLVM18 [ most constant expressions were removed](https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179).
The problem can be reproduced with the attached `bug.ll`:
```
@.str = private unnamed_addr constant [5 x i8] c"WORK\00", align 1
define ptr @bug(i8 noundef %0) {
switch i8 %0, label %2 [
i8 1, label %5
i8 2, label %5
i8 3, label %3
i8 0, label %4
]
2: ; preds = %1
unreachable
3: ; preds = %1
br label %5
4: ; preds = %1
br label %5
5: ; preds = %4, %3, %1, %1
%6 = phi ptr [ inttoptr (i64 111 to ptr), %4 ], [ inttoptr (i64 222 to ptr), %3 ], [ inttoptr (i64 or (i64 sub (i64 ptrtoint (ptr @.str to i64), i64 32), i64 -9223372036854775808) to ptr), %1 ], [ inttoptr (i64 or (i64 sub (i64 ptrtoint (ptr @.str to i64), i64 32), i64 -9223372036854775808) to ptr), %1 ]
ret ptr %6
}
```
Compile it to binary bitcode with LLVM17:
`/opt/llvm@17/bin/llvm-as bug.ll -o bug17.bc`
(`bug17.bc` is also attached)
The resulted bitcode file will be improperly read by LLVM18+:
```
/opt/llvm@19/bin/opt -passes="verify" bug17.bc
PHINode should have one entry for each predecessor of its parent basic block!
%6 = phi ptr [ inttoptr (i64 111 to ptr), %4 ], [ inttoptr (i64 222 to ptr), %3 ], [ %constexpr1, %phi.constexpr ], [ %constexpr1, %phi.constexpr ]
/opt/llvm@19/bin/opt: bug17.bc: error: input module is broken!
```
Produced IR:
```
define ptr @bug(i8 noundef %0) {
switch i8 %0, label %2 [
i8 1, label %phi.constexpr
i8 2, label %phi.constexpr
i8 3, label %3
i8 0, label %4
]
2: ; preds = %1
unreachable
3: ; preds = %1
br label %5
4: ; preds = %1
br label %5
phi.constexpr: ; preds = %1, %1
%constexpr = or i64 sub (i64 ptrtoint (ptr @.str to i64), i64 32), -9223372036854775808
%constexpr1 = inttoptr i64 %constexpr to ptr
br label %5
5: ; preds = %phi.constexpr, %4, %3
%6 = phi ptr [ inttoptr (i64 111 to ptr), %4 ], [ inttoptr (i64 222 to ptr), %3 ], [ %constexpr1, %phi.constexpr ], [ %constexpr1, %phi.constexpr ]
ret ptr %6
}
```
Note that `phi.constexpr` appears twice in the PHI node, while it should appear only once.
[bug.zip](https://github.com/user-attachments/files/20120768/bug.zip)
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs