Implement black_box using intrinsic

The new implementation allows some `memcpy`s to be optimized away,
so the uninit value in ui/sanitize/memory.rs is constructed directly
onto the return place. Therefore the sanitizer now says that the
value is allocated by `main` rather than `random`.
This commit is contained in:
Gary Guo
2021-08-10 11:50:33 +01:00
parent ae90dcf020
commit 1fb1643129
9 changed files with 52 additions and 15 deletions

View File

@@ -152,23 +152,19 @@ pub fn spin_loop() {
/// backend used. Programs cannot rely on `black_box` for *correctness* in any way.
///
/// [`std::convert::identity`]: crate::convert::identity
#[cfg_attr(not(miri), inline)]
#[cfg_attr(miri, inline(never))]
#[inline]
#[unstable(feature = "bench_black_box", issue = "64102")]
#[cfg_attr(miri, allow(unused_mut))]
#[cfg_attr(not(bootstrap), allow(unused_mut))]
pub fn black_box<T>(mut dummy: T) -> T {
// We need to "use" the argument in some way LLVM can't introspect, and on
// targets that support it we can typically leverage inline assembly to do
// this. LLVM's interpretation of inline assembly is that it's, well, a black
// box. This isn't the greatest implementation since it probably deoptimizes
// more than we want, but it's so far good enough.
#[cfg(not(miri))] // This is just a hint, so it is fine to skip in Miri.
#[cfg(bootstrap)]
// SAFETY: the inline assembly is a no-op.
unsafe {
// FIXME: Cannot use `asm!` because it doesn't support MIPS and other architectures.
llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile");
dummy
}
dummy
#[cfg(not(bootstrap))]
{
crate::intrinsics::black_box(dummy)
}
}