Extended Description
Originally reported at: rust-lang/rust#58692
The following IR remains unchanged under opt -O3:
define i1 @test(i64 %x, i64 %y) nounwind {
%a = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x, i64 %y)
%b = extractvalue { i64, i1 } %a, 1
br i1 %b, label %trap, label %bb
bb:
%c = extractvalue { i64, i1 } %a, 0
%d = icmp ult i64 %c, %x
ret i1 %d
trap:
call void @llvm.trap()
unreachable
}
declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64)
declare void @llvm.trap()
Here %d is the same as %b, and must be false in %bb by implication.
I think this should be fairly easy to fix (at least for this specific case) with an instcombine pattern that converts the icmp into an extract, and CSE/GVN will take care of the rest.