Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/core_arch/missing-x86.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@

<details><summary>["CLFLUSHOPT"]</summary><p>

* [ ] [`_mm_clflushopt`](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_clflushopt)
* [x] [`_mm_clflushopt`](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_clflushopt)
</p></details>


Expand Down
45 changes: 45 additions & 0 deletions crates/core_arch/src/x86/clflushopt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! `CLFLUSHOPT` cache-line flush.

#[cfg(test)]
use stdarch_test::assert_instr;

#[allow(improper_ctypes)]
unsafe extern "C" {
#[link_name = "llvm.x86.clflushopt"]
fn clflushopt(p: *mut i8);
}

/// Invalidates from every level of the cache hierarchy the cache line that
/// contains `p`.
///
/// Unlike [`_mm_clflush`], `CLFLUSHOPT` is only ordered with respect to older
/// writes to the flushed cache line and with respect to fence/locked
/// operations; it is *not* serialized against other `CLFLUSHOPT`/`CLFLUSH`
/// instructions or unrelated stores. This makes flushing a range of lines
/// substantially faster, but a fence (e.g. [`_mm_sfence`] or [`_mm_mfence`]) is
/// required afterward to order the flushes against subsequent operations.
///
/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_clflushopt)
Copy link
Copy Markdown
Contributor

@folkertdev folkertdev May 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a # Safety section here where you document that (unlike other prefetch functions) this function needs a valid pointer? Or at least that is what I think

subject to all permission checking and faults associated with a byte load

means?

cc @Amanieu @sayantn if I'm misinterpreting that.

View changes since the review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency you can add the same section to the _mm_clflush doc comment.

///
/// [`_mm_clflush`]: crate::arch::x86_64::_mm_clflush
/// [`_mm_sfence`]: crate::arch::x86_64::_mm_sfence
/// [`_mm_mfence`]: crate::arch::x86_64::_mm_mfence
#[inline]
#[target_feature(enable = "clflushopt")]
#[cfg_attr(test, assert_instr(clflushopt))]
#[unstable(feature = "simd_x86_clflushopt", issue = "157096")]
pub unsafe fn _mm_clflushopt(p: *const u8) {
clflushopt(p as *mut i8);
}

#[cfg(test)]
mod tests {
use crate::core_arch::x86::*;
use stdarch_test::simd_test;

#[simd_test(enable = "clflushopt")]
unsafe fn test_mm_clflushopt() {
let x = 0_u8;
_mm_clflushopt(core::ptr::addr_of!(x));
}
}
4 changes: 4 additions & 0 deletions crates/core_arch/src/x86/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,10 @@ mod adx;
#[stable(feature = "simd_x86_adx", since = "1.33.0")]
pub use self::adx::*;

mod clflushopt;
#[unstable(feature = "simd_x86_clflushopt", issue = "157096")]
pub use self::clflushopt::*;

#[cfg(test)]
use stdarch_test::assert_instr;

Expand Down
2 changes: 1 addition & 1 deletion crates/stdarch-verify/tests/x86-intel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ fn pointed_type(intrinsic: &Intrinsic) -> Result<Type, String> {
{
// AMX, KEYLOCKER and XSAVE intrinsics should take `*u8`
U8
} else if intrinsic.name == "_mm_clflush" {
} else if intrinsic.name == "_mm_clflush" || intrinsic.name == "_mm_clflushopt" {
// Just a false match in the following logic
U8
} else if ["_mm_storeu_si", "_mm_loadu_si"]
Expand Down
Loading