-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Totally-not-a-tracking-issue for UB-detecting debug assertions in the standard library #120848
Comments
There is the rust-cold calling convention. That probably shouldn't be inlined by the mir inliner since we want to tell LLVM that's coldcc. |
The LLVM LangRef documents this about coldcc:
So I don't think that does the post-mono-only inlining that I described. |
Use intrinsics::debug_assertions in debug_assert_nounwind This is the first item in rust-lang#120848. Based on the benchmarking in this PR, it looks like, for the programs in our benchmark suite, enabling all these additional checks does not introduce significant compile-time overhead, with the single exception of `Alignment::new_unchecked`. Therefore, I've added `#[cfg(debug_assertions)]` to that one call site, so that it remains compiled out in the distributed standard library. The trailing commas in the previous calls to `debug_assert_nounwind!` were causing the macro to expand to `panic_nouwnind_fmt`, which requires more work to set up its arguments, and that overhead alone is measured between this perf run and the next: rust-lang#120863 (comment)
Add `#[rustc_no_mir_inline]` for standard library UB checks should help with rust-lang#121110 and also with rust-lang#120848 I am not entirely sure whether this is the correct solution and I haven't validated it, I just quickly threw it together before going to sleep. r? `@saethlin`
Use intrinsics::debug_assertions in debug_assert_nounwind This is the first item in rust-lang#120848. Based on the benchmarking in this PR, it looks like, for the programs in our benchmark suite, enabling all these additional checks does not introduce significant compile-time overhead, with the single exception of `Alignment::new_unchecked`. Therefore, I've added `#[cfg(debug_assertions)]` to that one call site, so that it remains compiled out in the distributed standard library. The trailing commas in the previous calls to `debug_assert_nounwind!` were causing the macro to expand to `panic_nouwnind_fmt`, which requires more work to set up its arguments, and that overhead alone is measured between this perf run and the next: rust-lang#120863 (comment)
Use intrinsics::debug_assertions in debug_assert_nounwind This is the first item in rust-lang#120848. Based on the benchmarking in this PR, it looks like, for the programs in our benchmark suite, enabling all these additional checks does not introduce significant compile-time overhead, with the single exception of `Alignment::new_unchecked`. Therefore, I've added `#[cfg(debug_assertions)]` to that one call site, so that it remains compiled out in the distributed standard library. The trailing commas in the previous calls to `debug_assert_nounwind!` were causing the macro to expand to `panic_nouwnind_fmt`, which requires more work to set up its arguments, and that overhead alone is measured between this perf run and the next: rust-lang#120863 (comment)
Use intrinsics::debug_assertions in debug_assert_nounwind This is the first item in rust-lang#120848. Based on the benchmarking in this PR, it looks like, for the programs in our benchmark suite, enabling all these additional checks does not introduce significant compile-time overhead, with the single exception of `Alignment::new_unchecked`. Therefore, I've added `#[cfg(debug_assertions)]` to that one call site, so that it remains compiled out in the distributed standard library. The trailing commas in the previous calls to `debug_assert_nounwind!` were causing the macro to expand to `panic_nouwnind_fmt`, which requires more work to set up its arguments, and that overhead alone is measured between this perf run and the next: rust-lang#120863 (comment)
Use intrinsics::debug_assertions in debug_assert_nounwind This is the first item in rust-lang#120848. Based on the benchmarking in this PR, it looks like, for the programs in our benchmark suite, enabling all these additional checks does not introduce significant compile-time overhead, with the single exception of `Alignment::new_unchecked`. Therefore, I've added `#[cfg(debug_assertions)]` to that one call site, so that it remains compiled out in the distributed standard library. The trailing commas in the previous calls to `debug_assert_nounwind!` were causing the macro to expand to `panic_nouwnind_fmt`, which requires more work to set up its arguments, and that overhead alone is measured between this perf run and the next: rust-lang#120863 (comment)
…thlin Make `is_nonoverlapping` `#[inline]` It showed up with 3% execution time in a compiler profile. backlink to rust-lang#120848 r? `@saethlin`
…thlin Make `is_nonoverlapping` `#[inline]` It showed up with 3% execution time in a compiler profile. backlink to rust-lang#120848 r? ``@saethlin``
Rollup merge of rust-lang#121311 - Nilstrieb:is-it-overlapping, r=saethlin Make `is_nonoverlapping` `#[inline]` It showed up with 3% execution time in a compiler profile. backlink to rust-lang#120848 r? ``@saethlin``
Use intrinsics::debug_assertions in debug_assert_nounwind This is the first item in rust-lang#120848. Based on the benchmarking in this PR, it looks like, for the programs in our benchmark suite, enabling all these additional checks does not introduce significant compile-time overhead, with the single exception of `Alignment::new_unchecked`. Therefore, I've added `#[cfg(debug_assertions)]` to that one call site, so that it remains compiled out in the distributed standard library. The trailing commas in the previous calls to `debug_assert_nounwind!` were causing the macro to expand to `panic_nouwnind_fmt`, which requires more work to set up its arguments, and that overhead alone is measured between this perf run and the next: rust-lang#120863 (comment)
Avoid lowering code under dead SwitchInt targets r? `@ghost` Reviving rust-lang#91222 per rust-lang#120848
Avoid lowering code under dead SwitchInt targets r? `@ghost` Reviving rust-lang#91222 per rust-lang#120848
Avoid lowering code under dead SwitchInt targets r? `@ghost` Reviving rust-lang#91222 per rust-lang#120848
Add `#[rustc_no_mir_inline]` for standard library UB checks should help with rust-lang#121110 and also with rust-lang#120848 I am not entirely sure whether this is the correct solution and I haven't validated it, I just quickly threw it together before going to sleep. r? `@saethlin`
Avoid lowering code under dead SwitchInt targets r? `@ghost` Reviving rust-lang#91222 per rust-lang#120848
Add `#[rustc_no_mir_inline]` for standard library UB checks should help with rust-lang#121110 and also with rust-lang#120848 Because the MIR inliner cannot know whether the checks are enabled or not, so inlining is an unnecessary compile time pessimization when debug assertions are disabled. LLVM knows whether they are enabled or not, so it can optimize accordingly without wasting time. r? `@saethlin`
Avoid lowering code under dead SwitchInt targets The objective of this PR is to detect and eliminate code which is guarded by an `if false`, even if that `false` is a constant which is not known until monomorphization, or is `intrinsics::debug_assertions()`. The effect of this is that we generate no LLVM IR the standard library's unsafe preconditions, when they are compiled in a build where they should be immediately optimized out. This mono-time optimization ensures that builds which disable debug assertions do not grow a linkage requirement against `core`, which compiler-builtins currently needs: rust-lang#121552 This revives the codegen side of rust-lang#91222 as planned in rust-lang#120848.
Avoid lowering code under dead SwitchInt targets The objective of this PR is to detect and eliminate code which is guarded by an `if false`, even if that `false` is a constant which is not known until monomorphization, or is `intrinsics::debug_assertions()`. The effect of this is that we generate no LLVM IR the standard library's unsafe preconditions, when they are compiled in a build where they should be immediately optimized out. This mono-time optimization ensures that builds which disable debug assertions do not grow a linkage requirement against `core`, which compiler-builtins currently needs: rust-lang#121552 This revives the codegen side of rust-lang#91222 as planned in rust-lang#120848.
Use intrinsics::debug_assertions in debug_assert_nounwind This is the first item in rust-lang/rust#120848. Based on the benchmarking in this PR, it looks like, for the programs in our benchmark suite, enabling all these additional checks does not introduce significant compile-time overhead, with the single exception of `Alignment::new_unchecked`. Therefore, I've added `#[cfg(debug_assertions)]` to that one call site, so that it remains compiled out in the distributed standard library. The trailing commas in the previous calls to `debug_assert_nounwind!` were causing the macro to expand to `panic_nouwnind_fmt`, which requires more work to set up its arguments, and that overhead alone is measured between this perf run and the next: rust-lang/rust#120863 (comment)
Avoid more NonNull-raw-NonNull roundtrips in Vec r? the8472 The standard library in general has a lot of these round-trips from niched types to their raw innards and back. Such round-trips have overhead in debug builds since rust-lang#120594. I removed some such round-trips in that initial PR and I've been meaning to come back and hunt down more such examples (this is the last item on rust-lang#120848).
Avoid more NonNull-raw-NonNull roundtrips in Vec r? the8472 The standard library in general has a lot of these round-trips from niched types to their raw innards and back. Such round-trips have overhead in debug builds since rust-lang#120594. I removed some such round-trips in that initial PR and I've been meaning to come back and hunt down more such examples (this is the last item on rust-lang#120848).
Rollup merge of rust-lang#123835 - saethlin:vec-from-nonnull, r=the8472 Avoid more NonNull-raw-NonNull roundtrips in Vec r? the8472 The standard library in general has a lot of these round-trips from niched types to their raw innards and back. Such round-trips have overhead in debug builds since rust-lang#120594. I removed some such round-trips in that initial PR and I've been meaning to come back and hunt down more such examples (this is the last item on rust-lang#120848).
Use intrinsics::debug_assertions in debug_assert_nounwind This is the first item in rust-lang/rust#120848. Based on the benchmarking in this PR, it looks like, for the programs in our benchmark suite, enabling all these additional checks does not introduce significant compile-time overhead, with the single exception of `Alignment::new_unchecked`. Therefore, I've added `#[cfg(debug_assertions)]` to that one call site, so that it remains compiled out in the distributed standard library. The trailing commas in the previous calls to `debug_assert_nounwind!` were causing the macro to expand to `panic_nouwnind_fmt`, which requires more work to set up its arguments, and that overhead alone is measured between this perf run and the next: rust-lang/rust#120863 (comment)
What's this?
For a long time, we've been trickling support into the standard library for detecting at runtime calls to unsafe functions that violate their documented preconditions. These checks have become way more interesting with #120594 because they can now trip in default
cargo run/test
. Some nice people recently prompted me to list what improvements I want to make on top of that PR, so I'm going to track them here.If you're interested in working on this topic, this issue can be a hub for coordinating that effort. I am not offering mentoring per se but I'd be happy to discuss work on this topic.
Things to do next
debug_assert_nounwind
to use the new intrinsic. Use intrinsics::debug_assertions in debug_assert_nounwind #120863get_unchecked
should useintrinsics::unreachable
instead ofhint::unreachable_unchecked
and comment why.--emit=llvm-ir
and searching the IR for the check calls.debug_assert_nounwind
andassert_unsafe_precondition
, while ensuring that Library UB checks are checked in Miri/const-eval as described in this comment: rename debug_assert_nounwind → debug_assert_ubcheck #121583 (comment) PR is up at Distinguish between library and lang UB in assert_unsafe_precondition #121662const
. This might produce less MIR (and thus improve compile times) but the implementation complexity inside the compiler might not be worth it. (This idea has been obviated by lowering the intrinsic function to aMir::NullOp
, which has very nearly the same effect)#[inline(never)]
to prevent monomorphizing them many times, but that attribute also means LLVM cannot see what is being checked and optimize on it. Try changing the monomorphic check function from#[inline(never)]
to some new attribute that makes them inlinable by LLVM, but not by the MIR inliner. Perhaps we call this#[inline(only_post_mono)]
? Add#[rustc_no_mir_inline]
for standard library UB checks #121114SimplifyCfg
but aren't. Usebr
instead of a conditional when switching on a constant boolean #120650 targets this pattern, but we should try to revive the strategy in [EXPERIMENT] Don't monomorphize things that are unused due toif <T as Trait>::CONST
#91222 as well: Avoid lowering code under dead SwitchInt targets #121421NonNull::new_unchecked
, I'm sure there are others.Implementation history
debug_assert_nounwind
and convertassert_unsafe_precondition
#110303assert_unsafe_precondition
with cfg(debug_assertions) #121196is_nonoverlapping
#[inline]
#121311#[rustc_no_mir_inline]
for standard library UB checks #121114UbChecks
for non-standard libraries #122975The text was updated successfully, but these errors were encountered: