rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.08k stars 12.54k forks source link

Suboptimal Assembly Output from a Modulo on a Power of Two #129795

Open Altanis opened 3 weeks ago

Altanis commented 3 weeks ago

I tried this code:

#[no_mangle]
pub fn index(key: usize, buckets: usize) -> usize {
    assert!(buckets.is_power_of_two());
    key % buckets
}

Since assert!(buckets.is_power_of_two()) is run (and .is_power_of_two() is an inbuilt function), the latter modulus operation should reduce to key & (buckets - 1).

Instead, the outputted assembly here shows that this reduction does not take place.

Meta

The compiler in the GodBolt link is version 1.80.0.

scottmcm commented 2 weeks ago

This is https://github.com/llvm/llvm-project/issues/58996, and needs to be fixed in LLVM. Rust itself won't do this optimization.

dtcxzyw commented 2 weeks ago

@scottmcm @DianQK @nikic This issue has been fixed by https://github.com/llvm/llvm-project/pull/107745. Please add llvm-fixed-upstream.

DianQK commented 2 weeks ago

You can also add it. :) @rustbot label +llvm-fixed-upstream

nikic commented 2 weeks ago

@dtcxzyw Doesn't this issue need support for dominating condition rather than assumption?

dtcxzyw commented 2 weeks ago

@dtcxzyw Doesn't this issue need support for dominating condition rather than assumption?

I am preparing a follow-up patch for this :)

DianQK commented 2 weeks ago

@rustbot label -llvm-fixed-upstream