-
Notifications
You must be signed in to change notification settings - Fork 746
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
Tail calls not respected after inlining #4587
Comments
This does look like a bug. To see it it's enough to run The pass does have logic that should handle binaryen/src/passes/Inlining.cpp Lines 254 to 282 in 094deb0
cc @tlively |
That code failed to anticipate the case where there is a "loop" of (mutually) recursive tail calls. I think it would work to only downgrade return calls in the callee to normal calls if and only if the inlined call site is not a return call. If the inlined call site is not a return call, then this recursion could have blown the stack anyway, and if it is a return call, then the types must be compatible such that we don't need to downgrade the return calls in the callee. |
We can preserve return_calls in inlined functions when the inlined call site is itself a return_call, since the call result types must transitively match in that case. This solves a problem where the previous inlining logic could introduce stack exhaustion by downgrading recursive return_calls to normal calls. Fixes #4587.
We can preserve return_calls in inlined functions when the inlined call site is itself a return_call, since the call result types must transitively match in that case. This solves a problem where the previous inlining logic could introduce stack exhaustion by downgrading recursive return_calls to normal calls. Fixes #4587.
I ran into a bit of an issue with
return_call
instructions not being honored after inlining. This can cause code that otherwise works without blowing the stack to cause a stack overflow after being optimized.A fairly small reproduction is available here (and my apologies for the OCaml 😶): https://github.com/ospencer/binaryen_tailcall_bug_repro/blob/main/lib/Util.re
If you have
esy
installed, you can run the example withesy && esy test
, and you'll get this output:I haven't looked at the code just yet, but my intuition is that this happens because it wouldn't be safe to copy over a
return_call
in the body of a function, as it likely would change the semantics of the function it's being inlined into. I can't really think of something more clever than just not inlining functions with areturn_call
instruction, though in "simple" cases like this one where the result of the inlined function is returned, thereturn_call
could be kept, but that analysis seems a bit annoying to write 😅Let me know if there's any additional information I can provide or any way I can help.
The text was updated successfully, but these errors were encountered: