Issue 115767
Summary Failure to optimize `udiv`/`urem` when non-constant divisor is known power of two
Labels missed-optimization
Assignees
Reporter Kmeakin
    Strength reduction can be performed on `udiv`/`urem` if the divisor is known to be a power of two, due to dominating condition or assume:

Compiler explorer: https://godbolt.org/z/4ncnjsPTM
Alive proof: https://alive2.llvm.org/ce/z/3FJYeg
```rust

#![feature(core_intrinsics)]

use std::hint::assert_unchecked as assume;
use std::intrinsics::unchecked_div;
use std::intrinsics::unchecked_rem;

#[no_mangle]
pub fn src_udiv_if(x: u32, y: u32) -> u32 {
    if y.is_power_of_two() {
        unsafe { unchecked_div(x, y) }
    } else {
        0
 }
}

#[no_mangle]
pub fn tgt_udiv_if(x: u32, y: u32) -> u32 {
 if y.is_power_of_two() {
        x >> y.trailing_zeros()
    } else {
        0
    }
}

#[no_mangle]
pub fn src_udiv_assume(x: u32, y: u32) -> u32 {
    unsafe {
 assume(y.is_power_of_two());
        unchecked_div(x, y)
 }
}

#[no_mangle]
pub fn tgt_udiv_assume(x: u32, y: u32) -> u32 {
    unsafe {
        assume(y.is_power_of_two());
        x >> y.trailing_zeros()
    }
}

#[no_mangle]
pub fn src_urem_if(x: u32, y: u32) -> u32 {
    if y.is_power_of_two() {
        unsafe { unchecked_rem(x, y) }
    } else {
        0
 }
}

#[no_mangle]
pub fn tgt_urem_if(x: u32, y: u32) -> u32 {
 if y.is_power_of_two() {
        x & (y - 1)
    } else {
 0
    }
}

#[no_mangle]
pub fn src_urem_assume(x: u32, y: u32) -> u32 {
    unsafe {
        assume(y.is_power_of_two());
 unchecked_rem(x, y)
    }
}

#[no_mangle]
pub fn tgt_urem_assume(x: u32, y: u32) -> u32 {
    unsafe {
 assume(y.is_power_of_two());
        x & (y - 1)
    }
}
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to