Description
For reasons outside my control, I would like to have the option to perform unchecked, wrapping arithmetic in debug mode with reasonable performance. Since + is checking for overflows, I thought that using wrapping_add would do the job, however a function like:
pub fn inc_opt(data: u64) -> u64 {
u64::wrapping_add(data, 42)
}
gets compiled (in debug mode) to
0000000000005d50 <inc::inc_opt>:
5d50: push %rax
5d51: mov $0x2a,%esi
5d56: callq 5650 <core::num::<impl u64>::wrapping_add>
5d5b: mov %rax,(%rsp)
5d5f: mov (%rsp),%rax
5d63: pop %rcx
5d64: retq
5d65: nopw %cs:0x0(%rax,%rax,1)
5d6f: nop
The call to wrapping_add
does not get inlined, even though wrapping_add
is marked #[inline]
and is obviously short. I tried to the following patch:
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index a259e293b0c..6c2d3fc6d5a 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1242,7 +1242,7 @@ $EndFeature, "
#[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
- #[inline]
+ #[inline(always)]
pub const fn wrapping_add(self, rhs: Self) -> Self {
intrinsics::wrapping_add(self, rhs)
}
However that did not seem to change the generated code (I'm new to hacking on rustc, so it's very possible I did not try it correctly).
Is there any hope in stable rust to be able to compile wrapping arithmetic expressions to a single instruction even in debug mode?
Is there a more general issue with inlining not being performed when it should?