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:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user