-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Description
When inserting phi constexpr block it simply replaces predecessor block with newly created block, 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 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.
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.