-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Use probe-stack=inline-asm in LLVM 11+ #77885
Conversation
Thanks! This may have perf implications, so I'm excluding it from rollups. @bors r+ rollup=never |
📌 Commit 95269c2d2ee2d59305d0599f0b389f4583cdb5ea has been approved by |
⌛ Testing commit 95269c2d2ee2d59305d0599f0b389f4583cdb5ea with merge 1272a1aeb3d394ebcf93f59298e04cd63d45e050... |
💔 Test failed - checks-actions |
The specific failures start here. I'm not sure why this change would cause new stack overflows, but it needs investigation.
|
Looks like a comparison is inverted. This is a code snippet from add ebx, 15
and ebx, -16
mov eax, esp
sub eax, ebx
mov dword ptr [ebp - 368], edx
mov dword ptr [ebp - 372], esi
mov dword ptr [ebp - 376], edi
mov dword ptr [ebp - 380], eax
.LBB87_43:
mov eax, dword ptr [ebp - 380]
cmp eax, esp
jl .LBB87_45
mov dword ptr [esp], 0
sub esp, 4096
jmp .LBB87_43
.LBB87_45:
mov eax, dword ptr [ebp - 380]
mov esp, eax Due to: cmp eax, esp
jl .LBB87_45 ...if The same thing shows up in Clang 11 with int size;
void foo(void*);
int main() {
foo(alloca(size));
} I suppose nobody noticed this in C because it's rare to call Assuming I haven't misinterpreted something, can you report this to LLVM? I don't have an account yet. |
@bors r- The PR failed but bors forgot about that during synchronize. |
Hmm, I thought we fixed that |
Yeah, the changes to |
@erikdesjardins / @cuviper https://reviews.llvm.org/D90216 should do the trick. Thanks for spotting this! |
Ah, so there are two parts to this...
This actually was already reported in bug 47657 and fixed in D88548.
This problem remains, but I just confirmed locally that it is fixed by D90216. I stepped through the assembly in gdb just to be sure. 🙂 I think both fixes would be good to have in LLVM 11.0.1. For Rust's part, we can backport the fixes to our bundled LLVM fork, but we should be careful about how this is enabled for external LLVM. I don't think we usually check the patch version for functionality, but maybe this one justifies it -- assuming 11.0.1 does get fixed. |
- Perform the probing in the correct direction. Related to rust-lang/rust#77885 (comment) - The first touch on a dynamic alloca cannot use a mov because it clobbers existing space. Use a xor 0 instead Differential Revision: https://reviews.llvm.org/D90216
- Perform the probing in the correct direction. Related to rust-lang/rust#77885 (comment) - The first touch on a dynamic alloca cannot use a mov because it clobbers existing space. Use a xor 0 instead Differential Revision: https://reviews.llvm.org/D90216
Triage: So it seems this is blocked on a llvm bug. |
- Perform the probing in the correct direction. Related to rust-lang/rust#77885 (comment) - The first touch on a dynamic alloca cannot use a mov because it clobbers existing space. Use a xor 0 instead Differential Revision: https://reviews.llvm.org/D90216 (cherry picked from commit 0f60bcc)
- Perform the probing in the correct direction. Related to rust-lang/rust#77885 (comment) - The first touch on a dynamic alloca cannot use a mov because it clobbers existing space. Use a xor 0 instead Differential Revision: https://reviews.llvm.org/D90216 (cherry picked from commit 0f60bcc)
- Perform the probing in the correct direction. Related to rust-lang/rust#77885 (comment) - The first touch on a dynamic alloca cannot use a mov because it clobbers existing space. Use a xor 0 instead Differential Revision: https://reviews.llvm.org/D90216 (cherry picked from commit 0f60bcc)
@@ -13,11 +13,12 @@ | |||
// ignore-emscripten | |||
// ignore-windows | |||
// compile-flags: -C no-prepopulate-passes | |||
// min-llvm-version: 11.0.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by the way, doesn't adding this mean that we are effectively no longer unit-testing our old stack-probe strategy, since we will just skip this test if the LLVM version is not sufficiently new?
Maybe we should have two files, one for LLVM < 11.0.1 and one for LLVM >= 11.0.1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't generally test very meticulously the setups that use LLVM versions outside of what is in the Rust repository. This is reflected in e.g. tests for all our (oft backported) soundness fixes only being applicable to the newest LLVM versions and our fork.
So far it has been the unwritten policy that it is up to the users who build with alternative LLVM versions to ensure that their builds do what they expect. (This is also another of those things that I should eventually look into codifying in some document outlining our LLVM support strategy)
…7885-for-issue-83139, r=nagisa [stable] probe-stack=call everywhere again, for now. To buy time on issue 83139, revert effect of PR 77885: We will not conditionally enable probe-stack=inline-asm on LLVM 11+ anymore on any of our targets that opted into doing so on PR rust-lang#77885 (and were subsequently configured to do so in a fine grained manner on PR rust-lang#80838). After we resolve 83139 (potentially by backporting a fix to LLVM, or potentially by deciding that one cannot rely on the quality of our DWARF output in the manner described in issue 83139), we can change this back. cc rust-lang#83139
- Perform the probing in the correct direction. Related to rust-lang/rust#77885 (comment) - The first touch on a dynamic alloca cannot use a mov because it clobbers existing space. Use a xor 0 instead Differential Revision: https://reviews.llvm.org/D90216
Pkgsrc changes: * Remove one SunOS patch, apparently no longer needed. * Adapt one patch for Darwin, adjust cargo checksum accordingly. * Adjust bootstraps to version 1.50.0. Version 1.51.0 (2021-03-25) ============================ Language -------- - [You can now parameterize items such as functions, traits, and `struct`s by constant values in addition to by types and lifetimes.][79135] Also known as "const generics" E.g. you can now write the following. Note: Only values of primitive integers, `bool`, or `char` types are currently permitted. ```rust struct GenericArray<T, const LENGTH: usize> { inner: [T; LENGTH] } impl<T, const LENGTH: usize> GenericArray<T, LENGTH> { const fn last(&self) -> Option<&T> { if LENGTH == 0 { None } else { Some(&self.inner[LENGTH - 1]) } } } ``` Compiler -------- - [Added the `-Csplit-debuginfo` codegen option for macOS platforms.][79570] This option controls whether debug information is split across multiple files or packed into a single file. **Note** This option is unstable on other platforms. - [Added tier 3\* support for `aarch64_be-unknown-linux-gnu`, `aarch64-unknown-linux-gnu_ilp32`, and `aarch64_be-unknown-linux-gnu_ilp32` targets.][81455] - [Added tier 3 support for `i386-unknown-linux-gnu` and `i486-unknown-linux-gnu` targets.][80662] - [The `target-cpu=native` option will now detect individual features of CPUs.][80749] - [Rust now uses `inline-asm` for stack probes when used with LLVM 11.0.1+][77885] \* Refer to Rust's [platform support page][forge-platform-support] for more information on Rust's tiered platform support. Libraries --------- - [`Box::downcast` is now also implemented for any `dyn Any + Send + Sync` object.][80945] - [`str` now implements `AsMut<str>`.][80279] - [`u64` and `u128` now implement `From<char>`.][79502] - [`Error` is now implemented for `&T` where `T` implements `Error`.][75180] - [`Poll::{map_ok, map_err}` are now implemented for `Poll<Option<Result<T, E>>>`.][80968] - [`unsigned_abs` is now implemented for all signed integer types.][80959] - [`io::Empty` now implements `io::Seek`.][78044] - [`rc::Weak<T>` and `sync::Weak<T>`'s methods such as `as_ptr` are now implemented for `T: ?Sized` types.][80764] Stabilized APIs --------------- - [`Arc::decrement_strong_count`] - [`Arc::increment_strong_count`] - [`Once::call_once_force`] - [`Peekable::next_if_eq`] - [`Peekable::next_if`] - [`Seek::stream_position`] - [`array::IntoIter`] - [`panic::panic_any`] - [`ptr::addr_of!`] - [`ptr::addr_of_mut!`] - [`slice::fill_with`] - [`slice::split_inclusive_mut`] - [`slice::split_inclusive`] - [`slice::strip_prefix`] - [`slice::strip_suffix`] - [`str::split_inclusive`] - [`sync::OnceState`] - [`task::Wake`] Cargo ----- - [Added the `split-debuginfo` profile option to control the -Csplit-debuginfo codegen option.][cargo/9112] - [Added the `resolver` field to `Cargo.toml` to enable the new feature resolver and CLI option behavior.][cargo/8997] Version 2 of the feature resolver will try to avoid unifying features of dependencies where that unification could be unwanted. Such as using the same dependency with a `std` feature in a build scripts and proc-macros, while using the `no-std` feature in the final binary. See the [Cargo book documentation][feature-resolver@2.0] for more information on the feature. Rustdoc ------- - [Rustdoc will now include documentation for methods available from `Deref` traits.][80653] - [You can now provide a `--default-theme` flag which sets the default theme to use for documentation.][79642] Various improvements to intra-doc links: - [You can link to non-path primitives such as `slice`.][80181] - [You can link to associated items.][74489] - [You can now include generic parameters when linking to items, like `Vec<T>`.][76934] Misc ---- - [You can now pass `--include-ignored` to tests (e.g. with `cargo test -- --include-ignored`) to include testing tests marked `#[ignore]`.][80053] Compatibility Notes ------------------- - [WASI platforms no longer use the `wasm-bindgen` ABI, and instead use the wasm32 ABI.][79998] - [`rustc` no longer promotes division, modulo and indexing operations to `const` that could fail.][80579] - [The minimum version of glibc for the following platforms has been bumped to version 2.31 for the distributed artifacts.][81521] - `armv5te-unknown-linux-gnueabi` - `sparc64-unknown-linux-gnu` - `thumbv7neon-unknown-linux-gnueabihf` - `armv7-unknown-linux-gnueabi` - `x86_64-unknown-linux-gnux32` Internal Only ------------- - [Consistently avoid constructing optimized MIR when not doing codegen][80718] [79135]: rust-lang/rust#79135 [74489]: rust-lang/rust#74489 [76934]: rust-lang/rust#76934 [79570]: rust-lang/rust#79570 [80181]: rust-lang/rust#80181 [79642]: rust-lang/rust#79642 [80945]: rust-lang/rust#80945 [80279]: rust-lang/rust#80279 [80053]: rust-lang/rust#80053 [79502]: rust-lang/rust#79502 [75180]: rust-lang/rust#75180 [79135]: rust-lang/rust#79135 [81521]: rust-lang/rust#81521 [80968]: rust-lang/rust#80968 [80959]: rust-lang/rust#80959 [80718]: rust-lang/rust#80718 [80653]: rust-lang/rust#80653 [80579]: rust-lang/rust#80579 [79998]: rust-lang/rust#79998 [78044]: rust-lang/rust#78044 [81455]: rust-lang/rust#81455 [80764]: rust-lang/rust#80764 [80749]: rust-lang/rust#80749 [80662]: rust-lang/rust#80662 [77885]: rust-lang/rust#77885 [cargo/8997]: rust-lang/cargo#8997 [cargo/9112]: rust-lang/cargo#9112 [feature-resolver@2.0]: https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2 [`Once::call_once_force`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.call_once_force [`sync::OnceState`]: https://doc.rust-lang.org/stable/std/sync/struct.OnceState.html [`panic::panic_any`]: https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html [`slice::strip_prefix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix [`slice::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix [`Arc::increment_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.increment_strong_count [`Arc::decrement_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.decrement_strong_count [`slice::fill_with`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.fill_with [`ptr::addr_of!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of.html [`ptr::addr_of_mut!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of_mut.html [`array::IntoIter`]: https://doc.rust-lang.org/nightly/std/array/struct.IntoIter.html [`slice::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive [`slice::split_inclusive_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive_mut [`str::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_inclusive [`task::Wake`]: https://doc.rust-lang.org/nightly/std/task/trait.Wake.html [`Seek::stream_position`]: https://doc.rust-lang.org/nightly/std/io/trait.Seek.html#method.stream_position [`Peekable::next_if`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if [`Peekable::next_if_eq`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if_eq
…verted in this PR.
…in, for now. We had already reverted the change on stable back in PR rust-lang#83412. Since then, we've had some movement on issue rust-lang#83139, but not a 100% fix. But also since then, we had bug reported, issue rust-lang#84667, that looks like outright codegen breakage, rather than problems confined to debuginfo issues. So we are reverting PR rust-lang#77885 on stable and beta. We'll reland PR rust-lang#77885 (or some variant) switching back to an LLVM-dependent selection of out-of-line call vs inline-asm, after these other issues have been resolved.
…verted in this PR.
…ark-Simulacrum Revert PR 77885 everywhere Change to probe-stack=call (instead of inline-or-call) everywhere again, for now. We had already reverted the change on stable back in PR rust-lang#83412. Since then, we've had some movement on issue rust-lang#83139, but not a 100% fix. But also since then, we had bug reported, issue rust-lang#84667, that looks like outright codegen breakage, rather than problems confined to debuginfo issues. So we are reverting PR rust-lang#77885 on stable and beta. We'll reland PR rust-lang#77885 (or some variant) switching back to an LLVM-dependent selection of out-of-line call vs inline-asm, after these other issues have been resolved.
…verted in this PR.
…imulacrum [stable] 1.52.0 release This includes the release notes (rust-lang#84183) as well as cherry-picked commits from: * [beta] revert PR rust-lang#77885 rust-lang#84710 * [beta] remove assert_matches rust-lang#84759 * Revert PR 81473 to resolve (on beta) issues 81626 and 81658. rust-lang#83171 * [beta] rustdoc revert deref recur rust-lang#84868 * Fix ICE of for-loop mut borrowck where no suggestions are available rust-lang#83401 Additionally in "fresh work" we're also: * reverting: directly expose copy and copy_nonoverlapping intrinsics rust-lang#81238 to avoid rust-lang#84297 on 1.52
- Perform the probing in the correct direction. Related to rust-lang/rust#77885 (comment) - The first touch on a dynamic alloca cannot use a mov because it clobbers existing space. Use a xor 0 instead Differential Revision: https://reviews.llvm.org/D90216 (cherry picked from commit 3c4d49e)
Enable inline stack probes on X86 with LLVM 16 The known problems with x86 inline-asm stack probes have been solved on LLVM main (16), so this flips the switch. Anyone using bleeding-edge LLVM with rustc can start testing this, as I have done locally. We'll get more direct rust-ci when LLVM 16 branches and we start our upgrade, and we can always patch or disable it then if we find new problems. The previous attempt was rust-lang#77885, reverted in rust-lang#84708.
- Perform the probing in the correct direction. Related to rust-lang/rust#77885 (comment) - The first touch on a dynamic alloca cannot use a mov because it clobbers existing space. Use a xor 0 instead Differential Revision: https://reviews.llvm.org/D90216
Enable inline stack probes on X86 with LLVM 16 The known problems with x86 inline-asm stack probes have been solved on LLVM main (16), so this flips the switch. Anyone using bleeding-edge LLVM with rustc can start testing this, as I have done locally. We'll get more direct rust-ci when LLVM 16 branches and we start our upgrade, and we can always patch or disable it then if we find new problems. The previous attempt was rust-lang#77885, reverted in rust-lang#84708.
Fixes (?) #74405, related to #43241
r? @cuviper