-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
explicit tail calls: support indirect arguments #151143
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
base: main
Are you sure you want to change the base?
Conversation
8a1cd78 to
6f7eede
Compare
| PassMode::Indirect { on_stack: true, .. } => { | ||
| // FIXME: some LLVM backends (notably x86) do not correctly pass byval | ||
| // arguments to tail calls (as of LLVM 21). See also: | ||
| // | ||
| // - https://github.com/rust-lang/rust/pull/144232#discussion_r2218543841 | ||
| // - https://github.com/rust-lang/rust/issues/144855 | ||
| span_bug!( | ||
| fn_span, | ||
| "arguments using PassMode::Indirect {{ on_stack: true, .. }} are currently not supported for tail calls" | ||
| ) |
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.
I've kept the span_bug! for now.
It looks like a fix for x86 might get cherry-picked into LLVM 22. If so, I think that is enough support to allow this variant too. At that point riscv would be the next most commonly used target that would miscompile.
This comment has been minimized.
This comment has been minimized.
6f7eede to
a904f16
Compare
This comment has been minimized.
This comment has been minimized.
a904f16 to
fc79542
Compare
This comment has been minimized.
This comment has been minimized.
029786e to
414b969
Compare
|
@bors try=x86_64-msvc-1,x86_64-msvc-2 |
|
Unknown command "try". Run |
|
@bors try job=x86_64-msvc-1,x86_64-msvc-2 |
This comment has been minimized.
This comment has been minimized.
explicit tail calls: support indirect arguments try-job: x86_64-msvc-1 try-job: x86_64-msvc-2
This comment has been minimized.
This comment has been minimized.
|
💔 Test for e8cb9bb failed: CI. Failed job:
|
414b969 to
33942c6
Compare
|
@bors try job=x86_64-msvc-1,x86_64-msvc-2 |
|
⌛ Trying commit 33942c6 with merge 282e2c8… To cancel the try build, run the command Workflow: https://github.com/rust-lang/rust/actions/runs/21048427234 |
explicit tail calls: support indirect arguments try-job: x86_64-msvc-1 try-job: x86_64-msvc-2
tracking issue: #112788
After discussion in #144855, I was wrong and it is actually possible to support tail calls with
PassMode::Indirect { on_stack: false, .. }arguments.Normally an indirect argument with
on_stack: falsewould be passed as a pointer into the caller's stack frame. For tail calls, that would be unsound, because the caller's stack frame is overwritten by the callee's stack frame.Therefore we store the argument for the callee in the corresponding caller's slot. Because guaranteed tail calls demand that the caller's signature matches the callee's, the corresponding slot has the correct type.
To handle cases like the one below, the tail call arguments must first be copied to a temporary, and can only then be copied to the caller's argument slots.
I'm not really familiar with MIR and what tricks/helpers we have, so I'm just cobbling this together. Hopefully we can arrive at something more elegant.