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

Reply via email to