Skip to content

Commit 8c27ba6

Browse files
authored
Rollup merge of rust-lang#145626 - folkertdev:prefetch-fallback, r=Amanieu
add a fallback implementation for the `prefetch_*` intrinsics related ACP: rust-lang/libs-team#638 The fallback is to just ignore the arguments. That is a valid implementation because this intrinsic is just a hint. I also added the `miri::intrinsic_fallback_is_spec` annotation, so that miri now supports these operations. A prefetch intrinsic call is valid on any pointer. (specifically LLVM guarantees this https://llvm.org/docs/LangRef.html#llvm-prefetch-intrinsic) Next, I made the `LOCALITY` argument a const generic. That argument must be const (otherwise LLVM crashes), but that was not reflected in the type. Finally, with these changes, the intrinsic can be safe and `const` (a prefetch at const evaluation time is just a no-op). cc `@Amanieu` r? `@RalfJung`
2 parents daec924 + 0a6b3f6 commit 8c27ba6

File tree

1 file changed

+35
-16
lines changed

1 file changed

+35
-16
lines changed

core/src/intrinsics/mod.rs

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -261,53 +261,72 @@ 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
///
268-
/// The `locality` argument must be a constant integer and is a temporal locality specifier
269-
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
268+
/// The `LOCALITY` argument is a temporal locality specifier ranging from (0) - no locality,
269+
/// to (3) - extremely local keep in cache.
270270
///
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 const fn prefetch_read_data<T, const LOCALITY: i32>(data: *const T) {
276+
// This operation is a no-op, unless it is overridden by the backend.
277+
let _ = data;
278+
}
279+
275280
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
276-
/// if supported; otherwise, it is a no-op.
281+
/// for the given address if supported; otherwise, it is a no-op.
277282
/// Prefetches have no effect on the behavior of the program but can change its performance
278283
/// characteristics.
279284
///
280-
/// The `locality` argument must be a constant integer and is a temporal locality specifier
281-
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
285+
/// The `LOCALITY` argument is a temporal locality specifier ranging from (0) - no locality,
286+
/// to (3) - extremely local keep in cache.
282287
///
283288
/// This intrinsic does not have a stable counterpart.
284289
#[rustc_intrinsic]
285290
#[rustc_nounwind]
286-
pub unsafe fn prefetch_write_data<T>(data: *const T, locality: i32);
291+
#[miri::intrinsic_fallback_is_spec]
292+
pub const fn prefetch_write_data<T, const LOCALITY: i32>(data: *const T) {
293+
// This operation is a no-op, unless it is overridden by the backend.
294+
let _ = data;
295+
}
296+
287297
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
288-
/// if supported; otherwise, it is a no-op.
298+
/// for the given address if supported; otherwise, it is a no-op.
289299
/// Prefetches have no effect on the behavior of the program but can change its performance
290300
/// characteristics.
291301
///
292-
/// The `locality` argument must be a constant integer and is a temporal locality specifier
293-
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
302+
/// The `LOCALITY` argument is a temporal locality specifier ranging from (0) - no locality,
303+
/// to (3) - extremely local keep in cache.
294304
///
295305
/// This intrinsic does not have a stable counterpart.
296306
#[rustc_intrinsic]
297307
#[rustc_nounwind]
298-
pub unsafe fn prefetch_read_instruction<T>(data: *const T, locality: i32);
308+
#[miri::intrinsic_fallback_is_spec]
309+
pub const fn prefetch_read_instruction<T, const LOCALITY: i32>(data: *const T) {
310+
// This operation is a no-op, unless it is overridden by the backend.
311+
let _ = data;
312+
}
313+
299314
/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
300-
/// if supported; otherwise, it is a no-op.
315+
/// for the given address if supported; otherwise, it is a no-op.
301316
/// Prefetches have no effect on the behavior of the program but can change its performance
302317
/// characteristics.
303318
///
304-
/// The `locality` argument must be a constant integer and is a temporal locality specifier
305-
/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
319+
/// The `LOCALITY` argument is a temporal locality specifier ranging from (0) - no locality,
320+
/// to (3) - extremely local keep in cache.
306321
///
307322
/// This intrinsic does not have a stable counterpart.
308323
#[rustc_intrinsic]
309324
#[rustc_nounwind]
310-
pub unsafe fn prefetch_write_instruction<T>(data: *const T, locality: i32);
325+
#[miri::intrinsic_fallback_is_spec]
326+
pub const fn prefetch_write_instruction<T, const LOCALITY: i32>(data: *const T) {
327+
// This operation is a no-op, unless it is overridden by the backend.
328+
let _ = data;
329+
}
311330

312331
/// Executes a breakpoint trap, for inspection by a debugger.
313332
///

0 commit comments

Comments
 (0)