Open
Description
For the following case, due to the attached !range !0
metadata, the value %3 is constrained to the range [0, 2). Based on control flow, when entering block %5, %3 must be 0. However, under opt -O3, LLVM only optimizes the ret instruction and does not optimize the store instruction.
By comparing the differences, we suspect this may be a missed optimization in IPSCCP?
Godbolt: https://godbolt.org/z/W41K3j8b5
alive2 proof: https://alive2.llvm.org/ce/z/6TirEj
the reduced case:
define i8 @src(ptr %0, ptr %1){
%3 = load i8, ptr %0, align 1, !range !0
%4 = trunc i8 %3 to i1
br i1 %4, label %common.ret, label %5
common.ret: ; preds = %5, %1
ret i8 0
5: ; preds = %1
store i8 %3, ptr %1, align 1
ret i8 %3
}
!0 = !{i8 0, i8 2}
opt -O3:
define noundef range(i8 0, 2) i8 @src(ptr readonly captures(none) %0, ptr writeonly captures(none) %1) local_unnamed_addr #0 {
%3 = load i8, ptr %0, align 1, !range !0
%4 = trunc nuw i8 %3 to i1
br i1 %4, label %common.ret1, label %5
common.ret1: ; preds = %2, %5
ret i8 0
5: ; preds = %2
store i8 %3, ptr %1, align 1
br label %common.ret1
}
The reduced case is derived from https://github.com/ceres-solver/ceres-solver/blob/b5b63b5b66d4075c3b7726995b704428b3985e23/internal/ceres/solver.cc#L269.