Skip to content

compiler: preserve AVX2 specialization across Midway calls - #2835

Merged
cpunion merged 4 commits into
xgo-dev:mainfrom
zhouguangyuan0718:codex/midway-fmv-followup-20261017
Oct 19, 2026
Merged

cpunion merged 4 commits into
xgo-dev:mainfrom
zhouguangyuan0718:codex/midway-fmv-followup-20261017

Conversation

@zhouguangyuan0718

Copy link
Copy Markdown
Collaborator

Midway's 128-bit portable representations are defined simd/internal/bridge types. FMV currently recognizes only archsimd vectors, so an AVX2-specialized portable function calling a vector-containing aggregate or array helper in another package keeps calling the baseline entry. This recognizes the official bridge representation and preserves AVX2 specialization across those calls, without changing its storage or calling convention.

Based on main c41bc55d9, following #2819. Bridge eligibility requires a matching official archsimd type and identical underlying storage; emulated representations, wider vectors, unrelated packages, and incompatible storage remain ineligible. CPU queries remain independent of Midway representation selection: emulation does not imply AVX2 is off, and SIMD128 does not imply AVX2 is on. Propagating additional Midway entry guarantees and pruning feature combinations remain separate follow-up work.

Validation:

  • The new cross-package LLVM regression fails on the main implementation for Linux, Darwin, and Windows amd64 at O0/O2. With the fix it checks fast declarations/definitions, direct-call rewriting, query folding, aggregate tail-forwarding ABI, LLVM verification, and baseline assembly.
  • SIMD-focused cl, ssa, and internal/build tests; full internal/llvmfmv, internal/midway, and internal/packages tests.
  • Fresh Linux amd64 Docker and Windows amd64 Wine execution at O0, O2, ThinLTO, and FullLTO, with 12 SIMD/CPU settings per build: all 96 runs passed (1440 individual test passes). The matrix covers aggregate copies and result aliasing, arrays, cross-package calls, function values, methods, closures, interfaces, generics, and initialization.
  • Four official Go control runs for the common composition tests. The native CI script now also crosses simd=0/128 with AVX2, AVX, FMA, and all optional CPU features disabled.
  • Formatting, shell syntax, and diff checks. go vet ./... reports diagnostics in unchanged test fixtures (context, assignment order, unsafe pointer, JSON, and syscall lock-copy cases).

Docker/Wine results are emulated execution, not native hardware qualification. Hosted CI will run on this PR.

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: preserve AVX2 specialization across Midway calls

The production change is small, correct, and well-covered. simdFMVVector cleanly separates the two recognition paths — the official archsimd shape via SIMDVectorShape, and the simd/internal/bridge peer type validated by package path, a vector-shaped namesake in simd/archsimd, and types.Identical on the underlyings. That structural identity check is the right mechanism (a bridge type can't pass SIMDVectorShape directly because its v128 tag lives in archsimd, not its own package), and it only recognizes types for FMV marking without touching lowering or ABI. The types.Unalias handling, the negative cases (wrong package, pointer wrapper, wider type, mismatched underlying), and the cross-package/aggregate/array/closure/method/interface/generic/initialization fixtures are thorough. No security concerns, and the README prose accurately matches the implemented behavior.

A few minor, non-blocking suggestions are left inline. None block merge.

Other notes (no inline location)

  • Test readability (low priority): The embedded Go source in internal/build/simd_midway_fmv_test.go (lines ~24–51) and the negative-case table in cl/simd_bridge_test.go:52-61 pack several operations per line. Adding per-case labels to the negative table and de-densifying the embedded source would make future failure localization easier. The embedded source files are also written by ranging a map[string]string, so the write order is nondeterministic — harmless today, but a []{name, source} slice would be deterministic at no cost.
  • Pre-existing, out of this PR's scope: markSIMDFMV is invoked from cl/instr.go:739 on every function reference (outside the aFn == nil cache-miss guard), not once per function. This PR's bridge path adds a small gated import scan + scope lookup that is therefore repeated per reference. It's tightly gated behind the two simd/internal/bridge path checks, so there's no asymptotic blow-up, but if that per-reference call is ever tightened to the cache-miss path it would remove the redundancy for free.

Comment thread cl/simd_fmv.go Resolved
Comment thread cl/simd_fmv.go Resolved
@codecov

codecov Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

LLGo WebAssembly build benchmarks

9a9b771bd237 | workflow run | long-term charts

WebAssembly output sizes
Example, profile and compiler Wasm module vs base Generated JS glue vs base
cprintf/j32-emscripten/LLGo 147058 B 0 B / +0.0% 88541 B 0 B / +0.0%
cprintf/j32-goos-js/LLGo 145666 B 0 B / +0.0% 72985 B 0 B / +0.0%
cprintf/j64-emscripten-memory64/LLGo 134527 B 0 B / +0.0% 91712 B 0 B / +0.0%
cprintf/w32-goos-wasip1/LLGo 156385 B 0 B / +0.0% 0 B 0 B / 0.0%
cprintf/w32-wasi/LLGo 157083 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/j32-emscripten/LLGo 2983979 B 0 B / +0.0% 120989 B 0 B / +0.0%
fmtprintf/j32-goos-js/Go 2526852 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/j32-goos-js/LLGo 3074748 B 0 B / +0.0% 92052 B 0 B / +0.0%
fmtprintf/j64-emscripten-memory64/LLGo 2748837 B 0 B / +0.0% 125530 B 0 B / +0.0%
fmtprintf/w32-goos-wasip1/Go 2500019 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/w32-goos-wasip1/LLGo 2343602 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/w32-wasi/LLGo 2340298 B 0 B / +0.0% 0 B 0 B / 0.0%
j32-emscripten/LLGo 146575 B 0 B / +0.0% 88541 B 0 B / +0.0%
j32-goos-js/Go 1895533 B 0 B / +0.0% 0 B 0 B / 0.0%
j32-goos-js/LLGo 145416 B 0 B / +0.0% 72985 B 0 B / +0.0%
j64-emscripten-memory64/LLGo 134082 B 0 B / +0.0% 91712 B 0 B / +0.0%
reflectcall/j32-emscripten/LLGo 1510134 B 0 B / +0.0% 95329 B 0 B / +0.0%
reflectcall/j32-goos-js/Go 2191221 B 0 B / +0.0% 0 B 0 B / 0.0%
reflectcall/j32-goos-js/LLGo 1562301 B 0 B / +0.0% 79769 B 0 B / +0.0%
reflectcall/j64-emscripten-memory64/LLGo 1391259 B 0 B / +0.0% 99026 B 0 B / +0.0%
reflectcall/w32-goos-wasip1/Go 2205707 B 0 B / +0.0% 0 B 0 B / 0.0%
reflectcall/w32-goos-wasip1/LLGo 1273789 B 0 B / +0.0% 0 B 0 B / 0.0%
reflectcall/w32-wasi/LLGo 1271430 B 0 B / +0.0% 0 B 0 B / 0.0%
w32-goos-wasip1/Go 1909947 B 0 B / +0.0% 0 B 0 B / 0.0%
w32-goos-wasip1/LLGo 156059 B 0 B / +0.0% 0 B 0 B / 0.0%
w32-wasi/LLGo 156757 B 0 B / +0.0% 0 B 0 B / 0.0%
LLGo WebAssembly build measurements
Example and profile Build vs base
j32-emscripten 8.377 s -1.399 s / -14.3% (better)
j32-goos-js 8.388 s -647.6 ms / -7.2% (better)
j64-emscripten-memory64 7.264 s -598.4 ms / -7.6% (better)
reflectcall/w32-wasi 29.160 s +2.27 s / +8.4% (worse)
w32-goos-wasip1 5.326 s -701.6 ms / -11.6% (better)
w32-wasi 4.541 s -1.184 s / -20.7% (better)

Compared with 0a2ebb890b83 measured in the same runner job.

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

LLGo baseline benchmarks

9a9b771bd237 | workflow run | long-term charts

Program measurements

Platform Workload File size vs base Text size vs base Build vs base Run vs base
Linux cprintf 8544 B 0 B / +0.0% 387 B 0 B / +0.0% 924.431 ms +53.76 ms / +6.2% (worse) 1.375 ms +99.81 us / +7.8% (worse)
Linux cprintf-lto 8336 B 0 B / +0.0% 368 B 0 B / +0.0% 912.119 ms +82.83 ms / +10.0% (worse) 1.335 ms +35.07 us / +2.7% (worse)
Linux fmtprintf 2701768 B -56 B / -0.002073% (better) 506897 B 0 B / +0.0% 5.440 s +249.6 ms / +4.8% (worse) 4.383 ms -264.6 us / -5.7% (better)
Linux fmtprintf-lto 2193800 B +32 B / +0.001459% (worse) 444811 B 0 B / +0.0% 15.207 s -1.454 s / -8.7% (better) 4.099 ms -339.2 us / -7.6% (better)
Linux println 242016 B +56 B / +0.02314% (worse) 17095 B 0 B / +0.0% 938.099 ms +88.34 ms / +10.4% (worse) 1.711 ms +46.58 us / +2.8% (worse)
Linux println-lto 105152 B -8 B / -0.007607% (better) 14484 B 0 B / +0.0% 1.198 s +29.77 ms / +2.5% (worse) 1.618 ms -56.52 us / -3.4% (better)
macOS cprintf 50672 B 0 B / +0.0% 4409 B 0 B / +0.0% 1.173 s -78.78 ms / -6.3% (better) 3.930 ms -3.817 ms / -49.3% (better)
macOS cprintf-lto 50592 B -16 B / -0.03162% (better) 161 B 0 B / +0.0% 1.258 s -43.8 ms / -3.4% (better) 7.224 ms +1.662 ms / +29.9% (worse)
macOS fmtprintf 1659808 B 0 B / +0.0% 883744 B 0 B / +0.0% 5.157 s +983.4 ms / +23.6% (worse) 48.989 ms +15.95 ms / +48.3% (worse)
macOS fmtprintf-lto 1362160 B -16 B / -0.001175% (better) 766828 B 0 B / +0.0% 9.641 s -926.8 ms / -8.8% (better) 56.353 ms -5.542 ms / -9.0% (better)
macOS println 96512 B 0 B / +0.0% 24519 B 0 B / +0.0% 1.159 s -54.58 ms / -4.5% (better) 5.583 ms +377.1 us / +7.2% (worse)
macOS println-lto 84112 B -16 B / -0.01902% (better) 21732 B 0 B / +0.0% 1.256 s -15.29 ms / -1.2% (better) 7.360 ms +3.36 ms / +84.0% (worse)
Windows MinGW cprintf 676352 B 0 B / +0.0% 4390 B 0 B / +0.0% 1.618 s -39.84 ms / -2.4% (better) 3.505 ms -247.7 us / -6.6% (better)
Windows MinGW cprintf-lto 44544 B 0 B / +0.0% 4342 B 0 B / +0.0% 1.663 s -71.13 ms / -4.1% (better) 3.370 ms -351.1 us / -9.4% (better)
Windows MinGW fmtprintf 5473280 B 0 B / +0.0% 605974 B 0 B / +0.0% 5.460 s +6.412 ms / +0.1% (worse) 10.757 ms -1.06 ms / -9.0% (better)
Windows MinGW fmtprintf-lto 4161024 B 0 B / +0.0% 553094 B 0 B / +0.0% 13.052 s +39.5 ms / +0.3% (worse) 10.560 ms +235.1 us / +2.3% (worse)
Windows MinGW println 733696 B 0 B / +0.0% 25286 B 0 B / +0.0% 1.673 s +38.13 ms / +2.3% (worse) 7.912 ms +1.058 ms / +15.4% (worse)
Windows MinGW println-lto 210944 B 0 B / +0.0% 22166 B 0 B / +0.0% 1.915 s -1.056 ms / -0.1% (better) 6.794 ms -194.6 us / -2.8% (better)
Windows MinGW 386 cprintf 627200 B 0 B / +0.0% 5352 B 0 B / +0.0% 1.229 s -220.1 ms / -15.2% (better) 3.240 ms +96.9 us / +3.1% (worse)
Windows MinGW 386 cprintf-lto 104448 B 0 B / +0.0% 5112 B 0 B / +0.0% 1.322 s +102.8 ms / +8.4% (worse) 3.239 ms -43.7 us / -1.3% (better)
Windows MinGW 386 fmtprintf 4776960 B 0 B / +0.0% 473902 B 0 B / +0.0% 3.910 s +28.34 ms / +0.7% (worse) 7.617 ms -460.6 us / -5.7% (better)
Windows MinGW 386 fmtprintf-lto 4163072 B 0 B / +0.0% 452294 B 0 B / +0.0% 8.850 s +61.48 ms / +0.7% (worse) 8.042 ms -36.6 us / -0.5% (better)
Windows MinGW 386 println 681472 B 0 B / +0.0% 21694 B 0 B / +0.0% 1.460 s +150.1 ms / +11.5% (worse) 5.478 ms +86.6 us / +1.6% (worse)
Windows MinGW 386 println-lto 260608 B 0 B / +0.0% 19514 B 0 B / +0.0% 1.651 s +188.9 ms / +12.9% (worse) 5.454 ms -105.9 us / -1.9% (better)
Windows MinGW ARM64 cprintf 686592 B 0 B / +0.0% 4204 B 0 B / +0.0% 1.791 s -5.706 ms / -0.3% (better) 5.981 ms -86.2 us / -1.4% (better)
Windows MinGW ARM64 cprintf-lto 44032 B 0 B / +0.0% 4156 B 0 B / +0.0% 1.814 s -15.07 ms / -0.8% (better) 6.034 ms +98 us / +1.7% (worse)
Windows MinGW ARM64 fmtprintf 5382144 B 0 B / +0.0% 514060 B 0 B / +0.0% 5.233 s +100 ms / +1.9% (worse) 13.905 ms -575.3 us / -4.0% (better)
Windows MinGW ARM64 fmtprintf-lto 4326912 B 0 B / +0.0% 480120 B 0 B / +0.0% 11.766 s +5.849 ms / +0.04974% (worse) 13.886 ms -171 us / -1.2% (better)
Windows MinGW ARM64 println 739840 B 0 B / +0.0% 23928 B 0 B / +0.0% 1.811 s +16.8 ms / +0.9% (worse) 10.260 ms +154 us / +1.5% (worse)
Windows MinGW ARM64 println-lto 218112 B 0 B / +0.0% 21284 B 0 B / +0.0% 2.053 s +19.68 ms / +1.0% (worse) 10.507 ms -449.7 us / -4.1% (better)
Windows MSVC cprintf 921088 B 0 B / +0.0% 66003 B 0 B / +0.0% 1.560 s -117.6 ms / -7.0% (better) 3.524 ms +116.4 us / +3.4% (worse)
Windows MSVC cprintf-lto 292352 B 0 B / +0.0% 65971 B 0 B / +0.0% 1.580 s +14.34 ms / +0.9% (worse) 3.514 ms +99.5 us / +2.9% (worse)
Windows MSVC fmtprintf 5774848 B 0 B / +0.0% 701894 B 0 B / +0.0% 6.163 s +905.3 ms / +17.2% (worse) 14.392 ms +2.116 ms / +17.2% (worse)
Windows MSVC fmtprintf-lto 4484096 B 0 B / +0.0% 652806 B 0 B / +0.0% 13.019 s +486.7 ms / +3.9% (worse) 12.166 ms -1.378 ms / -10.2% (better)
Windows MSVC println 1044992 B 0 B / +0.0% 121334 B 0 B / +0.0% 1.784 s +230.8 ms / +14.9% (worse) 7.897 ms +474.9 us / +6.4% (worse)
Windows MSVC println-lto 531456 B 0 B / +0.0% 118870 B 0 B / +0.0% 1.831 s +44.43 ms / +2.5% (worse) 7.535 ms -98 us / -1.3% (better)
Windows MSVC 386 cprintf 538624 B 0 B / +0.0% 3947 B 0 B / +0.0% 1.575 s +113.6 ms / +7.8% (worse) 5.281 ms -763.6 us / -12.6% (better)
Windows MSVC 386 cprintf-lto 44544 B 0 B / +0.0% 3901 B 0 B / +0.0% 1.757 s +251.8 ms / +16.7% (worse) 6.880 ms +1.691 ms / +32.6% (worse)
Windows MSVC 386 fmtprintf 4508672 B 0 B / +0.0% 457314 B 0 B / +0.0% 5.224 s -185.9 ms / -3.4% (better) 13.247 ms -270.3 us / -2.0% (better)
Windows MSVC 386 fmtprintf-lto 3910656 B 0 B / +0.0% 427681 B 0 B / +0.0% 12.127 s +406.2 ms / +3.5% (worse) 14.035 ms -78 us / -0.6% (better)
Windows MSVC 386 println 593920 B 0 B / +0.0% 20566 B 0 B / +0.0% 1.621 s +176.6 ms / +12.2% (worse) 11.083 ms +1.111 ms / +11.1% (worse)
Windows MSVC 386 println-lto 200192 B 0 B / +0.0% 18711 B 0 B / +0.0% 1.779 s +81.87 ms / +4.8% (worse) 10.069 ms +429.8 us / +4.5% (worse)
Windows MSVC ARM64 cprintf 687616 B 0 B / +0.0% 4240 B 0 B / +0.0% 1.682 s -60.92 ms / -3.5% (better) 7.318 ms -111.4 us / -1.5% (better)
Windows MSVC ARM64 cprintf-lto 49152 B 0 B / +0.0% 4140 B 0 B / +0.0% 1.684 s -20.23 ms / -1.2% (better) 7.546 ms -111.2 us / -1.5% (better)
Windows MSVC ARM64 fmtprintf 5379072 B 0 B / +0.0% 514164 B 0 B / +0.0% 5.398 s -108.7 ms / -2.0% (better) 18.376 ms -591.5 us / -3.1% (better)
Windows MSVC ARM64 fmtprintf-lto 4334080 B 0 B / +0.0% 480960 B 0 B / +0.0% 12.149 s -445.6 ms / -3.5% (better) 18.493 ms -1.646 ms / -8.2% (better)
Windows MSVC ARM64 println 741376 B 0 B / +0.0% 24200 B 0 B / +0.0% 1.721 s +47.31 ms / +2.8% (worse) 13.211 ms -216.9 us / -1.6% (better)
Windows MSVC ARM64 println-lto 223232 B 0 B / +0.0% 21688 B 0 B / +0.0% 1.973 s -3.674 ms / -0.2% (better) 12.795 ms -1.393 ms / -9.8% (better)
Core language and compiler benchmarks
Platform Benchmark ns/op vs base
Linux BenchmarkLookupPCRandom 14.640 ns/op +0.16 ns/op / +1.1% (worse)
Linux BenchmarkMergeCompilerFlags 206.300 ns/op -9 ns/op / -4.2% (better)
Linux BenchmarkMergeLinkerFlags 129 ns/op -9.6 ns/op / -6.9% (better)
Linux BenchmarkChannelBuffered 55.190 ns/op -0.22 ns/op / -0.4% (better)
Linux BenchmarkChannelHandoff 19389 ns/op +5396 ns/op / +38.6% (worse)
Linux BenchmarkDefer 53.640 ns/op -2.67 ns/op / -4.7% (better)
Linux BenchmarkDirectCall 1.169 ns/op +0.002 ns/op / +0.2% (worse)
Linux BenchmarkGlobalRead 1.166 ns/op -0.063 ns/op / -5.1% (better)
Linux BenchmarkGlobalWrite 7.796 ns/op -0.017 ns/op / -0.2% (better)
Linux BenchmarkGoroutine 26374 ns/op +1861 ns/op / +7.6% (worse)
Linux BenchmarkInterfaceCall 6.843 ns/op +0.409 ns/op / +6.4% (worse)
Linux BenchmarkRuntimeGetG 2.900 ns/op +0.02 ns/op / +0.7% (worse)
macOS BenchmarkLookupPCRandom 20.400 ns/op +0.26 ns/op / +1.3% (worse)
macOS BenchmarkMergeCompilerFlags 213.500 ns/op +64.8 ns/op / +43.6% (worse)
macOS BenchmarkMergeLinkerFlags 139.900 ns/op +38.6 ns/op / +38.1% (worse)
macOS BenchmarkChannelBuffered 35.840 ns/op +2.17 ns/op / +6.4% (worse)
macOS BenchmarkChannelHandoff 14186 ns/op +2321 ns/op / +19.6% (worse)
macOS BenchmarkDefer 46.940 ns/op +6.22 ns/op / +15.3% (worse)
macOS BenchmarkDirectCall 1.393 ns/op -0.042 ns/op / -2.9% (better)
macOS BenchmarkGlobalRead 1.382 ns/op +0.112 ns/op / +8.8% (worse)
macOS BenchmarkGlobalWrite 1.457 ns/op +0.14 ns/op / +10.6% (worse)
macOS BenchmarkGoroutine 68062 ns/op +158 ns/op / +0.2% (worse)
macOS BenchmarkInterfaceCall 5.292 ns/op +0.403 ns/op / +8.2% (worse)
macOS BenchmarkRuntimeGetG 3.014 ns/op +0.222 ns/op / +8.0% (worse)
Windows MinGW BenchmarkLookupPCRandom 13.110 ns/op -0.11 ns/op / -0.8% (better)
Windows MinGW BenchmarkMergeCompilerFlags 614.100 ns/op -3.3 ns/op / -0.5% (better)
Windows MinGW BenchmarkMergeLinkerFlags 542.800 ns/op -5.2 ns/op / -0.9% (better)
Windows MinGW BenchmarkChannelBuffered 30.180 ns/op -0.45 ns/op / -1.5% (better)
Windows MinGW BenchmarkChannelHandoff 1157 ns/op +57 ns/op / +5.2% (worse)
Windows MinGW BenchmarkDefer 55.630 ns/op +0.37 ns/op / +0.7% (worse)
Windows MinGW BenchmarkDirectCall 1.551 ns/op +0.005 ns/op / +0.3% (worse)
Windows MinGW BenchmarkGlobalRead 1.548 ns/op +0.001 ns/op / +0.1% (worse)
Windows MinGW BenchmarkGlobalWrite 2.460 ns/op -0.001 ns/op / -0.04063% (better)
Windows MinGW BenchmarkGoroutine 91715 ns/op +2659 ns/op / +3.0% (worse)
Windows MinGW BenchmarkInterfaceCall 8.707 ns/op -0.021 ns/op / -0.2% (better)
Windows MinGW BenchmarkRuntimeGetG 1.864 ns/op -0.001 ns/op / -0.1% (better)
Windows MinGW 386 BenchmarkLookupPCRandom 15 ns/op +0.01 ns/op / +0.1% (worse)
Windows MinGW 386 BenchmarkMergeCompilerFlags 866.900 ns/op +26.3 ns/op / +3.1% (worse)
Windows MinGW 386 BenchmarkMergeLinkerFlags 851.500 ns/op +58.9 ns/op / +7.4% (worse)
Windows MinGW 386 BenchmarkChannelBuffered 35.010 ns/op +0.07 ns/op / +0.2% (worse)
Windows MinGW 386 BenchmarkChannelHandoff 637.900 ns/op +2.1 ns/op / +0.3% (worse)
Windows MinGW 386 BenchmarkDefer 26.150 ns/op -0.06 ns/op / -0.2% (better)
Windows MinGW 386 BenchmarkDirectCall 0.895 ns/op +0.0002 ns/op / +0.02234% (worse)
Windows MinGW 386 BenchmarkGlobalRead 0.889 ns/op -0.0113 ns/op / -1.3% (better)
Windows MinGW 386 BenchmarkGlobalWrite 8.063 ns/op -0.017 ns/op / -0.2% (better)
Windows MinGW 386 BenchmarkGoroutine 51186 ns/op +1399 ns/op / +2.8% (worse)
Windows MinGW 386 BenchmarkInterfaceCall 4.656 ns/op +0.214 ns/op / +4.8% (worse)
Windows MinGW 386 BenchmarkRuntimeGetG 1.142 ns/op +0.022 ns/op / +2.0% (worse)
Windows MinGW ARM64 BenchmarkLookupPCRandom 12.090 ns/op +0.04 ns/op / +0.3% (worse)
Windows MinGW ARM64 BenchmarkMergeCompilerFlags 572.800 ns/op +1.2 ns/op / +0.2% (worse)
Windows MinGW ARM64 BenchmarkMergeLinkerFlags 532 ns/op -2.6 ns/op / -0.5% (better)
Windows MinGW ARM64 BenchmarkChannelBuffered 37.650 ns/op -0.36 ns/op / -0.9% (better)
Windows MinGW ARM64 BenchmarkChannelHandoff 2780 ns/op -15 ns/op / -0.5% (better)
Windows MinGW ARM64 BenchmarkDefer 54.840 ns/op +1.77 ns/op / +3.3% (worse)
Windows MinGW ARM64 BenchmarkDirectCall 0.590 ns/op 0 ns/op / +0.0%
Windows MinGW ARM64 BenchmarkGlobalRead 0.664 ns/op -0.0002 ns/op / -0.03013% (better)
Windows MinGW ARM64 BenchmarkGlobalWrite 0.663 ns/op +0.0003 ns/op / +0.04524% (worse)
Windows MinGW ARM64 BenchmarkGoroutine 61653 ns/op +1307 ns/op / +2.2% (worse)
Windows MinGW ARM64 BenchmarkInterfaceCall 4.238 ns/op +0.004 ns/op / +0.1% (worse)
Windows MinGW ARM64 BenchmarkRuntimeGetG 1.804 ns/op +0.027 ns/op / +1.5% (worse)
Windows MSVC BenchmarkLookupPCRandom 13.350 ns/op +0.2 ns/op / +1.5% (worse)
Windows MSVC BenchmarkMergeCompilerFlags 614 ns/op -14 ns/op / -2.2% (better)
Windows MSVC BenchmarkMergeLinkerFlags 554.400 ns/op +4.1 ns/op / +0.7% (worse)
Windows MSVC BenchmarkChannelBuffered 28.830 ns/op -0.01 ns/op / -0.03467% (better)
Windows MSVC BenchmarkChannelHandoff 1204 ns/op -36 ns/op / -2.9% (better)
Windows MSVC BenchmarkDefer 67.030 ns/op +0.04 ns/op / +0.1% (worse)
Windows MSVC BenchmarkDirectCall 1.548 ns/op -0.001 ns/op / -0.1% (better)
Windows MSVC BenchmarkGlobalRead 1.551 ns/op +0.004 ns/op / +0.3% (worse)
Windows MSVC BenchmarkGlobalWrite 2.457 ns/op -0.003 ns/op / -0.1% (better)
Windows MSVC BenchmarkGoroutine 91798 ns/op +2331 ns/op / +2.6% (worse)
Windows MSVC BenchmarkInterfaceCall 8.700 ns/op +0.028 ns/op / +0.3% (worse)
Windows MSVC BenchmarkRuntimeGetG 2.185 ns/op +0.004 ns/op / +0.2% (worse)
Windows MSVC 386 BenchmarkLookupPCRandom 26.600 ns/op 0 ns/op / +0.0%
Windows MSVC 386 BenchmarkMergeCompilerFlags 811.800 ns/op +44.8 ns/op / +5.8% (worse)
Windows MSVC 386 BenchmarkMergeLinkerFlags 637.800 ns/op -29.2 ns/op / -4.4% (better)
Windows MSVC 386 BenchmarkChannelBuffered 38.950 ns/op -4.77 ns/op / -10.9% (better)
Windows MSVC 386 BenchmarkChannelHandoff 959.200 ns/op -349.8 ns/op / -26.7% (better)
Windows MSVC 386 BenchmarkDefer 46.030 ns/op -5.37 ns/op / -10.4% (better)
Windows MSVC 386 BenchmarkDirectCall 1.551 ns/op -0.142 ns/op / -8.4% (better)
Windows MSVC 386 BenchmarkGlobalRead 1.552 ns/op -0.125 ns/op / -7.5% (better)
Windows MSVC 386 BenchmarkGlobalWrite 7.795 ns/op -0.285 ns/op / -3.5% (better)
Windows MSVC 386 BenchmarkGoroutine 106543 ns/op -1899 ns/op / -1.8% (better)
Windows MSVC 386 BenchmarkInterfaceCall 8.147 ns/op -1.675 ns/op / -17.1% (better)
Windows MSVC 386 BenchmarkRuntimeGetG 2.478 ns/op -0.345 ns/op / -12.2% (better)
Windows MSVC ARM64 BenchmarkLookupPCRandom 12.050 ns/op -0.07 ns/op / -0.6% (better)
Windows MSVC ARM64 BenchmarkMergeCompilerFlags 572.600 ns/op -3.1 ns/op / -0.5% (better)
Windows MSVC ARM64 BenchmarkMergeLinkerFlags 540.400 ns/op +6.4 ns/op / +1.2% (worse)
Windows MSVC ARM64 BenchmarkChannelBuffered 39 ns/op +0.74 ns/op / +1.9% (worse)
Windows MSVC ARM64 BenchmarkChannelHandoff 3658 ns/op +437 ns/op / +13.6% (worse)
Windows MSVC ARM64 BenchmarkDefer 60.660 ns/op -3.63 ns/op / -5.6% (better)
Windows MSVC ARM64 BenchmarkDirectCall 0.590 ns/op +0.0001 ns/op / +0.01696% (worse)
Windows MSVC ARM64 BenchmarkGlobalRead 0.590 ns/op -0.0004 ns/op / -0.1% (better)
Windows MSVC ARM64 BenchmarkGlobalWrite 3.749 ns/op -0.029 ns/op / -0.8% (better)
Windows MSVC ARM64 BenchmarkGoroutine 58907 ns/op -980 ns/op / -1.6% (better)
Windows MSVC ARM64 BenchmarkInterfaceCall 4.139 ns/op +0.004 ns/op / +0.1% (worse)
Windows MSVC ARM64 BenchmarkRuntimeGetG 1.768 ns/op -0.032 ns/op / -1.8% (better)
Timer runtime benchmarks
Platform Operation and runtime ns/op vs base
Linux AfterFuncZeroDelivery/Go 911.400 ns/op -29.7 ns/op / -3.2% (better)
Linux AfterFuncZeroDelivery/LLGo 38017 ns/op -14030 ns/op / -27.0% (better)
Linux CreateStop/Go 295.300 ns/op -2.4 ns/op / -0.8% (better)
Linux CreateStop/LLGo 1772 ns/op +59 ns/op / +3.4% (worse)
Linux RearmStopped/Go 116.100 ns/op -4.2 ns/op / -3.5% (better)
Linux RearmStopped/LLGo 1233 ns/op +78 ns/op / +6.8% (worse)
Linux ResetActive/Go 68.850 ns/op -0.21 ns/op / -0.3% (better)
Linux ResetActive/LLGo 693.300 ns/op +65.3 ns/op / +10.4% (worse)
Linux ResetHeap1024/Go 67.210 ns/op -0.69 ns/op / -1.0% (better)
Linux ResetHeap1024/LLGo 160.500 ns/op -1.9 ns/op / -1.2% (better)
macOS AfterFuncZeroDelivery/Go 741 ns/op +142.9 ns/op / +23.9% (worse)
macOS AfterFuncZeroDelivery/LLGo 65259 ns/op -1543 ns/op / -2.3% (better)
macOS CreateStop/Go 274.700 ns/op +63.3 ns/op / +29.9% (worse)
macOS CreateStop/LLGo 704 ns/op -36.5 ns/op / -4.9% (better)
macOS RearmStopped/Go 94.730 ns/op +18.35 ns/op / +24.0% (worse)
macOS RearmStopped/LLGo 373.700 ns/op -150.7 ns/op / -28.7% (better)
macOS ResetActive/Go 89.230 ns/op +31.56 ns/op / +54.7% (worse)
macOS ResetActive/LLGo 168.800 ns/op -5.6 ns/op / -3.2% (better)
macOS ResetHeap1024/Go 69.440 ns/op +15.48 ns/op / +28.7% (worse)
macOS ResetHeap1024/LLGo 106.800 ns/op -70.1 ns/op / -39.6% (better)
Windows MinGW AfterFuncZeroDelivery/Go 568.300 ns/op +18.1 ns/op / +3.3% (worse)
Windows MinGW AfterFuncZeroDelivery/LLGo 183110 ns/op -2935 ns/op / -1.6% (better)
Windows MinGW CreateStop/Go 116.200 ns/op +0.4 ns/op / +0.3% (worse)
Windows MinGW CreateStop/LLGo 470.200 ns/op -27.4 ns/op / -5.5% (better)
Windows MinGW RearmStopped/Go 31.550 ns/op -0.07 ns/op / -0.2% (better)
Windows MinGW RearmStopped/LLGo 231.900 ns/op -11.8 ns/op / -4.8% (better)
Windows MinGW ResetActive/Go 20.180 ns/op +0.08 ns/op / +0.4% (worse)
Windows MinGW ResetActive/LLGo 171 ns/op +28.7 ns/op / +20.2% (worse)
Windows MinGW ResetHeap1024/Go 20.540 ns/op -0.11 ns/op / -0.5% (better)
Windows MinGW ResetHeap1024/LLGo 122.200 ns/op +2 ns/op / +1.7% (worse)
Windows MinGW 386 AfterFuncZeroDelivery/Go 586.600 ns/op -4.7 ns/op / -0.8% (better)
Windows MinGW 386 AfterFuncZeroDelivery/LLGo 101036 ns/op -1433 ns/op / -1.4% (better)
Windows MinGW 386 CreateStop/Go 155.700 ns/op +3.3 ns/op / +2.2% (worse)
Windows MinGW 386 CreateStop/LLGo 329.900 ns/op -73.8 ns/op / -18.3% (better)
Windows MinGW 386 RearmStopped/Go 58.450 ns/op -0.01 ns/op / -0.01711% (better)
Windows MinGW 386 RearmStopped/LLGo 231.800 ns/op +5.5 ns/op / +2.4% (worse)
Windows MinGW 386 ResetActive/Go 28 ns/op +0.08 ns/op / +0.3% (worse)
Windows MinGW 386 ResetActive/LLGo 737 ns/op +14.6 ns/op / +2.0% (worse)
Windows MinGW 386 ResetHeap1024/Go 28.060 ns/op +0.05 ns/op / +0.2% (worse)
Windows MinGW 386 ResetHeap1024/LLGo 108.200 ns/op +2.9 ns/op / +2.8% (worse)
Windows MinGW ARM64 AfterFuncZeroDelivery/Go 670.400 ns/op +5.6 ns/op / +0.8% (worse)
Windows MinGW ARM64 AfterFuncZeroDelivery/LLGo 147251 ns/op +4086 ns/op / +2.9% (worse)
Windows MinGW ARM64 CreateStop/Go 195.400 ns/op -3.2 ns/op / -1.6% (better)
Windows MinGW ARM64 CreateStop/LLGo 443.700 ns/op +74.1 ns/op / +20.0% (worse)
Windows MinGW ARM64 RearmStopped/Go 70.600 ns/op -0.62 ns/op / -0.9% (better)
Windows MinGW ARM64 RearmStopped/LLGo 215.800 ns/op -0.5 ns/op / -0.2% (better)
Windows MinGW ARM64 ResetActive/Go 30.940 ns/op -0.87 ns/op / -2.7% (better)
Windows MinGW ARM64 ResetActive/LLGo 123.500 ns/op -18.9 ns/op / -13.3% (better)
Windows MinGW ARM64 ResetHeap1024/Go 31.030 ns/op -0.05 ns/op / -0.2% (better)
Windows MinGW ARM64 ResetHeap1024/LLGo 109.800 ns/op -1.6 ns/op / -1.4% (better)
Windows MSVC AfterFuncZeroDelivery/Go 553.600 ns/op +1.3 ns/op / +0.2% (worse)
Windows MSVC AfterFuncZeroDelivery/LLGo 178090 ns/op -1093 ns/op / -0.6% (better)
Windows MSVC CreateStop/Go 115.400 ns/op -1.1 ns/op / -0.9% (better)
Windows MSVC CreateStop/LLGo 399.600 ns/op -15 ns/op / -3.6% (better)
Windows MSVC RearmStopped/Go 31.570 ns/op -0.23 ns/op / -0.7% (better)
Windows MSVC RearmStopped/LLGo 235.300 ns/op -0.3 ns/op / -0.1% (better)
Windows MSVC ResetActive/Go 20.150 ns/op -0.16 ns/op / -0.8% (better)
Windows MSVC ResetActive/LLGo 151.200 ns/op +12.8 ns/op / +9.2% (worse)
Windows MSVC ResetHeap1024/Go 20.660 ns/op +0.08 ns/op / +0.4% (worse)
Windows MSVC ResetHeap1024/LLGo 119.500 ns/op +2.6 ns/op / +2.2% (worse)
Windows MSVC 386 AfterFuncZeroDelivery/Go 1218 ns/op +253.8 ns/op / +26.3% (worse)
Windows MSVC 386 AfterFuncZeroDelivery/LLGo 203423 ns/op +1583 ns/op / +0.8% (worse)
Windows MSVC 386 CreateStop/Go 196.600 ns/op +2.6 ns/op / +1.3% (worse)
Windows MSVC 386 CreateStop/LLGo 451.200 ns/op -3.4 ns/op / -0.7% (better)
Windows MSVC 386 RearmStopped/Go 63.630 ns/op +0.02 ns/op / +0.03144% (worse)
Windows MSVC 386 RearmStopped/LLGo 297.300 ns/op -0.9 ns/op / -0.3% (better)
Windows MSVC 386 ResetActive/Go 39.120 ns/op -0.18 ns/op / -0.5% (better)
Windows MSVC 386 ResetActive/LLGo 946 ns/op -10.4 ns/op / -1.1% (better)
Windows MSVC 386 ResetHeap1024/Go 39.630 ns/op +0.06 ns/op / +0.2% (worse)
Windows MSVC 386 ResetHeap1024/LLGo 161.900 ns/op -0.8 ns/op / -0.5% (better)
Windows MSVC ARM64 AfterFuncZeroDelivery/Go 675 ns/op -0.3 ns/op / -0.04442% (better)
Windows MSVC ARM64 AfterFuncZeroDelivery/LLGo 150385 ns/op -3176 ns/op / -2.1% (better)
Windows MSVC ARM64 CreateStop/Go 196.700 ns/op -14.5 ns/op / -6.9% (better)
Windows MSVC ARM64 CreateStop/LLGo 337.600 ns/op -7.2 ns/op / -2.1% (better)
Windows MSVC ARM64 RearmStopped/Go 70.660 ns/op +0.1 ns/op / +0.1% (worse)
Windows MSVC ARM64 RearmStopped/LLGo 223.300 ns/op -0.4 ns/op / -0.2% (better)
Windows MSVC ARM64 ResetActive/Go 30.980 ns/op +0.02 ns/op / +0.1% (worse)
Windows MSVC ARM64 ResetActive/LLGo 111.900 ns/op +3.8 ns/op / +3.5% (worse)
Windows MSVC ARM64 ResetHeap1024/Go 31.010 ns/op +0.04 ns/op / +0.1% (worse)
Windows MSVC ARM64 ResetHeap1024/LLGo 116.600 ns/op 0 ns/op / +0.0%

Compared with 0a2ebb890b83 measured in the same runner job.

@zhouguangyuan0718
zhouguangyuan0718 force-pushed the codex/midway-fmv-followup-20261017 branch from 96958ae to 0e0e784 Compare October 18, 2026 03:51
@zhouguangyuan0718

Copy link
Copy Markdown
Collaborator Author

@fennoai /review

Please re-review the latest head 9a9b771bd237a18e433485a168e27f5ebb71c5de against main, including the full PR diff and the follow-up changes since your previous review.

The bridge peer-package lookup now has linear control flow, and the earlier missing-peer/import coverage tests remain in place. FMV bridge tests and Linux/Darwin/Windows O0/O2 Midway IR tests pass locally.

The previous inline findings have individual responses and dispositions. All three SIMD PRs also include the isolated native-debug harness fix from commit 2cc3c5b in #2849: disable external symbol lookup and stream LLDB progress. Their preceding Ubuntu jobs exhausted the job limit in native source-debug acceptance after SIMD tests passed; the fixed harness passes locally. The preceding coverage checks passed (this is not a claim about the fresh CI run).

Fresh CI has been triggered for this head and is still pending. Please report any remaining correctness, regression, or performance issues against this exact revision. Review only; no code changes are requested.

@fennoai

fennoai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Re-review: PR #2835 — preserve AVX2 specialization across Midway calls

Reviewed the exact revision 9a9b771bd237a18e433485a168e27f5ebb71c5de against base 0a2ebb890b83960eb218218af570a4c133c7ba0b, covering the full PR diff and the follow-up commits since the previous review (cl: clarify SIMD bridge peer resolution, cl: test rejected SIMD bridge identities, test: keep native debug acceptance independent of symbol servers). Ran code-quality, performance, security, and documentation passes, and verified the load-bearing claims directly against the code.

Verdict: No correctness, regression, or performance issues against this revision. The follow-up cleanly resolves the prior inline findings. Approve-equivalent; only one optional wording nit remains.

Follow-up changes verified

  • cl/simd_fmv.go — peer resolution refactor. simdFMVVector now extracts the simd/archsimd import first, nil-checks it, then does the scope lookup and types.Identical underlying comparison — linear control flow, functionally equivalent to the prior version, no dead code or logic drift. The missing-peer path (arch.Scope().Lookup(...) returning nil) is correctly funneled through the comma-ok *types.TypeName assertion, so it cannot panic.
  • cl/simd_bridge_test.go — rejected-identity coverage. The new cases precisely exercise each rejection branch introduced by the refactor: bridge package with no imports (nil arch), an unrelated import present, and the import present but no same-named peer. Combined with the existing wrong-package / pointer / mismatched-underlying cases, the negative coverage is thorough and clearly named.
  • test/debug/native/{runtest.sh,acceptance.py} — harness isolation fix. Disabling symbols.enable-external-lookup (in both the shell -O flag and create_session) keeps inferior launch and unwinding independent of external/remote symbol servers — an isolation improvement that matches the runtime debug suite. Variable definition order, quoting, and the tee + grep -Fq failure gate are all sound. Env values reach LLDB via os.environ[...] inside the Python one-liner rather than shell interpolation, so there is no injection surface; LLGO_NATIVE_DEBUG_SOURCE/LLDB_PATH/TMPDIR are harness-derived and consistently quoted.

Soundness of the core change

The bridge-type eligibility is conjunctive and tight: *types.Named in exactly simd/internal/bridge, that package importing simd/archsimd, a same-named peer that independently passes SIMDVectorShape (2-field struct, zero-sized v128 tag, 128-bit lane array, canonical name), and types.Identical underlyings. The result only drives MarkSIMDFMV (adding LLVM string function attributes); it never substitutes the type or alters lowering, so the "without changing their ABI" claim holds and a crafted/non-vector type cannot cause an ABI/codegen mismatch. Emulated bridge types correctly do not qualify.

Performance

No concern. For all non-SIMD code the function returns after an O(1) type assertion plus one or two package-path string compares; the import scan + lookup + types.Identical are reached only for genuine simd/internal/bridge types, and markSIMDFMV short-circuits entirely on non-amd64. The per-reference invocation of markSIMDFMV (cl/instr.go:739) is pre-existing and not modified by this PR, so it is not a regression here; caching is not warranted.

Minor (optional, non-blocking)

  • test/simd/README.md:210-212 — "The composition fixtures cover cross-package aggregates and arrays, function values, methods, interfaces, closures, generics, and initialization." The first seven map exactly to TestPortableFMVComposition, but initialization lives in a separate fixture (TestPortableFMVInit in fmv_init_amd64_llgo_test.go). The portable suite does exercise it, so the claim is true; only the attribution to the "composition fixtures" is slightly loose. Consider "The composition and initialization fixtures cover…".
  • test/debug/native/runtest.sh:26-33 — With set -euo pipefail, a hard LLDB crash aborts at the | tee pipeline via set -e, while an assertion failure inside acceptance.py (LLDB exits 0) is caught by the grep gate. Both failure modes fail the script, so detection is preserved; a one-line comment noting the two intentional layers would aid future readers. Not a defect.

CI for this head is still pending per the PR note; this review reflects static analysis of the exact revision, not the fresh CI run. No security concerns, and all prior inline findings are addressed or appropriately dispositioned.

View job run

@cpunion
cpunion merged commit 4d30b89 into xgo-dev:main Oct 19, 2026
107 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.

2 participants