From 63740cfada080d0f24ae3db2b185f32452a7e328 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 16 Sep 2025 11:24:58 +0200 Subject: [PATCH 1/9] LLVM 21 support --- .github/workflows/test.yml | 9 ++++----- ir.go | 13 ------------- ir_test.go | 1 - llvm_config_darwin_llvm20.go | 2 +- llvm_config_darwin_llvm21.go | 15 +++++++++++++++ llvm_config_linux_llvm20.go | 2 +- llvm_config_linux_llvm21.go | 10 ++++++++++ 7 files changed, 31 insertions(+), 21 deletions(-) create mode 100644 llvm_config_darwin_llvm21.go create mode 100644 llvm_config_linux_llvm21.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bed9b95..8946fd3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: runs-on: macos-latest strategy: matrix: - llvm: [14, 15, 16, 17, 18, 19, 20] + llvm: [14, 15, 16, 17, 18, 19, 20, 21] steps: - name: Checkout uses: actions/checkout@v4 @@ -20,7 +20,6 @@ jobs: go-version: '1.22' # Optional step when a LLVM version is very new. - name: Update Homebrew - if: matrix.llvm == 20 run: brew update - name: Install LLVM run: HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@${{ matrix.llvm }} @@ -28,14 +27,14 @@ jobs: run: go test -v -tags=llvm${{ matrix.llvm }} - name: Test default LLVM - if: matrix.llvm == 20 + if: matrix.llvm == 21 run: go test -v test-linux: runs-on: ubuntu-22.04 strategy: matrix: - llvm: [14, 15, 16, 17, 18, 19, 20] + llvm: [14, 15, 16, 17, 18, 19, 20, 21] steps: - name: Checkout uses: actions/checkout@v4 @@ -53,6 +52,6 @@ jobs: run: go test -v -tags=llvm${{ matrix.llvm }} - name: Test default LLVM - if: matrix.llvm == 20 + if: matrix.llvm == 21 run: go test -v diff --git a/ir.go b/ir.go index 7e03ec6..efb0de1 100644 --- a/ir.go +++ b/ir.go @@ -76,7 +76,6 @@ type ( ComdatSelectionKind C.LLVMComdatSelectionKind IntPredicate C.LLVMIntPredicate FloatPredicate C.LLVMRealPredicate - LandingPadClause C.LLVMLandingPadClauseTy InlineAsmDialect C.LLVMInlineAsmDialect ) @@ -344,15 +343,6 @@ const ( FloatPredicateTrue FloatPredicate = C.LLVMRealPredicateTrue ) -//------------------------------------------------------------------------- -// llvm.LandingPadClause -//------------------------------------------------------------------------- - -const ( - LandingPadCatch LandingPadClause = C.LLVMLandingPadCatch - LandingPadFilter LandingPadClause = C.LLVMLandingPadFilter -) - //------------------------------------------------------------------------- // llvm.InlineAsmDialect //------------------------------------------------------------------------- @@ -928,9 +918,6 @@ func ConstNUWAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWAdd(lhs.C, rhs. func ConstSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSub(lhs.C, rhs.C); return } func ConstNSWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWSub(lhs.C, rhs.C); return } func ConstNUWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWSub(lhs.C, rhs.C); return } -func ConstMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstMul(lhs.C, rhs.C); return } -func ConstNSWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWMul(lhs.C, rhs.C); return } -func ConstNUWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWMul(lhs.C, rhs.C); return } func ConstXor(lhs, rhs Value) (v Value) { v.C = C.LLVMConstXor(lhs.C, rhs.C); return } func ConstGEP(t Type, v Value, indices []Value) (rv Value) { diff --git a/ir_test.go b/ir_test.go index 57b306f..a912aec 100644 --- a/ir_test.go +++ b/ir_test.go @@ -62,7 +62,6 @@ func TestAttributes(t *testing.T) { "nest", "noalias", "nobuiltin", - "nocapture", "noduplicate", "noimplicitfloat", "noinline", diff --git a/llvm_config_darwin_llvm20.go b/llvm_config_darwin_llvm20.go index 22d2826..880e0d0 100644 --- a/llvm_config_darwin_llvm20.go +++ b/llvm_config_darwin_llvm20.go @@ -1,4 +1,4 @@ -//go:build !byollvm && darwin && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 +//go:build !byollvm && darwin && llvm20 package llvm diff --git a/llvm_config_darwin_llvm21.go b/llvm_config_darwin_llvm21.go new file mode 100644 index 0000000..1bc7c3c --- /dev/null +++ b/llvm_config_darwin_llvm21.go @@ -0,0 +1,15 @@ +//go:build !byollvm && darwin && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20 + +package llvm + +// Automatically generated by `make config BUILDDIR=`, do not edit. + +// #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@21/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo amd64 CXXFLAGS: -std=c++17 +// #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@21/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@21/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo arm64 CXXFLAGS: -std=c++17 +// #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@21/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +import "C" + +type run_build_sh int diff --git a/llvm_config_linux_llvm20.go b/llvm_config_linux_llvm20.go index a610933..90c8b9b 100644 --- a/llvm_config_linux_llvm20.go +++ b/llvm_config_linux_llvm20.go @@ -1,4 +1,4 @@ -//go:build !byollvm && linux && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 +//go:build !byollvm && linux && llvm20 package llvm diff --git a/llvm_config_linux_llvm21.go b/llvm_config_linux_llvm21.go new file mode 100644 index 0000000..00c0560 --- /dev/null +++ b/llvm_config_linux_llvm21.go @@ -0,0 +1,10 @@ +//go:build !byollvm && linux && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20 + +package llvm + +// #cgo CPPFLAGS: -I/usr/include/llvm-21 -I/usr/include/llvm-c-21 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo CXXFLAGS: -std=c++17 +// #cgo LDFLAGS: -L/usr/lib/llvm-21/lib -lLLVM-21 +import "C" + +type run_build_sh int From 12a422f411a96d40c8f5c7318b714d12dcb2625c Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 16 Sep 2025 17:01:18 +0200 Subject: [PATCH 2/9] Move the separate darwin/linux config files into one 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. --- llvm_config_darwin_llvm14.go | 15 --------------- llvm_config_darwin_llvm15.go | 15 --------------- llvm_config_darwin_llvm16.go | 15 --------------- llvm_config_darwin_llvm17.go | 15 --------------- llvm_config_darwin_llvm18.go | 15 --------------- llvm_config_darwin_llvm19.go | 15 --------------- llvm_config_darwin_llvm20.go | 15 --------------- llvm_config_darwin_llvm21.go | 15 --------------- llvm_config_linux_llvm14.go | 10 ---------- llvm_config_linux_llvm15.go | 10 ---------- llvm_config_linux_llvm16.go | 10 ---------- llvm_config_linux_llvm17.go | 10 ---------- llvm_config_linux_llvm18.go | 10 ---------- llvm_config_linux_llvm19.go | 10 ---------- llvm_config_linux_llvm20.go | 10 ---------- llvm_config_linux_llvm21.go | 10 ---------- llvm_config_llvm14.go | 16 ++++++++++++++++ llvm_config_llvm15.go | 16 ++++++++++++++++ llvm_config_llvm16.go | 16 ++++++++++++++++ llvm_config_llvm17.go | 16 ++++++++++++++++ llvm_config_llvm18.go | 16 ++++++++++++++++ llvm_config_llvm19.go | 16 ++++++++++++++++ llvm_config_llvm20.go | 16 ++++++++++++++++ llvm_config_llvm21.go | 16 ++++++++++++++++ 24 files changed, 128 insertions(+), 200 deletions(-) delete mode 100644 llvm_config_darwin_llvm14.go delete mode 100644 llvm_config_darwin_llvm15.go delete mode 100644 llvm_config_darwin_llvm16.go delete mode 100644 llvm_config_darwin_llvm17.go delete mode 100644 llvm_config_darwin_llvm18.go delete mode 100644 llvm_config_darwin_llvm19.go delete mode 100644 llvm_config_darwin_llvm20.go delete mode 100644 llvm_config_darwin_llvm21.go delete mode 100644 llvm_config_linux_llvm14.go delete mode 100644 llvm_config_linux_llvm15.go delete mode 100644 llvm_config_linux_llvm16.go delete mode 100644 llvm_config_linux_llvm17.go delete mode 100644 llvm_config_linux_llvm18.go delete mode 100644 llvm_config_linux_llvm19.go delete mode 100644 llvm_config_linux_llvm20.go delete mode 100644 llvm_config_linux_llvm21.go create mode 100644 llvm_config_llvm14.go create mode 100644 llvm_config_llvm15.go create mode 100644 llvm_config_llvm16.go create mode 100644 llvm_config_llvm17.go create mode 100644 llvm_config_llvm18.go create mode 100644 llvm_config_llvm19.go create mode 100644 llvm_config_llvm20.go create mode 100644 llvm_config_llvm21.go diff --git a/llvm_config_darwin_llvm14.go b/llvm_config_darwin_llvm14.go deleted file mode 100644 index 2a3c8a9..0000000 --- a/llvm_config_darwin_llvm14.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !byollvm && darwin && llvm14 - -package llvm - -// Automatically generated by `make config BUILDDIR=`, do not edit. - -// #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@14/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo amd64 CXXFLAGS: -std=c++14 -// #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@14/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@14/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo arm64 CXXFLAGS: -std=c++14 -// #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@14/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -import "C" - -type run_build_sh int diff --git a/llvm_config_darwin_llvm15.go b/llvm_config_darwin_llvm15.go deleted file mode 100644 index 07a72fc..0000000 --- a/llvm_config_darwin_llvm15.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !byollvm && darwin && llvm15 - -package llvm - -// Automatically generated by `make config BUILDDIR=`, do not edit. - -// #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@15/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo amd64 CXXFLAGS: -std=c++14 -// #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@15/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@15/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo arm64 CXXFLAGS: -std=c++14 -// #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@15/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -import "C" - -type run_build_sh int diff --git a/llvm_config_darwin_llvm16.go b/llvm_config_darwin_llvm16.go deleted file mode 100644 index 2acf0b0..0000000 --- a/llvm_config_darwin_llvm16.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !byollvm && darwin && llvm16 - -package llvm - -// Automatically generated by `make config BUILDDIR=`, do not edit. - -// #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@16/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo amd64 CXXFLAGS: -std=c++17 -// #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@16/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@16/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo arm64 CXXFLAGS: -std=c++17 -// #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@16/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -import "C" - -type run_build_sh int diff --git a/llvm_config_darwin_llvm17.go b/llvm_config_darwin_llvm17.go deleted file mode 100644 index 3dc8f26..0000000 --- a/llvm_config_darwin_llvm17.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !byollvm && darwin && llvm17 - -package llvm - -// Automatically generated by `make config BUILDDIR=`, do not edit. - -// #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@17/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo amd64 CXXFLAGS: -std=c++17 -// #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@17/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@17/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo arm64 CXXFLAGS: -std=c++17 -// #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@17/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -import "C" - -type run_build_sh int diff --git a/llvm_config_darwin_llvm18.go b/llvm_config_darwin_llvm18.go deleted file mode 100644 index 744a11e..0000000 --- a/llvm_config_darwin_llvm18.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !byollvm && darwin && llvm18 - -package llvm - -// Automatically generated by `make config BUILDDIR=`, do not edit. - -// #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@18/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo amd64 CXXFLAGS: -std=c++17 -// #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@18/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@18/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo arm64 CXXFLAGS: -std=c++17 -// #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@18/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -import "C" - -type run_build_sh int diff --git a/llvm_config_darwin_llvm19.go b/llvm_config_darwin_llvm19.go deleted file mode 100644 index eae7744..0000000 --- a/llvm_config_darwin_llvm19.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !byollvm && darwin && llvm19 - -package llvm - -// Automatically generated by `make config BUILDDIR=`, do not edit. - -// #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@19/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo amd64 CXXFLAGS: -std=c++17 -// #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@19/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@19/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo arm64 CXXFLAGS: -std=c++17 -// #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@19/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -import "C" - -type run_build_sh int diff --git a/llvm_config_darwin_llvm20.go b/llvm_config_darwin_llvm20.go deleted file mode 100644 index 880e0d0..0000000 --- a/llvm_config_darwin_llvm20.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !byollvm && darwin && llvm20 - -package llvm - -// Automatically generated by `make config BUILDDIR=`, do not edit. - -// #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@20/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo amd64 CXXFLAGS: -std=c++17 -// #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@20/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@20/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo arm64 CXXFLAGS: -std=c++17 -// #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@20/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -import "C" - -type run_build_sh int diff --git a/llvm_config_darwin_llvm21.go b/llvm_config_darwin_llvm21.go deleted file mode 100644 index 1bc7c3c..0000000 --- a/llvm_config_darwin_llvm21.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !byollvm && darwin && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20 - -package llvm - -// Automatically generated by `make config BUILDDIR=`, do not edit. - -// #cgo amd64 CPPFLAGS: -I/usr/local/opt/llvm@21/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo amd64 CXXFLAGS: -std=c++17 -// #cgo amd64 LDFLAGS: -L/usr/local/opt/llvm@21/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@21/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo arm64 CXXFLAGS: -std=c++17 -// #cgo arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@21/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -import "C" - -type run_build_sh int diff --git a/llvm_config_linux_llvm14.go b/llvm_config_linux_llvm14.go deleted file mode 100644 index 3f91a53..0000000 --- a/llvm_config_linux_llvm14.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !byollvm && linux && llvm14 - -package llvm - -// #cgo CPPFLAGS: -I/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo CXXFLAGS: -std=c++14 -// #cgo LDFLAGS: -L/usr/lib/llvm-14/lib -lLLVM-14 -import "C" - -type run_build_sh int diff --git a/llvm_config_linux_llvm15.go b/llvm_config_linux_llvm15.go deleted file mode 100644 index 607ed7e..0000000 --- a/llvm_config_linux_llvm15.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !byollvm && linux && llvm15 - -package llvm - -// #cgo CPPFLAGS: -I/usr/lib/llvm-15/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo CXXFLAGS: -std=c++14 -// #cgo LDFLAGS: -L/usr/lib/llvm-15/lib -lLLVM-15 -import "C" - -type run_build_sh int diff --git a/llvm_config_linux_llvm16.go b/llvm_config_linux_llvm16.go deleted file mode 100644 index 4208cf4..0000000 --- a/llvm_config_linux_llvm16.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !byollvm && linux && llvm16 - -package llvm - -// #cgo CPPFLAGS: -I/usr/lib/llvm-16/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo CXXFLAGS: -std=c++17 -// #cgo LDFLAGS: -L/usr/lib/llvm-16/lib -lLLVM-16 -import "C" - -type run_build_sh int diff --git a/llvm_config_linux_llvm17.go b/llvm_config_linux_llvm17.go deleted file mode 100644 index f2951d7..0000000 --- a/llvm_config_linux_llvm17.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !byollvm && linux && llvm17 - -package llvm - -// #cgo CPPFLAGS: -I/usr/include/llvm-17 -I/usr/include/llvm-c-17 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo CXXFLAGS: -std=c++17 -// #cgo LDFLAGS: -L/usr/lib/llvm-17/lib -lLLVM-17 -import "C" - -type run_build_sh int diff --git a/llvm_config_linux_llvm18.go b/llvm_config_linux_llvm18.go deleted file mode 100644 index a4bbea0..0000000 --- a/llvm_config_linux_llvm18.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !byollvm && linux && llvm18 - -package llvm - -// #cgo CPPFLAGS: -I/usr/include/llvm-18 -I/usr/include/llvm-c-18 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo CXXFLAGS: -std=c++17 -// #cgo LDFLAGS: -L/usr/lib/llvm-18/lib -lLLVM-18 -import "C" - -type run_build_sh int diff --git a/llvm_config_linux_llvm19.go b/llvm_config_linux_llvm19.go deleted file mode 100644 index ec7c36a..0000000 --- a/llvm_config_linux_llvm19.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !byollvm && linux && llvm19 - -package llvm - -// #cgo CPPFLAGS: -I/usr/include/llvm-19 -I/usr/include/llvm-c-19 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo CXXFLAGS: -std=c++17 -// #cgo LDFLAGS: -L/usr/lib/llvm-19/lib -lLLVM-19 -import "C" - -type run_build_sh int diff --git a/llvm_config_linux_llvm20.go b/llvm_config_linux_llvm20.go deleted file mode 100644 index 90c8b9b..0000000 --- a/llvm_config_linux_llvm20.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !byollvm && linux && llvm20 - -package llvm - -// #cgo CPPFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo CXXFLAGS: -std=c++17 -// #cgo LDFLAGS: -L/usr/lib/llvm-20/lib -lLLVM-20 -import "C" - -type run_build_sh int diff --git a/llvm_config_linux_llvm21.go b/llvm_config_linux_llvm21.go deleted file mode 100644 index 00c0560..0000000 --- a/llvm_config_linux_llvm21.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !byollvm && linux && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20 - -package llvm - -// #cgo CPPFLAGS: -I/usr/include/llvm-21 -I/usr/include/llvm-c-21 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo CXXFLAGS: -std=c++17 -// #cgo LDFLAGS: -L/usr/lib/llvm-21/lib -lLLVM-21 -import "C" - -type run_build_sh int diff --git a/llvm_config_llvm14.go b/llvm_config_llvm14.go new file mode 100644 index 0000000..9d38a5b --- /dev/null +++ b/llvm_config_llvm14.go @@ -0,0 +1,16 @@ +//go:build !byollvm && llvm14 + +package llvm + +// #cgo darwin,amd64 CPPFLAGS: -I/usr/local/opt/llvm@14/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,amd64 CXXFLAGS: -std=c++14 +// #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@14/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@14/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,arm64 CXXFLAGS: -std=c++14 +// #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@14/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo linux CPPFLAGS: -I/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CXXFLAGS: -std=c++14 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-14/lib -lLLVM-14 +import "C" + +type run_build_sh int diff --git a/llvm_config_llvm15.go b/llvm_config_llvm15.go new file mode 100644 index 0000000..34aebc0 --- /dev/null +++ b/llvm_config_llvm15.go @@ -0,0 +1,16 @@ +//go:build !byollvm && llvm15 + +package llvm + +// #cgo darwin,amd64 CPPFLAGS: -I/usr/local/opt/llvm@15/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,amd64 CXXFLAGS: -std=c++14 +// #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@15/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@15/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,arm64 CXXFLAGS: -std=c++14 +// #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@15/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo linux CPPFLAGS: -I/usr/lib/llvm-15/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CXXFLAGS: -std=c++14 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-15/lib -lLLVM-15 +import "C" + +type run_build_sh int diff --git a/llvm_config_llvm16.go b/llvm_config_llvm16.go new file mode 100644 index 0000000..936ca0f --- /dev/null +++ b/llvm_config_llvm16.go @@ -0,0 +1,16 @@ +//go:build !byollvm && llvm16 + +package llvm + +// #cgo darwin,amd64 CPPFLAGS: -I/usr/local/opt/llvm@16/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,amd64 CXXFLAGS: -std=c++17 +// #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@16/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@16/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,arm64 CXXFLAGS: -std=c++17 +// #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@16/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo linux CPPFLAGS: -I/usr/lib/llvm-16/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CXXFLAGS: -std=c++17 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-16/lib -lLLVM-16 +import "C" + +type run_build_sh int diff --git a/llvm_config_llvm17.go b/llvm_config_llvm17.go new file mode 100644 index 0000000..6a00b39 --- /dev/null +++ b/llvm_config_llvm17.go @@ -0,0 +1,16 @@ +//go:build !byollvm && llvm17 + +package llvm + +// #cgo darwin,amd64 CPPFLAGS: -I/usr/local/opt/llvm@17/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,amd64 CXXFLAGS: -std=c++17 +// #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@17/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@17/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,arm64 CXXFLAGS: -std=c++17 +// #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@17/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo linux CPPFLAGS: -I/usr/include/llvm-17 -I/usr/include/llvm-c-17 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CXXFLAGS: -std=c++17 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-17/lib -lLLVM-17 +import "C" + +type run_build_sh int diff --git a/llvm_config_llvm18.go b/llvm_config_llvm18.go new file mode 100644 index 0000000..c41fea0 --- /dev/null +++ b/llvm_config_llvm18.go @@ -0,0 +1,16 @@ +//go:build !byollvm && llvm18 + +package llvm + +// #cgo darwin,amd64 CPPFLAGS: -I/usr/local/opt/llvm@18/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,amd64 CXXFLAGS: -std=c++17 +// #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@18/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@18/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,arm64 CXXFLAGS: -std=c++17 +// #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@18/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo linux CPPFLAGS: -I/usr/include/llvm-18 -I/usr/include/llvm-c-18 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CXXFLAGS: -std=c++17 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-18/lib -lLLVM-18 +import "C" + +type run_build_sh int diff --git a/llvm_config_llvm19.go b/llvm_config_llvm19.go new file mode 100644 index 0000000..29e2246 --- /dev/null +++ b/llvm_config_llvm19.go @@ -0,0 +1,16 @@ +//go:build !byollvm && llvm19 + +package llvm + +// #cgo darwin,amd64 CPPFLAGS: -I/usr/local/opt/llvm@19/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,amd64 CXXFLAGS: -std=c++17 +// #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@19/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@19/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,arm64 CXXFLAGS: -std=c++17 +// #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@19/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo linux CPPFLAGS: -I/usr/include/llvm-19 -I/usr/include/llvm-c-19 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CXXFLAGS: -std=c++17 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-19/lib -lLLVM-19 +import "C" + +type run_build_sh int diff --git a/llvm_config_llvm20.go b/llvm_config_llvm20.go new file mode 100644 index 0000000..e0ca6a6 --- /dev/null +++ b/llvm_config_llvm20.go @@ -0,0 +1,16 @@ +//go:build !byollvm && llvm20 + +package llvm + +// #cgo darwin,amd64 CPPFLAGS: -I/usr/local/opt/llvm@20/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,amd64 CXXFLAGS: -std=c++17 +// #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@20/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@20/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,arm64 CXXFLAGS: -std=c++17 +// #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@20/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo linux CPPFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CXXFLAGS: -std=c++17 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-20/lib -lLLVM-20 +import "C" + +type run_build_sh int diff --git a/llvm_config_llvm21.go b/llvm_config_llvm21.go new file mode 100644 index 0000000..904cc58 --- /dev/null +++ b/llvm_config_llvm21.go @@ -0,0 +1,16 @@ +//go:build !byollvm && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20 + +package llvm + +// #cgo darwin,amd64 CPPFLAGS: -I/usr/local/opt/llvm@21/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,amd64 CXXFLAGS: -std=c++17 +// #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@21/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@21/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,arm64 CXXFLAGS: -std=c++17 +// #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@21/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo linux CPPFLAGS: -I/usr/include/llvm-21 -I/usr/include/llvm-c-21 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CXXFLAGS: -std=c++17 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-21/lib -lLLVM-21 +import "C" + +type run_build_sh int From 5ab4b69dc9792ccb7ebc95e1627b66e8e56ae5e3 Mon Sep 17 00:00:00 2001 From: Qi Zhou Date: Tue, 29 Jul 2025 20:47:44 +0000 Subject: [PATCH 3/9] add ExecutionEngine.NewJITCompiler() add ExecutionEngine.GetFunctionAddress() --- executionengine.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/executionengine.go b/executionengine.go index 5fa8204..f9a3f99 100644 --- a/executionengine.go +++ b/executionengine.go @@ -18,8 +18,10 @@ package llvm #include */ import "C" -import "unsafe" -import "errors" +import ( + "errors" + "unsafe" +) func LinkInMCJIT() { C.LLVMLinkInMCJIT() } func LinkInInterpreter() { C.LLVMLinkInInterpreter() } @@ -110,6 +112,17 @@ func NewInterpreter(m Module) (ee ExecutionEngine, err error) { return } +func NewJITCompiler(m Module, optLevel int) (ee ExecutionEngine, err error) { + var cmsg *C.char + fail := C.LLVMCreateJITCompilerForModule(&ee.C, m.C, C.uint(optLevel), &cmsg) + if fail != 0 { + ee.C = nil + err = errors.New(C.GoString(cmsg)) + C.LLVMDisposeMessage(cmsg) + } + return +} + func NewMCJITCompilerOptions() MCJITCompilerOptions { var options C.struct_LLVMMCJITCompilerOptions C.LLVMInitializeMCJITCompilerOptions(&options, C.size_t(unsafe.Sizeof(C.struct_LLVMMCJITCompilerOptions{}))) @@ -159,6 +172,12 @@ func (ee ExecutionEngine) FindFunction(name string) (f Value) { return } +func (ee ExecutionEngine) GetFunctionAddress(name string) uint64 { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + return uint64(C.LLVMGetFunctionAddress(ee.C, cname)) +} + func (ee ExecutionEngine) RecompileAndRelinkFunction(f Value) unsafe.Pointer { return C.LLVMRecompileAndRelinkFunction(ee.C, f.C) } From 1113dcfe4f0217265911799210785f9d2f468b73 Mon Sep 17 00:00:00 2001 From: Al Hoang <3811822-hoanga@users.noreply.gitlab.com> Date: Thu, 11 Sep 2025 16:58:29 -0500 Subject: [PATCH 4/9] fix compilation on freebsd and add ci --- .github/workflows/test.yml | 29 +++++++++++++++++++++++++++++ llvm_config_llvm19.go | 3 +++ llvm_config_llvm20.go | 3 +++ llvm_config_llvm21.go | 3 +++ 4 files changed, 38 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8946fd3..ddacaeb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,3 +55,32 @@ jobs: if: matrix.llvm == 21 run: go test -v + test-freebsd: + name: test-freebsd + runs-on: ubuntu-latest + strategy: + matrix: + llvm: [19, 20] + steps: + - uses: actions/checkout@v4 + - name: FreeBSD test 14.3 + uses: vmactions/freebsd-vm@v1 + with: + release: '14.3' + usesh: true + prepare: | + # Update package database with IGNORE_OSVERSION + pkg update -f || true + # Install llvm build dependencies + pkg install -y llvm${{ matrix.llvm }} + # Install default version go dependency + pkg install -y go + run: | + # Show environment info + echo "FreeBSD version:" + freebsd-version + # Test with llvm${{ matrix.llvm }} + echo "Clang ${{ matrix.llvm }} version info:" + /usr/local/llvm${{ matrix.llvm }}/bin/clang --version + echo "Test with llvm${{ matrix.llvm }} tag" + go test -v -tags=llvm${{ matrix.llvm }} diff --git a/llvm_config_llvm19.go b/llvm_config_llvm19.go index 29e2246..a05623d 100644 --- a/llvm_config_llvm19.go +++ b/llvm_config_llvm19.go @@ -8,6 +8,9 @@ package llvm // #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@19/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo darwin,arm64 CXXFLAGS: -std=c++17 // #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@19/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo freebsd CPPFLAGS: -I/usr/local/llvm19/include -I/usr/local/llvm19/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo freebsd CXXFLAGS: -std=c++17 +// #cgo freebsd LDFLAGS: -L/usr/local/llvm19/lib -lLLVM // #cgo linux CPPFLAGS: -I/usr/include/llvm-19 -I/usr/include/llvm-c-19 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo linux CXXFLAGS: -std=c++17 // #cgo linux LDFLAGS: -L/usr/lib/llvm-19/lib -lLLVM-19 diff --git a/llvm_config_llvm20.go b/llvm_config_llvm20.go index e0ca6a6..439a160 100644 --- a/llvm_config_llvm20.go +++ b/llvm_config_llvm20.go @@ -8,6 +8,9 @@ package llvm // #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@20/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo darwin,arm64 CXXFLAGS: -std=c++17 // #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@20/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo freebsd CPPFLAGS: -I/usr/local/llvm20/include -I/usr/local/llvm20/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo freebsd CXXFLAGS: -std=c++17 +// #cgo freebsd LDFLAGS: -L/usr/local/llvm20/lib -lLLVM // #cgo linux CPPFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo linux CXXFLAGS: -std=c++17 // #cgo linux LDFLAGS: -L/usr/lib/llvm-20/lib -lLLVM-20 diff --git a/llvm_config_llvm21.go b/llvm_config_llvm21.go index 904cc58..9c54d90 100644 --- a/llvm_config_llvm21.go +++ b/llvm_config_llvm21.go @@ -8,6 +8,9 @@ package llvm // #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@21/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo darwin,arm64 CXXFLAGS: -std=c++17 // #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@21/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo freebsd CPPFLAGS: -I/usr/local/llvm21/include -I/usr/local/llvm21/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo freebsd CXXFLAGS: -std=c++17 +// #cgo freebsd LDFLAGS: -L/usr/local/llvm21/lib -lLLVM // #cgo linux CPPFLAGS: -I/usr/include/llvm-21 -I/usr/include/llvm-c-21 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo linux CXXFLAGS: -std=c++17 // #cgo linux LDFLAGS: -L/usr/lib/llvm-21/lib -lLLVM-21 From 2e3bbddad9e1ee71ed842a224dd541e6f0ae4f00 Mon Sep 17 00:00:00 2001 From: Al Hoang <3811822-hoanga@users.noreply.gitlab.com> Date: Wed, 24 Sep 2025 20:32:28 -0500 Subject: [PATCH 5/9] remove freebsd ci --- .github/workflows/test.yml | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ddacaeb..8946fd3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,32 +55,3 @@ jobs: if: matrix.llvm == 21 run: go test -v - test-freebsd: - name: test-freebsd - runs-on: ubuntu-latest - strategy: - matrix: - llvm: [19, 20] - steps: - - uses: actions/checkout@v4 - - name: FreeBSD test 14.3 - uses: vmactions/freebsd-vm@v1 - with: - release: '14.3' - usesh: true - prepare: | - # Update package database with IGNORE_OSVERSION - pkg update -f || true - # Install llvm build dependencies - pkg install -y llvm${{ matrix.llvm }} - # Install default version go dependency - pkg install -y go - run: | - # Show environment info - echo "FreeBSD version:" - freebsd-version - # Test with llvm${{ matrix.llvm }} - echo "Clang ${{ matrix.llvm }} version info:" - /usr/local/llvm${{ matrix.llvm }}/bin/clang --version - echo "Test with llvm${{ matrix.llvm }} tag" - go test -v -tags=llvm${{ matrix.llvm }} From 00fb4309ddd2aeea5ff0e4b8bda9a6d844aa2349 Mon Sep 17 00:00:00 2001 From: Al Hoang <3811822-hoanga@users.noreply.gitlab.com> Date: Thu, 25 Sep 2025 07:33:18 -0500 Subject: [PATCH 6/9] fix bad formatting --- llvm_config_llvm19.go | 6 +++--- llvm_config_llvm20.go | 6 +++--- llvm_config_llvm21.go | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/llvm_config_llvm19.go b/llvm_config_llvm19.go index a05623d..e540f57 100644 --- a/llvm_config_llvm19.go +++ b/llvm_config_llvm19.go @@ -8,9 +8,9 @@ package llvm // #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@19/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo darwin,arm64 CXXFLAGS: -std=c++17 // #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@19/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo freebsd CPPFLAGS: -I/usr/local/llvm19/include -I/usr/local/llvm19/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo freebsd CXXFLAGS: -std=c++17 -// #cgo freebsd LDFLAGS: -L/usr/local/llvm19/lib -lLLVM +// #cgo freebsd CPPFLAGS: -I/usr/local/llvm19/include -I/usr/local/llvm19/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo freebsd CXXFLAGS: -std=c++17 +// #cgo freebsd LDFLAGS: -L/usr/local/llvm19/lib -lLLVM // #cgo linux CPPFLAGS: -I/usr/include/llvm-19 -I/usr/include/llvm-c-19 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo linux CXXFLAGS: -std=c++17 // #cgo linux LDFLAGS: -L/usr/lib/llvm-19/lib -lLLVM-19 diff --git a/llvm_config_llvm20.go b/llvm_config_llvm20.go index 439a160..090bdd6 100644 --- a/llvm_config_llvm20.go +++ b/llvm_config_llvm20.go @@ -8,9 +8,9 @@ package llvm // #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@20/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo darwin,arm64 CXXFLAGS: -std=c++17 // #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@20/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo freebsd CPPFLAGS: -I/usr/local/llvm20/include -I/usr/local/llvm20/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo freebsd CXXFLAGS: -std=c++17 -// #cgo freebsd LDFLAGS: -L/usr/local/llvm20/lib -lLLVM +// #cgo freebsd CPPFLAGS: -I/usr/local/llvm20/include -I/usr/local/llvm20/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo freebsd CXXFLAGS: -std=c++17 +// #cgo freebsd LDFLAGS: -L/usr/local/llvm20/lib -lLLVM // #cgo linux CPPFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo linux CXXFLAGS: -std=c++17 // #cgo linux LDFLAGS: -L/usr/lib/llvm-20/lib -lLLVM-20 diff --git a/llvm_config_llvm21.go b/llvm_config_llvm21.go index 9c54d90..e74a1f8 100644 --- a/llvm_config_llvm21.go +++ b/llvm_config_llvm21.go @@ -8,9 +8,9 @@ package llvm // #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@21/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo darwin,arm64 CXXFLAGS: -std=c++17 // #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@21/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm -// #cgo freebsd CPPFLAGS: -I/usr/local/llvm21/include -I/usr/local/llvm21/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -// #cgo freebsd CXXFLAGS: -std=c++17 -// #cgo freebsd LDFLAGS: -L/usr/local/llvm21/lib -lLLVM +// #cgo freebsd CPPFLAGS: -I/usr/local/llvm21/include -I/usr/local/llvm21/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo freebsd CXXFLAGS: -std=c++17 +// #cgo freebsd LDFLAGS: -L/usr/local/llvm21/lib -lLLVM // #cgo linux CPPFLAGS: -I/usr/include/llvm-21 -I/usr/include/llvm-c-21 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo linux CXXFLAGS: -std=c++17 // #cgo linux LDFLAGS: -L/usr/lib/llvm-21/lib -lLLVM-21 From 9bf73fc8f506a2c67106003b8e9f60813c80a43d Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 21 Apr 2026 11:13:22 +0200 Subject: [PATCH 7/9] Add paths for older LLVM versions on Fedora --- .github/workflows/test.yml | 23 +++++++++++++++++++++++ llvm_config_llvm19.go | 4 ++-- llvm_config_llvm20.go | 4 ++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8946fd3..6d004c5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,3 +55,26 @@ jobs: if: matrix.llvm == 21 run: go test -v + test-linux-fedora: + # Fedora uses different paths than other systems, so testing it separately. + runs-on: ubuntu-24.04 + strategy: + matrix: + llvm: [19, 20, 21] + container: fedora:43 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install dependencies (default LLVM) + if: matrix.llvm == 21 + run: dnf install --assumeyes g++ golang llvm-devel + - name: Install dependencies (older LLVM) + if: matrix.llvm != 21 + run: dnf install --assumeyes g++ golang llvm${{ matrix.llvm }}-devel + - name: Test LLVM ${{ matrix.llvm }} + run: + go test -v -tags=llvm${{ matrix.llvm }} + - name: Test default LLVM + if: matrix.llvm == 21 + run: + go test -v diff --git a/llvm_config_llvm19.go b/llvm_config_llvm19.go index e540f57..f5493ef 100644 --- a/llvm_config_llvm19.go +++ b/llvm_config_llvm19.go @@ -11,9 +11,9 @@ package llvm // #cgo freebsd CPPFLAGS: -I/usr/local/llvm19/include -I/usr/local/llvm19/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo freebsd CXXFLAGS: -std=c++17 // #cgo freebsd LDFLAGS: -L/usr/local/llvm19/lib -lLLVM -// #cgo linux CPPFLAGS: -I/usr/include/llvm-19 -I/usr/include/llvm-c-19 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CPPFLAGS: -I/usr/include/llvm-19 -I/usr/include/llvm-c-19 -I/usr/lib64/llvm19/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo linux CXXFLAGS: -std=c++17 -// #cgo linux LDFLAGS: -L/usr/lib/llvm-19/lib -lLLVM-19 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-19/lib -L/usr/lib64/llvm19/lib -lLLVM-19 import "C" type run_build_sh int diff --git a/llvm_config_llvm20.go b/llvm_config_llvm20.go index 090bdd6..9c0a350 100644 --- a/llvm_config_llvm20.go +++ b/llvm_config_llvm20.go @@ -11,9 +11,9 @@ package llvm // #cgo freebsd CPPFLAGS: -I/usr/local/llvm20/include -I/usr/local/llvm20/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo freebsd CXXFLAGS: -std=c++17 // #cgo freebsd LDFLAGS: -L/usr/local/llvm20/lib -lLLVM -// #cgo linux CPPFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CPPFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -I/usr/lib64/llvm20/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS // #cgo linux CXXFLAGS: -std=c++17 -// #cgo linux LDFLAGS: -L/usr/lib/llvm-20/lib -lLLVM-20 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-20/lib -L/usr/lib64/llvm20/lib64 -lLLVM-20 import "C" type run_build_sh int From 06c6725fe5e675a26a3997977473089fa0f5e5b7 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 22 Apr 2026 11:14:49 +0200 Subject: [PATCH 8/9] Use LLVM 20 by default for now We still haven't updated TinyGo, so this change is needed so we can use https://github.com/tinygo-org/go-llvm/pull/73 in TinyGo. --- .github/workflows/test.yml | 6 +++--- llvm_config_llvm20.go | 2 +- llvm_config_llvm21.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6d004c5..9432e6a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,7 +27,7 @@ jobs: run: go test -v -tags=llvm${{ matrix.llvm }} - name: Test default LLVM - if: matrix.llvm == 21 + if: matrix.llvm == 20 run: go test -v test-linux: @@ -52,7 +52,7 @@ jobs: run: go test -v -tags=llvm${{ matrix.llvm }} - name: Test default LLVM - if: matrix.llvm == 21 + if: matrix.llvm == 20 run: go test -v test-linux-fedora: @@ -75,6 +75,6 @@ jobs: run: go test -v -tags=llvm${{ matrix.llvm }} - name: Test default LLVM - if: matrix.llvm == 21 + if: matrix.llvm == 20 run: go test -v diff --git a/llvm_config_llvm20.go b/llvm_config_llvm20.go index 9c0a350..6741b28 100644 --- a/llvm_config_llvm20.go +++ b/llvm_config_llvm20.go @@ -1,4 +1,4 @@ -//go:build !byollvm && llvm20 +//go:build !byollvm && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm21 package llvm diff --git a/llvm_config_llvm21.go b/llvm_config_llvm21.go index e74a1f8..263c2fc 100644 --- a/llvm_config_llvm21.go +++ b/llvm_config_llvm21.go @@ -1,4 +1,4 @@ -//go:build !byollvm && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20 +//go:build !byollvm && llvm21 package llvm From ddd595b68360452252ef9758971958152e9fe559 Mon Sep 17 00:00:00 2001 From: Damian Gryski Date: Tue, 7 Jul 2026 13:03:25 -0700 Subject: [PATCH 9/9] Add LLVM 22 build support (#75) * Add LLVM 22 build support Written entirely by Claude (Anthropic's Claude Code), at the request of and under the direction of dgryski, as part of a broader effort to get TinyGo building against upcoming LLVM releases. Adds the llvm22 build-tag config file (mirroring the existing llvm21 one) and a CI matrix entry for it. Also adds a regression test confirming that LLVM 21+'s 'captures' parameter attribute (which replaced the boolean 'nocapture' enum attribute) round-trips correctly through the existing generic enum-attribute API, with value 0 corresponding to captures(none) -- no binding/C++ shim changes were needed for this, since 'captures' is an IntAttr using the same wire format as e.g. 'align' or 'dereferenceable'. Verified by running the full test suite against real LLVM 22.1.8 headers and libraries (via Homebrew). * limit captures_test to llvm 21 and above. * Fix switch-instruction case-value access for LLVM 22 Written entirely by Claude (Anthropic's Claude Code), at the request of and under the direction of dgryski, on the dgryski/llvm23 branch (LLVM 22 support, in preparation for the eventual LLVM 23 release). LLVM 22 stopped exposing SwitchInst case values as regular instruction operands -- only the condition and destination-block operands remain as operands now. Case values must be read via the new LLVMGetSwitchCaseValue C API added in the same release. This was discovered while chasing a real-world regression in TinyGo's interp package (see the paired tinygo commit on the same branch), which manually walked switch operands assuming the old layout; verified independently here first via a minimal standalone .ll repro against real LLVM 20/21/22 headers and libraries, isolating the exact version cutoff (21 -> 22) before touching any tinygo code. Adds: - Value.SuccessorsCount()/Value.Successor(i) in ir.go, using the stable, version-independent LLVMGetNumSuccessors/LLVMGetSuccessor API to enumerate a switch's destination blocks (successor 0 is always the default destination; successors 1..N-1 are the cases). - Value.GetSwitchCaseValue(i), version-gated: switch_llvm22.go uses the new LLVMGetSwitchCaseValue API, switch_pre22.go falls back to the old operand-based read for LLVM <22. - switch_test.go, a regression test verifying case values and destinations round-trip correctly; passes against real LLVM 20/21/22. --- .github/workflows/test.yml | 4 +- captures_test.go | 47 +++++++++++++++++++++++ ir.go | 12 ++++++ llvm_config_llvm20.go | 2 +- llvm_config_llvm22.go | 19 ++++++++++ switch_llvm22.go | 21 +++++++++++ switch_pre22.go | 15 ++++++++ switch_test.go | 76 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 captures_test.go create mode 100644 llvm_config_llvm22.go create mode 100644 switch_llvm22.go create mode 100644 switch_pre22.go create mode 100644 switch_test.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9432e6a..9294ab5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,7 +10,7 @@ jobs: runs-on: macos-latest strategy: matrix: - llvm: [14, 15, 16, 17, 18, 19, 20, 21] + llvm: [14, 15, 16, 17, 18, 19, 20, 21, 22] steps: - name: Checkout uses: actions/checkout@v4 @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - llvm: [14, 15, 16, 17, 18, 19, 20, 21] + llvm: [14, 15, 16, 17, 18, 19, 20, 21, 22] steps: - name: Checkout uses: actions/checkout@v4 diff --git a/captures_test.go b/captures_test.go new file mode 100644 index 0000000..6baaa96 --- /dev/null +++ b/captures_test.go @@ -0,0 +1,47 @@ +package llvm + +import ( + "strconv" + "strings" + "testing" +) + +// TestCapturesAttribute checks that the 'captures' parameter attribute +// (which replaced the boolean 'nocapture' enum attribute starting with +// LLVM 21) round-trips through the generic enum-attribute API, and that a +// value of 0 corresponds to CaptureInfo::none(), i.e. captures(none). +func TestCapturesAttribute(t *testing.T) { + majorVersion, _ := strconv.Atoi(strings.SplitN(Version, ".", 2)[0]) + if majorVersion < 21 { + t.Skip("not llvm 21") + } + + ctx := NewContext() + mod := ctx.NewModule("") + defer mod.Dispose() + + ptrType := PointerType(ctx.Int8Type(), 0) + ftyp := FunctionType(ctx.VoidType(), []Type{ptrType}, false) + fn := AddFunction(mod, "foo", ftyp) + + kind := AttributeKindID("captures") + if kind == 0 { + t.Fatal("captures kind id not found") + } + + attr := ctx.CreateEnumAttribute(kind, 0) + fn.AddAttributeAtIndex(1, attr) + + got := fn.GetEnumAttributeAtIndex(1, kind) + if got.IsNil() { + t.Fatal("expected captures attribute on param 1, got nil") + } + if val := got.GetEnumValue(); val != 0 { + t.Errorf("expected captures value 0 (none), got %d", val) + } + + text := mod.String() + if !strings.Contains(text, "captures(none)") { + t.Errorf("expected 'captures(none)' in output, got:\n%s", text) + } +} diff --git a/ir.go b/ir.go index efb0de1..47bf413 100644 --- a/ir.go +++ b/ir.go @@ -792,6 +792,18 @@ func (v Value) Operand(i int) (rv Value) { rv.C = C.LLVMGetOperand(v.C, C.unsi func (v Value) SetOperand(i int, op Value) { C.LLVMSetOperand(v.C, C.unsigned(i), op.C) } func (v Value) OperandsCount() int { return int(C.LLVMGetNumOperands(v.C)) } +// Operations on terminator instructions (br, switch, etc). Unlike operands, +// the number and meaning of successors has been stable across LLVM versions, +// making these a safe, version-independent way to enumerate the destination +// blocks of a switch instruction: successor 0 is the default destination, +// and successors 1..N-1 correspond to case 0..N-2 (see GetSwitchCaseValue for +// the matching case value). +func (v Value) SuccessorsCount() int { return int(C.LLVMGetNumSuccessors(v.C)) } +func (v Value) Successor(i int) (bb BasicBlock) { + bb.C = C.LLVMGetSuccessor(v.C, C.unsigned(i)) + return +} + // Operations on constants of any type func ConstNull(t Type) (v Value) { v.C = C.LLVMConstNull(t.C); return } func ConstAllOnes(t Type) (v Value) { v.C = C.LLVMConstAllOnes(t.C); return } diff --git a/llvm_config_llvm20.go b/llvm_config_llvm20.go index 6741b28..2132c5a 100644 --- a/llvm_config_llvm20.go +++ b/llvm_config_llvm20.go @@ -1,4 +1,4 @@ -//go:build !byollvm && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm21 +//go:build !byollvm && !llvm14 && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm21 && !llvm22 package llvm diff --git a/llvm_config_llvm22.go b/llvm_config_llvm22.go new file mode 100644 index 0000000..103e930 --- /dev/null +++ b/llvm_config_llvm22.go @@ -0,0 +1,19 @@ +//go:build !byollvm && llvm22 + +package llvm + +// #cgo darwin,amd64 CPPFLAGS: -I/usr/local/opt/llvm@22/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,amd64 CXXFLAGS: -std=c++17 +// #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@22/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo darwin,arm64 CPPFLAGS: -I/opt/homebrew/opt/llvm@22/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo darwin,arm64 CXXFLAGS: -std=c++17 +// #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@22/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM -lz -lm +// #cgo freebsd CPPFLAGS: -I/usr/local/llvm22/include -I/usr/local/llvm22/include/llvm-c -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo freebsd CXXFLAGS: -std=c++17 +// #cgo freebsd LDFLAGS: -L/usr/local/llvm22/lib -lLLVM +// #cgo linux CPPFLAGS: -I/usr/include/llvm-22 -I/usr/include/llvm-c-22 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS +// #cgo linux CXXFLAGS: -std=c++17 +// #cgo linux LDFLAGS: -L/usr/lib/llvm-22/lib -lLLVM-22 +import "C" + +type run_build_sh int diff --git a/switch_llvm22.go b/switch_llvm22.go new file mode 100644 index 0000000..0c70b08 --- /dev/null +++ b/switch_llvm22.go @@ -0,0 +1,21 @@ +//go:build llvm22 + +package llvm + +/* +#include "llvm-c/Core.h" +*/ +import "C" + +// GetSwitchCaseValue obtains the case value for a successor of a switch +// instruction. i corresponds to the successor index; the first successor (0) +// is the default destination, so i must be greater than zero. +// +// LLVM 22 stopped exposing switch case values as regular instruction +// operands (only the condition and destination-block operands remain), so +// this is implemented via the new LLVMGetSwitchCaseValue C API added in the +// same release. +func (v Value) GetSwitchCaseValue(i int) (rv Value) { + rv.C = C.LLVMGetSwitchCaseValue(v.C, C.unsigned(i)) + return +} diff --git a/switch_pre22.go b/switch_pre22.go new file mode 100644 index 0000000..cfa381c --- /dev/null +++ b/switch_pre22.go @@ -0,0 +1,15 @@ +//go:build !llvm22 + +package llvm + +// GetSwitchCaseValue obtains the case value for a successor of a switch +// instruction. i corresponds to the successor index; the first successor (0) +// is the default destination, so i must be greater than zero. +// +// Before LLVM 22, switch case values were stored as regular instruction +// operands (alternating with their destination blocks, after the leading +// condition/default-destination pair), so this is implemented via Operand +// access instead of the LLVM 22+-only LLVMGetSwitchCaseValue. +func (v Value) GetSwitchCaseValue(i int) Value { + return v.Operand(2 * i) +} diff --git a/switch_test.go b/switch_test.go new file mode 100644 index 0000000..aa7ca26 --- /dev/null +++ b/switch_test.go @@ -0,0 +1,76 @@ +package llvm + +import ( + "os" + "testing" +) + +// TestSwitchCaseValue checks that GetSwitchCaseValue/SuccessorsCount/Successor +// correctly read a switch instruction's cases across LLVM versions. LLVM 22 +// stopped exposing case values as regular instruction operands (only the +// condition and destination-block operands remain), instead requiring the +// new LLVMGetSwitchCaseValue API; code that assumed the old operand layout +// silently reads a destination block where it expects a case value. +func TestSwitchCaseValue(t *testing.T) { + src := ` +define void @foo(i64 %callback) { +entry: + switch i64 %callback, label %default [ + i64 0, label %case0 + i64 5, label %case1 + ] +default: + ret void +case0: + ret void +case1: + ret void +} +` + f, err := os.CreateTemp("", "switchcase-*.ll") + if err != nil { + t.Fatal(err) + } + defer os.Remove(f.Name()) + if _, err := f.WriteString(src); err != nil { + t.Fatal(err) + } + f.Close() + + ctx := NewContext() + defer ctx.Dispose() + + buf, err := NewMemoryBufferFromFile(f.Name()) + if err != nil { + t.Fatal(err) + } + + m, err := ctx.ParseIR(buf) + if err != nil { + t.Fatal(err) + } + defer m.Dispose() + + fn := m.NamedFunction("foo") + sw := fn.EntryBasicBlock().FirstInstruction() + + if n := sw.SuccessorsCount(); n != 3 { + t.Fatalf("expected 3 successors (default + 2 cases), got %d", n) + } + if got := sw.Successor(0).AsValue().Name(); got != "default" { + t.Errorf("expected default destination %q, got %q", "default", got) + } + + wantCaseValues := []uint64{0, 5} + wantCaseDests := []string{"case0", "case1"} + for i, want := range wantCaseValues { + successor := i + 1 + val := sw.GetSwitchCaseValue(successor) + if got := val.ZExtValue(); got != want { + t.Errorf("case %d: expected value %d, got %d", i, want, got) + } + if got := sw.Successor(successor).AsValue().Name(); got != wantCaseDests[i] { + t.Errorf("case %d: expected destination %q, got %q", i, wantCaseDests[i], got) + } + } +}