-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Closed
Closed
Copy link
Labels
llvm:instcombineCovers the InstCombine, InstSimplify and AggressiveInstCombine passesCovers the InstCombine, InstSimplify and AggressiveInstCombine passesmissed-optimization
Description
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
#![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)
}
}
Metadata
Metadata
Assignees
Labels
llvm:instcombineCovers the InstCombine, InstSimplify and AggressiveInstCombine passesCovers the InstCombine, InstSimplify and AggressiveInstCombine passesmissed-optimization