Skip to content

Commit 5ac5b5b

Browse files
committed
Auto merge of rust-lang#87916 - nbdd0121:black_box, r=nagisa
Implement `black_box` using intrinsic Introduce `black_box` intrinsic, as suggested in rust-lang#87590 (comment). This is still codegenned as empty inline assembly for LLVM. For MIR interpretation and cranelift it's treated as identity. cc `@Amanieu` as this is related to inline assembly cc `@bjorn3` for rustc_codegen_cranelift changes cc `@RalfJung` as this affects MIRI r? `@nagisa` I suppose
2 parents 17c156d + 40307dd commit 5ac5b5b

File tree

2 files changed

+14
-12
lines changed

2 files changed

+14
-12
lines changed

core/src/hint.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -152,23 +152,19 @@ pub fn spin_loop() {
152152
/// backend used. Programs cannot rely on `black_box` for *correctness* in any way.
153153
///
154154
/// [`std::convert::identity`]: crate::convert::identity
155-
#[cfg_attr(not(miri), inline)]
156-
#[cfg_attr(miri, inline(never))]
155+
#[inline]
157156
#[unstable(feature = "bench_black_box", issue = "64102")]
158-
#[cfg_attr(miri, allow(unused_mut))]
157+
#[cfg_attr(not(bootstrap), allow(unused_mut))]
159158
pub fn black_box<T>(mut dummy: T) -> T {
160-
// We need to "use" the argument in some way LLVM can't introspect, and on
161-
// targets that support it we can typically leverage inline assembly to do
162-
// this. LLVM's interpretation of inline assembly is that it's, well, a black
163-
// box. This isn't the greatest implementation since it probably deoptimizes
164-
// more than we want, but it's so far good enough.
165-
166-
#[cfg(not(miri))] // This is just a hint, so it is fine to skip in Miri.
159+
#[cfg(bootstrap)]
167160
// SAFETY: the inline assembly is a no-op.
168161
unsafe {
169-
// FIXME: Cannot use `asm!` because it doesn't support MIPS and other architectures.
170162
llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
163+
dummy
171164
}
172165

173-
dummy
166+
#[cfg(not(bootstrap))]
167+
{
168+
crate::intrinsics::black_box(dummy)
169+
}
174170
}

core/src/intrinsics.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,6 +1933,12 @@ extern "rust-intrinsic" {
19331933
/// which is UB if any of their inputs are `undef`.)
19341934
#[rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none")]
19351935
pub fn raw_eq<T>(a: &T, b: &T) -> bool;
1936+
1937+
/// See documentation of [`std::hint::black_box`] for details.
1938+
///
1939+
/// [`std::hint::black_box`]: crate::hint::black_box
1940+
#[cfg(not(bootstrap))]
1941+
pub fn black_box<T>(dummy: T) -> T;
19361942
}
19371943

19381944
// Some functions are defined here because they accidentally got made

0 commit comments

Comments
 (0)