Skip to content

Commit 51df7aa

Browse files
committed
add a fallback implementation for the prefetch_* intrinsics
The fallback is to just ignore the arguments. That is a valid implementation because this intrinsic is just a hint. I also added `miri::intrinsic_fallback_is_spec` annotation, so that miri now supports these operations. A prefetch intrinsic call is valid on any pointer.
1 parent 16ad385 commit 51df7aa

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

library/core/src/intrinsics/mod.rs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ pub unsafe fn atomic_fence<const ORD: AtomicOrdering>();
261261
pub unsafe fn atomic_singlethreadfence<const ORD: AtomicOrdering>();
262262

263263
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
264-
/// if supported; otherwise, it is a no-op.
264+
/// for the given address if supported; otherwise, it is a no-op.
265265
/// Prefetches have no effect on the behavior of the program but can change its performance
266266
/// characteristics.
267267
///
@@ -271,9 +271,15 @@ pub unsafe fn atomic_singlethreadfence<const ORD: AtomicOrdering>();
271271
/// This intrinsic does not have a stable counterpart.
272272
#[rustc_intrinsic]
273273
#[rustc_nounwind]
274-
pub unsafe fn prefetch_read_data<T>(data: *const T, locality: i32);
274+
#[miri::intrinsic_fallback_is_spec]
275+
pub unsafe fn prefetch_read_data<T>(data: *const T, locality: i32) {
276+
// This operation is a no-op, unless it is overridden by the backend.
277+
let _ = data;
278+
let _ = locality;
279+
}
280+
275281
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
276-
/// if supported; otherwise, it is a no-op.
282+
/// for the given address if supported; otherwise, it is a no-op.
277283
/// Prefetches have no effect on the behavior of the program but can change its performance
278284
/// characteristics.
279285
///
@@ -283,9 +289,15 @@ pub unsafe fn prefetch_read_data<T>(data: *const T, locality: i32);
283289
/// This intrinsic does not have a stable counterpart.
284290
#[rustc_intrinsic]
285291
#[rustc_nounwind]
286-
pub unsafe fn prefetch_write_data<T>(data: *const T, locality: i32);
292+
#[miri::intrinsic_fallback_is_spec]
293+
pub unsafe fn prefetch_write_data<T>(data: *const T, locality: i32) {
294+
// This operation is a no-op, unless it is overridden by the backend.
295+
let _ = data;
296+
let _ = locality;
297+
}
298+
287299
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
288-
/// if supported; otherwise, it is a no-op.
300+
/// for the given address if supported; otherwise, it is a no-op.
289301
/// Prefetches have no effect on the behavior of the program but can change its performance
290302
/// characteristics.
291303
///
@@ -295,9 +307,15 @@ pub unsafe fn prefetch_write_data<T>(data: *const T, locality: i32);
295307
/// This intrinsic does not have a stable counterpart.
296308
#[rustc_intrinsic]
297309
#[rustc_nounwind]
298-
pub unsafe fn prefetch_read_instruction<T>(data: *const T, locality: i32);
310+
#[miri::intrinsic_fallback_is_spec]
311+
pub unsafe fn prefetch_read_instruction<T>(data: *const T, locality: i32) {
312+
// This operation is a no-op, unless it is overridden by the backend.
313+
let _ = data;
314+
let _ = locality;
315+
}
316+
299317
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
300-
/// if supported; otherwise, it is a no-op.
318+
/// for the given address if supported; otherwise, it is a no-op.
301319
/// Prefetches have no effect on the behavior of the program but can change its performance
302320
/// characteristics.
303321
///
@@ -307,7 +325,12 @@ pub unsafe fn prefetch_read_instruction<T>(data: *const T, locality: i32);
307325
/// This intrinsic does not have a stable counterpart.
308326
#[rustc_intrinsic]
309327
#[rustc_nounwind]
310-
pub unsafe fn prefetch_write_instruction<T>(data: *const T, locality: i32);
328+
#[miri::intrinsic_fallback_is_spec]
329+
pub unsafe fn prefetch_write_instruction<T>(data: *const T, locality: i32) {
330+
// This operation is a no-op, unless it is overridden by the backend.
331+
let _ = data;
332+
let _ = locality;
333+
}
311334

312335
/// Executes a breakpoint trap, for inspection by a debugger.
313336
///

src/tools/miri/tests/pass/prefetch.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#![feature(core_intrinsics)]
2+
3+
fn main() {
4+
static X: [u8; 8] = [0; 8];
5+
6+
unsafe {
7+
::std::intrinsics::prefetch_read_data(::std::ptr::null::<u8>(), 1);
8+
::std::intrinsics::prefetch_read_data(::std::ptr::dangling::<u8>(), 2);
9+
::std::intrinsics::prefetch_read_data(X.as_ptr(), 3);
10+
11+
::std::intrinsics::prefetch_write_data(::std::ptr::null::<u8>(), 1);
12+
::std::intrinsics::prefetch_write_data(::std::ptr::dangling::<u8>(), 2);
13+
::std::intrinsics::prefetch_write_data(X.as_ptr(), 3);
14+
15+
::std::intrinsics::prefetch_read_instruction(::std::ptr::null::<u8>(), 1);
16+
::std::intrinsics::prefetch_read_instruction(::std::ptr::dangling::<u8>(), 2);
17+
::std::intrinsics::prefetch_read_instruction(X.as_ptr(), 3);
18+
19+
::std::intrinsics::prefetch_write_instruction(::std::ptr::null::<u8>(), 1);
20+
::std::intrinsics::prefetch_write_instruction(::std::ptr::dangling::<u8>(), 2);
21+
::std::intrinsics::prefetch_write_instruction(X.as_ptr(), 3);
22+
}
23+
}

0 commit comments

Comments
 (0)