A device transfer's free is emitted at end of block, not from a lifetime
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 14
- Forks
- 2
- Avg merge
- 12h 42m
- Merged PRs (30d)
- 61
Description
TransferToPluginLowering emits vx_plugin_free before the enclosing block's terminator. That is correct for straight-line code and wrong in the two places it matters.
A transfer inside a loop allocates every iteration and frees every iteration -- so the buffer is released at the bottom of the body while the program may still hold the descriptor, and a long-running loop churns the device allocator. Staging weights once outside a loop is the shape inference actually wants, and it happens to be the shape this handles correctly, which is how it passed.
A transfer whose result outlives the block -- returned from a function, stored in a struct -- is freed while still referenced.
The previous host lowering had the same end-of-block rule (it emitted memref.dealloc there), so this is inherited rather than introduced. It matters more now: freeing host memory early is a use-after-free the allocator often survives, and freeing device memory early is a use-after-free across a bus.
What it should be
The lifetime is a property the compiler can know. A transferred buffer is live until its last use, and the borrow machinery already tracks that for references (live_borrows, NLL sweeps, hiraditya/Vx.1#276). The free belongs at the end of the value's live range, not the end of the syntactic block.
Until then, the honest interim is to refuse what cannot be placed correctly: a device transfer whose result escapes its block, or one inside a loop, should be a diagnostic rather than a silently misplaced free.
Related: hiraditya/Vx.1#319 (device residency).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing TransferToPluginLowering and compare its end-of-block free placement with the live_borrows and NLL sweeps machinery mentioned in the issue. Check the loop and escaping-result cases described here, including the inherited host-lowering behavior. Done means the compiler either places release at the value's last use or diagnoses transfers whose lifetime cannot be placed safely.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100