This revision adds the following peephole optimization and it's negation:
%a = urem i64 %x, %y %b = icmp ule i64 %a, %x ====> %b = true
With John Regehr's help this optimization was checked with Alive2 which suggests it should be valid.
This pattern occurs in the bound checks of Rust code, the program
const N: usize = 3; const T = u8; pub fn split_mutiple(slice: &[T]) -> (&[T], &[T]) { let len = slice.len() / N; slice.split_at(len * N) }
the method call slice.split_at will check that len * N is within the bounds of slice, this bounds check is after some transformations turned into the urem seen above and then LLVM fails to optimize it any further. Adding this optimization would cause this bounds check to be fully optimized away.
Minor nit: icmp pred (urem X, Y), X might be better for readability