[depends on #2327] target: add COFF linking and Go architecture tuning - #2335
[depends on #2327] target: add COFF linking and Go architecture tuning#2335cpunion wants to merge 27 commits into
Conversation
LLGo baseline benchmarks
Program measurements
Core language and compiler benchmarks
Compared with |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
|
@fennoai please review the current head, including the Go-compatible GO386/GOAMD64/GOARM64 parsing, LLVM CPU/feature mapping, build-cache isolation, and Windows COFF linker behavior. |
There was a problem hiding this comment.
Review: Windows COFF linker flags & GOARCH build config
Solid, well-tested PR. The platform split for file locking (filelock_*.go) and mmap (mmap_*.go) is clean, the new internal/goarch package nicely separates Go semantics from LLVM mapping, and the test coverage across the new resolvers, triple builder, and target features is thorough. I verified the areas most prone to subtle bugs and they are correct:
goarchEnvemitting emptyGO386=/GOAMD64=/GOARM64=entries — intended and correct.withEnvtreats each entry's key as an override, so the empty entries deliberately clear inherited parent-env arch values for childgoinvocations.releaseLockno longer removing the lock file — correct improvement; unlinking a lock file while another holder has it open by inode is a classic mutual-exclusion race. Retention is the standard flock pattern and the accumulation is bounded to one file per fixed path.meta.Closeclearingmmap/raw— double-Close is now a safe no-op (covered by the new test).Target.Spec()re-resolving arch config — build.go passes already-normalized values and the resolvers are idempotent on their canonical output, so the double-resolution is safe.- Windows mmap /
unsafe.Slice— the newfi.Size()bound inOpenprevents negative/overflow lengths reachingunsafe.Slice, theCreateFileMappinghandle is released viadefer, andunmapFileguardslen(raw)==0. No leak.
A few minor, non-blocking items are inline below.
Behavioral note (intentional, but reviewer-visible): this changes the default GOOS=windows target ABI from GNU/MinGW (*-windows-gnu) to MSVC (*-pc-windows-msvc). That is a meaningful default change for existing Windows users — worth calling out in release notes so anyone relying on the MinGW runtime is aware.
Additional findings
ssa/target.go:160: [P3] Dead llvmarch assignments after triple refactor: After moving triple construction intoGetTargetTripleWithGOARM(line 161), thellvmarchvalues computed here for386/amd64/arm64/wasm/default are dead — only thearmbranch'sllvmarchis still consumed (in theswitch llvmarchat the arm feature block below). Consider reducing this first switch to computellvmarchonly for thearmcase (or inline it into the arm feature switch), so it no longer misleadingly appears to feed the triple.
|
FennoAI is processing your request, please wait a moment... |
There was a problem hiding this comment.
Review: COFF linking and Go architecture tuning
Reviewed the four requested areas at head 6e70577. This PR is stacked on #2327, so I scoped the review to the architecture-tuning and COFF-linker changes and treated the inherited crosscompile/meta foundation as context.
Overall: solid, well-tested, and no blocking issues. The four areas verified as correct:
- GO386/GOAMD64/GOARM64 parsing (
internal/goarch/config.go) — strict allow-lists, Go-compatible defaults (sse2/v1/v8.0), extension ordering, LSE-forced-from-v8.1, and Go-matching error messages. Round-trips stably throughARM64.String(). - LLVM CPU/feature mapping (
ssa/target.go) —GO386=softfloatdisables SSE/x87,GOAMD64 vNmaps tox86-64[-vN],GOARM64version→arch feature with+lse/+cryptoand-fmvon non-darwin. Correct. - Build-cache isolation (
fingerprint.go+collect.go) — distinctGO386/GOAMD64/GOARM64produce distinct fingerprints; normalized empty↔default configs still hit cache; inactive-arch fields are zeroed so no cross-arch leakage. Verified againstgoarch_test.go. - Windows COFF linker (
crosscompile.go) —/errorlimit:0,/opt:noicf(justified by Go's distinct-PC requirement, since lld-link's/opt:refenables ICF by default),/opt:lldlto=0..3, and/opt:refwith per-function/data sections.coffLTOLevelcorrectly clamps to lld-link's 0–3 range.
No security findings. Env values are validated before reaching LLVM feature/linker strings; linker flags are built from constants and passed as argv (no shell); the Windows CI workflow interpolates no untrusted ${{ }} into run: blocks.
The inline comments below are minor maintainability/documentation notes, not defects.
Informational (no reliable inline location)
internal/xtool/llvm/llvm.go— the newgoarmparameter ofGetTargetTripleWithGOARMis only wired throughssa/target.go. Production callerscrosscompile.go:273andplan9asm/translate.go:108still callGetTargetTriple(goarm=""→armv7), so GOARM triple tuning is unreachable there. This does not affect the arm64/386/amd64 tuning that is this PR's focus (those apply viaSpec()CPU/features), but worth noting for future GOARM work.
6e70577 to
9ba511d
Compare
|
Addressed the remaining FennoAI informational note in 9a11290: the resolved GOARM value now reaches the native clang/linker triple and Plan 9 assembly module triple, while named targets keep their configured triple. Focused crosscompile, Plan 9 assembly, build, SSA, and vet checks pass. I will request a final re-review after the current CI and Codecov uploads finish. |
|
@fennoai All checks now pass on the current head, including Ubuntu/macOS tests and coverage, and the prior review threads have been resolved. Could you please take a final review? |
|
FennoAI is processing your request, please wait a moment... |
There was a problem hiding this comment.
Final review: COFF linking and Go architecture tuning
Re-reviewed at head ad3c7dd, focusing on the delta since my prior review (6e70577): 6 new commits touching 18 files.
All prior review findings were addressed:
- Dual-return (default + error) contract is now documented on
Resolve386/ResolveAMD64/ParseARM/ParseARM64(internal/goarch/config.go). - The swallowed
_errors inSpec()now carry an explaining comment about relying on Build-time validation plus the Go-default fallback for hand-builtTargets (ssa/target.go). - The repeated reset-then-resolve boilerplate is extracted into the
goArchitectureSettinghelper. - My informational note about
GOARMtriple tuning being unreachable is now fully resolved:GOARMis threaded through config resolution, fingerprint, child env,crosscompile.UseWithGOARM, andplan9asmtranslate options.
New changes reviewed and verified sound:
ParseARM(GOARM) — Go-compatible: ARMv5 defaults to softfloat, v6/v7 to hardfloat,,softfloat/,hardfloatsuffixes honored,GOARM=5,hardfloatcorrectly forces VFPv2 features. Covered byTestParseARM(incl. the invalid7,softfloat,hardfloatcase) andTestTranslateGOARMTargetTriple.meta: reject malformed package headers(internal/meta/meta.go) — solid hardening. Section-offset decoding now validates monotonicity (off >= prev), bounds (off <= len(raw)), 4-byte alignment, a minimum file size (< headerSize), and a minimum symbols-section size before readingnsyms. I confirmed these checks are consistent with the writer inbuilder.go(monotonic non-decreasing offsets fromheaderSize, section sizes are 4-byte multiples). This closes potential out-of-bounds reads on corrupt/truncated.metafiles.- COFF linker — the ELF-vs-COFF LTO-level asymmetry I noted now has the clarifying comment near the
--ltobranch.
Verification (this environment):
go build,go test, andgo vetpass for the pure-Go packagesinternal/goarchandinternal/meta(the packages carrying the genuinely new logic).- LLVM-cgo packages (
ssa,crosscompile, anything importingxgo-dev/llvm) could not be built here because the LLVM C headers are not installed in this sandbox — an environment limitation, not a code issue. Per the PR, Ubuntu/macOS CI (tests + coverage) is green on this head.
Conclusion: LGTM. No blocking or non-blocking findings. The architecture-tuning parsing, LLVM CPU/feature mapping, build-cache isolation, GOARM propagation, and Windows COFF linker behavior are correct and well-tested; the meta-header hardening is a welcome robustness improvement.
Note: I cannot approve PRs — this is a non-blocking review. A human maintainer's approval is still required to merge.
a43d0d5 to
801303c
Compare
|
The rebased head The delta since the prior reviewed head is limited to the dependency rebase plus aligning the Plan 9 assembly GOARM=6,softfloat expectation with the shared Go-compatible triple resolver. @fennoai, could you please re-review the current head? |
|
FennoAI is processing your request, please wait a moment... |
There was a problem hiding this comment.
Re-review: COFF linking and Go architecture tuning (rebased head 801303c)
Re-reviewed at 801303c. I computed the true delta against my last reviewed head (ad3c7dd — still reachable in the object store) rather than trusting branch names.
Scope note: the delta is a bit larger than "rebase + one Plan 9 test alignment." Alongside the dependency rebase and the GOARM=6,softfloat triple test fix, there are several substantive code changes, which I reviewed fresh:
New changes reviewed and verified sound:
- COMDAT for shared COFF definitions (
ssa/decl.go,ssa/abitype.go,ssa/python.go) — newsetODRLinkagehelper centralizes weak/linkonce linkage and, onGOOS=windows, attaches a COMDAT withAnyComdatSelectionKindso lld-link can merge the identically-named ODR definitions that COFF would otherwise reject. All priorSetLinkage(WeakODR/LinkOnce…)call sites are routed through it. This is COMDAT deduplication of same-named symbols and does not conflict with the earlier/opt:noicfdecision (which prevents folding of distinct functions to preserve Go's distinct-PC requirement). Covered byTestWindowsODRDefinitionsUseCOMDATandTestUnixODRDefinitionsDoNotGainCOMDAT. - crosscompile refactor (
internal/crosscompile/crosscompile.go) — extractedconfigureNativeTargetFlagsandnativeSectionFlags(goos); native-host behavior is preserved (Unix--gc-sections/-latomic/-lpthread/-ldlreproduced faithfully), and Windows now uses the same explicit MSVC/COFF configuration for cross builds vianativeHost || goos == "windows". The host-only clang-lib/rpath/macOS-sysroot block stays correctly gated behindif nativeHost. - Windows debug linker policy —
DebugInfoPolicygainsPreserveLinkFlags(/debug:dwarf) vsOmitLinkFlags(/debug:none);debugInfoLinkerArgsnow emits preserve-or-omit consistent with the compile-time policy, since lld-link discards DWARF unless preservation is requested. Sound. - GOARM soft-float triple (
internal/xtool/llvm/llvm.go) — ARM triples now emit-gnueabifor softfloat and-gnueabihfotherwise; the Plan 9 test (801303c) is aligned toarmv6-unknown-linux-gnueabiaccordingly. Correct. - meta zero-copy cache bounds validation (
internal/meta/meta.go) — a thorough validation pass added at theOpen()trust boundary for mmap'd, file-controlled bytes: uint32 size bounds, per-section CSR header/data sizes and record alignment, monotonic offset arrays starting at 0 and covering exactlynrecords, and all name references bounded within the string table. ThepackageMetaView/validatesplit lets the builder skip validation for bytes it just wrote whileOpenvalidates untrusted input — the right boundary. Fully covered by new negative test cases (invalid symbols size, truncated CSR header, count mismatch, descending offsets, offset-past-data, and invalid name ranges in all four name-bearing sections). ParseARM64goto→continue cleanup — behavior-equivalent.
Prior findings: all remain resolved (documented resolver contracts, Spec() fallback comment, goArchitectureSetting helper, GOARM propagation).
Verification (this environment):
go build,go test, andgo vetpass forinternal/goarchandinternal/meta(the pure-Go packages carrying the new parsing and hardening logic).- LLVM-cgo packages (
ssa,crosscompile,xtool/llvm) can't be built here (LLVM C headers absent in this sandbox — environment limitation only). Per the PR, the full CI matrix is green on this head: LLVM 19 Windows host smoke, Go 1.26.5 / 1.24.2, Linux/macOS coverage, benchmarks, and release artifacts, with 99.69% patch coverage.
Conclusion: LGTM. No blocking or non-blocking findings. The COMDAT emission, crosscompile/debug refactor, GOARM soft-float triple handling, and the meta bounds-validation hardening are all correct and well-tested.
Note: I cannot approve PRs — this is a non-blocking review; a human maintainer's approval is still required to merge.
801303c to
4711da5
Compare
4711da5 to
a899147
Compare
Part of #2325, the MSVC-first Windows support proposal.
Depends on #2327, which establishes the MSVC target triples and native Windows host smoke foundation.
Summary
/errorlimit:0,/opt:noicf)/opt:lldlto=0..3), enable per-function/data sections, and use/opt:refGO386,GOAMD64,GOARM, andGOARM64with Go-compatible defaults, valid values, extension ordering, and diagnostics-targetconfigurations unchangedLLVM mapping
GO386=sse2preserves the existing Pentium 4/SSE2 baseline;softfloatenables LLVM software floating point and disables SSE/x87 floating-point instructionsGOAMD64=v1..v4maps to LLVMx86-64,x86-64-v2,x86-64-v3, andx86-64-v4GOARM=5/6/7selects the matching ARM ISA;,softfloatand,hardfloatselect Go-compatible floating-point behavior, including ARMv5's soft-float defaultGOARM64=v8.0..v9.5maps to the corresponding AArch64 architecture feature;lseandcryptoare propagated, with LSE enabled automatically from v8.1 as in GoThe architecture environment parsing is shared by native operating systems because these are Go architecture semantics, while the COFF linker translation remains Windows-specific.
Scope
This PR covers native target configuration and clang/lld flag generation. It does not add the Windows runtime, SDK discovery, FFI, C ABI, GC, goroutine, panic/recover, or debug backends.
Because this is stacked on #2327, GitHub will temporarily show the foundation changes in this PR diff until #2327 merges.
Validation
go test -cover ./internal/meta ./internal/goarch ./internal/xtool/llvm(internal/goarch: 98.3% statement coverage)go test ./ssa -count=1(full suite, 162 seconds on the current head)go test ./internal/build -count=1(full suite, 339 seconds on the current head)internal/buildtests cover explicit/default/environment values, child-command environment, invalid values, and cache separation for all four architecture variablesssatests validate LLVM CPU/features and emit real objects for 386 soft-float, amd64 v4, ARM soft/hard-float, and ARM64 v9.5+crypto target machinesgo vet ./internal/meta ./internal/goarch ./internal/xtool/llvm ./internal/crosscompile ./internal/plan9asm ./internal/build ./ssa/opt:lldlto=2The PR is Ready for review. FennoAI found no blocking design issue; all review follow-ups are addressed on the current head.