Go 1.28
mapsplitgroup by default. SSA package split into ssacompile and others. ARM64 SVE. The size-specialized-malloc flag is removed. Wyhash for small keys. Inlinable recover callers. Composite-literal type elision in progress. string(int) restricted. Linux perf profiles accepted for PGO.
Each area lists the stage every thread reached in this release (with what was left open afterwards), then changes that are not part of a thread. Thread names link to the full thread on its topic page.
Memory management
From Runtime: memory allocator and garbage collector (Go 1.18–1.28)
- Green Tea: span-based marking with vector scan kernels — Done: the benchmark now cycles random object masks (
27f1d81f7d). Left open: experiment flag not yet removed. - mallocgc decomposition and size-specialized malloc — Done: user-visible the GOEXPERIMENT was deleted, leaving the
sizeSpecializedMallocEnabledconstant (4a7645b730), plus ASAN dead-code cleanup (8a92448bc2). Left open: nothing noted. - Finalizers, runtime.AddCleanup and the cleanup queue — Done: cleanup argument layout uses the static
abi.TypeFor[S], fixing interface arguments hidden as noscan on 32-bit (c456de74b8); a faster specials-list walk (Finalizer −1.2%,1c72b3d2c1). Left open: nothing noted. - Weak pointers and the unique package — Done:
unique.Makeexample (232c9e1160). Left open: nothing noted. - Object pinning (runtime.Pinner) — Done: atomic stores instead of RMW (
91fa326dfe), skipping redundant bit updates (a69abce146), setting the specials bitmap only for the first special and skipping sweeper registration for swept spans (PinUnpinWithGC −32.5%,7d93750c51), per-span unpin batching (d6eb7bd6ae), a shorter specials lookup (1c72b3d2c1), per-P pin-counter cache (3544f81e5d), and no system-stack switches, since pin bits no longer depend on the heap lock (3017a6ec16). Left open: nothing noted. - Sweeper termination and pacing — Done: replacing
finishsweep_m’s sweep loop with a throw (5df35d3ce5) was reverted, because concurrentgcStarts can leave unswept spans (9684147f09). The reasons are now documented (8e0e1f7e99). Left open: #81957 remains open. - Stack and register root scanning — Done: register save blocks are no longer zeroed, since
xRegSaveoverwrites them before publication (8f71bead49);clobberdeadon loong64 (2c3e97ac68). Left open: nothing noted. - Address-space layout, tagged pointers and the mem.go layer — Done: openbsd/arm64 corrected to 39 address bits (
3a5e97de8b). Left open: nothing noted. - Heap base address randomization — Done: the prefix mask was misaligned by up to 2 bits, so in ~75% of launches hints collapsed in pairs or quads; fixed (
fb8616482c). Left open: nothing noted.
Scheduler and concurrency
From Runtime: scheduler, timers, channels, locks and synchronization (Go 1.18–1.28)
- Timer rewrite: per-P timer heap, timer.lock, and GC-able synchronous timer channels — Done: user-visible
time.Timer/Tickercopy detection (init bool replaced by self-pointer;f6ddbafcf0); delivered-time delta recomputed from a fresh clock just before send (277635b979); channel polling avoids duplicate timer checks and needless clock reads (713b754c97,737d626d12);timers.verifystale check removed (eab6938192). Left open: nothing noted. - Scheduler core: spinning Ms, work conservation, stealing, STW interaction — Done: spinning Ms don’t commit to a
runnextsteal if a STW became pending during the sleep (a22b5bf6c5, #81657); async-preemption signals sent outsidesched.lockinforEachP/stopTheWorldWithSema, avoiding a pile-up of Ms sleeping onsched.lock(b5bbf5b660);worldsemaasserted inforEachPInternal(14c1cd3e46); safe-point requests re-checked inexecute(BenchmarkAllocation -8.6%) (5336092116); preemption retry delay starts after each attempt and missed retries when pausing goroutines fixed (480af5e85a,d4fc38b7b6). Left open: nothing noted. - GOMAXPROCS container awareness and dynamic updates — Done: only the root of cgroup mounts is validated (
f91a6faead). Left open: nothing noted. - testing/synctest bubbles — Done:
synctest.IsInBubblemade inlinable when no bubble exists, sinceWaitGroup.Addcalls it (ace5a7527c). Left open: follow-up CL not to usesync.Poolwithin bubbles referenced. - Asynchronous preemption: extended register state — Done: AVX saved even without AVX2 (
674806dda3); save blocks no longer zeroed (8f71bead49). Left open: nothing noted. - sync package API evolution — Done:
Pool.Getonly clears the private slot when non-nil: PoolGetEmpty/P=10 23.1ns -> 2.6ns (-88.8%) by avoiding cache-line contention with stealing Ps (d461d8f704). Left open: “sync: don’t use Pool from within synctest bubbles” in progress (referenced byace5a7527c). - sync/atomic and runtime atomics — Done: riscv64
Xaddint64return fix (3b98eddbcd). Left open: nothing noted. - Netpoller — Done: 32-bit eventfd type confusion fixed (
b9ba134da6). Left open: nothing noted.
Other changes
- Misc internal —
leaveinstruction on AMD64 reverted (56d7cfd457,ebdf81fda7);align128marker (c2dcde178d); plan9 low-res timer (d2d6d44095); caller frame pointer inmstart1(2c081ba80d); pinning avoids stack switches and caches counters per P (3017a6ec16,3544f81e5d).
Data structures and type metadata
From Runtime: maps, built-in data structures, hashing, randomness and type metadata (Go 1.18–1.28)
- Swiss-table maps (GOEXPERIMENT=swissmap → only implementation) — Done:
mapaccess2inlined intomapaccess1by raising the inline budget, because the wrapper cost showed in synthetic benchmarks (defa1f0155; ideal of inliningmapaccess1at the call site judged hard since calls are introduced in walk, after inlining). Small-key hashing switched from AES to wyhash belowMinAeshashSize(c9e4a2aa07,b751a977cb; see hashing thread). Left open: latency-vs-throughput cutoff for arm64 (go.dev/issue/80970) noted inb751a977cb. - Map hashing and hash functions (memhash, aeshash, fallback hash) — Done:
UseAeshashreplaced by a tunableMinAeshashSize: very small keys use wyhash because AES SIMD “does not like being used for one-offs”: cutoff 8 bytes on Zen 4 (MapGroupBy, HashInt64Speed -10%, MapAccessMiss/int64/len=65536 -10.9%) (c9e4a2aa07), 16 bytes on Apple M1 Max (b751a977cb: Hash5 -41%, MapGroupBy/int64 -65%). Interface hashing now folds the dynamic type’s compiler typehash in soint64(0)anduint64(0)in interfaces no longer collide (40e7643c46). Left open: cutoffs for other microarchitectures (Intel steppings) are said to be easy follow-ups; latency cutoff of 192 on arm64 unexplored (issue 80970). - Compiler-generated equality/hash functions and type descriptor emission (reflectdata) — Done: subroutine-based eq/hash for large types (
16516099d7), noalg/alg dedup and its fixes (8fc7e76411,925ef8c02c,f3e4f788ed,4400f9ad36),writeTypesymbol reuse (7ea76879d2), cleanup ofcurfuncnaming in reflectdata (d5f5390d0d). Left open: signature names remain large (“The signatures themselves (and their names) are still pretty big”,16516099d7). - reflect implementation: performance, allocation and escape behaviour — Done: method
Valuerepresentation reworked: previously (receiver, method index, special flag) with lazy conversion to a func Value onInterface/Convert, which flowed the Value to a heapmethodValueand made those operations escape their receiver; now the func Value is created eagerly, and the receiver+index are stored in themethodValueclosure soCallkeeps its fast path (creating a method Value costs an allocation, Call unchanged) (3ebc191975, withc78af9ddc8improvingValue.Setescape);MethodByNameavoids building a fullMethodviaFuncOf(1a1b710b4c, motivated by text/template, e.g. Gitea’s ~4,700ctx.Locale.Trcalls),a795dd2918; embedded reflect types extracted before use (cff61723f3);SetIterKey/Valuetemporaries without map flags (d9377b86ee). Left open: nothing noted. - memmove / memclr / memequal / internal/bytealg assembly optimisation — Done: arm64 indexbyte algorithm (
5afcc450ee), compare 32 bytes per iteration and NEON for large inputs (e24c7a6508,ce608609c1), small-sizememequalrestructure (916488f43a), loong64 LSX for 33..64-byte memmove (55d79d1e8a), SIMD arm64 memmove (91aa6bb390) reverted a month later (dac9fe5ea9, named-register cleanupb6c48d70caretained). Left open: arm64 SIMD memmove needs redo.
Diagnostics and knobs
From Runtime: tracing, profiling, metrics and diagnostics (Go 1.18–1.28)
- The new execution tracer (trace v2): generations, per-M buffers, new parser — Done: test-only deflakes (
a300e279c5). Left open: nothing noted. - Mutex and block profiles, including runtime-internal lock contention — Done: deflake (
aa194b3f68). Left open: nothing noted. - CPU profiling, goroutine profiling, pprof labels and the protobuf writer — Done: stop logging an error when CPU sampling rate is already set (
2482f9c242); synthetic mappings for WebAssembly profiles (412f013cf8); reject dangling location IDs ininternal/profile.Parse(93a285f2bc). Left open: nothing noted. - Race detector, ASan, MSan and Valgrind integration — Done: loong64 MSan label spelling fix (
45c2e35625). Left open: nothing noted.
OS layer, stacks and panics
From Runtime: OS and platform layer, stacks, panics and tracebacks (Go 1.18–1.28)
- Defer, panic and recover re-implementation — Done:
nextFramematches the deferring function when searching for linked defers (02e6c32a4b). Left open: nothing noted. - Frame pointers: explicit NOFRAME, FP maintenance and FP unwinding — Done: FP cleared before calling C on riscv64 (
163abc10f3); FP adjustment fixed around injected calls (async preempt, sigpanic, debugger calls), including arm64’s 16-byte gap (40fd497af5). Left open: nothing noted. - Stack growth, stack bounds and the crash stack — Done: stackcheck implemented for riscv64 (
e68a67f6de) and removed from openbsd/riscv64 (d50f3c4fa8). Left open: nothing noted. - C-to-Go callbacks: extra-M reuse, system-stack bounds, init gating — Done: C-function indirections restored in
runtime/cgobecause direct text references broke-Bsymbolic-functionsc-shared builds (29a8492160); Windows preemption synchronised with G status, removingpreemptExtLockand a CAS/store pair from every cgo call (CgoCall −23% on windows/arm64,12c76d447f); pthread attrs destroyed (17d7bdecd0). Left open: nothing noted. runtime/secretand data-independent timing (DIT) — Done: secret enabled on loong64 (a133902362); test fixes (0bd978d532,ef2746c488,0400d6f9f6). Left open: nothing noted.- vDSO,
vgetrandomand fast clocks — Done: vgetrandom on riscv64 (e58ce6c835),riscv_hwprobevia vDSO (21167589a8). Left open: nothing noted. - Signals and async-preemption machinery — Done: ARM64 SVE preemption (
5e6be730dc), AVX saved when !AVX2 (674806dda3), darwinSA_SIGINFOfix (af83819064), riscv64 libc sigaction (61b0b6dd84), sigtramp ABI fix (d0eb91559a), Windows exceptions below goroutine stack crash (d58290fefd), Plan 9 fault address (90e5fac216). Left open: nothing noted. - Windows runtime port — Done: loader TLS (
35b807d2fc), precise monotonic clock (16d46baf6f), preemption/G-status sync (12c76d447f,0042b271db), system-stack thread creation (9a5f58afaa), exception below goroutine stack crash (d58290fefd), pipe I/O isolation (df3fe0b700, revertedc3a068eec9, restoredcb8219a071), profiler timer fallback (0d37007fda). Left open: nothing noted. - New, ported and removed platforms — Done: riscv64 vgetrandom, libc sigaction, stackcheck (
e58ce6c835,61b0b6dd84,e68a67f6de). Left open: nothing noted. - CPU feature detection, GOAMD64 checks and cpu GODEBUG options — Done: SVE2 on arm64 (
e077557cfb), RISC-V VLENB (2ba7d6096c), ARM64 on ios (8058a57773), AVX+ disabled on netbsd/amd64 (b6b368adc5), RISC-V GODEBUG restriction (aafcf7a2b8). Left open: nothing noted.
Other changes
- Misc internal —
mach_vm_region_trampolinearg fix (1b99a8da6c), AIXtstartcallee-saved registers and message (76ba5bf217,a5ae3a45aa), Plan 9 cancelling note (6c56350831),EpollEventsync (1190f7d1da), LSX register-erase fix on loong64 (b656fdc3c3), riscv64 CALLFN word copy (4fae1a9df9, CallArgCopy 4096B −72%). - Plan 9 cancelling note, ios working dir user-visible — keep cwd for non-bundled ios/arm64 binaries (
16e9662592, port47cc60743b1.27 in 1.27),usleep/notetsleeptimer-slack measurement (53d7fa8112),internal/cpuRISC-V VLENB and netbsd AVX disable (2ba7d6096c,b6b368adc5), X15 fully zeroed (3f1287d96a).
Compiler frontend · types2
From Compiler frontend: the types2 type checker (Go 1.18–1.28)
- Type inference and unification — Done:
49c3ea6464unification should never see nil types; target-type threading (see “Composite-literal elision” thread). - Language features as seen by the type checker (by release) — Done: user-visible
f095da59e4string(x)for integer x only permitted if x is byte or rune typed, or an untyped rune constant (“starting with Go 1.28”, #3939), withconstConvertibleTomade an operand method. - Composite-literal type elision via target types (#12854) — Done:
17810c616f,54539e7c9e,c7abbff510,73bc5e8ef6(struct literals),c33ea07d92(function calls),d87b733482(target may hold any type),b0434e1e9a(target.sigreturns Type),f1220f3337(delete),08a51e4d9b(append),96ef5b334c(copy),205624aac7(switch),430d19f07a(comparing an untyped composite literal with a typed operand flows the other operand’s type in). Left open: both-untyped or neither-typed comparisons fall back to the usual mechanism (430d19f07a). - Error reporting: codes, messages, and sub-errors — Done:
28a19a0327consistent overflows/truncated messages;c8abe73eb7oversized non-constant shift counts (case ordering bug: the untyped-constant case was shadowed);cd46a98014,2c02670704. - Sharing code between go/types and types2 — Done: the “remove tech debt” series (4 commits) plus
55f39ab788,0446ca4652,a89a200850,de246da3f3test cleanups. Left open: nothing noted. - Checker performance, memory and API ergonomics — Done:
8002a0da7c,6446eeb686,eeaa094535parallel tests. - Robustness: invariants, incomplete types and importers — Done:
b98d22c17f,de3b79e425,201f360765,be104ed62f,8a856e477e,ac059878bc,49c3ea6464,6939463d82. Left open:8a856e477esays “a second CL will swap out the existing types2 importer for this one”.
Other changes
- API user-visible —
f176f5e1a3NewTypeParamList,NewTypeListin go/types,e5f7ecd00edocumentsInterface.Methodorder. - Small fixes, unifier/assignment refactors, message and tracing tweaks internal — 1 commits:
19238528a8
Compiler frontend · syntax, IR, generics
From Compiler frontend: syntax, IR, unified IR and the generics implementation (Go 1.18–1.28)
- Unified IR: one serialization for noding, stenciling, inlining and export — Done: package docs (
5128514a6b); V5 export data (method indices) because V4 “encoded nongeneric methods followed by generic methods, losing source order… breaking objectpath, causing crashes” (fc987b55b9, reverted54ace3ff80, reapplied00a007d7b9);testimporterfork removed (900796a858,27a8868bc2); “p” export format preparation forGOEXPERIMENT=golistexportnewformat, default-off (528579ad20). Left open: “p” format not enabled. - Old typechecker and IR node-model cleanup — Done:
ir.CurFuncand the typecheckfuncStackeliminated: functions are injected as parameters (066f73ad47,6fb3b12e3d,65e7b09d38,cfd344d46b; WithFunc renamed WithPosc458b06048);base.Posis saved/restored where set (dfc6f7db9b,f9f805aa29,5be815fece) with the stated goal thatbase.Posvalues map to subtrees of the compiler call graph;Diagfwithout positions (fcb91c57fc); IR fields freed after each function compiles (d86dd2ed4f, -30% peak memory on aws ec2 package: 2.7 GB -> 1.9 GB). Left open:CurFuncremoval is tracked as #19683 (ongoing);base.Posstill global. - Generic methods (type parameters on methods) — Done: fixes: OMETHEXPR construction (
fdb1ba1325), alias-receiver qualification (ea7d327c80), shared-wrapper receiver qualification (61b3e65bd2), V5 export data (fc987b55b9). - Static initialization and package init — Done: synthetic init splitting reapplied (
dc72b71db0, reverted2b80068e2e, reapplied31ce17fe80); offsets >= 1 GiB (LSym limit) routed to dynamic init (dd612356d8);41cb39b794movesAnySideEffectstoir;5aaedc8a79(huge param offsets ICE). Left open: the repeated revert/reland of init splitting indicates correctness problems were still being worked through. - Compile-time performance, concurrency and the self-PGO’d compiler — Done: functions ordered by IR node count instead of top-level statement count (
6e88b3b4b6, Compiler -1.6%, SSA -2.1%); IR memory freed after each function (d86dd2ed4f);sync.WaitGroup.Go(2a74f63764); export data written before compiling function bodies so dependents can start sooner (ebe2feefc4,bcd5def4bfpreassigns symbol indices,ffee23ff7cnew-exportfdflag where the compiler writes a byte to an fd andcmd/gounblocks dependent compiles; fixes #15734) Left open: nothing noted. - Compiler debugging infrastructure: bisect/hash debugging, flags, dumps — Done:
-d=ssa/phase/@keyword=value(bef396c339), ssa html flag (6b0a207525),b13887b154compiler statistics package with a pointer-demographics pass. - Frontend support for new language features and spec changes — Done: user-visible untyped composite literals (
a3edc4c682syntax, test cases7ccdc93ad4),recoverworking in a range-over-func loop body (dba926f240), blank second range variable skips evaluation (dd5f863870),reflect.Value.Methodmarking (d8fec91a72). - The syntax package (parser, scanner, tree) — Done: untyped composite literals (
a3edc4c682), empty declaration group (72b8727aa8), NUL byte after buffer refill (452f3ea690),source.segmentreturns string (a8d1c0e823), scanner ident simplification (2c3abb202a). - Package paths,
-p, and build-system contract — Done:-Iand-importcfgmutually exclusive (85e6f00798),-exportfdand early export data (ffee23ff7c,ebe2feefc4). - Types package internals: size, algorithm kind, TFlag, SIMD flags — Done: SIMD flags stored in the
Type.flagsbitset (f0c78119ea),align128marker (c2dcde178d),abi.Type.TFlagloads constant-folded against the static type (7e9c70ae99; first attempt86eb9afa8creverted21ae06fe28), withMethodsComputedbit assertingCalcMethodsran;75f2c467f6keeps memory ABI for SVE mask types throughSetUnderlying. - Method wrappers and promoted-method sharing — Done:
f534300f98shared promoted wrappers. Left open: nothing noted. - SIMD frontend: the “midway” source-to-source translator — Done: fixes: ICEs with shared emulation selectors, range clauses, blank/unnamed params, zero values (
4ea26e6624,898e19087e,84fe05b3ae,d61b240b11,ad04d4de84), variadic forwarding (f51739cf2a), Midway docs (77a63bd811). Left open: SVE/arm64 mask ABI problems fixed ad hoc (75f2c467f6). - ir.StaticValue, ReassignOracle and function-variable tracking — Done: RHS nil in static value (
f192b5be2e).
Other changes
- Closure/method indices recorded before encoding internal —
1d1187a126preassigns indices for closure-variable types,2c3c1caad2records method indices before encoding a named type, groundwork for export-early (bcd5def4bf). - Result slot reuse internal —
rewriteresultsreuses result slot for a returned local (46eafb392d), across multiple returns (cd33533039), partial (dd8aa2845b). - Function ordering internal —
6e88b3b4b6. - Closure internal — avoid closure for captured dynamic constants (
8ba5076b90), b.Loop keepalive cleanups (903c4c08b0,412d6e161f). - String temp buffer internal — 64 bytes (
af26c13f95). - Inlinability tweaks internal —
slices.BinarySearchFunc(0adda8abb7),sort.Find(2589b1c420). - Generics: dictionary/shape fixes in the stenciler (1.28) internal — fixes in dictionary passes for type assertions, comparisons, switches, nested instantiation packages, and recursive generic interface instantiation (
67c1d42116) - Housekeeping (1.28) internal — dead-code removal, ioutil/seek/slices/atomic-type replacements, README edits, debug-flag removal, assorted small bug fixes and doc comments (
aa9e10cf48,d61f6c98a9,a6bdeaf6a9)
Middle end and SSA optimizer
From Compiler: middle end and SSA optimization (Go 1.18–1.28)
- Profile-guided optimization (PGO): hot-call inlining, devirtualization, profile preprocessing — Done: user-visible
FromPProfaccepts CPU profiles from external tools such as Linux perf viaperf_to_profile. When the value names differ from Go’s (for examplecycles_event/count), it takes the CPU-like sample column (3bd19c1c39, #64489). Left open: nothing noted. - Inliner: budget, closures, and the interleaved inline/devirtualize driver — Done:
- user-visible Functions that call
recoverbecame inlinable (0977a589b4). mapaccess2is inlined intomapaccess1ininternal/runtime/mapswith inliner support (defa1f0155).
- user-visible Functions that call
- Escape analysis: call modelling, closures, func-variable callees, and solver speed — Done: the queue reuse (
ab4ad11bad), immutable diagnostic paths (e78076d579) and walk coalescing (372c766cdd) described above. Left open: nothing noted. - Allocation avoidance: stack-allocated slice backing stores and allocation-free literals — Done:
- A slice whose element interior escapes through
&s[i].fis no longer stack-allocated (2b9e6788d4, #81612). - Non-escaping appends are not given a
move2heap(5391dd543a, #82126). make’s length-before-capacity evaluation order is preserved when rewriting with literals (d98516a9d2).makeslicecopywas extended beyond simple non-address-taken variables (98ef86b779).
- A slice whose element interior escapes through
- New inliner heuristics (GOEXPERIMENT=newinliner,
inline/inlheur) — Done: a nilcurfuncis passed during analysis (c0c6468861). Left open: the experiment is still off by default. - Prove pass and bounds-check elimination: from poset relations to a dense limit table, topo-sorted walk, and division-aware proofs — Done:
- Constant-delta additions (
8ee6c488c2). The induction-variable minimum is visible in its block (6547138e2b). - Signed↔︎unsigned limit propagation (
13a7b71d85). Unused poset unsigned machinery removed (0c0dacdf0b). - Time-traveling proofs fixed (
a595f29385). Slices of the same length are added later (f85791f6df). (x+y)-x == yand related identities (4d9381e946).Const64for 64-bit slicemasks (395f4f5e3f).IsInBoundsRsh bit width (d9884eed65).convertIntWithBitsize(12a1a35032).- Direct jump-table branches are not scanned (
9383561a67).
- Constant-delta additions (
- Known-bits pass (bitwise constant folding) — Done:
- Dead values are optimized when debugging (
548c25ea38). - No-op
And/Orare removed (4f21e8a963,8213feb422). - The toposort is shared with prove (
4b45efba20,fc44886932). On tsgo,fc44886932measured 491.3s versus 492.7s on master.
- Dead values are optimized when debugging (
- Memory-op optimization: memcombine, dead stores, store-to-load forwarding, alias analysis, mem2reg — Done:
disjointusesStoretypes (5e18e24123).- DSE handles
CondSelect(00ba484362). - Whole-copy loads are forwarded through
Move, including offset 0 (bfc0f5497b). - riscv64 memcombine requires alignment (
58e8638c80). - The
mem2regpass (59b9e2dc57); promoted variables loseaddrtaken(18d746bc25).
59b9e2dc57says it handles only variables whose loads and stores sit in one basic block; “a later CL extends the analysis across blocks with phi insertion”. Some edge cases are “not handled”. - Lowering of builtins to memory ops: memmove/memclr/memequal inlining and generated equality — Done: constant-size equality with 32-bit
Const32lengths (8aec6766e9, #63131). Left open: nothing noted. - Stack-slot merging (mergelocals) — Done: only address uses known not to propagate the address are accepted; any other use aborts merging for that local (
06bc6592c3, #80127). Left open: the message calls this conservative, with tracking “uses of uses” as a possible refinement. - Switch lowering: jump tables, type-switch caches, and switch lookup tables — Done:
- Lookup tables support assignments (
36042fe95b). uint64indices are truncated for imm8 jump tables (b590fd1075).- Prove skips direct jump-table branches (
9383561a67). Switch statement positions fixed (2a2f42823b). - Jump tables on riscv64 and mips (
8e35b7dc52,c8337c9bb2,84ee19cf1a).
- Lookup tables support assignments (
- testing.B.Loop support in the compiler (bloop) — Done: switch case expressions are not rewritten (
412d6e161f). Compiler#-names are removed from keepalives (903c4c08b0). Uses ofir.CurFuncwere replaced (611b566506). Left open: nothing noted. - Range-loop and range-over-func lowering in walk — Done: range-clear is avoided when the target depends on the index (
505c369188). An ICE on range over an unsigned constant ≥ 2^63 was fixed (0564ffd5f2, #82234). Left open: nothing noted. - Loop-invariant code motion (licm) — Done: arm64 regalloc preloads multi-instruction constants (MOVD+MOVK) before loops when a register is free (
addee8c213), since regalloc never preloaded rematerializable values. Left open: nothing noted. - Branch-free lowering: CondSelect-into-math and ARM64 CCMP — Done: pow2 Or/Xor enabled on amd64 (
3c2bdfff47), always for powers of two (3e6ad2cd0a); fix: do not rewrite IF to CMOV if argument instructions cannot run early (2bc055441f). - ARM64 load/store pairing (LDP/STP) — Done: NEON loads/stores paired (
3e6eb83f95); regalloc spill/reload STR/LDR fused into STP/LDP in a finalSSAGenFinishstep (aa5fc60a63). Left open: nothing noted. - SSA package decomposition and compiler-infrastructure refactor — Done: all of the above (~45 commits). Also post-regalloc strict SSA is re-established with inserted phis, allowing dead-code elimination after regalloc and trimming 11,937 dead restores over std (
4cff6b2647, motivated by #74365);IterDomFrontierPlusextracted from the Sreedhar-Gao phi walk (d46cdb752b,98ea765140,a0fa72258f); per-value debug data and CSE memory args in HTML dumps (b60817a581,2cf686292a); compile-speed items: value slice forFunc.Names(e7d8668a6a), no heapLocalSlot(d3c517908d),sparseSetinliveValues(38630629d9). Left open: refactor ongoing.
Other changes
- Misc internal — riscv64 shift-extension cleanups (
6a4ff9ce36,5a6340ff28),int(!bool)^cfold (4a7dfbfa38), 32-bit rotate amounts (6b3800e1dd), regallocuniqueRegssync (769dcc296c), ssa check mode SizeAndAlign (7f9af814e1),base.Possave/restore (dfc6f7db9b), tail-call wrapper interface-call marking (78407c1122), SIMD nil checks and zero-block placement (54649710ed,d61b240b11), logopt with -trimpath (e0ecd48a28), pair NEON (3e6eb83f95). - Rule/lowering additions internal —
x-(x&y)→x&^y(1008f900f6), bits.Mul64 strength reduction and bits constant folding (33b70e98de,5bec0d2b8f,61d964eff9), OrB/AndB folding (88a5dddc7e), reassociationC*(D*x)andx+(y-(x-z))(13f61f0518,82a8bf1e2e), zero-comparison canonicalization (e3ba9f96d2), ZeroUpper*Bits coverage (e8c07b9708,9f3cf13d78). - Static data sharing internal —
staticuint64ssharing generalized to integer constants in [0,255] of any width (ee64db65cf); string temp buffer raised to 64 bytes (af26c13f95); no closure for captured dynamic constants (8ba5076b90); no temporaries for float-division call args (d060863557). - Write barrier internal —
wbMoveABI optimization removed as unsafe (f23bcc2fa7). - SIMD/SVE register allocation internal — K-register masks on amd64, SVE predicate regs and RegMask, cpufeatures pass recognizes GOAMD64 features (
a5ef336780,7f51efb674,bc769ea44b,0b2fd4aa9c,fbea197d32,d61b240b11). - riscv64/loong64/mips64/s390x internal — shift/extension cleanups, rounding and atomic And/Or intrinsics (
77fb1abefe,78c9eae8ee,603439a1c6,286c7389e9,85ec0589e2,026391c1b9); large riscv64 move/zero fix (5c1ad454f5). - Fixes internal — fuse not removing edges with live phis (
b5bc8baf3c), rewrite cycle in dead code (6ab4df6612), tail-call racefuncexit (cd6dd4ce34), tighten not moving InitMem (9823ced63e), splitPtr analysis (b9301d4823), canMergeLoad visited tracking (a58be5b52d).
Backends and assemblers · architectures, ABI
From Compiler backend: architectures, register allocation, ABI and assemblers (Go 1.18–1.28)
- Register-based calling convention (ABIInternal) ports beyond amd64 — Done: SVE register-argument morestack spill offsets fixed
3e62cba7ac;clobberdeadon loong645d4666bcda; separate pointer vs register widths564f7d071a. - Register allocator, scheduler and block-level backend passes — Done: free “doomed” registers at loop headers
be79f93983;RegisterSetwidened tossaop.RegMask966c78ed74; HI/LO special register handling removed from regalloc for mips (mul/div results no longer homed there)af4b02c461,6db72bb92b; break false dependencies for BSF/BSRca9c560a43. - amd64 code generation and GOAMD64 microarchitecture levels — Done:
LEAVEinstruction for Go-compiled functions (retried after revert; distpack −0.79%, code −2%; asm functions keep arithmetic restore since users may scribble on BP)56d7cfd457,ebdf81fda7,38b5f91aa5, extended to ABIInternal asm3d45c38896, breakage on ABI0 NOFRAME fixed4c06723736, excluded on plan9d6bec360b3;bits.Mul64→ MULXQ at v3 (flag-free, interleavable with ADCX/ADOX)4dfb312b5f;x*y-z/x-y*z→ fused multiply-subtract at v3fb355d8a3c,88a3e6202a;x±carry→ ADC/SBB0a6ccc557a;LOCK ADDinstead ofLOCK XADDwhen sum unused,LOCK SUB,LOCK INC/DEC(030734422d,b0197759ac,61154e8998); sub-word read-modify-write folded ({ADD,AND,OR,XOR}{B,W}constmodify)ee74f99276; X15 for 4/8-byte zero stores7ecd9096a2; float min/max branch idiom → MINSD/MAXSDf9de8c0900; VEX encodings for zero/move/spill when AVX presentc2f76b656d,5763a306d2; magic-constant 32-bit unsigned div by pre-shifted constant1b0e91bf6e; -buildmode=pie on openbsd/amd648b3ed8a068; endbr64 (1.25)04de448c6d1.25. - arm64 code generation and assembler — Done: SVE archsimd support in the compiler (
68f391a3c2, broadcastdfbb9da7ff, mask First/All/Nonead2488e65c,8a2ef7eb43,9bdbfc8fa5, predicate zero276175b8fe, Broadcast+Mask peepholee76a7d23eb, callerSave70c31c1f4f); spill/reloadSTR/LDRfusion intoSTP/LDPas the last step of code generation via a newssagen.ArchInfo.SSAGenFinishhook (the SSA pair pass runs before regalloc and cannot see spills; second Prog becomes ANOP)aa5fc60a63; byte compare vs 128 → TBZ/TBNZ197b975aee; redundant byte/halfword zero-extensions stripped5de5a2ec8a; CASPA/CASPAL/CASPLc122d7e6c5, LDSMAX/LDSMIN/LDUMAX/LDUMINb553a7cb8a, VSMOVb01fe21278, ID system registers601d28a5b0, large offsets in load/store pairsb3f5034b15; miscompile: noov InvertFlags at min int — the optimization was unsound since its inception (CL 233097), so asymmetric comparisons are no longer folded607cfcea17. - riscv64 compiler and assembler (RVA profiles, vector, compressed) — Done: crypto vector suites Zvkg/Zvkned/Zvknh/Zvksed/Zvksh
0b02c60612; compressed branches, returns and known-immediate jumps7496531e00,e5ec1263ca,46f508b3aa; jump tables8e35b7dc52; atomic And/Or intrinsics78c9eae8ee; math rounding intrinsics77fb1abefe; bit testsa4485949ce,91d55590e6; SLLW for Lsh32603439a1c6; multiply-by-constant0485478d9b; single ADDI for load/store offsets and unified split point1f162b7286,689cdf4cda; MOVDnop removeddeab4989e6; rva23u64 feature macros documented4472de41fd; large move/zero fix5c1ad454f5; sign extension of unsigned values no longer elided incorrectly10a908733a; vector DWARF regsa89c2ff8a3. - loong64 backend and assembler — Done: unified OpCode definition and register aliases shared with the linker
e83070192e; zero-upper-bits made a declared op attribute (e8285ccd6e,1ba085ec21) plus redundant extension removal (286c7389e9,a1b734e408,a4bac74d2a); floating-point comparisons absorbed into branches384cf71367; mask comparisons69b2918247; offset+base lowering38f24c5c46; ibard7e269d1ac; preprocess/stacksplit/WORD implementation optimized (4b590865d7,9350068b23,29ceccda77,143c05549f); vector encoding fixes. - Late-lower pass, memory-op combining and arch-independent rule migration — Done: rewrite rule clean up
b5ff81cdbb, multiplication reordering54bae9bf84;x-(x&y) → x&^y1008f900f6. - Stack slot merging, liveness and stack maps — Done: mergelocals address-use analysis tightened
06bc6592c3, fixes for arm32/s390x/riscv645d5c7ff1f0and mips3a171a2aca. Left open: nothing noted. - Prologue, frame pointer, stack split and function alignment (cmd/internal/obj) — Done:
LEAVEon amd6456d7cfd457/38b5f91aa5; fixes for ABI0 NOFRAME BP expectations4c06723736. - Jump tables for switch statements on more architectures — Done: riscv64
8e35b7dc52, mips64xc8337c9bb2, mipsx84ee19cf1a; common table-entry code403b3349ca. - Multi-word arithmetic, intrinsics and carry-chain support — Done: MULXQ at GOAMD64≥v3
4dfb312b5f; ADC/SBB generation0a6ccc557a. - Atomics and memory-ordering code generation — Done: riscv64
78c9eae8ee; arm64 pair CASc122d7e6c5; ppc64 atomics cleanup553ac454c2. - WebAssembly backend — Done: float min/max lowered to wasm instructions
4494c64f5a; fold redundant extensions26844c5113; avoid widening 32-bit import results9c8f4b0ab1. - s390x, MIPS, 386 and 32-bit ARM backends — Done: mips64/mips load/store simplifications
bcd794d277,e798729d8c; bounded shift on mips64x85ec0589e2; mips64le large pointer offsetsd52464487f; s390x VLER/VSTER/VLLEZab480527a3; s390x CMPUconst/SRDconst fix69fe0c724a. - Backend hooks for GOEXPERIMENT=simd (amd64 AVX-512, arm64 SVE, wasm) — Done: SVE (arm64 thread).
- SSA package split into subpackages (issue #80409) — Done: the steps above; Left open: “later once we split out most of the rest of ssa we’ll rename ssacore to the ssa package” (
9b32c1225c); name stutter (op.Op386ORL) to be fixed later (ef0bd1f8df).
Other changes
- stack object pointer-size alignment
5d29d80b6c; location-list structures made smaller6d79995d3b; descriptor flag preservation8fc7e76411; initialize large static offsets dynamicallydd612356d8; constant-size equality with 32-bit lengths8aec6766e9; forward loads through Movebfc0f5497b. - 3 small obj/riscv and riscv64 rules commits internal — e.g. cc: avoid zero extension when sufficiently shifted on riscv6; ssa: remove unnecessary masking with shifts on riscv64; obj/riscv: reject extra operands for jumps. (
6a4ff9ce36,5a6340ff28,5720ecd2c3) - 11 small ssa/regalloc/liveness/obj generic commits internal — e.g. cc: utilize regMask to use F31, vector regs; cc: use right shift to compute >= 0 and < 0; ssa: convert AVX integer multiply to shift. (
d934b909f6,831c5835d9,7025f0f711,0948ed6c87,d3b66241ca,b593321f02,50223278fc,501a974c6b,6b3800e1dd,6ca0658a7b,e2889b0bf5) - 3 small obj/x86 and amd64/386 rules commits internal — e.g. cc: remove duplicate rewrite x-(x&y) => x&^y rules in amd64; obj/x86: clear forward-jump list on PCALIGN; obj/x86: reject high byte registers with REX prefix. (
41b5566d61,27903a8717,b0d3d283f1) - 8 small obj/loong64 and loong64 asm commits internal — e.g. obj/loong64: add [X]VBITSELV and [X]VBITSELB instructions su; obj/loong64: add [X]VSTELM.{B/H/W/D} instructions support; cc: fix type mismatches in float and int conversion lowering. (
5d7583fe1f,417429c636,849501bbd9,8bf767e052,b0f0b1df21,7a90186a75,8360c0d8c0,210f033140) - 1 small cmd/asm commits internal — e.g. cmd/asm, obj: support 6-bit VROR.VI immediates. (
979f74e417) - 1 small mips/s390x/arm/wasm commits internal — e.g. obj/wasm, cmd/link/internal/ld: fix grammatical errors. (
a4f5746af5)
Backends and assemblers · SIMD
From SIMD: the simd packages and their compiler support (Go 1.18–1.28)
- Compiler SIMD type system, ABI and register-allocation support — Done: SIMD-zero block placement (
d61b240b11), no-code values not implying features (fbea197d32), VEX encodings (5763a306d2), critical-edge features (0b2fd4aa9c), whole-X15 zeroing (3f1287d96a), RegMask widening (966c78ed74), GOAMD64 seeding attempted and reverted (bc769ea44b,4a1a9dfeb7). Left open: GOAMD64-derived feature seeding. - simdgen: the instruction-table-driven generator — Done: gentools consolidation, Operand type filled by XED/ARM64/SVE (
7b916597d3,1f0d9ab3af), README, GOROOT logic; “mem” naming (c5612f0ccf); CPU feature of mask ops (f507c3fc9f). Left open: transition of old inputs (categories.yaml) to the executable spec, see spec thread. - AMD64 archsimd API: AVX, AVX2 and AVX-512 operations — Done: user-visible 8-bit interleave on amd64 (
efef5f05e5),Int*.Absreturns Uint (7e0c8984d8), OnesCount emulation for 8-bit (385f272158), Mask All/Any/None/TrailingZeros (bc10f4ab7f,145490ed8a,0291846537), Mask Xor/AndNot/Equal/Not (9f0fa36092,e6cce8b4da,2753eb3c05), exposing CLMUL feature checks (b7f9fde523), floating Min/Max made non-commutative so CSE cannot merge opposite operand orders (c7aa83bdd2: AMD64 Min/Max prefer the second operand for NaNs/equal zeros), alternating FMA lane parity fix (fe0449ba3a), signed rotates dropped (8031ffce5f: unclear sign semantics), AndNot operand order for KANDN fixed (e2889b0bf5: x.AndNot(y) on 512-bit masks returnedy &^ x, found by conformance testing). Left open:MulAddin the spec had to be split into int/float becausex*y+zonly fuses at GOAMD64>=v3 (958aac0d81, “inspired proposal #82653”). - Mask representation, masked operations and merge peepholes — Done: user-visible mask queries
All/Any/None/TrailingZeros, Mask Xor/AndNot/Equal/Not (see AMD64 thread); SVE predicate masks (see SVE thread). Left open: nothing noted. - dev.simd branch, GOEXPERIMENT=simd lifecycle and merges to master — Done: reverse merge
060245832f(2026-07-15);go.modmodule path forsimd/_genrepaired (db97d07dbb1.27); SVE reaches master (68f391a3c2). Left open: flag still off by default at HEAD (no commit changes this). - Portable
simdpackage and the “midway” source translator — Done: user-visible architectural variation / “nclm” variant (8dd7aa0168), GODEBUG parsing fixes (30843789bf,069f875c97), ReduceSum for floats and 8/16/32-bit ints (33c1f65079,366d1805d1,ba7fdba26b),Load*Partno longer reads past the slice end (beaf715aaa), generatedsimd_emulated.go(c1db0bc3c4), copies-test (a58ac9ec4a). Left open: SVE-sized vectors (rewriteSizes comment: “this will change for SVE and cannot just be a size-based choice”). - ARM64 NEON archsimd — Done: pairwise min/max, 64-bit-element Reduce, 8-bit ConcatAddPairs (
77984f0ab4,ac2f54e4aa,651ec67c3b), VCMTST (62bb6b4a80). Left open: nothing noted. - ARM64 SVE: scalable vectors and predicate masks — Done: user-visible MVP (
68f391a3c2,e5da70bf01,6fbc254146,fddf2d237d,1a8b63dad2), IfElse/Masked (4756f33d43), arithmetic/compare/bitwise families (5b7fced4a3,9de2d19c49,cc71e4955c,76b21f0229,a9aed73003,216cbea870, Sqrt/Ceil/Floor/Trunc/Round978a95f616..5bcfe1bdd1, Equal/NotEqual/GreaterEqual1dcfdf6fbf..2ba3d5f667, Max/Min/Div/MulAdd740fcaabb9,bfc1e31771,24fb3e7bc4,8921b16049), ReduceSum/Max (dbd397ac6d,387be25962), ShiftAllLeft (c72492ee6d), mask<->int (142236914f), SGEMM test with assembly baseline (2924f24765), SVE2 CPU detection (e077557cfb), RegMask widening. Left open: only a subset of SVE ops; predicate-register allocation bugs possible (RegisterSet fixed966c78ed74); vector-length handling is fixed-256-bit model. - Spec-driven API generation (internal/spec, specgen, specfill) — Done: initial spec (
810fe52b24), generator (aa7b8a796d), specls (9704c21b22), refgen, categories and commutativity (251583b606), shifts (f081a1ab32), docs filled from spec (ede51d4986,9450dc4b55), name filling (d9c017a1fa,021b49fbb9), host feature audit (1fe66956c2), “simd-common” done (b6680141e6),ScaleSaturatedrename (299a042625), parameter-name reconciliation (c35d7bdf94,5d8f28c94d). Left open: retirecategories.yaml, behavioural conformance beyond mathlib tests; impl-defined behaviour (“allowed wiggle room is not yet well-defined”). - API shaping and renames before stabilisation — Done:
23761e7bb2,299a042625,8031ffce5f. Left open: nothing noted. - Emulation of missing instructions and test infrastructure — Done:
385f272158,ba7fdba26b,71e81366eb,23207a3342. Left open: nothing noted.
Other changes
- Generator refactors (grouped, ~35 commits) internal — gentools adoption and vestige removal (
6d6dd571a7,1e794b078c,cf39a43980,26c87f9ca0,409a372fa8,dcbdcc34a8,9d44da442d,7237c87c8c), Go 1.26 update and SSA-refactor preparation (cbb6afc18a,ca80ab0453), unify/simdgen internals (0e82b22d24,3b2be116e3,5d12b248d5,36b2899c9e,6422d573b2,eb6ab72118,dd10d4c844), SVE generator details (7eca4e7ce3,b4edab0de1,a40a16659e,8d781f9969), specfill wiring and tasks (d2b5d45002,135af94578,ef4cb34cbf,643ad5f8df,25ff1b6cc8,9ef75bdaa4,e8653e969a,dffe249bc6,a5c9b914d0,68b130d442,c397af47ef,47fea15542), spec content (1e963f8291,908abadd8b,73afac4dad,e89c4220c7,c05e6588b3,d65eaaac17,072b45cb3f,63313a0fc5), emulation/signature repairs (229d482629,26bc19edfa,e6a5e89339,89428e89f6,0178fa45ad,2b9844540e,a89bb77d0a,ac2436c3cd,d27b23f671,f30364b083,48743ddd31). - Remaining SVE ops (grouped) user-visible — Neg, Abs for floats, Ceil/Floor/Trunc, Greater on unsigned/float, NotEqual, Or/Xor/AndNot, 8/16/32-bit integer ReduceSum, Float32s.ConvertToInt32 (
3e5d652309,f0b5a85f0b,71d1fb55de,d162d69f7e,8d6fbb0152,e5851791cd,1da1ff7ee2,1afe83171b,336f6cfe75,7ae2269d48,c4bf40aac9,efb714d031). - ARM64 VSMOV internal (
b01fe21278,8db4546f29). - Runtime memmove SIMD on arm64 internal — added and reverted (
91aa6bb390,dac9fe5ea9), cross-area.
Linker and object files
From Linker, object files and debug info (Go 1.18–1.28)
- Type, itab and typelink layout (.go.type section, relro rework) — Done: compiler and linker use one name for alg and noalg descriptors; the algorithm-bearing one wins via a weak definition and TFlag marks the noalg one, avoiding two descriptors per type
15bcf54708. Left open: nothing noted. - DWARF quality for debuggers (types, variables, trampolines) — Done: source-less
DW_TAG_subprogramwith address-valuedDW_AT_trampolinefor each direct linker trampoline (ARM, ARM64, Loong64, PPC64, RISC-V), inspired by Delve561f6e6101, simplified inf91ce18c4d. Left open: dynamic/GOT trampolines excluded. - Darwin split DWARF (dSYM) — Done: split DWARF behind a flag
a3b72a4a0d; enabled by default with a test once the go command supported it48f0ff2044; symbol table in the DWARF file3223d9d127;.debug_aranges844f96c5d1;-dmade no-op on Darwin95bc6b93fc. Left open: LLDB can’t read compressed DWARF. - Linker performance and memory — Done: ELF
.strtabdeduplicated (cmd/go −0.21%, cmd/compile −0.34%)4dd8b7df66; funcdata scratch slice reuse6a1d404935. Left open: nothing noted. - Per-platform object formats and internal linking (Mach-O, PE, XCOFF, wasm, ppc64, riscv64, loong64) — Done: Wasm PC high bit set so PCs never look like data pointers to GC
9d8bad3bbd; 32-bit Darwin removeda479c5b3ef;__ImageBaseon Windows3b21b1d0cc; split text sections for over-aligned functions2fb15af7f0. Left open: nothing noted.
Other changes
- Linker fixes internal — flag probes pass the external linker’s own args (
ce2e732927), AIX crt0_64 (26fd8f14e6), OpenBSD-nopieduplicate (697fe8caba), plugins on macOS get-no_fixup_chains(01e4798b98), ppc64 TOC restore slot panic (ea0fa54dc5), no label symbol for unallocated symbols (c5550198dc), netbsd fallocate (90b13c1644). - Remaining small linker/DWARF/goobj changes (about 90 commits across 1.18-1.28) internal — cleanups and minor fixes grouped here for completeness: goobj builtin list (
b5f37faf3b1.18), dwarf param/pos cleanups (838079beef1.18,322879d5c91.18,661e3be4971.22,c641900f721.26), Go-version-gated syscall use (9e4dc6f37f1.18,7c3284401f1.20), ELF cleanups (3001b0abf01.18,f90bb8a38f1.21,75136fc14c1.21,63169c8bdf1.19,b9d6cea5011.19), error-message and debug-output improvements (f92c8f07ac1.18,1ec51087e51.18,8205d83fe21.20,780db9a63d1.21,f24afeef9a1.21,4304529a161.21,b152d9a1181.27), loader/loadelf/refactors (77680a06441.19,42d2d5e2b51.19,9b0140a6951.22,3f700ce4d21.22,dc9d219cad1.21,0067d814b61.21,3f8f929d601.21,94f47fc03f1.26), full-RELRO option later reverted (45b641ce151.23), per-package text address assignment (d1ef9673061.22, reverted in 1.22),.go.buildinforelocation special cases (2a3c695c4b1.21), dynamic import variables on Darwin plugin mode (44f18706661.23), ARM text splitting and Go-linker gold avoidance (790f25052d1.21,cd777381981.21), PPC64 trampoline distance (1ed636dc971.20), Darwin codesign offset and IMAGE_FILE_DEBUG_STRIPPED (7dc8509c691.21,949fdd9f0d1.21), assorted spelling and modernization (d922c0a8f51.19,f8c659b62f1.20,d31c4bc2de1.20,ab0d057e641.20,fac5338a6c1.20,527829a7cb1.22,a5a249d6a61.26), AIX build fixes (276cc4d3db1.26,d8269ab0d51.26), runtime-adjacent (3fefec96ad1.23,8623c0ba951.23,92a63bdfee1.25,06450a82b01.25).