Stream: git-wasmtime

Topic: wasmtime / PR #14349 winch: support tail calls with calle...


view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 19:43):

macovedj opened PR #14349 from macovedj:winch-tailcall-callee-clean to bytecodealliance:main:

Adds support for return_call and return_call_indirect to Winch on x86-64 and AArch64.
The implementation changes Winch’s internal calling convention so callees reclaim their aligned incoming stack-argument area before returning. This applies to ordinary calls as well as tail calls. Tail calls can then replace the current frame and resize the argument area without requiring the original caller to recover SP afterward. Cranelift-generated trampolines use the existing callee_pop_size machinery to follow the same convention.
Includes two performance optimizations:

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 19:43):

macovedj requested cfallin for a review on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 19:43):

macovedj requested wasmtime-compiler-reviewers for a review on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 19:43):

macovedj requested wasmtime-core-reviewers for a review on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 20:45):

github-actions[bot] added the label cranelift on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 20:45):

github-actions[bot] added the label cranelift:area:machinst on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 20:45):

github-actions[bot] added the label cranelift:area:aarch64 on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 20:45):

github-actions[bot] added the label cranelift:area:x64 on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 20:45):

github-actions[bot] added the label wasmtime:api on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 20:45):

github-actions[bot] added the label wasmtime:config on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 20:46):

github-actions[bot] commented on PR #14349:

Label Messager: wasmtime:config

It looks like you are changing Wasmtime's configuration options. Make sure to
complete this check list:

[fuzzing-config]: https://github.com/bytecodealliance/wasmtime/blob/ca0e8d0a1d8cefc0496dba2f77a670571d8fdcab/crates/fuzzing/src/generators.rs#L182-L194
[fuzzing-docs]: https://docs.wasmtime.dev/contributing-fuzzing.html


<details>

To modify this label's message, edit the <code>.github/label-messager/wasmtime-config.md</code> file.

To add new label messages or remove existing label messages, edit the
<code>.github/label-messager.json</code> configuration file.

Learn more.

</details>

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2026 at 21:02):

cfallin commented on PR #14349:

Thanks for this -- I will be able to review next week (currently on a work trip with limited availability).

view this post on Zulip Wasmtime GitHub notifications bot (Sep 17 2026 at 20:25):

:memo: saulecabrera submitted PR review:

Did a first pass; thanks for all the changes here. FWIW, @macovedj and myself discussed some of the trade-offs here between a caller and callee pop approach.


The following programs fail to compile:

(module
  (type $t (func (result i32)))
  (table 1 funcref)
  (func (export "f") (param i32) (result i32)
    (if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
    (if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
    (if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
    (if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
    (if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
    (i32.const 0)
  )
)

When invoked via

target/release/wasmtime -C compiler=winch -W tail-call issue_a.wat

It fails with

Winch internal error: Expected register to be available.

I think we are failing to free the register in emit_return?

(module
  (func $f
    (return_call $f)
    (loop)
  )
)

When invoked using epoch or using fuel interruption, like:

It fails with:

Winch internal error: Invalid local offset

Is it possible that we are not handling SP correctly at emit_return?

Aside from the issues above, I think we'd also want to:

view this post on Zulip Wasmtime GitHub notifications bot (Sep 17 2026 at 23:40):

:memo: saulecabrera submitted PR review:

Did a first pass; thanks for all the changes here. FWIW, @macovedj and myself discussed some of the trade-offs here between a caller and callee pop approach.


The following programs fail to compile:

(module
  (type $t (func (result i32)))
  (table 1 funcref)
  (func (export "f") (param i32) (result i32)
    (if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
    (if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
    (if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
    (if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
    (if (local.get 0) (then (return_call_indirect (type $t) (i32.const 0))))
    (i32.const 0)
  )
)

When invoked via

target/release/wasmtime -C compiler=winch -W tail-call <wasm>

It fails with

Winch internal error: Expected register to be available.

I think we are failing to free the register in emit_return?

(module
  (func $f
    (return_call $f)
    (loop)
  )
)

When invoked using epoch or using fuel interruption, like:

It fails with:

Winch internal error: Invalid local offset

Is it possible that we are not handling SP correctly at emit_return?

Aside from the issues above, I think we'd also want to:

view this post on Zulip Wasmtime GitHub notifications bot (Sep 18 2026 at 15:40):

macovedj updated PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 18 2026 at 15:40):

macovedj requested fitzgen for a review on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 18 2026 at 15:40):

macovedj requested wasmtime-fuzz-reviewers for a review on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 18 2026 at 15:46):

macovedj commented on PR #14349:

Thanks Saul!
I’ve pushed an update addressing the feedback. It updates the documentation and fuzz configuration, releases the temporary callee registers after tail-call lowering, and skips fuel/epoch checks for unreachable loops while preserving the control-stack bookkeeping. I also added regressions for the register cleanup and unreachable-loop cases.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 18 2026 at 15:58):

macovedj edited a comment on PR #14349:

Thanks @saulecabrera!
I’ve pushed an update addressing the feedback. It updates the documentation and fuzz configuration, releases the temporary callee registers after tail-call lowering, and skips fuel/epoch checks for unreachable loops while preserving the control-stack bookkeeping. I also added regressions for the register cleanup and unreachable-loop cases.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 18 2026 at 17:44):

github-actions[bot] added the label fuzzing on PR #14349.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 18 2026 at 17:44):

github-actions[bot] commented on PR #14349:

Subscribe to Label Action

cc @fitzgen

<details>
This issue or pull request has been labeled: "cranelift", "cranelift:area:aarch64", "cranelift:area:machinst", "cranelift:area:x64", "fuzzing", "wasmtime:api", "wasmtime:config"

Thus the following users have been cc'd because of the following labels:

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

Learn more.
</details>


Last updated: Sep 20 2026 at 18:08 UTC