-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
"LLVM ERROR: Access past stack top!" when compiling without sse2 #65844
Comments
Does this also happen on older Rust versions? |
AFAIK it affects all Rust versions since 1.18.0. |
@rustbot ping ICEbreakers-LLVM |
Error: This team ( Please let |
@rustbot ping icebreakers-llvm |
Hey LLVM ICE-breakers! This bug has been identified as a good cc @hdhoang @heyrutvik @jryans @mmilenko @nagisa @nikic @rkruppe @spastorino @vertexclique |
triage: P-high, removing I-nominated |
FWIW I can reproduce with
but can't reproduce with
|
Reproduces on Compiler Explorer with latest nightly but only with optimisations disabled. |
Oh dear:
|
I love segfaults from |
(seems like it might only happen at opt-level=0 ... oh, that matches what @mati865 already said ) |
Building with a compiler that has
However, if I break the compile up into two stages, so that
The rustc-generated LLVM IR in question looks like this:
So... is this rustc's fault for generating LLVM IR that passes around a |
My personal suspicion is that we shift this over to LLVM's camp, and that we should try to turn the LLVM IR |
LLVM should not crash on valid LLVM IR (accepted by |
I wonder if this reduction would be acceptable to the LLVM developers: https://godbolt.org/z/9RvgsQ : attributes #0 = { "target-cpu"="x86-64" "target-features"="-sse2" }
define { double, double } @get_pair() unnamed_addr #0 {
%1 = alloca { double, double }, align 8
%2 = bitcast { double, double }* %1 to double*
store double 0.000000e+00, double* %2, align 8
%3 = getelementptr inbounds { double, double }, { double, double }* %1, i32 0, i32 1
store double 0.000000e+00, double* %3, align 8
%4 = getelementptr inbounds { double, double }, { double, double }* %1, i32 0, i32 0
%5 = load double, double* %4, align 8
%6 = getelementptr inbounds { double, double }, { double, double }* %1, i32 0, i32 1
%7 = load double, double* %6, align 8
%8 = insertvalue { double, double } undef, double %5, 0
%9 = insertvalue { double, double } %8, double %7, 1
ret { double, double } %9
} |
That seems to (relatively) gracefully report an error, not fail an assertion. And not exactly a novel error, see e.g. #26449. I can't say for sure but "x86_64 without SSE2" is an extremely odd configuration to begin with, so it seems sensible to require addition of |
So that means its not the right reduction then, it seems. I wasn't sure if there was something going on where |
(It also still seems very bad that this scenario leads to |
Possibly this is just a failure to handle rust/src/librustc_codegen_llvm/back/write.rs Line 264 in 0a953cd
|
Aha! My insight today: why bother reducing to some Step 1. Verified that bug still reproduces with this version of the code (when I use a pub struct S1 { _x: f64, _y: f64 }
pub fn indirect(get_pair: fn () -> S1) {
let _s1 = get_pair();
} Step 2. The above is readily translatable to C: struct S { double x; double y; };
int indirect(struct S get_pair()) {
struct S s = get_pair();
return 0;
} Step 3. Get your hands on Step 4: Run
Step 5. Get sad that the above compiled without error. Set the bug aside for the day Step 6. Review work in evening. Realize that above Step 7. Rerun clang the right way:
Woot! Time to finally file that LLVM bug! |
Filed https://bugs.llvm.org/show_bug.cgi?id=44413 At this point I'm going to downgrade this to P-medium. (It is not really reasonable for us to try to fix this on our end; it will need to wait for LLVM to fix its bug, and then us to either cherry-pick the fix, or wait for an LLVM upgrade.) |
LLVM posted proposed "fix" (*) in llvm/llvm-project@e898ba2 ; see also topper's comment on my bug report (*) at least fix in terms of removing the assertions; the codegen is still wrong, but they say we should at least get a diagnostic now in addition to no assertions... |
I tried the patch locally; I do not see any diagnostics from (That may be due to the issue @nikic noted above. Will investigate.) |
Its possible that LLVM's preferred solution may be this one: https://reviews.llvm.org/D70465 |
This also happens when compiling with Also, possibly related but slightly different (I can open another issue if you want), when building with
|
This continues to occur with Rust 1.60 and 1.62.0-nightly (e1b71fe 2022-05-03). I've seen it in the wild with both the |
My working assumption is that the continued occurrences are due to https://bugs.llvm.org/show_bug.cgi?id=44413 still being unclosed on the LLVM side. However, there is this comment over there:
which would imply that we shouldn't be seeing an assert/crash anymore, just ... wrong... codegen...? |
With the latest nightly, running the rustc command will only cause the "SSE2 register return with SSE2 disabled" error. AFAIK it is unfeasible to return a pair of doubles without SSE2, which makes this behavior normal. Compiling the C code provided by @pnkfelix with clang produces a similar error. I could also reproduce the crash/assertion failure with previous versions. Edit: I realized that compiling with the rustc built from source would give me |
Without SSE I would expect a pair of doubles to be returned on the stack, "by invisible reference," i.e. caller supplies an invisible zeroth argument (or possibly N+1'th argument, it's been a long time) which is a pointer to a space in caller's stack frame where the return value is to be written. Same as how it would be done in x86-32 mode, or how it would be done for returning a large struct that doesn't fit in registers at all. |
Noted. I would also add that:
|
the following code produces the compilation error
LLVM ERROR: Access past stack top!
when compiling withE:RUSTFLAGS="-Ctarget-feature=-sse2" cargo +nightly run
only happens when the return values of
get_pair
are named.also when compiling an example to a library crate like this:
E:RUSTFLAGS="-Ctarget-feature=-sse2" cargo +nightly run --example bug
i get the following error instead:
rustc version:
The text was updated successfully, but these errors were encountered: