chore: upgrade default LLVM toolchain to 22 - #2470
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
LLGo baseline benchmarks
Program measurements
Core language and compiler benchmarks
Timer runtime benchmarks
Compared with |
0230937 to
1215cd0
Compare
2c9e521 to
f06d15e
Compare
LLGo WebAssembly build benchmarks
WebAssembly output sizes
LLGo WebAssembly build measurements
Compared with |
720c60b to
2d37a57
Compare
92bca18 to
7f9f06b
Compare
There was a problem hiding this comment.
Review: LLVM 19 → LLVM 22 upgrade
Overall this is a well-structured toolchain upgrade. The compiled-library cache-key refactor (keying on compiler version + codegen flags), the streaming SHA256 verification of downloaded ESP Clang archives (fail-closed on a missing checksum), and the dcepass switch to IsStructOpaque() are all solid, and each is backed by targeted tests. No correctness or performance blockers found.
A few points below, plus one pre-existing security note surfaced for follow-up (not introduced by this PR):
- Pre-existing zip-slip gap in
extractZip(internal/crosscompile/fetch.go). UnlikeextractTarGz,extractZipjoins the archive-controlled entry name into the destination with no containment check, and it's reachable via the unauthenticated picolibc.zipdownload (no checksum on that path). Out of this PR's diff, so not blocking — but worth mirroring the tar guard (reject../absolute names, requirefilepath.Clean(dest)+sepprefix) in a follow-up now that the codebase relies on archive integrity elsewhere.
Verified as correct: the new -gnu linux triple leaves ARM on -gnueabihf; ESP Clang checksum enforcement cannot reach extraction with an empty hash (map-miss errors out, all five entries populated); the per-build clang --version probe runs once per UseTarget, not in any hot path.
This is the main-based LLVM 22 upgrade. It supersedes #2334 rather than stacking LLVM 22 changes onto the LLVM 21 PR.
Exact base:
714e8c6eff9fa5c51e037a89f05af9a6a6c80986Exact head:
052e23226d90e235dcd8bef5f9933cdf5723643fScope
github.com/xgo-dev/llvm v0.9.922.1.4_20260905for named embedded targets on every supported host, including Windows, with pinned checksums and toolchain-aware cross-library cachesxtensa_release_22.1.4_20260903The wasm64 closure CodeGen issue is fixed independently by #2496, which is now part of this PR's base. This branch retains that
nonnullallocation contract and its optimized CodeGen/runtime tests; it does not carry the earlier volatile code-pointer barrier or require dynamic closure calls to remain indirect.Plan9ASM remains covered by the repository tests; no Plan9ASM source change is required.
Deliberately excluded
The branch keeps the LLVM 22 upgrade, direct LLVM 22 IR expectations, the released full-target ESP payload switch, and a focused CI cleanup. It does not contain:
internal/llvmpayloadpackage/CLI and runtime version parsercompiler.used, inline-asm keepalive,llvm.reloc.none, or LTO modernizationLLGO_WINDOWS_EMBEDDED_CLANG_ROOTReleased dependencies
github.com/xgo-dev/llvm v0.9.9github.com/goplus/lib v0.5.1github.com/goplus/compiler-rt@xtensa_release_22.1.4_20260903github.com/goplus/espressif-llvm-project-prebuilt@22.1.4_20260905No personal-fork module replacement, temporary dependency branch, or unstable payload URL remains.
Windows ESP selection test repair
Commit
2d37a571b69868ce0abc24c3f304e90fd2d91814fixes the test fixture responsible for both Windows coverage-job failures on the previous head. The old fixture created an empty toolchain cache directory, butUseTargetmust executeclang++ --versionfor its library cache key.Local validation with host LLVM 22.1.8 and released ESP LLVM 22.1.4_20260905: all five focused tests pass (
TestUseTargetESPClang,TestESPClangHostDownload,TestUseTargetESPClangDownloadError,TestCompilerVersionCacheKey,TestCompilerCacheKeyErrors). The selection test actually builds RP2040 picolibc and compiler-rt. A local-only Go test overlay redirects the cache root to an isolated directory; it does not replace the compiler or test assertions. Formatting andgit diff --checkpass. Windows execution remains pending at the new exact head.CI setup cleanup
Commit
61c15cd5dremoves four redundant setup changes without changing compiler/runtime code or dependency pins:EM_LLVM_ROOToverrides from both workflows; the SDK's own configuration selects its target LLVM.Validation for this CI-only cleanup:
git diff --checkpassesEM_LLVM_ROOTunset, Emscripten selects its SDK compiler/linker and passes a C-to-WebAssembly compile/link/Node execution smoke test using an isolated build directory and fresh cachePrior upgrade validation (before this CI-only cleanup)
git diff --check, conflict-marker and obsolete closure/toolchain-workaround scans: passgo test ./ssa -count=1: pass, using the actual generated IR without normalizationencoding/json/v2reproducer: pass33908361034: all five platform builds, native Windows validation, and release job passRebase onto current main (2026-09-05)
Rebased onto
714e8c6eff9fa5c51e037a89f05af9a6a6c80986, including main's runner fixes from #2476. The five failed Linux runner jobs on old head720c60b9f634e88f799f37386d3901c67566632cfailed during Go setup withEACCES: permission denied, mkdir '/opt/go', before compilation/tests. Main now configures writable Go paths underRUNNER_TEMPand updates runner placement; this PR preserves those changes instead of adding an upgrade-specific workaround.Resolved only the three workflow conflicts by combining main's runner selections with LLVM 22. All job runner selections match main, and setup-go is byte-for-byte identical to main. Range-diff confirms the five later commits retain their original patches.
Validation after rebase: all 29 action/workflow YAML files parse; actionlint passes for build-cache, llgo, targets, benchmark, and go workflows with the existing
qiniucustom runner label declared in a local-only config (shellcheck/pyflakes disabled). Diff/conflict-marker checks pass. Focusedgo testruns pass for crosscompile ESP selection/cache keys, SSA struct comparison/TargetMachine, and compiler large-struct comparison under LLVM 22.1.8 with isolated task caches. Full host/target CI must run again at the new exact head.Review follow-up (2026-09-05)
Commit
104aec559defc032c9f97b180878ef8b2974c4c5implements three requested scope corrections:c++tomsvcprtmapping and its added test/import. Both internal/build files now match main. The released lib already has a Windows-specific C++ link configuration.Validation: focused internal/build package/link-argument tests pass; 29 YAML files parse; workflow actionlint passes with the main custom runner label declared locally; all Docker RUN shell syntax checks pass; a stubbed apt harness passes first-success, retry-success and retry-failure paths and confirms both attempts request identical LLVM 22 packages. Diff checks pass. A native Windows run and a full Docker image build were not performed locally (Docker daemon did not respond); new-head CI is pending.
Win32 LLDB investigation, not a toolchain change in this commit: the immutable
mstorsjo/llvm-mingwrelease20260616containsllvm-mingw-20260616-ucrt-i686.zip(SHA-256c68b26561883d5c7f33307aeb2b9b6c188eb705808b3f780dfce0be49f4e835d). Download/checksum and extracted PE headers confirm native i386 LLDB plus Python 3.14 and the LLDB Python extension. liblldb contains version 22.1.8. Its tagged workflow builds i686 with Python and includes native LLDB breakpoint/backtrace tests. This is a concrete candidate to restore full 386 debugging; LLGo's MSVC/MinGW suites have not yet been run with it. At that commit,load-onlywas still unchanged; it is removed by the native Win32 LLDB follow-up below.Native Win32 LLDB and restored full tests
Commit
460e9925bfce6480131d08e03c3c5df1454ea9d4switches both Windows 386 ABI profiles to the pinned llvm-mingw 20260616 i686 LLDB 22.1.8 payload described above. The cache preserves the debugger's bundled DLLs and Python 3.14 layout, with a new cache key. The debugger directory is not placed on the compiler/target runtime's global PATH. Only the debugger setup check uses it in its step-local PATH.--load-onlyand both workflow bypasses.cmd/llgo/lldbtest/runtest.shmatches main byte-for-byte; both Go variable-formatting and mixed Go/C fault/backtrace suites execute for 386 MSVC and MinGW.Local verification: immutable archive SHA-256 passes; PE headers confirm i386 debugger/Python, and direct DLL imports match bundled libraries or Windows system libraries. All 29 YAML files parse; 16 PowerShell blocks parse with PowerShell's parser; 38 Bash/MSYS2 blocks plus runtest.sh parse; actionlint passes with the existing custom runner label configured locally; diff and removed-option scans pass. This CI/test-harness change does not alter compiler source or Go dependencies; no full Go suite was rerun locally. Native Windows LLDB launch, Python initialization, source breakpoints, variables and mixed-stack execution must pass at the new exact CI head; they have not been claimed as locally validated.
Hello World standalone dependency correction
Commit
92946954a111316e32131077482f1a17752ce344updates only the standalone module created bydev/test_helloworld.sh, fromgoplus/lib v0.3.1to the same releasedv0.5.1used by this PR. The Windows ARM64 MSVC job on head460e9925bfailed before LLDB withlld-link: error: could not open 'c++.lib'. The script's independently pinned old lib still declareslink: c++and lacks the current Windows string layout; the root go.mod update does not affect this temporary module. The compiler-side runtime-name mapping remains removed. All Hello World output assertions, the Go module-version matrix, and embedded test logic are unchanged.Local verification: built the current LLGo with LLVM 22.1.8 and ran the native Hello World smoke for go.mod 1.21 through 1.27 under Go 1.27.0 on macOS arm64; all seven pass including C++ string output. A local-only build overlay redirects LLGo's runtime cache into the task directory. Local smoke runs use the existing
LLGO_HELLO_EMBED=falseoption; embedded checks remain enabled in the CI Go 1.27 step and were not revalidated locally here. Windows ARM64 package selection resolves v0.5.1's config_windows.go and string_type_windows.go. Bash syntax and diff checks pass; native Windows execution awaits new-head CI.On the superseded head, three Linux jobs failed from runner disk exhaustion; populate-linux-sysroot failed downloading Debian security packages (HTTP 404), leaving rsync unavailable and dependent artifact/release jobs skipped. Those are not source-test passes. Job rerun remains unavailable to the current account (GitHub 403, no repository push/admin permission); no runner settings or release tags were changed.
Checksum error-path tests
Commit
92bca1838bc755aa12f43309db1066dba8a36d3fadds only two unit tests (27 lines). After all four coverage uploads for head92946954acompleted, Codecov reported 93.54% patch coverage against 94.24%, with six uncovered added lines. The tests exercise rejection of a missing host payload checksum and hashing a missing file/directory. Five focused crosscompile tests pass locally with LLVM 22.1.8; the coverage profile confirms the missing-checksum return and both file-hash error returns execute. No production code, CI configuration, coverage threshold, or existing assertions changed. New exact-head coverage and full CI remain pending.Rebase onto Debian 12 release baseline (2026-09-05)
Rebased onto
714e8c6eff9fa5c51e037a89f05af9a6a6c80986, which includes merged #2504. The upstream sysroot script is retained byte-for-byte: it uses pinned Debian 12 amd64/arm64 images, GCC 12 headers/libraries, package download retries, and explicit layout checks. Conflict resolution in.goreleaser.yamlkeeps those Debian 12/GCC 12 paths and changes only the four platform link entries from LLVM 19 to LLVM 22 relative to main.Range-diff shows the other nine LLVM 22 commits are patch-identical. YAML parsing, sysroot shell syntax, conflict-marker and obsolete Debian 11/GCC 10 scans pass. Actionlint passes with shellcheck/pyflakes disabled and the repository's custom runner label declared locally. PR #2504's exact-head CI passed sysroot population, GoReleaser build, and all four release-artifact smoke tests; the combined LLVM 22 branch must pass those checks again at the new exact head.
Review follow-up after rebase
Commit
052e23226d90e235dcd8bef5f9933cdf5723643faddresses both new review threads without changing behavior: README now documents the actual LLDB candidate search and explicit overrides, and compiled-library cache parameters use the namecompiledLibraryKeyconsistently. Four focused crosscompile cache/config tests pass locally with LLVM 22.1.8; formatting and diff checks pass. Both review threads are resolved.CI
CI must be evaluated at exact head
052e23226d90e235dcd8bef5f9933cdf5723643f. Pending checks are not counted as passing. The earlier empty-commit retry and all older-head results are historical only.Windows 386 now runs the full LLDB suites with native i686 LLDB; pending checks are not debugger validation. A failed Windows benchmark base build still yields unavailable base comparisons, not a passing performance comparison.