Missed Dead Branch due to Always-False Unsigned Comparison
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
The following reduced IR is derived from https://github.com/wolfSSL/wolfssl/blob/5b1d2d795c0e1d13dc452071c07f39386cb6062f/tests/api.c#L33905
https://godbolt.org/z/G5hvaYf69
alive2: https://alive2.llvm.org/ce/z/mwHXgs
During iteration, `%2` is always negative (-1, -2, ...), so `%3 = icmp ult i32 %2, 2` is always false. Therefore, block `%5` is dead and execution always goes through %.thread5.
```llvm
define noundef i32 @test_wolfSSL_SendUserCanceled() local_unnamed_addr {
br label %1
1: ; preds = %8, %0
%.01510 = phi i32 [ 0, %0 ], [ %.pre-phi, %8 ]
%exitcond.not = phi i1 [ false, %0 ], [ true, %8 ]
%2 = add i32 %.01510, -1
%3 = icmp ult i32 %2, 2
br i1 %3, label %5, label %.thread5
.thread5: ; preds = %1
%4 = tail call i32 @fputs()
br label %8
5: ; preds = %1
%6 = icmp eq i32 %.01510, 1
%7 = zext i1 %6 to i32
br label %8
common.ret: ; preds = %8
ret i32 0
8: ; preds = %5, %.thread5
%.pre-phi = phi i32 [ %7, %5 ], [ %2, %.thread5 ]
br i1 %exitcond.not, label %common.ret, label %1, !llvm.loop !0
}
```
Expected:
```llvm
define noundef i32 @test_wolfSSL_SendUserCanceled() local_unnamed_addr {
common.ret:
%0 = tail call i32 @fputs()
%1 = tail call i32 @fputs()
ret i32 0
}
```
Contributor guide
Research direction
The report is derived from tests/api.c around line 33905; first reproduce the reduced IR in Godbolt and inspect the Alive2 trace. Then trace the relevant LLVM optimizer path for the always-false unsigned comparison and add a regression test whose output matches the expected simplified IR.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100