Skip to content

transform: assert that pointer-bearing selects do not reach escape analysis - #5882

Closed
davecheney wants to merge 1 commit into
tinygo-org:devfrom
davecheney:davecheney-check-assert-aggregate-select
Closed

davecheney wants to merge 1 commit into
tinygo-org:devfrom
davecheney:davecheney-check-assert-aggregate-select

Conversation

@davecheney

Copy link
Copy Markdown
Contributor

Escape analysis does not follow pointers through select instructions. It treats these uses as escaping, which can leave allocations on the heap.

The passes before OptimizeAllocs do not currently produce these selects. Add an assertion to detect a pipeline change that breaks this assumption, rather than silently reducing allocation optimization.

…alysis

Escape analysis does not follow pointers through select instructions.
It treats these uses as escaping, which can leave allocations on the heap.

The passes before OptimizeAllocs do not currently produce these selects.
Add an assertion to detect a pipeline change that breaks this assumption,
rather than silently reducing allocation optimization.
@davecheney

Copy link
Copy Markdown
Contributor Author

Replaced by #5891. The assumption in this PR is false: min and max on strings make a select over a pointer-bearing value before OptimizeAllocs runs, so the assertion crashes the compiler on valid code. #5891 follows the select result instead.

@davecheney davecheney closed this Oct 15, 2026
davecheney added a commit that referenced this pull request Oct 16, 2026
…ect (#5891)

Escape analysis treats every select as an escape, so allocations that flow through a select stay on the heap even when nothing outside the function can see them. The frontend makes these selects for min and max on strings, and instcombine can make a select over a pointer before OptimizeAllocs runs.

This came up in review of #5882, which tried to assert that no pointer-bearing select reaches escape analysis. That assumption is false, and the assertion crashes the compiler on valid Go code that calls min on a string that points to a local allocation. The better fix is to follow the select result in the same way as a bitcast, because the pointer can only leave through that result.

The allocs2.go case does not show the stack allocation, because runtime.stringLess is only declared in that test. The IR cases in allocs-aggregate.ll show both the heap and the stack result.
@davecheney
davecheney deleted the davecheney-check-assert-aggregate-select branch October 17, 2026 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant