Skip to content

Commit e24cfe8

Browse files
authored
cmov: use black_box in portable impl (#1255)
The core predication function of the portable implementation is called `is_non_zero` and it returns a 1-bit mask value which is subsequently used to "select" between two values using bitwise masking. In some previous real-world cases in the Rust compiler, it has been able to deduce, when using this sort of pattern in a loop, that the entire loop can be skipped when e.g. the condition is zero. [RUSTSEC-2024-0344](https://rustsec.org/advisories/RUSTSEC-2024-0344.html) is one such example. Adding a `black_box` in this position should hopefully help hint to the compiler that we do not want such an "optimization" performed. Note that the only thing we're actually relying on from `black_box` for program correctness is that it behaves as an identity function, so this will not have deleterious effects. Whether it actually helps avoid problems like RUSTSEC-2024-0344 is something that can only be seen in practice, unfortunately, as we don't have any way to get actual guarantees out of the Rust compiler in cases where we can't use `asm!`.
1 parent 3f2d622 commit e24cfe8

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

cmov/src/portable.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// TODO(tarcieri): more optimized implementation for small integers
88

99
use crate::{Cmov, CmovEq, Condition};
10-
use core::mem::size_of;
10+
use core::{hint::black_box, mem::size_of};
1111

1212
impl Cmov for u16 {
1313
#[inline]
@@ -100,5 +100,5 @@ impl CmovEq for u64 {
100100
fn is_non_zero(condition: Condition) -> u64 {
101101
const SHIFT_BITS: usize = size_of::<u64>() - 1;
102102
let condition = condition as u64;
103-
((condition | (!condition).wrapping_add(1)) >> SHIFT_BITS) & 1
103+
black_box(((condition | (!condition).wrapping_add(1)) >> SHIFT_BITS) & 1)
104104
}

0 commit comments

Comments
 (0)