Open ProgramCrafter opened 1 year ago
It's worrying about wrap around overflow inlim * 3 >= lim
by itself in case lim
is something like usize::MAX
, I'm guessing the problem is that the numerical bounds of what leads to lim
could be are not being tracked with respect to division by a constant.
nuw
already gets inferred on the mul
: https://rust.godbolt.org/z/99r9no3MP
So LLVM just needs this transform: https://alive2.llvm.org/ce/z/4a6RLR
declare void @llvm.assume(i1)
define i1 @src(i16 %x, i16 %c) {
%c_nonzero = icmp ne i16 %c, 0
call void @llvm.assume(i1 %c_nonzero)
%x3 = mul nuw i16 %x, %c
%cmp = icmp uge i16 %x3, %x
ret i1 %cmp
}
define i1 @tgt(i16 %x, i16 %c) {
ret i1 true
}
I tried this code:
The check
lim * 3 >= lim
is trivially true, sincelim
is obtained by dividingusize
by 3 so there can be no overflow. I expected to see it optimized out in ASM, like here (obtained via std::hint::black_box-ing true):Instead, this happened:
Meta
https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=17cc61a317c18d7ea86d7d98b6a43510
triple_lim >= triple_lim / 3
in a similar test is actually optimized away.Source
Optimized down from https://rust.godbolt.org/z/jsh6zhPYa (utility function for converting BGR to RGBA arrays).