Skip to content

Add LLVM 21 support while keeping LLVM 19 as default#35

Merged
xushiwei merged 7 commits intoxgo-dev:goplusfrom
zhouguangyuan0718:goplus_21
Mar 2, 2026
Merged

Add LLVM 21 support while keeping LLVM 19 as default#35
xushiwei merged 7 commits intoxgo-dev:goplusfrom
zhouguangyuan0718:goplus_21

Conversation

@zhouguangyuan0718
Copy link
Copy Markdown

Summary

This PR brings in the recent upstream TinyGo changes needed for LLVM 21 support, while keeping LLVM 19 as the default version in this branch.

Included changes

  • add LLVM 21 support
  • keep LLVM 19 as the default config
  • consolidate Darwin/Linux LLVM config files into unified per-version config files
  • add ExecutionEngine.NewJITCompiler and ExecutionEngine.GetFunctionAddress
  • apply the follow-up formatting fixes

Notes

  • LLVM 21 support is available via the llvm21 build tag
  • the default configuration still resolves to LLVM 19
  • the temporary FreeBSD CI change from upstream was also followed by its upstream removal, so the final workflow does not keep that job

Fixes #32

aykevl and others added 7 commits March 1, 2026 10:47
This matches TinyGo, where they are merged. It should make maintenance a
little bit easier, and also makes it easier to add new OSes (like
FreeBSD) without having to create a whole new set of files.
add ExecutionEngine.GetFunctionAddress()
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request updates the project to support LLVM 21, integrating recent upstream changes while maintaining LLVM 19 as the default version. It streamlines the LLVM configuration by consolidating platform-specific files into unified, version-based configurations and introduces new JIT compilation and function address retrieval functionalities.

Highlights

  • LLVM 21 Support: Added support for LLVM 21, integrating recent upstream changes.
  • Default LLVM Version: Maintained LLVM 19 as the default version for the project.
  • Configuration Consolidation: Consolidated platform-specific (Darwin/Linux) LLVM configuration files into unified, per-version configuration files.
  • New ExecutionEngine Functions: Introduced ExecutionEngine.NewJITCompiler for creating JIT compilers and ExecutionEngine.GetFunctionAddress for retrieving function addresses.
  • Code Formatting: Applied follow-up formatting fixes across the codebase.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • executionengine.go
    • Reordered import statements for unsafe and errors.
    • Added NewJITCompiler function to create a JIT compiler for a module.
    • Added GetFunctionAddress method to retrieve the address of a function.
  • ir.go
    • Removed LandingPadClause type definition and associated constants (LandingPadCatch, LandingPadFilter).
    • Removed ConstMul, ConstNSWMul, and ConstNUWMul constant multiplication functions.
  • ir_test.go
    • Removed "nocapture" from the list of tested attributes.
  • llvm_config_darwin_llvm14.go
    • Removed Darwin-specific LLVM 14 configuration file.
  • llvm_config_darwin_llvm15.go
    • Removed Darwin-specific LLVM 15 configuration file.
  • llvm_config_darwin_llvm16.go
    • Removed Darwin-specific LLVM 16 configuration file.
  • llvm_config_darwin_llvm17.go
    • Removed Darwin-specific LLVM 17 configuration file.
  • llvm_config_darwin_llvm18.go
    • Removed Darwin-specific LLVM 18 configuration file.
  • llvm_config_darwin_llvm19.go
    • Removed Darwin-specific LLVM 19 configuration file.
  • llvm_config_darwin_llvm20.go
    • Removed Darwin-specific LLVM 20 configuration file.
  • llvm_config_linux_llvm14.go
    • Removed Linux-specific LLVM 14 configuration file.
  • llvm_config_linux_llvm15.go
    • Removed Linux-specific LLVM 15 configuration file.
  • llvm_config_linux_llvm16.go
    • Removed Linux-specific LLVM 16 configuration file.
  • llvm_config_linux_llvm17.go
    • Removed Linux-specific LLVM 17 configuration file.
  • llvm_config_linux_llvm18.go
    • Removed Linux-specific LLVM 18 configuration file.
  • llvm_config_linux_llvm19.go
    • Removed Linux-specific LLVM 19 configuration file.
  • llvm_config_linux_llvm20.go
    • Removed Linux-specific LLVM 20 configuration file.
  • llvm_config_llvm14.go
    • Added consolidated LLVM 14 configuration file, supporting Darwin and Linux.
  • llvm_config_llvm15.go
    • Added consolidated LLVM 15 configuration file, supporting Darwin and Linux.
  • llvm_config_llvm16.go
    • Added consolidated LLVM 16 configuration file, supporting Darwin and Linux.
  • llvm_config_llvm17.go
    • Added consolidated LLVM 17 configuration file, supporting Darwin and Linux.
  • llvm_config_llvm18.go
    • Added consolidated LLVM 18 configuration file, supporting Darwin and Linux.
  • llvm_config_llvm19.go
    • Added consolidated LLVM 19 configuration file, supporting Darwin, FreeBSD, and Linux.
  • llvm_config_llvm20.go
    • Added consolidated LLVM 20 configuration file, supporting Darwin, FreeBSD, and Linux.
  • llvm_config_llvm21.go
    • Added consolidated LLVM 21 configuration file, supporting Darwin, FreeBSD, and Linux.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/go.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds support for LLVM 21 and refactors the LLVM build configuration files, which is a great improvement for maintainability. However, I've identified a critical issue in executionengine.go. A new function, NewJITCompiler, is introduced using a C function that has been removed in recent LLVM versions (including the targeted LLVM 19 and 21), which will cause build failures. I have provided a detailed comment and a code suggestion to resolve this.

