Skip to content

Commit

Permalink
Auto merge of rust-lang#128250 - Amanieu:select_unpredictable, r=nikic
Browse files Browse the repository at this point in the history
Add `select_unpredictable` to force LLVM to use CMOV

Since https://reviews.llvm.org/D118118, LLVM will no longer turn CMOVs into branches if it comes from a `select` marked with an `unpredictable` metadata attribute.

This PR introduces `core::intrinsics::select_unpredictable` which emits such a `select` and uses it in the implementation of `binary_search_by`.
  • Loading branch information
bors committed Jul 30, 2024
2 parents f70ce7f + 5119266 commit a50fe57
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,34 @@ pub const fn unlikely(b: bool) -> bool {
b
}

/// Returns either `true_val` or `false_val` depending on condition `b` with a
/// hint to the compiler that this condition is unlikely to be correctly
/// predicted by a CPU's branch predictor (e.g. a binary search).
///
/// This is otherwise functionally equivalent to `if b { true_val } else { false_val }`.
///
/// Note that, unlike most intrinsics, this is safe to call;
/// it does not require an `unsafe` block.
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
///
/// This intrinsic does not have a stable counterpart.
#[cfg(not(bootstrap))]
#[unstable(feature = "core_intrinsics", issue = "none")]
#[rustc_intrinsic]
#[rustc_nounwind]
#[miri::intrinsic_fallback_is_spec]
#[inline]
pub fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
if b { true_val } else { false_val }
}

#[cfg(bootstrap)]
#[inline]
pub fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
if b { true_val } else { false_val }
}

extern "rust-intrinsic" {
/// Executes a breakpoint trap, for inspection by a debugger.
///
Expand Down

0 comments on commit a50fe57

Please sign in to comment.