Closed
Description
I tried this code: (godbolt)
// DOES NOT optimise to `a & b`
pub fn min_std(a: bool, b: bool) -> bool {
std::cmp::min(a, b)
}
// DOES NOT optimise to `a | b`
pub fn max_std(a: bool, b: bool) -> bool {
std::cmp::max(a, b)
}
// DOES optimise to `a & b`
pub fn min_if(a: bool, b: bool) -> bool {
if (a < b) {
return a;
}
b
}
// DOES optimise to `a | b` on x86_64
// DOES NOT optimise to `a | b` on AArch64
pub fn max_if(a: bool, b: bool) -> bool {
if (a > b) {
return a;
}
b
}
pub fn min_and(a: bool, b: bool) -> bool {
a & b
}
pub fn max_or(a: bool, b: bool) -> bool {
a | b
}
I expected to see this happen:
All implementations of max should optimise to a & b
. All implementations of min should optimise to a | b
Instead, this happened:
The generated assembly code is suboptimal for min_std
, max_std
, max_ternary
and max_if
(on AArch64)
min_std
and max_std
can be fixed by overriding the default implementation of min
and max
for bool
:
impl Ord for bool {
fn min(self, other: Self) -> Self { a & b }
fn max(self, other: Self) -> Self { a | b }
}
But it might be worth investigating the LLVM-IR that rustc generates in min_if
/max_if
too to see why it isn't optimised to llvm.umin()
/llvm.umax()
Meta
rustc --version --verbose
:
rustc 1.73.0-nightly (f88a8b71c 2023-08-08)
binary: rustc
commit-hash: f88a8b71cebb730cbd5058c45ebcae1d4d9be377
commit-date: 2023-08-08
host: x86_64-unknown-linux-gnu
release: 1.73.0-nightly
LLVM version: 17.0.0
Backtrace
<backtrace>