Uh oh!
There was an error while loading. Please reload this page.
explicit tail calls: pass caller's argument slots as arguments for untuple indirect arguments - #158248
explicit tail calls: pass caller's argument slots as arguments for untuple indirect arguments#158248dianqk wants to merge 1 commit into
Conversation
rustbot
commented
Jun 22, 2026
|
| // temporaries, then copy back to the caller's argument slots. | ||
| // Finally, we pass the caller's argument slots as arguments. | ||
| // | ||
| // To do that, the argument must be MUST-by-move value. |
| let local = self.mir.args_iter().nth(i).unwrap(); | ||
| match &self.locals[local] { |
There was a problem hiding this comment.
This is not a reliable way to get the LLVM value for the argument. We are allowed to introduce a copy alloca in this case:
rust/compiler/rustc_codegen_ssa/src/mir/mod.rs
Lines 539 to 541 in 9030e34
cc @folkertdev
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| // We don't need `tail_call_temporaries` for the untuple arguments because they won't be | ||
| // modified, they are the last arguments. |
There was a problem hiding this comment.
I don't get what this comment is saying...
There was a problem hiding this comment.
The new comment should be clearer.
5493c9b to
a61a2b4Compare| // For untupled arguments, it is safe to store them directly into the caller's | ||
| // argument slots without temporaries, because the untupled arguments are | ||
| // always passed through a tuple alloca. The alloca serves as a temporary | ||
| // that does not overlap with any caller argument. | ||
| // No temporaries are needed for the caller's untupled arguments either, | ||
| // because they are used last. |
There was a problem hiding this comment.
I still don't quite get this. First of all, this should probably mention tail calls, as otherwise it doesn't make sense why anything here wouldn't be ok.
But second of all, I checked out your branch locally and I'm getting incorrect codegen (rustc t.rs --emit=llvm-ir -O):
#![feature(unboxed_closures)]#![feature(explicit_tail_calls)]#![crate_type = "lib"]typeTuple = (u64,u64,u64,u64);traitX{extern"rust-call"fnf(self,args:Tuple) -> u8;extern"rust-call"fng(self,args:Tuple) -> u8;}implXforTuple{extern"rust-call"fnf(self,args:Tuple) -> u8{
become args.g(self)}#[inline(never)]extern"rust-call"fng(self,args:Tuple) -> u8{
std::hint::black_box((self, args));0}}; <(u64, u64, u64, u64) as t::X>::f; Function Attrs: nounwind nonlazybind uwtabledefine noundef i8@_RNvXCs146zwHEvxau_1tTyyyyENtB2_1X1f(ptr dead_on_return noalias nofree noundef align8 captures(none) dereferenceable(32) initializes((0, 32)) %self, i64 noundef %0, i64 noundef %1, i64 noundef %2, i64 noundef %3) unnamed_addr #0 {
start:
storei64%0, ptr%self, align8%.sroa.4.0.self.sroa_idx = getelementptrinboundsnuwi8, ptr%self, i648storei64%1, ptr%.sroa.4.0.self.sroa_idx, align8%.sroa.5.0.self.sroa_idx = getelementptrinboundsnuwi8, ptr%self, i6416storei64%2, ptr%.sroa.5.0.self.sroa_idx, align8%.sroa.6.0.self.sroa_idx = getelementptrinboundsnuwi8, ptr%self, i6424storei64%3, ptr%.sroa.6.0.self.sroa_idx, align8; call <(u64, u64, u64, u64) as t::X>::g%4 = musttail call noundef i8@_RNvXCs146zwHEvxau_1tTyyyyENtB2_1X1g(ptrnoalias nofree noundef nonnullalign8 captures(address) dereferenceable(32) %self, i64 noundef %0, i64 noundef %1, i64 noundef %2, i64 noundef %3) #4reti8%4
}Granted, this code is weird and I couldn't come up with a more normal looking one, but I don't get the justification for why this is sound...
WaffleLapkin
commented
Jun 23, 2026
I could honestly see us just banning tail calling |
a61a2b4 to
c48e49cComparedianqk
commented
Jun 23, 2026
I don’t have a strong opinion on this decision. I think it’s up to you. |
rust-log-analyzer
commented
Jun 23, 2026
The job Click to see the possible cause of the failure (guessed by this bot) |
WaffleLapkin
commented
Jun 24, 2026
@folkertdev I'm tempted to say that we should disallow tail calling |
folkertdev
commented
Jun 24, 2026
Not really, what are the implications of that? |
WaffleLapkin
commented
Jun 24, 2026
@folkertdev not much. The only reason to use |
folkertdev
commented
Jun 24, 2026
Sounds like a good idea then 👍 |
…folkertdev disallow tail calling extern "rust-call" functions r? folkertdev Following discussion from rust-lang#158248. Fixesrust-lang#158017Closesrust-lang#158248
☔ The latest upstream changes (presumably #158342) made this pull request unmergeable. Please resolve the merge conflicts by rebasing. |
…folkertdev disallow tail calling extern "rust-call" functions r? folkertdev Following discussion from rust-lang#158248. Fixesrust-lang#158017Closesrust-lang#158248
…folkertdev disallow tail calling extern "rust-call" functions r? folkertdev Following discussion from rust-lang#158248. Fixesrust-lang#158017Closesrust-lang#158248
tracking issue: #112788
Fixes#158017.
Same as #151143, but for untuple indirect arguments.
r? WaffleLapkin