about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/intrinsics/mod.rs39
-rw-r--r--src/tools/miri/tests/pass/prefetch.rs23
2 files changed, 54 insertions, 8 deletions
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index dd838d494bc..346c7825b74 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -261,7 +261,7 @@ pub unsafe fn atomic_fence<const ORD: AtomicOrdering>();
 pub unsafe fn atomic_singlethreadfence<const ORD: AtomicOrdering>();
 
 /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-/// if supported; otherwise, it is a no-op.
+/// for the given address if supported; otherwise, it is a no-op.
 /// Prefetches have no effect on the behavior of the program but can change its performance
 /// characteristics.
 ///
@@ -271,9 +271,15 @@ pub unsafe fn atomic_singlethreadfence<const ORD: AtomicOrdering>();
 /// This intrinsic does not have a stable counterpart.
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn prefetch_read_data<T>(data: *const T, locality: i32);
+#[miri::intrinsic_fallback_is_spec]
+pub unsafe fn prefetch_read_data<T>(data: *const T, locality: i32) {
+    // This operation is a no-op, unless it is overridden by the backend.
+    let _ = data;
+    let _ = locality;
+}
+
 /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-/// if supported; otherwise, it is a no-op.
+/// for the given address if supported; otherwise, it is a no-op.
 /// Prefetches have no effect on the behavior of the program but can change its performance
 /// characteristics.
 ///
@@ -283,9 +289,15 @@ pub unsafe fn prefetch_read_data<T>(data: *const T, locality: i32);
 /// This intrinsic does not have a stable counterpart.
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn prefetch_write_data<T>(data: *const T, locality: i32);
+#[miri::intrinsic_fallback_is_spec]
+pub unsafe fn prefetch_write_data<T>(data: *const T, locality: i32) {
+    // This operation is a no-op, unless it is overridden by the backend.
+    let _ = data;
+    let _ = locality;
+}
+
 /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-/// if supported; otherwise, it is a no-op.
+/// for the given address if supported; otherwise, it is a no-op.
 /// Prefetches have no effect on the behavior of the program but can change its performance
 /// characteristics.
 ///
@@ -295,9 +307,15 @@ pub unsafe fn prefetch_write_data<T>(data: *const T, locality: i32);
 /// This intrinsic does not have a stable counterpart.
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn prefetch_read_instruction<T>(data: *const T, locality: i32);
+#[miri::intrinsic_fallback_is_spec]
+pub unsafe fn prefetch_read_instruction<T>(data: *const T, locality: i32) {
+    // This operation is a no-op, unless it is overridden by the backend.
+    let _ = data;
+    let _ = locality;
+}
+
 /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-/// if supported; otherwise, it is a no-op.
+/// for the given address if supported; otherwise, it is a no-op.
 /// Prefetches have no effect on the behavior of the program but can change its performance
 /// characteristics.
 ///
@@ -307,7 +325,12 @@ pub unsafe fn prefetch_read_instruction<T>(data: *const T, locality: i32);
 /// This intrinsic does not have a stable counterpart.
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn prefetch_write_instruction<T>(data: *const T, locality: i32);
+#[miri::intrinsic_fallback_is_spec]
+pub unsafe fn prefetch_write_instruction<T>(data: *const T, locality: i32) {
+    // This operation is a no-op, unless it is overridden by the backend.
+    let _ = data;
+    let _ = locality;
+}
 
 /// Executes a breakpoint trap, for inspection by a debugger.
 ///
diff --git a/src/tools/miri/tests/pass/prefetch.rs b/src/tools/miri/tests/pass/prefetch.rs
new file mode 100644
index 00000000000..09352695989
--- /dev/null
+++ b/src/tools/miri/tests/pass/prefetch.rs
@@ -0,0 +1,23 @@
+#![feature(core_intrinsics)]
+
+fn main() {
+    static X: [u8; 8] = [0; 8];
+
+    unsafe {
+        ::std::intrinsics::prefetch_read_data(::std::ptr::null::<u8>(), 1);
+        ::std::intrinsics::prefetch_read_data(::std::ptr::dangling::<u8>(), 2);
+        ::std::intrinsics::prefetch_read_data(X.as_ptr(), 3);
+
+        ::std::intrinsics::prefetch_write_data(::std::ptr::null::<u8>(), 1);
+        ::std::intrinsics::prefetch_write_data(::std::ptr::dangling::<u8>(), 2);
+        ::std::intrinsics::prefetch_write_data(X.as_ptr(), 3);
+
+        ::std::intrinsics::prefetch_read_instruction(::std::ptr::null::<u8>(), 1);
+        ::std::intrinsics::prefetch_read_instruction(::std::ptr::dangling::<u8>(), 2);
+        ::std::intrinsics::prefetch_read_instruction(X.as_ptr(), 3);
+
+        ::std::intrinsics::prefetch_write_instruction(::std::ptr::null::<u8>(), 1);
+        ::std::intrinsics::prefetch_write_instruction(::std::ptr::dangling::<u8>(), 2);
+        ::std::intrinsics::prefetch_write_instruction(X.as_ptr(), 3);
+    }
+}