Skip to content

cmd/compile: use typed byval for stack ABI inputs - #138

Merged
zhouguangyuan0718 merged 4 commits into
go1.27.masterfrom
codex/go-typed-byval
Aug 18, 2026
Merged

cmd/compile: use typed byval for stack ABI inputs#138
zhouguangyuan0718 merged 4 commits into
go1.27.masterfrom
codex/go-typed-byval

Conversation

@zhouguangyuan0718

@zhouguangyuan0718 zhouguangyuan0718 commented Aug 16, 2026

Copy link
Copy Markdown

This change uses the Go ABI allocator as the source of truth for LLVM input carriers. A non-empty input assigned wholly to the Go stack is emitted as a typed, aligned byval pointer; a register-assigned input remains a direct LLVM value. Results are intentionally unchanged.

For a memory-backed argument whose current SSA memory state is already the call state, the frontend passes the existing address directly. A pure SSA value, or a value that must preserve an earlier memory state, uses an ordinary entry alloca plus store as the byval source. Standard LLVM byval copying remains the correctness mechanism.

LLVM PR #85 recognizes only a strict private alloca plus stores plus one byval-consumer shape and forwards those stores into the final outgoing stack argument area. The predicate is now a shared target-independent CodeGen analysis used by both SelectionDAG and the Go statepoint plugin. Consequently, the plugin does not manufacture a deopt use for an ephemeral outgoing carrier and accidentally block the later forwarding. A carrier spanning an intervening call remains an ordinary pointer-containing stack object at every safepoint.

Incoming argument-copy elision remains responsible for fixed formal-argument homes, while late byval forwarding skips fixed objects, so the two optimizations do not overlap. Pointer values loaded from incoming homes continue to use ordinary statepoint spill slots; this change does not reuse byval fields as spill slots and does not require readonly or mutation analysis.

The LLVM base calling convention expresses AArch64 and X86 assignment with TableGen rules plus CCState. Direct inputs have no stack fallback, so any carrier/allocation mismatch fails closed. Register fixed homes are retained and the result ABI remains unchanged.

Validation for the coordinated release and Go head:

  • LLVM release goallc-llvm23.1.0-20260818T010709Z
  • LLVM revision 040059c00d16bfb643a87bf77d162f926a96466f
  • Go head 8e4ba75be3
  • native Darwin/arm64 LLVM AArch64/X86 byval lit: 2/2
  • Go statepoint plugin tests including GoObj/objview: 95/95
  • native arm64 archive/tar LLVM O2 dependency closure: pass through compile, statepoint, llc/GoObj, link, and package tests
  • runtime frames restored from the failing current baseline: runtime.throw 64 to 48 bytes, runtime.fatalthrow 80 to 64 bytes, runtime.getGCMaskOnDemand 96 to 80 bytes
  • abi-differential/machine-args-pointer-maps: pass after recording the already-required 0/16 Go ABI frame layout in its hand-written MIR
  • isolated fixedbugs/issue19658.go: pass; the full highly parallel local run timed that case out under load

compress/flate still reaches the independent stack-result problem in compress/flate.indexTokens. A dedicated result carrier is intentionally outside this input-only change.

@zhouguangyuan0718
zhouguangyuan0718 merged commit 349c6cf into go1.27.master Aug 18, 2026
4 of 5 checks passed
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