Comment thread executionengine.go
Comment thread executionengine.go
return
}

func NewJITCompiler(m Module, optLevel int) (ee ExecutionEngine, err error) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ee.C = nil is redundant here — Go zero-initializes the named return value, so ee.C is already nil on entry and LLVMCreateJITCompilerForModule does not populate it on failure. The existing NewInterpreter omits this line for the same reason. Keeping it introduces a misleading asymmetry between the two constructors.

Comment thread executionengine.go
@@ -110,6 +112,17 @@ func NewInterpreter(m Module) (ee ExecutionEngine, err error) {
return
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

NewJITCompiler wraps LLVMCreateJITCompilerForModule, which is the legacy pre-MCJIT interface and has been deprecated by LLVM in favour of MCJIT (NewMCJITCompiler already exists in this package) and newer ORC/LLJIT APIs. A doc comment is needed to:

  1. Signal that this is the legacy JIT.
  2. Direct callers toward NewMCJITCompiler or ORC as the modern alternatives.

Without this, callers cannot distinguish between the two JIT constructors in the package.

Comment thread executionengine.go
@@ -159,6 +172,12 @@ func (ee ExecutionEngine) FindFunction(name string) (f Value) {
return
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LLVMGetFunctionAddress returns 0 when the function is not found (or on failure). The binding surfaces this as a uint64(0) with no accompanying error, making it impossible for callers to distinguish "function not found" from "function is at address 0". Callers who blindly cast the result to a function pointer and call it will dereference a null pointer.

Consider mirroring the pattern of FindFunction — either return (uint64, bool) or return 0 with documentation that callers must check for zero before use. At minimum, a doc comment is needed.

Additionally, per LLVM docs, getFunctionAddress may trigger JIT compilation rather than being a simple lookup. Callers who call this in a hot path for the same name should cache the result.

Comment thread llvm_config_llvm19.go
@@ -0,0 +1,19 @@
//go:build !byollvm && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm20 && !llvm21
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The build constraint is missing !llvm19. As written, this file activates both when no version tag is provided (acting as the default) and when -tags llvm19 is explicitly passed — which is likely intentional, but is not how any other versioned config is structured.

The risk: a future maintainer adding LLVM 22 who forgets to add !llvm22 here will silently get LLVM 19 paths in an LLVM 22 build. A short comment explaining the intentional omission and the "default fallback" pattern would prevent this.

Comment thread .github/workflows/go.yml
@@ -24,7 +24,7 @@ jobs:
# run: brew update
# Optional step when a LLVM version is very new.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The brew update guard was moved from llvm == 20 to llvm == 21, but not extended to cover 20. If the LLVM 20 Homebrew formula drifts or becomes unavailable without a brew update, macOS CI for LLVM 20 will silently fail or use a stale index. The original intent was to run brew update for the newest/freshest version. Now that 21 is the newest, consider whether 20 also still needs it, or document why only 21 requires this step.

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Mar 1, 2026

The consolidation of per-OS config files and LLVM 21 CI support are clean improvements. Two broader issues worth addressing:

Breaking API removalsLandingPadClause, LandingPadCatch, LandingPadFilter, ConstMul, ConstNSWMul, ConstNUWMul are exported symbols removed without prior deprecation. Downstream consumers will get hard compile errors. If these were dropped because LLVM 21 removed the underlying C API, that should be noted somewhere (changelog, commit message, or build-tag-guarded stub).

READMEREADME.markdown still lists LLVM 20 as the maximum supported version; LLVM 21 should be added to both the macOS and Linux lines.

@xushiwei xushiwei merged commit cb01f6c into xgo-dev:goplus Mar 2, 2026
32 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.

llvm21 support

3 participants