Skip to content

Commit 84e435a

Browse files
Noratriebsaethlin
andcommitted
Add #[rustc_no_mir_inline] for standard library UB checks
Co-authored-by: Ben Kimock <[email protected]>
1 parent 6837b82 commit 84e435a

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

core/src/intrinsics.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,13 +2706,25 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize)
27062706
macro_rules! assert_unsafe_precondition {
27072707
($message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => {
27082708
{
2709+
// #[cfg(bootstrap)] (this comment)
27092710
// When the standard library is compiled with debug assertions, we want the check to inline for better performance.
27102711
// This is important when working on the compiler, which is compiled with debug assertions locally.
27112712
// When not compiled with debug assertions (so the precompiled std) we outline the check to minimize the compile
27122713
// time impact when debug assertions are disabled.
2713-
// It is not clear whether that is the best solution, see #120848.
2714-
#[cfg_attr(debug_assertions, inline(always))]
2715-
#[cfg_attr(not(debug_assertions), inline(never))]
2714+
// The proper solution to this is the `#[rustc_no_mir_inline]` below, but we still want decent performance for cfg(bootstrap).
2715+
#[cfg_attr(all(debug_assertions, bootstrap), inline(always))]
2716+
#[cfg_attr(all(not(debug_assertions), bootstrap), inline(never))]
2717+
2718+
// This check is inlineable, but not by the MIR inliner.
2719+
// The reason for this is that the MIR inliner is in an exceptionally bad position
2720+
// to think about whether or not to inline this. In MIR, this call is gated behind `debug_assertions`,
2721+
// which will codegen to `false` in release builds. Inlining the check would be wasted work in that case and
2722+
// would be bad for compile times.
2723+
//
2724+
// LLVM on the other hand sees the constant branch, so if it's `false`, it can immediately delete it without
2725+
// inlining the check. If it's `true`, it can inline it and get significantly better performance.
2726+
#[cfg_attr(not(bootstrap), rustc_no_mir_inline)]
2727+
#[cfg_attr(not(bootstrap), inline)]
27162728
#[rustc_nounwind]
27172729
fn precondition_check($($name:$ty),*) {
27182730
if !$e {

0 commit comments

Comments
 (0)