Skip to content

cmd/compile: model stack ABI values with preallocated and goret - #126

Draft
zhouguangyuan0718 wants to merge 8 commits into
go1.27.masterfrom
codex/go-stack-byval
Draft

cmd/compile: model stack ABI values with preallocated and goret#126
zhouguangyuan0718 wants to merge 8 commits into
go1.27.masterfrom
codex/go-stack-byval

Conversation

@zhouguangyuan0718

@zhouguangyuan0718 zhouguangyuan0718 commented Aug 12, 2026

Copy link
Copy Markdown

LLVM-PR: goallc/llvm-project#70

Depends on goallc/llvm-project#70 at head 5f9499711cfd85c7d0fb64e9cf4b75fb1573682d.

Summary

  • classify non-empty memory-only parameters and results directly from the Go ABI assignment rather than separate scalar/aggregate heuristics
  • emit typed preallocated(T) parameters and call operand bundles for values wholly assigned to the incoming stack
  • write caller values directly into the reserved outgoing ABI home and bind callee accesses directly to the incoming home, removing the redundant argument alloca/copy
  • emit typed goret(T) "goretindex"="N" carriers for stack results while preserving compact LLVM returns for register results
  • remove the function-level go_memory_results list; each result carrier records its own logical index with an ordinary key/value parameter attribute
  • preserve memory carriers through statepoint rewriting, pointer-map construction, and GoObj emission, including pointer-containing stack parameters
  • keep fixed-home statepoint reuse only for read-only, non-escaping incoming homes; mutable or captured values fall back to ordinary relocation spill slots
  • keep the previous direct-parameter copy-elision hook only for register parameters; it does not participate in either memory carrier path
  • preserve independent ARM64 PC-relative instruction relocations for ELF and Mach-O external links, so the platform linker applies the final section layout instead of using the Go linker's preliminary addresses
  • qualify archive/zip, compress/flate, compress/gzip, and compress/zlib in the standard-library LLVM whitelist

This deliberately does not use sret: Go supports multiple mixed register/stack results.

ARM64 external-link regression

The carrier lowering allowed the AArch64 scheduler to separate an ADRP and its later LDR. GoObj correctly represented these as independent R_ARM64_PCREL relocations, but the Go external linker resolved each relocation against its preliminary data layout. The system linker then moved the target data section, leaving the load pointed at the old address and making fixedbugs/issue34968.go fault in _cgo_cmalloc.

The linker now identifies each affected ARM64 instruction and emits the corresponding ELF ADR_PREL_PG_HI21/ADD_ABS_LO12_NC/LDST*_ABS_LO12_NC or Mach-O PAGE21/PAGEOFF12 relocation. Windows keeps the existing PE resolution path. Unsupported instructions fail closed.

Joint validation

  • exact LLVM cmd/compile: lower bit reversal and wide multiply to LLVM #70 Linux arm64 payload and standard dynamic src/make.bash: PASS
  • exact LLVM cmd/compile: lower bit reversal and wide multiply to LLVM #70 Darwin arm64 development payload and standard static src/make.bash: PASS
  • GoALLC statepoint/GoObj/ObjView CTest suite: 77/77 PASS
  • cmd/compile/internal/ssa with llvm23,dynamicllvm: PASS
  • cmd/llvmtoolexec tests: PASS
  • linker unit tests for cmd/link/internal/arm64, ld, and loader: PASS
  • Linux arm64 issue34968, issue36705, and issue47227: 10 consecutive focused policy PASS after the full rebuild
  • Linux arm64 full LLVM test policy: PASS in 584.234s; all required white entries passed
  • Darwin arm64 issue34968: 10 consecutive focused policy PASS; a separately forced -linkmode=external binary also ran 10/10
  • strict LLVM-built runtime dependency closure at default<O2>: PASS
  • standard-library LLVM CI driver with full LLVM dependency closures: all 66 packages PASS on Linux amd64 and arm64 in the preceding joint run
  • compress/flate current-package tests with native dependencies at default<O2>: 3 consecutive PASS
  • preserved compress/flate raw IR, optimized IR, GoObj, and executable evidence contains preallocated carriers and no Go-specific byval temporary path
  • the exact Linux amd64 optimized reflect.Value.call IR that exposed the large-result statepoint path lowers through llc and produces a Go object
  • amd64 raw math.Abs lowering is checked as Go's sign-bit clear; its O2 form and the arm64 lowering are checked as llvm.fabs

The new Linux amd64/arm64 joint qualification must select the exact LLVM #70 payload and pass before this draft is ready.

@zhouguangyuan0718 zhouguangyuan0718 changed the title cmd/compile: model stack ABI values as LLVM memory carriers cmd/compile: model stack ABI values with byval and goret Aug 12, 2026
@zhouguangyuan0718
zhouguangyuan0718 force-pushed the codex/go-stack-byval branch 3 times, most recently from 391a633 to ba11337 Compare August 13, 2026 04:12
@zhouguangyuan0718 zhouguangyuan0718 changed the title cmd/compile: model stack ABI values with byval and goret cmd/compile: model stack ABI values with preallocated and goret Aug 15, 2026
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