diff --git a/.gitignore b/.gitignore index 4ddee71..18595d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,38 +1,19 @@ +/tinygo-*.tar.gz /avr-*.tar.gz /cmsis-*.tar.gz /cmsis-*-clean.tar.xz /cmsis_svd-*.tar.gz /cmsis_svd-*-clean.tar.xz +/cmsis_svd_data-*.tar.gz +/cmsis_svd_data-*-clean.tar.xz /compiler-rt-*.src.tar.xz /compiler-rt-*.src.tar.xz.sig +/macos-minimal-sdk-*.tar.gz +/mingw64-*.tar.gz +/musl-*.tar.gz +/musl-*.tar.gz.asc +/net-*.tar.gz /nrfx-*.tar.gz /picolibc-*.tar.gz /wasi-libc-*.tar.gz -/tinygo-0.6.0.tar.gz -/tinygo-0.7.0.tar.gz -/tinygo-0.7.1.tar.gz -/tinygo-0.8.0.tar.gz -/tinygo-0.9.0.tar.gz -/tinygo-0.10.0.tar.gz -/tinygo-0.11.0.tar.gz -/tinygo-0.12.0.tar.gz -/tinygo-0.13.0.tar.gz -/tinygo-0.13.1.tar.gz -/tinygo-0.14.0.tar.gz -/tinygo-0.14.1.tar.gz -/tinygo-0.15.0.tar.gz -/tinygo-0.16.0.tar.gz -/tinygo-0.17.0.tar.gz -/tinygo-0.18.0.tar.gz -/tinygo-0.19.0.tar.gz -/tinygo-0.20.0.tar.gz -/tinygo-0.21.0.tar.gz -/musl-1.2.2.tar.gz -/musl-1.2.2.tar.gz.asc -/tinygo-0.22.0.tar.gz -/musl-1.2.0.tar.gz -/musl-1.2.0.tar.gz.asc -/tinygo-0.23.0.tar.gz -/macos-minimal-sdk-ebb736fda2bec7cea38dcda807518b835a539525.tar.gz -/tinygo-0.25.0.tar.gz -/tinygo-0.26.0.tar.gz +/bdwgc-1166f11f7dee08d7ad369296b24cf8c9582f8789.tar.gz diff --git a/0001-Skip-WASI-tests.patch b/0001-Skip-WASI-tests.patch index 1f648df..32e8ce8 100644 --- a/0001-Skip-WASI-tests.patch +++ b/0001-Skip-WASI-tests.patch @@ -1,38 +1,50 @@ -From 6b50974a6d4972b755a35d40d87e5bdf9c97d925 Mon Sep 17 00:00:00 2001 +From fdd5322026e4b7b2e7fe6a80628b7239b4c4eb99 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 15 Dec 2020 05:06:04 -0500 -Subject: [PATCH 01/18] Skip WASI tests. +Subject: [PATCH 1/5] Skip WASI tests. We do not have wasmtime available. Signed-off-by: Elliott Sales de Andrade --- - main_test.go | 5 ----- - 1 file changed, 5 deletions(-) + main_test.go | 17 ----------------- + 1 file changed, 17 deletions(-) diff --git a/main_test.go b/main_test.go -index 9ddbe52f..79ae2cf2 100644 +index b07d6aaa..ae0a4482 100644 --- a/main_test.go +++ b/main_test.go -@@ -154,10 +154,6 @@ func TestBuild(t *testing.T) { - t.Parallel() - runPlatTests(optionsFromTarget("wasm", sema), tests, t) +@@ -188,22 +188,6 @@ func TestBuild(t *testing.T) { + runTest("gc.go", optionsBoehm, t, nil, nil) + }) }) -- t.Run("WASI", func(t *testing.T) { +- t.Run("WASIp1", func(t *testing.T) { - t.Parallel() -- runPlatTests(optionsFromTarget("wasi", sema), tests, t) +- runPlatTests(optionsFromTarget("wasip1", sema), tests, t) +- +- // Test with -gc=boehm. +- t.Run("gc.go-boehm", func(t *testing.T) { +- t.Parallel() +- optionsBoehm := optionsFromTarget("wasip1", sema) +- optionsBoehm.GC = "boehm" +- runTest("gc.go", optionsBoehm, t, nil, nil) +- }) +- }) +- t.Run("WASIp2", func(t *testing.T) { +- t.Parallel() +- runPlatTests(optionsFromTarget("wasip2", sema), tests, t) - }) } - } -@@ -413,7 +409,6 @@ func TestTest(t *testing.T) { + if runtime.GOOS == "linux" { +@@ -925,7 +909,6 @@ func TestTest(t *testing.T) { // Node/Wasmtime targ{"WASM", optionsFromTarget("wasm", sema)}, -- targ{"WASI", optionsFromTarget("wasi", sema)}, +- targ{"WASI", optionsFromTarget("wasip1", sema)}, ) } for _, targ := range targs { -- -2.36.1 +2.50.0 diff --git a/0002-Skip-tests-that-require-Go-module-mode.patch b/0002-Skip-tests-that-require-Go-module-mode.patch new file mode 100644 index 0000000..01dc83c --- /dev/null +++ b/0002-Skip-tests-that-require-Go-module-mode.patch @@ -0,0 +1,58 @@ +From f650ab16b5a3badf48922f77683ceaf791c82d64 Mon Sep 17 00:00:00 2001 +From: Elliott Sales de Andrade +Date: Wed, 28 Feb 2024 04:26:40 -0500 +Subject: [PATCH 2/5] Skip tests that require Go module mode + +Signed-off-by: Elliott Sales de Andrade +--- + errors_test.go | 2 +- + main_test.go | 2 +- + testdata/errors/loader-invaliddep.go | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/errors_test.go b/errors_test.go +index 871dc4c0..3d0bb162 100644 +--- a/errors_test.go ++++ b/errors_test.go +@@ -37,7 +37,7 @@ func TestErrors(t *testing.T) { + {name: "loader-importcycle"}, + {name: "loader-invaliddep"}, + {name: "loader-invalidpackage"}, +- {name: "loader-nopackage"}, ++ // {name: "loader-nopackage"}, + {name: "optimizer"}, + {name: "syntax"}, + {name: "types"}, +diff --git a/main_test.go b/main_test.go +index ae0a4482..ca052821 100644 +--- a/main_test.go ++++ b/main_test.go +@@ -78,7 +78,6 @@ func TestBuild(t *testing.T) { + "json.go", + "map.go", + "math.go", +- "oldgo/", + "print.go", + "reflect.go", + "signal.go", +@@ -1031,6 +1030,7 @@ func ioLogger(t *testing.T, wg *sync.WaitGroup) io.WriteCloser { + } + + func TestGetListOfPackages(t *testing.T) { ++ t.Skip("Not available in non-module mode") + opts := optionsFromTarget("", sema) + tests := []struct { + pkgs []string +diff --git a/testdata/errors/loader-invaliddep.go b/testdata/errors/loader-invaliddep.go +index 05c2f2d5..719a617b 100644 +--- a/testdata/errors/loader-invaliddep.go ++++ b/testdata/errors/loader-invaliddep.go +@@ -5,4 +5,4 @@ import _ "github.com/tinygo-org/tinygo/testdata/errors/invaliddep" + func main() { + } + +-// ERROR: invaliddep{{[\\/]}}invaliddep.go:1:1: expected 'package', found ppackage ++// ERROR: {{.*}}invaliddep{{[\\/]}}invaliddep.go:1:1: expected 'package', found ppackage +-- +2.50.0 + diff --git a/0002-Use-system-mingw64-headers-and-crt.patch b/0002-Use-system-mingw64-headers-and-crt.patch deleted file mode 100644 index 821f09a..0000000 --- a/0002-Use-system-mingw64-headers-and-crt.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 76c575659d42187b0c4c15d4f5978c4368800da7 Mon Sep 17 00:00:00 2001 -From: Elliott Sales de Andrade -Date: Sun, 2 Jan 2022 05:47:18 -0500 -Subject: [PATCH 02/18] Use system mingw64 headers and crt - -Signed-off-by: Elliott Sales de Andrade ---- - builder/mingw-w64.go | 68 ++++--------------------------------------- - compileopts/config.go | 7 ++--- - 2 files changed, 7 insertions(+), 68 deletions(-) - -diff --git a/builder/mingw-w64.go b/builder/mingw-w64.go -index 27fefee0..d233068d 100644 ---- a/builder/mingw-w64.go -+++ b/builder/mingw-w64.go -@@ -1,31 +1,11 @@ - package builder - - import ( -- "io" -- "os" -- "path/filepath" -- "strings" -- -- "github.com/tinygo-org/tinygo/goenv" -+ "fmt" - ) - - var MinGW = Library{ -- name: "mingw-w64", -- makeHeaders: func(target, includeDir string) error { -- // copy _mingw.h -- srcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib", "mingw-w64") -- outf, err := os.Create(includeDir + "/_mingw.h") -- if err != nil { -- return err -- } -- defer outf.Close() -- inf, err := os.Open(srcDir + "/mingw-w64-headers/crt/_mingw.h.in") -- if err != nil { -- return err -- } -- _, err = io.Copy(outf, inf) -- return err -- }, -+ name: "mingw-w64", - sourceDir: func() string { return "" }, // unused - cflags: func(target, headerPath string) []string { - // No flags necessary because there are no files to compile. -@@ -45,47 +25,9 @@ var MinGW = Library{ - // compile these files. - func makeMinGWExtraLibs(tmpdir string) []*compileJob { - var jobs []*compileJob -- root := goenv.Get("TINYGOROOT") -- // Normally all the api-ms-win-crt-*.def files are all compiled to a single -- // .lib file. But to simplify things, we're going to leave them as separate -- // files. -- for _, name := range []string{ -- "kernel32.def.in", -- "api-ms-win-crt-conio-l1-1-0.def", -- "api-ms-win-crt-convert-l1-1-0.def", -- "api-ms-win-crt-environment-l1-1-0.def", -- "api-ms-win-crt-filesystem-l1-1-0.def", -- "api-ms-win-crt-heap-l1-1-0.def", -- "api-ms-win-crt-locale-l1-1-0.def", -- "api-ms-win-crt-math-l1-1-0.def.in", -- "api-ms-win-crt-multibyte-l1-1-0.def", -- "api-ms-win-crt-private-l1-1-0.def.in", -- "api-ms-win-crt-process-l1-1-0.def", -- "api-ms-win-crt-runtime-l1-1-0.def.in", -- "api-ms-win-crt-stdio-l1-1-0.def", -- "api-ms-win-crt-string-l1-1-0.def", -- "api-ms-win-crt-time-l1-1-0.def", -- "api-ms-win-crt-utility-l1-1-0.def", -- } { -- outpath := filepath.Join(tmpdir, filepath.Base(name)+".lib") -- inpath := filepath.Join(root, "lib/mingw-w64/mingw-w64-crt/lib-common/"+name) -- job := &compileJob{ -- description: "create lib file " + inpath, -- result: outpath, -- run: func(job *compileJob) error { -- defpath := inpath -- if strings.HasSuffix(inpath, ".in") { -- // .in files need to be preprocessed by a preprocessor (-E) -- // first. -- defpath = outpath + ".def" -- err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", "-DDEF_X64", "-DDATA", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/") -- if err != nil { -- return err -- } -- } -- return link("ld.lld", "-m", "i386pep", "-o", outpath, defpath) -- }, -- } -+ for _, name := range []string{"kernel32", "ucrt"} { -+ outpath := fmt.Sprintf("/usr/x86_64-w64-mingw32/sys-root/mingw/lib/lib%s.a", name) -+ job := dummyCompileJob(outpath) - jobs = append(jobs, job) - } - return jobs -diff --git a/compileopts/config.go b/compileopts/config.go -index ebfc5082..cd49283d 100644 ---- a/compileopts/config.go -+++ b/compileopts/config.go -@@ -304,12 +304,9 @@ func (c *Config) CFlags() []string { - root := goenv.Get("TINYGOROOT") - cflags = append(cflags, "--sysroot="+root+"/lib/wasi-libc/sysroot") - case "mingw-w64": -- root := goenv.Get("TINYGOROOT") -- path, _ := c.LibcPath("mingw-w64") - cflags = append(cflags, -- "--sysroot="+path, -- "-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"), -- "-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"), -+ "--sysroot=/usr/x86_64-w64-mingw32/sys-root", -+ "-isystem", "/usr/x86_64-w64-mingw32/sys-root/mingw/include", - "-D_UCRT", - ) - case "": --- -2.36.1 - diff --git a/0003-Set-LLVM-search-paths-for-Fedora.patch b/0003-Set-LLVM-search-paths-for-Fedora.patch new file mode 100644 index 0000000..d375623 --- /dev/null +++ b/0003-Set-LLVM-search-paths-for-Fedora.patch @@ -0,0 +1,126 @@ +From d516beb86673a9b80ca75c41e8fb7cba7e3f126f Mon Sep 17 00:00:00 2001 +From: Elliott Sales de Andrade +Date: Sun, 27 Oct 2024 23:33:18 -0400 +Subject: [PATCH 3/5] Set LLVM search paths for Fedora + +Signed-off-by: Elliott Sales de Andrade +--- + cgo/libclang_config_llvm15.go | 4 ++-- + cgo/libclang_config_llvm16.go | 4 ++-- + cgo/libclang_config_llvm17.go | 4 ++-- + cgo/libclang_config_llvm18.go | 4 ++-- + cgo/libclang_config_llvm19.go | 4 ++-- + cgo/libclang_config_llvm20.go | 4 ++-- + 6 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/cgo/libclang_config_llvm15.go b/cgo/libclang_config_llvm15.go +index edb1128d..0dc87193 100644 +--- a/cgo/libclang_config_llvm15.go ++++ b/cgo/libclang_config_llvm15.go +@@ -3,11 +3,11 @@ + package cgo + + /* +-#cgo linux CFLAGS: -I/usr/lib/llvm-15/include ++#cgo linux CFLAGS: -I/usr/lib64/llvm15/include + #cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@15/include + #cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@15/include + #cgo freebsd CFLAGS: -I/usr/local/llvm15/include +-#cgo linux LDFLAGS: -L/usr/lib/llvm-15/lib -lclang ++#cgo linux LDFLAGS: -L/usr/lib64/llvm15/lib -lclang + #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@15/lib -lclang + #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@15/lib -lclang + #cgo freebsd LDFLAGS: -L/usr/local/llvm15/lib -lclang +diff --git a/cgo/libclang_config_llvm16.go b/cgo/libclang_config_llvm16.go +index ee354e21..4c338678 100644 +--- a/cgo/libclang_config_llvm16.go ++++ b/cgo/libclang_config_llvm16.go +@@ -9,11 +9,11 @@ package cgo + // ln -sf ../../x86_64-linux-gnu/libclang-16.so.1 /usr/lib/llvm-16/lib/libclang.so + + /* +-#cgo linux CFLAGS: -I/usr/lib/llvm-16/include ++#cgo linux CFLAGS: -I/usr/lib64/llvm16/include + #cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@16/include + #cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@16/include + #cgo freebsd CFLAGS: -I/usr/local/llvm16/include +-#cgo linux LDFLAGS: -L/usr/lib/llvm-16/lib -lclang ++#cgo linux LDFLAGS: -L/usr/lib64/llvm16/lib -lclang + #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@16/lib -lclang + #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@16/lib -lclang + #cgo freebsd LDFLAGS: -L/usr/local/llvm16/lib -lclang +diff --git a/cgo/libclang_config_llvm17.go b/cgo/libclang_config_llvm17.go +index 6395d8a3..609b0758 100644 +--- a/cgo/libclang_config_llvm17.go ++++ b/cgo/libclang_config_llvm17.go +@@ -3,11 +3,11 @@ + package cgo + + /* +-#cgo linux CFLAGS: -I/usr/include/llvm-17 -I/usr/include/llvm-c-17 -I/usr/lib/llvm-17/include ++#cgo linux CFLAGS: -I/usr/lib64/llvm17/include + #cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@17/include + #cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@17/include + #cgo freebsd CFLAGS: -I/usr/local/llvm17/include +-#cgo linux LDFLAGS: -L/usr/lib/llvm-17/lib -lclang ++#cgo linux LDFLAGS: -L/usr/lib64/llvm17/lib -lclang + #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@17/lib -lclang + #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@17/lib -lclang + #cgo freebsd LDFLAGS: -L/usr/local/llvm17/lib -lclang +diff --git a/cgo/libclang_config_llvm18.go b/cgo/libclang_config_llvm18.go +index da181291..76f23129 100644 +--- a/cgo/libclang_config_llvm18.go ++++ b/cgo/libclang_config_llvm18.go +@@ -3,11 +3,11 @@ + package cgo + + /* +-#cgo linux CFLAGS: -I/usr/include/llvm-18 -I/usr/include/llvm-c-18 -I/usr/lib/llvm-18/include ++#cgo linux CFLAGS: -I/usr/lib64/llvm18/include + #cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@18/include + #cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@18/include + #cgo freebsd CFLAGS: -I/usr/local/llvm18/include +-#cgo linux LDFLAGS: -L/usr/lib/llvm-18/lib -lclang ++#cgo linux LDFLAGS: -L/usr/lib64/llvm18/lib -lclang + #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@18/lib -lclang + #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@18/lib -lclang + #cgo freebsd LDFLAGS: -L/usr/local/llvm18/lib -lclang +diff --git a/cgo/libclang_config_llvm19.go b/cgo/libclang_config_llvm19.go +index 11a64e72..94c95bcb 100644 +--- a/cgo/libclang_config_llvm19.go ++++ b/cgo/libclang_config_llvm19.go +@@ -3,11 +3,11 @@ + package cgo + + /* +-#cgo linux CFLAGS: -I/usr/include/llvm-19 -I/usr/include/llvm-c-19 -I/usr/lib/llvm-19/include ++#cgo linux CFLAGS: -I/usr/lib64/llvm19/include + #cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@19/include + #cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@19/include + #cgo freebsd CFLAGS: -I/usr/local/llvm19/include +-#cgo linux LDFLAGS: -L/usr/lib/llvm-19/lib -lclang ++#cgo linux LDFLAGS: -L/usr/lib64/llvm19/lib -lclang + #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@19/lib -lclang + #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@19/lib -lclang + #cgo freebsd LDFLAGS: -L/usr/local/llvm19/lib -lclang +diff --git a/cgo/libclang_config_llvm20.go b/cgo/libclang_config_llvm20.go +index faa2e54d..947558d6 100644 +--- a/cgo/libclang_config_llvm20.go ++++ b/cgo/libclang_config_llvm20.go +@@ -3,11 +3,11 @@ + package cgo + + /* +-#cgo linux CFLAGS: -I/usr/include/llvm-20 -I/usr/include/llvm-c-20 -I/usr/lib/llvm-20/include ++#cgo linux CFLAGS: -I/usr/lib64/llvm20/include + #cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@20/include + #cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@20/include + #cgo freebsd CFLAGS: -I/usr/local/llvm20/include +-#cgo linux LDFLAGS: -L/usr/lib/llvm-20/lib -lclang ++#cgo linux LDFLAGS: -L/usr/lib64/llvm20/lib -lclang + #cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@20/lib -lclang + #cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@20/lib -lclang + #cgo freebsd LDFLAGS: -L/usr/local/llvm20/lib -lclang +-- +2.50.0 + diff --git a/0003-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch b/0003-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch deleted file mode 100644 index 87d5c28..0000000 --- a/0003-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 2a2e35e4565e8ea7f7ac2d34cb9da24000bb6474 Mon Sep 17 00:00:00 2001 -From: Elliott Sales de Andrade -Date: Mon, 3 Jan 2022 22:39:31 -0500 -Subject: [PATCH 03/18] Skip some cross Linux tests where qemu is broken - -The upstream issues will hopefully be fixed soon: - -- https://gitlab.com/qemu-project/qemu/-/issues/447 -- https://gitlab.com/qemu-project/qemu/-/issues/690 - -Signed-off-by: Elliott Sales de Andrade ---- - main_test.go | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/main_test.go b/main_test.go -index 79ae2cf2..9359ef0c 100644 ---- a/main_test.go -+++ b/main_test.go -@@ -252,6 +252,20 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) { - } - - func emuCheck(t *testing.T, options compileopts.Options) { -+ // Skip running the test executable due to bugs in qemu. -+ // https://gitlab.com/qemu-project/qemu/-/issues/447 -+ // https://gitlab.com/qemu-project/qemu/-/issues/690 -+ switch runtime.GOARCH { -+ case "arm64": -+ if options.GOARCH == "386" || options.GOARCH == "arm" { -+ t.Skipf("qemu is broken for this host/target architecture combination") -+ } -+ case "386": -+ if options.GOARCH == "arm" { -+ t.Skipf("qemu is broken for this host/target architecture combination") -+ } -+ } -+ - // Check if the emulator is installed. - spec, err := compileopts.LoadTarget(&options) - if err != nil { -@@ -341,6 +355,20 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c - return - } - -+ // Skip running the test executable due to bugs in qemu. -+ // https://gitlab.com/qemu-project/qemu/-/issues/447 -+ // https://gitlab.com/qemu-project/qemu/-/issues/690 -+ switch runtime.GOARCH { -+ case "arm64": -+ if options.GOARCH == "386" || options.GOARCH == "arm" { -+ return -+ } -+ case "386": -+ if options.GOARCH == "arm" { -+ return -+ } -+ } -+ - // putchar() prints CRLF, convert it to LF. - actual := bytes.Replace(stdout.Bytes(), []byte{'\r', '\n'}, []byte{'\n'}, -1) - expected = bytes.Replace(expected, []byte{'\r', '\n'}, []byte{'\n'}, -1) // for Windows --- -2.36.1 - diff --git a/0004-Normalize-expected-path-for-chdir-tests.patch b/0004-Normalize-expected-path-for-chdir-tests.patch new file mode 100644 index 0000000..0285c03 --- /dev/null +++ b/0004-Normalize-expected-path-for-chdir-tests.patch @@ -0,0 +1,33 @@ +From d83874e6ab92ee4142cc7672da226a9091f7211a Mon Sep 17 00:00:00 2001 +From: Elliott Sales de Andrade +Date: Tue, 31 Dec 2024 02:00:17 -0500 +Subject: [PATCH 4/5] Normalize expected path for chdir tests + +The expected path comes from a simple string concatenation in shell, but +`os.Getwd` appears to have the normalized working directory, so this can +fail if any parent directory is a symlink. + +Signed-off-by: Elliott Sales de Andrade +--- + tests/testing/chdir/chdir.go | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tests/testing/chdir/chdir.go b/tests/testing/chdir/chdir.go +index 75281c21..660b25ac 100644 +--- a/tests/testing/chdir/chdir.go ++++ b/tests/testing/chdir/chdir.go +@@ -20,6 +20,11 @@ func main() { + } + if runtime.GOOS == "windows" { + cwd = filepath.ToSlash(cwd) ++ } else { ++ expectDir, err = filepath.EvalSymlinks(expectDir) ++ if err != nil { ++ log.Fatal(err) ++ } + } + if cwd != expectDir { + log.Fatalf("expected:\"%v\" != os.Getwd():\"%v\"", expectDir, cwd) +-- +2.50.0 + diff --git a/0004-Suggest-optional-packages-to-install-if-missing.patch b/0004-Suggest-optional-packages-to-install-if-missing.patch deleted file mode 100644 index b7f2c2c..0000000 --- a/0004-Suggest-optional-packages-to-install-if-missing.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 3f935d679870de924aa65d78c23ecdcb483ab4a3 Mon Sep 17 00:00:00 2001 -From: Elliott Sales de Andrade -Date: Sun, 6 Feb 2022 03:49:16 -0500 -Subject: [PATCH 04/18] Suggest optional packages to install if missing - -Signed-off-by: Elliott Sales de Andrade ---- - builder/jobs.go | 17 +++++++++++++++++ - builder/mingw-w64.go | 2 +- - builder/tools.go | 6 +++++- - 3 files changed, 23 insertions(+), 2 deletions(-) - -diff --git a/builder/jobs.go b/builder/jobs.go -index 3d510974..d24a4165 100644 ---- a/builder/jobs.go -+++ b/builder/jobs.go -@@ -7,6 +7,7 @@ import ( - "container/heap" - "errors" - "fmt" -+ "os" - "runtime" - "sort" - "strings" -@@ -37,6 +38,22 @@ type compileJob struct { - duration time.Duration // how long it took to run this job (only set after finishing) - } - -+// checkIfPackagedFileExistsJob returns a new *compileJob that checks if a file -+// exists. If the file does not exist, the job will fail with an error -+// suggesting to install the named system packageToInstall. -+func checkIfPackagedFileExistsJob(fileName, packageToInstall string) *compileJob { -+ return &compileJob{ -+ description: fmt.Sprintf("check if %v exists", fileName), -+ result: fileName, -+ run: func(*compileJob) (err error) { -+ if _, err := os.Stat(fileName); errors.Is(err, os.ErrNotExist) { -+ return fmt.Errorf("%v does not exist; please install %v via dnf", fileName, packageToInstall) -+ } -+ return nil -+ }, -+ } -+} -+ - // dummyCompileJob returns a new *compileJob that produces an output without - // doing anything. This can be useful where a *compileJob producing an output is - // expected but nothing needs to be done, for example for a load from a cache. -diff --git a/builder/mingw-w64.go b/builder/mingw-w64.go -index d233068d..d2539f6e 100644 ---- a/builder/mingw-w64.go -+++ b/builder/mingw-w64.go -@@ -27,7 +27,7 @@ func makeMinGWExtraLibs(tmpdir string) []*compileJob { - var jobs []*compileJob - for _, name := range []string{"kernel32", "ucrt"} { - outpath := fmt.Sprintf("/usr/x86_64-w64-mingw32/sys-root/mingw/lib/lib%s.a", name) -- job := dummyCompileJob(outpath) -+ job := checkIfPackagedFileExistsJob(outpath, "mingw64-crt and mingw64-headers") - jobs = append(jobs, job) - } - return jobs -diff --git a/builder/tools.go b/builder/tools.go -index 53d89bf0..e55719b2 100644 ---- a/builder/tools.go -+++ b/builder/tools.go -@@ -46,5 +46,9 @@ func link(linker string, flags ...string) error { - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Dir = goenv.Get("TINYGOROOT") -- return cmd.Run() -+ err := cmd.Run() -+ if linker == "avr-gcc" && errors.Is(err, exec.ErrNotFound) { -+ return errors.New("avr-gcc not found; please install avr-gcc and avr-libc via dnf") -+ } -+ return err - } --- -2.36.1 - diff --git a/0005-Skip-TestDirFS-on-32-bit-systems.patch b/0005-Skip-TestDirFS-on-32-bit-systems.patch deleted file mode 100644 index 9101800..0000000 --- a/0005-Skip-TestDirFS-on-32-bit-systems.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 41cbdf1cfe50f24b49beb615f0924ea3255c7e7d Mon Sep 17 00:00:00 2001 -From: Elliott Sales de Andrade -Date: Sun, 8 May 2022 04:18:05 -0400 -Subject: [PATCH 05/18] Skip TestDirFS on 32-bit systems - -Because Seek is not fully implemented there. - -Signed-off-by: Elliott Sales de Andrade ---- - src/os/os_anyos_test.go | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/os/os_anyos_test.go b/src/os/os_anyos_test.go -index dd255fb4..5dc0d860 100644 ---- a/src/os/os_anyos_test.go -+++ b/src/os/os_anyos_test.go -@@ -277,6 +277,10 @@ func TestDirFS(t *testing.T) { - t.Log("TODO: implement Readdir for Windows") - return - } -+ if runtime.GOARCH == "386" || runtime.GOARCH == "arm" { -+ t.Log("TODO: implement seek for 386 and arm") -+ return -+ } - if isWASI { - t.Log("TODO: allow foo/bar/. as synonym for path foo/bar on wasi?") - return --- -2.36.1 - diff --git a/0005-Skip-x86-tests-on-ARM.patch b/0005-Skip-x86-tests-on-ARM.patch new file mode 100644 index 0000000..aab0e48 --- /dev/null +++ b/0005-Skip-x86-tests-on-ARM.patch @@ -0,0 +1,44 @@ +From 9c8cef8d589dfbd2d913010a1211d8a49279c986 Mon Sep 17 00:00:00 2001 +From: Elliott Sales de Andrade +Date: Sat, 2 Aug 2025 18:30:43 -0400 +Subject: [PATCH 5/5] Skip x86 tests on ARM + +They are currently broken: +https://github.com/tinygo-org/tinygo/issues/4969 + +Signed-off-by: Elliott Sales de Andrade +--- + main_test.go | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/main_test.go b/main_test.go +index ca052821..13a40997 100644 +--- a/main_test.go ++++ b/main_test.go +@@ -192,7 +192,10 @@ func TestBuild(t *testing.T) { + if runtime.GOOS == "linux" { + for name, osArch := range supportedLinuxArches { + options := optionsFromOSARCH(osArch, sema) +- if options.GOARCH != runtime.GOARCH { // Native architecture already run above. ++ if options.GOARCH == "386" && runtime.GOARCH == "arm64" { ++ // This is currently broken running in qemu. ++ // https://github.com/tinygo-org/tinygo/issues/4969 ++ } else if options.GOARCH != runtime.GOARCH { // Native architecture already run above. + t.Run(name, func(t *testing.T) { + runPlatTests(options, tests, t) + }) +@@ -895,7 +898,10 @@ func TestTest(t *testing.T) { + if runtime.GOOS == "linux" { + for name, osArch := range supportedLinuxArches { + options := optionsFromOSARCH(osArch, sema) +- if options.GOARCH != runtime.GOARCH { // Native architecture already run above. ++ if options.GOARCH == "386" && runtime.GOARCH == "arm64" { ++ // This is currently broken running in qemu. ++ // https://github.com/tinygo-org/tinygo/issues/4969 ++ } else if options.GOARCH != runtime.GOARCH { // Native architecture already run above. + targs = append(targs, targ{name, options}) + } + } +-- +2.50.0 + diff --git a/0006-Skip-broken-tests-on-i686.patch b/0006-Skip-broken-tests-on-i686.patch deleted file mode 100644 index 98e0acf..0000000 --- a/0006-Skip-broken-tests-on-i686.patch +++ /dev/null @@ -1,44 +0,0 @@ -From a44f31de099aaf6768af2102919f1a8c221ce6f4 Mon Sep 17 00:00:00 2001 -From: Elliott Sales de Andrade -Date: Sun, 8 May 2022 18:39:26 -0400 -Subject: [PATCH 06/18] Skip broken tests on i686 - -* compress/flate runs out of memory -* testing/fstest uses Seek, which is not implemented there - -Signed-off-by: Elliott Sales de Andrade ---- - Makefile | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/Makefile b/Makefile -index 99f67c29..1ef11d29 100644 ---- a/Makefile -+++ b/Makefile -@@ -338,15 +338,21 @@ endif - # Additional standard library packages that pass tests on individual platforms - TEST_PACKAGES_LINUX := \ - archive/zip \ -- compress/flate \ - compress/lzw \ - crypto/hmac \ - debug/dwarf \ - debug/plan9obj \ - io/ioutil \ - strconv \ -- testing/fstest \ - text/template/parse -+ifneq ($(shell getconf LONG_BIT),32) -+# Some tests are skipped on 32-bit because: -+# compress/flate runs out of memory -+# testing/fstest uses Seek, which is not implemented there -+TEST_PACKAGES_LINUX += \ -+ compress/flate \ -+ testing/fstest -+endif - - TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX) - --- -2.36.1 - diff --git a/0007-wasm-fix-GC-scanning-of-allocas.patch b/0007-wasm-fix-GC-scanning-of-allocas.patch deleted file mode 100644 index 02da873..0000000 --- a/0007-wasm-fix-GC-scanning-of-allocas.patch +++ /dev/null @@ -1,265 +0,0 @@ -From e8f07384a0f5a61351a62931d3fb69bf6c451c1b Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Sun, 16 Oct 2022 00:44:38 +0200 -Subject: [PATCH 07/18] wasm: fix GC scanning of allocas - -Scanning of allocas was entirely broken on WebAssembly. The code -intended to do this was never run. There were also no tests. - -Looking into this further, I found that it is actually not really -necessary to do that: the C stack can be scanned conservatively and in -fact this was already done for goroutine stacks (because they live on -the heap and are always referenced). It wasn't done for the system stack -however. - -With these fixes, I believe code should be both faster *and* more -correct. - -I found this in my work to get opaque pointers supported in LLVM 15, -because the code that was never reached now finally got run and was -actually quite buggy. - -Signed-off-by: Elliott Sales de Andrade ---- - src/runtime/arch_tinygowasm.go | 3 +++ - src/runtime/asm_tinygowasm.S | 10 ++++++++++ - src/runtime/gc_stack_portable.go | 34 +++++++++++++++++++++----------- - targets/wasi.json | 3 +++ - targets/wasm.json | 3 +++ - transform/gc.go | 30 ++++++++-------------------- - transform/llvm.go | 28 ++++++++------------------ - 7 files changed, 57 insertions(+), 54 deletions(-) - create mode 100644 src/runtime/asm_tinygowasm.S - -diff --git a/src/runtime/arch_tinygowasm.go b/src/runtime/arch_tinygowasm.go -index 597b2489..f1893d91 100644 ---- a/src/runtime/arch_tinygowasm.go -+++ b/src/runtime/arch_tinygowasm.go -@@ -58,6 +58,8 @@ var ( - - globalsStart = uintptr(unsafe.Pointer(&globalsStartSymbol)) - globalsEnd = uintptr(unsafe.Pointer(&heapStartSymbol)) -+ -+ stackTop = uintptr(unsafe.Pointer(&globalsStartSymbol)) - ) - - func align(ptr uintptr) uintptr { -@@ -67,6 +69,7 @@ func align(ptr uintptr) uintptr { - return (ptr + heapAlign - 1) &^ (heapAlign - 1) - } - -+//export tinygo_getCurrentStackPointer - func getCurrentStackPointer() uintptr - - // growHeap tries to grow the heap size. It returns true if it succeeds, false -diff --git a/src/runtime/asm_tinygowasm.S b/src/runtime/asm_tinygowasm.S -new file mode 100644 -index 00000000..3278a7f6 ---- /dev/null -+++ b/src/runtime/asm_tinygowasm.S -@@ -0,0 +1,10 @@ -+.globaltype __stack_pointer, i32 -+ -+.global tinygo_getCurrentStackPointer -+.hidden tinygo_getCurrentStackPointer -+.type tinygo_getCurrentStackPointer,@function -+tinygo_getCurrentStackPointer: // func getCurrentStackPointer() uintptr -+ .functype tinygo_getCurrentStackPointer() -> (i32) -+ global.get __stack_pointer -+ return -+ end_function -diff --git a/src/runtime/gc_stack_portable.go b/src/runtime/gc_stack_portable.go -index 6ffc35d4..6802de02 100644 ---- a/src/runtime/gc_stack_portable.go -+++ b/src/runtime/gc_stack_portable.go -@@ -4,6 +4,7 @@ - package runtime - - import ( -+ "internal/task" - "unsafe" - ) - -@@ -17,19 +18,28 @@ type stackChainObject struct { - - // markStack marks all root pointers found on the stack. - // --// This implementation is conservative and relies on the compiler inserting code --// to manually push/pop stack objects that are stored in a linked list starting --// with stackChainStart. Manually keeping track of stack values is _much_ more --// expensive than letting the compiler do it and it inhibits a few important --// optimizations, but it has the big advantage of being portable to basically --// any ISA, including WebAssembly. -+// - Goroutine stacks are heap allocated and always reachable in some way -+// (for example through internal/task.currentTask) so they will always be -+// scanned. -+// - The system stack (aka startup stack) is not heap allocated, so even -+// though it may be referenced it will not be scanned by default. -+// -+// Therefore, we only need to scan the system stack. -+// It is relatively easy to scan the system stack while we're on it: we can -+// simply read __stack_pointer and __global_base and scan the area inbetween. -+// Unfortunately, it's hard to get the system stack pointer while we're on a -+// goroutine stack. But when we're on a goroutine stack, the system stack is in -+// the scheduler which means there shouldn't be anything on the system stack -+// anyway. -+// ...I hope this assumption holds, otherwise we will need to store the system -+// stack in a global or something. -+// -+// The compiler also inserts code to store all globals in a chain via -+// stackChainStart. Luckily we don't need to scan these, as these globals are -+// stored on the goroutine stack and are therefore already getting scanned. - func markStack() { -- stackObject := stackChainStart -- for stackObject != nil { -- start := uintptr(unsafe.Pointer(stackObject)) + unsafe.Sizeof(uintptr(0))*2 -- end := start + stackObject.numSlots*unsafe.Alignof(uintptr(0)) -- markRoots(start, end) -- stackObject = stackObject.parent -+ if task.OnSystemStack() { -+ markRoots(getCurrentStackPointer(), stackTop) - } - } - -diff --git a/targets/wasi.json b/targets/wasi.json -index e710b4bb..6cec6be4 100644 ---- a/targets/wasi.json -+++ b/targets/wasi.json -@@ -18,6 +18,9 @@ - "--stack-first", - "--no-demangle" - ], -+ "extra-files": [ -+ "src/runtime/asm_tinygowasm.S" -+ ], - "emulator": "wasmtime {}", - "wasm-abi": "generic" - } -diff --git a/targets/wasm.json b/targets/wasm.json -index 2bcada5f..26494cc4 100644 ---- a/targets/wasm.json -+++ b/targets/wasm.json -@@ -19,6 +19,9 @@ - "--stack-first", - "--no-demangle" - ], -+ "extra-files": [ -+ "src/runtime/asm_tinygowasm.S" -+ ], - "emulator": "node {root}/targets/wasm_exec.js {}", - "wasm-abi": "js" - } -diff --git a/transform/gc.go b/transform/gc.go -index eb3520aa..87dc6e88 100644 ---- a/transform/gc.go -+++ b/transform/gc.go -@@ -139,7 +139,7 @@ func MakeGCStackSlots(mod llvm.Module) bool { - } - - // Determine what to do with each call. -- var allocas, pointers []llvm.Value -+ var pointers []llvm.Value - for _, call := range calls { - ptr := call.Operand(0) - call.EraseFromParentAsInstruction() -@@ -189,16 +189,15 @@ func MakeGCStackSlots(mod llvm.Module) bool { - // be optimized if needed. - } - -- if !ptr.IsAAllocaInst().IsNil() { -- if typeHasPointers(ptr.Type().ElementType()) { -- allocas = append(allocas, ptr) -- } -- } else { -- pointers = append(pointers, ptr) -+ if ptr := stripPointerCasts(ptr); !ptr.IsAAllocaInst().IsNil() { -+ // Allocas don't need to be tracked because they are allocated -+ // on the C stack which is scanned separately. -+ continue - } -+ pointers = append(pointers, ptr) - } - -- if len(allocas) == 0 && len(pointers) == 0 { -+ if len(pointers) == 0 { - // This function does not need to keep track of stack pointers. - continue - } -@@ -208,9 +207,6 @@ func MakeGCStackSlots(mod llvm.Module) bool { - stackChainStartType, // Pointer to parent frame. - uintptrType, // Number of elements in this frame. - } -- for _, alloca := range allocas { -- fields = append(fields, alloca.Type().ElementType()) -- } - for _, ptr := range pointers { - fields = append(fields, ptr.Type()) - } -@@ -235,16 +231,6 @@ func MakeGCStackSlots(mod llvm.Module) bool { - stackObjectCast := builder.CreateBitCast(stackObject, stackChainStartType, "") - builder.CreateStore(stackObjectCast, stackChainStart) - -- // Replace all independent allocas with GEPs in the stack object. -- for i, alloca := range allocas { -- gep := builder.CreateGEP(stackObject, []llvm.Value{ -- llvm.ConstInt(ctx.Int32Type(), 0, false), -- llvm.ConstInt(ctx.Int32Type(), uint64(2+i), false), -- }, "") -- alloca.ReplaceAllUsesWith(gep) -- alloca.EraseFromParentAsInstruction() -- } -- - // Do a store to the stack object after each new pointer that is created. - pointerStores := make(map[llvm.Value]struct{}) - for i, ptr := range pointers { -@@ -260,7 +246,7 @@ func MakeGCStackSlots(mod llvm.Module) bool { - // Extract a pointer to the appropriate section of the stack object. - gep := builder.CreateGEP(stackObject, []llvm.Value{ - llvm.ConstInt(ctx.Int32Type(), 0, false), -- llvm.ConstInt(ctx.Int32Type(), uint64(2+len(allocas)+i), false), -+ llvm.ConstInt(ctx.Int32Type(), uint64(2+i), false), - }, "") - - // Store the pointer into the stack slot. -diff --git a/transform/llvm.go b/transform/llvm.go -index 90b7a7c7..32ee9560 100644 ---- a/transform/llvm.go -+++ b/transform/llvm.go -@@ -75,26 +75,14 @@ func replaceGlobalIntWithArray(mod llvm.Module, name string, buf interface{}) ll - return global - } - --// typeHasPointers returns whether this type is a pointer or contains pointers. --// If the type is an aggregate type, it will check whether there is a pointer --// inside. --func typeHasPointers(t llvm.Type) bool { -- switch t.TypeKind() { -- case llvm.PointerTypeKind: -- return true -- case llvm.StructTypeKind: -- for _, subType := range t.StructElementTypes() { -- if typeHasPointers(subType) { -- return true -- } -+// stripPointerCasts strips instruction pointer casts (getelementptr and -+// bitcast) and returns the original value without the casts. -+func stripPointerCasts(value llvm.Value) llvm.Value { -+ if !value.IsAInstruction().IsNil() { -+ switch value.InstructionOpcode() { -+ case llvm.GetElementPtr, llvm.BitCast: -+ return stripPointerCasts(value.Operand(0)) - } -- return false -- case llvm.ArrayTypeKind: -- if typeHasPointers(t.ElementType()) { -- return true -- } -- return false -- default: -- return false - } -+ return value - } --- -2.36.1 - diff --git a/0008-compiler-return-a-FunctionType-not-a-PointerType-in-.patch b/0008-compiler-return-a-FunctionType-not-a-PointerType-in-.patch deleted file mode 100644 index 77d6ea3..0000000 --- a/0008-compiler-return-a-FunctionType-not-a-PointerType-in-.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 9e64a63d49100e550fad97b390bb01489ed6ca44 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Tue, 20 Sep 2022 23:59:22 +0200 -Subject: [PATCH 08/18] compiler: return a FunctionType (not a PointerType) in - getRawFuncType - -This is necessary for opaque pointer support (in LLVM 15). - -Signed-off-by: Elliott Sales de Andrade ---- - compiler/func.go | 4 ++-- - compiler/interface.go | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/compiler/func.go b/compiler/func.go -index 75656cb7..a8b2874e 100644 ---- a/compiler/func.go -+++ b/compiler/func.go -@@ -62,7 +62,7 @@ func (b *builder) decodeFuncValue(funcValue llvm.Value, sig *types.Signature) (f - funcPtr = bitcast.Operand(0) - return - } -- llvmSig := b.getRawFuncType(sig) -+ llvmSig := llvm.PointerType(b.getRawFuncType(sig), b.funcPtrAddrSpace) - funcPtr = b.CreateBitCast(bitcast, llvmSig, "") - return - } -@@ -117,7 +117,7 @@ func (c *compilerContext) getRawFuncType(typ *types.Signature) llvm.Type { - paramTypes = append(paramTypes, c.i8ptrType) // context - - // Make a func type out of the signature. -- return llvm.PointerType(llvm.FunctionType(returnType, paramTypes, false), c.funcPtrAddrSpace) -+ return llvm.FunctionType(returnType, paramTypes, false) - } - - // parseMakeClosure makes a function value (with context) from the given -diff --git a/compiler/interface.go b/compiler/interface.go -index c59a9ade..b0ea71e3 100644 ---- a/compiler/interface.go -+++ b/compiler/interface.go -@@ -465,7 +465,7 @@ func (c *compilerContext) getInvokeFunction(instr *ssa.CallCommon) llvm.Value { - paramTuple = append(paramTuple, sig.Params().At(i)) - } - paramTuple = append(paramTuple, types.NewVar(token.NoPos, nil, "$typecode", types.Typ[types.Uintptr])) -- llvmFnType := c.getRawFuncType(types.NewSignature(sig.Recv(), types.NewTuple(paramTuple...), sig.Results(), false)).ElementType() -+ llvmFnType := c.getRawFuncType(types.NewSignature(sig.Recv(), types.NewTuple(paramTuple...), sig.Results(), false)) - llvmFn = llvm.AddFunction(c.mod, fnName, llvmFnType) - c.addStandardDeclaredAttributes(llvmFn) - llvmFn.AddFunctionAttr(c.ctx.CreateStringAttribute("tinygo-invoke", c.getMethodSignatureName(instr.Method))) --- -2.36.1 - diff --git a/0009-all-add-type-parameter-to-CreateCall.patch b/0009-all-add-type-parameter-to-CreateCall.patch deleted file mode 100644 index ca16ea3..0000000 --- a/0009-all-add-type-parameter-to-CreateCall.patch +++ /dev/null @@ -1,993 +0,0 @@ -From 8138d69793c00829df45501c35975055ad52d151 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Wed, 21 Sep 2022 00:37:01 +0200 -Subject: [PATCH 09/18] all: add type parameter to CreateCall - -This uses LLVMBuildCall2 in the background, which is the replacement for -the deprecated LLVMBuildCall function. - -Signed-off-by: Elliott Sales de Andrade ---- - builder/build.go | 2 +- - compiler/alias.go | 2 +- - compiler/atomic.go | 4 ++-- - compiler/calls.go | 14 +++++++------- - compiler/compiler.go | 25 ++++++++++++++++--------- - compiler/defer.go | 16 ++++++++++------ - compiler/func.go | 8 +++++--- - compiler/goroutine.go | 33 ++++++++++++++++++--------------- - compiler/inlineasm.go | 16 ++++++++-------- - compiler/interface.go | 17 ++++++++--------- - compiler/interrupt.go | 4 ++-- - compiler/intrinsics.go | 6 +++--- - compiler/llvm.go | 2 +- - compiler/llvmutil/llvm.go | 24 ++++++++++++++---------- - compiler/llvmutil/wordpack.go | 4 ++-- - compiler/symbol.go | 6 +++--- - compiler/syscall.go | 14 +++++++------- - go.mod | 2 +- - go.sum | 4 ++-- - interp/interp.go | 2 +- - interp/interpreter.go | 2 +- - transform/interface-lowering.go | 7 ++++--- - transform/interrupt.go | 2 +- - transform/panic.go | 2 +- - transform/rtcalls.go | 2 +- - transform/wasm-abi.go | 6 +++--- - 26 files changed, 123 insertions(+), 103 deletions(-) - -diff --git a/builder/build.go b/builder/build.go -index 2008c897..28385044 100644 ---- a/builder/build.go -+++ b/builder/build.go -@@ -523,7 +523,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil - if pkgInit.IsNil() { - panic("init not found for " + pkg.Pkg.Path()) - } -- irbuilder.CreateCall(pkgInit, []llvm.Value{llvm.Undef(i8ptrType)}, "") -+ irbuilder.CreateCall(pkgInit.GlobalValueType(), pkgInit, []llvm.Value{llvm.Undef(i8ptrType)}, "") - } - irbuilder.CreateRetVoid() - -diff --git a/compiler/alias.go b/compiler/alias.go -index 9e88e3c6..b16cbce8 100644 ---- a/compiler/alias.go -+++ b/compiler/alias.go -@@ -52,7 +52,7 @@ func (b *builder) createAlias(alias llvm.Value) { - b.CreateUnreachable() - return - } -- result := b.CreateCall(alias, b.llvmFn.Params(), "") -+ result := b.CreateCall(alias.GlobalValueType(), alias, b.llvmFn.Params(), "") - if result.Type().TypeKind() == llvm.VoidTypeKind { - b.CreateRetVoid() - } else { -diff --git a/compiler/atomic.go b/compiler/atomic.go -index f12c6d11..6ba3849c 100644 ---- a/compiler/atomic.go -+++ b/compiler/atomic.go -@@ -25,7 +25,7 @@ func (b *builder) createAtomicOp(name string) llvm.Value { - if fn.IsNil() { - fn = llvm.AddFunction(b.mod, name, llvm.FunctionType(vType, []llvm.Type{ptr.Type(), vType}, false)) - } -- oldVal := b.createCall(fn, []llvm.Value{ptr, val}, "") -+ oldVal := b.createCall(fn.GlobalValueType(), fn, []llvm.Value{ptr, val}, "") - // Return the new value, not the original value returned. - return b.CreateAdd(oldVal, val, "") - } -@@ -78,7 +78,7 @@ func (b *builder) createAtomicOp(name string) llvm.Value { - if fn.IsNil() { - fn = llvm.AddFunction(b.mod, name, llvm.FunctionType(vType, []llvm.Type{ptr.Type(), vType, b.uintptrType}, false)) - } -- b.createCall(fn, []llvm.Value{ptr, val, llvm.ConstInt(b.uintptrType, 5, false)}, "") -+ b.createCall(fn.GlobalValueType(), fn, []llvm.Value{ptr, val, llvm.ConstInt(b.uintptrType, 5, false)}, "") - return llvm.Value{} - } - store := b.CreateStore(val, ptr) -diff --git a/compiler/calls.go b/compiler/calls.go -index aeca518a..b38d770f 100644 ---- a/compiler/calls.go -+++ b/compiler/calls.go -@@ -37,15 +37,15 @@ const ( - // createRuntimeInvoke instead. - func (b *builder) createRuntimeCallCommon(fnName string, args []llvm.Value, name string, isInvoke bool) llvm.Value { - fn := b.program.ImportedPackage("runtime").Members[fnName].(*ssa.Function) -- llvmFn := b.getFunction(fn) -+ fnType, llvmFn := b.getFunction(fn) - if llvmFn.IsNil() { - panic("trying to call non-existent function: " + fn.RelString(nil)) - } - args = append(args, llvm.Undef(b.i8ptrType)) // unused context parameter - if isInvoke { -- return b.createInvoke(llvmFn, args, name) -+ return b.createInvoke(fnType, llvmFn, args, name) - } -- return b.createCall(llvmFn, args, name) -+ return b.createCall(fnType, llvmFn, args, name) - } - - // createRuntimeCall creates a new call to runtime. with the given -@@ -65,22 +65,22 @@ func (b *builder) createRuntimeInvoke(fnName string, args []llvm.Value, name str - - // createCall creates a call to the given function with the arguments possibly - // expanded. --func (b *builder) createCall(fn llvm.Value, args []llvm.Value, name string) llvm.Value { -+func (b *builder) createCall(fnType llvm.Type, fn llvm.Value, args []llvm.Value, name string) llvm.Value { - expanded := make([]llvm.Value, 0, len(args)) - for _, arg := range args { - fragments := b.expandFormalParam(arg) - expanded = append(expanded, fragments...) - } -- return b.CreateCall(fn, expanded, name) -+ return b.CreateCall(fnType, fn, expanded, name) - } - - // createInvoke is like createCall but continues execution at the landing pad if - // the call resulted in a panic. --func (b *builder) createInvoke(fn llvm.Value, args []llvm.Value, name string) llvm.Value { -+func (b *builder) createInvoke(fnType llvm.Type, fn llvm.Value, args []llvm.Value, name string) llvm.Value { - if b.hasDeferFrame() { - b.createInvokeCheckpoint() - } -- return b.createCall(fn, args, name) -+ return b.createCall(fnType, fn, args, name) - } - - // Expand an argument type to a list that can be used in a function call -diff --git a/compiler/compiler.go b/compiler/compiler.go -index bbaf6432..b64fddcc 100644 ---- a/compiler/compiler.go -+++ b/compiler/compiler.go -@@ -131,6 +131,7 @@ type builder struct { - *compilerContext - llvm.Builder - fn *ssa.Function -+ llvmFnType llvm.Type - llvmFn llvm.Value - info functionInfo - locals map[ssa.Value]llvm.Value // local variables -@@ -155,11 +156,13 @@ type builder struct { - } - - func newBuilder(c *compilerContext, irbuilder llvm.Builder, f *ssa.Function) *builder { -+ fnType, fn := c.getFunction(f) - return &builder{ - compilerContext: c, - Builder: irbuilder, - fn: f, -- llvmFn: c.getFunction(f), -+ llvmFnType: fnType, -+ llvmFn: fn, - info: c.getFunctionInfo(f), - locals: make(map[ssa.Value]llvm.Value), - dilocals: make(map[*types.Var]llvm.Metadata), -@@ -711,7 +714,8 @@ func (b *builder) getLocalVariable(variable *types.Var) llvm.Metadata { - // DISubprogram metadata node. - func (c *compilerContext) attachDebugInfo(f *ssa.Function) llvm.Metadata { - pos := c.program.Fset.Position(f.Syntax().Pos()) -- return c.attachDebugInfoRaw(f, c.getFunction(f), "", pos.Filename, pos.Line) -+ _, fn := c.getFunction(f) -+ return c.attachDebugInfoRaw(f, fn, "", pos.Filename, pos.Line) - } - - // attachDebugInfo adds debug info to a function declaration. It returns the -@@ -1654,6 +1658,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) - - // Try to call the function directly for trivially static calls. - var callee, context llvm.Value -+ var calleeType llvm.Type - exported := false - if fn := instr.StaticCallee(); fn != nil { - // Direct function call, either to a named or anonymous (directly -@@ -1684,7 +1689,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) - return b.createInterruptGlobal(instr) - } - -- callee = b.getFunction(fn) -+ calleeType, callee = b.getFunction(fn) - info := b.getFunctionInfo(fn) - if callee.IsNil() { - return llvm.Value{}, b.makeError(instr.Pos(), "undefined function: "+info.linkName) -@@ -1698,8 +1703,8 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) - // Eventually we might be able to eliminate this special case - // entirely. For details, see: - // https://discourse.llvm.org/t/rfc-enabling-wstrict-prototypes-by-default-in-c/60521 -- fnType := llvm.FunctionType(callee.Type().ElementType().ReturnType(), nil, false) -- callee = llvm.ConstBitCast(callee, llvm.PointerType(fnType, b.funcPtrAddrSpace)) -+ calleeType = llvm.FunctionType(callee.Type().ElementType().ReturnType(), nil, false) -+ callee = llvm.ConstBitCast(callee, llvm.PointerType(calleeType, b.funcPtrAddrSpace)) - } - case *ssa.MakeClosure: - // A call on a func value, but the callee is trivial to find. For -@@ -1726,13 +1731,14 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) - params = append([]llvm.Value{value}, params...) - params = append(params, typecode) - callee = b.getInvokeFunction(instr) -+ calleeType = callee.GlobalValueType() - context = llvm.Undef(b.i8ptrType) - } else { - // Function pointer. - value := b.getValue(instr.Value) - // This is a func value, which cannot be called directly. We have to - // extract the function pointer and context first from the func value. -- callee, context = b.decodeFuncValue(value, instr.Value.Type().Underlying().(*types.Signature)) -+ calleeType, callee, context = b.decodeFuncValue(value, instr.Value.Type().Underlying().(*types.Signature)) - b.createNilCheck(instr.Value, callee, "fpcall") - } - -@@ -1742,7 +1748,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) - params = append(params, context) - } - -- return b.createInvoke(callee, params, ""), nil -+ return b.createInvoke(calleeType, callee, params, ""), nil - } - - // getValue returns the LLVM value of a constant, function value, global, or -@@ -1756,7 +1762,8 @@ func (b *builder) getValue(expr ssa.Value) llvm.Value { - b.addError(expr.Pos(), "cannot use an exported function as value: "+expr.String()) - return llvm.Undef(b.getLLVMType(expr.Type())) - } -- return b.createFuncValue(b.getFunction(expr), llvm.Undef(b.i8ptrType), expr.Signature) -+ _, fn := b.getFunction(expr) -+ return b.createFuncValue(fn, llvm.Undef(b.i8ptrType), expr.Signature) - case *ssa.Global: - value := b.getGlobal(expr) - if value.IsNil() { -@@ -3080,7 +3087,7 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) { - // Instead of a load from the global, create a bitcast of the - // function pointer itself. - name := strings.TrimSuffix(unop.X.(*ssa.Global).Name(), "$funcaddr") -- fn := b.getFunction(b.fn.Pkg.Members[name].(*ssa.Function)) -+ _, fn := b.getFunction(b.fn.Pkg.Members[name].(*ssa.Function)) - if fn.IsNil() { - return llvm.Value{}, b.makeError(unop.Pos(), "cgo function not found: "+name) - } -diff --git a/compiler/defer.go b/compiler/defer.go -index 75c1be3d..e82370fa 100644 ---- a/compiler/defer.go -+++ b/compiler/defer.go -@@ -201,7 +201,7 @@ li a0, 0 - } - asmType := llvm.FunctionType(resultType, []llvm.Type{b.deferFrame.Type()}, false) - asm := llvm.InlineAsm(asmType, asmString, constraints, false, false, 0, false) -- result := b.CreateCall(asm, []llvm.Value{b.deferFrame}, "setjmp") -+ result := b.CreateCall(asmType, asm, []llvm.Value{b.deferFrame}, "setjmp") - result.AddCallSiteAttribute(-1, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("returns_twice"), 0)) - isZero := b.CreateICmp(llvm.IntEQ, result, llvm.ConstInt(resultType, 0, false), "setjmp.result") - continueBB := b.insertBasicBlock("") -@@ -492,6 +492,7 @@ func (b *builder) createRunDefers() { - } - - var fnPtr llvm.Value -+ var fnType llvm.Type - - if !callback.IsInvoke() { - // Isolate the func value. -@@ -499,8 +500,8 @@ func (b *builder) createRunDefers() { - forwardParams = forwardParams[1:] - - //Get function pointer and context -- fp, context := b.decodeFuncValue(funcValue, callback.Signature()) -- fnPtr = fp -+ var context llvm.Value -+ fnType, fnPtr, context = b.decodeFuncValue(funcValue, callback.Signature()) - - //Pass context - forwardParams = append(forwardParams, context) -@@ -509,6 +510,7 @@ func (b *builder) createRunDefers() { - // parameters. - forwardParams = append(forwardParams[1:], forwardParams[0]) - fnPtr = b.getInvokeFunction(callback) -+ fnType = fnPtr.GlobalValueType() - - // Add the context parameter. An interface call cannot also be a - // closure but we have to supply the parameter anyway for platforms -@@ -516,7 +518,7 @@ func (b *builder) createRunDefers() { - forwardParams = append(forwardParams, llvm.Undef(b.i8ptrType)) - } - -- b.createCall(fnPtr, forwardParams, "") -+ b.createCall(fnType, fnPtr, forwardParams, "") - - case *ssa.Function: - // Direct call. -@@ -547,7 +549,8 @@ func (b *builder) createRunDefers() { - } - - // Call real function. -- b.createInvoke(b.getFunction(callback), forwardParams, "") -+ fnType, fn := b.getFunction(callback) -+ b.createInvoke(fnType, fn, forwardParams, "") - - case *ssa.MakeClosure: - // Get the real defer struct type and cast to it. -@@ -571,7 +574,8 @@ func (b *builder) createRunDefers() { - } - - // Call deferred function. -- b.createCall(b.getFunction(fn), forwardParams, "") -+ fnType, llvmFn := b.getFunction(fn) -+ b.createCall(fnType, llvmFn, forwardParams, "") - case *ssa.Builtin: - db := b.deferBuiltinFuncs[callback] - -diff --git a/compiler/func.go b/compiler/func.go -index a8b2874e..c6a8802d 100644 ---- a/compiler/func.go -+++ b/compiler/func.go -@@ -55,14 +55,15 @@ func (b *builder) extractFuncContext(funcValue llvm.Value) llvm.Value { - - // decodeFuncValue extracts the context and the function pointer from this func - // value. This may be an expensive operation. --func (b *builder) decodeFuncValue(funcValue llvm.Value, sig *types.Signature) (funcPtr, context llvm.Value) { -+func (b *builder) decodeFuncValue(funcValue llvm.Value, sig *types.Signature) (funcType llvm.Type, funcPtr, context llvm.Value) { - context = b.CreateExtractValue(funcValue, 0, "") - bitcast := b.CreateExtractValue(funcValue, 1, "") - if !bitcast.IsAConstantExpr().IsNil() && bitcast.Opcode() == llvm.BitCast { - funcPtr = bitcast.Operand(0) - return - } -- llvmSig := llvm.PointerType(b.getRawFuncType(sig), b.funcPtrAddrSpace) -+ funcType = b.getRawFuncType(sig) -+ llvmSig := llvm.PointerType(funcType, b.funcPtrAddrSpace) - funcPtr = b.CreateBitCast(bitcast, llvmSig, "") - return - } -@@ -141,5 +142,6 @@ func (b *builder) parseMakeClosure(expr *ssa.MakeClosure) (llvm.Value, error) { - context := b.emitPointerPack(boundVars) - - // Create the closure. -- return b.createFuncValue(b.getFunction(f), context, f.Signature), nil -+ _, fn := b.getFunction(f) -+ return b.createFuncValue(fn, context, f.Signature), nil - } -diff --git a/compiler/goroutine.go b/compiler/goroutine.go -index 8d76c89f..ba8ec0f4 100644 ---- a/compiler/goroutine.go -+++ b/compiler/goroutine.go -@@ -22,6 +22,7 @@ func (b *builder) createGo(instr *ssa.Go) { - - var prefix string - var funcPtr llvm.Value -+ var funcPtrType llvm.Type - hasContext := false - if callee := instr.Call.StaticCallee(); callee != nil { - // Static callee is known. This makes it easier to start a new -@@ -42,7 +43,7 @@ func (b *builder) createGo(instr *ssa.Go) { - params = append(params, context) // context parameter - hasContext = true - } -- funcPtr = b.getFunction(callee) -+ funcPtrType, funcPtr = b.getFunction(callee) - } else if builtin, ok := instr.Call.Value.(*ssa.Builtin); ok { - // We cheat. None of the builtins do any long or blocking operation, so - // we might as well run these builtins right away without the program -@@ -80,6 +81,7 @@ func (b *builder) createGo(instr *ssa.Go) { - itfTypeCode := b.CreateExtractValue(itf, 0, "") - itfValue := b.CreateExtractValue(itf, 1, "") - funcPtr = b.getInvokeFunction(&instr.Call) -+ funcPtrType = funcPtr.GlobalValueType() - params = append([]llvm.Value{itfValue}, params...) // start with receiver - params = append(params, itfTypeCode) // end with typecode - } else { -@@ -89,7 +91,7 @@ func (b *builder) createGo(instr *ssa.Go) { - // * The function context, for closures. - // * The function pointer (for tasks). - var context llvm.Value -- funcPtr, context = b.decodeFuncValue(b.getValue(instr.Call.Value), instr.Call.Value.Type().Underlying().(*types.Signature)) -+ funcPtrType, funcPtr, context = b.decodeFuncValue(b.getValue(instr.Call.Value), instr.Call.Value.Type().Underlying().(*types.Signature)) - params = append(params, context, funcPtr) - hasContext = true - prefix = b.fn.RelString(nil) -@@ -97,14 +99,14 @@ func (b *builder) createGo(instr *ssa.Go) { - - paramBundle := b.emitPointerPack(params) - var stackSize llvm.Value -- callee := b.createGoroutineStartWrapper(funcPtr, prefix, hasContext, instr.Pos()) -+ callee := b.createGoroutineStartWrapper(funcPtrType, funcPtr, prefix, hasContext, instr.Pos()) - if b.AutomaticStackSize { - // The stack size is not known until after linking. Call a dummy - // function that will be replaced with a load from a special ELF - // section that contains the stack size (and is modified after - // linking). -- stackSizeFn := b.getFunction(b.program.ImportedPackage("internal/task").Members["getGoroutineStackSize"].(*ssa.Function)) -- stackSize = b.createCall(stackSizeFn, []llvm.Value{callee, llvm.Undef(b.i8ptrType)}, "stacksize") -+ stackSizeFnType, stackSizeFn := b.getFunction(b.program.ImportedPackage("internal/task").Members["getGoroutineStackSize"].(*ssa.Function)) -+ stackSize = b.createCall(stackSizeFnType, stackSizeFn, []llvm.Value{callee, llvm.Undef(b.i8ptrType)}, "stacksize") - } else { - // The stack size is fixed at compile time. By emitting it here as a - // constant, it can be optimized. -@@ -113,8 +115,8 @@ func (b *builder) createGo(instr *ssa.Go) { - } - stackSize = llvm.ConstInt(b.uintptrType, b.DefaultStackSize, false) - } -- start := b.getFunction(b.program.ImportedPackage("internal/task").Members["start"].(*ssa.Function)) -- b.createCall(start, []llvm.Value{callee, paramBundle, stackSize, llvm.Undef(b.i8ptrType)}, "") -+ fnType, start := b.getFunction(b.program.ImportedPackage("internal/task").Members["start"].(*ssa.Function)) -+ b.createCall(fnType, start, []llvm.Value{callee, paramBundle, stackSize, llvm.Undef(b.i8ptrType)}, "") - } - - // createGoroutineStartWrapper creates a wrapper for the task-based -@@ -140,15 +142,16 @@ func (b *builder) createGo(instr *ssa.Go) { - // to last parameter of the function) is used for this wrapper. If hasContext is - // false, the parameter bundle is assumed to have no context parameter and undef - // is passed instead. --func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix string, hasContext bool, pos token.Pos) llvm.Value { -+func (c *compilerContext) createGoroutineStartWrapper(fnType llvm.Type, fn llvm.Value, prefix string, hasContext bool, pos token.Pos) llvm.Value { - var wrapper llvm.Value - - builder := c.ctx.NewBuilder() - defer builder.Dispose() - - var deadlock llvm.Value -+ var deadlockType llvm.Type - if c.Scheduler == "asyncify" { -- deadlock = c.getFunction(c.program.ImportedPackage("runtime").Members["deadlock"].(*ssa.Function)) -+ deadlockType, deadlock = c.getFunction(c.program.ImportedPackage("runtime").Members["deadlock"].(*ssa.Function)) - } - - if !fn.IsAFunction().IsNil() { -@@ -192,7 +195,7 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri - } - - // Create the list of params for the call. -- paramTypes := fn.Type().ElementType().ParamTypes() -+ paramTypes := fnType.ParamTypes() - if !hasContext { - paramTypes = paramTypes[:len(paramTypes)-1] // strip context parameter - } -@@ -202,10 +205,10 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri - } - - // Create the call. -- builder.CreateCall(fn, params, "") -+ builder.CreateCall(fnType, fn, params, "") - - if c.Scheduler == "asyncify" { -- builder.CreateCall(deadlock, []llvm.Value{ -+ builder.CreateCall(deadlockType, deadlock, []llvm.Value{ - llvm.Undef(c.i8ptrType), - }, "") - } -@@ -261,7 +264,7 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri - } - - // Get the list of parameters, with the extra parameters at the end. -- paramTypes := fn.Type().ElementType().ParamTypes() -+ paramTypes := fnType.ParamTypes() - paramTypes = append(paramTypes, fn.Type()) // the last element is the function pointer - params := llvmutil.EmitPointerUnpack(builder, c.mod, wrapper.Param(0), paramTypes) - -@@ -270,10 +273,10 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri - params = params[:len(params)-1] - - // Create the call. -- builder.CreateCall(fnPtr, params, "") -+ builder.CreateCall(fnType, fnPtr, params, "") - - if c.Scheduler == "asyncify" { -- builder.CreateCall(deadlock, []llvm.Value{ -+ builder.CreateCall(deadlockType, deadlock, []llvm.Value{ - llvm.Undef(c.i8ptrType), - }, "") - } -diff --git a/compiler/inlineasm.go b/compiler/inlineasm.go -index 27b0492b..2afb0a16 100644 ---- a/compiler/inlineasm.go -+++ b/compiler/inlineasm.go -@@ -25,7 +25,7 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) { - fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{}, false) - asm := constant.StringVal(args[0].(*ssa.Const).Value) - target := llvm.InlineAsm(fnType, asm, "", true, false, 0, false) -- return b.CreateCall(target, nil, ""), nil -+ return b.CreateCall(fnType, target, nil, ""), nil - } - - // This is a compiler builtin, which allows assembly to be called in a flexible -@@ -120,7 +120,7 @@ func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error) - } - fnType := llvm.FunctionType(outputType, argTypes, false) - target := llvm.InlineAsm(fnType, asmString, strings.Join(constraints, ","), true, false, 0, false) -- result := b.CreateCall(target, args, "") -+ result := b.CreateCall(fnType, target, args, "") - if hasOutput { - return result, nil - } else { -@@ -163,7 +163,7 @@ func (b *builder) emitSVCall(args []ssa.Value) (llvm.Value, error) { - constraints += ",~{r1},~{r2},~{r3}" - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) - target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0, false) -- return b.CreateCall(target, llvmArgs, ""), nil -+ return b.CreateCall(fnType, target, llvmArgs, ""), nil - } - - // This is a compiler builtin which emits an inline SVCall instruction. It can -@@ -201,7 +201,7 @@ func (b *builder) emitSV64Call(args []ssa.Value) (llvm.Value, error) { - constraints += ",~{x1},~{x2},~{x3},~{x4},~{x5},~{x6},~{x7}" - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) - target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0, false) -- return b.CreateCall(target, llvmArgs, ""), nil -+ return b.CreateCall(fnType, target, llvmArgs, ""), nil - } - - // This is a compiler builtin which emits CSR instructions. It can be one of: -@@ -226,24 +226,24 @@ func (b *builder) emitCSROperation(call *ssa.CallCommon) (llvm.Value, error) { - fnType := llvm.FunctionType(b.uintptrType, nil, false) - asm := fmt.Sprintf("csrr $0, %d", csr) - target := llvm.InlineAsm(fnType, asm, "=r", true, false, 0, false) -- return b.CreateCall(target, nil, ""), nil -+ return b.CreateCall(fnType, target, nil, ""), nil - case "Set": - fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.uintptrType}, false) - asm := fmt.Sprintf("csrw %d, $0", csr) - target := llvm.InlineAsm(fnType, asm, "r", true, false, 0, false) -- return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil -+ return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil - case "SetBits": - // Note: it may be possible to optimize this to csrrsi in many cases. - fnType := llvm.FunctionType(b.uintptrType, []llvm.Type{b.uintptrType}, false) - asm := fmt.Sprintf("csrrs $0, %d, $1", csr) - target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0, false) -- return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil -+ return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil - case "ClearBits": - // Note: it may be possible to optimize this to csrrci in many cases. - fnType := llvm.FunctionType(b.uintptrType, []llvm.Type{b.uintptrType}, false) - asm := fmt.Sprintf("csrrc $0, %d, $1", csr) - target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0, false) -- return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil -+ return b.CreateCall(fnType, target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil - default: - return llvm.Value{}, b.makeError(call.Pos(), "unknown CSR operation: "+name) - } -diff --git a/compiler/interface.go b/compiler/interface.go -index b0ea71e3..72f8952d 100644 ---- a/compiler/interface.go -+++ b/compiler/interface.go -@@ -254,12 +254,12 @@ func (c *compilerContext) getTypeMethodSet(typ types.Type) llvm.Value { - method := ms.At(i) - signatureGlobal := c.getMethodSignature(method.Obj().(*types.Func)) - fn := c.program.MethodValue(method) -- llvmFn := c.getFunction(fn) -+ llvmFnType, llvmFn := c.getFunction(fn) - if llvmFn.IsNil() { - // compiler error, so panic - panic("cannot find function: " + c.getFunctionInfo(fn).linkName) - } -- wrapper := c.getInterfaceInvokeWrapper(fn, llvmFn) -+ wrapper := c.getInterfaceInvokeWrapper(fn, llvmFnType, llvmFn) - methodInfo := llvm.ConstNamedStruct(interfaceMethodInfoType, []llvm.Value{ - signatureGlobal, - llvm.ConstPtrToInt(wrapper, c.uintptrType), -@@ -361,7 +361,7 @@ func (b *builder) createTypeAssert(expr *ssa.TypeAssert) llvm.Value { - // implements each method of the interface. See: - // https://research.swtch.com/interfaces - fn := b.getInterfaceImplementsFunc(expr.AssertedType) -- commaOk = b.CreateCall(fn, []llvm.Value{actualTypeNum}, "") -+ commaOk = b.CreateCall(fn.GlobalValueType(), fn, []llvm.Value{actualTypeNum}, "") - - } else { - globalName := "reflect/types.typeid:" + getTypeCodeName(expr.AssertedType) -@@ -480,7 +480,7 @@ func (c *compilerContext) getInvokeFunction(instr *ssa.CallCommon) llvm.Value { - // value, dereferences or unpacks it if necessary, and calls the real method. - // If the method to wrap has a pointer receiver, no wrapping is necessary and - // the function is returned directly. --func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFn llvm.Value) llvm.Value { -+func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFnType llvm.Type, llvmFn llvm.Value) llvm.Value { - wrapperName := llvmFn.Name() + "$invoke" - wrapper := c.mod.NamedFunction(wrapperName) - if !wrapper.IsNil() { -@@ -505,9 +505,8 @@ func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFn llv - } - - // create wrapper function -- fnType := llvmFn.Type().ElementType() -- paramTypes := append([]llvm.Type{c.i8ptrType}, fnType.ParamTypes()[len(expandedReceiverType):]...) -- wrapFnType := llvm.FunctionType(fnType.ReturnType(), paramTypes, false) -+ paramTypes := append([]llvm.Type{c.i8ptrType}, llvmFnType.ParamTypes()[len(expandedReceiverType):]...) -+ wrapFnType := llvm.FunctionType(llvmFnType.ReturnType(), paramTypes, false) - wrapper = llvm.AddFunction(c.mod, wrapperName, wrapFnType) - c.addStandardAttributes(wrapper) - -@@ -535,10 +534,10 @@ func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFn llv - receiverValue := b.emitPointerUnpack(wrapper.Param(0), []llvm.Type{receiverType})[0] - params := append(b.expandFormalParam(receiverValue), wrapper.Params()[1:]...) - if llvmFn.Type().ElementType().ReturnType().TypeKind() == llvm.VoidTypeKind { -- b.CreateCall(llvmFn, params, "") -+ b.CreateCall(llvmFnType, llvmFn, params, "") - b.CreateRetVoid() - } else { -- ret := b.CreateCall(llvmFn, params, "ret") -+ ret := b.CreateCall(llvmFnType, llvmFn, params, "ret") - b.CreateRet(ret) - } - -diff --git a/compiler/interrupt.go b/compiler/interrupt.go -index bcd407cd..45c7d074 100644 ---- a/compiler/interrupt.go -+++ b/compiler/interrupt.go -@@ -36,7 +36,7 @@ func (b *builder) createInterruptGlobal(instr *ssa.CallCommon) (llvm.Value, erro - // Fall back to a generic error. - return llvm.Value{}, b.makeError(instr.Pos(), "interrupt function must be constant") - } -- funcRawPtr, funcContext := b.decodeFuncValue(funcValue, nil) -+ _, funcRawPtr, funcContext := b.decodeFuncValue(funcValue, nil) - funcPtr := llvm.ConstPtrToInt(funcRawPtr, b.uintptrType) - - // Create a new global of type runtime/interrupt.handle. Globals of this -@@ -85,7 +85,7 @@ func (b *builder) createInterruptGlobal(instr *ssa.CallCommon) (llvm.Value, erro - useFnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{interrupt.Type()}, false) - useFn = llvm.AddFunction(b.mod, "runtime/interrupt.use", useFnType) - } -- b.CreateCall(useFn, []llvm.Value{interrupt}, "") -+ b.CreateCall(useFn.GlobalValueType(), useFn, []llvm.Value{interrupt}, "") - } - - return interrupt, nil -diff --git a/compiler/intrinsics.go b/compiler/intrinsics.go -index 0203d441..9fedfbd6 100644 ---- a/compiler/intrinsics.go -+++ b/compiler/intrinsics.go -@@ -55,7 +55,7 @@ func (b *builder) createMemoryCopyImpl() { - params = append(params, b.getValue(param)) - } - params = append(params, llvm.ConstInt(b.ctx.Int1Type(), 0, false)) -- b.CreateCall(llvmFn, params, "") -+ b.CreateCall(llvmFn.GlobalValueType(), llvmFn, params, "") - b.CreateRetVoid() - } - -@@ -76,7 +76,7 @@ func (b *builder) createMemoryZeroImpl() { - b.getValue(b.fn.Params[1]), - llvm.ConstInt(b.ctx.Int1Type(), 0, false), - } -- b.CreateCall(llvmFn, params, "") -+ b.CreateCall(llvmFn.GlobalValueType(), llvmFn, params, "") - b.CreateRetVoid() - } - -@@ -119,6 +119,6 @@ func (b *builder) defineMathOp() { - for i, param := range b.fn.Params { - args[i] = b.getValue(param) - } -- result := b.CreateCall(llvmFn, args, "") -+ result := b.CreateCall(llvmFn.GlobalValueType(), llvmFn, args, "") - b.CreateRet(result) - } -diff --git a/compiler/llvm.go b/compiler/llvm.go -index 0d2ba9da..9540bcc6 100644 ---- a/compiler/llvm.go -+++ b/compiler/llvm.go -@@ -312,5 +312,5 @@ func (b *builder) readStackPointer() llvm.Value { - fnType := llvm.FunctionType(b.i8ptrType, nil, false) - stacksave = llvm.AddFunction(b.mod, "llvm.stacksave", fnType) - } -- return b.CreateCall(stacksave, nil, "") -+ return b.CreateCall(stacksave.GlobalValueType(), stacksave, nil, "") - } -diff --git a/compiler/llvmutil/llvm.go b/compiler/llvmutil/llvm.go -index 74404a3e..e73b68da 100644 ---- a/compiler/llvmutil/llvm.go -+++ b/compiler/llvmutil/llvm.go -@@ -39,7 +39,8 @@ func CreateTemporaryAlloca(builder llvm.Builder, mod llvm.Module, t llvm.Type, n - alloca = CreateEntryBlockAlloca(builder, t, name) - bitcast = builder.CreateBitCast(alloca, i8ptrType, name+".bitcast") - size = llvm.ConstInt(ctx.Int64Type(), targetData.TypeAllocSize(t), false) -- builder.CreateCall(getLifetimeStartFunc(mod), []llvm.Value{size, bitcast}, "") -+ fnType, fn := getLifetimeStartFunc(mod) -+ builder.CreateCall(fnType, fn, []llvm.Value{size, bitcast}, "") - return - } - -@@ -54,13 +55,15 @@ func CreateInstructionAlloca(builder llvm.Builder, mod llvm.Module, t llvm.Type, - builder.SetInsertPointBefore(inst) - bitcast := builder.CreateBitCast(alloca, i8ptrType, name+".bitcast") - size := llvm.ConstInt(ctx.Int64Type(), targetData.TypeAllocSize(t), false) -- builder.CreateCall(getLifetimeStartFunc(mod), []llvm.Value{size, bitcast}, "") -+ fnType, fn := getLifetimeStartFunc(mod) -+ builder.CreateCall(fnType, fn, []llvm.Value{size, bitcast}, "") - if next := llvm.NextInstruction(inst); !next.IsNil() { - builder.SetInsertPointBefore(next) - } else { - builder.SetInsertPointAtEnd(inst.InstructionParent()) - } -- builder.CreateCall(getLifetimeEndFunc(mod), []llvm.Value{size, bitcast}, "") -+ fnType, fn = getLifetimeEndFunc(mod) -+ builder.CreateCall(fnType, fn, []llvm.Value{size, bitcast}, "") - return alloca - } - -@@ -68,33 +71,34 @@ func CreateInstructionAlloca(builder llvm.Builder, mod llvm.Module, t llvm.Type, - // llvm.lifetime.end intrinsic. It is commonly used together with - // createTemporaryAlloca. - func EmitLifetimeEnd(builder llvm.Builder, mod llvm.Module, ptr, size llvm.Value) { -- builder.CreateCall(getLifetimeEndFunc(mod), []llvm.Value{size, ptr}, "") -+ fnType, fn := getLifetimeEndFunc(mod) -+ builder.CreateCall(fnType, fn, []llvm.Value{size, ptr}, "") - } - - // getLifetimeStartFunc returns the llvm.lifetime.start intrinsic and creates it - // first if it doesn't exist yet. --func getLifetimeStartFunc(mod llvm.Module) llvm.Value { -+func getLifetimeStartFunc(mod llvm.Module) (llvm.Type, llvm.Value) { - fn := mod.NamedFunction("llvm.lifetime.start.p0i8") - ctx := mod.Context() - i8ptrType := llvm.PointerType(ctx.Int8Type(), 0) -+ fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false) - if fn.IsNil() { -- fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false) - fn = llvm.AddFunction(mod, "llvm.lifetime.start.p0i8", fnType) - } -- return fn -+ return fnType, fn - } - - // getLifetimeEndFunc returns the llvm.lifetime.end intrinsic and creates it - // first if it doesn't exist yet. --func getLifetimeEndFunc(mod llvm.Module) llvm.Value { -+func getLifetimeEndFunc(mod llvm.Module) (llvm.Type, llvm.Value) { - fn := mod.NamedFunction("llvm.lifetime.end.p0i8") - ctx := mod.Context() - i8ptrType := llvm.PointerType(ctx.Int8Type(), 0) -+ fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false) - if fn.IsNil() { -- fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false) - fn = llvm.AddFunction(mod, "llvm.lifetime.end.p0i8", fnType) - } -- return fn -+ return fnType, fn - } - - // SplitBasicBlock splits a LLVM basic block into two parts. All instructions -diff --git a/compiler/llvmutil/wordpack.go b/compiler/llvmutil/wordpack.go -index 41d4c581..73b1e27e 100644 ---- a/compiler/llvmutil/wordpack.go -+++ b/compiler/llvmutil/wordpack.go -@@ -95,14 +95,14 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, prefix string, needs - // Packed data is bigger than a pointer, so allocate it on the heap. - sizeValue := llvm.ConstInt(uintptrType, size, false) - alloc := mod.NamedFunction("runtime.alloc") -- packedHeapAlloc := builder.CreateCall(alloc, []llvm.Value{ -+ packedHeapAlloc := builder.CreateCall(alloc.GlobalValueType(), alloc, []llvm.Value{ - sizeValue, - llvm.ConstNull(i8ptrType), - llvm.Undef(i8ptrType), // unused context parameter - }, "") - if needsStackObjects { - trackPointer := mod.NamedFunction("runtime.trackPointer") -- builder.CreateCall(trackPointer, []llvm.Value{ -+ builder.CreateCall(trackPointer.GlobalValueType(), trackPointer, []llvm.Value{ - packedHeapAlloc, - llvm.Undef(i8ptrType), // unused context parameter - }, "") -diff --git a/compiler/symbol.go b/compiler/symbol.go -index c4ce6f21..83fe050b 100644 ---- a/compiler/symbol.go -+++ b/compiler/symbol.go -@@ -53,11 +53,11 @@ const ( - - // getFunction returns the LLVM function for the given *ssa.Function, creating - // it if needed. It can later be filled with compilerContext.createFunction(). --func (c *compilerContext) getFunction(fn *ssa.Function) llvm.Value { -+func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value) { - info := c.getFunctionInfo(fn) - llvmFn := c.mod.NamedFunction(info.linkName) - if !llvmFn.IsNil() { -- return llvmFn -+ return llvmFn.GlobalValueType(), llvmFn - } - - var retType llvm.Type -@@ -202,7 +202,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) llvm.Value { - llvmFn.SetUnnamedAddr(true) - } - -- return llvmFn -+ return fnType, llvmFn - } - - // getFunctionInfo returns information about a function that is not directly -diff --git a/compiler/syscall.go b/compiler/syscall.go -index 0c5f1246..66baf826 100644 ---- a/compiler/syscall.go -+++ b/compiler/syscall.go -@@ -44,7 +44,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { - constraints += ",~{rcx},~{r11}" - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) - target := llvm.InlineAsm(fnType, "syscall", constraints, true, false, llvm.InlineAsmDialectIntel, false) -- return b.CreateCall(target, args, ""), nil -+ return b.CreateCall(fnType, target, args, ""), nil - case b.GOARCH == "386" && b.GOOS == "linux": - // Sources: - // syscall(2) man page -@@ -70,7 +70,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { - } - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) - target := llvm.InlineAsm(fnType, "int 0x80", constraints, true, false, llvm.InlineAsmDialectIntel, false) -- return b.CreateCall(target, args, ""), nil -+ return b.CreateCall(fnType, target, args, ""), nil - case b.GOARCH == "arm" && b.GOOS == "linux": - // Implement the EABI system call convention for Linux. - // Source: syscall(2) man page. -@@ -102,7 +102,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { - } - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) - target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0, false) -- return b.CreateCall(target, args, ""), nil -+ return b.CreateCall(fnType, target, args, ""), nil - case b.GOARCH == "arm64" && b.GOOS == "linux": - // Source: syscall(2) man page. - args := []llvm.Value{} -@@ -134,7 +134,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { - constraints += ",~{x16},~{x17}" // scratch registers - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) - target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0, false) -- return b.CreateCall(target, args, ""), nil -+ return b.CreateCall(fnType, target, args, ""), nil - default: - return llvm.Value{}, b.makeError(call.Pos(), "unknown GOOS/GOARCH for syscall: "+b.GOOS+"/"+b.GOARCH) - } -@@ -205,9 +205,9 @@ func (b *builder) createSyscall(call *ssa.CallCommon) (llvm.Value, error) { - // Note that SetLastError/GetLastError could be replaced with direct - // access to the thread control block, which is probably smaller and - // faster. The Go runtime does this in assembly. -- b.CreateCall(setLastError, []llvm.Value{llvm.ConstNull(b.ctx.Int32Type())}, "") -- syscallResult := b.CreateCall(fnPtr, params, "") -- errResult := b.CreateCall(getLastError, nil, "err") -+ b.CreateCall(setLastError.GlobalValueType(), setLastError, []llvm.Value{llvm.ConstNull(b.ctx.Int32Type())}, "") -+ syscallResult := b.CreateCall(llvmType, fnPtr, params, "") -+ errResult := b.CreateCall(getLastError.GlobalValueType(), getLastError, nil, "err") - if b.uintptrType != b.ctx.Int32Type() { - errResult = b.CreateZExt(errResult, b.uintptrType, "err.uintptr") - } -diff --git a/go.mod b/go.mod -index fdf686d4..4af10427 100644 ---- a/go.mod -+++ b/go.mod -@@ -17,7 +17,7 @@ require ( - golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 - golang.org/x/tools v0.1.11 - gopkg.in/yaml.v2 v2.4.0 -- tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7 -+ tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636 - ) - - require ( -diff --git a/go.sum b/go.sum -index 3fc9cac1..401de3be 100644 ---- a/go.sum -+++ b/go.sum -@@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 - gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= - gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= --tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7 h1:nSLR52mUw7DPQQVA3ZJFH63zjU4ME84fKiin6mdnYWc= --tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= -+tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636 h1:JxtI6P/lyWHAcs/4QJWeWIbh4HntxPFONMVWvx7wf8Y= -+tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= -diff --git a/interp/interp.go b/interp/interp.go -index a1f5f507..856f08b1 100644 ---- a/interp/interp.go -+++ b/interp/interp.go -@@ -127,7 +127,7 @@ func Run(mod llvm.Module, timeout time.Duration, debug bool) error { - // Create a call to the package initializer (which was - // previously deleted). - i8undef := llvm.Undef(r.i8ptrType) -- r.builder.CreateCall(fn, []llvm.Value{i8undef}, "") -+ r.builder.CreateCall(fn.GlobalValueType(), fn, []llvm.Value{i8undef}, "") - // Make sure that any globals touched by the package - // initializer, won't be accessed by later package initializers. - err := r.markExternalLoad(fn) -diff --git a/interp/interpreter.go b/interp/interpreter.go -index 7cee14bf..4a4553f8 100644 ---- a/interp/interpreter.go -+++ b/interp/interpreter.go -@@ -977,7 +977,7 @@ func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, me - } - } - } -- result = r.builder.CreateCall(llvmFn, args, inst.name) -+ result = r.builder.CreateCall(inst.llvmInst.CalledFunctionType(), llvmFn, args, inst.name) - case llvm.Load: - err := mem.markExternalLoad(operands[0]) - if err != nil { -diff --git a/transform/interface-lowering.go b/transform/interface-lowering.go -index 7a01c2ea..f5b29e30 100644 ---- a/transform/interface-lowering.go -+++ b/transform/interface-lowering.go -@@ -493,12 +493,13 @@ func (p *lowerInterfacesPass) defineInterfaceMethodFunc(fn llvm.Value, itf *inte - paramTypes = append(paramTypes, param.Type()) - } - calledFunctionType := function.Type() -- sig := llvm.PointerType(llvm.FunctionType(returnType, paramTypes, false), calledFunctionType.PointerAddressSpace()) -+ functionType := llvm.FunctionType(returnType, paramTypes, false) -+ sig := llvm.PointerType(functionType, calledFunctionType.PointerAddressSpace()) - if sig != function.Type() { - function = p.builder.CreateBitCast(function, sig, "") - } - -- retval := p.builder.CreateCall(function, append([]llvm.Value{receiver}, params...), "") -+ retval := p.builder.CreateCall(functionType, function, append([]llvm.Value{receiver}, params...), "") - if retval.Type().TypeKind() == llvm.VoidTypeKind { - p.builder.CreateRetVoid() - } else { -@@ -518,7 +519,7 @@ func (p *lowerInterfacesPass) defineInterfaceMethodFunc(fn llvm.Value, itf *inte - // importantly, it avoids undefined behavior when accidentally calling a - // method on a nil interface. - nilPanic := p.mod.NamedFunction("runtime.nilPanic") -- p.builder.CreateCall(nilPanic, []llvm.Value{ -+ p.builder.CreateCall(nilPanic.GlobalValueType(), nilPanic, []llvm.Value{ - llvm.Undef(llvm.PointerType(p.ctx.Int8Type(), 0)), - }, "") - p.builder.CreateUnreachable() -diff --git a/transform/interrupt.go b/transform/interrupt.go -index 3ffe7048..2c301be0 100644 ---- a/transform/interrupt.go -+++ b/transform/interrupt.go -@@ -91,7 +91,7 @@ func LowerInterrupts(mod llvm.Module) []error { - initializer := handler.Initializer() - context := llvm.ConstExtractValue(initializer, []uint32{0}) - funcPtr := llvm.ConstExtractValue(initializer, []uint32{1}).Operand(0) -- builder.CreateCall(funcPtr, []llvm.Value{ -+ builder.CreateCall(funcPtr.GlobalValueType(), funcPtr, []llvm.Value{ - num, - context, - }, "") -diff --git a/transform/panic.go b/transform/panic.go -index e8e9a1fe..dee3bae0 100644 ---- a/transform/panic.go -+++ b/transform/panic.go -@@ -27,7 +27,7 @@ func ReplacePanicsWithTrap(mod llvm.Module) { - panic("expected use of a panic function to be a call") - } - builder.SetInsertPointBefore(use) -- builder.CreateCall(trap, nil, "") -+ builder.CreateCall(trap.GlobalValueType(), trap, nil, "") - } - } - } -diff --git a/transform/rtcalls.go b/transform/rtcalls.go -index 2edfd655..2f17f815 100644 ---- a/transform/rtcalls.go -+++ b/transform/rtcalls.go -@@ -165,7 +165,7 @@ func OptimizeReflectImplements(mod llvm.Module) { - - // Replace Implements call with the type assert call. - builder.SetInsertPointBefore(call) -- implements := builder.CreateCall(typeAssertFunction, []llvm.Value{ -+ implements := builder.CreateCall(typeAssertFunction.GlobalValueType(), typeAssertFunction, []llvm.Value{ - builder.CreatePtrToInt(call.Operand(0), uintptrType, ""), // typecode to check - }, "") - call.ReplaceAllUsesWith(implements) -diff --git a/transform/wasm-abi.go b/transform/wasm-abi.go -index aeba713d..aedad71d 100644 ---- a/transform/wasm-abi.go -+++ b/transform/wasm-abi.go -@@ -124,12 +124,12 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error { - // Pass a stack-allocated pointer as the first parameter - // where the return value should be stored, instead of using - // the regular return value. -- builder.CreateCall(externalFn, callParams, callName) -+ builder.CreateCall(externalFnType, externalFn, callParams, callName) - returnValue := builder.CreateLoad(retvalAlloca, "retval") - call.ReplaceAllUsesWith(returnValue) - call.EraseFromParentAsInstruction() - } else { -- newCall := builder.CreateCall(externalFn, callParams, callName) -+ newCall := builder.CreateCall(externalFnType, externalFn, callParams, callName) - call.ReplaceAllUsesWith(newCall) - call.EraseFromParentAsInstruction() - } -@@ -156,7 +156,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error { - } - callParams = append(callParams, paramValue) - } -- retval := builder.CreateCall(fn, callParams, "") -+ retval := builder.CreateCall(fn.GlobalValueType(), fn, callParams, "") - if retval.Type().TypeKind() == llvm.VoidTypeKind { - builder.CreateRetVoid() - } else { --- -2.36.1 - diff --git a/0010-all-add-type-parameter-to-CreateLoad.patch b/0010-all-add-type-parameter-to-CreateLoad.patch deleted file mode 100644 index 2cbfe1b..0000000 --- a/0010-all-add-type-parameter-to-CreateLoad.patch +++ /dev/null @@ -1,377 +0,0 @@ -From 65a18179d8ff911ba43a3a28ffb2f36c262cff5e Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Wed, 21 Sep 2022 13:55:32 +0200 -Subject: [PATCH 10/18] all: add type parameter to CreateLoad - -This is needed for LLVM 15. - -Signed-off-by: Elliott Sales de Andrade ---- - compiler/atomic.go | 2 +- - compiler/channel.go | 8 ++++---- - compiler/compiler.go | 13 +++++++------ - compiler/defer.go | 19 +++++++++++-------- - compiler/llvmutil/wordpack.go | 4 ++-- - compiler/map.go | 6 +++--- - compiler/volatile.go | 5 ++++- - go.mod | 2 +- - go.sum | 4 ++-- - interp/interpreter.go | 2 +- - transform/gc.go | 2 +- - transform/stacksize.go | 13 +++++++++---- - transform/wasm-abi.go | 4 ++-- - 13 files changed, 48 insertions(+), 36 deletions(-) - -diff --git a/compiler/atomic.go b/compiler/atomic.go -index 6ba3849c..73761be4 100644 ---- a/compiler/atomic.go -+++ b/compiler/atomic.go -@@ -56,7 +56,7 @@ func (b *builder) createAtomicOp(name string) llvm.Value { - return swapped - case "LoadInt32", "LoadInt64", "LoadUint32", "LoadUint64", "LoadUintptr", "LoadPointer": - ptr := b.getValue(b.fn.Params[0]) -- val := b.CreateLoad(ptr, "") -+ val := b.CreateLoad(b.getLLVMType(b.fn.Signature.Results().At(0).Type()), ptr, "") - val.SetOrdering(llvm.AtomicOrderingSequentiallyConsistent) - val.SetAlignment(b.targetData.PrefTypeAlignment(val.Type())) // required - return val -diff --git a/compiler/channel.go b/compiler/channel.go -index a9886e10..5c3b6c59 100644 ---- a/compiler/channel.go -+++ b/compiler/channel.go -@@ -84,7 +84,7 @@ func (b *builder) createChanRecv(unop *ssa.UnOp) llvm.Value { - if isZeroSize { - received = llvm.ConstNull(valueType) - } else { -- received = b.CreateLoad(valueAlloca, "chan.received") -+ received = b.CreateLoad(valueType, valueAlloca, "chan.received") - b.emitLifetimeEnd(valueAllocaCast, valueAllocaSize) - } - b.emitLifetimeEnd(channelBlockedListAllocaCast, channelBlockedListAllocaSize) -@@ -264,8 +264,8 @@ func (b *builder) getChanSelectResult(expr *ssa.Extract) llvm.Value { - // receive can proceed at a time) so we'll get that alloca, bitcast - // it to the correct type, and dereference it. - recvbuf := b.selectRecvBuf[expr.Tuple.(*ssa.Select)] -- typ := llvm.PointerType(b.getLLVMType(expr.Type()), 0) -- ptr := b.CreateBitCast(recvbuf, typ, "") -- return b.CreateLoad(ptr, "") -+ typ := b.getLLVMType(expr.Type()) -+ ptr := b.CreateBitCast(recvbuf, llvm.PointerType(typ, 0), "") -+ return b.CreateLoad(typ, ptr, "") - } - } -diff --git a/compiler/compiler.go b/compiler/compiler.go -index b64fddcc..7ab2fe4e 100644 ---- a/compiler/compiler.go -+++ b/compiler/compiler.go -@@ -1931,11 +1931,12 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - - // Can't load directly from array (as index is non-constant), so have to - // do it using an alloca+gep+load. -- alloca, allocaPtr, allocaSize := b.createTemporaryAlloca(array.Type(), "index.alloca") -+ arrayType := array.Type() -+ alloca, allocaPtr, allocaSize := b.createTemporaryAlloca(arrayType, "index.alloca") - b.CreateStore(array, alloca) - zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) - ptr := b.CreateInBoundsGEP(alloca, []llvm.Value{zero, index}, "index.gep") -- result := b.CreateLoad(ptr, "index.load") -+ result := b.CreateLoad(arrayType.ElementType(), ptr, "index.load") - b.emitLifetimeEnd(allocaPtr, allocaSize) - return result, nil - case *ssa.IndexAddr: -@@ -2012,7 +2013,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - // Lookup byte - buf := b.CreateExtractValue(value, 0, "") - bufPtr := b.CreateInBoundsGEP(buf, []llvm.Value{index}, "") -- return b.CreateLoad(bufPtr, ""), nil -+ return b.CreateLoad(b.ctx.Int8Type(), bufPtr, ""), nil - case *types.Map: - valueType := expr.Type() - if expr.CommaOk { -@@ -3076,10 +3077,10 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) { - return llvm.Value{}, b.makeError(unop.Pos(), "todo: unknown type for negate: "+unop.X.Type().Underlying().String()) - } - case token.MUL: // *x, dereference pointer -- unop.X.Type().Underlying().(*types.Pointer).Elem() -+ valueType := b.getLLVMType(unop.X.Type().Underlying().(*types.Pointer).Elem()) - if b.targetData.TypeAllocSize(x.Type().ElementType()) == 0 { - // zero-length data -- return llvm.ConstNull(x.Type().ElementType()), nil -+ return llvm.ConstNull(valueType), nil - } else if strings.HasSuffix(unop.X.String(), "$funcaddr") { - // CGo function pointer. The cgo part has rewritten CGo function - // pointers as stub global variables of the form: -@@ -3094,7 +3095,7 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) { - return b.CreateBitCast(fn, b.i8ptrType, ""), nil - } else { - b.createNilCheck(unop.X, x, "deref") -- load := b.CreateLoad(x, "") -+ load := b.CreateLoad(valueType, x, "") - return load, nil - } - case token.XOR: // ^x, toggle all bits in integer -diff --git a/compiler/defer.go b/compiler/defer.go -index e82370fa..1f892e5b 100644 ---- a/compiler/defer.go -+++ b/compiler/defer.go -@@ -249,7 +249,8 @@ func isInLoop(start *ssa.BasicBlock) bool { - func (b *builder) createDefer(instr *ssa.Defer) { - // The pointer to the previous defer struct, which we will replace to - // make a linked list. -- next := b.CreateLoad(b.deferPtr, "defer.next") -+ deferType := llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0) -+ next := b.CreateLoad(deferType, b.deferPtr, "defer.next") - - var values []llvm.Value - valueTypes := []llvm.Type{b.uintptrType, next.Type()} -@@ -406,6 +407,8 @@ func (b *builder) createDefer(instr *ssa.Defer) { - - // createRunDefers emits code to run all deferred functions. - func (b *builder) createRunDefers() { -+ deferType := llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0) -+ - // Add a loop like the following: - // for stack != nil { - // _stack := stack -@@ -431,7 +434,7 @@ func (b *builder) createRunDefers() { - // Create loop head: - // for stack != nil { - b.SetInsertPointAtEnd(loophead) -- deferData := b.CreateLoad(b.deferPtr, "") -+ deferData := b.CreateLoad(deferType, b.deferPtr, "") - stackIsNil := b.CreateICmp(llvm.IntEQ, deferData, llvm.ConstPointerNull(deferData.Type()), "stackIsNil") - b.CreateCondBr(stackIsNil, end, loop) - -@@ -444,13 +447,13 @@ func (b *builder) createRunDefers() { - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - llvm.ConstInt(b.ctx.Int32Type(), 1, false), // .next field - }, "stack.next.gep") -- nextStack := b.CreateLoad(nextStackGEP, "stack.next") -+ nextStack := b.CreateLoad(deferType, nextStackGEP, "stack.next") - b.CreateStore(nextStack, b.deferPtr) - gep := b.CreateInBoundsGEP(deferData, []llvm.Value{ - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - llvm.ConstInt(b.ctx.Int32Type(), 0, false), // .callback field - }, "callback.gep") -- callback := b.CreateLoad(gep, "callback") -+ callback := b.CreateLoad(b.uintptrType, gep, "callback") - sw := b.CreateSwitch(callback, unreachable, len(b.allDeferFuncs)) - - for i, callback := range b.allDeferFuncs { -@@ -487,7 +490,7 @@ func (b *builder) createRunDefers() { - zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) - for i := 2; i < len(valueTypes); i++ { - gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "gep") -- forwardParam := b.CreateLoad(gep, "param") -+ forwardParam := b.CreateLoad(valueTypes[i], gep, "param") - forwardParams = append(forwardParams, forwardParam) - } - -@@ -536,7 +539,7 @@ func (b *builder) createRunDefers() { - zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) - for i := range getParams(callback.Signature) { - gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep") -- forwardParam := b.CreateLoad(gep, "param") -+ forwardParam := b.CreateLoad(valueTypes[i+2], gep, "param") - forwardParams = append(forwardParams, forwardParam) - } - -@@ -569,7 +572,7 @@ func (b *builder) createRunDefers() { - zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) - for i := 2; i < len(valueTypes); i++ { - gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "") -- forwardParam := b.CreateLoad(gep, "param") -+ forwardParam := b.CreateLoad(valueTypes[i], gep, "param") - forwardParams = append(forwardParams, forwardParam) - } - -@@ -596,7 +599,7 @@ func (b *builder) createRunDefers() { - zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) - for i := 0; i < params.Len(); i++ { - gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep") -- forwardParam := b.CreateLoad(gep, "param") -+ forwardParam := b.CreateLoad(valueTypes[i+2], gep, "param") - argValues = append(argValues, forwardParam) - } - -diff --git a/compiler/llvmutil/wordpack.go b/compiler/llvmutil/wordpack.go -index 73b1e27e..97b86045 100644 ---- a/compiler/llvmutil/wordpack.go -+++ b/compiler/llvmutil/wordpack.go -@@ -63,7 +63,7 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, prefix string, needs - } - - // Load value (the *i8) from the alloca. -- result := builder.CreateLoad(packedAlloc, "") -+ result := builder.CreateLoad(i8ptrType, packedAlloc, "") - - // End the lifetime of the alloca, to help the optimizer. - packedPtr := builder.CreateBitCast(packedAlloc, i8ptrType, "") -@@ -171,7 +171,7 @@ func EmitPointerUnpack(builder llvm.Builder, mod llvm.Module, ptr llvm.Value, va - llvm.ConstInt(ctx.Int32Type(), uint64(i), false), - } - gep := builder.CreateInBoundsGEP(packedAlloc, indices, "") -- values[i] = builder.CreateLoad(gep, "") -+ values[i] = builder.CreateLoad(valueType, gep, "") - } - if !packedRawAlloc.IsNil() { - allocPtr := builder.CreateBitCast(packedRawAlloc, i8ptrType, "") -diff --git a/compiler/map.go b/compiler/map.go -index 57a7033a..7655ec70 100644 ---- a/compiler/map.go -+++ b/compiler/map.go -@@ -106,7 +106,7 @@ func (b *builder) createMapLookup(keyType, valueType types.Type, m, key llvm.Val - - // Load the resulting value from the hashmap. The value is set to the zero - // value if the key doesn't exist in the hashmap. -- mapValue := b.CreateLoad(mapValueAlloca, "") -+ mapValue := b.CreateLoad(llvmValueType, mapValueAlloca, "") - b.emitLifetimeEnd(mapValuePtr, mapValueAllocaSize) - - if commaOk { -@@ -217,8 +217,8 @@ func (b *builder) createMapIteratorNext(rangeVal ssa.Value, llvmRangeVal, it llv - mapKeyAlloca, mapKeyPtr, mapKeySize := b.createTemporaryAlloca(llvmStoredKeyType, "range.key") - mapValueAlloca, mapValuePtr, mapValueSize := b.createTemporaryAlloca(llvmValueType, "range.value") - ok := b.createRuntimeCall("hashmapNext", []llvm.Value{llvmRangeVal, it, mapKeyPtr, mapValuePtr}, "range.next") -- mapKey := b.CreateLoad(mapKeyAlloca, "") -- mapValue := b.CreateLoad(mapValueAlloca, "") -+ mapKey := b.CreateLoad(llvmStoredKeyType, mapKeyAlloca, "") -+ mapValue := b.CreateLoad(llvmValueType, mapValueAlloca, "") - - if isKeyStoredAsInterface { - // The key is stored as an interface but it isn't of interface type. -diff --git a/compiler/volatile.go b/compiler/volatile.go -index 143eff28..3d3a67fa 100644 ---- a/compiler/volatile.go -+++ b/compiler/volatile.go -@@ -1,5 +1,7 @@ - package compiler - -+import "go/types" -+ - // This file implements volatile loads/stores in runtime/volatile.LoadT and - // runtime/volatile.StoreT as compiler builtins. - -@@ -9,7 +11,8 @@ func (b *builder) createVolatileLoad() { - b.createFunctionStart(true) - addr := b.getValue(b.fn.Params[0]) - b.createNilCheck(b.fn.Params[0], addr, "deref") -- val := b.CreateLoad(addr, "") -+ valType := b.getLLVMType(b.fn.Params[0].Type().(*types.Pointer).Elem()) -+ val := b.CreateLoad(valType, addr, "") - val.SetVolatile(true) - b.CreateRet(val) - } -diff --git a/go.mod b/go.mod -index 4af10427..26707a96 100644 ---- a/go.mod -+++ b/go.mod -@@ -17,7 +17,7 @@ require ( - golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 - golang.org/x/tools v0.1.11 - gopkg.in/yaml.v2 v2.4.0 -- tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636 -+ tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6 - ) - - require ( -diff --git a/go.sum b/go.sum -index 401de3be..e5c734cd 100644 ---- a/go.sum -+++ b/go.sum -@@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 - gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= - gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= --tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636 h1:JxtI6P/lyWHAcs/4QJWeWIbh4HntxPFONMVWvx7wf8Y= --tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= -+tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6 h1:bJYUpmJrVm7Uluxh80qSivfeU3d9D4JNg5oJ+h9U+xc= -+tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= -diff --git a/interp/interpreter.go b/interp/interpreter.go -index 4a4553f8..2c7fd8c3 100644 ---- a/interp/interpreter.go -+++ b/interp/interpreter.go -@@ -983,7 +983,7 @@ func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, me - if err != nil { - return r.errorAt(inst, err) - } -- result = r.builder.CreateLoad(operands[0], inst.name) -+ result = r.builder.CreateLoad(inst.llvmInst.Type(), operands[0], inst.name) - if inst.llvmInst.IsVolatile() { - result.SetVolatile(true) - } -diff --git a/transform/gc.go b/transform/gc.go -index 87dc6e88..7a4e99ac 100644 ---- a/transform/gc.go -+++ b/transform/gc.go -@@ -222,7 +222,7 @@ func MakeGCStackSlots(mod llvm.Module) bool { - builder.CreateStore(initialStackObject, stackObject) - - // Update stack start. -- parent := builder.CreateLoad(stackChainStart, "") -+ parent := builder.CreateLoad(stackChainStartType, stackChainStart, "") - gep := builder.CreateGEP(stackObject, []llvm.Value{ - llvm.ConstInt(ctx.Int32Type(), 0, false), - llvm.ConstInt(ctx.Int32Type(), 0, false), -diff --git a/transform/stacksize.go b/transform/stacksize.go -index 7be49238..f1a3c93d 100644 ---- a/transform/stacksize.go -+++ b/transform/stacksize.go -@@ -34,6 +34,11 @@ func CreateStackSizeLoads(mod llvm.Module, config *compileopts.Config) []string - return nil - } - -+ ctx := mod.Context() -+ targetData := llvm.NewTargetData(mod.DataLayout()) -+ defer targetData.Dispose() -+ uintptrType := ctx.IntType(targetData.PointerSize() * 8) -+ - // Create the new global with stack sizes, that will be put in a new section - // just for itself. - stackSizesGlobalType := llvm.ArrayType(functions[0].Type(), len(functions)) -@@ -50,16 +55,16 @@ func CreateStackSizeLoads(mod llvm.Module, config *compileopts.Config) []string - appendToUsedGlobals(mod, append([]llvm.Value{stackSizesGlobal}, functionValues...)...) - - // Replace the calls with loads from the new global with stack sizes. -- irbuilder := mod.Context().NewBuilder() -+ irbuilder := ctx.NewBuilder() - defer irbuilder.Dispose() - for i, function := range functions { - for _, use := range functionMap[function] { - ptr := llvm.ConstGEP(stackSizesGlobal, []llvm.Value{ -- llvm.ConstInt(mod.Context().Int32Type(), 0, false), -- llvm.ConstInt(mod.Context().Int32Type(), uint64(i), false), -+ llvm.ConstInt(ctx.Int32Type(), 0, false), -+ llvm.ConstInt(ctx.Int32Type(), uint64(i), false), - }) - irbuilder.SetInsertPointBefore(use) -- stacksize := irbuilder.CreateLoad(ptr, "stacksize") -+ stacksize := irbuilder.CreateLoad(uintptrType, ptr, "stacksize") - use.ReplaceAllUsesWith(stacksize) - use.EraseFromParentAsInstruction() - } -diff --git a/transform/wasm-abi.go b/transform/wasm-abi.go -index aedad71d..064e38f4 100644 ---- a/transform/wasm-abi.go -+++ b/transform/wasm-abi.go -@@ -125,7 +125,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error { - // where the return value should be stored, instead of using - // the regular return value. - builder.CreateCall(externalFnType, externalFn, callParams, callName) -- returnValue := builder.CreateLoad(retvalAlloca, "retval") -+ returnValue := builder.CreateLoad(int64Type, retvalAlloca, "retval") - call.ReplaceAllUsesWith(returnValue) - call.EraseFromParentAsInstruction() - } else { -@@ -152,7 +152,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error { - for i, origParam := range fn.Params() { - paramValue := externalFn.Param(i) - if origParam.Type() == int64Type { -- paramValue = builder.CreateLoad(paramValue, "i64") -+ paramValue = builder.CreateLoad(int64Type, paramValue, "i64") - } - callParams = append(callParams, paramValue) - } --- -2.36.1 - diff --git a/0011-all-add-type-parameter-to-GEP-calls.patch b/0011-all-add-type-parameter-to-GEP-calls.patch deleted file mode 100644 index 866f9fb..0000000 --- a/0011-all-add-type-parameter-to-GEP-calls.patch +++ /dev/null @@ -1,565 +0,0 @@ -From dd4f1c594ef0fadb59fa418f1049542f86237800 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Wed, 21 Sep 2022 17:00:09 +0200 -Subject: [PATCH 11/18] all: add type parameter to *GEP calls - -This is necessary for LLVM 15. - -Signed-off-by: Elliott Sales de Andrade ---- - builder/build.go | 2 +- - compiler/channel.go | 8 +++--- - compiler/compiler.go | 46 ++++++++++++++++++++--------------- - compiler/defer.go | 19 ++++++++------- - compiler/interface.go | 16 ++++++------ - compiler/llvm.go | 6 ++--- - compiler/llvmutil/wordpack.go | 6 ++--- - go.mod | 2 +- - go.sum | 4 +-- - interp/memory.go | 4 +-- - transform/gc.go | 4 +-- - transform/llvm.go | 10 ++++---- - transform/stacksize.go | 2 +- - 13 files changed, 69 insertions(+), 60 deletions(-) - -diff --git a/builder/build.go b/builder/build.go -index 28385044..7a7dd9ac 100644 ---- a/builder/build.go -+++ b/builder/build.go -@@ -1153,7 +1153,7 @@ func setGlobalValues(mod llvm.Module, globals map[string]map[string]string) erro - - // Create the string value, which is a {ptr, len} pair. - zero := llvm.ConstInt(mod.Context().Int32Type(), 0, false) -- ptr := llvm.ConstGEP(buf, []llvm.Value{zero, zero}) -+ ptr := llvm.ConstGEP(bufInitializer.Type(), buf, []llvm.Value{zero, zero}) - if ptr.Type() != elementTypes[0] { - return fmt.Errorf("%s: not a string", globalName) - } -diff --git a/compiler/channel.go b/compiler/channel.go -index 5c3b6c59..81f84565 100644 ---- a/compiler/channel.go -+++ b/compiler/channel.go -@@ -173,7 +173,7 @@ func (b *builder) createSelect(expr *ssa.Select) llvm.Value { - allocaType := llvm.ArrayType(b.ctx.Int8Type(), int(recvbufSize)) - recvbufAlloca, _, _ := b.createTemporaryAlloca(allocaType, "select.recvbuf.alloca") - recvbufAlloca.SetAlignment(recvbufAlign) -- recvbuf = b.CreateGEP(recvbufAlloca, []llvm.Value{ -+ recvbuf = b.CreateGEP(allocaType, recvbufAlloca, []llvm.Value{ - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - }, "select.recvbuf") -@@ -184,13 +184,13 @@ func (b *builder) createSelect(expr *ssa.Select) llvm.Value { - statesAlloca, statesI8, statesSize := b.createTemporaryAlloca(statesAllocaType, "select.states.alloca") - for i, state := range selectStates { - // Set each slice element to the appropriate channel. -- gep := b.CreateGEP(statesAlloca, []llvm.Value{ -+ gep := b.CreateGEP(statesAllocaType, statesAlloca, []llvm.Value{ - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false), - }, "") - b.CreateStore(state, gep) - } -- statesPtr := b.CreateGEP(statesAlloca, []llvm.Value{ -+ statesPtr := b.CreateGEP(statesAllocaType, statesAlloca, []llvm.Value{ - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - }, "select.states") -@@ -204,7 +204,7 @@ func (b *builder) createSelect(expr *ssa.Select) llvm.Value { - chBlockAllocaType := llvm.ArrayType(b.getLLVMRuntimeType("channelBlockedList"), len(selectStates)) - chBlockAlloca, chBlockAllocaPtr, chBlockSize := b.createTemporaryAlloca(chBlockAllocaType, "select.block.alloca") - chBlockLen := llvm.ConstInt(b.uintptrType, uint64(len(selectStates)), false) -- chBlockPtr := b.CreateGEP(chBlockAlloca, []llvm.Value{ -+ chBlockPtr := b.CreateGEP(chBlockAllocaType, chBlockAlloca, []llvm.Value{ - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - }, "select.block") -diff --git a/compiler/compiler.go b/compiler/compiler.go -index 7ab2fe4e..c93b2e56 100644 ---- a/compiler/compiler.go -+++ b/compiler/compiler.go -@@ -918,7 +918,7 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu - bufferGlobal.SetInitializer(bufferValue) - bufferGlobal.SetLinkage(llvm.InternalLinkage) - bufferGlobal.SetAlignment(1) -- slicePtr := llvm.ConstInBoundsGEP(bufferGlobal, []llvm.Value{ -+ slicePtr := llvm.ConstInBoundsGEP(bufferValue.Type(), bufferGlobal, []llvm.Value{ - llvm.ConstInt(c.uintptrType, 0, false), - llvm.ConstInt(c.uintptrType, 0, false), - }) -@@ -990,7 +990,7 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu - // Create the slice object itself. - // Because embed.FS refers to it as *[]embed.file instead of a plain - // []embed.file, we have to store this as a global. -- slicePtr := llvm.ConstInBoundsGEP(sliceDataGlobal, []llvm.Value{ -+ slicePtr := llvm.ConstInBoundsGEP(sliceDataInitializer.Type(), sliceDataGlobal, []llvm.Value{ - llvm.ConstInt(c.uintptrType, 0, false), - llvm.ConstInt(c.uintptrType, 0, false), - }) -@@ -1018,11 +1018,11 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu - func (c *compilerContext) getEmbedFileString(file *loader.EmbedFile) llvm.Value { - dataGlobalName := "embed/file_" + file.Hash - dataGlobal := c.mod.NamedGlobal(dataGlobalName) -+ dataGlobalType := llvm.ArrayType(c.ctx.Int8Type(), int(file.Size)) - if dataGlobal.IsNil() { -- dataGlobalType := llvm.ArrayType(c.ctx.Int8Type(), int(file.Size)) - dataGlobal = llvm.AddGlobal(c.mod, dataGlobalType, dataGlobalName) - } -- strPtr := llvm.ConstInBoundsGEP(dataGlobal, []llvm.Value{ -+ strPtr := llvm.ConstInBoundsGEP(dataGlobalType, dataGlobal, []llvm.Value{ - llvm.ConstInt(c.uintptrType, 0, false), - llvm.ConstInt(c.uintptrType, 0, false), - }) -@@ -1601,7 +1601,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c - // Note: the pointer is always of type *i8. - ptr := argValues[0] - len := argValues[1] -- return b.CreateGEP(ptr, []llvm.Value{len}, ""), nil -+ return b.CreateGEP(b.ctx.Int8Type(), ptr, []llvm.Value{len}, ""), nil - case "Alignof": // unsafe.Alignof - align := b.targetData.ABITypeAlignment(argValues[0].Type()) - return llvm.ConstInt(b.uintptrType, uint64(align), false), nil -@@ -1911,7 +1911,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - llvm.ConstInt(b.ctx.Int32Type(), uint64(expr.Field), false), - } -- return b.CreateInBoundsGEP(val, indices, ""), nil -+ elementType := b.getLLVMType(expr.X.Type().Underlying().(*types.Pointer).Elem()) -+ return b.CreateInBoundsGEP(elementType, val, indices, ""), nil - case *ssa.Function: - panic("function is not an expression") - case *ssa.Global: -@@ -1935,7 +1936,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - alloca, allocaPtr, allocaSize := b.createTemporaryAlloca(arrayType, "index.alloca") - b.CreateStore(array, alloca) - zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) -- ptr := b.CreateInBoundsGEP(alloca, []llvm.Value{zero, index}, "index.gep") -+ ptr := b.CreateInBoundsGEP(arrayType, alloca, []llvm.Value{zero, index}, "index.gep") - result := b.CreateLoad(arrayType.ElementType(), ptr, "index.load") - b.emitLifetimeEnd(allocaPtr, allocaSize) - return result, nil -@@ -1945,13 +1946,15 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - - // Get buffer pointer and length - var bufptr, buflen llvm.Value -+ var bufType llvm.Type - switch ptrTyp := expr.X.Type().Underlying().(type) { - case *types.Pointer: -- typ := expr.X.Type().Underlying().(*types.Pointer).Elem().Underlying() -+ typ := ptrTyp.Elem().Underlying() - switch typ := typ.(type) { - case *types.Array: - bufptr = val - buflen = llvm.ConstInt(b.uintptrType, uint64(typ.Len()), false) -+ bufType = b.getLLVMType(typ) - // Check for nil pointer before calculating the address, from - // the spec: - // > For an operand x of type T, the address operation &x -@@ -1965,6 +1968,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - case *types.Slice: - bufptr = b.CreateExtractValue(val, 0, "indexaddr.ptr") - buflen = b.CreateExtractValue(val, 1, "indexaddr.len") -+ bufType = b.getLLVMType(ptrTyp.Elem()) - default: - return llvm.Value{}, b.makeError(expr.Pos(), "todo: indexaddr: "+ptrTyp.String()) - } -@@ -1982,9 +1986,9 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - index, - } -- return b.CreateInBoundsGEP(bufptr, indices, ""), nil -+ return b.CreateInBoundsGEP(bufType, bufptr, indices, ""), nil - case *types.Slice: -- return b.CreateInBoundsGEP(bufptr, []llvm.Value{index}, ""), nil -+ return b.CreateInBoundsGEP(bufType, bufptr, []llvm.Value{index}, ""), nil - default: - panic("unreachable") - } -@@ -2012,8 +2016,9 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - - // Lookup byte - buf := b.CreateExtractValue(value, 0, "") -- bufPtr := b.CreateInBoundsGEP(buf, []llvm.Value{index}, "") -- return b.CreateLoad(b.ctx.Int8Type(), bufPtr, ""), nil -+ bufElemType := b.ctx.Int8Type() -+ bufPtr := b.CreateInBoundsGEP(bufElemType, buf, []llvm.Value{index}, "") -+ return b.CreateLoad(bufElemType, bufPtr, ""), nil - case *types.Map: - valueType := expr.Type() - if expr.CommaOk { -@@ -2146,7 +2151,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - switch typ := expr.X.Type().Underlying().(type) { - case *types.Pointer: // pointer to array - // slice an array -- length := typ.Elem().Underlying().(*types.Array).Len() -+ arrayType := typ.Elem().Underlying().(*types.Array) -+ length := arrayType.Len() - llvmLen := llvm.ConstInt(b.uintptrType, uint64(length), false) - if high.IsNil() { - high = llvmLen -@@ -2175,7 +2181,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - } - - sliceLen := b.CreateSub(high, low, "slice.len") -- slicePtr := b.CreateInBoundsGEP(value, indices, "slice.ptr") -+ slicePtr := b.CreateInBoundsGEP(b.getLLVMType(arrayType), value, indices, "slice.ptr") - sliceCap := b.CreateSub(max, low, "slice.cap") - - slice := b.ctx.ConstStruct([]llvm.Value{ -@@ -2214,7 +2220,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - max = b.CreateTrunc(max, b.uintptrType, "") - } - -- newPtr := b.CreateInBoundsGEP(oldPtr, []llvm.Value{low}, "") -+ ptrElemType := b.getLLVMType(typ.Elem()) -+ newPtr := b.CreateInBoundsGEP(ptrElemType, oldPtr, []llvm.Value{low}, "") - newLen := b.CreateSub(high, low, "") - newCap := b.CreateSub(max, low, "") - slice := b.ctx.ConstStruct([]llvm.Value{ -@@ -2254,7 +2261,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { - high = b.CreateTrunc(high, b.uintptrType, "") - } - -- newPtr := b.CreateInBoundsGEP(oldPtr, []llvm.Value{low}, "") -+ newPtr := b.CreateInBoundsGEP(b.ctx.Int8Type(), oldPtr, []llvm.Value{low}, "") - newLen := b.CreateSub(high, low, "") - str := llvm.Undef(b.getLLVMRuntimeType("_string")) - str = b.CreateInsertValue(str, newPtr, 0, "") -@@ -2717,14 +2724,15 @@ func (c *compilerContext) createConst(expr *ssa.Const) llvm.Value { - var strPtr llvm.Value - if str != "" { - objname := c.pkg.Path() + "$string" -- global := llvm.AddGlobal(c.mod, llvm.ArrayType(c.ctx.Int8Type(), len(str)), objname) -+ globalType := llvm.ArrayType(c.ctx.Int8Type(), len(str)) -+ global := llvm.AddGlobal(c.mod, globalType, objname) - global.SetInitializer(c.ctx.ConstString(str, false)) - global.SetLinkage(llvm.InternalLinkage) - global.SetGlobalConstant(true) - global.SetUnnamedAddr(true) - global.SetAlignment(1) - zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false) -- strPtr = llvm.ConstInBoundsGEP(global, []llvm.Value{zero, zero}) -+ strPtr = llvm.ConstInBoundsGEP(globalType, global, []llvm.Value{zero, zero}) - } else { - strPtr = llvm.ConstNull(c.i8ptrType) - } -@@ -2844,7 +2852,7 @@ func (b *builder) createConvert(typeFrom, typeTo types.Type, value llvm.Value, p - // create a GEP that is not in bounds. However, we're - // talking about unsafe code here so the programmer has to - // be careful anyway. -- return b.CreateInBoundsGEP(origptr, []llvm.Value{index}, ""), nil -+ return b.CreateInBoundsGEP(b.ctx.Int8Type(), origptr, []llvm.Value{index}, ""), nil - } - } - } -diff --git a/compiler/defer.go b/compiler/defer.go -index 1f892e5b..27e90331 100644 ---- a/compiler/defer.go -+++ b/compiler/defer.go -@@ -407,7 +407,8 @@ func (b *builder) createDefer(instr *ssa.Defer) { - - // createRunDefers emits code to run all deferred functions. - func (b *builder) createRunDefers() { -- deferType := llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0) -+ deferType := b.getLLVMRuntimeType("_defer") -+ deferPtrType := llvm.PointerType(deferType, 0) - - // Add a loop like the following: - // for stack != nil { -@@ -434,7 +435,7 @@ func (b *builder) createRunDefers() { - // Create loop head: - // for stack != nil { - b.SetInsertPointAtEnd(loophead) -- deferData := b.CreateLoad(deferType, b.deferPtr, "") -+ deferData := b.CreateLoad(deferPtrType, b.deferPtr, "") - stackIsNil := b.CreateICmp(llvm.IntEQ, deferData, llvm.ConstPointerNull(deferData.Type()), "stackIsNil") - b.CreateCondBr(stackIsNil, end, loop) - -@@ -443,13 +444,13 @@ func (b *builder) createRunDefers() { - // stack = stack.next - // switch stack.callback { - b.SetInsertPointAtEnd(loop) -- nextStackGEP := b.CreateInBoundsGEP(deferData, []llvm.Value{ -+ nextStackGEP := b.CreateInBoundsGEP(deferType, deferData, []llvm.Value{ - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - llvm.ConstInt(b.ctx.Int32Type(), 1, false), // .next field - }, "stack.next.gep") -- nextStack := b.CreateLoad(deferType, nextStackGEP, "stack.next") -+ nextStack := b.CreateLoad(deferPtrType, nextStackGEP, "stack.next") - b.CreateStore(nextStack, b.deferPtr) -- gep := b.CreateInBoundsGEP(deferData, []llvm.Value{ -+ gep := b.CreateInBoundsGEP(deferType, deferData, []llvm.Value{ - llvm.ConstInt(b.ctx.Int32Type(), 0, false), - llvm.ConstInt(b.ctx.Int32Type(), 0, false), // .callback field - }, "callback.gep") -@@ -489,7 +490,7 @@ func (b *builder) createRunDefers() { - forwardParams := []llvm.Value{} - zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) - for i := 2; i < len(valueTypes); i++ { -- gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "gep") -+ gep := b.CreateInBoundsGEP(deferredCallType, deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "gep") - forwardParam := b.CreateLoad(valueTypes[i], gep, "param") - forwardParams = append(forwardParams, forwardParam) - } -@@ -538,7 +539,7 @@ func (b *builder) createRunDefers() { - forwardParams := []llvm.Value{} - zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) - for i := range getParams(callback.Signature) { -- gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep") -+ gep := b.CreateInBoundsGEP(deferredCallType, deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep") - forwardParam := b.CreateLoad(valueTypes[i+2], gep, "param") - forwardParams = append(forwardParams, forwardParam) - } -@@ -571,7 +572,7 @@ func (b *builder) createRunDefers() { - forwardParams := []llvm.Value{} - zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) - for i := 2; i < len(valueTypes); i++ { -- gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "") -+ gep := b.CreateInBoundsGEP(deferredCallType, deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "") - forwardParam := b.CreateLoad(valueTypes[i], gep, "param") - forwardParams = append(forwardParams, forwardParam) - } -@@ -598,7 +599,7 @@ func (b *builder) createRunDefers() { - var argValues []llvm.Value - zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) - for i := 0; i < params.Len(); i++ { -- gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep") -+ gep := b.CreateInBoundsGEP(deferredCallType, deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep") - forwardParam := b.CreateLoad(valueTypes[i+2], gep, "param") - argValues = append(argValues, forwardParam) - } -diff --git a/compiler/interface.go b/compiler/interface.go -index 72f8952d..acb474f5 100644 ---- a/compiler/interface.go -+++ b/compiler/interface.go -@@ -122,19 +122,19 @@ func (c *compilerContext) makeStructTypeFields(typ *types.Struct) llvm.Value { - for i := 0; i < typ.NumFields(); i++ { - fieldGlobalValue := llvm.ConstNull(runtimeStructField) - fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, c.getTypeCode(typ.Field(i).Type()), []uint32{0}) -- fieldName := c.makeGlobalArray([]byte(typ.Field(i).Name()), "reflect/types.structFieldName", c.ctx.Int8Type()) -+ fieldNameType, fieldName := c.makeGlobalArray([]byte(typ.Field(i).Name()), "reflect/types.structFieldName", c.ctx.Int8Type()) - fieldName.SetLinkage(llvm.PrivateLinkage) - fieldName.SetUnnamedAddr(true) -- fieldName = llvm.ConstGEP(fieldName, []llvm.Value{ -+ fieldName = llvm.ConstGEP(fieldNameType, fieldName, []llvm.Value{ - llvm.ConstInt(c.ctx.Int32Type(), 0, false), - llvm.ConstInt(c.ctx.Int32Type(), 0, false), - }) - fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, fieldName, []uint32{1}) - if typ.Tag(i) != "" { -- fieldTag := c.makeGlobalArray([]byte(typ.Tag(i)), "reflect/types.structFieldTag", c.ctx.Int8Type()) -+ fieldTagType, fieldTag := c.makeGlobalArray([]byte(typ.Tag(i)), "reflect/types.structFieldTag", c.ctx.Int8Type()) - fieldTag.SetLinkage(llvm.PrivateLinkage) - fieldTag.SetUnnamedAddr(true) -- fieldTag = llvm.ConstGEP(fieldTag, []llvm.Value{ -+ fieldTag = llvm.ConstGEP(fieldTagType, fieldTag, []llvm.Value{ - llvm.ConstInt(c.ctx.Int32Type(), 0, false), - llvm.ConstInt(c.ctx.Int32Type(), 0, false), - }) -@@ -239,7 +239,7 @@ func (c *compilerContext) getTypeMethodSet(typ types.Type) llvm.Value { - zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false) - if !global.IsNil() { - // the method set already exists -- return llvm.ConstGEP(global, []llvm.Value{zero, zero}) -+ return llvm.ConstGEP(global.GlobalValueType(), global, []llvm.Value{zero, zero}) - } - - ms := c.program.MethodSets.MethodSet(typ) -@@ -272,7 +272,7 @@ func (c *compilerContext) getTypeMethodSet(typ types.Type) llvm.Value { - global.SetInitializer(value) - global.SetGlobalConstant(true) - global.SetLinkage(llvm.LinkOnceODRLinkage) -- return llvm.ConstGEP(global, []llvm.Value{zero, zero}) -+ return llvm.ConstGEP(arrayType, global, []llvm.Value{zero, zero}) - } - - // getInterfaceMethodSet returns a global variable with the method set of the -@@ -288,7 +288,7 @@ func (c *compilerContext) getInterfaceMethodSet(typ types.Type) llvm.Value { - zero := llvm.ConstInt(c.ctx.Int32Type(), 0, false) - if !global.IsNil() { - // method set already exist, return it -- return llvm.ConstGEP(global, []llvm.Value{zero, zero}) -+ return llvm.ConstGEP(global.GlobalValueType(), global, []llvm.Value{zero, zero}) - } - - // Every method is a *i8 reference indicating the signature of this method. -@@ -303,7 +303,7 @@ func (c *compilerContext) getInterfaceMethodSet(typ types.Type) llvm.Value { - global.SetInitializer(value) - global.SetGlobalConstant(true) - global.SetLinkage(llvm.LinkOnceODRLinkage) -- return llvm.ConstGEP(global, []llvm.Value{zero, zero}) -+ return llvm.ConstGEP(value.Type(), global, []llvm.Value{zero, zero}) - } - - // getMethodSignatureName returns a unique name (that can be used as the name of -diff --git a/compiler/llvm.go b/compiler/llvm.go -index 9540bcc6..686d4d2b 100644 ---- a/compiler/llvm.go -+++ b/compiler/llvm.go -@@ -61,10 +61,10 @@ func (b *builder) emitPointerUnpack(ptr llvm.Value, valueTypes []llvm.Type) []ll - } - - // makeGlobalArray creates a new LLVM global with the given name and integers as --// contents, and returns the global. -+// contents, and returns the global and initializer type. - // Note that it is left with the default linkage etc., you should set - // linkage/constant/etc properties yourself. --func (c *compilerContext) makeGlobalArray(buf []byte, name string, elementType llvm.Type) llvm.Value { -+func (c *compilerContext) makeGlobalArray(buf []byte, name string, elementType llvm.Type) (llvm.Type, llvm.Value) { - globalType := llvm.ArrayType(elementType, len(buf)) - global := llvm.AddGlobal(c.mod, globalType, name) - value := llvm.Undef(globalType) -@@ -73,7 +73,7 @@ func (c *compilerContext) makeGlobalArray(buf []byte, name string, elementType l - value = llvm.ConstInsertValue(value, llvm.ConstInt(elementType, ch, false), []uint32{uint32(i)}) - } - global.SetInitializer(value) -- return global -+ return globalType, global - } - - // createObjectLayout returns a LLVM value (of type i8*) that describes where -diff --git a/compiler/llvmutil/wordpack.go b/compiler/llvmutil/wordpack.go -index 97b86045..2a4607c8 100644 ---- a/compiler/llvmutil/wordpack.go -+++ b/compiler/llvmutil/wordpack.go -@@ -58,7 +58,7 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, prefix string, needs - llvm.ConstInt(ctx.Int32Type(), 0, false), - llvm.ConstInt(ctx.Int32Type(), uint64(i), false), - } -- gep := builder.CreateInBoundsGEP(packedAllocCast, indices, "") -+ gep := builder.CreateInBoundsGEP(packedType, packedAllocCast, indices, "") - builder.CreateStore(value, gep) - } - -@@ -115,7 +115,7 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, prefix string, needs - llvm.ConstInt(ctx.Int32Type(), 0, false), - llvm.ConstInt(ctx.Int32Type(), uint64(i), false), - } -- gep := builder.CreateInBoundsGEP(packedAlloc, indices, "") -+ gep := builder.CreateInBoundsGEP(packedType, packedAlloc, indices, "") - builder.CreateStore(value, gep) - } - -@@ -170,7 +170,7 @@ func EmitPointerUnpack(builder llvm.Builder, mod llvm.Module, ptr llvm.Value, va - llvm.ConstInt(ctx.Int32Type(), 0, false), - llvm.ConstInt(ctx.Int32Type(), uint64(i), false), - } -- gep := builder.CreateInBoundsGEP(packedAlloc, indices, "") -+ gep := builder.CreateInBoundsGEP(packedType, packedAlloc, indices, "") - values[i] = builder.CreateLoad(valueType, gep, "") - } - if !packedRawAlloc.IsNil() { -diff --git a/go.mod b/go.mod -index 26707a96..feb4e0d6 100644 ---- a/go.mod -+++ b/go.mod -@@ -17,7 +17,7 @@ require ( - golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 - golang.org/x/tools v0.1.11 - gopkg.in/yaml.v2 v2.4.0 -- tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6 -+ tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634 - ) - - require ( -diff --git a/go.sum b/go.sum -index e5c734cd..907364f9 100644 ---- a/go.sum -+++ b/go.sum -@@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 - gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= - gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= --tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6 h1:bJYUpmJrVm7Uluxh80qSivfeU3d9D4JNg5oJ+h9U+xc= --tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= -+tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634 h1:hihbmHkJjalV4kGshoCF03P/G4IjoXcNAbzLblXLa/M= -+tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= -diff --git a/interp/memory.go b/interp/memory.go -index 3a16b875..2fa6f5cb 100644 ---- a/interp/memory.go -+++ b/interp/memory.go -@@ -646,8 +646,8 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val - if llvmValue.Type() != mem.r.i8ptrType { - llvmValue = llvm.ConstBitCast(llvmValue, mem.r.i8ptrType) - } -- llvmValue = llvm.ConstInBoundsGEP(llvmValue, []llvm.Value{ -- llvm.ConstInt(llvmValue.Type().Context().Int32Type(), uint64(v.offset()), false), -+ llvmValue = llvm.ConstInBoundsGEP(mem.r.mod.Context().Int8Type(), llvmValue, []llvm.Value{ -+ llvm.ConstInt(mem.r.mod.Context().Int32Type(), uint64(v.offset()), false), - }) - } - -diff --git a/transform/gc.go b/transform/gc.go -index 7a4e99ac..3870a6b6 100644 ---- a/transform/gc.go -+++ b/transform/gc.go -@@ -223,7 +223,7 @@ func MakeGCStackSlots(mod llvm.Module) bool { - - // Update stack start. - parent := builder.CreateLoad(stackChainStartType, stackChainStart, "") -- gep := builder.CreateGEP(stackObject, []llvm.Value{ -+ gep := builder.CreateGEP(stackObjectType, stackObject, []llvm.Value{ - llvm.ConstInt(ctx.Int32Type(), 0, false), - llvm.ConstInt(ctx.Int32Type(), 0, false), - }, "") -@@ -244,7 +244,7 @@ func MakeGCStackSlots(mod llvm.Module) bool { - builder.SetInsertPointBefore(insertionPoint) - - // Extract a pointer to the appropriate section of the stack object. -- gep := builder.CreateGEP(stackObject, []llvm.Value{ -+ gep := builder.CreateGEP(stackObjectType, stackObject, []llvm.Value{ - llvm.ConstInt(ctx.Int32Type(), 0, false), - llvm.ConstInt(ctx.Int32Type(), uint64(2+i), false), - }, "") -diff --git a/transform/llvm.go b/transform/llvm.go -index 32ee9560..6716dd63 100644 ---- a/transform/llvm.go -+++ b/transform/llvm.go -@@ -31,10 +31,10 @@ func hasUses(value llvm.Value) bool { - } - - // makeGlobalArray creates a new LLVM global with the given name and integers as --// contents, and returns the global. -+// contents, and returns the global and initializer type. - // Note that it is left with the default linkage etc., you should set - // linkage/constant/etc properties yourself. --func makeGlobalArray(mod llvm.Module, bufItf interface{}, name string, elementType llvm.Type) llvm.Value { -+func makeGlobalArray(mod llvm.Module, bufItf interface{}, name string, elementType llvm.Type) (llvm.Type, llvm.Value) { - buf := reflect.ValueOf(bufItf) - globalType := llvm.ArrayType(elementType, buf.Len()) - global := llvm.AddGlobal(mod, globalType, name) -@@ -44,7 +44,7 @@ func makeGlobalArray(mod llvm.Module, bufItf interface{}, name string, elementTy - value = llvm.ConstInsertValue(value, llvm.ConstInt(elementType, ch, false), []uint32{uint32(i)}) - } - global.SetInitializer(value) -- return global -+ return globalType, global - } - - // getGlobalBytes returns the slice contained in the array of the provided -@@ -64,8 +64,8 @@ func getGlobalBytes(global llvm.Value) []byte { - // function used for creating reflection sidetables, for example. - func replaceGlobalIntWithArray(mod llvm.Module, name string, buf interface{}) llvm.Value { - oldGlobal := mod.NamedGlobal(name) -- global := makeGlobalArray(mod, buf, name+".tmp", oldGlobal.Type().ElementType()) -- gep := llvm.ConstGEP(global, []llvm.Value{ -+ globalType, global := makeGlobalArray(mod, buf, name+".tmp", oldGlobal.Type().ElementType()) -+ gep := llvm.ConstGEP(globalType, global, []llvm.Value{ - llvm.ConstInt(mod.Context().Int32Type(), 0, false), - llvm.ConstInt(mod.Context().Int32Type(), 0, false), - }) -diff --git a/transform/stacksize.go b/transform/stacksize.go -index f1a3c93d..169f1454 100644 ---- a/transform/stacksize.go -+++ b/transform/stacksize.go -@@ -59,7 +59,7 @@ func CreateStackSizeLoads(mod llvm.Module, config *compileopts.Config) []string - defer irbuilder.Dispose() - for i, function := range functions { - for _, use := range functionMap[function] { -- ptr := llvm.ConstGEP(stackSizesGlobal, []llvm.Value{ -+ ptr := llvm.ConstGEP(stackSizesGlobalType, stackSizesGlobal, []llvm.Value{ - llvm.ConstInt(ctx.Int32Type(), 0, false), - llvm.ConstInt(ctx.Int32Type(), uint64(i), false), - }) --- -2.36.1 - diff --git a/0012-all-replace-llvm.Const-calls-with-builder.Create-cal.patch b/0012-all-replace-llvm.Const-calls-with-builder.Create-cal.patch deleted file mode 100644 index a730ef6..0000000 --- a/0012-all-replace-llvm.Const-calls-with-builder.Create-cal.patch +++ /dev/null @@ -1,578 +0,0 @@ -From 6053c1c8528c63a669d070550bacd43f2f6a68e1 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Tue, 20 Sep 2022 23:26:49 +0200 -Subject: [PATCH 12/18] all: replace llvm.Const* calls with builder.Create* - calls - -A number of llvm.Const* functions (in particular extractvalue and -insertvalue) were removed in LLVM 15, so we have to use a builder -instead. This builder will create the same constant values, it simply -uses a different API. - -Signed-off-by: Elliott Sales de Andrade ---- - compiler/asserts.go | 2 +- - compiler/compiler.go | 23 ++++++++++++++++------- - compiler/interface.go | 20 ++++++++++---------- - compiler/interrupt.go | 8 +++++--- - compiler/llvm.go | 2 +- - interp/interpreter.go | 13 +++++++------ - interp/memory.go | 8 ++++---- - transform/gc.go | 2 +- - transform/interface-lowering.go | 14 +++++++------- - transform/interrupt.go | 7 ++++--- - transform/llvm.go | 16 +++++++++------- - transform/reflect.go | 32 +++++++++++++++++++------------- - transform/rtcalls.go | 4 ++-- - 13 files changed, 86 insertions(+), 65 deletions(-) - -diff --git a/compiler/asserts.go b/compiler/asserts.go -index 8d9efdde..2a5265e9 100644 ---- a/compiler/asserts.go -+++ b/compiler/asserts.go -@@ -145,7 +145,7 @@ func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value, - } - // Make the maxBufSize actually the maximum allowed value (in number of - // elements in the channel buffer). -- maxBufSize = llvm.ConstUDiv(maxBufSize, llvm.ConstInt(b.uintptrType, elementSize, false)) -+ maxBufSize = b.CreateUDiv(maxBufSize, llvm.ConstInt(b.uintptrType, elementSize, false), "") - - // Make sure maxBufSize has the same type as bufSize. - if maxBufSize.Type() != bufSize.Type() { -diff --git a/compiler/compiler.go b/compiler/compiler.go -index c93b2e56..3d29628c 100644 ---- a/compiler/compiler.go -+++ b/compiler/compiler.go -@@ -63,6 +63,7 @@ type compilerContext struct { - DumpSSA bool - mod llvm.Module - ctx llvm.Context -+ builder llvm.Builder // only used for constant operations - dibuilder *llvm.DIBuilder - cu llvm.Metadata - difiles map[string]llvm.Metadata -@@ -98,6 +99,7 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C - } - - c.ctx = llvm.NewContext() -+ c.builder = c.ctx.NewBuilder() - c.mod = c.ctx.NewModule(moduleName) - c.mod.SetTarget(config.Triple) - c.mod.SetDataLayout(c.targetData.String()) -@@ -126,6 +128,12 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C - return c - } - -+// Dispose everything related to the context, _except_ for the IR module (and -+// the associated context). -+func (c *compilerContext) dispose() { -+ c.builder.Dispose() -+} -+ - // builder contains all information relevant to build a single function. - type builder struct { - *compilerContext -@@ -256,6 +264,7 @@ func Sizes(machine llvm.TargetMachine) types.Sizes { - // CompilePackage compiles a single package to a LLVM module. - func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package, machine llvm.TargetMachine, config *Config, dumpSSA bool) (llvm.Module, []error) { - c := newCompilerContext(moduleName, machine, config, dumpSSA) -+ defer c.dispose() - c.packageDir = pkg.OriginalDir() - c.embedGlobals = pkg.EmbedGlobals - c.pkg = pkg.Pkg -@@ -972,10 +981,10 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu - for _, file := range allFiles { - fileStruct := llvm.ConstNull(embedFileStructType) - name := c.createConst(ssa.NewConst(constant.MakeString(file.Name), types.Typ[types.String])) -- fileStruct = llvm.ConstInsertValue(fileStruct, name, []uint32{0}) // "name" field -+ fileStruct = c.builder.CreateInsertValue(fileStruct, name, 0, "") // "name" field - if file.Hash != "" { - data := c.getEmbedFileString(file) -- fileStruct = llvm.ConstInsertValue(fileStruct, data, []uint32{1}) // "data" field -+ fileStruct = c.builder.CreateInsertValue(fileStruct, data, 1, "") // "data" field - } - fileStructs = append(fileStructs, fileStruct) - } -@@ -1006,7 +1015,7 @@ func (c *compilerContext) createEmbedGlobal(member *ssa.Global, global llvm.Valu - // Define the embed.FS struct. It has only one field: the files (as a - // *[]embed.file). - globalInitializer := llvm.ConstNull(c.getLLVMType(member.Type().(*types.Pointer).Elem())) -- globalInitializer = llvm.ConstInsertValue(globalInitializer, sliceGlobal, []uint32{0}) -+ globalInitializer = c.builder.CreateInsertValue(globalInitializer, sliceGlobal, 0, "") - global.SetInitializer(globalInitializer) - global.SetVisibility(llvm.HiddenVisibility) - global.SetAlignment(c.targetData.ABITypeAlignment(globalInitializer.Type())) -@@ -2757,15 +2766,15 @@ func (c *compilerContext) createConst(expr *ssa.Const) llvm.Value { - r := c.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float32])) - i := c.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float32])) - cplx := llvm.Undef(c.ctx.StructType([]llvm.Type{c.ctx.FloatType(), c.ctx.FloatType()}, false)) -- cplx = llvm.ConstInsertValue(cplx, r, []uint32{0}) -- cplx = llvm.ConstInsertValue(cplx, i, []uint32{1}) -+ cplx = c.builder.CreateInsertValue(cplx, r, 0, "") -+ cplx = c.builder.CreateInsertValue(cplx, i, 1, "") - return cplx - } else if typ.Kind() == types.Complex128 { - r := c.createConst(ssa.NewConst(constant.Real(expr.Value), types.Typ[types.Float64])) - i := c.createConst(ssa.NewConst(constant.Imag(expr.Value), types.Typ[types.Float64])) - cplx := llvm.Undef(c.ctx.StructType([]llvm.Type{c.ctx.DoubleType(), c.ctx.DoubleType()}, false)) -- cplx = llvm.ConstInsertValue(cplx, r, []uint32{0}) -- cplx = llvm.ConstInsertValue(cplx, i, []uint32{1}) -+ cplx = c.builder.CreateInsertValue(cplx, r, 0, "") -+ cplx = c.builder.CreateInsertValue(cplx, i, 1, "") - return cplx - } else { - panic("unknown constant of basic type: " + expr.String()) -diff --git a/compiler/interface.go b/compiler/interface.go -index acb474f5..106c327a 100644 ---- a/compiler/interface.go -+++ b/compiler/interface.go -@@ -88,20 +88,20 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value { - } - globalValue := llvm.ConstNull(global.Type().ElementType()) - if !references.IsNil() { -- globalValue = llvm.ConstInsertValue(globalValue, references, []uint32{0}) -+ globalValue = c.builder.CreateInsertValue(globalValue, references, 0, "") - } - if length != 0 { - lengthValue := llvm.ConstInt(c.uintptrType, uint64(length), false) -- globalValue = llvm.ConstInsertValue(globalValue, lengthValue, []uint32{1}) -+ globalValue = c.builder.CreateInsertValue(globalValue, lengthValue, 1, "") - } - if !methodSet.IsNil() { -- globalValue = llvm.ConstInsertValue(globalValue, methodSet, []uint32{2}) -+ globalValue = c.builder.CreateInsertValue(globalValue, methodSet, 2, "") - } - if !ptrTo.IsNil() { -- globalValue = llvm.ConstInsertValue(globalValue, ptrTo, []uint32{3}) -+ globalValue = c.builder.CreateInsertValue(globalValue, ptrTo, 3, "") - } - if !typeAssert.IsNil() { -- globalValue = llvm.ConstInsertValue(globalValue, typeAssert, []uint32{4}) -+ globalValue = c.builder.CreateInsertValue(globalValue, typeAssert, 4, "") - } - global.SetInitializer(globalValue) - global.SetLinkage(llvm.LinkOnceODRLinkage) -@@ -121,7 +121,7 @@ func (c *compilerContext) makeStructTypeFields(typ *types.Struct) llvm.Value { - structGlobalValue := llvm.ConstNull(structGlobalType) - for i := 0; i < typ.NumFields(); i++ { - fieldGlobalValue := llvm.ConstNull(runtimeStructField) -- fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, c.getTypeCode(typ.Field(i).Type()), []uint32{0}) -+ fieldGlobalValue = c.builder.CreateInsertValue(fieldGlobalValue, c.getTypeCode(typ.Field(i).Type()), 0, "") - fieldNameType, fieldName := c.makeGlobalArray([]byte(typ.Field(i).Name()), "reflect/types.structFieldName", c.ctx.Int8Type()) - fieldName.SetLinkage(llvm.PrivateLinkage) - fieldName.SetUnnamedAddr(true) -@@ -129,7 +129,7 @@ func (c *compilerContext) makeStructTypeFields(typ *types.Struct) llvm.Value { - llvm.ConstInt(c.ctx.Int32Type(), 0, false), - llvm.ConstInt(c.ctx.Int32Type(), 0, false), - }) -- fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, fieldName, []uint32{1}) -+ fieldGlobalValue = c.builder.CreateInsertValue(fieldGlobalValue, fieldName, 1, "") - if typ.Tag(i) != "" { - fieldTagType, fieldTag := c.makeGlobalArray([]byte(typ.Tag(i)), "reflect/types.structFieldTag", c.ctx.Int8Type()) - fieldTag.SetLinkage(llvm.PrivateLinkage) -@@ -138,13 +138,13 @@ func (c *compilerContext) makeStructTypeFields(typ *types.Struct) llvm.Value { - llvm.ConstInt(c.ctx.Int32Type(), 0, false), - llvm.ConstInt(c.ctx.Int32Type(), 0, false), - }) -- fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, fieldTag, []uint32{2}) -+ fieldGlobalValue = c.builder.CreateInsertValue(fieldGlobalValue, fieldTag, 2, "") - } - if typ.Field(i).Embedded() { - fieldEmbedded := llvm.ConstInt(c.ctx.Int1Type(), 1, false) -- fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, fieldEmbedded, []uint32{3}) -+ fieldGlobalValue = c.builder.CreateInsertValue(fieldGlobalValue, fieldEmbedded, 3, "") - } -- structGlobalValue = llvm.ConstInsertValue(structGlobalValue, fieldGlobalValue, []uint32{uint32(i)}) -+ structGlobalValue = c.builder.CreateInsertValue(structGlobalValue, fieldGlobalValue, i, "") - } - structGlobal.SetInitializer(structGlobalValue) - structGlobal.SetUnnamedAddr(true) -diff --git a/compiler/interrupt.go b/compiler/interrupt.go -index 45c7d074..c1f7d69f 100644 ---- a/compiler/interrupt.go -+++ b/compiler/interrupt.go -@@ -49,9 +49,11 @@ func (b *builder) createInterruptGlobal(instr *ssa.CallCommon) (llvm.Value, erro - global.SetGlobalConstant(true) - global.SetUnnamedAddr(true) - initializer := llvm.ConstNull(globalLLVMType) -- initializer = llvm.ConstInsertValue(initializer, funcContext, []uint32{0}) -- initializer = llvm.ConstInsertValue(initializer, funcPtr, []uint32{1}) -- initializer = llvm.ConstInsertValue(initializer, llvm.ConstInt(b.intType, uint64(id.Int64()), true), []uint32{2, 0}) -+ initializer = b.CreateInsertValue(initializer, funcContext, 0, "") -+ initializer = b.CreateInsertValue(initializer, funcPtr, 1, "") -+ initializer = b.CreateInsertValue(initializer, llvm.ConstNamedStruct(globalLLVMType.StructElementTypes()[2], []llvm.Value{ -+ llvm.ConstInt(b.intType, uint64(id.Int64()), true), -+ }), 2, "") - global.SetInitializer(initializer) - - // Add debug info to the interrupt global. -diff --git a/compiler/llvm.go b/compiler/llvm.go -index 686d4d2b..8b80869b 100644 ---- a/compiler/llvm.go -+++ b/compiler/llvm.go -@@ -70,7 +70,7 @@ func (c *compilerContext) makeGlobalArray(buf []byte, name string, elementType l - value := llvm.Undef(globalType) - for i := 0; i < len(buf); i++ { - ch := uint64(buf[i]) -- value = llvm.ConstInsertValue(value, llvm.ConstInt(elementType, ch, false), []uint32{uint32(i)}) -+ value = c.builder.CreateInsertValue(value, llvm.ConstInt(elementType, ch, false), i, "") - } - global.SetInitializer(value) - return globalType, global -diff --git a/interp/interpreter.go b/interp/interpreter.go -index 2c7fd8c3..d029aa33 100644 ---- a/interp/interpreter.go -+++ b/interp/interpreter.go -@@ -408,7 +408,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent - // Elem() is only valid for certain type classes. - switch class { - case "chan", "pointer", "slice", "array": -- elementType := llvm.ConstExtractValue(typecodeID.Initializer(), []uint32{0}) -+ elementType := r.builder.CreateExtractValue(typecodeID.Initializer(), 0, "") - uintptrType := r.mod.Context().IntType(int(mem.r.pointerSize) * 8) - locals[inst.localIndex] = r.getValue(llvm.ConstPtrToInt(elementType, uintptrType)) - default: -@@ -461,8 +461,8 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent - // easier checking in the next step. - concreteTypeMethods := map[string]struct{}{} - for i := 0; i < methodSet.Type().ArrayLength(); i++ { -- methodInfo := llvm.ConstExtractValue(methodSet, []uint32{uint32(i)}) -- name := llvm.ConstExtractValue(methodInfo, []uint32{0}).Name() -+ methodInfo := r.builder.CreateExtractValue(methodSet, i, "") -+ name := r.builder.CreateExtractValue(methodInfo, 0, "").Name() - concreteTypeMethods[name] = struct{}{} - } - -@@ -496,7 +496,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent - typecodeID := typecodeIDBitCast.Operand(0).Initializer() - - // Load the method set, which is part of the typecodeID object. -- methodSet := llvm.ConstExtractValue(typecodeID, []uint32{2}).Operand(0).Initializer() -+ methodSet := r.builder.CreateExtractValue(typecodeID, 2, "").Operand(0).Initializer() - - // We don't need to load the interface method set. - -@@ -511,9 +511,10 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent - numMethods := methodSet.Type().ArrayLength() - var method llvm.Value - for i := 0; i < numMethods; i++ { -- methodSignature := llvm.ConstExtractValue(methodSet, []uint32{uint32(i), 0}) -+ methodSignatureAgg := r.builder.CreateExtractValue(methodSet, i, "") -+ methodSignature := r.builder.CreateExtractValue(methodSignatureAgg, 0, "") - if methodSignature == signature { -- method = llvm.ConstExtractValue(methodSet, []uint32{uint32(i), 1}).Operand(0) -+ method = r.builder.CreateExtractValue(methodSignatureAgg, 1, "").Operand(0) - } - } - if method.IsNil() { -diff --git a/interp/memory.go b/interp/memory.go -index 2fa6f5cb..583f9355 100644 ---- a/interp/memory.go -+++ b/interp/memory.go -@@ -215,7 +215,7 @@ func (mv *memoryView) markExternal(llvmValue llvm.Value, mark uint8) error { - case llvm.StructTypeKind: - numElements := llvmType.StructElementTypesCount() - for i := 0; i < numElements; i++ { -- element := llvm.ConstExtractValue(llvmValue, []uint32{uint32(i)}) -+ element := mv.r.builder.CreateExtractValue(llvmValue, i, "") - err := mv.markExternal(element, mark) - if err != nil { - return err -@@ -224,7 +224,7 @@ func (mv *memoryView) markExternal(llvmValue llvm.Value, mark uint8) error { - case llvm.ArrayTypeKind: - numElements := llvmType.ArrayLength() - for i := 0; i < numElements; i++ { -- element := llvm.ConstExtractValue(llvmValue, []uint32{uint32(i)}) -+ element := mv.r.builder.CreateExtractValue(llvmValue, i, "") - err := mv.markExternal(element, mark) - if err != nil { - return err -@@ -1074,7 +1074,7 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) { - field := rawValue{ - buf: v.buf[offset:], - } -- field.set(llvm.ConstExtractValue(llvmValue, []uint32{uint32(i)}), r) -+ field.set(r.builder.CreateExtractValue(llvmValue, i, ""), r) - } - case llvm.ArrayTypeKind: - numElements := llvmType.ArrayLength() -@@ -1085,7 +1085,7 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) { - field := rawValue{ - buf: v.buf[offset:], - } -- field.set(llvm.ConstExtractValue(llvmValue, []uint32{uint32(i)}), r) -+ field.set(r.builder.CreateExtractValue(llvmValue, i, ""), r) - } - case llvm.DoubleTypeKind: - f, _ := llvmValue.DoubleValue() -diff --git a/transform/gc.go b/transform/gc.go -index 3870a6b6..514fb1bf 100644 ---- a/transform/gc.go -+++ b/transform/gc.go -@@ -218,7 +218,7 @@ func MakeGCStackSlots(mod llvm.Module) bool { - initialStackObject := llvm.ConstNull(stackObjectType) - numSlots := (targetData.TypeAllocSize(stackObjectType) - uint64(targetData.PointerSize())*2) / uint64(targetData.ABITypeAlignment(uintptrType)) - numSlotsValue := llvm.ConstInt(uintptrType, numSlots, false) -- initialStackObject = llvm.ConstInsertValue(initialStackObject, numSlotsValue, []uint32{1}) -+ initialStackObject = builder.CreateInsertValue(initialStackObject, numSlotsValue, 1, "") - builder.CreateStore(initialStackObject, stackObject) - - // Update stack start. -diff --git a/transform/interface-lowering.go b/transform/interface-lowering.go -index f5b29e30..f28443dc 100644 ---- a/transform/interface-lowering.go -+++ b/transform/interface-lowering.go -@@ -154,7 +154,7 @@ func (p *lowerInterfacesPass) run() error { - if initializer.IsNil() { - continue - } -- methodSet := llvm.ConstExtractValue(initializer, []uint32{2}) -+ methodSet := p.builder.CreateExtractValue(initializer, 2, "") - p.addTypeMethods(t, methodSet) - } - } -@@ -288,9 +288,9 @@ func (p *lowerInterfacesPass) run() error { - zeroUintptr := llvm.ConstNull(p.uintptrType) - for _, t := range p.types { - initializer := t.typecode.Initializer() -- methodSet := llvm.ConstExtractValue(initializer, []uint32{2}) -- initializer = llvm.ConstInsertValue(initializer, llvm.ConstNull(methodSet.Type()), []uint32{2}) -- initializer = llvm.ConstInsertValue(initializer, zeroUintptr, []uint32{4}) -+ methodSet := p.builder.CreateExtractValue(initializer, 2, "") -+ initializer = p.builder.CreateInsertValue(initializer, llvm.ConstNull(methodSet.Type()), 2, "") -+ initializer = p.builder.CreateInsertValue(initializer, zeroUintptr, 4, "") - t.typecode.SetInitializer(initializer) - } - -@@ -311,10 +311,10 @@ func (p *lowerInterfacesPass) addTypeMethods(t *typeInfo, methodSet llvm.Value) - t.methodSet = methodSet - set := methodSet.Initializer() // get value from global - for i := 0; i < set.Type().ArrayLength(); i++ { -- methodData := llvm.ConstExtractValue(set, []uint32{uint32(i)}) -- signatureGlobal := llvm.ConstExtractValue(methodData, []uint32{0}) -+ methodData := p.builder.CreateExtractValue(set, i, "") -+ signatureGlobal := p.builder.CreateExtractValue(methodData, 0, "") - signatureName := signatureGlobal.Name() -- function := llvm.ConstExtractValue(methodData, []uint32{1}).Operand(0) -+ function := p.builder.CreateExtractValue(methodData, 1, "").Operand(0) - signature := p.getSignature(signatureName) - method := &methodInfo{ - function: function, -diff --git a/transform/interrupt.go b/transform/interrupt.go -index 2c301be0..b15ff8a9 100644 ---- a/transform/interrupt.go -+++ b/transform/interrupt.go -@@ -44,7 +44,8 @@ func LowerInterrupts(mod llvm.Module) []error { - - // Get the interrupt number from the initializer - initializer := global.Initializer() -- num := llvm.ConstExtractValue(initializer, []uint32{2, 0}).SExtValue() -+ interrupt := builder.CreateExtractValue(initializer, 2, "") -+ num := builder.CreateExtractValue(interrupt, 0, "").SExtValue() - pkg := packageFromInterruptHandle(global) - - handles, exists := handleMap[num] -@@ -89,8 +90,8 @@ func LowerInterrupts(mod llvm.Module) []error { - builder.SetInsertPointBefore(call) - for _, handler := range handlers { - initializer := handler.Initializer() -- context := llvm.ConstExtractValue(initializer, []uint32{0}) -- funcPtr := llvm.ConstExtractValue(initializer, []uint32{1}).Operand(0) -+ context := builder.CreateExtractValue(initializer, 0, "") -+ funcPtr := builder.CreateExtractValue(initializer, 1, "").Operand(0) - builder.CreateCall(funcPtr.GlobalValueType(), funcPtr, []llvm.Value{ - num, - context, -diff --git a/transform/llvm.go b/transform/llvm.go -index 6716dd63..17968f8a 100644 ---- a/transform/llvm.go -+++ b/transform/llvm.go -@@ -36,25 +36,27 @@ func hasUses(value llvm.Value) bool { - // linkage/constant/etc properties yourself. - func makeGlobalArray(mod llvm.Module, bufItf interface{}, name string, elementType llvm.Type) (llvm.Type, llvm.Value) { - buf := reflect.ValueOf(bufItf) -- globalType := llvm.ArrayType(elementType, buf.Len()) -- global := llvm.AddGlobal(mod, globalType, name) -- value := llvm.Undef(globalType) -+ var values []llvm.Value - for i := 0; i < buf.Len(); i++ { - ch := buf.Index(i).Uint() -- value = llvm.ConstInsertValue(value, llvm.ConstInt(elementType, ch, false), []uint32{uint32(i)}) -+ values = append(values, llvm.ConstInt(elementType, ch, false)) - } -+ value := llvm.ConstArray(elementType, values) -+ global := llvm.AddGlobal(mod, value.Type(), name) - global.SetInitializer(value) -- return globalType, global -+ return value.Type(), global - } - - // getGlobalBytes returns the slice contained in the array of the provided - // global. It can recover the bytes originally created using makeGlobalArray, if - // makeGlobalArray was given a byte slice. --func getGlobalBytes(global llvm.Value) []byte { -+// -+// The builder parameter is only used for constant operations. -+func getGlobalBytes(global llvm.Value, builder llvm.Builder) []byte { - value := global.Initializer() - buf := make([]byte, value.Type().ArrayLength()) - for i := range buf { -- buf[i] = byte(llvm.ConstExtractValue(value, []uint32{uint32(i)}).ZExtValue()) -+ buf[i] = byte(builder.CreateExtractValue(value, i, "").ZExtValue()) - } - return buf - } -diff --git a/transform/reflect.go b/transform/reflect.go -index fd70ccb7..68beba9b 100644 ---- a/transform/reflect.go -+++ b/transform/reflect.go -@@ -76,6 +76,10 @@ var nonBasicTypes = map[string]int64{ - // typeCodeAssignmentState keeps some global state around for type code - // assignments, used to assign one unique type code to each Go type. - type typeCodeAssignmentState struct { -+ // Builder used purely for constant operations (because LLVM 15 removed many -+ // llvm.Const* functions). -+ builder llvm.Builder -+ - // An integer that's incremented each time it's used to give unique IDs to - // type codes that are not yet fully supported otherwise by the reflect - // package (or are simply unused in the compiled program). -@@ -165,6 +169,7 @@ func LowerReflect(mod llvm.Module) { - defer targetData.Dispose() - uintptrType := mod.Context().IntType(targetData.PointerSize() * 8) - state := typeCodeAssignmentState{ -+ builder: mod.Context().NewBuilder(), - fallbackIndex: 1, - uintptrLen: targetData.PointerSize() * 8, - namedBasicTypes: make(map[string]int), -@@ -177,6 +182,7 @@ func LowerReflect(mod llvm.Module) { - needsStructNamesSidetable: len(getUses(mod.NamedGlobal("reflect.structNamesSidetable"))) != 0, - needsArrayTypesSidetable: len(getUses(mod.NamedGlobal("reflect.arrayTypesSidetable"))) != 0, - } -+ defer state.builder.Dispose() - for _, t := range types { - num := state.getTypeCodeNum(t.typecode) - if num.BitLen() > state.uintptrLen || !num.IsUint64() { -@@ -238,7 +244,7 @@ func LowerReflect(mod llvm.Module) { - // It also cleans up the IR for testing. - for _, typ := range types { - initializer := typ.typecode.Initializer() -- references := llvm.ConstExtractValue(initializer, []uint32{0}) -+ references := state.builder.CreateExtractValue(initializer, 0, "") - typ.typecode.SetInitializer(llvm.ConstNull(initializer.Type())) - if strings.HasPrefix(typ.name, "reflect/types.type:struct:") { - // Structs have a 'references' field that is not a typecode but -@@ -260,7 +266,7 @@ func (state *typeCodeAssignmentState) getTypeCodeNum(typecode llvm.Value) *big.I - name := "" - if class == "named" { - name = value -- typecode = llvm.ConstExtractValue(typecode.Initializer(), []uint32{0}) -+ typecode = state.builder.CreateExtractValue(typecode.Initializer(), 0, "") - class, value = getClassAndValueFromTypeCode(typecode) - } - if class == "basic" { -@@ -344,7 +350,7 @@ func (state *typeCodeAssignmentState) getNonBasicTypeCode(class string, typecode - switch class { - case "chan", "pointer", "slice": - // Prefix-style type kinds. The upper bits contain the element type. -- sub := llvm.ConstExtractValue(typecode.Initializer(), []uint32{0}) -+ sub := state.builder.CreateExtractValue(typecode.Initializer(), 0, "") - return state.getTypeCodeNum(sub) - case "array": - // An array is basically a pair of (typecode, length) stored in a -@@ -416,7 +422,7 @@ func (state *typeCodeAssignmentState) getArrayTypeNum(typecode llvm.Value) int { - return num - } - -- elemTypeCode := llvm.ConstExtractValue(typecode.Initializer(), []uint32{0}) -+ elemTypeCode := state.builder.CreateExtractValue(typecode.Initializer(), 0, "") - elemTypeNum := state.getTypeCodeNum(elemTypeCode) - if elemTypeNum.BitLen() > state.uintptrLen || !elemTypeNum.IsUint64() { - // TODO: make this a regular error -@@ -424,7 +430,7 @@ func (state *typeCodeAssignmentState) getArrayTypeNum(typecode llvm.Value) int { - } - - // The array side table is a sequence of {element type, array length}. -- arrayLength := llvm.ConstExtractValue(typecode.Initializer(), []uint32{1}).ZExtValue() -+ arrayLength := state.builder.CreateExtractValue(typecode.Initializer(), 1, "").ZExtValue() - buf := makeVarint(elemTypeNum.Uint64()) - buf = append(buf, makeVarint(arrayLength)...) - -@@ -454,7 +460,7 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int - - // Get the fields this struct type contains. - // The struct number will be the start index of -- structTypeGlobal := llvm.ConstExtractValue(typecode.Initializer(), []uint32{0}).Operand(0).Initializer() -+ structTypeGlobal := state.builder.CreateExtractValue(typecode.Initializer(), 0, "").Operand(0).Initializer() - numFields := structTypeGlobal.Type().ArrayLength() - - // The first data that is stored in the struct sidetable is the number of -@@ -471,28 +477,28 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int - // the sidetable bigger. - for i := 0; i < numFields; i++ { - // Collect some information about this field. -- field := llvm.ConstExtractValue(structTypeGlobal, []uint32{uint32(i)}) -+ field := state.builder.CreateExtractValue(structTypeGlobal, i, "") - -- nameGlobal := llvm.ConstExtractValue(field, []uint32{1}) -+ nameGlobal := state.builder.CreateExtractValue(field, 1, "") - if nameGlobal == llvm.ConstPointerNull(nameGlobal.Type()) { - panic("compiler: no name for this struct field") - } -- fieldNameBytes := getGlobalBytes(nameGlobal.Operand(0)) -+ fieldNameBytes := getGlobalBytes(nameGlobal.Operand(0), state.builder) - fieldNameNumber := state.getStructNameNumber(fieldNameBytes) - - // See whether this struct field has an associated tag, and if so, - // store that tag in the tags sidetable. -- tagGlobal := llvm.ConstExtractValue(field, []uint32{2}) -+ tagGlobal := state.builder.CreateExtractValue(field, 2, "") - hasTag := false - tagNumber := 0 - if tagGlobal != llvm.ConstPointerNull(tagGlobal.Type()) { - hasTag = true -- tagBytes := getGlobalBytes(tagGlobal.Operand(0)) -+ tagBytes := getGlobalBytes(tagGlobal.Operand(0), state.builder) - tagNumber = state.getStructNameNumber(tagBytes) - } - - // The 'embedded' or 'anonymous' flag for this field. -- embedded := llvm.ConstExtractValue(field, []uint32{3}).ZExtValue() != 0 -+ embedded := state.builder.CreateExtractValue(field, 3, "").ZExtValue() != 0 - - // The first byte in the struct types sidetable is a flags byte with - // two bits in it. -@@ -510,7 +516,7 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int - - // Get the type number and add it to the buffer. - // All fields have a type, so include it directly here. -- typeNum := state.getTypeCodeNum(llvm.ConstExtractValue(field, []uint32{0})) -+ typeNum := state.getTypeCodeNum(state.builder.CreateExtractValue(field, 0, "")) - if typeNum.BitLen() > state.uintptrLen || !typeNum.IsUint64() { - // TODO: make this a regular error - panic("struct field has a type code that is too big") -diff --git a/transform/rtcalls.go b/transform/rtcalls.go -index 2f17f815..d70bc626 100644 ---- a/transform/rtcalls.go -+++ b/transform/rtcalls.go -@@ -149,7 +149,7 @@ func OptimizeReflectImplements(mod llvm.Module) { - interfaceType := interfaceTypeBitCast.Operand(0) - if strings.HasPrefix(interfaceType.Name(), "reflect/types.type:named:") { - // Get the underlying type. -- interfaceType = llvm.ConstExtractValue(interfaceType.Initializer(), []uint32{0}) -+ interfaceType = builder.CreateExtractValue(interfaceType.Initializer(), 0, "") - } - if !strings.HasPrefix(interfaceType.Name(), "reflect/types.type:interface:") { - // This is an error. The Type passed to Implements should be of -@@ -161,7 +161,7 @@ func OptimizeReflectImplements(mod llvm.Module) { - // Interface is unknown at compile time. This can't be optimized. - continue - } -- typeAssertFunction := llvm.ConstExtractValue(interfaceType.Initializer(), []uint32{4}).Operand(0) -+ typeAssertFunction := builder.CreateExtractValue(interfaceType.Initializer(), 4, "").Operand(0) - - // Replace Implements call with the type assert call. - builder.SetInsertPointBefore(call) --- -2.36.1 - diff --git a/0013-interp-change-object.llvmType-to-the-initializer-typ.patch b/0013-interp-change-object.llvmType-to-the-initializer-typ.patch deleted file mode 100644 index 4ef130d..0000000 --- a/0013-interp-change-object.llvmType-to-the-initializer-typ.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 1004deaafd70d4eb94196977c20a5b1a17cded81 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Thu, 22 Sep 2022 01:06:40 +0200 -Subject: [PATCH 13/18] interp: change object.llvmType to the initializer type - -Previously it was a pointer type, which won't work with opaque pointers. -Instead, use the global initializer type instead. - -Signed-off-by: Elliott Sales de Andrade ---- - go.mod | 2 +- - go.sum | 4 ++-- - interp/interpreter.go | 2 +- - interp/memory.go | 4 ++-- - 4 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/go.mod b/go.mod -index feb4e0d6..a50f1174 100644 ---- a/go.mod -+++ b/go.mod -@@ -17,7 +17,7 @@ require ( - golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 - golang.org/x/tools v0.1.11 - gopkg.in/yaml.v2 v2.4.0 -- tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634 -+ tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec - ) - - require ( -diff --git a/go.sum b/go.sum -index 907364f9..4af03408 100644 ---- a/go.sum -+++ b/go.sum -@@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 - gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= - gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= --tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634 h1:hihbmHkJjalV4kGshoCF03P/G4IjoXcNAbzLblXLa/M= --tinygo.org/x/go-llvm v0.0.0-20220921144624-dabbe3f30634/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= -+tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec h1:FYtAFrw/YQPc644uNN65dW50FrEuVNaPBf70x23ApY4= -+tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= -diff --git a/interp/interpreter.go b/interp/interpreter.go -index d029aa33..8c783a70 100644 ---- a/interp/interpreter.go -+++ b/interp/interpreter.go -@@ -637,7 +637,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent - // Create the new object. - size := operands[0].(literalValue).value.(uint64) - alloca := object{ -- llvmType: inst.llvmInst.Type(), -+ llvmType: inst.llvmInst.AllocatedType(), - globalName: r.pkgName + "$alloca", - buffer: newRawValue(uint32(size)), - size: uint32(size), -diff --git a/interp/memory.go b/interp/memory.go -index 583f9355..6a537bad 100644 ---- a/interp/memory.go -+++ b/interp/memory.go -@@ -37,7 +37,7 @@ import ( - // ability to roll back interpreting a function. - type object struct { - llvmGlobal llvm.Value -- llvmType llvm.Type // must match llvmGlobal.Type() if both are set, may be unset if llvmGlobal is set -+ llvmType llvm.Type // must match llvmGlobal.GlobalValueType() if both are set, may be unset if llvmGlobal is set - llvmLayoutType llvm.Type // LLVM type based on runtime.alloc layout parameter, if available - globalName string // name, if not yet created (not guaranteed to be the final name) - buffer value // buffer with value as given by interp, nil if external -@@ -594,7 +594,7 @@ func (v pointerValue) toLLVMValue(llvmType llvm.Type, mem *memoryView) (llvm.Val - var globalType llvm.Type - if !obj.llvmType.IsNil() { - // The exact type is known. -- globalType = obj.llvmType.ElementType() -+ globalType = obj.llvmType - } else { // !obj.llvmLayoutType.IsNil() - // The exact type isn't known, but the object layout is known. - globalType = obj.llvmLayoutType --- -2.36.1 - diff --git a/0014-all-remove-pointer-ElementType-calls.patch b/0014-all-remove-pointer-ElementType-calls.patch deleted file mode 100644 index 36f0818..0000000 --- a/0014-all-remove-pointer-ElementType-calls.patch +++ /dev/null @@ -1,586 +0,0 @@ -From 0cdaa0f6db40e372db24d945b557d03b97ff92e9 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Thu, 22 Sep 2022 13:33:00 +0200 -Subject: [PATCH 14/18] all: remove pointer ElementType calls - -This is needed for opaque pointers, which are enabled by default in -LLVM 15. - -Signed-off-by: Elliott Sales de Andrade ---- - builder/build.go | 4 +-- - compiler/asserts.go | 4 +-- - compiler/calls.go | 58 ++++++++++++++------------------- - compiler/compiler.go | 15 +++++---- - compiler/func.go | 2 +- - compiler/interface.go | 4 +-- - compiler/ircheck/check.go | 5 +-- - compiler/symbol.go | 15 ++------- - interp/compiler.go | 21 ++++++++---- - interp/interp.go | 10 +++--- - interp/interpreter.go | 2 +- - interp/memory.go | 23 +++++++------ - transform/allocs.go | 2 +- - transform/gc.go | 4 +-- - transform/interface-lowering.go | 2 +- - transform/llvm.go | 2 +- - transform/wasm-abi.go | 2 +- - 17 files changed, 82 insertions(+), 93 deletions(-) - -diff --git a/builder/build.go b/builder/build.go -index 7a7dd9ac..488ee823 100644 ---- a/builder/build.go -+++ b/builder/build.go -@@ -418,7 +418,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil - return errors.New("global not found: " + globalName) - } - name := global.Name() -- newGlobal := llvm.AddGlobal(mod, global.Type().ElementType(), name+".tmp") -+ newGlobal := llvm.AddGlobal(mod, global.GlobalValueType(), name+".tmp") - global.ReplaceAllUsesWith(newGlobal) - global.EraseFromParentAsGlobal() - newGlobal.SetName(name) -@@ -1134,7 +1134,7 @@ func setGlobalValues(mod llvm.Module, globals map[string]map[string]string) erro - - // A strin is a {ptr, len} pair. We need these types to build the - // initializer. -- initializerType := global.Type().ElementType() -+ initializerType := global.GlobalValueType() - if initializerType.TypeKind() != llvm.StructTypeKind || initializerType.StructName() == "" { - return fmt.Errorf("%s: not a string", globalName) - } -diff --git a/compiler/asserts.go b/compiler/asserts.go -index 2a5265e9..ba482494 100644 ---- a/compiler/asserts.go -+++ b/compiler/asserts.go -@@ -91,7 +91,7 @@ func (b *builder) createSliceToArrayPointerCheck(sliceLen llvm.Value, arrayLen i - - // createUnsafeSliceCheck inserts a runtime check used for unsafe.Slice. This - // function must panic if the ptr/len parameters are invalid. --func (b *builder) createUnsafeSliceCheck(ptr, len llvm.Value, lenType *types.Basic) { -+func (b *builder) createUnsafeSliceCheck(ptr, len llvm.Value, elementType llvm.Type, lenType *types.Basic) { - // From the documentation of unsafe.Slice: - // > At run time, if len is negative, or if ptr is nil and len is not - // > zero, a run-time panic occurs. -@@ -105,7 +105,7 @@ func (b *builder) createUnsafeSliceCheck(ptr, len llvm.Value, lenType *types.Bas - - // Determine the maximum slice size, and therefore the maximum value of the - // len parameter. -- maxSize := b.maxSliceSize(ptr.Type().ElementType()) -+ maxSize := b.maxSliceSize(elementType) - maxSizeValue := llvm.ConstInt(len.Type(), maxSize, false) - - // Do the check. By using unsigned greater than for the length check, signed -diff --git a/compiler/calls.go b/compiler/calls.go -index b38d770f..b122f0c8 100644 ---- a/compiler/calls.go -+++ b/compiler/calls.go -@@ -20,7 +20,7 @@ const maxFieldsPerParam = 3 - type paramInfo struct { - llvmType llvm.Type - name string // name, possibly with suffixes for e.g. struct fields -- flags paramFlags -+ elemSize uint64 // size of pointer element type, or 0 if this isn't a pointer - } - - // paramFlags identifies parameter attributes for flags. Most importantly, it -@@ -96,13 +96,7 @@ func (c *compilerContext) expandFormalParamType(t llvm.Type, name string, goType - // failed to expand this parameter: too many fields - } - // TODO: split small arrays -- return []paramInfo{ -- { -- llvmType: t, -- name: name, -- flags: getTypeFlags(goType), -- }, -- } -+ return []paramInfo{c.getParamInfo(t, name, goType)} - } - - // expandFormalParamOffsets returns a list of offsets from the start of an -@@ -152,7 +146,6 @@ func (b *builder) expandFormalParam(v llvm.Value) []llvm.Value { - // Try to flatten a struct type to a list of types. Returns a 1-element slice - // with the passed in type if this is not possible. - func (c *compilerContext) flattenAggregateType(t llvm.Type, name string, goType types.Type) []paramInfo { -- typeFlags := getTypeFlags(goType) - switch t.TypeKind() { - case llvm.StructTypeKind: - var paramInfos []paramInfo -@@ -183,40 +176,37 @@ func (c *compilerContext) flattenAggregateType(t llvm.Type, name string, goType - } - } - subInfos := c.flattenAggregateType(subfield, name+"."+suffix, extractSubfield(goType, i)) -- for i := range subInfos { -- subInfos[i].flags |= typeFlags -- } - paramInfos = append(paramInfos, subInfos...) - } - return paramInfos - default: -- return []paramInfo{ -- { -- llvmType: t, -- name: name, -- flags: typeFlags, -- }, -- } -+ return []paramInfo{c.getParamInfo(t, name, goType)} - } - } - --// getTypeFlags returns the type flags for a given type. It will not recurse --// into sub-types (such as in structs). --func getTypeFlags(t types.Type) paramFlags { -- if t == nil { -- return 0 -+// getParamInfo collects information about a parameter. For example, if this -+// parameter is pointer-like, it will also store the element type for the -+// dereferenceable_or_null attribute. -+func (c *compilerContext) getParamInfo(t llvm.Type, name string, goType types.Type) paramInfo { -+ info := paramInfo{ -+ llvmType: t, -+ name: name, - } -- switch t.Underlying().(type) { -- case *types.Pointer: -- // Pointers in Go must either point to an object or be nil. -- return paramIsDeferenceableOrNull -- case *types.Chan, *types.Map: -- // Channels and maps are implemented as pointers pointing to some -- // object, and follow the same rules as *types.Pointer. -- return paramIsDeferenceableOrNull -- default: -- return 0 -+ if goType != nil { -+ switch underlying := goType.Underlying().(type) { -+ case *types.Pointer: -+ // Pointers in Go must either point to an object or be nil. -+ info.elemSize = c.targetData.TypeAllocSize(c.getLLVMType(underlying.Elem())) -+ case *types.Chan: -+ // Channels are implemented simply as a *runtime.channel. -+ info.elemSize = c.targetData.TypeAllocSize(c.getLLVMRuntimeType("channel")) -+ case *types.Map: -+ // Maps are similar to channels: they are implemented as a -+ // *runtime.hashmap. -+ info.elemSize = c.targetData.TypeAllocSize(c.getLLVMRuntimeType("hashmap")) -+ } - } -+ return info - } - - // extractSubfield extracts a field from a struct, or returns null if this is -diff --git a/compiler/compiler.go b/compiler/compiler.go -index 3d29628c..fc47c29c 100644 ---- a/compiler/compiler.go -+++ b/compiler/compiler.go -@@ -862,7 +862,7 @@ func (c *compilerContext) createPackage(irbuilder llvm.Builder, pkg *ssa.Package - if files, ok := c.embedGlobals[member.Name()]; ok { - c.createEmbedGlobal(member, global, files) - } else if !info.extern { -- global.SetInitializer(llvm.ConstNull(global.Type().ElementType())) -+ global.SetInitializer(llvm.ConstNull(global.GlobalValueType())) - global.SetVisibility(llvm.HiddenVisibility) - if info.section != "" { - global.SetSection(info.section) -@@ -1405,7 +1405,7 @@ func (b *builder) createInstruction(instr ssa.Instruction) { - b.CreateRet(b.getValue(instr.Results[0])) - } else { - // Multiple return values. Put them all in a struct. -- retVal := llvm.ConstNull(b.llvmFn.Type().ElementType().ReturnType()) -+ retVal := llvm.ConstNull(b.llvmFn.GlobalValueType().ReturnType()) - for i, result := range instr.Results { - val := b.getValue(result) - retVal = b.CreateInsertValue(retVal, val, i, "") -@@ -1444,7 +1444,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c - elemsBuf := b.CreateExtractValue(elems, 0, "append.elemsBuf") - elemsPtr := b.CreateBitCast(elemsBuf, b.i8ptrType, "append.srcPtr") - elemsLen := b.CreateExtractValue(elems, 1, "append.elemsLen") -- elemType := srcBuf.Type().ElementType() -+ elemType := b.getLLVMType(argTypes[0].Underlying().(*types.Slice).Elem()) - elemSize := llvm.ConstInt(b.uintptrType, b.targetData.TypeAllocSize(elemType), false) - result := b.createRuntimeCall("sliceAppend", []llvm.Value{srcPtr, elemsPtr, srcLen, srcCap, elemsLen, elemSize}, "append.new") - newPtr := b.CreateExtractValue(result, 0, "append.newPtr") -@@ -1497,7 +1497,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c - srcLen := b.CreateExtractValue(src, 1, "copy.srcLen") - dstBuf := b.CreateExtractValue(dst, 0, "copy.dstArray") - srcBuf := b.CreateExtractValue(src, 0, "copy.srcArray") -- elemType := dstBuf.Type().ElementType() -+ elemType := b.getLLVMType(argTypes[0].Underlying().(*types.Slice).Elem()) - dstBuf = b.CreateBitCast(dstBuf, b.i8ptrType, "copy.dstPtr") - srcBuf = b.CreateBitCast(srcBuf, b.i8ptrType, "copy.srcPtr") - elemSize := llvm.ConstInt(b.uintptrType, b.targetData.TypeAllocSize(elemType), false) -@@ -1637,7 +1637,8 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c - b.uintptrType, - b.uintptrType, - }, false)) -- b.createUnsafeSliceCheck(ptr, len, argTypes[1].Underlying().(*types.Basic)) -+ elementType := b.getLLVMType(argTypes[0].Underlying().(*types.Pointer).Elem()) -+ b.createUnsafeSliceCheck(ptr, len, elementType, argTypes[1].Underlying().(*types.Basic)) - if len.Type().IntTypeWidth() < b.uintptrType.IntTypeWidth() { - // Too small, zero-extend len. - len = b.CreateZExt(len, b.uintptrType, "") -@@ -1712,7 +1713,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) - // Eventually we might be able to eliminate this special case - // entirely. For details, see: - // https://discourse.llvm.org/t/rfc-enabling-wstrict-prototypes-by-default-in-c/60521 -- calleeType = llvm.FunctionType(callee.Type().ElementType().ReturnType(), nil, false) -+ calleeType = llvm.FunctionType(callee.GlobalValueType().ReturnType(), nil, false) - callee = llvm.ConstBitCast(callee, llvm.PointerType(calleeType, b.funcPtrAddrSpace)) - } - case *ssa.MakeClosure: -@@ -3095,7 +3096,7 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) { - } - case token.MUL: // *x, dereference pointer - valueType := b.getLLVMType(unop.X.Type().Underlying().(*types.Pointer).Elem()) -- if b.targetData.TypeAllocSize(x.Type().ElementType()) == 0 { -+ if b.targetData.TypeAllocSize(valueType) == 0 { - // zero-length data - return llvm.ConstNull(valueType), nil - } else if strings.HasSuffix(unop.X.String(), "$funcaddr") { -diff --git a/compiler/func.go b/compiler/func.go -index c6a8802d..4203fdf7 100644 ---- a/compiler/func.go -+++ b/compiler/func.go -@@ -73,7 +73,7 @@ func (c *compilerContext) getFuncType(typ *types.Signature) llvm.Type { - return c.ctx.StructType([]llvm.Type{c.i8ptrType, c.rawVoidFuncType}, false) - } - --// getRawFuncType returns a LLVM function pointer type for a given signature. -+// getRawFuncType returns a LLVM function type for a given signature. - func (c *compilerContext) getRawFuncType(typ *types.Signature) llvm.Type { - // Get the return type. - var returnType llvm.Type -diff --git a/compiler/interface.go b/compiler/interface.go -index 106c327a..2007b7d7 100644 ---- a/compiler/interface.go -+++ b/compiler/interface.go -@@ -86,7 +86,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value { - if _, ok := typ.Underlying().(*types.Pointer); !ok { - ptrTo = c.getTypeCode(types.NewPointer(typ)) - } -- globalValue := llvm.ConstNull(global.Type().ElementType()) -+ globalValue := llvm.ConstNull(global.GlobalValueType()) - if !references.IsNil() { - globalValue = c.builder.CreateInsertValue(globalValue, references, 0, "") - } -@@ -533,7 +533,7 @@ func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFnType - - receiverValue := b.emitPointerUnpack(wrapper.Param(0), []llvm.Type{receiverType})[0] - params := append(b.expandFormalParam(receiverValue), wrapper.Params()[1:]...) -- if llvmFn.Type().ElementType().ReturnType().TypeKind() == llvm.VoidTypeKind { -+ if llvmFnType.ReturnType().TypeKind() == llvm.VoidTypeKind { - b.CreateCall(llvmFnType, llvmFn, params, "") - b.CreateRetVoid() - } else { -diff --git a/compiler/ircheck/check.go b/compiler/ircheck/check.go -index 30c6ee17..e2b7ed51 100644 ---- a/compiler/ircheck/check.go -+++ b/compiler/ircheck/check.go -@@ -70,10 +70,7 @@ func (c *checker) checkType(t llvm.Type, checked map[llvm.Type]struct{}, special - return fmt.Errorf("failed to verify element type of array type %s: %s", t.String(), err.Error()) - } - case llvm.PointerTypeKind: -- // check underlying type -- if err := c.checkType(t.ElementType(), checked, specials); err != nil { -- return fmt.Errorf("failed to verify underlying type of pointer type %s: %s", t.String(), err.Error()) -- } -+ // Pointers can't be checked in an opaque pointer world. - case llvm.VectorTypeKind: - // check element type - if err := c.checkType(t.ElementType(), checked, specials); err != nil { -diff --git a/compiler/symbol.go b/compiler/symbol.go -index 83fe050b..01b3fc37 100644 ---- a/compiler/symbol.go -+++ b/compiler/symbol.go -@@ -83,7 +83,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value) - // Add an extra parameter as the function context. This context is used in - // closures and bound methods, but should be optimized away when not used. - if !info.exported { -- paramInfos = append(paramInfos, paramInfo{llvmType: c.i8ptrType, name: "context", flags: 0}) -+ paramInfos = append(paramInfos, paramInfo{llvmType: c.i8ptrType, name: "context", elemSize: 0}) - } - - var paramTypes []llvm.Type -@@ -112,17 +112,8 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value) - - dereferenceableOrNullKind := llvm.AttributeKindID("dereferenceable_or_null") - for i, info := range paramInfos { -- if info.flags¶mIsDeferenceableOrNull == 0 { -- continue -- } -- if info.llvmType.TypeKind() == llvm.PointerTypeKind { -- el := info.llvmType.ElementType() -- size := c.targetData.TypeAllocSize(el) -- if size == 0 { -- // dereferenceable_or_null(0) appears to be illegal in LLVM. -- continue -- } -- dereferenceableOrNull := c.ctx.CreateEnumAttribute(dereferenceableOrNullKind, size) -+ if info.elemSize != 0 { -+ dereferenceableOrNull := c.ctx.CreateEnumAttribute(dereferenceableOrNullKind, info.elemSize) - llvmFn.AddAttributeAtIndex(i+1, dereferenceableOrNull) - } - } -diff --git a/interp/compiler.go b/interp/compiler.go -index 20723c64..ffef69e5 100644 ---- a/interp/compiler.go -+++ b/interp/compiler.go -@@ -209,7 +209,7 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function { - case llvm.Alloca: - // Alloca allocates stack space for local variables. - numElements := r.getValue(inst.llvmInst.Operand(0)).(literalValue).value.(uint32) -- elementSize := r.targetData.TypeAllocSize(inst.llvmInst.Type().ElementType()) -+ elementSize := r.targetData.TypeAllocSize(inst.llvmInst.AllocatedType()) - inst.operands = []value{ - literalValue{elementSize * uint64(numElements)}, - } -@@ -218,17 +218,17 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function { - inst.name = llvmInst.Name() - ptr := llvmInst.Operand(0) - n := llvmInst.OperandsCount() -- elementType := ptr.Type().ElementType() -+ elementType := llvmInst.GEPSourceElementType() - // gep: [source ptr, dest value size, pairs of indices...] - inst.operands = []value{ - r.getValue(ptr), -- literalValue{r.targetData.TypeAllocSize(llvmInst.Type().ElementType())}, - r.getValue(llvmInst.Operand(1)), - literalValue{r.targetData.TypeAllocSize(elementType)}, - } - for i := 2; i < n; i++ { - operand := r.getValue(llvmInst.Operand(i)) -- if elementType.TypeKind() == llvm.StructTypeKind { -+ switch elementType.TypeKind() { -+ case llvm.StructTypeKind: - index := operand.(literalValue).value.(uint32) - elementOffset := r.targetData.ElementOffset(elementType, int(index)) - // Encode operands in a special way. The elementOffset -@@ -242,12 +242,15 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function { - // runtime. - inst.operands = append(inst.operands, literalValue{elementOffset}, literalValue{^uint64(index)}) - elementType = elementType.StructElementTypes()[index] -- } else { -+ case llvm.ArrayTypeKind: - elementType = elementType.ElementType() - elementSize := r.targetData.TypeAllocSize(elementType) - elementSizeOperand := literalValue{elementSize} - // Add operand * elementSizeOperand bytes to the pointer. - inst.operands = append(inst.operands, operand, elementSizeOperand) -+ default: -+ // This should be unreachable. -+ panic("unknown type: " + elementType.String()) - } - } - case llvm.BitCast, llvm.IntToPtr, llvm.PtrToInt: -@@ -267,10 +270,12 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function { - case llvm.StructTypeKind: - offset += r.targetData.ElementOffset(indexingType, int(index)) - indexingType = indexingType.StructElementTypes()[index] -- default: // ArrayTypeKind -+ case llvm.ArrayTypeKind: - indexingType = indexingType.ElementType() - elementSize := r.targetData.TypeAllocSize(indexingType) - offset += elementSize * uint64(index) -+ default: -+ panic("unknown type kind") // unreachable - } - } - size := r.targetData.TypeAllocSize(inst.llvmInst.Type()) -@@ -290,10 +295,12 @@ func (r *runner) compileFunction(llvmFn llvm.Value) *function { - case llvm.StructTypeKind: - offset += r.targetData.ElementOffset(indexingType, int(index)) - indexingType = indexingType.StructElementTypes()[index] -- default: // ArrayTypeKind -+ case llvm.ArrayTypeKind: - indexingType = indexingType.ElementType() - elementSize := r.targetData.TypeAllocSize(indexingType) - offset += elementSize * uint64(index) -+ default: -+ panic("unknown type kind") // unreachable - } - } - // insertvalue [agg, elt, byteOffset] -diff --git a/interp/interp.go b/interp/interp.go -index 856f08b1..7833dfe9 100644 ---- a/interp/interp.go -+++ b/interp/interp.go -@@ -156,7 +156,7 @@ func Run(mod llvm.Module, timeout time.Duration, debug bool) error { - if obj.constant { - continue // constant buffers can't have been modified - } -- initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.Type().ElementType(), &mem) -+ initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.GlobalValueType(), &mem) - if err == errInvalidPtrToIntSize { - // This can happen when a previous interp run did not have the - // correct LLVM type for a global and made something up. In that -@@ -190,7 +190,7 @@ func Run(mod llvm.Module, timeout time.Duration, debug bool) error { - if err != nil { - return err - } -- if checks && initializer.Type() != obj.llvmGlobal.Type().ElementType() { -+ if checks && initializer.Type() != obj.llvmGlobal.GlobalValueType() { - panic("initializer type mismatch") - } - obj.llvmGlobal.SetInitializer(initializer) -@@ -213,7 +213,7 @@ func RunFunc(fn llvm.Value, timeout time.Duration, debug bool) error { - r.pkgName = initName[:len(initName)-len(".init")] - - // Create new function with the interp result. -- newFn := llvm.AddFunction(mod, fn.Name()+".tmp", fn.Type().ElementType()) -+ newFn := llvm.AddFunction(mod, fn.Name()+".tmp", fn.GlobalValueType()) - newFn.SetLinkage(fn.Linkage()) - newFn.SetVisibility(fn.Visibility()) - entry := mod.Context().AddBasicBlock(newFn, "entry") -@@ -263,11 +263,11 @@ func RunFunc(fn llvm.Value, timeout time.Duration, debug bool) error { - if obj.constant { - continue // constant, so can't have been modified - } -- initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.Type().ElementType(), &mem) -+ initializer, err := obj.buffer.toLLVMValue(obj.llvmGlobal.GlobalValueType(), &mem) - if err != nil { - return err - } -- if checks && initializer.Type() != obj.llvmGlobal.Type().ElementType() { -+ if checks && initializer.Type() != obj.llvmGlobal.GlobalValueType() { - panic("initializer type mismatch") - } - obj.llvmGlobal.SetInitializer(initializer) -diff --git a/interp/interpreter.go b/interp/interpreter.go -index 8c783a70..c438b4b6 100644 ---- a/interp/interpreter.go -+++ b/interp/interpreter.go -@@ -655,7 +655,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent - // GetElementPtr does pointer arithmetic, changing the offset of the - // pointer into the underlying object. - var offset uint64 -- for i := 2; i < len(operands); i += 2 { -+ for i := 1; i < len(operands); i += 2 { - index := operands[i].Uint() - elementSize := operands[i+1].Uint() - if int64(elementSize) < 0 { -diff --git a/interp/memory.go b/interp/memory.go -index 6a537bad..82ab716d 100644 ---- a/interp/memory.go -+++ b/interp/memory.go -@@ -808,14 +808,17 @@ func (v rawValue) rawLLVMValue(mem *memoryView) (llvm.Value, error) { - if err != nil { - return llvm.Value{}, err - } -- elementType := field.Type().ElementType() -- if elementType.TypeKind() == llvm.StructTypeKind { -- // There are some special pointer types that should be used as a -- // ptrtoint, so that they can be used in certain optimizations. -- name := elementType.StructName() -- if name == "runtime.typecodeID" || name == "runtime.funcValueWithSignature" { -- uintptrType := ctx.IntType(int(mem.r.pointerSize) * 8) -- field = llvm.ConstPtrToInt(field, uintptrType) -+ if !field.IsAGlobalVariable().IsNil() { -+ elementType := field.GlobalValueType() -+ if elementType.TypeKind() == llvm.StructTypeKind { -+ // There are some special pointer types that should be used -+ // as a ptrtoint, so that they can be used in certain -+ // optimizations. -+ name := elementType.StructName() -+ if name == "runtime.typecodeID" || name == "runtime.funcValueWithSignature" { -+ uintptrType := ctx.IntType(int(mem.r.pointerSize) * 8) -+ field = llvm.ConstPtrToInt(field, uintptrType) -+ } - } - } - structFields = append(structFields, field) -@@ -998,7 +1001,7 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) { - ptr := llvmValue.Operand(0) - index := llvmValue.Operand(1) - numOperands := llvmValue.OperandsCount() -- elementType := ptr.Type().ElementType() -+ elementType := llvmValue.GEPSourceElementType() - totalOffset := r.targetData.TypeAllocSize(elementType) * index.ZExtValue() - for i := 2; i < numOperands; i++ { - indexValue := llvmValue.Operand(i) -@@ -1173,7 +1176,7 @@ func (r *runner) getValue(llvmValue llvm.Value) value { - r.globals[llvmValue] = index - r.objects = append(r.objects, obj) - if !llvmValue.IsAGlobalVariable().IsNil() { -- obj.size = uint32(r.targetData.TypeAllocSize(llvmValue.Type().ElementType())) -+ obj.size = uint32(r.targetData.TypeAllocSize(llvmValue.GlobalValueType())) - if initializer := llvmValue.Initializer(); !initializer.IsNil() { - obj.buffer = r.getValue(initializer) - obj.constant = llvmValue.IsGlobalConstant() -diff --git a/transform/allocs.go b/transform/allocs.go -index af7c70b2..5be7df2d 100644 ---- a/transform/allocs.go -+++ b/transform/allocs.go -@@ -124,7 +124,7 @@ func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, logger func(tok - alloca.SetAlignment(alignment) - - // Zero the allocation inside the block where the value was originally allocated. -- zero := llvm.ConstNull(alloca.Type().ElementType()) -+ zero := llvm.ConstNull(alloca.AllocatedType()) - builder.SetInsertPointBefore(bitcast) - store := builder.CreateStore(zero, alloca) - store.SetAlignment(alignment) -diff --git a/transform/gc.go b/transform/gc.go -index 514fb1bf..e2d23987 100644 ---- a/transform/gc.go -+++ b/transform/gc.go -@@ -18,7 +18,7 @@ func MakeGCStackSlots(mod llvm.Module) bool { - stackChainStart := mod.NamedGlobal("runtime.stackChainStart") - if !stackChainStart.IsNil() { - stackChainStart.SetLinkage(llvm.InternalLinkage) -- stackChainStart.SetInitializer(llvm.ConstNull(stackChainStart.Type().ElementType())) -+ stackChainStart.SetInitializer(llvm.ConstNull(stackChainStart.GlobalValueType())) - stackChainStart.SetGlobalConstant(true) - } - return false -@@ -96,7 +96,7 @@ func MakeGCStackSlots(mod llvm.Module) bool { - return false - } - stackChainStart.SetLinkage(llvm.InternalLinkage) -- stackChainStartType := stackChainStart.Type().ElementType() -+ stackChainStartType := stackChainStart.GlobalValueType() - stackChainStart.SetInitializer(llvm.ConstNull(stackChainStartType)) - - // Iterate until runtime.trackPointer has no uses left. -diff --git a/transform/interface-lowering.go b/transform/interface-lowering.go -index f28443dc..9e2ffa90 100644 ---- a/transform/interface-lowering.go -+++ b/transform/interface-lowering.go -@@ -423,7 +423,7 @@ func (p *lowerInterfacesPass) defineInterfaceImplementsFunc(fn llvm.Value, itf * - func (p *lowerInterfacesPass) defineInterfaceMethodFunc(fn llvm.Value, itf *interfaceInfo, signature *signatureInfo) { - context := fn.LastParam() - actualType := llvm.PrevParam(context) -- returnType := fn.Type().ElementType().ReturnType() -+ returnType := fn.GlobalValueType().ReturnType() - context.SetName("context") - actualType.SetName("actualType") - fn.SetLinkage(llvm.InternalLinkage) -diff --git a/transform/llvm.go b/transform/llvm.go -index 17968f8a..7042b32d 100644 ---- a/transform/llvm.go -+++ b/transform/llvm.go -@@ -66,7 +66,7 @@ func getGlobalBytes(global llvm.Value, builder llvm.Builder) []byte { - // function used for creating reflection sidetables, for example. - func replaceGlobalIntWithArray(mod llvm.Module, name string, buf interface{}) llvm.Value { - oldGlobal := mod.NamedGlobal(name) -- globalType, global := makeGlobalArray(mod, buf, name+".tmp", oldGlobal.Type().ElementType()) -+ globalType, global := makeGlobalArray(mod, buf, name+".tmp", oldGlobal.GlobalValueType()) - gep := llvm.ConstGEP(globalType, global, []llvm.Value{ - llvm.ConstInt(mod.Context().Int32Type(), 0, false), - llvm.ConstInt(mod.Context().Int32Type(), 0, false), -diff --git a/transform/wasm-abi.go b/transform/wasm-abi.go -index 064e38f4..83a16d85 100644 ---- a/transform/wasm-abi.go -+++ b/transform/wasm-abi.go -@@ -50,7 +50,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error { - paramTypes := []llvm.Type{} - - // Check return type for 64-bit integer. -- fnType := fn.Type().ElementType() -+ fnType := fn.GlobalValueType() - returnType := fnType.ReturnType() - if returnType == int64Type { - hasInt64 = true --- -2.36.1 - diff --git a/0015-transform-fix-memory-corruption-issues.patch b/0015-transform-fix-memory-corruption-issues.patch deleted file mode 100644 index d209b69..0000000 --- a/0015-transform-fix-memory-corruption-issues.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 6bf7aa1623b6d7d9a269df876453af22b1c54c2d Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Wed, 12 Oct 2022 21:46:50 +0200 -Subject: [PATCH 15/18] transform: fix memory corruption issues - -There was a bug in the wasm ABI lowering pass (found using -AddressSanitizer on LLVM 15) that resulted in a rather subtle memory -corruption. This commit fixes this issues. - -Signed-off-by: Elliott Sales de Andrade ---- - transform/wasm-abi.go | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/transform/wasm-abi.go b/transform/wasm-abi.go -index 83a16d85..08122a3e 100644 ---- a/transform/wasm-abi.go -+++ b/transform/wasm-abi.go -@@ -88,8 +88,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error { - // Update all users to call the external function. - // The old $i64wrapper function could be removed, but it may as well - // be left in place. -- for use := fn.FirstUse(); !use.IsNil(); use = use.NextUse() { -- call := use.User() -+ for _, call := range getUses(fn) { - entryBlockBuilder.SetInsertPointBefore(call.InstructionParent().Parent().EntryBasicBlock().FirstInstruction()) - builder.SetInsertPointBefore(call) - callParams := []llvm.Value{} --- -2.36.1 - diff --git a/0016-riscv-add-target-abi-metadata-flag.patch b/0016-riscv-add-target-abi-metadata-flag.patch deleted file mode 100644 index e194223..0000000 --- a/0016-riscv-add-target-abi-metadata-flag.patch +++ /dev/null @@ -1,193 +0,0 @@ -From 003963ddc796960ce498361409a9d121366b1c42 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Wed, 12 Oct 2022 22:05:38 +0000 -Subject: [PATCH 16/18] riscv: add "target-abi" metadata flag - -This flag is necessary in LLVM 15 because it appears that LLVM 15 has -changed the default target ABI from lp64 to lp64d. This results in a -linker failure. Setting the "target-abi" forces the RISC-V backend to -use the intended target ABI. - -Signed-off-by: Elliott Sales de Andrade ---- - builder/build.go | 1 + - builder/library.go | 7 +++++-- - compileopts/config.go | 13 +++++++++++++ - compileopts/target.go | 1 + - compiler/compiler.go | 13 +++++++++++++ - compiler/compiler_test.go | 1 + - targets/riscv32.json | 4 ++-- - targets/riscv64.json | 4 ++-- - 8 files changed, 38 insertions(+), 6 deletions(-) - -diff --git a/builder/build.go b/builder/build.go -index 488ee823..4818185f 100644 ---- a/builder/build.go -+++ b/builder/build.go -@@ -170,6 +170,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil - Triple: config.Triple(), - CPU: config.CPU(), - Features: config.Features(), -+ ABI: config.ABI(), - GOOS: config.GOOS(), - GOARCH: config.GOARCH(), - CodeModel: config.CodeModel(), -diff --git a/builder/library.go b/builder/library.go -index 385f1610..87822d15 100644 ---- a/builder/library.go -+++ b/builder/library.go -@@ -155,6 +155,9 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ - args = append(args, "-mcpu="+cpu) - } - } -+ if config.ABI() != "" { -+ args = append(args, "-mabi="+config.ABI()) -+ } - if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") { - if strings.Split(target, "-")[2] == "linux" { - args = append(args, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables") -@@ -170,10 +173,10 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ - args = append(args, "-mdouble=64") - } - if strings.HasPrefix(target, "riscv32-") { -- args = append(args, "-march=rv32imac", "-mabi=ilp32", "-fforce-enable-int128") -+ args = append(args, "-march=rv32imac", "-fforce-enable-int128") - } - if strings.HasPrefix(target, "riscv64-") { -- args = append(args, "-march=rv64gc", "-mabi=lp64") -+ args = append(args, "-march=rv64gc") - } - if strings.HasPrefix(target, "xtensa") { - // Hack to work around an issue in the Xtensa port: -diff --git a/compileopts/config.go b/compileopts/config.go -index cd49283d..80ea8cff 100644 ---- a/compileopts/config.go -+++ b/compileopts/config.go -@@ -47,6 +47,12 @@ func (c *Config) Features() string { - return c.Target.Features + "," + c.Options.LLVMFeatures - } - -+// ABI returns the -mabi= flag for this target (like -mabi=lp64). A zero-length -+// string is returned if the target doesn't specify an ABI. -+func (c *Config) ABI() string { -+ return c.Target.ABI -+} -+ - // GOOS returns the GOOS of the target. This might not always be the actual OS: - // for example, bare-metal targets will usually pretend to be linux to get the - // standard library to compile. -@@ -230,6 +236,9 @@ func (c *Config) LibcPath(name string) (path string, precompiled bool) { - if c.CPU() != "" { - archname += "-" + c.CPU() - } -+ if c.ABI() != "" { -+ archname += "-" + c.ABI() -+ } - - // Try to load a precompiled library. - precompiledDir := filepath.Join(goenv.Get("TINYGOROOT"), "pkg", archname, name) -@@ -335,6 +344,10 @@ func (c *Config) CFlags() []string { - cflags = append(cflags, "-mcpu="+c.Target.CPU) - } - } -+ // Set the -mabi flag, if needed. -+ if c.ABI() != "" { -+ cflags = append(cflags, "-mabi="+c.ABI()) -+ } - return cflags - } - -diff --git a/compileopts/target.go b/compileopts/target.go -index 865b8afe..c26c870e 100644 ---- a/compileopts/target.go -+++ b/compileopts/target.go -@@ -26,6 +26,7 @@ type TargetSpec struct { - Inherits []string `json:"inherits"` - Triple string `json:"llvm-target"` - CPU string `json:"cpu"` -+ ABI string `json:"target-abi"` // rougly equivalent to -mabi= flag - Features string `json:"features"` - GOOS string `json:"goos"` - GOARCH string `json:"goarch"` -diff --git a/compiler/compiler.go b/compiler/compiler.go -index fc47c29c..8b6e8661 100644 ---- a/compiler/compiler.go -+++ b/compiler/compiler.go -@@ -41,6 +41,7 @@ type Config struct { - Triple string - CPU string - Features string -+ ABI string - GOOS string - GOARCH string - CodeModel string -@@ -321,6 +322,18 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package, - c.dibuilder.Destroy() - } - -+ // Add the "target-abi" flag, which is necessary on RISC-V otherwise it will -+ // pick one that doesn't match the -mabi Clang flag. -+ if c.ABI != "" { -+ c.mod.AddNamedMetadataOperand("llvm.module.flags", -+ c.ctx.MDNode([]llvm.Metadata{ -+ llvm.ConstInt(c.ctx.Int32Type(), 1, false).ConstantAsMetadata(), // Error on mismatch -+ c.ctx.MDString("target-abi"), -+ c.ctx.MDString(c.ABI), -+ }), -+ ) -+ } -+ - return c.mod, c.diagnostics - } - -diff --git a/compiler/compiler_test.go b/compiler/compiler_test.go -index 2ed26921..a5cd9c6b 100644 ---- a/compiler/compiler_test.go -+++ b/compiler/compiler_test.go -@@ -73,6 +73,7 @@ func TestCompiler(t *testing.T) { - compilerConfig := &Config{ - Triple: config.Triple(), - Features: config.Features(), -+ ABI: config.ABI(), - GOOS: config.GOOS(), - GOARCH: config.GOARCH(), - CodeModel: config.CodeModel(), -diff --git a/targets/riscv32.json b/targets/riscv32.json -index c3c8dff5..a2878089 100644 ---- a/targets/riscv32.json -+++ b/targets/riscv32.json -@@ -1,12 +1,12 @@ - { - "inherits": ["riscv"], - "llvm-target": "riscv32-unknown-none", -+ "target-abi": "ilp32", - "build-tags": ["tinygo.riscv32"], - "scheduler": "tasks", - "default-stack-size": 2048, - "cflags": [ -- "-march=rv32imac", -- "-mabi=ilp32" -+ "-march=rv32imac" - ], - "ldflags": [ - "-melf32lriscv" -diff --git a/targets/riscv64.json b/targets/riscv64.json -index c2378e97..fc45c91c 100644 ---- a/targets/riscv64.json -+++ b/targets/riscv64.json -@@ -1,10 +1,10 @@ - { - "inherits": ["riscv"], - "llvm-target": "riscv64-unknown-none", -+ "target-abi": "lp64", - "build-tags": ["tinygo.riscv64"], - "cflags": [ -- "-march=rv64gc", -- "-mabi=lp64" -+ "-march=rv64gc" - ], - "ldflags": [ - "-melf64lriscv" --- -2.36.1 - diff --git a/0017-interp-add-support-for-constant-icmp-instructions.patch b/0017-interp-add-support-for-constant-icmp-instructions.patch deleted file mode 100644 index 500803c..0000000 --- a/0017-interp-add-support-for-constant-icmp-instructions.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 76f42a3fac44ac6d07c53b10ddadb683ca019684 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Tue, 18 Oct 2022 23:16:36 +0000 -Subject: [PATCH 17/18] interp: add support for constant icmp instructions - -These instructions sometimes pop up in LLVM 15, but they never occured -in LLVM 14. Implementing them is relatively straightforward: simply -generalize the code that already exists for llvm.ICmp interpreting. - -Signed-off-by: Elliott Sales de Andrade ---- - interp/interpreter.go | 84 +++++++++++++++++--------------- - interp/memory.go | 11 +++++ - interp/testdata/consteval.ll | 15 ++++++ - interp/testdata/consteval.out.ll | 1 + - 4 files changed, 73 insertions(+), 38 deletions(-) - -diff --git a/interp/interpreter.go b/interp/interpreter.go -index c438b4b6..83fd2cd9 100644 ---- a/interp/interpreter.go -+++ b/interp/interpreter.go -@@ -723,46 +723,9 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent - locals[inst.localIndex] = newagg - case llvm.ICmp: - predicate := llvm.IntPredicate(operands[2].(literalValue).value.(uint8)) -- var result bool - lhs := operands[0] - rhs := operands[1] -- switch predicate { -- case llvm.IntEQ, llvm.IntNE: -- lhsPointer, lhsErr := lhs.asPointer(r) -- rhsPointer, rhsErr := rhs.asPointer(r) -- if (lhsErr == nil) != (rhsErr == nil) { -- // Fast path: only one is a pointer, so they can't be equal. -- result = false -- } else if lhsErr == nil { -- // Both must be nil, so both are pointers. -- // Compare them directly. -- result = lhsPointer.equal(rhsPointer) -- } else { -- // Fall back to generic comparison. -- result = lhs.asRawValue(r).equal(rhs.asRawValue(r)) -- } -- if predicate == llvm.IntNE { -- result = !result -- } -- case llvm.IntUGT: -- result = lhs.Uint() > rhs.Uint() -- case llvm.IntUGE: -- result = lhs.Uint() >= rhs.Uint() -- case llvm.IntULT: -- result = lhs.Uint() < rhs.Uint() -- case llvm.IntULE: -- result = lhs.Uint() <= rhs.Uint() -- case llvm.IntSGT: -- result = lhs.Int() > rhs.Int() -- case llvm.IntSGE: -- result = lhs.Int() >= rhs.Int() -- case llvm.IntSLT: -- result = lhs.Int() < rhs.Int() -- case llvm.IntSLE: -- result = lhs.Int() <= rhs.Int() -- default: -- return nil, mem, r.errorAt(inst, errors.New("interp: unsupported icmp")) -- } -+ result := r.interpretICmp(lhs, rhs, predicate) - if result { - locals[inst.localIndex] = literalValue{uint8(1)} - } else { -@@ -948,6 +911,51 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent - return nil, mem, r.errorAt(bb.instructions[len(bb.instructions)-1], errors.New("interp: reached end of basic block without terminator")) - } - -+// Interpret an icmp instruction. Doesn't have side effects, only returns the -+// output of the comparison. -+func (r *runner) interpretICmp(lhs, rhs value, predicate llvm.IntPredicate) bool { -+ switch predicate { -+ case llvm.IntEQ, llvm.IntNE: -+ var result bool -+ lhsPointer, lhsErr := lhs.asPointer(r) -+ rhsPointer, rhsErr := rhs.asPointer(r) -+ if (lhsErr == nil) != (rhsErr == nil) { -+ // Fast path: only one is a pointer, so they can't be equal. -+ result = false -+ } else if lhsErr == nil { -+ // Both must be nil, so both are pointers. -+ // Compare them directly. -+ result = lhsPointer.equal(rhsPointer) -+ } else { -+ // Fall back to generic comparison. -+ result = lhs.asRawValue(r).equal(rhs.asRawValue(r)) -+ } -+ if predicate == llvm.IntNE { -+ result = !result -+ } -+ return result -+ case llvm.IntUGT: -+ return lhs.Uint() > rhs.Uint() -+ case llvm.IntUGE: -+ return lhs.Uint() >= rhs.Uint() -+ case llvm.IntULT: -+ return lhs.Uint() < rhs.Uint() -+ case llvm.IntULE: -+ return lhs.Uint() <= rhs.Uint() -+ case llvm.IntSGT: -+ return lhs.Int() > rhs.Int() -+ case llvm.IntSGE: -+ return lhs.Int() >= rhs.Int() -+ case llvm.IntSLT: -+ return lhs.Int() < rhs.Int() -+ case llvm.IntSLE: -+ return lhs.Int() <= rhs.Int() -+ default: -+ // _should_ be unreachable, until LLVM adds new icmp operands (unlikely) -+ panic("interp: unsupported icmp") -+ } -+} -+ - func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, mem *memoryView, indent string) *Error { - numOperands := inst.llvmInst.OperandsCount() - operands := make([]llvm.Value, numOperands) -diff --git a/interp/memory.go b/interp/memory.go -index 82ab716d..248825f6 100644 ---- a/interp/memory.go -+++ b/interp/memory.go -@@ -1031,6 +1031,17 @@ func (v *rawValue) set(llvmValue llvm.Value, r *runner) { - for i := uint32(0); i < ptrSize; i++ { - v.buf[i] = ptrValue.pointer - } -+ case llvm.ICmp: -+ size := r.targetData.TypeAllocSize(llvmValue.Operand(0).Type()) -+ lhs := newRawValue(uint32(size)) -+ rhs := newRawValue(uint32(size)) -+ lhs.set(llvmValue.Operand(0), r) -+ rhs.set(llvmValue.Operand(1), r) -+ if r.interpretICmp(lhs, rhs, llvmValue.IntPredicate()) { -+ v.buf[0] = 1 // result is true -+ } else { -+ v.buf[0] = 0 // result is false -+ } - default: - llvmValue.Dump() - println() -diff --git a/interp/testdata/consteval.ll b/interp/testdata/consteval.ll -index 9afb9ff7..d0c0e3b6 100644 ---- a/interp/testdata/consteval.ll -+++ b/interp/testdata/consteval.ll -@@ -3,6 +3,7 @@ target triple = "x86_64--linux" - - @intToPtrResult = global i8 0 - @ptrToIntResult = global i8 0 -+@icmpResult = global i8 0 - @someArray = internal global {i16, i8, i8} zeroinitializer - @someArrayPointer = global i8* zeroinitializer - -@@ -15,6 +16,7 @@ define internal void @main.init() { - call void @testIntToPtr() - call void @testPtrToInt() - call void @testConstGEP() -+ call void @testICmp() - ret void - } - -@@ -48,3 +50,16 @@ define internal void @testConstGEP() { - store i8* getelementptr inbounds (i8, i8* bitcast ({i16, i8, i8}* @someArray to i8*), i32 2), i8** @someArrayPointer - ret void - } -+ -+define internal void @testICmp() { -+ br i1 icmp eq (i64 ptrtoint (i8* @ptrToIntResult to i64), i64 0), label %equal, label %unequal -+equal: -+ ; should not be reached -+ store i8 1, i8* @icmpResult -+ ret void -+unequal: -+ ; should be reached -+ store i8 2, i8* @icmpResult -+ ret void -+ ret void -+} -diff --git a/interp/testdata/consteval.out.ll b/interp/testdata/consteval.out.ll -index 5fac449e..08d74c85 100644 ---- a/interp/testdata/consteval.out.ll -+++ b/interp/testdata/consteval.out.ll -@@ -3,6 +3,7 @@ target triple = "x86_64--linux" - - @intToPtrResult = local_unnamed_addr global i8 2 - @ptrToIntResult = local_unnamed_addr global i8 2 -+@icmpResult = local_unnamed_addr global i8 2 - @someArray = internal global { i16, i8, i8 } zeroinitializer - @someArrayPointer = local_unnamed_addr global i8* getelementptr inbounds ({ i16, i8, i8 }, { i16, i8, i8 }* @someArray, i64 0, i32 1) - --- -2.36.1 - diff --git a/0018-ci-add-support-for-LLVM-15.patch b/0018-ci-add-support-for-LLVM-15.patch deleted file mode 100644 index 7c17787..0000000 --- a/0018-ci-add-support-for-LLVM-15.patch +++ /dev/null @@ -1,3490 +0,0 @@ -From 6557b534a1c2195cb7f2a465f8dc36662525f764 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Thu, 22 Sep 2022 13:39:51 +0200 -Subject: [PATCH 18/18] ci: add support for LLVM 15 - -This commit switches to LLVM 15 everywhere by default, while still -keeping LLVM 14 support. - -Signed-off-by: Elliott Sales de Andrade ---- - .github/workflows/build-macos.yml | 6 +- - .github/workflows/linux.yml | 16 +- - .github/workflows/windows.yml | 4 +- - Makefile | 6 +- - builder/cc1as.cpp | 21 +- - builder/cc1as.h | 7 + - builder/musl.go | 10 +- - cgo/libclang_config_llvm14.go | 4 +- - cgo/libclang_config_llvm15.go | 16 ++ - compiler/func.go | 15 +- - compiler/intrinsics.go | 11 +- - compiler/llvmutil/llvm.go | 33 ++- - compiler/symbol.go | 11 +- - compiler/testdata/basic.go | 12 +- - compiler/testdata/basic.ll | 69 +++-- - compiler/testdata/channel.ll | 110 +++----- - compiler/testdata/defer-cortex-m-qemu.ll | 267 +++++++++--------- - compiler/testdata/float.ll | 22 +- - compiler/testdata/func.ll | 23 +- - compiler/testdata/gc.ll | 176 ++++++------ - .../testdata/goroutine-cortex-m-qemu-tasks.ll | 189 ++++++------- - compiler/testdata/goroutine-wasm-asyncify.ll | 206 ++++++-------- - compiler/testdata/interface.ll | 83 +++--- - compiler/testdata/pointer.ll | 68 +++-- - compiler/testdata/pragma.ll | 18 +- - compiler/testdata/slice.ll | 264 ++++++++--------- - compiler/testdata/string.ll | 50 ++-- - go.mod | 2 +- - go.sum | 4 +- - interp/interpreter.go | 16 +- - src/runtime/runtime.go | 6 +- - targets/esp32c3.json | 2 +- - targets/fe310.json | 2 +- - targets/k210.json | 2 +- - targets/riscv-qemu.json | 2 +- - transform/interface-lowering.go | 4 +- - transform/interrupt.go | 3 +- - transform/llvm.go | 6 + - transform/reflect.go | 11 +- - transform/rtcalls.go | 5 +- - 40 files changed, 898 insertions(+), 884 deletions(-) - create mode 100644 cgo/libclang_config_llvm15.go - -diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml -index 2059574a..9197ea3c 100644 ---- a/.github/workflows/build-macos.yml -+++ b/.github/workflows/build-macos.yml -@@ -40,7 +40,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-source - with: -- key: llvm-source-14-macos-v1 -+ key: llvm-source-15-macos-v1 - path: | - llvm-project/clang/lib/Headers - llvm-project/clang/include -@@ -54,7 +54,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-build - with: -- key: llvm-build-14-macos-v1 -+ key: llvm-build-15-macos-v1 - path: llvm-build - - name: Build LLVM - if: steps.cache-llvm-build.outputs.cache-hit != 'true' -@@ -108,7 +108,7 @@ jobs: - - name: Install LLVM - shell: bash - run: | -- HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@14 -+ HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@15 - - name: Checkout - uses: actions/checkout@v2 - - name: Install Go -diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml -index 8fc52717..cf26a4f2 100644 ---- a/.github/workflows/linux.yml -+++ b/.github/workflows/linux.yml -@@ -43,7 +43,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-source - with: -- key: llvm-source-14-linux-alpine-v1 -+ key: llvm-source-15-linux-alpine-v1 - path: | - llvm-project/clang/lib/Headers - llvm-project/clang/include -@@ -57,7 +57,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-build - with: -- key: llvm-build-14-linux-alpine-v1 -+ key: llvm-build-15-linux-alpine-v1 - path: llvm-build - - name: Build LLVM - if: steps.cache-llvm-build.outputs.cache-hit != 'true' -@@ -185,7 +185,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-source - with: -- key: llvm-source-14-linux-asserts-v2 -+ key: llvm-source-15-linux-asserts-v1 - path: | - llvm-project/clang/lib/Headers - llvm-project/clang/include -@@ -199,7 +199,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-build - with: -- key: llvm-build-14-linux-asserts-v1 -+ key: llvm-build-15-linux-asserts-v1 - path: llvm-build - - name: Build LLVM - if: steps.cache-llvm-build.outputs.cache-hit != 'true' -@@ -277,7 +277,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-source - with: -- key: llvm-source-14-linux-v2 -+ key: llvm-source-15-linux-v1 - path: | - llvm-project/clang/lib/Headers - llvm-project/clang/include -@@ -291,7 +291,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-build - with: -- key: llvm-build-14-linux-arm-v1 -+ key: llvm-build-15-linux-arm-v1 - path: llvm-build - - name: Build LLVM - if: steps.cache-llvm-build.outputs.cache-hit != 'true' -@@ -377,7 +377,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-source - with: -- key: llvm-source-14-linux-v1 -+ key: llvm-source-15-linux-v1 - path: | - llvm-project/clang/lib/Headers - llvm-project/clang/include -@@ -391,7 +391,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-build - with: -- key: llvm-build-14-linux-arm64-v1 -+ key: llvm-build-15-linux-arm64-v1 - path: llvm-build - - name: Build LLVM - if: steps.cache-llvm-build.outputs.cache-hit != 'true' -diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml -index 76c010cf..2ea1dc8c 100644 ---- a/.github/workflows/windows.yml -+++ b/.github/workflows/windows.yml -@@ -35,7 +35,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-source - with: -- key: llvm-source-14-windows-v2 -+ key: llvm-source-15-windows-v1 - path: | - llvm-project/clang/lib/Headers - llvm-project/clang/include -@@ -49,7 +49,7 @@ jobs: - uses: actions/cache@v3 - id: cache-llvm-build - with: -- key: llvm-build-14-windows-v2 -+ key: llvm-build-15-windows-v1 - path: llvm-build - - name: Build LLVM - if: steps.cache-llvm-build.outputs.cache-hit != 'true' -diff --git a/Makefile b/Makefile -index 1ef11d29..89927961 100644 ---- a/Makefile -+++ b/Makefile -@@ -107,7 +107,7 @@ endif - - .PHONY: all tinygo test $(LLVM_BUILDDIR) llvm-source clean fmt gen-device gen-device-nrf gen-device-nxp gen-device-avr gen-device-rp - --LLVM_COMPONENTS = all-targets analysis asmparser asmprinter bitreader bitwriter codegen core coroutines coverage debuginfodwarf debuginfopdb executionengine frontendopenmp instrumentation interpreter ipo irreader libdriver linker lto mc mcjit objcarcopts option profiledata scalaropts support target windowsmanifest -+LLVM_COMPONENTS = all-targets analysis asmparser asmprinter bitreader bitwriter codegen core coroutines coverage debuginfodwarf debuginfopdb executionengine frontendopenmp instrumentation interpreter ipo irreader libdriver linker lto mc mcjit objcarcopts option profiledata scalaropts support target windowsdriver windowsmanifest - - ifeq ($(OS),Windows_NT) - EXE = .exe -@@ -142,7 +142,7 @@ else - endif - - # Libraries that should be linked in for the statically linked Clang. --CLANG_LIB_NAMES = clangAnalysis clangAST clangASTMatchers clangBasic clangCodeGen clangCrossTU clangDriver clangDynamicASTMatchers clangEdit clangFormat clangFrontend clangFrontendTool clangHandleCXX clangHandleLLVM clangIndex clangLex clangParse clangRewrite clangRewriteFrontend clangSema clangSerialization clangTooling clangToolingASTDiff clangToolingCore clangToolingInclusions -+CLANG_LIB_NAMES = clangAnalysis clangAST clangASTMatchers clangBasic clangCodeGen clangCrossTU clangDriver clangDynamicASTMatchers clangEdit clangExtractAPI clangFormat clangFrontend clangFrontendTool clangHandleCXX clangHandleLLVM clangIndex clangLex clangParse clangRewrite clangRewriteFrontend clangSema clangSerialization clangSupport clangTooling clangToolingASTDiff clangToolingCore clangToolingInclusions - CLANG_LIBS = $(START_GROUP) $(addprefix -l,$(CLANG_LIB_NAMES)) $(END_GROUP) -lstdc++ - - # Libraries that should be linked in for the statically linked LLD. -@@ -230,7 +230,7 @@ gen-device-rp: build/gen-device-svd - - # Get LLVM sources. - $(LLVM_PROJECTDIR)/llvm: -- git clone -b xtensa_release_14.0.0-patched --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR) -+ git clone -b xtensa_release_15.x --depth=1 https://github.com/espressif/llvm-project $(LLVM_PROJECTDIR) - llvm-source: $(LLVM_PROJECTDIR)/llvm - - # Configure LLVM. -diff --git a/builder/cc1as.cpp b/builder/cc1as.cpp -index 11500121..cd3229ad 100644 ---- a/builder/cc1as.cpp -+++ b/builder/cc1as.cpp -@@ -101,6 +101,9 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, - - // Target Options - Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple)); -+ if (Arg *A = Args.getLastArg(options::OPT_darwin_target_variant_triple)) -+ Opts.DarwinTargetVariantTriple = llvm::Triple(A->getValue()); -+ - Opts.CPU = std::string(Args.getLastArgValue(OPT_target_cpu)); - Opts.Features = Args.getAllArgValues(OPT_target_feature); - -@@ -203,6 +206,14 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, - .Default(0); - } - -+ if (auto *A = Args.getLastArg(OPT_femit_dwarf_unwind_EQ)) { -+ Opts.EmitDwarfUnwind = -+ llvm::StringSwitch(A->getValue()) -+ .Case("always", EmitDwarfUnwindType::Always) -+ .Case("no-compact-unwind", EmitDwarfUnwindType::NoCompactUnwind) -+ .Case("default", EmitDwarfUnwindType::Default); -+ } -+ - return Success; - } - -@@ -253,6 +264,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts, - assert(MRI && "Unable to create target register info!"); - - MCTargetOptions MCOptions; -+ MCOptions.EmitDwarfUnwind = Opts.EmitDwarfUnwind; -+ - std::unique_ptr MAI( - TheTarget->createMCAsmInfo(*MRI, Opts.Triple, MCOptions)); - assert(MAI && "Unable to create target asm info!"); -@@ -299,6 +312,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts, - // MCObjectFileInfo needs a MCContext reference in order to initialize itself. - std::unique_ptr MOFI( - TheTarget->createMCObjectFileInfo(Ctx, PIC)); -+ if (Opts.DarwinTargetVariantTriple) -+ MOFI->setDarwinTargetVariantTriple(*Opts.DarwinTargetVariantTriple); - Ctx.setObjectFileInfo(MOFI.get()); - - if (Opts.SaveTemporaryLabels) -@@ -347,7 +362,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts, - - std::unique_ptr CE; - if (Opts.ShowEncoding) -- CE.reset(TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx)); -+ CE.reset(TheTarget->createMCCodeEmitter(*MCII, Ctx)); - std::unique_ptr MAB( - TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions)); - -@@ -367,7 +382,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts, - } - - std::unique_ptr CE( -- TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx)); -+ TheTarget->createMCCodeEmitter(*MCII, Ctx)); - std::unique_ptr MAB( - TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions)); - assert(MAB && "Unable to create asm backend!"); -@@ -389,7 +404,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts, - if (Opts.EmbedBitcode && Ctx.getObjectFileType() == MCContext::IsMachO) { - MCSection *AsmLabel = Ctx.getMachOSection( - "__LLVM", "__asm", MachO::S_REGULAR, 4, SectionKind::getReadOnly()); -- Str.get()->SwitchSection(AsmLabel); -+ Str.get()->switchSection(AsmLabel); - Str.get()->emitZeros(1); - } - -diff --git a/builder/cc1as.h b/builder/cc1as.h -index 538e9a26..150d6f14 100644 ---- a/builder/cc1as.h -+++ b/builder/cc1as.h -@@ -85,6 +85,9 @@ struct AssemblerInvocation { - unsigned IncrementalLinkerCompatible : 1; - unsigned EmbedBitcode : 1; - -+ /// Whether to emit DWARF unwind info. -+ EmitDwarfUnwindType EmitDwarfUnwind; -+ - /// The name of the relocation model to use. - std::string RelocationModel; - -@@ -92,6 +95,9 @@ struct AssemblerInvocation { - /// otherwise. - std::string TargetABI; - -+ /// Darwin target variant triple, the variant of the deployment target -+ /// for which the code is being compiled. -+ llvm::Optional DarwinTargetVariantTriple; - /// @} - - public: -@@ -112,6 +118,7 @@ public: - Dwarf64 = 0; - DwarfVersion = 0; - EmbedBitcode = 0; -+ EmitDwarfUnwind = EmitDwarfUnwindType::Default; - } - - static bool CreateFromArgs(AssemblerInvocation &Res, -diff --git a/builder/musl.go b/builder/musl.go -index a1967e37..c266898d 100644 ---- a/builder/musl.go -+++ b/builder/musl.go -@@ -6,10 +6,12 @@ import ( - "os" - "path/filepath" - "regexp" -+ "strconv" - "strings" - - "github.com/tinygo-org/tinygo/compileopts" - "github.com/tinygo-org/tinygo/goenv" -+ "tinygo.org/x/go-llvm" - ) - - var Musl = Library{ -@@ -77,7 +79,7 @@ var Musl = Library{ - cflags: func(target, headerPath string) []string { - arch := compileopts.MuslArchitecture(target) - muslDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/musl") -- return []string{ -+ cflags := []string{ - "-std=c99", // same as in musl - "-D_XOPEN_SOURCE=700", // same as in musl - // Musl triggers some warnings and we don't want to show any -@@ -103,6 +105,12 @@ var Musl = Library{ - "-I" + muslDir + "/include", - "-fno-stack-protector", - } -+ llvmMajor, _ := strconv.Atoi(strings.SplitN(llvm.Version, ".", 2)[0]) -+ if llvmMajor >= 15 { -+ // This flag was added in Clang 15. It is not present in LLVM 14. -+ cflags = append(cflags, "-Wno-deprecated-non-prototype") -+ } -+ return cflags - }, - sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/musl/src") }, - librarySources: func(target string) []string { -diff --git a/cgo/libclang_config_llvm14.go b/cgo/libclang_config_llvm14.go -index 0553bd50..953ce8e2 100644 ---- a/cgo/libclang_config_llvm14.go -+++ b/cgo/libclang_config_llvm14.go -@@ -1,5 +1,5 @@ --//go:build !byollvm --// +build !byollvm -+//go:build !byollvm && llvm14 -+// +build !byollvm,llvm14 - - package cgo - -diff --git a/cgo/libclang_config_llvm15.go b/cgo/libclang_config_llvm15.go -new file mode 100644 -index 00000000..e918a473 ---- /dev/null -+++ b/cgo/libclang_config_llvm15.go -@@ -0,0 +1,16 @@ -+//go:build !byollvm && !llvm14 -+// +build !byollvm,!llvm14 -+ -+package cgo -+ -+/* -+#cgo linux CFLAGS: -I/usr/lib/llvm-15/include -+#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@15/include -+#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@15/include -+#cgo freebsd CFLAGS: -I/usr/local/llvm15/include -+#cgo linux LDFLAGS: -L/usr/lib/llvm-15/lib -lclang -+#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@15/lib -lclang -lffi -+#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@15/lib -lclang -lffi -+#cgo freebsd LDFLAGS: -L/usr/local/llvm15/lib -lclang -+*/ -+import "C" -diff --git a/compiler/func.go b/compiler/func.go -index 4203fdf7..404c7316 100644 ---- a/compiler/func.go -+++ b/compiler/func.go -@@ -57,14 +57,15 @@ func (b *builder) extractFuncContext(funcValue llvm.Value) llvm.Value { - // value. This may be an expensive operation. - func (b *builder) decodeFuncValue(funcValue llvm.Value, sig *types.Signature) (funcType llvm.Type, funcPtr, context llvm.Value) { - context = b.CreateExtractValue(funcValue, 0, "") -- bitcast := b.CreateExtractValue(funcValue, 1, "") -- if !bitcast.IsAConstantExpr().IsNil() && bitcast.Opcode() == llvm.BitCast { -- funcPtr = bitcast.Operand(0) -- return -+ funcPtr = b.CreateExtractValue(funcValue, 1, "") -+ if !funcPtr.IsAConstantExpr().IsNil() && funcPtr.Opcode() == llvm.BitCast { -+ funcPtr = funcPtr.Operand(0) // needed for LLVM 14 (no opaque pointers) -+ } -+ if sig != nil { -+ funcType = b.getRawFuncType(sig) -+ llvmSig := llvm.PointerType(funcType, b.funcPtrAddrSpace) -+ funcPtr = b.CreateBitCast(funcPtr, llvmSig, "") - } -- funcType = b.getRawFuncType(sig) -- llvmSig := llvm.PointerType(funcType, b.funcPtrAddrSpace) -- funcPtr = b.CreateBitCast(bitcast, llvmSig, "") - return - } - -diff --git a/compiler/intrinsics.go b/compiler/intrinsics.go -index 9fedfbd6..a511e518 100644 ---- a/compiler/intrinsics.go -+++ b/compiler/intrinsics.go -@@ -7,6 +7,7 @@ import ( - "strconv" - "strings" - -+ "github.com/tinygo-org/tinygo/compiler/llvmutil" - "tinygo.org/x/go-llvm" - ) - -@@ -44,7 +45,10 @@ func (b *builder) defineIntrinsicFunction() { - // and will otherwise be lowered to regular libc memcpy/memmove calls. - func (b *builder) createMemoryCopyImpl() { - b.createFunctionStart(true) -- fnName := "llvm." + b.fn.Name() + ".p0i8.p0i8.i" + strconv.Itoa(b.uintptrType.IntTypeWidth()) -+ fnName := "llvm." + b.fn.Name() + ".p0.p0.i" + strconv.Itoa(b.uintptrType.IntTypeWidth()) -+ if llvmutil.Major() < 15 { // compatibility with LLVM 14 -+ fnName = "llvm." + b.fn.Name() + ".p0i8.p0i8.i" + strconv.Itoa(b.uintptrType.IntTypeWidth()) -+ } - llvmFn := b.mod.NamedFunction(fnName) - if llvmFn.IsNil() { - fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.i8ptrType, b.i8ptrType, b.uintptrType, b.ctx.Int1Type()}, false) -@@ -64,7 +68,10 @@ func (b *builder) createMemoryCopyImpl() { - // regular libc memset calls if they aren't optimized out in a different way. - func (b *builder) createMemoryZeroImpl() { - b.createFunctionStart(true) -- fnName := "llvm.memset.p0i8.i" + strconv.Itoa(b.uintptrType.IntTypeWidth()) -+ fnName := "llvm.memset.p0.i" + strconv.Itoa(b.uintptrType.IntTypeWidth()) -+ if llvmutil.Major() < 15 { // compatibility with LLVM 14 -+ fnName = "llvm.memset.p0i8.i" + strconv.Itoa(b.uintptrType.IntTypeWidth()) -+ } - llvmFn := b.mod.NamedFunction(fnName) - if llvmFn.IsNil() { - fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.i8ptrType, b.ctx.Int8Type(), b.uintptrType, b.ctx.Int1Type()}, false) -diff --git a/compiler/llvmutil/llvm.go b/compiler/llvmutil/llvm.go -index e73b68da..ca277765 100644 ---- a/compiler/llvmutil/llvm.go -+++ b/compiler/llvmutil/llvm.go -@@ -7,7 +7,22 @@ - // places would be a big risk if only one of them is updated. - package llvmutil - --import "tinygo.org/x/go-llvm" -+import ( -+ "strconv" -+ "strings" -+ -+ "tinygo.org/x/go-llvm" -+) -+ -+// Major returns the LLVM major version. -+func Major() int { -+ llvmMajor, err := strconv.Atoi(strings.SplitN(llvm.Version, ".", 2)[0]) -+ if err != nil { -+ // sanity check, should be unreachable -+ panic("could not parse LLVM version: " + err.Error()) -+ } -+ return llvmMajor -+} - - // CreateEntryBlockAlloca creates a new alloca in the entry block, even though - // the IR builder is located elsewhere. It assumes that the insert point is -@@ -78,12 +93,16 @@ func EmitLifetimeEnd(builder llvm.Builder, mod llvm.Module, ptr, size llvm.Value - // getLifetimeStartFunc returns the llvm.lifetime.start intrinsic and creates it - // first if it doesn't exist yet. - func getLifetimeStartFunc(mod llvm.Module) (llvm.Type, llvm.Value) { -- fn := mod.NamedFunction("llvm.lifetime.start.p0i8") -+ fnName := "llvm.lifetime.start.p0" -+ if Major() < 15 { // compatibility with LLVM 14 -+ fnName = "llvm.lifetime.start.p0i8" -+ } -+ fn := mod.NamedFunction(fnName) - ctx := mod.Context() - i8ptrType := llvm.PointerType(ctx.Int8Type(), 0) - fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false) - if fn.IsNil() { -- fn = llvm.AddFunction(mod, "llvm.lifetime.start.p0i8", fnType) -+ fn = llvm.AddFunction(mod, fnName, fnType) - } - return fnType, fn - } -@@ -91,12 +110,16 @@ func getLifetimeStartFunc(mod llvm.Module) (llvm.Type, llvm.Value) { - // getLifetimeEndFunc returns the llvm.lifetime.end intrinsic and creates it - // first if it doesn't exist yet. - func getLifetimeEndFunc(mod llvm.Module) (llvm.Type, llvm.Value) { -- fn := mod.NamedFunction("llvm.lifetime.end.p0i8") -+ fnName := "llvm.lifetime.end.p0" -+ if Major() < 15 { -+ fnName = "llvm.lifetime.end.p0i8" -+ } -+ fn := mod.NamedFunction(fnName) - ctx := mod.Context() - i8ptrType := llvm.PointerType(ctx.Int8Type(), 0) - fnType := llvm.FunctionType(ctx.VoidType(), []llvm.Type{ctx.Int64Type(), i8ptrType}, false) - if fn.IsNil() { -- fn = llvm.AddFunction(mod, "llvm.lifetime.end.p0i8", fnType) -+ fn = llvm.AddFunction(mod, fnName, fnType) - } - return fnType, fn - } -diff --git a/compiler/symbol.go b/compiler/symbol.go -index 01b3fc37..61ca4473 100644 ---- a/compiler/symbol.go -+++ b/compiler/symbol.go -@@ -10,6 +10,7 @@ import ( - "strconv" - "strings" - -+ "github.com/tinygo-org/tinygo/compiler/llvmutil" - "github.com/tinygo-org/tinygo/loader" - "golang.org/x/tools/go/ssa" - "tinygo.org/x/go-llvm" -@@ -353,7 +354,15 @@ func (c *compilerContext) addStandardDefinedAttributes(llvmFn llvm.Value) { - llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nounwind"), 0)) - if strings.Split(c.Triple, "-")[0] == "x86_64" { - // Required by the ABI. -- llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("uwtable"), 0)) -+ if llvmutil.Major() < 15 { -+ // Needed for LLVM 14 support. -+ llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("uwtable"), 0)) -+ } else { -+ // The uwtable has two possible values: sync (1) or async (2). We -+ // use sync because we currently don't use async unwind tables. -+ // For details, see: https://llvm.org/docs/LangRef.html#function-attributes -+ llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("uwtable"), 1)) -+ } - } - } - -diff --git a/compiler/testdata/basic.go b/compiler/testdata/basic.go -index e9fcbad3..d2b4a96d 100644 ---- a/compiler/testdata/basic.go -+++ b/compiler/testdata/basic.go -@@ -75,14 +75,18 @@ func complexMul(x, y complex64) complex64 { - // A type 'kv' also exists in function foo. Test that these two types don't - // conflict with each other. - type kv struct { -- v float32 -+ v float32 -+ x, y, z int - } - --func foo(a *kv) { -+var kvGlobal kv -+ -+func foo() { - // Define a new 'kv' type. - type kv struct { -- v byte -+ v byte -+ x, y, z int - } - // Use this type. -- func(b *kv) {}(nil) -+ func(b kv) {}(kv{}) - } -diff --git a/compiler/testdata/basic.ll b/compiler/testdata/basic.ll -index 4d88f66f..6ef0dc92 100644 ---- a/compiler/testdata/basic.ll -+++ b/compiler/testdata/basic.ll -@@ -3,35 +3,37 @@ source_filename = "basic.go" - target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" - target triple = "wasm32-unknown-wasi" - --%main.kv = type { float } --%main.kv.0 = type { i8 } -+%main.kv = type { float, i32, i32, i32 } -+%main.kv.0 = type { i8, i32, i32, i32 } - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+@main.kvGlobal = hidden global %main.kv zeroinitializer, align 4 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -+ -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden i32 @main.addInt(i32 %x, i32 %y, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.addInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 { - entry: - %0 = add i32 %x, %y - ret i32 %0 - } - - ; Function Attrs: nounwind --define hidden i1 @main.equalInt(i32 %x, i32 %y, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.equalInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 { - entry: - %0 = icmp eq i32 %x, %y - ret i1 %0 - } - - ; Function Attrs: nounwind --define hidden i32 @main.divInt(i32 %x, i32 %y, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.divInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 { - entry: - %0 = icmp eq i32 %y, 0 - br i1 %0, label %divbyzero.throw, label %divbyzero.next -@@ -45,14 +47,14 @@ divbyzero.next: ; preds = %entry - ret i32 %5 - - divbyzero.throw: ; preds = %entry -- call void @runtime.divideByZeroPanic(i8* undef) #2 -+ call void @runtime.divideByZeroPanic(ptr undef) #2 - unreachable - } - --declare void @runtime.divideByZeroPanic(i8*) #0 -+declare void @runtime.divideByZeroPanic(ptr) #0 - - ; Function Attrs: nounwind --define hidden i32 @main.divUint(i32 %x, i32 %y, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.divUint(i32 %x, i32 %y, ptr %context) unnamed_addr #1 { - entry: - %0 = icmp eq i32 %y, 0 - br i1 %0, label %divbyzero.throw, label %divbyzero.next -@@ -62,12 +64,12 @@ divbyzero.next: ; preds = %entry - ret i32 %1 - - divbyzero.throw: ; preds = %entry -- call void @runtime.divideByZeroPanic(i8* undef) #2 -+ call void @runtime.divideByZeroPanic(ptr undef) #2 - unreachable - } - - ; Function Attrs: nounwind --define hidden i32 @main.remInt(i32 %x, i32 %y, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.remInt(i32 %x, i32 %y, ptr %context) unnamed_addr #1 { - entry: - %0 = icmp eq i32 %y, 0 - br i1 %0, label %divbyzero.throw, label %divbyzero.next -@@ -81,12 +83,12 @@ divbyzero.next: ; preds = %entry - ret i32 %5 - - divbyzero.throw: ; preds = %entry -- call void @runtime.divideByZeroPanic(i8* undef) #2 -+ call void @runtime.divideByZeroPanic(ptr undef) #2 - unreachable - } - - ; Function Attrs: nounwind --define hidden i32 @main.remUint(i32 %x, i32 %y, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.remUint(i32 %x, i32 %y, ptr %context) unnamed_addr #1 { - entry: - %0 = icmp eq i32 %y, 0 - br i1 %0, label %divbyzero.throw, label %divbyzero.next -@@ -96,66 +98,66 @@ divbyzero.next: ; preds = %entry - ret i32 %1 - - divbyzero.throw: ; preds = %entry -- call void @runtime.divideByZeroPanic(i8* undef) #2 -+ call void @runtime.divideByZeroPanic(ptr undef) #2 - unreachable - } - - ; Function Attrs: nounwind --define hidden i1 @main.floatEQ(float %x, float %y, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.floatEQ(float %x, float %y, ptr %context) unnamed_addr #1 { - entry: - %0 = fcmp oeq float %x, %y - ret i1 %0 - } - - ; Function Attrs: nounwind --define hidden i1 @main.floatNE(float %x, float %y, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.floatNE(float %x, float %y, ptr %context) unnamed_addr #1 { - entry: - %0 = fcmp une float %x, %y - ret i1 %0 - } - - ; Function Attrs: nounwind --define hidden i1 @main.floatLower(float %x, float %y, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.floatLower(float %x, float %y, ptr %context) unnamed_addr #1 { - entry: - %0 = fcmp olt float %x, %y - ret i1 %0 - } - - ; Function Attrs: nounwind --define hidden i1 @main.floatLowerEqual(float %x, float %y, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.floatLowerEqual(float %x, float %y, ptr %context) unnamed_addr #1 { - entry: - %0 = fcmp ole float %x, %y - ret i1 %0 - } - - ; Function Attrs: nounwind --define hidden i1 @main.floatGreater(float %x, float %y, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.floatGreater(float %x, float %y, ptr %context) unnamed_addr #1 { - entry: - %0 = fcmp ogt float %x, %y - ret i1 %0 - } - - ; Function Attrs: nounwind --define hidden i1 @main.floatGreaterEqual(float %x, float %y, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.floatGreaterEqual(float %x, float %y, ptr %context) unnamed_addr #1 { - entry: - %0 = fcmp oge float %x, %y - ret i1 %0 - } - - ; Function Attrs: nounwind --define hidden float @main.complexReal(float %x.r, float %x.i, i8* %context) unnamed_addr #1 { -+define hidden float @main.complexReal(float %x.r, float %x.i, ptr %context) unnamed_addr #1 { - entry: - ret float %x.r - } - - ; Function Attrs: nounwind --define hidden float @main.complexImag(float %x.r, float %x.i, i8* %context) unnamed_addr #1 { -+define hidden float @main.complexImag(float %x.r, float %x.i, ptr %context) unnamed_addr #1 { - entry: - ret float %x.i - } - - ; Function Attrs: nounwind --define hidden { float, float } @main.complexAdd(float %x.r, float %x.i, float %y.r, float %y.i, i8* %context) unnamed_addr #1 { -+define hidden { float, float } @main.complexAdd(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 { - entry: - %0 = fadd float %x.r, %y.r - %1 = fadd float %x.i, %y.i -@@ -165,7 +167,7 @@ entry: - } - - ; Function Attrs: nounwind --define hidden { float, float } @main.complexSub(float %x.r, float %x.i, float %y.r, float %y.i, i8* %context) unnamed_addr #1 { -+define hidden { float, float } @main.complexSub(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 { - entry: - %0 = fsub float %x.r, %y.r - %1 = fsub float %x.i, %y.i -@@ -175,7 +177,7 @@ entry: - } - - ; Function Attrs: nounwind --define hidden { float, float } @main.complexMul(float %x.r, float %x.i, float %y.r, float %y.i, i8* %context) unnamed_addr #1 { -+define hidden { float, float } @main.complexMul(float %x.r, float %x.i, float %y.r, float %y.i, ptr %context) unnamed_addr #1 { - entry: - %0 = fmul float %x.r, %y.r - %1 = fmul float %x.i, %y.i -@@ -189,15 +191,22 @@ entry: - } - - ; Function Attrs: nounwind --define hidden void @main.foo(%main.kv* dereferenceable_or_null(4) %a, i8* %context) unnamed_addr #1 { -+define hidden void @main.foo(ptr %context) unnamed_addr #1 { - entry: -- call void @"main.foo$1"(%main.kv.0* null, i8* undef) -+ %complit = alloca %main.kv.0, align 8 -+ store %main.kv.0 zeroinitializer, ptr %complit, align 8 -+ call void @runtime.trackPointer(ptr nonnull %complit, ptr undef) #2 -+ call void @"main.foo$1"(%main.kv.0 zeroinitializer, ptr undef) - ret void - } - - ; Function Attrs: nounwind --define internal void @"main.foo$1"(%main.kv.0* dereferenceable_or_null(1) %b, i8* %context) unnamed_addr #1 { -+define internal void @"main.foo$1"(%main.kv.0 %b, ptr %context) unnamed_addr #1 { - entry: -+ %b1 = alloca %main.kv.0, align 8 -+ store %main.kv.0 zeroinitializer, ptr %b1, align 8 -+ call void @runtime.trackPointer(ptr nonnull %b1, ptr undef) #2 -+ store %main.kv.0 %b, ptr %b1, align 8 - ret void - } - -diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll -index ec3dd6b9..8f4ed74e 100644 ---- a/compiler/testdata/channel.ll -+++ b/compiler/testdata/channel.ll -@@ -3,110 +3,94 @@ source_filename = "channel.go" - target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" - target triple = "wasm32-unknown-wasi" - --%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* } --%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } } --%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* } --%"internal/task.gcData" = type { i8* } --%"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 } --%"internal/task.stackState" = type { i32, i32 } --%runtime.chanSelectState = type { %runtime.channel*, i8* } -+%runtime.channelBlockedList = type { ptr, ptr, ptr, { ptr, i32, i32 } } -+%runtime.chanSelectState = type { ptr, ptr } - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.chanIntSend(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 { -+define hidden void @main.chanIntSend(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 { - entry: - %chan.blockedList = alloca %runtime.channelBlockedList, align 8 - %chan.value = alloca i32, align 4 -- %chan.value.bitcast = bitcast i32* %chan.value to i8* -- call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %chan.value.bitcast) -- store i32 3, i32* %chan.value, align 4 -- %chan.blockedList.bitcast = bitcast %runtime.channelBlockedList* %chan.blockedList to i8* -- call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast) -- call void @runtime.chanSend(%runtime.channel* %ch, i8* nonnull %chan.value.bitcast, %runtime.channelBlockedList* nonnull %chan.blockedList, i8* undef) #3 -- call void @llvm.lifetime.end.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast) -- call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %chan.value.bitcast) -+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %chan.value) -+ store i32 3, ptr %chan.value, align 4 -+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList) -+ call void @runtime.chanSend(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.blockedList, ptr undef) #3 -+ call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList) -+ call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %chan.value) - ret void - } - --; Function Attrs: argmemonly nofree nosync nounwind willreturn --declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #2 -+; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn -+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #2 - --declare void @runtime.chanSend(%runtime.channel* dereferenceable_or_null(32), i8*, %runtime.channelBlockedList* dereferenceable_or_null(24), i8*) #0 -+declare void @runtime.chanSend(ptr dereferenceable_or_null(32), ptr, ptr dereferenceable_or_null(24), ptr) #0 - --; Function Attrs: argmemonly nofree nosync nounwind willreturn --declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #2 -+; Function Attrs: argmemonly nocallback nofree nosync nounwind willreturn -+declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #2 - - ; Function Attrs: nounwind --define hidden void @main.chanIntRecv(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 { -+define hidden void @main.chanIntRecv(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 { - entry: - %chan.blockedList = alloca %runtime.channelBlockedList, align 8 - %chan.value = alloca i32, align 4 -- %chan.value.bitcast = bitcast i32* %chan.value to i8* -- call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %chan.value.bitcast) -- %chan.blockedList.bitcast = bitcast %runtime.channelBlockedList* %chan.blockedList to i8* -- call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast) -- %0 = call i1 @runtime.chanRecv(%runtime.channel* %ch, i8* nonnull %chan.value.bitcast, %runtime.channelBlockedList* nonnull %chan.blockedList, i8* undef) #3 -- call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %chan.value.bitcast) -- call void @llvm.lifetime.end.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast) -+ call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %chan.value) -+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList) -+ %0 = call i1 @runtime.chanRecv(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.blockedList, ptr undef) #3 -+ call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %chan.value) -+ call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList) - ret void - } - --declare i1 @runtime.chanRecv(%runtime.channel* dereferenceable_or_null(32), i8*, %runtime.channelBlockedList* dereferenceable_or_null(24), i8*) #0 -+declare i1 @runtime.chanRecv(ptr dereferenceable_or_null(32), ptr, ptr dereferenceable_or_null(24), ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.chanZeroSend(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 { -+define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 { - entry: - %complit = alloca {}, align 8 - %chan.blockedList = alloca %runtime.channelBlockedList, align 8 -- %0 = bitcast {}* %complit to i8* -- call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #3 -- %chan.blockedList.bitcast = bitcast %runtime.channelBlockedList* %chan.blockedList to i8* -- call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast) -- call void @runtime.chanSend(%runtime.channel* %ch, i8* null, %runtime.channelBlockedList* nonnull %chan.blockedList, i8* undef) #3 -- call void @llvm.lifetime.end.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast) -+ call void @runtime.trackPointer(ptr nonnull %complit, ptr undef) #3 -+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList) -+ call void @runtime.chanSend(ptr %ch, ptr null, ptr nonnull %chan.blockedList, ptr undef) #3 -+ call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList) - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.chanZeroRecv(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 { -+define hidden void @main.chanZeroRecv(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 { - entry: - %chan.blockedList = alloca %runtime.channelBlockedList, align 8 -- %chan.blockedList.bitcast = bitcast %runtime.channelBlockedList* %chan.blockedList to i8* -- call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast) -- %0 = call i1 @runtime.chanRecv(%runtime.channel* %ch, i8* null, %runtime.channelBlockedList* nonnull %chan.blockedList, i8* undef) #3 -- call void @llvm.lifetime.end.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast) -+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList) -+ %0 = call i1 @runtime.chanRecv(ptr %ch, ptr null, ptr nonnull %chan.blockedList, ptr undef) #3 -+ call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList) - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.selectZeroRecv(%runtime.channel* dereferenceable_or_null(32) %ch1, %runtime.channel* dereferenceable_or_null(32) %ch2, i8* %context) unnamed_addr #1 { -+define hidden void @main.selectZeroRecv(ptr dereferenceable_or_null(32) %ch1, ptr dereferenceable_or_null(32) %ch2, ptr %context) unnamed_addr #1 { - entry: - %select.states.alloca = alloca [2 x %runtime.chanSelectState], align 8 - %select.send.value = alloca i32, align 4 -- store i32 1, i32* %select.send.value, align 4 -- %select.states.alloca.bitcast = bitcast [2 x %runtime.chanSelectState]* %select.states.alloca to i8* -- call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %select.states.alloca.bitcast) -- %.repack = getelementptr inbounds [2 x %runtime.chanSelectState], [2 x %runtime.chanSelectState]* %select.states.alloca, i32 0, i32 0, i32 0 -- store %runtime.channel* %ch1, %runtime.channel** %.repack, align 8 -- %.repack1 = getelementptr inbounds [2 x %runtime.chanSelectState], [2 x %runtime.chanSelectState]* %select.states.alloca, i32 0, i32 0, i32 1 -- %0 = bitcast i8** %.repack1 to i32** -- store i32* %select.send.value, i32** %0, align 4 -- %.repack3 = getelementptr inbounds [2 x %runtime.chanSelectState], [2 x %runtime.chanSelectState]* %select.states.alloca, i32 0, i32 1, i32 0 -- store %runtime.channel* %ch2, %runtime.channel** %.repack3, align 8 -- %.repack4 = getelementptr inbounds [2 x %runtime.chanSelectState], [2 x %runtime.chanSelectState]* %select.states.alloca, i32 0, i32 1, i32 1 -- store i8* null, i8** %.repack4, align 4 -- %select.states = getelementptr inbounds [2 x %runtime.chanSelectState], [2 x %runtime.chanSelectState]* %select.states.alloca, i32 0, i32 0 -- %select.result = call { i32, i1 } @runtime.tryChanSelect(i8* undef, %runtime.chanSelectState* nonnull %select.states, i32 2, i32 2, i8* undef) #3 -- call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %select.states.alloca.bitcast) -+ store i32 1, ptr %select.send.value, align 4 -+ call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %select.states.alloca) -+ store ptr %ch1, ptr %select.states.alloca, align 8 -+ %select.states.alloca.repack1 = getelementptr inbounds %runtime.chanSelectState, ptr %select.states.alloca, i32 0, i32 1 -+ store ptr %select.send.value, ptr %select.states.alloca.repack1, align 4 -+ %0 = getelementptr inbounds [2 x %runtime.chanSelectState], ptr %select.states.alloca, i32 0, i32 1 -+ store ptr %ch2, ptr %0, align 8 -+ %.repack3 = getelementptr inbounds [2 x %runtime.chanSelectState], ptr %select.states.alloca, i32 0, i32 1, i32 1 -+ store ptr null, ptr %.repack3, align 4 -+ %select.result = call { i32, i1 } @runtime.tryChanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr undef) #3 -+ call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %select.states.alloca) - %1 = extractvalue { i32, i1 } %select.result, 0 - %2 = icmp eq i32 %1, 0 - br i1 %2, label %select.done, label %select.next -@@ -122,9 +106,9 @@ select.body: ; preds = %select.next - br label %select.done - } - --declare { i32, i1 } @runtime.tryChanSelect(i8*, %runtime.chanSelectState*, i32, i32, i8*) #0 -+declare { i32, i1 } @runtime.tryChanSelect(ptr, ptr, i32, i32, ptr) #0 - - attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } - attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } --attributes #2 = { argmemonly nofree nosync nounwind willreturn } -+attributes #2 = { argmemonly nocallback nofree nosync nounwind willreturn } - attributes #3 = { nounwind } -diff --git a/compiler/testdata/defer-cortex-m-qemu.ll b/compiler/testdata/defer-cortex-m-qemu.ll -index 693f1b07..0841e255 100644 ---- a/compiler/testdata/defer-cortex-m-qemu.ll -+++ b/compiler/testdata/defer-cortex-m-qemu.ll -@@ -3,103 +3,99 @@ source_filename = "defer.go" - target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" - target triple = "thumbv7m-unknown-unknown-eabi" - --%runtime._defer = type { i32, %runtime._defer* } --%runtime.deferFrame = type { i8*, i8*, [0 x i8*], %runtime.deferFrame*, i1, %runtime._interface } --%runtime._interface = type { i32, i8* } -+%runtime.deferFrame = type { ptr, ptr, [0 x ptr], ptr, i1, %runtime._interface } -+%runtime._interface = type { i32, ptr } -+%runtime._defer = type { i32, ptr } - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - --declare void @main.external(i8*) #0 -+declare void @main.external(ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.deferSimple(i8* %context) unnamed_addr #1 { -+define hidden void @main.deferSimple(ptr %context) unnamed_addr #1 { - entry: -- %defer.alloca = alloca { i32, %runtime._defer* }, align 4 -- %deferPtr = alloca %runtime._defer*, align 4 -- store %runtime._defer* null, %runtime._defer** %deferPtr, align 4 -+ %defer.alloca = alloca { i32, ptr }, align 4 -+ %deferPtr = alloca ptr, align 4 -+ store ptr null, ptr %deferPtr, align 4 - %deferframe.buf = alloca %runtime.deferFrame, align 4 -- %0 = call i8* @llvm.stacksave() -- call void @runtime.setupDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* %0, i8* undef) #3 -- %defer.alloca.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 0 -- store i32 0, i32* %defer.alloca.repack, align 4 -- %defer.alloca.repack16 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 1 -- store %runtime._defer* null, %runtime._defer** %defer.alloca.repack16, align 4 -- %1 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }** -- store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %1, align 4 -- %setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 -+ %0 = call ptr @llvm.stacksave() -+ call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #3 -+ store i32 0, ptr %defer.alloca, align 4 -+ %defer.alloca.repack15 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1 -+ store ptr null, ptr %defer.alloca.repack15, align 4 -+ store ptr %defer.alloca, ptr %deferPtr, align 4 -+ %setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 - %setjmp.result = icmp eq i32 %setjmp, 0 -- br i1 %setjmp.result, label %2, label %lpad -+ br i1 %setjmp.result, label %1, label %lpad - --2: ; preds = %entry -- call void @main.external(i8* undef) #3 -+1: ; preds = %entry -+ call void @main.external(ptr undef) #3 - br label %rundefers.loophead - --rundefers.loophead: ; preds = %4, %2 -- %3 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4 -- %stackIsNil = icmp eq %runtime._defer* %3, null -+rundefers.loophead: ; preds = %3, %1 -+ %2 = load ptr, ptr %deferPtr, align 4 -+ %stackIsNil = icmp eq ptr %2, null - br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop - - rundefers.loop: ; preds = %rundefers.loophead -- %stack.next.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %3, i32 0, i32 1 -- %stack.next = load %runtime._defer*, %runtime._defer** %stack.next.gep, align 4 -- store %runtime._defer* %stack.next, %runtime._defer** %deferPtr, align 4 -- %callback.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %3, i32 0, i32 0 -- %callback = load i32, i32* %callback.gep, align 4 -+ %stack.next.gep = getelementptr inbounds %runtime._defer, ptr %2, i32 0, i32 1 -+ %stack.next = load ptr, ptr %stack.next.gep, align 4 -+ store ptr %stack.next, ptr %deferPtr, align 4 -+ %callback = load i32, ptr %2, align 4 - switch i32 %callback, label %rundefers.default [ - i32 0, label %rundefers.callback0 - ] - - rundefers.callback0: ; preds = %rundefers.loop -- %setjmp1 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 -+ %setjmp1 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 - %setjmp.result2 = icmp eq i32 %setjmp1, 0 -- br i1 %setjmp.result2, label %4, label %lpad -+ br i1 %setjmp.result2, label %3, label %lpad - --4: ; preds = %rundefers.callback0 -- call void @"main.deferSimple$1"(i8* undef) -+3: ; preds = %rundefers.callback0 -+ call void @"main.deferSimple$1"(ptr undef) - br label %rundefers.loophead - - rundefers.default: ; preds = %rundefers.loop - unreachable - - rundefers.end: ; preds = %rundefers.loophead -- call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3 -+ call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3 - ret void - - recover: ; preds = %rundefers.end3 -- call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3 -+ call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3 - ret void - - lpad: ; preds = %rundefers.callback012, %rundefers.callback0, %entry - br label %rundefers.loophead6 - --rundefers.loophead6: ; preds = %6, %lpad -- %5 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4 -- %stackIsNil7 = icmp eq %runtime._defer* %5, null -+rundefers.loophead6: ; preds = %5, %lpad -+ %4 = load ptr, ptr %deferPtr, align 4 -+ %stackIsNil7 = icmp eq ptr %4, null - br i1 %stackIsNil7, label %rundefers.end3, label %rundefers.loop5 - - rundefers.loop5: ; preds = %rundefers.loophead6 -- %stack.next.gep8 = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 1 -- %stack.next9 = load %runtime._defer*, %runtime._defer** %stack.next.gep8, align 4 -- store %runtime._defer* %stack.next9, %runtime._defer** %deferPtr, align 4 -- %callback.gep10 = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 0 -- %callback11 = load i32, i32* %callback.gep10, align 4 -+ %stack.next.gep8 = getelementptr inbounds %runtime._defer, ptr %4, i32 0, i32 1 -+ %stack.next9 = load ptr, ptr %stack.next.gep8, align 4 -+ store ptr %stack.next9, ptr %deferPtr, align 4 -+ %callback11 = load i32, ptr %4, align 4 - switch i32 %callback11, label %rundefers.default4 [ - i32 0, label %rundefers.callback012 - ] - - rundefers.callback012: ; preds = %rundefers.loop5 -- %setjmp14 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 -- %setjmp.result15 = icmp eq i32 %setjmp14, 0 -- br i1 %setjmp.result15, label %6, label %lpad -+ %setjmp13 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 -+ %setjmp.result14 = icmp eq i32 %setjmp13, 0 -+ br i1 %setjmp.result14, label %5, label %lpad - --6: ; preds = %rundefers.callback012 -- call void @"main.deferSimple$1"(i8* undef) -+5: ; preds = %rundefers.callback012 -+ call void @"main.deferSimple$1"(ptr undef) - br label %rundefers.loophead6 - - rundefers.default4: ; preds = %rundefers.loop5 -@@ -109,158 +105,151 @@ rundefers.end3: ; preds = %rundefers.loophead6 - br label %recover - } - --; Function Attrs: nofree nosync nounwind willreturn --declare i8* @llvm.stacksave() #2 -+; Function Attrs: nocallback nofree nosync nounwind willreturn -+declare ptr @llvm.stacksave() #2 - --declare void @runtime.setupDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*, i8*) #0 -+declare void @runtime.setupDeferFrame(ptr dereferenceable_or_null(24), ptr, ptr) #0 - - ; Function Attrs: nounwind --define internal void @"main.deferSimple$1"(i8* %context) unnamed_addr #1 { -+define internal void @"main.deferSimple$1"(ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.printint32(i32 3, i8* undef) #3 -+ call void @runtime.printint32(i32 3, ptr undef) #3 - ret void - } - --declare void @runtime.destroyDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*) #0 -+declare void @runtime.destroyDeferFrame(ptr dereferenceable_or_null(24), ptr) #0 - --declare void @runtime.printint32(i32, i8*) #0 -+declare void @runtime.printint32(i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.deferMultiple(i8* %context) unnamed_addr #1 { -+define hidden void @main.deferMultiple(ptr %context) unnamed_addr #1 { - entry: -- %defer.alloca2 = alloca { i32, %runtime._defer* }, align 4 -- %defer.alloca = alloca { i32, %runtime._defer* }, align 4 -- %deferPtr = alloca %runtime._defer*, align 4 -- store %runtime._defer* null, %runtime._defer** %deferPtr, align 4 -+ %defer.alloca2 = alloca { i32, ptr }, align 4 -+ %defer.alloca = alloca { i32, ptr }, align 4 -+ %deferPtr = alloca ptr, align 4 -+ store ptr null, ptr %deferPtr, align 4 - %deferframe.buf = alloca %runtime.deferFrame, align 4 -- %0 = call i8* @llvm.stacksave() -- call void @runtime.setupDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* %0, i8* undef) #3 -- %defer.alloca.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 0 -- store i32 0, i32* %defer.alloca.repack, align 4 -- %defer.alloca.repack26 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 1 -- store %runtime._defer* null, %runtime._defer** %defer.alloca.repack26, align 4 -- %1 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }** -- store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %1, align 4 -- %defer.alloca2.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca2, i32 0, i32 0 -- store i32 1, i32* %defer.alloca2.repack, align 4 -- %defer.alloca2.repack27 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca2, i32 0, i32 1 -- %2 = bitcast %runtime._defer** %defer.alloca2.repack27 to { i32, %runtime._defer* }** -- store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %2, align 4 -- %3 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }** -- store { i32, %runtime._defer* }* %defer.alloca2, { i32, %runtime._defer* }** %3, align 4 -- %setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 -+ %0 = call ptr @llvm.stacksave() -+ call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #3 -+ store i32 0, ptr %defer.alloca, align 4 -+ %defer.alloca.repack22 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1 -+ store ptr null, ptr %defer.alloca.repack22, align 4 -+ store ptr %defer.alloca, ptr %deferPtr, align 4 -+ store i32 1, ptr %defer.alloca2, align 4 -+ %defer.alloca2.repack23 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca2, i32 0, i32 1 -+ store ptr %defer.alloca, ptr %defer.alloca2.repack23, align 4 -+ store ptr %defer.alloca2, ptr %deferPtr, align 4 -+ %setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 - %setjmp.result = icmp eq i32 %setjmp, 0 -- br i1 %setjmp.result, label %4, label %lpad -+ br i1 %setjmp.result, label %1, label %lpad - --4: ; preds = %entry -- call void @main.external(i8* undef) #3 -+1: ; preds = %entry -+ call void @main.external(ptr undef) #3 - br label %rundefers.loophead - --rundefers.loophead: ; preds = %7, %6, %4 -- %5 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4 -- %stackIsNil = icmp eq %runtime._defer* %5, null -+rundefers.loophead: ; preds = %4, %3, %1 -+ %2 = load ptr, ptr %deferPtr, align 4 -+ %stackIsNil = icmp eq ptr %2, null - br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop - - rundefers.loop: ; preds = %rundefers.loophead -- %stack.next.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 1 -- %stack.next = load %runtime._defer*, %runtime._defer** %stack.next.gep, align 4 -- store %runtime._defer* %stack.next, %runtime._defer** %deferPtr, align 4 -- %callback.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 0 -- %callback = load i32, i32* %callback.gep, align 4 -+ %stack.next.gep = getelementptr inbounds %runtime._defer, ptr %2, i32 0, i32 1 -+ %stack.next = load ptr, ptr %stack.next.gep, align 4 -+ store ptr %stack.next, ptr %deferPtr, align 4 -+ %callback = load i32, ptr %2, align 4 - switch i32 %callback, label %rundefers.default [ - i32 0, label %rundefers.callback0 - i32 1, label %rundefers.callback1 - ] - - rundefers.callback0: ; preds = %rundefers.loop -- %setjmp4 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 -- %setjmp.result5 = icmp eq i32 %setjmp4, 0 -- br i1 %setjmp.result5, label %6, label %lpad -+ %setjmp3 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 -+ %setjmp.result4 = icmp eq i32 %setjmp3, 0 -+ br i1 %setjmp.result4, label %3, label %lpad - --6: ; preds = %rundefers.callback0 -- call void @"main.deferMultiple$1"(i8* undef) -+3: ; preds = %rundefers.callback0 -+ call void @"main.deferMultiple$1"(ptr undef) - br label %rundefers.loophead - - rundefers.callback1: ; preds = %rundefers.loop -- %setjmp7 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 -- %setjmp.result8 = icmp eq i32 %setjmp7, 0 -- br i1 %setjmp.result8, label %7, label %lpad -+ %setjmp5 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 -+ %setjmp.result6 = icmp eq i32 %setjmp5, 0 -+ br i1 %setjmp.result6, label %4, label %lpad - --7: ; preds = %rundefers.callback1 -- call void @"main.deferMultiple$2"(i8* undef) -+4: ; preds = %rundefers.callback1 -+ call void @"main.deferMultiple$2"(ptr undef) - br label %rundefers.loophead - - rundefers.default: ; preds = %rundefers.loop - unreachable - - rundefers.end: ; preds = %rundefers.loophead -- call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3 -+ call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3 - ret void - --recover: ; preds = %rundefers.end9 -- call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3 -+recover: ; preds = %rundefers.end7 -+ call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3 - ret void - --lpad: ; preds = %rundefers.callback122, %rundefers.callback018, %rundefers.callback1, %rundefers.callback0, %entry -- br label %rundefers.loophead12 -- --rundefers.loophead12: ; preds = %10, %9, %lpad -- %8 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4 -- %stackIsNil13 = icmp eq %runtime._defer* %8, null -- br i1 %stackIsNil13, label %rundefers.end9, label %rundefers.loop11 -- --rundefers.loop11: ; preds = %rundefers.loophead12 -- %stack.next.gep14 = getelementptr inbounds %runtime._defer, %runtime._defer* %8, i32 0, i32 1 -- %stack.next15 = load %runtime._defer*, %runtime._defer** %stack.next.gep14, align 4 -- store %runtime._defer* %stack.next15, %runtime._defer** %deferPtr, align 4 -- %callback.gep16 = getelementptr inbounds %runtime._defer, %runtime._defer* %8, i32 0, i32 0 -- %callback17 = load i32, i32* %callback.gep16, align 4 -- switch i32 %callback17, label %rundefers.default10 [ -- i32 0, label %rundefers.callback018 -- i32 1, label %rundefers.callback122 -+lpad: ; preds = %rundefers.callback119, %rundefers.callback016, %rundefers.callback1, %rundefers.callback0, %entry -+ br label %rundefers.loophead10 -+ -+rundefers.loophead10: ; preds = %7, %6, %lpad -+ %5 = load ptr, ptr %deferPtr, align 4 -+ %stackIsNil11 = icmp eq ptr %5, null -+ br i1 %stackIsNil11, label %rundefers.end7, label %rundefers.loop9 -+ -+rundefers.loop9: ; preds = %rundefers.loophead10 -+ %stack.next.gep12 = getelementptr inbounds %runtime._defer, ptr %5, i32 0, i32 1 -+ %stack.next13 = load ptr, ptr %stack.next.gep12, align 4 -+ store ptr %stack.next13, ptr %deferPtr, align 4 -+ %callback15 = load i32, ptr %5, align 4 -+ switch i32 %callback15, label %rundefers.default8 [ -+ i32 0, label %rundefers.callback016 -+ i32 1, label %rundefers.callback119 - ] - --rundefers.callback018: ; preds = %rundefers.loop11 -- %setjmp20 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 -- %setjmp.result21 = icmp eq i32 %setjmp20, 0 -- br i1 %setjmp.result21, label %9, label %lpad -+rundefers.callback016: ; preds = %rundefers.loop9 -+ %setjmp17 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 -+ %setjmp.result18 = icmp eq i32 %setjmp17, 0 -+ br i1 %setjmp.result18, label %6, label %lpad - --9: ; preds = %rundefers.callback018 -- call void @"main.deferMultiple$1"(i8* undef) -- br label %rundefers.loophead12 -+6: ; preds = %rundefers.callback016 -+ call void @"main.deferMultiple$1"(ptr undef) -+ br label %rundefers.loophead10 - --rundefers.callback122: ; preds = %rundefers.loop11 -- %setjmp24 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 -- %setjmp.result25 = icmp eq i32 %setjmp24, 0 -- br i1 %setjmp.result25, label %10, label %lpad -+rundefers.callback119: ; preds = %rundefers.loop9 -+ %setjmp20 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 -+ %setjmp.result21 = icmp eq i32 %setjmp20, 0 -+ br i1 %setjmp.result21, label %7, label %lpad - --10: ; preds = %rundefers.callback122 -- call void @"main.deferMultiple$2"(i8* undef) -- br label %rundefers.loophead12 -+7: ; preds = %rundefers.callback119 -+ call void @"main.deferMultiple$2"(ptr undef) -+ br label %rundefers.loophead10 - --rundefers.default10: ; preds = %rundefers.loop11 -+rundefers.default8: ; preds = %rundefers.loop9 - unreachable - --rundefers.end9: ; preds = %rundefers.loophead12 -+rundefers.end7: ; preds = %rundefers.loophead10 - br label %recover - } - - ; Function Attrs: nounwind --define internal void @"main.deferMultiple$1"(i8* %context) unnamed_addr #1 { -+define internal void @"main.deferMultiple$1"(ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.printint32(i32 3, i8* undef) #3 -+ call void @runtime.printint32(i32 3, ptr undef) #3 - ret void - } - - ; Function Attrs: nounwind --define internal void @"main.deferMultiple$2"(i8* %context) unnamed_addr #1 { -+define internal void @"main.deferMultiple$2"(ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.printint32(i32 5, i8* undef) #3 -+ call void @runtime.printint32(i32 5, ptr undef) #3 - ret void - } - - attributes #0 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } - attributes #1 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } --attributes #2 = { nofree nosync nounwind willreturn } -+attributes #2 = { nocallback nofree nosync nounwind willreturn } - attributes #3 = { nounwind } - attributes #4 = { nounwind returns_twice } -diff --git a/compiler/testdata/float.ll b/compiler/testdata/float.ll -index 0ecd21e9..2acc2ed4 100644 ---- a/compiler/testdata/float.ll -+++ b/compiler/testdata/float.ll -@@ -3,18 +3,18 @@ source_filename = "float.go" - target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" - target triple = "wasm32-unknown-wasi" - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden i32 @main.f32tou32(float %v, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.f32tou32(float %v, ptr %context) unnamed_addr #1 { - entry: - %positive = fcmp oge float %v, 0.000000e+00 - %withinmax = fcmp ole float %v, 0x41EFFFFFC0000000 -@@ -26,25 +26,25 @@ entry: - } - - ; Function Attrs: nounwind --define hidden float @main.maxu32f(i8* %context) unnamed_addr #1 { -+define hidden float @main.maxu32f(ptr %context) unnamed_addr #1 { - entry: - ret float 0x41F0000000000000 - } - - ; Function Attrs: nounwind --define hidden i32 @main.maxu32tof32(i8* %context) unnamed_addr #1 { -+define hidden i32 @main.maxu32tof32(ptr %context) unnamed_addr #1 { - entry: - ret i32 -1 - } - - ; Function Attrs: nounwind --define hidden { i32, i32, i32, i32 } @main.inftoi32(i8* %context) unnamed_addr #1 { -+define hidden { i32, i32, i32, i32 } @main.inftoi32(ptr %context) unnamed_addr #1 { - entry: - ret { i32, i32, i32, i32 } { i32 -1, i32 0, i32 2147483647, i32 -2147483648 } - } - - ; Function Attrs: nounwind --define hidden i32 @main.u32tof32tou32(i32 %v, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.u32tof32tou32(i32 %v, ptr %context) unnamed_addr #1 { - entry: - %0 = uitofp i32 %v to float - %withinmax = fcmp ole float %0, 0x41EFFFFFC0000000 -@@ -54,7 +54,7 @@ entry: - } - - ; Function Attrs: nounwind --define hidden float @main.f32tou32tof32(float %v, i8* %context) unnamed_addr #1 { -+define hidden float @main.f32tou32tof32(float %v, ptr %context) unnamed_addr #1 { - entry: - %positive = fcmp oge float %v, 0.000000e+00 - %withinmax = fcmp ole float %v, 0x41EFFFFFC0000000 -@@ -67,7 +67,7 @@ entry: - } - - ; Function Attrs: nounwind --define hidden i8 @main.f32tou8(float %v, i8* %context) unnamed_addr #1 { -+define hidden i8 @main.f32tou8(float %v, ptr %context) unnamed_addr #1 { - entry: - %positive = fcmp oge float %v, 0.000000e+00 - %withinmax = fcmp ole float %v, 2.550000e+02 -@@ -79,7 +79,7 @@ entry: - } - - ; Function Attrs: nounwind --define hidden i8 @main.f32toi8(float %v, i8* %context) unnamed_addr #1 { -+define hidden i8 @main.f32toi8(float %v, ptr %context) unnamed_addr #1 { - entry: - %abovemin = fcmp oge float %v, -1.280000e+02 - %belowmax = fcmp ole float %v, 1.270000e+02 -diff --git a/compiler/testdata/func.ll b/compiler/testdata/func.ll -index 2ed16eaf..227e52c1 100644 ---- a/compiler/testdata/func.ll -+++ b/compiler/testdata/func.ll -@@ -3,43 +3,42 @@ source_filename = "func.go" - target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" - target triple = "wasm32-unknown-wasi" - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.foo(i8* %callback.context, void ()* %callback.funcptr, i8* %context) unnamed_addr #1 { -+define hidden void @main.foo(ptr %callback.context, ptr %callback.funcptr, ptr %context) unnamed_addr #1 { - entry: -- %0 = icmp eq void ()* %callback.funcptr, null -+ %0 = icmp eq ptr %callback.funcptr, null - br i1 %0, label %fpcall.throw, label %fpcall.next - - fpcall.next: ; preds = %entry -- %1 = bitcast void ()* %callback.funcptr to void (i32, i8*)* -- call void %1(i32 3, i8* %callback.context) #2 -+ call void %callback.funcptr(i32 3, ptr %callback.context) #2 - ret void - - fpcall.throw: ; preds = %entry -- call void @runtime.nilPanic(i8* undef) #2 -+ call void @runtime.nilPanic(ptr undef) #2 - unreachable - } - --declare void @runtime.nilPanic(i8*) #0 -+declare void @runtime.nilPanic(ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.bar(i8* %context) unnamed_addr #1 { -+define hidden void @main.bar(ptr %context) unnamed_addr #1 { - entry: -- call void @main.foo(i8* undef, void ()* bitcast (void (i32, i8*)* @main.someFunc to void ()*), i8* undef) -+ call void @main.foo(ptr undef, ptr nonnull @main.someFunc, ptr undef) - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.someFunc(i32 %arg0, i8* %context) unnamed_addr #1 { -+define hidden void @main.someFunc(i32 %arg0, ptr %context) unnamed_addr #1 { - entry: - ret void - } -diff --git a/compiler/testdata/gc.ll b/compiler/testdata/gc.ll -index 26bc4c24..e54b207d 100644 ---- a/compiler/testdata/gc.ll -+++ b/compiler/testdata/gc.ll -@@ -3,133 +3,129 @@ source_filename = "gc.go" - target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" - target triple = "wasm32-unknown-wasi" - --%runtime.typecodeID = type { %runtime.typecodeID*, i32, %runtime.interfaceMethodInfo*, %runtime.typecodeID*, i32 } --%runtime.interfaceMethodInfo = type { i8*, i32 } --%runtime._interface = type { i32, i8* } -+%runtime.typecodeID = type { ptr, i32, ptr, ptr, i32 } -+%runtime._interface = type { i32, ptr } - --@main.scalar1 = hidden global i8* null, align 4 --@main.scalar2 = hidden global i32* null, align 4 --@main.scalar3 = hidden global i64* null, align 4 --@main.scalar4 = hidden global float* null, align 4 --@main.array1 = hidden global [3 x i8]* null, align 4 --@main.array2 = hidden global [71 x i8]* null, align 4 --@main.array3 = hidden global [3 x i8*]* null, align 4 --@main.struct1 = hidden global {}* null, align 4 --@main.struct2 = hidden global { i32, i32 }* null, align 4 --@main.struct3 = hidden global { i8*, [60 x i32], i8* }* null, align 4 --@main.struct4 = hidden global { i8*, [61 x i32] }* null, align 4 --@main.slice1 = hidden global { i8*, i32, i32 } zeroinitializer, align 8 --@main.slice2 = hidden global { i32**, i32, i32 } zeroinitializer, align 8 --@main.slice3 = hidden global { { i8*, i32, i32 }*, i32, i32 } zeroinitializer, align 8 -+@main.scalar1 = hidden global ptr null, align 4 -+@main.scalar2 = hidden global ptr null, align 4 -+@main.scalar3 = hidden global ptr null, align 4 -+@main.scalar4 = hidden global ptr null, align 4 -+@main.array1 = hidden global ptr null, align 4 -+@main.array2 = hidden global ptr null, align 4 -+@main.array3 = hidden global ptr null, align 4 -+@main.struct1 = hidden global ptr null, align 4 -+@main.struct2 = hidden global ptr null, align 4 -+@main.struct3 = hidden global ptr null, align 4 -+@main.struct4 = hidden global ptr null, align 4 -+@main.slice1 = hidden global { ptr, i32, i32 } zeroinitializer, align 8 -+@main.slice2 = hidden global { ptr, i32, i32 } zeroinitializer, align 8 -+@main.slice3 = hidden global { ptr, i32, i32 } zeroinitializer, align 8 - @"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c" \00\00\00\00\00\00\01" } - @"runtime/gc.layout:62-0001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\00\00\00\00\00\00\00\01" } --@"reflect/types.type:basic:complex128" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* null, i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:basic:complex128", i32 0 } --@"reflect/types.type:pointer:basic:complex128" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:basic:complex128", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 } -+@"reflect/types.type:basic:complex128" = linkonce_odr constant %runtime.typecodeID { ptr null, i32 0, ptr null, ptr @"reflect/types.type:pointer:basic:complex128", i32 0 } -+@"reflect/types.type:pointer:basic:complex128" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:basic:complex128", i32 0, ptr null, ptr null, i32 0 } - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.newScalar(i8* %context) unnamed_addr #1 { -+define hidden void @main.newScalar(ptr %context) unnamed_addr #1 { - entry: -- %new = call i8* @runtime.alloc(i32 1, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new, i8* undef) #2 -- store i8* %new, i8** @main.scalar1, align 4 -- %new1 = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new1, i8* undef) #2 -- store i8* %new1, i8** bitcast (i32** @main.scalar2 to i8**), align 4 -- %new2 = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new2, i8* undef) #2 -- store i8* %new2, i8** bitcast (i64** @main.scalar3 to i8**), align 4 -- %new3 = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new3, i8* undef) #2 -- store i8* %new3, i8** bitcast (float** @main.scalar4 to i8**), align 4 -+ %new = call ptr @runtime.alloc(i32 1, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2 -+ store ptr %new, ptr @main.scalar1, align 4 -+ %new1 = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2 -+ store ptr %new1, ptr @main.scalar2, align 4 -+ %new2 = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2 -+ store ptr %new2, ptr @main.scalar3, align 4 -+ %new3 = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new3, ptr undef) #2 -+ store ptr %new3, ptr @main.scalar4, align 4 - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.newArray(i8* %context) unnamed_addr #1 { -+define hidden void @main.newArray(ptr %context) unnamed_addr #1 { - entry: -- %new = call i8* @runtime.alloc(i32 3, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new, i8* undef) #2 -- store i8* %new, i8** bitcast ([3 x i8]** @main.array1 to i8**), align 4 -- %new1 = call i8* @runtime.alloc(i32 71, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new1, i8* undef) #2 -- store i8* %new1, i8** bitcast ([71 x i8]** @main.array2 to i8**), align 4 -- %new2 = call i8* @runtime.alloc(i32 12, i8* nonnull inttoptr (i32 67 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new2, i8* undef) #2 -- store i8* %new2, i8** bitcast ([3 x i8*]** @main.array3 to i8**), align 4 -+ %new = call ptr @runtime.alloc(i32 3, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2 -+ store ptr %new, ptr @main.array1, align 4 -+ %new1 = call ptr @runtime.alloc(i32 71, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2 -+ store ptr %new1, ptr @main.array2, align 4 -+ %new2 = call ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2 -+ store ptr %new2, ptr @main.array3, align 4 - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.newStruct(i8* %context) unnamed_addr #1 { -+define hidden void @main.newStruct(ptr %context) unnamed_addr #1 { - entry: -- %new = call i8* @runtime.alloc(i32 0, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new, i8* undef) #2 -- store i8* %new, i8** bitcast ({}** @main.struct1 to i8**), align 4 -- %new1 = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new1, i8* undef) #2 -- store i8* %new1, i8** bitcast ({ i32, i32 }** @main.struct2 to i8**), align 4 -- %new2 = call i8* @runtime.alloc(i32 248, i8* bitcast ({ i32, [8 x i8] }* @"runtime/gc.layout:62-2000000000000001" to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new2, i8* undef) #2 -- store i8* %new2, i8** bitcast ({ i8*, [60 x i32], i8* }** @main.struct3 to i8**), align 4 -- %new3 = call i8* @runtime.alloc(i32 248, i8* bitcast ({ i32, [8 x i8] }* @"runtime/gc.layout:62-0001" to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %new3, i8* undef) #2 -- store i8* %new3, i8** bitcast ({ i8*, [61 x i32] }** @main.struct4 to i8**), align 4 -+ %new = call ptr @runtime.alloc(i32 0, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2 -+ store ptr %new, ptr @main.struct1, align 4 -+ %new1 = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2 -+ store ptr %new1, ptr @main.struct2, align 4 -+ %new2 = call ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-2000000000000001", ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2 -+ store ptr %new2, ptr @main.struct3, align 4 -+ %new3 = call ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-0001", ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new3, ptr undef) #2 -+ store ptr %new3, ptr @main.struct4, align 4 - ret void - } - - ; Function Attrs: nounwind --define hidden { i8*, void ()* }* @main.newFuncValue(i8* %context) unnamed_addr #1 { -+define hidden ptr @main.newFuncValue(ptr %context) unnamed_addr #1 { - entry: -- %new = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 197 to i8*), i8* undef) #2 -- %0 = bitcast i8* %new to { i8*, void ()* }* -- call void @runtime.trackPointer(i8* nonnull %new, i8* undef) #2 -- ret { i8*, void ()* }* %0 -+ %new = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 197 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2 -+ ret ptr %new - } - - ; Function Attrs: nounwind --define hidden void @main.makeSlice(i8* %context) unnamed_addr #1 { -+define hidden void @main.makeSlice(ptr %context) unnamed_addr #1 { - entry: -- %makeslice = call i8* @runtime.alloc(i32 5, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef) #2 -- store i8* %makeslice, i8** getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 0), align 8 -- store i32 5, i32* getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 1), align 4 -- store i32 5, i32* getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 2), align 8 -- %makeslice1 = call i8* @runtime.alloc(i32 20, i8* nonnull inttoptr (i32 67 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %makeslice1, i8* undef) #2 -- store i8* %makeslice1, i8** bitcast ({ i32**, i32, i32 }* @main.slice2 to i8**), align 8 -- store i32 5, i32* getelementptr inbounds ({ i32**, i32, i32 }, { i32**, i32, i32 }* @main.slice2, i32 0, i32 1), align 4 -- store i32 5, i32* getelementptr inbounds ({ i32**, i32, i32 }, { i32**, i32, i32 }* @main.slice2, i32 0, i32 2), align 8 -- %makeslice3 = call i8* @runtime.alloc(i32 60, i8* nonnull inttoptr (i32 71 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %makeslice3, i8* undef) #2 -- store i8* %makeslice3, i8** bitcast ({ { i8*, i32, i32 }*, i32, i32 }* @main.slice3 to i8**), align 8 -- store i32 5, i32* getelementptr inbounds ({ { i8*, i32, i32 }*, i32, i32 }, { { i8*, i32, i32 }*, i32, i32 }* @main.slice3, i32 0, i32 1), align 4 -- store i32 5, i32* getelementptr inbounds ({ { i8*, i32, i32 }*, i32, i32 }, { { i8*, i32, i32 }*, i32, i32 }* @main.slice3, i32 0, i32 2), align 8 -+ %makeslice = call ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %makeslice, ptr undef) #2 -+ store ptr %makeslice, ptr @main.slice1, align 8 -+ store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 1), align 4 -+ store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 8 -+ %makeslice1 = call ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr undef) #2 -+ store ptr %makeslice1, ptr @main.slice2, align 8 -+ store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 1), align 4 -+ store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 8 -+ %makeslice3 = call ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr undef) #2 -+ store ptr %makeslice3, ptr @main.slice3, align 8 -+ store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 1), align 4 -+ store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 8 - ret void - } - - ; Function Attrs: nounwind --define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, i8* %context) unnamed_addr #1 { -+define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, ptr %context) unnamed_addr #1 { - entry: -- %0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2 -- %.repack = bitcast i8* %0 to double* -- store double %v.r, double* %.repack, align 8 -- %.repack1 = getelementptr inbounds i8, i8* %0, i32 8 -- %1 = bitcast i8* %.repack1 to double* -- store double %v.i, double* %1, align 8 -- %2 = insertvalue %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:basic:complex128" to i32), i8* undef }, i8* %0, 1 -- call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2 -- ret %runtime._interface %2 -+ %0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2 -+ store double %v.r, ptr %0, align 8 -+ %.repack1 = getelementptr inbounds { double, double }, ptr %0, i32 0, i32 1 -+ store double %v.i, ptr %.repack1, align 8 -+ %1 = insertvalue %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:complex128" to i32), ptr undef }, ptr %0, 1 -+ call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2 -+ ret %runtime._interface %1 - } - - attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } -diff --git a/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll b/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll -index edd4d666..ac1adaff 100644 ---- a/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll -+++ b/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll -@@ -3,201 +3,176 @@ source_filename = "goroutine.go" - target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" - target triple = "thumbv7m-unknown-unknown-eabi" - --%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* } --%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } } --%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* } --%"internal/task.gcData" = type {} --%"internal/task.state" = type { i32, i32* } --%runtime.chanSelectState = type { %runtime.channel*, i8* } -+%runtime._string = type { ptr, i32 } - - @"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.regularFunctionGoroutine(i8* %context) unnamed_addr #1 { -+define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #1 { - entry: -- %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (void (i8*)* @"main.regularFunction$gowrapper" to i32), i8* undef) #8 -- call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.regularFunction$gowrapper" to i32), i8* nonnull inttoptr (i32 5 to i8*), i32 %stacksize, i8* undef) #8 -+ %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr undef) #8 -+ call void @"internal/task.start"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 %stacksize, ptr undef) #8 - ret void - } - --declare void @main.regularFunction(i32, i8*) #0 -+declare void @main.regularFunction(i32, ptr) #0 - - ; Function Attrs: nounwind --define linkonce_odr void @"main.regularFunction$gowrapper"(i8* %0) unnamed_addr #2 { -+define linkonce_odr void @"main.regularFunction$gowrapper"(ptr %0) unnamed_addr #2 { - entry: -- %unpack.int = ptrtoint i8* %0 to i32 -- call void @main.regularFunction(i32 %unpack.int, i8* undef) #8 -+ %unpack.int = ptrtoint ptr %0 to i32 -+ call void @main.regularFunction(i32 %unpack.int, ptr undef) #8 - ret void - } - --declare i32 @"internal/task.getGoroutineStackSize"(i32, i8*) #0 -+declare i32 @"internal/task.getGoroutineStackSize"(i32, ptr) #0 - --declare void @"internal/task.start"(i32, i8*, i32, i8*) #0 -+declare void @"internal/task.start"(i32, ptr, i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.inlineFunctionGoroutine(i8* %context) unnamed_addr #1 { -+define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #1 { - entry: -- %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (void (i8*)* @"main.inlineFunctionGoroutine$1$gowrapper" to i32), i8* undef) #8 -- call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.inlineFunctionGoroutine$1$gowrapper" to i32), i8* nonnull inttoptr (i32 5 to i8*), i32 %stacksize, i8* undef) #8 -+ %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.inlineFunctionGoroutine$1$gowrapper" to i32), ptr undef) #8 -+ call void @"internal/task.start"(i32 ptrtoint (ptr @"main.inlineFunctionGoroutine$1$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 %stacksize, ptr undef) #8 - ret void - } - - ; Function Attrs: nounwind --define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 { -+define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(i8* %0) unnamed_addr #3 { -+define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #3 { - entry: -- %unpack.int = ptrtoint i8* %0 to i32 -- call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, i8* undef) -+ %unpack.int = ptrtoint ptr %0 to i32 -+ call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, ptr undef) - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.closureFunctionGoroutine(i8* %context) unnamed_addr #1 { -+define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 { - entry: -- %n = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #8 -- %0 = bitcast i8* %n to i32* -- store i32 3, i32* %0, align 4 -- %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef) #8 -- %2 = bitcast i8* %1 to i32* -- store i32 5, i32* %2, align 4 -- %3 = getelementptr inbounds i8, i8* %1, i32 4 -- %4 = bitcast i8* %3 to i8** -- store i8* %n, i8** %4, align 4 -- %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (void (i8*)* @"main.closureFunctionGoroutine$1$gowrapper" to i32), i8* undef) #8 -- call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.closureFunctionGoroutine$1$gowrapper" to i32), i8* nonnull %1, i32 %stacksize, i8* undef) #8 -- %5 = load i32, i32* %0, align 4 -- call void @runtime.printint32(i32 %5, i8* undef) #8 -+ %n = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #8 -+ store i32 3, ptr %n, align 4 -+ %0 = call ptr @runtime.alloc(i32 8, ptr null, ptr undef) #8 -+ store i32 5, ptr %0, align 4 -+ %1 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1 -+ store ptr %n, ptr %1, align 4 -+ %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr undef) #8 -+ call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #8 -+ %2 = load i32, ptr %n, align 4 -+ call void @runtime.printint32(i32 %2, ptr undef) #8 - ret void - } - - ; Function Attrs: nounwind --define internal void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 { -+define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 { - entry: -- %unpack.ptr = bitcast i8* %context to i32* -- store i32 7, i32* %unpack.ptr, align 4 -+ store i32 7, ptr %context, align 4 - ret void - } - - ; Function Attrs: nounwind --define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(i8* %0) unnamed_addr #4 { -+define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #4 { - entry: -- %1 = bitcast i8* %0 to i32* -- %2 = load i32, i32* %1, align 4 -- %3 = getelementptr inbounds i8, i8* %0, i32 4 -- %4 = bitcast i8* %3 to i8** -- %5 = load i8*, i8** %4, align 4 -- call void @"main.closureFunctionGoroutine$1"(i32 %2, i8* %5) -+ %1 = load i32, ptr %0, align 4 -+ %2 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1 -+ %3 = load ptr, ptr %2, align 4 -+ call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3) - ret void - } - --declare void @runtime.printint32(i32, i8*) #0 -+declare void @runtime.printint32(i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.funcGoroutine(i8* %fn.context, void ()* %fn.funcptr, i8* %context) unnamed_addr #1 { -+define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #1 { - entry: -- %0 = call i8* @runtime.alloc(i32 12, i8* null, i8* undef) #8 -- %1 = bitcast i8* %0 to i32* -- store i32 5, i32* %1, align 4 -- %2 = getelementptr inbounds i8, i8* %0, i32 4 -- %3 = bitcast i8* %2 to i8** -- store i8* %fn.context, i8** %3, align 4 -- %4 = getelementptr inbounds i8, i8* %0, i32 8 -- %5 = bitcast i8* %4 to void ()** -- store void ()* %fn.funcptr, void ()** %5, align 4 -- %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (void (i8*)* @main.funcGoroutine.gowrapper to i32), i8* undef) #8 -- call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @main.funcGoroutine.gowrapper to i32), i8* nonnull %0, i32 %stacksize, i8* undef) #8 -+ %0 = call ptr @runtime.alloc(i32 12, ptr null, ptr undef) #8 -+ store i32 5, ptr %0, align 4 -+ %1 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1 -+ store ptr %fn.context, ptr %1, align 4 -+ %2 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 2 -+ store ptr %fn.funcptr, ptr %2, align 4 -+ %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr undef) #8 -+ call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #8 - ret void - } - - ; Function Attrs: nounwind --define linkonce_odr void @main.funcGoroutine.gowrapper(i8* %0) unnamed_addr #5 { -+define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #5 { - entry: -- %1 = bitcast i8* %0 to i32* -- %2 = load i32, i32* %1, align 4 -- %3 = getelementptr inbounds i8, i8* %0, i32 4 -- %4 = bitcast i8* %3 to i8** -- %5 = load i8*, i8** %4, align 4 -- %6 = getelementptr inbounds i8, i8* %0, i32 8 -- %7 = bitcast i8* %6 to void (i32, i8*)** -- %8 = load void (i32, i8*)*, void (i32, i8*)** %7, align 4 -- call void %8(i32 %2, i8* %5) #8 -+ %1 = load i32, ptr %0, align 4 -+ %2 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1 -+ %3 = load ptr, ptr %2, align 4 -+ %4 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 2 -+ %5 = load ptr, ptr %4, align 4 -+ call void %5(i32 %1, ptr %3) #8 - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.recoverBuiltinGoroutine(i8* %context) unnamed_addr #1 { -+define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.copyBuiltinGoroutine(i8* %dst.data, i32 %dst.len, i32 %dst.cap, i8* %src.data, i32 %src.len, i32 %src.cap, i8* %context) unnamed_addr #1 { -+define hidden void @main.copyBuiltinGoroutine(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #1 { - entry: -- %copy.n = call i32 @runtime.sliceCopy(i8* %dst.data, i8* %src.data, i32 %dst.len, i32 %src.len, i32 1, i8* undef) #8 -+ %copy.n = call i32 @runtime.sliceCopy(ptr %dst.data, ptr %src.data, i32 %dst.len, i32 %src.len, i32 1, ptr undef) #8 - ret void - } - --declare i32 @runtime.sliceCopy(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i32, i8*) #0 -+declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.closeBuiltinGoroutine(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 { -+define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.chanClose(%runtime.channel* %ch, i8* undef) #8 -+ call void @runtime.chanClose(ptr %ch, ptr undef) #8 - ret void - } - --declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i8*) #0 -+declare void @runtime.chanClose(ptr dereferenceable_or_null(32), ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.startInterfaceMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { -+define hidden void @main.startInterfaceMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { - entry: -- %0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef) #8 -- %1 = bitcast i8* %0 to i8** -- store i8* %itf.value, i8** %1, align 4 -- %2 = getelementptr inbounds i8, i8* %0, i32 4 -- %.repack = bitcast i8* %2 to i8** -- store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main$string", i32 0, i32 0), i8** %.repack, align 4 -- %.repack1 = getelementptr inbounds i8, i8* %0, i32 8 -- %3 = bitcast i8* %.repack1 to i32* -- store i32 4, i32* %3, align 4 -- %4 = getelementptr inbounds i8, i8* %0, i32 12 -- %5 = bitcast i8* %4 to i32* -- store i32 %itf.typecode, i32* %5, align 4 -- %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (void (i8*)* @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), i8* undef) #8 -- call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), i8* nonnull %0, i32 %stacksize, i8* undef) #8 -+ %0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #8 -+ store ptr %itf.value, ptr %0, align 4 -+ %1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1 -+ store ptr @"main$string", ptr %1, align 4 -+ %.repack1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1, i32 1 -+ store i32 4, ptr %.repack1, align 4 -+ %2 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 2 -+ store i32 %itf.typecode, ptr %2, align 4 -+ %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr undef) #8 -+ call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #8 - ret void - } - --declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(i8*, i8*, i32, i32, i8*) #6 -+declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr, ptr, i32, i32, ptr) #6 - - ; Function Attrs: nounwind --define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(i8* %0) unnamed_addr #7 { -+define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #7 { - entry: -- %1 = bitcast i8* %0 to i8** -- %2 = load i8*, i8** %1, align 4 -- %3 = getelementptr inbounds i8, i8* %0, i32 4 -- %4 = bitcast i8* %3 to i8** -- %5 = load i8*, i8** %4, align 4 -- %6 = getelementptr inbounds i8, i8* %0, i32 8 -- %7 = bitcast i8* %6 to i32* -- %8 = load i32, i32* %7, align 4 -- %9 = getelementptr inbounds i8, i8* %0, i32 12 -- %10 = bitcast i8* %9 to i32* -- %11 = load i32, i32* %10, align 4 -- call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(i8* %2, i8* %5, i32 %8, i32 %11, i8* undef) #8 -+ %1 = load ptr, ptr %0, align 4 -+ %2 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 1 -+ %3 = load ptr, ptr %2, align 4 -+ %4 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 2 -+ %5 = load i32, ptr %4, align 4 -+ %6 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 3 -+ %7 = load i32, ptr %6, align 4 -+ call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, i32 %7, ptr undef) #8 - ret void - } - -diff --git a/compiler/testdata/goroutine-wasm-asyncify.ll b/compiler/testdata/goroutine-wasm-asyncify.ll -index 21da7477..280f216a 100644 ---- a/compiler/testdata/goroutine-wasm-asyncify.ll -+++ b/compiler/testdata/goroutine-wasm-asyncify.ll -@@ -3,210 +3,184 @@ source_filename = "goroutine.go" - target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" - target triple = "wasm32-unknown-wasi" - --%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* } --%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } } --%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* } --%"internal/task.gcData" = type { i8* } --%"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 } --%"internal/task.stackState" = type { i32, i32 } --%runtime.chanSelectState = type { %runtime.channel*, i8* } -+%runtime._string = type { ptr, i32 } - - @"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.regularFunctionGoroutine(i8* %context) unnamed_addr #1 { -+define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #1 { - entry: -- call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.regularFunction$gowrapper" to i32), i8* nonnull inttoptr (i32 5 to i8*), i32 16384, i8* undef) #8 -+ call void @"internal/task.start"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 16384, ptr undef) #8 - ret void - } - --declare void @main.regularFunction(i32, i8*) #0 -+declare void @main.regularFunction(i32, ptr) #0 - --declare void @runtime.deadlock(i8*) #0 -+declare void @runtime.deadlock(ptr) #0 - - ; Function Attrs: nounwind --define linkonce_odr void @"main.regularFunction$gowrapper"(i8* %0) unnamed_addr #2 { -+define linkonce_odr void @"main.regularFunction$gowrapper"(ptr %0) unnamed_addr #2 { - entry: -- %unpack.int = ptrtoint i8* %0 to i32 -- call void @main.regularFunction(i32 %unpack.int, i8* undef) #8 -- call void @runtime.deadlock(i8* undef) #8 -+ %unpack.int = ptrtoint ptr %0 to i32 -+ call void @main.regularFunction(i32 %unpack.int, ptr undef) #8 -+ call void @runtime.deadlock(ptr undef) #8 - unreachable - } - --declare void @"internal/task.start"(i32, i8*, i32, i8*) #0 -+declare void @"internal/task.start"(i32, ptr, i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.inlineFunctionGoroutine(i8* %context) unnamed_addr #1 { -+define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #1 { - entry: -- call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.inlineFunctionGoroutine$1$gowrapper" to i32), i8* nonnull inttoptr (i32 5 to i8*), i32 16384, i8* undef) #8 -+ call void @"internal/task.start"(i32 ptrtoint (ptr @"main.inlineFunctionGoroutine$1$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 16384, ptr undef) #8 - ret void - } - - ; Function Attrs: nounwind --define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 { -+define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(i8* %0) unnamed_addr #3 { -+define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #3 { - entry: -- %unpack.int = ptrtoint i8* %0 to i32 -- call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, i8* undef) -- call void @runtime.deadlock(i8* undef) #8 -+ %unpack.int = ptrtoint ptr %0 to i32 -+ call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, ptr undef) -+ call void @runtime.deadlock(ptr undef) #8 - unreachable - } - - ; Function Attrs: nounwind --define hidden void @main.closureFunctionGoroutine(i8* %context) unnamed_addr #1 { --entry: -- %n = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #8 -- %0 = bitcast i8* %n to i32* -- call void @runtime.trackPointer(i8* nonnull %n, i8* undef) #8 -- store i32 3, i32* %0, align 4 -- call void @runtime.trackPointer(i8* nonnull %n, i8* undef) #8 -- call void @runtime.trackPointer(i8* bitcast (void (i32, i8*)* @"main.closureFunctionGoroutine$1" to i8*), i8* undef) #8 -- %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef) #8 -- call void @runtime.trackPointer(i8* nonnull %1, i8* undef) #8 -- %2 = bitcast i8* %1 to i32* -- store i32 5, i32* %2, align 4 -- %3 = getelementptr inbounds i8, i8* %1, i32 4 -- %4 = bitcast i8* %3 to i8** -- store i8* %n, i8** %4, align 4 -- call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.closureFunctionGoroutine$1$gowrapper" to i32), i8* nonnull %1, i32 16384, i8* undef) #8 -- %5 = load i32, i32* %0, align 4 -- call void @runtime.printint32(i32 %5, i8* undef) #8 -+define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 { -+entry: -+ %n = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #8 -+ call void @runtime.trackPointer(ptr nonnull %n, ptr undef) #8 -+ store i32 3, ptr %n, align 4 -+ call void @runtime.trackPointer(ptr nonnull %n, ptr undef) #8 -+ call void @runtime.trackPointer(ptr nonnull @"main.closureFunctionGoroutine$1", ptr undef) #8 -+ %0 = call ptr @runtime.alloc(i32 8, ptr null, ptr undef) #8 -+ call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8 -+ store i32 5, ptr %0, align 4 -+ %1 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1 -+ store ptr %n, ptr %1, align 4 -+ call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 16384, ptr undef) #8 -+ %2 = load i32, ptr %n, align 4 -+ call void @runtime.printint32(i32 %2, ptr undef) #8 - ret void - } - - ; Function Attrs: nounwind --define internal void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 { -+define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 { - entry: -- %unpack.ptr = bitcast i8* %context to i32* -- store i32 7, i32* %unpack.ptr, align 4 -+ store i32 7, ptr %context, align 4 - ret void - } - - ; Function Attrs: nounwind --define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(i8* %0) unnamed_addr #4 { -+define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #4 { - entry: -- %1 = bitcast i8* %0 to i32* -- %2 = load i32, i32* %1, align 4 -- %3 = getelementptr inbounds i8, i8* %0, i32 4 -- %4 = bitcast i8* %3 to i8** -- %5 = load i8*, i8** %4, align 4 -- call void @"main.closureFunctionGoroutine$1"(i32 %2, i8* %5) -- call void @runtime.deadlock(i8* undef) #8 -+ %1 = load i32, ptr %0, align 4 -+ %2 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1 -+ %3 = load ptr, ptr %2, align 4 -+ call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3) -+ call void @runtime.deadlock(ptr undef) #8 - unreachable - } - --declare void @runtime.printint32(i32, i8*) #0 -+declare void @runtime.printint32(i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.funcGoroutine(i8* %fn.context, void ()* %fn.funcptr, i8* %context) unnamed_addr #1 { -+define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #1 { - entry: -- %0 = call i8* @runtime.alloc(i32 12, i8* null, i8* undef) #8 -- call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #8 -- %1 = bitcast i8* %0 to i32* -- store i32 5, i32* %1, align 4 -- %2 = getelementptr inbounds i8, i8* %0, i32 4 -- %3 = bitcast i8* %2 to i8** -- store i8* %fn.context, i8** %3, align 4 -- %4 = getelementptr inbounds i8, i8* %0, i32 8 -- %5 = bitcast i8* %4 to void ()** -- store void ()* %fn.funcptr, void ()** %5, align 4 -- call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @main.funcGoroutine.gowrapper to i32), i8* nonnull %0, i32 16384, i8* undef) #8 -+ %0 = call ptr @runtime.alloc(i32 12, ptr null, ptr undef) #8 -+ call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8 -+ store i32 5, ptr %0, align 4 -+ %1 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1 -+ store ptr %fn.context, ptr %1, align 4 -+ %2 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 2 -+ store ptr %fn.funcptr, ptr %2, align 4 -+ call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 16384, ptr undef) #8 - ret void - } - - ; Function Attrs: nounwind --define linkonce_odr void @main.funcGoroutine.gowrapper(i8* %0) unnamed_addr #5 { -+define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #5 { - entry: -- %1 = bitcast i8* %0 to i32* -- %2 = load i32, i32* %1, align 4 -- %3 = getelementptr inbounds i8, i8* %0, i32 4 -- %4 = bitcast i8* %3 to i8** -- %5 = load i8*, i8** %4, align 4 -- %6 = getelementptr inbounds i8, i8* %0, i32 8 -- %7 = bitcast i8* %6 to void (i32, i8*)** -- %8 = load void (i32, i8*)*, void (i32, i8*)** %7, align 4 -- call void %8(i32 %2, i8* %5) #8 -- call void @runtime.deadlock(i8* undef) #8 -+ %1 = load i32, ptr %0, align 4 -+ %2 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1 -+ %3 = load ptr, ptr %2, align 4 -+ %4 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 2 -+ %5 = load ptr, ptr %4, align 4 -+ call void %5(i32 %1, ptr %3) #8 -+ call void @runtime.deadlock(ptr undef) #8 - unreachable - } - - ; Function Attrs: nounwind --define hidden void @main.recoverBuiltinGoroutine(i8* %context) unnamed_addr #1 { -+define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.copyBuiltinGoroutine(i8* %dst.data, i32 %dst.len, i32 %dst.cap, i8* %src.data, i32 %src.len, i32 %src.cap, i8* %context) unnamed_addr #1 { -+define hidden void @main.copyBuiltinGoroutine(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #1 { - entry: -- %copy.n = call i32 @runtime.sliceCopy(i8* %dst.data, i8* %src.data, i32 %dst.len, i32 %src.len, i32 1, i8* undef) #8 -+ %copy.n = call i32 @runtime.sliceCopy(ptr %dst.data, ptr %src.data, i32 %dst.len, i32 %src.len, i32 1, ptr undef) #8 - ret void - } - --declare i32 @runtime.sliceCopy(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i32, i8*) #0 -+declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.closeBuiltinGoroutine(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 { -+define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.chanClose(%runtime.channel* %ch, i8* undef) #8 -+ call void @runtime.chanClose(ptr %ch, ptr undef) #8 - ret void - } - --declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i8*) #0 -+declare void @runtime.chanClose(ptr dereferenceable_or_null(32), ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.startInterfaceMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { -+define hidden void @main.startInterfaceMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { - entry: -- %0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef) #8 -- call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #8 -- %1 = bitcast i8* %0 to i8** -- store i8* %itf.value, i8** %1, align 4 -- %2 = getelementptr inbounds i8, i8* %0, i32 4 -- %.repack = bitcast i8* %2 to i8** -- store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main$string", i32 0, i32 0), i8** %.repack, align 4 -- %.repack1 = getelementptr inbounds i8, i8* %0, i32 8 -- %3 = bitcast i8* %.repack1 to i32* -- store i32 4, i32* %3, align 4 -- %4 = getelementptr inbounds i8, i8* %0, i32 12 -- %5 = bitcast i8* %4 to i32* -- store i32 %itf.typecode, i32* %5, align 4 -- call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), i8* nonnull %0, i32 16384, i8* undef) #8 -+ %0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #8 -+ call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8 -+ store ptr %itf.value, ptr %0, align 4 -+ %1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1 -+ store ptr @"main$string", ptr %1, align 4 -+ %.repack1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1, i32 1 -+ store i32 4, ptr %.repack1, align 4 -+ %2 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 2 -+ store i32 %itf.typecode, ptr %2, align 4 -+ call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 16384, ptr undef) #8 - ret void - } - --declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(i8*, i8*, i32, i32, i8*) #6 -+declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr, ptr, i32, i32, ptr) #6 - - ; Function Attrs: nounwind --define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(i8* %0) unnamed_addr #7 { -+define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #7 { - entry: -- %1 = bitcast i8* %0 to i8** -- %2 = load i8*, i8** %1, align 4 -- %3 = getelementptr inbounds i8, i8* %0, i32 4 -- %4 = bitcast i8* %3 to i8** -- %5 = load i8*, i8** %4, align 4 -- %6 = getelementptr inbounds i8, i8* %0, i32 8 -- %7 = bitcast i8* %6 to i32* -- %8 = load i32, i32* %7, align 4 -- %9 = getelementptr inbounds i8, i8* %0, i32 12 -- %10 = bitcast i8* %9 to i32* -- %11 = load i32, i32* %10, align 4 -- call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(i8* %2, i8* %5, i32 %8, i32 %11, i8* undef) #8 -- call void @runtime.deadlock(i8* undef) #8 -+ %1 = load ptr, ptr %0, align 4 -+ %2 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 1 -+ %3 = load ptr, ptr %2, align 4 -+ %4 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 2 -+ %5 = load i32, ptr %4, align 4 -+ %6 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 3 -+ %7 = load i32, ptr %6, align 4 -+ call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, i32 %7, ptr undef) #8 -+ call void @runtime.deadlock(ptr undef) #8 - unreachable - } - -diff --git a/compiler/testdata/interface.ll b/compiler/testdata/interface.ll -index 0b44585a..38d4e567 100644 ---- a/compiler/testdata/interface.ll -+++ b/compiler/testdata/interface.ll -@@ -3,71 +3,70 @@ source_filename = "interface.go" - target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" - target triple = "wasm32-unknown-wasi" - --%runtime.typecodeID = type { %runtime.typecodeID*, i32, %runtime.interfaceMethodInfo*, %runtime.typecodeID*, i32 } --%runtime.interfaceMethodInfo = type { i8*, i32 } --%runtime._interface = type { i32, i8* } --%runtime._string = type { i8*, i32 } -- --@"reflect/types.type:basic:int" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* null, i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:basic:int", i32 0 } --@"reflect/types.type:pointer:basic:int" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:basic:int", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 } --@"reflect/types.type:pointer:named:error" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:named:error", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 } --@"reflect/types.type:named:error" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:named:error", i32 ptrtoint (i1 (i32)* @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) } --@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* bitcast ([1 x i8*]* @"reflect/types.interface:interface{Error() string}$interface" to %runtime.typecodeID*), i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}", i32 ptrtoint (i1 (i32)* @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) } -+%runtime.typecodeID = type { ptr, i32, ptr, ptr, i32 } -+%runtime._interface = type { i32, ptr } -+%runtime._string = type { ptr, i32 } -+ -+@"reflect/types.type:basic:int" = linkonce_odr constant %runtime.typecodeID { ptr null, i32 0, ptr null, ptr @"reflect/types.type:pointer:basic:int", i32 0 } -+@"reflect/types.type:pointer:basic:int" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:basic:int", i32 0, ptr null, ptr null, i32 0 } -+@"reflect/types.type:pointer:named:error" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:named:error", i32 0, ptr null, ptr null, i32 0 } -+@"reflect/types.type:named:error" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, ptr null, ptr @"reflect/types.type:pointer:named:error", i32 ptrtoint (ptr @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) } -+@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.interface:interface{Error() string}$interface", i32 0, ptr null, ptr @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}", i32 ptrtoint (ptr @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) } - @"reflect/methods.Error() string" = linkonce_odr constant i8 0, align 1 --@"reflect/types.interface:interface{Error() string}$interface" = linkonce_odr constant [1 x i8*] [i8* @"reflect/methods.Error() string"] --@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 } --@"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:interface:{String:func:{}{basic:string}}", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 } --@"reflect/types.type:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* bitcast ([1 x i8*]* @"reflect/types.interface:interface{String() string}$interface" to %runtime.typecodeID*), i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", i32 ptrtoint (i1 (i32)* @"interface:{String:func:{}{basic:string}}.$typeassert" to i32) } -+@"reflect/types.interface:interface{Error() string}$interface" = linkonce_odr constant [1 x ptr] [ptr @"reflect/methods.Error() string"] -+@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, ptr null, ptr null, i32 0 } -+@"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:interface:{String:func:{}{basic:string}}", i32 0, ptr null, ptr null, i32 0 } -+@"reflect/types.type:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.interface:interface{String() string}$interface", i32 0, ptr null, ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", i32 ptrtoint (ptr @"interface:{String:func:{}{basic:string}}.$typeassert" to i32) } - @"reflect/methods.String() string" = linkonce_odr constant i8 0, align 1 --@"reflect/types.interface:interface{String() string}$interface" = linkonce_odr constant [1 x i8*] [i8* @"reflect/methods.String() string"] -+@"reflect/types.interface:interface{String() string}$interface" = linkonce_odr constant [1 x ptr] [ptr @"reflect/methods.String() string"] - @"reflect/types.typeid:basic:int" = external constant i8 - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden %runtime._interface @main.simpleType(i8* %context) unnamed_addr #1 { -+define hidden %runtime._interface @main.simpleType(ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.trackPointer(i8* null, i8* undef) #6 -- ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:basic:int" to i32), i8* null } -+ call void @runtime.trackPointer(ptr null, ptr undef) #6 -+ ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:int" to i32), ptr null } - } - - ; Function Attrs: nounwind --define hidden %runtime._interface @main.pointerType(i8* %context) unnamed_addr #1 { -+define hidden %runtime._interface @main.pointerType(ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.trackPointer(i8* null, i8* undef) #6 -- ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:basic:int" to i32), i8* null } -+ call void @runtime.trackPointer(ptr null, ptr undef) #6 -+ ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:basic:int" to i32), ptr null } - } - - ; Function Attrs: nounwind --define hidden %runtime._interface @main.interfaceType(i8* %context) unnamed_addr #1 { -+define hidden %runtime._interface @main.interfaceType(ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.trackPointer(i8* null, i8* undef) #6 -- ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:named:error" to i32), i8* null } -+ call void @runtime.trackPointer(ptr null, ptr undef) #6 -+ ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:named:error" to i32), ptr null } - } - - declare i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(i32) #2 - - ; Function Attrs: nounwind --define hidden %runtime._interface @main.anonymousInterfaceType(i8* %context) unnamed_addr #1 { -+define hidden %runtime._interface @main.anonymousInterfaceType(ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.trackPointer(i8* null, i8* undef) #6 -- ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), i8* null } -+ call void @runtime.trackPointer(ptr null, ptr undef) #6 -+ ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), ptr null } - } - - declare i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(i32) #3 - - ; Function Attrs: nounwind --define hidden i1 @main.isInt(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.isInt(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { - entry: -- %typecode = call i1 @runtime.typeAssert(i32 %itf.typecode, i8* nonnull @"reflect/types.typeid:basic:int", i8* undef) #6 -+ %typecode = call i1 @runtime.typeAssert(i32 %itf.typecode, ptr nonnull @"reflect/types.typeid:basic:int", ptr undef) #6 - br i1 %typecode, label %typeassert.ok, label %typeassert.next - - typeassert.next: ; preds = %typeassert.ok, %entry -@@ -77,10 +76,10 @@ typeassert.ok: ; preds = %entry - br label %typeassert.next - } - --declare i1 @runtime.typeAssert(i32, i8* dereferenceable_or_null(1), i8*) #0 -+declare i1 @runtime.typeAssert(i32, ptr dereferenceable_or_null(1), ptr) #0 - - ; Function Attrs: nounwind --define hidden i1 @main.isError(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.isError(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { - entry: - %0 = call i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(i32 %itf.typecode) #6 - br i1 %0, label %typeassert.ok, label %typeassert.next -@@ -93,7 +92,7 @@ typeassert.ok: ; preds = %entry - } - - ; Function Attrs: nounwind --define hidden i1 @main.isStringer(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.isStringer(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { - entry: - %0 = call i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(i32 %itf.typecode) #6 - br i1 %0, label %typeassert.ok, label %typeassert.next -@@ -106,24 +105,24 @@ typeassert.ok: ; preds = %entry - } - - ; Function Attrs: nounwind --define hidden i8 @main.callFooMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { -+define hidden i8 @main.callFooMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { - entry: -- %0 = call i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(i8* %itf.value, i32 3, i32 %itf.typecode, i8* undef) #6 -+ %0 = call i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr %itf.value, i32 3, i32 %itf.typecode, ptr undef) #6 - ret i8 %0 - } - --declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(i8*, i32, i32, i8*) #4 -+declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr, i32, i32, ptr) #4 - - ; Function Attrs: nounwind --define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { -+define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { - entry: -- %0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(i8* %itf.value, i32 %itf.typecode, i8* undef) #6 -+ %0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr %itf.value, i32 %itf.typecode, ptr undef) #6 - %1 = extractvalue %runtime._string %0, 0 -- call void @runtime.trackPointer(i8* %1, i8* undef) #6 -+ call void @runtime.trackPointer(ptr %1, ptr undef) #6 - ret %runtime._string %0 - } - --declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(i8*, i32, i8*) #5 -+declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr, i32, ptr) #5 - - attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } - attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } -diff --git a/compiler/testdata/pointer.ll b/compiler/testdata/pointer.ll -index cedea380..9bc8bd35 100644 ---- a/compiler/testdata/pointer.ll -+++ b/compiler/testdata/pointer.ll -@@ -3,76 +3,72 @@ source_filename = "pointer.go" - target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" - target triple = "wasm32-unknown-wasi" - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden [0 x i32] @main.pointerDerefZero([0 x i32]* %x, i8* %context) unnamed_addr #1 { -+define hidden [0 x i32] @main.pointerDerefZero(ptr %x, ptr %context) unnamed_addr #1 { - entry: - ret [0 x i32] zeroinitializer - } - - ; Function Attrs: nounwind --define hidden i32* @main.pointerCastFromUnsafe(i8* %x, i8* %context) unnamed_addr #1 { -+define hidden ptr @main.pointerCastFromUnsafe(ptr %x, ptr %context) unnamed_addr #1 { - entry: -- %0 = bitcast i8* %x to i32* -- call void @runtime.trackPointer(i8* %x, i8* undef) #2 -- ret i32* %0 -+ call void @runtime.trackPointer(ptr %x, ptr undef) #2 -+ ret ptr %x - } - - ; Function Attrs: nounwind --define hidden i8* @main.pointerCastToUnsafe(i32* dereferenceable_or_null(4) %x, i8* %context) unnamed_addr #1 { -+define hidden ptr @main.pointerCastToUnsafe(ptr dereferenceable_or_null(4) %x, ptr %context) unnamed_addr #1 { - entry: -- %0 = bitcast i32* %x to i8* -- call void @runtime.trackPointer(i8* %0, i8* undef) #2 -- ret i8* %0 -+ call void @runtime.trackPointer(ptr %x, ptr undef) #2 -+ ret ptr %x - } - - ; Function Attrs: nounwind --define hidden i8* @main.pointerCastToUnsafeNoop(i8* dereferenceable_or_null(1) %x, i8* %context) unnamed_addr #1 { -+define hidden ptr @main.pointerCastToUnsafeNoop(ptr dereferenceable_or_null(1) %x, ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.trackPointer(i8* %x, i8* undef) #2 -- ret i8* %x -+ call void @runtime.trackPointer(ptr %x, ptr undef) #2 -+ ret ptr %x - } - - ; Function Attrs: nounwind --define hidden i8* @main.pointerUnsafeGEPFixedOffset(i8* dereferenceable_or_null(1) %ptr, i8* %context) unnamed_addr #1 { -+define hidden ptr @main.pointerUnsafeGEPFixedOffset(ptr dereferenceable_or_null(1) %ptr, ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.trackPointer(i8* %ptr, i8* undef) #2 -- %0 = getelementptr inbounds i8, i8* %ptr, i32 10 -- call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #2 -- ret i8* %0 -+ call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 -+ %0 = getelementptr inbounds i8, ptr %ptr, i32 10 -+ call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2 -+ ret ptr %0 - } - - ; Function Attrs: nounwind --define hidden i8* @main.pointerUnsafeGEPByteOffset(i8* dereferenceable_or_null(1) %ptr, i32 %offset, i8* %context) unnamed_addr #1 { -+define hidden ptr @main.pointerUnsafeGEPByteOffset(ptr dereferenceable_or_null(1) %ptr, i32 %offset, ptr %context) unnamed_addr #1 { - entry: -- call void @runtime.trackPointer(i8* %ptr, i8* undef) #2 -- %0 = getelementptr inbounds i8, i8* %ptr, i32 %offset -- call void @runtime.trackPointer(i8* %0, i8* undef) #2 -- call void @runtime.trackPointer(i8* %0, i8* undef) #2 -- ret i8* %0 -+ call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 -+ %0 = getelementptr inbounds i8, ptr %ptr, i32 %offset -+ call void @runtime.trackPointer(ptr %0, ptr undef) #2 -+ call void @runtime.trackPointer(ptr %0, ptr undef) #2 -+ ret ptr %0 - } - - ; Function Attrs: nounwind --define hidden i32* @main.pointerUnsafeGEPIntOffset(i32* dereferenceable_or_null(4) %ptr, i32 %offset, i8* %context) unnamed_addr #1 { -+define hidden ptr @main.pointerUnsafeGEPIntOffset(ptr dereferenceable_or_null(4) %ptr, i32 %offset, ptr %context) unnamed_addr #1 { - entry: -- %0 = bitcast i32* %ptr to i8* -- call void @runtime.trackPointer(i8* %0, i8* undef) #2 -- %1 = getelementptr i32, i32* %ptr, i32 %offset -- %2 = bitcast i32* %1 to i8* -- call void @runtime.trackPointer(i8* %2, i8* undef) #2 -- %3 = bitcast i32* %1 to i8* -- call void @runtime.trackPointer(i8* %3, i8* undef) #2 -- ret i32* %1 -+ call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 -+ %0 = shl i32 %offset, 2 -+ %1 = getelementptr inbounds i8, ptr %ptr, i32 %0 -+ call void @runtime.trackPointer(ptr %1, ptr undef) #2 -+ call void @runtime.trackPointer(ptr %1, ptr undef) #2 -+ ret ptr %1 - } - - attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } -diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll -index b243602d..c49c83bd 100644 ---- a/compiler/testdata/pragma.ll -+++ b/compiler/testdata/pragma.ll -@@ -10,12 +10,12 @@ target triple = "wasm32-unknown-wasi" - @undefinedGlobalNotInSection = external global i32, align 4 - @main.multipleGlobalPragmas = hidden global i32 0, section ".global_section", align 1024 - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } -@@ -27,27 +27,27 @@ entry: - } - - ; Function Attrs: nounwind --define hidden void @somepkg.someFunction1(i8* %context) unnamed_addr #1 { -+define hidden void @somepkg.someFunction1(ptr %context) unnamed_addr #1 { - entry: - ret void - } - --declare void @somepkg.someFunction2(i8*) #0 -+declare void @somepkg.someFunction2(ptr) #0 - - ; Function Attrs: inlinehint nounwind --define hidden void @main.inlineFunc(i8* %context) unnamed_addr #3 { -+define hidden void @main.inlineFunc(ptr %context) unnamed_addr #3 { - entry: - ret void - } - - ; Function Attrs: noinline nounwind --define hidden void @main.noinlineFunc(i8* %context) unnamed_addr #4 { -+define hidden void @main.noinlineFunc(ptr %context) unnamed_addr #4 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden void @main.functionInSection(i8* %context) unnamed_addr #1 section ".special_function_section" { -+define hidden void @main.functionInSection(ptr %context) unnamed_addr #1 section ".special_function_section" { - entry: - ret void - } -@@ -58,7 +58,7 @@ entry: - ret void - } - --declare void @main.undefinedFunctionNotInSection(i8*) #0 -+declare void @main.undefinedFunctionNotInSection(ptr) #0 - - attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } - attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } -diff --git a/compiler/testdata/slice.ll b/compiler/testdata/slice.ll -index c2e3ebd9..56e40f5f 100644 ---- a/compiler/testdata/slice.ll -+++ b/compiler/testdata/slice.ll -@@ -3,286 +3,270 @@ source_filename = "slice.go" - target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" - target triple = "wasm32-unknown-wasi" - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden i32 @main.sliceLen(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.sliceLen(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 { - entry: - ret i32 %ints.len - } - - ; Function Attrs: nounwind --define hidden i32 @main.sliceCap(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.sliceCap(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 { - entry: - ret i32 %ints.cap - } - - ; Function Attrs: nounwind --define hidden i32 @main.sliceElement(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i32 %index, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.sliceElement(ptr %ints.data, i32 %ints.len, i32 %ints.cap, i32 %index, ptr %context) unnamed_addr #1 { - entry: - %.not = icmp ult i32 %index, %ints.len - br i1 %.not, label %lookup.next, label %lookup.throw - - lookup.next: ; preds = %entry -- %0 = getelementptr inbounds i32, i32* %ints.data, i32 %index -- %1 = load i32, i32* %0, align 4 -+ %0 = getelementptr inbounds i32, ptr %ints.data, i32 %index -+ %1 = load i32, ptr %0, align 4 - ret i32 %1 - - lookup.throw: ; preds = %entry -- call void @runtime.lookupPanic(i8* undef) #2 -+ call void @runtime.lookupPanic(ptr undef) #2 - unreachable - } - --declare void @runtime.lookupPanic(i8*) #0 -+declare void @runtime.lookupPanic(ptr) #0 - - ; Function Attrs: nounwind --define hidden { i32*, i32, i32 } @main.sliceAppendValues(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i8* %context) unnamed_addr #1 { -+define hidden { ptr, i32, i32 } @main.sliceAppendValues(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 { - entry: -- %varargs = call i8* @runtime.alloc(i32 12, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %varargs, i8* undef) #2 -- %0 = bitcast i8* %varargs to i32* -- store i32 1, i32* %0, align 4 -- %1 = getelementptr inbounds i8, i8* %varargs, i32 4 -- %2 = bitcast i8* %1 to i32* -- store i32 2, i32* %2, align 4 -- %3 = getelementptr inbounds i8, i8* %varargs, i32 8 -- %4 = bitcast i8* %3 to i32* -- store i32 3, i32* %4, align 4 -- %append.srcPtr = bitcast i32* %ints.data to i8* -- %append.new = call { i8*, i32, i32 } @runtime.sliceAppend(i8* %append.srcPtr, i8* nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, i8* undef) #2 -- %append.newPtr = extractvalue { i8*, i32, i32 } %append.new, 0 -- %append.newBuf = bitcast i8* %append.newPtr to i32* -- %append.newLen = extractvalue { i8*, i32, i32 } %append.new, 1 -- %append.newCap = extractvalue { i8*, i32, i32 } %append.new, 2 -- %5 = insertvalue { i32*, i32, i32 } undef, i32* %append.newBuf, 0 -- %6 = insertvalue { i32*, i32, i32 } %5, i32 %append.newLen, 1 -- %7 = insertvalue { i32*, i32, i32 } %6, i32 %append.newCap, 2 -- call void @runtime.trackPointer(i8* %append.newPtr, i8* undef) #2 -- ret { i32*, i32, i32 } %7 -+ %varargs = call ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %varargs, ptr undef) #2 -+ store i32 1, ptr %varargs, align 4 -+ %0 = getelementptr inbounds [3 x i32], ptr %varargs, i32 0, i32 1 -+ store i32 2, ptr %0, align 4 -+ %1 = getelementptr inbounds [3 x i32], ptr %varargs, i32 0, i32 2 -+ store i32 3, ptr %1, align 4 -+ %append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, ptr undef) #2 -+ %append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0 -+ %append.newLen = extractvalue { ptr, i32, i32 } %append.new, 1 -+ %append.newCap = extractvalue { ptr, i32, i32 } %append.new, 2 -+ %2 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0 -+ %3 = insertvalue { ptr, i32, i32 } %2, i32 %append.newLen, 1 -+ %4 = insertvalue { ptr, i32, i32 } %3, i32 %append.newCap, 2 -+ call void @runtime.trackPointer(ptr %append.newPtr, ptr undef) #2 -+ ret { ptr, i32, i32 } %4 - } - --declare { i8*, i32, i32 } @runtime.sliceAppend(i8*, i8* nocapture readonly, i32, i32, i32, i32, i8*) #0 -+declare { ptr, i32, i32 } @runtime.sliceAppend(ptr, ptr nocapture readonly, i32, i32, i32, i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden { i32*, i32, i32 } @main.sliceAppendSlice(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i32* %added.data, i32 %added.len, i32 %added.cap, i8* %context) unnamed_addr #1 { -+define hidden { ptr, i32, i32 } @main.sliceAppendSlice(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %added.data, i32 %added.len, i32 %added.cap, ptr %context) unnamed_addr #1 { - entry: -- %append.srcPtr = bitcast i32* %ints.data to i8* -- %append.srcPtr1 = bitcast i32* %added.data to i8* -- %append.new = call { i8*, i32, i32 } @runtime.sliceAppend(i8* %append.srcPtr, i8* %append.srcPtr1, i32 %ints.len, i32 %ints.cap, i32 %added.len, i32 4, i8* undef) #2 -- %append.newPtr = extractvalue { i8*, i32, i32 } %append.new, 0 -- %append.newBuf = bitcast i8* %append.newPtr to i32* -- %append.newLen = extractvalue { i8*, i32, i32 } %append.new, 1 -- %append.newCap = extractvalue { i8*, i32, i32 } %append.new, 2 -- %0 = insertvalue { i32*, i32, i32 } undef, i32* %append.newBuf, 0 -- %1 = insertvalue { i32*, i32, i32 } %0, i32 %append.newLen, 1 -- %2 = insertvalue { i32*, i32, i32 } %1, i32 %append.newCap, 2 -- call void @runtime.trackPointer(i8* %append.newPtr, i8* undef) #2 -- ret { i32*, i32, i32 } %2 -+ %append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr %added.data, i32 %ints.len, i32 %ints.cap, i32 %added.len, i32 4, ptr undef) #2 -+ %append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0 -+ %append.newLen = extractvalue { ptr, i32, i32 } %append.new, 1 -+ %append.newCap = extractvalue { ptr, i32, i32 } %append.new, 2 -+ %0 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0 -+ %1 = insertvalue { ptr, i32, i32 } %0, i32 %append.newLen, 1 -+ %2 = insertvalue { ptr, i32, i32 } %1, i32 %append.newCap, 2 -+ call void @runtime.trackPointer(ptr %append.newPtr, ptr undef) #2 -+ ret { ptr, i32, i32 } %2 - } - - ; Function Attrs: nounwind --define hidden i32 @main.sliceCopy(i32* %dst.data, i32 %dst.len, i32 %dst.cap, i32* %src.data, i32 %src.len, i32 %src.cap, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.sliceCopy(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #1 { - entry: -- %copy.dstPtr = bitcast i32* %dst.data to i8* -- %copy.srcPtr = bitcast i32* %src.data to i8* -- %copy.n = call i32 @runtime.sliceCopy(i8* %copy.dstPtr, i8* %copy.srcPtr, i32 %dst.len, i32 %src.len, i32 4, i8* undef) #2 -+ %copy.n = call i32 @runtime.sliceCopy(ptr %dst.data, ptr %src.data, i32 %dst.len, i32 %src.len, i32 4, ptr undef) #2 - ret i32 %copy.n - } - --declare i32 @runtime.sliceCopy(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i32, i8*) #0 -+declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden { i8*, i32, i32 } @main.makeByteSlice(i32 %len, i8* %context) unnamed_addr #1 { -+define hidden { ptr, i32, i32 } @main.makeByteSlice(i32 %len, ptr %context) unnamed_addr #1 { - entry: - %slice.maxcap = icmp slt i32 %len, 0 - br i1 %slice.maxcap, label %slice.throw, label %slice.next - - slice.next: ; preds = %entry -- %makeslice.buf = call i8* @runtime.alloc(i32 %len, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- %0 = insertvalue { i8*, i32, i32 } undef, i8* %makeslice.buf, 0 -- %1 = insertvalue { i8*, i32, i32 } %0, i32 %len, 1 -- %2 = insertvalue { i8*, i32, i32 } %1, i32 %len, 2 -- call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef) #2 -- ret { i8*, i32, i32 } %2 -+ %makeslice.buf = call ptr @runtime.alloc(i32 %len, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ %0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0 -+ %1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1 -+ %2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2 -+ call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2 -+ ret { ptr, i32, i32 } %2 - - slice.throw: ; preds = %entry -- call void @runtime.slicePanic(i8* undef) #2 -+ call void @runtime.slicePanic(ptr undef) #2 - unreachable - } - --declare void @runtime.slicePanic(i8*) #0 -+declare void @runtime.slicePanic(ptr) #0 - - ; Function Attrs: nounwind --define hidden { i16*, i32, i32 } @main.makeInt16Slice(i32 %len, i8* %context) unnamed_addr #1 { -+define hidden { ptr, i32, i32 } @main.makeInt16Slice(i32 %len, ptr %context) unnamed_addr #1 { - entry: - %slice.maxcap = icmp slt i32 %len, 0 - br i1 %slice.maxcap, label %slice.throw, label %slice.next - - slice.next: ; preds = %entry - %makeslice.cap = shl i32 %len, 1 -- %makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- %makeslice.array = bitcast i8* %makeslice.buf to i16* -- %0 = insertvalue { i16*, i32, i32 } undef, i16* %makeslice.array, 0 -- %1 = insertvalue { i16*, i32, i32 } %0, i32 %len, 1 -- %2 = insertvalue { i16*, i32, i32 } %1, i32 %len, 2 -- call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef) #2 -- ret { i16*, i32, i32 } %2 -+ %makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ %0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0 -+ %1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1 -+ %2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2 -+ call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2 -+ ret { ptr, i32, i32 } %2 - - slice.throw: ; preds = %entry -- call void @runtime.slicePanic(i8* undef) #2 -+ call void @runtime.slicePanic(ptr undef) #2 - unreachable - } - - ; Function Attrs: nounwind --define hidden { [3 x i8]*, i32, i32 } @main.makeArraySlice(i32 %len, i8* %context) unnamed_addr #1 { -+define hidden { ptr, i32, i32 } @main.makeArraySlice(i32 %len, ptr %context) unnamed_addr #1 { - entry: - %slice.maxcap = icmp ugt i32 %len, 1431655765 - br i1 %slice.maxcap, label %slice.throw, label %slice.next - - slice.next: ; preds = %entry - %makeslice.cap = mul i32 %len, 3 -- %makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- %makeslice.array = bitcast i8* %makeslice.buf to [3 x i8]* -- %0 = insertvalue { [3 x i8]*, i32, i32 } undef, [3 x i8]* %makeslice.array, 0 -- %1 = insertvalue { [3 x i8]*, i32, i32 } %0, i32 %len, 1 -- %2 = insertvalue { [3 x i8]*, i32, i32 } %1, i32 %len, 2 -- call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef) #2 -- ret { [3 x i8]*, i32, i32 } %2 -+ %makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ %0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0 -+ %1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1 -+ %2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2 -+ call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2 -+ ret { ptr, i32, i32 } %2 - - slice.throw: ; preds = %entry -- call void @runtime.slicePanic(i8* undef) #2 -+ call void @runtime.slicePanic(ptr undef) #2 - unreachable - } - - ; Function Attrs: nounwind --define hidden { i32*, i32, i32 } @main.makeInt32Slice(i32 %len, i8* %context) unnamed_addr #1 { -+define hidden { ptr, i32, i32 } @main.makeInt32Slice(i32 %len, ptr %context) unnamed_addr #1 { - entry: - %slice.maxcap = icmp ugt i32 %len, 1073741823 - br i1 %slice.maxcap, label %slice.throw, label %slice.next - - slice.next: ; preds = %entry - %makeslice.cap = shl i32 %len, 2 -- %makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- %makeslice.array = bitcast i8* %makeslice.buf to i32* -- %0 = insertvalue { i32*, i32, i32 } undef, i32* %makeslice.array, 0 -- %1 = insertvalue { i32*, i32, i32 } %0, i32 %len, 1 -- %2 = insertvalue { i32*, i32, i32 } %1, i32 %len, 2 -- call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef) #2 -- ret { i32*, i32, i32 } %2 -+ %makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ %0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0 -+ %1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1 -+ %2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2 -+ call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2 -+ ret { ptr, i32, i32 } %2 - - slice.throw: ; preds = %entry -- call void @runtime.slicePanic(i8* undef) #2 -+ call void @runtime.slicePanic(ptr undef) #2 - unreachable - } - - ; Function Attrs: nounwind --define hidden i8* @main.Add32(i8* %p, i32 %len, i8* %context) unnamed_addr #1 { -+define hidden ptr @main.Add32(ptr %p, i32 %len, ptr %context) unnamed_addr #1 { - entry: -- %0 = getelementptr i8, i8* %p, i32 %len -- call void @runtime.trackPointer(i8* %0, i8* undef) #2 -- ret i8* %0 -+ %0 = getelementptr i8, ptr %p, i32 %len -+ call void @runtime.trackPointer(ptr %0, ptr undef) #2 -+ ret ptr %0 - } - - ; Function Attrs: nounwind --define hidden i8* @main.Add64(i8* %p, i64 %len, i8* %context) unnamed_addr #1 { -+define hidden ptr @main.Add64(ptr %p, i64 %len, ptr %context) unnamed_addr #1 { - entry: - %0 = trunc i64 %len to i32 -- %1 = getelementptr i8, i8* %p, i32 %0 -- call void @runtime.trackPointer(i8* %1, i8* undef) #2 -- ret i8* %1 -+ %1 = getelementptr i8, ptr %p, i32 %0 -+ call void @runtime.trackPointer(ptr %1, ptr undef) #2 -+ ret ptr %1 - } - - ; Function Attrs: nounwind --define hidden [4 x i32]* @main.SliceToArray(i32* %s.data, i32 %s.len, i32 %s.cap, i8* %context) unnamed_addr #1 { -+define hidden ptr @main.SliceToArray(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 { - entry: - %0 = icmp ult i32 %s.len, 4 - br i1 %0, label %slicetoarray.throw, label %slicetoarray.next - - slicetoarray.next: ; preds = %entry -- %1 = bitcast i32* %s.data to [4 x i32]* -- ret [4 x i32]* %1 -+ ret ptr %s.data - - slicetoarray.throw: ; preds = %entry -- call void @runtime.sliceToArrayPointerPanic(i8* undef) #2 -+ call void @runtime.sliceToArrayPointerPanic(ptr undef) #2 - unreachable - } - --declare void @runtime.sliceToArrayPointerPanic(i8*) #0 -+declare void @runtime.sliceToArrayPointerPanic(ptr) #0 - - ; Function Attrs: nounwind --define hidden [4 x i32]* @main.SliceToArrayConst(i8* %context) unnamed_addr #1 { -+define hidden ptr @main.SliceToArrayConst(ptr %context) unnamed_addr #1 { - entry: -- %makeslice = call i8* @runtime.alloc(i32 24, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2 -- call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef) #2 -+ %makeslice = call ptr @runtime.alloc(i32 24, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2 -+ call void @runtime.trackPointer(ptr nonnull %makeslice, ptr undef) #2 - br i1 false, label %slicetoarray.throw, label %slicetoarray.next - - slicetoarray.next: ; preds = %entry -- %0 = bitcast i8* %makeslice to [4 x i32]* -- ret [4 x i32]* %0 -+ ret ptr %makeslice - - slicetoarray.throw: ; preds = %entry - unreachable - } - - ; Function Attrs: nounwind --define hidden { i32*, i32, i32 } @main.SliceInt(i32* dereferenceable_or_null(4) %ptr, i32 %len, i8* %context) unnamed_addr #1 { -+define hidden { ptr, i32, i32 } @main.SliceInt(ptr dereferenceable_or_null(4) %ptr, i32 %len, ptr %context) unnamed_addr #1 { - entry: - %0 = icmp ugt i32 %len, 1073741823 -- %1 = icmp eq i32* %ptr, null -+ %1 = icmp eq ptr %ptr, null - %2 = icmp ne i32 %len, 0 - %3 = and i1 %1, %2 - %4 = or i1 %3, %0 - br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next - - unsafe.Slice.next: ; preds = %entry -- %5 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 -- %6 = insertvalue { i32*, i32, i32 } %5, i32 %len, 1 -- %7 = insertvalue { i32*, i32, i32 } %6, i32 %len, 2 -- %8 = bitcast i32* %ptr to i8* -- call void @runtime.trackPointer(i8* %8, i8* undef) #2 -- ret { i32*, i32, i32 } %7 -+ %5 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0 -+ %6 = insertvalue { ptr, i32, i32 } %5, i32 %len, 1 -+ %7 = insertvalue { ptr, i32, i32 } %6, i32 %len, 2 -+ call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 -+ ret { ptr, i32, i32 } %7 - - unsafe.Slice.throw: ; preds = %entry -- call void @runtime.unsafeSlicePanic(i8* undef) #2 -+ call void @runtime.unsafeSlicePanic(ptr undef) #2 - unreachable - } - --declare void @runtime.unsafeSlicePanic(i8*) #0 -+declare void @runtime.unsafeSlicePanic(ptr) #0 - - ; Function Attrs: nounwind --define hidden { i8*, i32, i32 } @main.SliceUint16(i8* dereferenceable_or_null(1) %ptr, i16 %len, i8* %context) unnamed_addr #1 { -+define hidden { ptr, i32, i32 } @main.SliceUint16(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 { - entry: -- %0 = icmp eq i8* %ptr, null -+ %0 = icmp eq ptr %ptr, null - %1 = icmp ne i16 %len, 0 - %2 = and i1 %0, %1 - br i1 %2, label %unsafe.Slice.throw, label %unsafe.Slice.next - - unsafe.Slice.next: ; preds = %entry - %3 = zext i16 %len to i32 -- %4 = insertvalue { i8*, i32, i32 } undef, i8* %ptr, 0 -- %5 = insertvalue { i8*, i32, i32 } %4, i32 %3, 1 -- %6 = insertvalue { i8*, i32, i32 } %5, i32 %3, 2 -- call void @runtime.trackPointer(i8* %ptr, i8* undef) #2 -- ret { i8*, i32, i32 } %6 -+ %4 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0 -+ %5 = insertvalue { ptr, i32, i32 } %4, i32 %3, 1 -+ %6 = insertvalue { ptr, i32, i32 } %5, i32 %3, 2 -+ call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 -+ ret { ptr, i32, i32 } %6 - - unsafe.Slice.throw: ; preds = %entry -- call void @runtime.unsafeSlicePanic(i8* undef) #2 -+ call void @runtime.unsafeSlicePanic(ptr undef) #2 - unreachable - } - - ; Function Attrs: nounwind --define hidden { i32*, i32, i32 } @main.SliceUint64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context) unnamed_addr #1 { -+define hidden { ptr, i32, i32 } @main.SliceUint64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 { - entry: - %0 = icmp ugt i64 %len, 1073741823 -- %1 = icmp eq i32* %ptr, null -+ %1 = icmp eq ptr %ptr, null - %2 = icmp ne i64 %len, 0 - %3 = and i1 %1, %2 - %4 = or i1 %3, %0 -@@ -290,23 +274,22 @@ entry: - - unsafe.Slice.next: ; preds = %entry - %5 = trunc i64 %len to i32 -- %6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 -- %7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1 -- %8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2 -- %9 = bitcast i32* %ptr to i8* -- call void @runtime.trackPointer(i8* %9, i8* undef) #2 -- ret { i32*, i32, i32 } %8 -+ %6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0 -+ %7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1 -+ %8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2 -+ call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 -+ ret { ptr, i32, i32 } %8 - - unsafe.Slice.throw: ; preds = %entry -- call void @runtime.unsafeSlicePanic(i8* undef) #2 -+ call void @runtime.unsafeSlicePanic(ptr undef) #2 - unreachable - } - - ; Function Attrs: nounwind --define hidden { i32*, i32, i32 } @main.SliceInt64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context) unnamed_addr #1 { -+define hidden { ptr, i32, i32 } @main.SliceInt64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 { - entry: - %0 = icmp ugt i64 %len, 1073741823 -- %1 = icmp eq i32* %ptr, null -+ %1 = icmp eq ptr %ptr, null - %2 = icmp ne i64 %len, 0 - %3 = and i1 %1, %2 - %4 = or i1 %3, %0 -@@ -314,15 +297,14 @@ entry: - - unsafe.Slice.next: ; preds = %entry - %5 = trunc i64 %len to i32 -- %6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 -- %7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1 -- %8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2 -- %9 = bitcast i32* %ptr to i8* -- call void @runtime.trackPointer(i8* %9, i8* undef) #2 -- ret { i32*, i32, i32 } %8 -+ %6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0 -+ %7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1 -+ %8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2 -+ call void @runtime.trackPointer(ptr %ptr, ptr undef) #2 -+ ret { ptr, i32, i32 } %8 - - unsafe.Slice.throw: ; preds = %entry -- call void @runtime.unsafeSlicePanic(i8* undef) #2 -+ call void @runtime.unsafeSlicePanic(ptr undef) #2 - unreachable - } - -diff --git a/compiler/testdata/string.ll b/compiler/testdata/string.ll -index 5e1f924c..bd3b8f5a 100644 ---- a/compiler/testdata/string.ll -+++ b/compiler/testdata/string.ll -@@ -3,96 +3,96 @@ source_filename = "string.go" - target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" - target triple = "wasm32-unknown-wasi" - --%runtime._string = type { i8*, i32 } -+%runtime._string = type { ptr, i32 } - - @"main$string" = internal unnamed_addr constant [3 x i8] c"foo", align 1 - --declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 -+declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - --declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 -+declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 - - ; Function Attrs: nounwind --define hidden void @main.init(i8* %context) unnamed_addr #1 { -+define hidden void @main.init(ptr %context) unnamed_addr #1 { - entry: - ret void - } - - ; Function Attrs: nounwind --define hidden %runtime._string @main.someString(i8* %context) unnamed_addr #1 { -+define hidden %runtime._string @main.someString(ptr %context) unnamed_addr #1 { - entry: -- ret %runtime._string { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"main$string", i32 0, i32 0), i32 3 } -+ ret %runtime._string { ptr @"main$string", i32 3 } - } - - ; Function Attrs: nounwind --define hidden %runtime._string @main.zeroLengthString(i8* %context) unnamed_addr #1 { -+define hidden %runtime._string @main.zeroLengthString(ptr %context) unnamed_addr #1 { - entry: - ret %runtime._string zeroinitializer - } - - ; Function Attrs: nounwind --define hidden i32 @main.stringLen(i8* %s.data, i32 %s.len, i8* %context) unnamed_addr #1 { -+define hidden i32 @main.stringLen(ptr %s.data, i32 %s.len, ptr %context) unnamed_addr #1 { - entry: - ret i32 %s.len - } - - ; Function Attrs: nounwind --define hidden i8 @main.stringIndex(i8* %s.data, i32 %s.len, i32 %index, i8* %context) unnamed_addr #1 { -+define hidden i8 @main.stringIndex(ptr %s.data, i32 %s.len, i32 %index, ptr %context) unnamed_addr #1 { - entry: - %.not = icmp ult i32 %index, %s.len - br i1 %.not, label %lookup.next, label %lookup.throw - - lookup.next: ; preds = %entry -- %0 = getelementptr inbounds i8, i8* %s.data, i32 %index -- %1 = load i8, i8* %0, align 1 -+ %0 = getelementptr inbounds i8, ptr %s.data, i32 %index -+ %1 = load i8, ptr %0, align 1 - ret i8 %1 - - lookup.throw: ; preds = %entry -- call void @runtime.lookupPanic(i8* undef) #2 -+ call void @runtime.lookupPanic(ptr undef) #2 - unreachable - } - --declare void @runtime.lookupPanic(i8*) #0 -+declare void @runtime.lookupPanic(ptr) #0 - - ; Function Attrs: nounwind --define hidden i1 @main.stringCompareEqual(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.stringCompareEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 { - entry: -- %0 = call i1 @runtime.stringEqual(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* undef) #2 -+ %0 = call i1 @runtime.stringEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr undef) #2 - ret i1 %0 - } - --declare i1 @runtime.stringEqual(i8*, i32, i8*, i32, i8*) #0 -+declare i1 @runtime.stringEqual(ptr, i32, ptr, i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden i1 @main.stringCompareUnequal(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.stringCompareUnequal(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 { - entry: -- %0 = call i1 @runtime.stringEqual(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* undef) #2 -+ %0 = call i1 @runtime.stringEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr undef) #2 - %1 = xor i1 %0, true - ret i1 %1 - } - - ; Function Attrs: nounwind --define hidden i1 @main.stringCompareLarger(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* %context) unnamed_addr #1 { -+define hidden i1 @main.stringCompareLarger(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 { - entry: -- %0 = call i1 @runtime.stringLess(i8* %s2.data, i32 %s2.len, i8* %s1.data, i32 %s1.len, i8* undef) #2 -+ %0 = call i1 @runtime.stringLess(ptr %s2.data, i32 %s2.len, ptr %s1.data, i32 %s1.len, ptr undef) #2 - ret i1 %0 - } - --declare i1 @runtime.stringLess(i8*, i32, i8*, i32, i8*) #0 -+declare i1 @runtime.stringLess(ptr, i32, ptr, i32, ptr) #0 - - ; Function Attrs: nounwind --define hidden i8 @main.stringLookup(i8* %s.data, i32 %s.len, i8 %x, i8* %context) unnamed_addr #1 { -+define hidden i8 @main.stringLookup(ptr %s.data, i32 %s.len, i8 %x, ptr %context) unnamed_addr #1 { - entry: - %0 = zext i8 %x to i32 - %.not = icmp ult i32 %0, %s.len - br i1 %.not, label %lookup.next, label %lookup.throw - - lookup.next: ; preds = %entry -- %1 = getelementptr inbounds i8, i8* %s.data, i32 %0 -- %2 = load i8, i8* %1, align 1 -+ %1 = getelementptr inbounds i8, ptr %s.data, i32 %0 -+ %2 = load i8, ptr %1, align 1 - ret i8 %2 - - lookup.throw: ; preds = %entry -- call void @runtime.lookupPanic(i8* undef) #2 -+ call void @runtime.lookupPanic(ptr undef) #2 - unreachable - } - -diff --git a/go.mod b/go.mod -index a50f1174..b985effc 100644 ---- a/go.mod -+++ b/go.mod -@@ -17,7 +17,7 @@ require ( - golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 - golang.org/x/tools v0.1.11 - gopkg.in/yaml.v2 v2.4.0 -- tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec -+ tinygo.org/x/go-llvm v0.0.0-20220922115213-dcb078a26266 - ) - - require ( -diff --git a/go.sum b/go.sum -index 4af03408..d3180085 100644 ---- a/go.sum -+++ b/go.sum -@@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 - gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= - gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= --tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec h1:FYtAFrw/YQPc644uNN65dW50FrEuVNaPBf70x23ApY4= --tinygo.org/x/go-llvm v0.0.0-20220922113433-4b5ad7ff76ec/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= -+tinygo.org/x/go-llvm v0.0.0-20220922115213-dcb078a26266 h1:vg4sYKEM+w6epr5S1nXqP/7UhMYcc8nRt7Ohkq28rok= -+tinygo.org/x/go-llvm v0.0.0-20220922115213-dcb078a26266/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= -diff --git a/interp/interpreter.go b/interp/interpreter.go -index 83fd2cd9..c61ce7cf 100644 ---- a/interp/interpreter.go -+++ b/interp/interpreter.go -@@ -356,7 +356,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent - default: - panic("unknown integer type width") - } -- case strings.HasPrefix(callFn.name, "llvm.memcpy.p0i8.p0i8.") || strings.HasPrefix(callFn.name, "llvm.memmove.p0i8.p0i8."): -+ case strings.HasPrefix(callFn.name, "llvm.memcpy.p0") || strings.HasPrefix(callFn.name, "llvm.memmove.p0"): - // Copy a block of memory from one pointer to another. - dst, err := operands[1].asPointer(r) - if err != nil { -@@ -496,7 +496,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent - typecodeID := typecodeIDBitCast.Operand(0).Initializer() - - // Load the method set, which is part of the typecodeID object. -- methodSet := r.builder.CreateExtractValue(typecodeID, 2, "").Operand(0).Initializer() -+ methodSet := stripPointerCasts(r.builder.CreateExtractValue(typecodeID, 2, "")).Initializer() - - // We don't need to load the interface method set. - -@@ -1095,3 +1095,15 @@ func intPredicateString(predicate llvm.IntPredicate) string { - return "cmp?" - } - } -+ -+// Strip some pointer casts. This is probably unnecessary once support for -+// LLVM 14 (non-opaque pointers) is dropped. -+func stripPointerCasts(value llvm.Value) llvm.Value { -+ if !value.IsAConstantExpr().IsNil() { -+ switch value.Opcode() { -+ case llvm.GetElementPtr, llvm.BitCast: -+ return stripPointerCasts(value.Operand(0)) -+ } -+ } -+ return value -+} -diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go -index cde8e2d9..4e24b923 100644 ---- a/src/runtime/runtime.go -+++ b/src/runtime/runtime.go -@@ -27,18 +27,18 @@ func GOROOT() string { - - // Copy size bytes from src to dst. The memory areas must not overlap. - // This function is implemented by the compiler as a call to a LLVM intrinsic --// like llvm.memcpy.p0i8.p0i8.i32(dst, src, size, false). -+// like llvm.memcpy.p0.p0.i32(dst, src, size, false). - func memcpy(dst, src unsafe.Pointer, size uintptr) - - // Copy size bytes from src to dst. The memory areas may overlap and will do the - // correct thing. - // This function is implemented by the compiler as a call to a LLVM intrinsic --// like llvm.memmove.p0i8.p0i8.i32(dst, src, size, false). -+// like llvm.memmove.p0.p0.i32(dst, src, size, false). - func memmove(dst, src unsafe.Pointer, size uintptr) - - // Set the given number of bytes to zero. - // This function is implemented by the compiler as a call to a LLVM intrinsic --// like llvm.memset.p0i8.i32(ptr, 0, size, false). -+// like llvm.memset.p0.i32(ptr, 0, size, false). - func memzero(ptr unsafe.Pointer, size uintptr) - - // This intrinsic returns the current stack pointer. -diff --git a/targets/esp32c3.json b/targets/esp32c3.json -index d7e3fc71..d377fcec 100644 ---- a/targets/esp32c3.json -+++ b/targets/esp32c3.json -@@ -1,6 +1,6 @@ - { - "inherits": ["riscv32"], -- "features": "+c,+m", -+ "features": "+c,+m,-relax,-save-restore", - "build-tags": ["esp32c3", "esp"], - "serial": "uart", - "rtlib": "compiler-rt", -diff --git a/targets/fe310.json b/targets/fe310.json -index e33308f2..2c9e6b5c 100644 ---- a/targets/fe310.json -+++ b/targets/fe310.json -@@ -1,6 +1,6 @@ - { - "inherits": ["riscv32"], - "cpu": "sifive-e31", -- "features": "+a,+c,+m", -+ "features": "+a,+c,+m,-64bit,-relax,-save-restore", - "build-tags": ["fe310", "sifive"] - } -diff --git a/targets/k210.json b/targets/k210.json -index 41c39f44..cc0d2ed4 100644 ---- a/targets/k210.json -+++ b/targets/k210.json -@@ -1,6 +1,6 @@ - { - "inherits": ["riscv64"], -- "features": "+64bit,+a,+c,+d,+f,+m", -+ "features": "+64bit,+a,+c,+d,+f,+m,-relax,-save-restore", - "build-tags": ["k210", "kendryte"], - "code-model": "medium" - } -diff --git a/targets/riscv-qemu.json b/targets/riscv-qemu.json -index 84050ff6..d55a685c 100644 ---- a/targets/riscv-qemu.json -+++ b/targets/riscv-qemu.json -@@ -1,6 +1,6 @@ - { - "inherits": ["riscv32"], -- "features": "+a,+c,+m", -+ "features": "+a,+c,+m,-relax,-save-restore", - "build-tags": ["virt", "qemu"], - "default-stack-size": 4096, - "linkerscript": "targets/riscv-qemu.ld", -diff --git a/transform/interface-lowering.go b/transform/interface-lowering.go -index 9e2ffa90..55d1af39 100644 ---- a/transform/interface-lowering.go -+++ b/transform/interface-lowering.go -@@ -305,7 +305,9 @@ func (p *lowerInterfacesPass) addTypeMethods(t *typeInfo, methodSet llvm.Value) - // no methods or methods already read - return - } -- methodSet = methodSet.Operand(0) // get global from GEP -+ if !methodSet.IsAConstantExpr().IsNil() && methodSet.Opcode() == llvm.GetElementPtr { -+ methodSet = methodSet.Operand(0) // get global from GEP, for LLVM 14 (non-opaque pointers) -+ } - - // This type has methods, collect all methods of this type. - t.methodSet = methodSet -diff --git a/transform/interrupt.go b/transform/interrupt.go -index b15ff8a9..043eebb8 100644 ---- a/transform/interrupt.go -+++ b/transform/interrupt.go -@@ -36,9 +36,8 @@ func LowerInterrupts(mod llvm.Module) []error { - handleMap := map[int64][]llvm.Value{} - handleType := mod.GetTypeByName("runtime/interrupt.handle") - if !handleType.IsNil() { -- handlePtrType := llvm.PointerType(handleType, 0) - for global := mod.FirstGlobal(); !global.IsNil(); global = llvm.NextGlobal(global) { -- if global.Type() != handlePtrType { -+ if global.GlobalValueType() != handleType { - continue - } - -diff --git a/transform/llvm.go b/transform/llvm.go -index 7042b32d..045bb050 100644 ---- a/transform/llvm.go -+++ b/transform/llvm.go -@@ -80,6 +80,12 @@ func replaceGlobalIntWithArray(mod llvm.Module, name string, buf interface{}) ll - // stripPointerCasts strips instruction pointer casts (getelementptr and - // bitcast) and returns the original value without the casts. - func stripPointerCasts(value llvm.Value) llvm.Value { -+ if !value.IsAConstantExpr().IsNil() { -+ switch value.Opcode() { -+ case llvm.GetElementPtr, llvm.BitCast: -+ return stripPointerCasts(value.Operand(0)) -+ } -+ } - if !value.IsAInstruction().IsNil() { - switch value.InstructionOpcode() { - case llvm.GetElementPtr, llvm.BitCast: -diff --git a/transform/reflect.go b/transform/reflect.go -index 68beba9b..b994df61 100644 ---- a/transform/reflect.go -+++ b/transform/reflect.go -@@ -251,7 +251,10 @@ func LowerReflect(mod llvm.Module) { - // a pointer to a runtime.structField array and therefore a - // bitcast. This global should be erased separately, otherwise - // typecode objects cannot be erased. -- structFields := references.Operand(0) -+ structFields := references -+ if !structFields.IsAConstantExpr().IsNil() && structFields.Opcode() == llvm.BitCast { -+ structFields = structFields.Operand(0) // get global from bitcast, for LLVM 14 compatibility (non-opaque pointers) -+ } - structFields.EraseFromParentAsGlobal() - } - } -@@ -460,7 +463,7 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int - - // Get the fields this struct type contains. - // The struct number will be the start index of -- structTypeGlobal := state.builder.CreateExtractValue(typecode.Initializer(), 0, "").Operand(0).Initializer() -+ structTypeGlobal := stripPointerCasts(state.builder.CreateExtractValue(typecode.Initializer(), 0, "")).Initializer() - numFields := structTypeGlobal.Type().ArrayLength() - - // The first data that is stored in the struct sidetable is the number of -@@ -483,7 +486,7 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int - if nameGlobal == llvm.ConstPointerNull(nameGlobal.Type()) { - panic("compiler: no name for this struct field") - } -- fieldNameBytes := getGlobalBytes(nameGlobal.Operand(0), state.builder) -+ fieldNameBytes := getGlobalBytes(stripPointerCasts(nameGlobal), state.builder) - fieldNameNumber := state.getStructNameNumber(fieldNameBytes) - - // See whether this struct field has an associated tag, and if so, -@@ -493,7 +496,7 @@ func (state *typeCodeAssignmentState) getStructTypeNum(typecode llvm.Value) int - tagNumber := 0 - if tagGlobal != llvm.ConstPointerNull(tagGlobal.Type()) { - hasTag = true -- tagBytes := getGlobalBytes(tagGlobal.Operand(0), state.builder) -+ tagBytes := getGlobalBytes(stripPointerCasts(tagGlobal), state.builder) - tagNumber = state.getStructNameNumber(tagBytes) - } - -diff --git a/transform/rtcalls.go b/transform/rtcalls.go -index d70bc626..209e15ae 100644 ---- a/transform/rtcalls.go -+++ b/transform/rtcalls.go -@@ -139,14 +139,13 @@ func OptimizeReflectImplements(mod llvm.Module) { - if call.IsACallInst().IsNil() { - continue - } -- interfaceTypeBitCast := call.Operand(2) -- if interfaceTypeBitCast.IsAConstantExpr().IsNil() || interfaceTypeBitCast.Opcode() != llvm.BitCast { -+ interfaceType := stripPointerCasts(call.Operand(2)) -+ if interfaceType.IsAGlobalVariable().IsNil() { - // The asserted interface is not constant, so can't optimize this - // code. - continue - } - -- interfaceType := interfaceTypeBitCast.Operand(0) - if strings.HasPrefix(interfaceType.Name(), "reflect/types.type:named:") { - // Get the underlying type. - interfaceType = builder.CreateExtractValue(interfaceType.Initializer(), 0, "") --- -2.36.1 - diff --git a/clean_tarballs.sh b/clean_tarballs.sh index 84b74a5..c3d5ac3 100755 --- a/clean_tarballs.sh +++ b/clean_tarballs.sh @@ -1,13 +1,13 @@ #!/bin/bash -e CMSIS_VERSION=9fe411cef1cef5de58e5957b89760759de44e393 -CMSIS_SVD_VERSION=df75ff974c76a911fc2815e29807f5ecaae06fc2 +CMSIS_SVD_DATA_VERSION=05a9562ec59b87945a8d7177a4b08b7aa2f2fd58 if [ -e "cmsis-${CMSIS_VERSION}-clean.tar.xz" ]; then echo "Not downloading cmsis-${CMSIS_VERSION}-clean.tar.xz again!" else -# The license for this tarball is complicated, but the headers are under a -# simple BSD license, so we only package them. +# The license for this tarball is complicated, but the headers are under the +# BSD-3-Clause license, so we only package them. wget -nc https://github.com/ARM-software/CMSIS/archive/${CMSIS_VERSION}/cmsis-${CMSIS_VERSION}.tar.gz tar xf cmsis-${CMSIS_VERSION}.tar.gz tar cJf cmsis-${CMSIS_VERSION}-clean.tar.xz \ @@ -16,24 +16,52 @@ tar cJf cmsis-${CMSIS_VERSION}-clean.tar.xz \ rm -r CMSIS-${CMSIS_VERSION}/ fi -if [ -e "cmsis_svd-${CMSIS_SVD_VERSION}-clean.tar.xz" ]; then -echo "Not downloading cmsis_svd-${CMSIS_SVD_VERSION}-clean.tar.xz again!" +if [ -e "cmsis_svd_data-${CMSIS_SVD_DATA_VERSION}-clean.tar.xz" ]; then +echo "Not downloading cmsis_svd_data-${CMSIS_SVD_DATA_VERSION}-clean.tar.xz again!" else # This is basically a "collection of random stuff" from various vendors, under # various licenses. Some licenses are non-free and some are actively hostile, -# but we only need a rather small portion under a good license. -#wget https://github.com/posborne/cmsis-svd/archive/${CMSIS_SVD_VERSION}/cmsis_svd-${CMSIS_SVD_VERSION}.tar.gz -wget -nc https://github.com/tinygo-org/cmsis-svd/archive/${CMSIS_SVD_VERSION}/cmsis_svd-${CMSIS_SVD_VERSION}.tar.gz -tar xf cmsis_svd-${CMSIS_SVD_VERSION}.tar.gz -tar cJf cmsis_svd-${CMSIS_SVD_VERSION}-clean.tar.xz \ - cmsis-svd-${CMSIS_SVD_VERSION}/data/Atmel/ \ - cmsis-svd-${CMSIS_SVD_VERSION}/data/Espressif/ \ - cmsis-svd-${CMSIS_SVD_VERSION}/data/Espressif-Community/ \ - cmsis-svd-${CMSIS_SVD_VERSION}/data/Kendryte-Community/ \ - cmsis-svd-${CMSIS_SVD_VERSION}/data/SiFive-Community/ \ - cmsis-svd-${CMSIS_SVD_VERSION}/data/NXP/M* \ - cmsis-svd-${CMSIS_SVD_VERSION}/data/RaspberryPi/ \ - # This has a weird license, so we cannot include it. - # cmsis-svd-${CMSIS_SVD_VERSION}/data/STMicro/ -rm -r cmsis-svd-${CMSIS_SVD_VERSION}/ +# but we only need a rather small portion under a good license: +# - Atmel: Apache-2.0 AND BSD-Source-Code +# - Espressif: Apache-2.0 +# - Espressif-Community: Apache-2.0 OR MIT +# - Kendryte-Community: ISC +# - Nordic: BSD-3-Clause +# - NXP/L*: Proprietary, so not included. +# - NXP/Q*: Unknown, so not included. +# - NXP/M*: BSD-3-Clause +# - RaspberryPi: BSD-3-Clause +# - Renesas: Proprietary +# - SiFive-Community: ISC AND (Apache-2.0 OR MIT) +# - STMicro: Apache-2.0 AND Proprietary, so only a subset included. +# These directories are not used by TinyGo, so are not kept: +# - ARM_SAMPLE: BSD-3-Clause +# - Allwinner-Community: Apache-2.0 OR MIT +# - ArteryTek: BSD-3-Clause +# - Cypress: Apache-2.0 +# - Freescale: Proprietary +# - Fujitsu: Proprietary +# - GigaDevice: Apache-2.0 +# - Holtek: Proprietary +# - Infineon: Proprietary +# - Nuvoton: Unknown +# - SiliconLabs: Zlib +# - Spansion: Proprietary +# - TexasInstruments: Proprietary +# - Toshiba: Unknown +wget -nc https://github.com/cmsis-svd/cmsis-svd-data/archive/${CMSIS_SVD_DATA_VERSION}/cmsis_svd_data-${CMSIS_SVD_DATA_VERSION}.tar.gz +tar xf cmsis_svd_data-${CMSIS_SVD_DATA_VERSION}.tar.gz +mapfile -t clean_stmicro < <(grep -Rl '^ *SPDX-License-Identifier: Apache-2.0$' \ + cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/STMicro/*.svd) +tar cJf cmsis_svd_data-${CMSIS_SVD_DATA_VERSION}-clean.tar.xz \ + cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/Atmel/ \ + cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/Espressif/ \ + cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/Espressif-Community/ \ + cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/Kendryte-Community/ \ + cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/Nordic/ \ + cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/NXP/M* \ + cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/RaspberryPi/ \ + cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/data/SiFive-Community/ \ + "${clean_stmicro[@]}" +rm -r cmsis-svd-data-${CMSIS_SVD_DATA_VERSION}/ fi diff --git a/musl-cve-2025-26519-1.patch b/musl-cve-2025-26519-1.patch new file mode 100644 index 0000000..e62d28d --- /dev/null +++ b/musl-cve-2025-26519-1.patch @@ -0,0 +1,38 @@ +>From e5adcd97b5196e29991b524237381a0202a60659 Mon Sep 17 00:00:00 2001 +From: Rich Felker +Date: Sun, 9 Feb 2025 10:07:19 -0500 +Subject: [PATCH] iconv: fix erroneous input validation in EUC-KR decoder + +as a result of incorrect bounds checking on the lead byte being +decoded, certain invalid inputs which should produce an encoding +error, such as "\xc8\x41", instead produced out-of-bounds loads from +the ksc table. + +in a worst case, the loaded value may not be a valid unicode scalar +value, in which case, if the output encoding was UTF-8, wctomb would +return (size_t)-1, causing an overflow in the output pointer and +remaining buffer size which could clobber memory outside of the output +buffer. + +bug report was submitted in private by Nick Wellnhofer on account of +potential security implications. +--- + src/locale/iconv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/locale/iconv.c b/src/locale/iconv.c +index 9605c8e9..008c93f0 100644 +--- a/src/locale/iconv.c ++++ b/src/locale/iconv.c +@@ -502,7 +502,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri + if (c >= 93 || d >= 94) { + c += (0xa1-0x81); + d += 0xa1; +- if (c >= 93 || c>=0xc6-0x81 && d>0x52) ++ if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52) + goto ilseq; + if (d-'A'<26) d = d-'A'; + else if (d-'a'<26) d = d-'a'+26; +-- +2.21.0 + diff --git a/musl-cve-2025-26519-2.patch b/musl-cve-2025-26519-2.patch new file mode 100644 index 0000000..9b64508 --- /dev/null +++ b/musl-cve-2025-26519-2.patch @@ -0,0 +1,38 @@ +>From c47ad25ea3b484e10326f933e927c0bc8cded3da Mon Sep 17 00:00:00 2001 +From: Rich Felker +Date: Wed, 12 Feb 2025 17:06:30 -0500 +Subject: [PATCH] iconv: harden UTF-8 output code path against input decoder + bugs + +the UTF-8 output code was written assuming an invariant that iconv's +decoders only emit valid Unicode Scalar Values which wctomb can encode +successfully, thereby always returning a value between 1 and 4. + +if this invariant is not satisfied, wctomb returns (size_t)-1, and the +subsequent adjustments to the output buffer pointer and remaining +output byte count overflow, moving the output position backwards, +potentially past the beginning of the buffer, without storing any +bytes. +--- + src/locale/iconv.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/locale/iconv.c b/src/locale/iconv.c +index 008c93f0..52178950 100644 +--- a/src/locale/iconv.c ++++ b/src/locale/iconv.c +@@ -545,6 +545,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri + if (*outb < k) goto toobig; + memcpy(*out, tmp, k); + } else k = wctomb_utf8(*out, c); ++ /* This failure condition should be unreachable, but ++ * is included to prevent decoder bugs from translating ++ * into advancement outside the output buffer range. */ ++ if (k>4) goto ilseq; + *out += k; + *outb -= k; + break; +-- +2.21.0 + + diff --git a/sources b/sources index 7f554f3..e96310c 100644 --- a/sources +++ b/sources @@ -1,12 +1,15 @@ -SHA512 (tinygo-0.26.0.tar.gz) = 7b95f6b4356545b806207092fa315863446227e3f90d05abad1f231b381d402b00654e11ab79472c32d5572ea7183bdd4e5ee34190a13e3aefa668ebcd1042b4 +SHA512 (tinygo-0.39.0.tar.gz) = ab9dbe6bfac56470d3703617bd0da152b044e84ced1bfcfb7e7bf6ba8880d07dfac267dca7356ace18bd3ed392ed7031b6cb4a2535ad5f956ab5912ecefe3807 SHA512 (avr-6624554c02b237b23dc17d53e992bf54033fc228.tar.gz) = 1aa157bd761db38f8680614fa1cf47d7009508f65291b7eaaa5aba1ae76d35103f68a42947b7269a170d2f1cf8fb09941a5d74070fe6d204b68dd15a9ad2ed29 +SHA512 (bdwgc-1166f11f7dee08d7ad369296b24cf8c9582f8789.tar.gz) = 030d5a9a0931915a76b1ec270e7208199cf40973ac6c8141c02e34f118f965bedcadff3bb36481b0e45703df8eb2750d20809f3fde367fd5efed5f8a44ccab32 SHA512 (cmsis-9fe411cef1cef5de58e5957b89760759de44e393-clean.tar.xz) = f131fc241f61982c49f334eb502c2f13da61eb7bdaa641ee84a8de30c4d576b735b8aadeafd7d75351473a2df6a42de6a236ecc5dcc616ee6cfcc07af29446f9 -SHA512 (cmsis_svd-df75ff974c76a911fc2815e29807f5ecaae06fc2-clean.tar.xz) = 8abbc6f366aed9571a74a4b6e7065ed2d6a59e0495c3745681d9a654d61edd136319788741f7afc781211adb64ed1faeafe9d6acc6be5a16d9ee48e98c5ddeb1 -SHA512 (compiler-rt-15.0.0.src.tar.xz) = 25763e581c90923260b7c3a03e220feb4cabb2757e418c4940db0eeb6a17f65b35db0c93d3c1e526adad2f6dc93595bec6d99b1bfb4a1bd13a14a0db5301e6cf -SHA512 (compiler-rt-15.0.0.src.tar.xz.sig) = 94f39d2e30372ccea4db96c3dd4005a5b44c2bf5d22fa0aaf45b86673ef7d3460884689f97bc96470db2d546042fb01fe3ca41bf22b6323abe0cd785b85d76ef -SHA512 (macos-minimal-sdk-ebb736fda2bec7cea38dcda807518b835a539525.tar.gz) = 2f97d5826c79116c851e1efde74faf806de56ac8acc5509d1ab7690d0edf88f6e227b273d2c5ef7d894a8ada2e316e285ef4e58d74ca0c6f91584653154eae10 -SHA512 (musl-1.2.0.tar.gz) = 58bd88189a6002356728cea1c6f6605a893fe54f7687595879add4eab283c8692c3b031eb9457ad00d1edd082cfe62fcc0eb5eb1d3bf4f1d749c0efa2a95fec1 -SHA512 (musl-1.2.0.tar.gz.asc) = 1639d1f39f3c587011cc6e1ae44774d20d306f4d18fb394bfa86c40f52af53a882ebd5326553b589a1c5316494b77658dc3310c0187836dfd1fd023ccfedaaf0 +SHA512 (cmsis_svd_data-05a9562ec59b87945a8d7177a4b08b7aa2f2fd58-clean.tar.xz) = e8ba9d74fb148dfa8b3ba140d307b243fb38378f69544529455eea5df57d4276b7177d3549228f8acadc4e72c94506456e78025d9b16d606b322fda8ab38327d +SHA512 (compiler-rt-19.1.7.src.tar.xz) = e2e8e6a094525b84184e9e4a4c1a727de518d4ef1a91370515f0c955719dc946fd60e7fabd10f52ab1905ef6d4a86084b8ddfb9b45de838aa1c5ddf3c042748b +SHA512 (compiler-rt-19.1.7.src.tar.xz.sig) = 48550377345331bfa0015d2c5bb6e063507a76e950f8f349a8e6877d35428a11d86bd617ea7a048f1584a42c58da924ef523d622b54ce4ca94eaa12ce290b49c +SHA512 (macos-minimal-sdk-e7c72156eac3ebf29c34cc2faa71efcb1296663f.tar.gz) = 44638fa9786e88327eb5a2f5cf06c8f09149f21b2592802bdd2db04cbdf4dfbee1bc9296af1b7745c4e30ac97f26a714e19168b742526a8a1b4f8ce23d8fa789 +SHA512 (mingw64-8526cb618269440a94810b94b77f8bd48c5c3396.tar.gz) = 723d1ac22d8026f31b59d39328f711f36976798445a82daddcdc9fa6ab4346a5030e9c2efc84ef009439b8f021c5c7c120cfa083a7912a5b0212ac6852c005a7 +SHA512 (musl-1.2.3.tar.gz) = 9332f713d3eb7de4369bc0327d99252275ee52abf523ee34b894b24a387f67579787f7c72a46cf652e090cffdb0bc3719a4e7b84dca66890b6a37f12e8ad089c +SHA512 (musl-1.2.3.tar.gz.asc) = 01a857dbc3981c90244d4d1d883efe51986652ca5734a741c9d1a4d06c5a22831e85520ac67212268b70c22049317a8f39b3219be182e7e67741add428ac5bc6 +SHA512 (net-c134160ae47d38b468b1c5ade43e78ad5a1e616d.tar.gz) = 449149af6bca15fa0fe1a9a8b37b3cab3bf83b177dd78d760fcca561bbacb415d6c7f0a355edf8d0de1b934d13fbce9d307c2a4410f1ff1c3bfe71b28e76b228 SHA512 (nrfx-d779b49fc59c7a165e7da1d7cd7d57b28a059f16.tar.gz) = 31c7fc6fd88d4a74e5739b29659cb717a4629480d17d84e491d61c36c435aba16d38ef63d1036e508666a17eeaac5f11a5ff83211f88410f30cc2e152146ee83 -SHA512 (picolibc-f68b8204f797d6b3bfbc7c4da4d257961fbc8770.tar.gz) = fa58a7ddcb1a40239a220ca701a83895804b9ddc837652fa18e9aed2603bba2825df2074e2fa4fbf8649bb9a21308e877850273ec9d421795e2ae549f331ab13 -SHA512 (wasi-libc-30094b6ed05f19cee102115215863d185f2db4f0.tar.gz) = 17492263fd5dca422f19e0ff8533e1f440e3b7516dc24ef0d16fdc44832cc63ec288c9e930f63b47fb71497144fed55cc313acc74339d067b8d4f5c7c683df0f +SHA512 (picolibc-b92edfda8ac6853772d87cadaeeeaa21b78609b6.tar.gz) = 9fb60d81bd98c96264c81e95cab6622ccacb34da285f7f3c137bd3cd8bc6e87cbc065a2e9d9fdfc7b93eec52f33bbfa70b6d0abc1a30551ebec1af351344cc39 +SHA512 (wasi-libc-wasi-sdk-20.tar.gz) = e264240dc7dbcf6398c8ca09bc108298f4a8aa955af22de5a3015fbcde81cb09dd83cd48349090082d5de0e8a3dbcf746c7b14657c67657b3f2f1ab28bb9cf05 diff --git a/tinygo.spec b/tinygo.spec index f358329..0242570 100644 --- a/tinygo.spec +++ b/tinygo.spec @@ -1,27 +1,30 @@ -# Generated by go2rpm 1 -%bcond_without check +%bcond check 1 +# I'm not sure what this is for, as no tests seem to use it, and it introduces +# some weird license that needs review. +%bcond wasi_cli 0 %global __brp_strip_lto %{nil} %global __brp_strip_static_archive %{nil} # https://github.com/tinygo-org/tinygo %global goipath github.com/tinygo-org/tinygo -Version: 0.26.0 +Version: 0.39.0 -%global CMSIS_commit 9fe411cef1cef5de58e5957b89760759de44e393 -%global avr_commit 6624554c02b237b23dc17d53e992bf54033fc228 -%if %{fedora} > 36 -%global clang_llvm_version 15 -%else -%global clang_llvm_version 14 -%endif -%global cmsis_svd_commit df75ff974c76a911fc2815e29807f5ecaae06fc2 -%global compiler_rt_version %{clang_llvm_version}.0.0 -%global macos_minsdk_commit ebb736fda2bec7cea38dcda807518b835a539525 -%global musl_version 1.2.0 -%global nrfx_commit d779b49fc59c7a165e7da1d7cd7d57b28a059f16 -%global picolibc_commit f68b8204f797d6b3bfbc7c4da4d257961fbc8770 -%global wasi_libc_commit 30094b6ed05f19cee102115215863d185f2db4f0 +%global CMSIS_commit 9fe411cef1cef5de58e5957b89760759de44e393 +%global avr_commit 6624554c02b237b23dc17d53e992bf54033fc228 +%global bdwgc_commit 1166f11f7dee08d7ad369296b24cf8c9582f8789 +%global clang_llvm_version 19 +%global cmsis_svd_data_commit 05a9562ec59b87945a8d7177a4b08b7aa2f2fd58 +%global compiler_rt_version %{clang_llvm_version}.1.7 +%global macos_minsdk_commit e7c72156eac3ebf29c34cc2faa71efcb1296663f +%global mingw64_commit 8526cb618269440a94810b94b77f8bd48c5c3396 +%global musl_version 1.2.3 +%global net_commit c134160ae47d38b468b1c5ade43e78ad5a1e616d +%global nrfx_commit d779b49fc59c7a165e7da1d7cd7d57b28a059f16 +%global picolibc_commit b92edfda8ac6853772d87cadaeeeaa21b78609b6 +%global wasi_libc_version 20 +%global wasi_libc_tag wasi-sdk-%{wasi_libc_version} +%global wasi_cli_version 0.2.0 # No longer matching regular Go's /usr/share/gocode because it also provides # pre-compiled binaries, and symlinks to arch-specific clang headers. @@ -33,31 +36,35 @@ Version: 0.26.0 Go compiler for small places. Microcontrollers, WebAssembly, and command-line tools. Based on LLVM.} -#global godocs CHANGELOG.md BUILDING.md CONTRIBUTING.md README.md -#global golicenses LICENSE LICENSE.TXT -#global gosupfiles lib/CMSIS/CMSIS/Include/*.h lib/compiler-rt/lib/builtins/*/*.S lib/nrfx/mdk/*.{ld,S} src/examples/wasm/*/*.js targets/*.{js,json,ld,S} - Name: tinygo Release: %autorelease Summary: Go compiler for small places -# Main files: BSD -# CMSIS: BSD (subsetted) -# avr-mcu: ASL 2.0 (packs) and MIT (Rust code, unused by this package) -# cmsis-svd: ASL 2.0 and BSD and ISC and MIT (subsetted) -# compiler-rt: NCSA or MIT -# macos-minimal-sdk: APSL 2.0 and BSD and ISC and Public Domain +# Main files: BSD-3-Clause +# builder/cc1as.*: Apache-2.0 WITH LLVM-exception +# corpus_test.go: MIT +# CMSIS: BSD-3-Clause (subsetted) +# avr-mcu: Apache-2.0 (packs) AND MIT (Rust code, unused by this package) +# cmsis-svd: Apache-2.0 AND (Apache-2.0 OR MIT) AND BSD-3-Clause AND BSD-Source-Code AND ISC AND MIT (subsetted) +# compiler-rt: Apache-2.0 WITH LLVM-exception OR NCSA OR MIT +# macos-minimal-sdk: APSL-2.0 AND BSD-2-Clause AND BSD-3-Clause AND BSD-4-Clause AND BSD-4-Clause-UC AND ISC AND LicenseRef-Fedora-Public-Domain # musl: MIT -# nrfx: BSD and ASL 2.0 -# picolibc: BSD and ISC and MIT and GPLv2 (testing code only, unused by this package) -# wasi-libc: BSD and CC0 and ISC and MIT and Public Domain -License: BSD and APSL 2.0 and ASL 2.0 and CC0 and ISC and MIT and (NCSA or MIT) and Public Domain +# net: BSD-2-Clause +# nrfx: BSD-3-Clause AND Apache-2.0 +# picolibc: BSD-2-Clause AND BSD-2-Clause-FreeBSD AND BSD-3-Clause AND ISC AND SMLNJ AND Spencer-94 AND GPLv2 (testing code only, unused by this package) +# wasi-libc: Apache-2.0 WITH LLVM-exception AND Apache-2.0 AND MIT AND BSD-2-Clause AND CC0-1.0 (dlmalloc implementation, unused by this package) +License: %{shrink: BSD-3-Clause AND Apache-2.0 WITH LLVM-exception AND BSD-2-Clause AND MIT AND + Apache-2.0 AND + (Apache-2.0 OR MIT) AND BSD-Source-Code AND ISC AND + (Apache-2.0 WITH LLVM-exception OR NCSA OR MIT) AND + APSL-2.0 AND BSD-2-Clause AND BSD-4-Clause AND BSD-4-Clause-UC AND LicenseRef-Fedora-Public-Domain AND + BSD-2-Clause-FreeBSD AND SMLNJ AND Spencer-94} URL: %{gourl} Source0: %{gosource} Source1: clean_tarballs.sh Source2: cmsis-%{CMSIS_commit}-clean.tar.xz Source3: https://github.com/avr-rust/avr-mcu/archive/%{avr_commit}/avr-%{avr_commit}.tar.gz -Source4: cmsis_svd-%{cmsis_svd_commit}-clean.tar.xz +Source4: cmsis_svd_data-%{cmsis_svd_data_commit}-clean.tar.xz Source50: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compiler_rt_version}/compiler-rt-%{compiler_rt_version}.src.tar.xz Source51: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{compiler_rt_version}/compiler-rt-%{compiler_rt_version}.src.tar.xz.sig Source52: https://src.fedoraproject.org/rpms/compiler-rt/raw/f8e98d51f0c3fdbaa9ce5d99816930e4fcbe504b/f/release-keys.asc#/compiler-rt-release-keys.asc @@ -67,76 +74,71 @@ Source62: https://musl.libc.org/musl.pub Source7: https://github.com/aykevl/macos-minimal-sdk/archive/%{macos_minsdk_commit}/macos-minimal-sdk-%{macos_minsdk_commit}.tar.gz Source8: https://github.com/NordicSemiconductor/nrfx/archive/%{nrfx_commit}/nrfx-%{nrfx_commit}.tar.gz Source9: https://github.com/keith-packard/picolibc/archive/%{picolibc_commit}/picolibc-%{picolibc_commit}.tar.gz -Source10: https://github.com/WebAssembly/wasi-libc/archive/%{wasi_libc_commit}/wasi-libc-%{wasi_libc_commit}.tar.gz +Source10: https://github.com/WebAssembly/wasi-libc/archive/%{wasi_libc_tag}/wasi-libc-%{wasi_libc_tag}.tar.gz +Source11: https://github.com/mingw-w64/mingw-w64/archive/%{mingw64_commit}/mingw64-%{mingw64_commit}.tar.gz +Source12: https://github.com/tinygo-org/net/archive/%{net_commit}/net-%{net_commit}.tar.gz +%if %{with wasi_cli} +Source13: https://github.com/WebAssembly/wasi-cli/archive/v%{wasi_cli_version}/wasi-cli-%{wasi_cli_version}.tar.gz +%endif +Source14: https://github.com/ivmai/bdwgc/archive/%{bdwgc_commit}/bdwgc-%{bdwgc_commit}.tar.gz + +# +# Unnumbered patches are applied to the main source tree. +# Patches that are 1X00-1X99 are applied to the subdirectory for source X. +# + # We don't have wasmtime to run these. -Patch0001: 0001-Skip-WASI-tests.patch -# Unbundling things -Patch0002: 0002-Use-system-mingw64-headers-and-crt.patch -# Skip testing some things where qemu is broken: -# https://gitlab.com/qemu-project/qemu/-/issues/447 -# https://gitlab.com/qemu-project/qemu/-/issues/690 -Patch0003: 0003-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch -# Add Fedora specific dnf instructions -Patch0004: 0004-Suggest-optional-packages-to-install-if-missing.patch +Patch: 0001-Skip-WASI-tests.patch +# We set GO111MODULE=off during tests, so can't run a few of them. +Patch: 0002-Skip-tests-that-require-Go-module-mode.patch +# Better search paths for non-default LLVM. +Patch: 0003-Set-LLVM-search-paths-for-Fedora.patch +#https://github.com/tinygo-org/tinygo/pull/4677 +Patch: 0004-Normalize-expected-path-for-chdir-tests.patch +# https://github.com/tinygo-org/tinygo/issues/4969 +Patch: 0005-Skip-x86-tests-on-ARM.patch -# https://github.com/tinygo-org/tinygo/pull/2840 -Patch0005: 0005-Skip-TestDirFS-on-32-bit-systems.patch -Patch0006: 0006-Skip-broken-tests-on-i686.patch - -# Backport patches for LLVM 15 support -# https://github.com/tinygo-org/tinygo/pull/3230 -Patch0007: 0007-wasm-fix-GC-scanning-of-allocas.patch -# https://github.com/tinygo-org/tinygo/pull/3189 -Patch0008: 0008-compiler-return-a-FunctionType-not-a-PointerType-in-.patch -Patch0009: 0009-all-add-type-parameter-to-CreateCall.patch -Patch0010: 0010-all-add-type-parameter-to-CreateLoad.patch -Patch0011: 0011-all-add-type-parameter-to-GEP-calls.patch -Patch0012: 0012-all-replace-llvm.Const-calls-with-builder.Create-cal.patch -Patch0013: 0013-interp-change-object.llvmType-to-the-initializer-typ.patch -Patch0014: 0014-all-remove-pointer-ElementType-calls.patch -Patch0015: 0015-transform-fix-memory-corruption-issues.patch -Patch0016: 0016-riscv-add-target-abi-metadata-flag.patch -Patch0017: 0017-interp-add-support-for-constant-icmp-instructions.patch -Patch0018: 0018-ci-add-support-for-LLVM-15.patch +# Fix CVE-2025-26519 in musl. +Patch1600: https://www.openwall.com/lists/musl/2025/02/13/1/1#/musl-cve-2025-26519-1.patch +Patch1601: https://www.openwall.com/lists/musl/2025/02/13/1/2#/musl-cve-2025-26519-2.patch # Not supported upstream yet. -ExcludeArch: armv7hl ppc64le s390x +ExcludeArch: ppc64le s390x # https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval ExcludeArch: %{ix86} -BuildRequires: (clang-devel >= %{clang_llvm_version} with clang-devel < %{lua: print(tonumber(rpm.expand('%{clang_llvm_version}')) + 1)}) +BuildRequires: clang-devel(major) = %{clang_llvm_version} BuildRequires: golang(github.com/aykevl/go-wasm) BuildRequires: golang(github.com/blakesmith/ar) -%ifnarch %{ix86} BuildRequires: chromium BuildRequires: golang(github.com/chromedp/chromedp) >= 0.7.6 BuildRequires: golang(github.com/chromedp/cdproto/cdp) -%endif BuildRequires: golang(github.com/gofrs/flock) >= 0.8.1 BuildRequires: golang(github.com/google/shlex) BuildRequires: golang(github.com/inhies/go-bytesize) BuildRequires: golang(github.com/marcinbor85/gohex) -BuildRequires: golang(github.com/mattn/go-colorable) >= 0.1.8 +BuildRequires: golang(github.com/mattn/go-colorable) >= 0.1.13 BuildRequires: golang(github.com/mattn/go-tty) >= 0.0.4 -BuildRequires: golang(go.bug.st/serial) >= 1.3.5 +BuildRequires: golang(github.com/tetratelabs/wazero) >= 1.6 +BuildRequires: golang(golang.org/x/net/http/httpguts) >= 0.35 +BuildRequires: golang(github.com/sigurn/crc16) +BuildRequires: golang(go.bug.st/serial) >= 1.6.0 BuildRequires: golang(golang.org/x/tools/go/ast/astutil) -BuildRequires: golang(golang.org/x/tools/go/ssa) >= 0.1.11 +BuildRequires: golang(golang.org/x/tools/go/ssa) >= 0.30 BuildRequires: golang(gopkg.in/yaml.v2) >= 2.4.0 BuildRequires: golang(tinygo.org/x/go-llvm) BuildRequires: golang-tests BuildRequires: llvm-devel(major) = %{clang_llvm_version} BuildRequires: make -BuildRequires: avr-gcc -BuildRequires: avr-libc -BuildRequires: binaryen >= 102 +BuildRequires: binaryen >= 116 # We don't have glibc for arm, so skip these. #BuildRequires: gcc-arm-linux-gnu #BuildRequires: gcc-aarch64-linux-gnu -BuildRequires: lld -BuildRequires: mingw64-crt -BuildRequires: mingw64-headers -BuildRequires: nodejs +BuildRequires: lld(major) = %{clang_llvm_version} +# BuildRequires: mingw64-crt +# BuildRequires: mingw64-headers +BuildRequires: nodejs >= 18 BuildRequires: qemu-system-arm-core BuildRequires: qemu-system-riscv-core BuildRequires: qemu-user @@ -144,46 +146,53 @@ BuildRequires: qemu-user # For GPG signature verification BuildRequires: gnupg2 -Requires: clang +Requires: clang(major) = %{clang_llvm_version} Requires: golang -Requires: lld -Recommends: avr-gcc -Recommends: avr-libc +Requires: lld(major) = %{clang_llvm_version} # Add this when LLVM supports ESP natively. # Recommends: esptool -Recommends: mingw64-crt -Recommends: mingw64-headers +# Recommends: mingw64-crt +# Recommends: mingw64-headers Recommends: qemu-system-arm-core Recommends: qemu-system-riscv-core Recommends: qemu-user # Make note of bundled libc's +Provides: bundled(bdwgc) = %{bdwgc_commit} +Provides: bundled(gc) = %{bdwgc_commit} Provides: bundled(compiler-rt) = %{compiler_rt_version} Provides: bundled(musl) = %{musl_version} Provides: bundled(picolibc) = %{picolibc_commit} -Provides: bundled(wasi-libc) = %{wasi_libc_commit} +Provides: bundled(wasi-libc) = %{wasi_libc_version} %description %{common_description} -#gopkg - %prep %goprep -%autopatch -p1 +%autopatch -q -p1 -M 999 tar -C lib -xf %{SOURCE2} rmdir lib/CMSIS mv lib/CMSIS-%{CMSIS_commit} lib/CMSIS +pushd lib/CMSIS +%autopatch -q -p1 -m 1200 -M 1299 +popd tar -C lib -xf %{SOURCE3} rmdir lib/avr mv lib/avr-mcu-%{avr_commit} lib/avr +pushd lib/avr +%autopatch -q -p1 -m 1300 -M 1399 +popd tar -C lib -xf %{SOURCE4} rmdir lib/cmsis-svd -mv lib/cmsis-svd-%{cmsis_svd_commit} lib/cmsis-svd +mv lib/cmsis-svd-data-%{cmsis_svd_data_commit} lib/cmsis-svd +pushd lib/cmsis-svd +%autopatch -q -p1 -m 1400 -M 1499 +popd # Verify *before* actually unpacking! %{gpgverify} --keyring='%{SOURCE52}' --signature='%{SOURCE51}' --data='%{SOURCE50}' @@ -191,61 +200,93 @@ tar -C lib -xf %{SOURCE50} mv lib/compiler-rt-%{compiler_rt_version}.src/lib/builtins lib/compiler-rt-builtins mv lib/compiler-rt-%{compiler_rt_version}.src/README.txt lib/compiler-rt-builtins/ mv lib/compiler-rt-%{compiler_rt_version}.src/LICENSE.TXT lib/compiler-rt-builtins/ +pushd lib/compiler-rt-builtins +%autopatch -q -p1 -m 1500 -M 1599 +popd # Verify *before* actually unpacking! %{gpgverify} --keyring='%{SOURCE62}' --signature='%{SOURCE61}' --data='%{SOURCE60}' tar -C lib -xf %{SOURCE60} rmdir lib/musl mv lib/musl-%{musl_version} lib/musl +pushd lib/musl +%autopatch -q -p1 -m 1600 -M 1699 +popd tar -C lib -xf %{SOURCE7} rmdir lib/macos-minimal-sdk mv lib/macos-minimal-sdk-%{macos_minsdk_commit} lib/macos-minimal-sdk +pushd lib/macos-minimal-sdk +%autopatch -q -p1 -m 1700 -M 1799 +popd tar -C lib -xf %{SOURCE8} rmdir lib/nrfx mv lib/nrfx-%{nrfx_commit} lib/nrfx rm lib/nrfx/.gitignore chmod -x lib/nrfx/doc/generate_html_doc.sh +pushd lib/nrfx +%autopatch -q -p1 -m 1800 -M 1899 +popd tar -C lib -xf %{SOURCE9} rmdir lib/picolibc mv lib/picolibc-%{picolibc_commit} lib/picolibc +pushd lib/picolibc +%autopatch -q -p1 -m 1900 -M 1999 +popd tar -C lib -xf %{SOURCE10} rmdir lib/wasi-libc -mv lib/wasi-libc-%{wasi_libc_commit} lib/wasi-libc +mv lib/wasi-libc-%{wasi_libc_tag} lib/wasi-libc +pushd lib/wasi-libc +%autopatch -q -p1 -m 11000 -M 11099 +popd -# This test is too slow and pretty much freezes. -%ifarch %{ix86} -sed -i -e 's!archive/zip!$(nil)!' Makefile +tar -C lib -xf %{SOURCE11} +rmdir lib/mingw-w64 +mv lib/mingw-w64-%{mingw64_commit} lib/mingw-w64 +pushd lib/mingw-w64 +%autopatch -q -p1 -m 11100 -M 11199 +popd + +tar -C src -xf %{SOURCE12} +rmdir src/net +mv src/net-%{net_commit} src/net +pushd src/net +%autopatch -q -p1 -m 11200 -M 11299 +popd + +%if %{with wasi_cli} +tar -C lib -xf %{SOURCE13} +rmdir lib/wasi-cli +mv lib/wasi-cli-%{wasi_cli_version} lib/wasi-cli +pushd lib/wasi-cli +%autopatch -q -p1 -m 11300 -M 11399 +popd %endif +tar -C lib -xf %{SOURCE14} +rmdir lib/bdwgc +mv lib/bdwgc-%{bdwgc_commit} lib/bdwgc +pushd lib/bdwgc +%autopatch -q -p1 -m 11400 -M 11499 +popd + %build -# Use only GOBUILDTAGS when https://pagure.io/go-rpm-macros/pull-request/34 is -# merged and released. -export BUILDTAGS="llvm%{clang_llvm_version}" LDFLAGS="-X github.com/tinygo-org/tinygo/goenv.TINYGOROOT=%{tinygoroot} " +export GO_BUILDTAGS="llvm%{clang_llvm_version}" GO_LDFLAGS="-X github.com/tinygo-org/tinygo/goenv.TINYGOROOT=%{tinygoroot} " %gobuild -o %{gobuilddir}/bin/tinygo %{goipath} -GO111MODULE=off %make_build gen-device STM32=0 -for target in thumbv6m-unknown-unknown-eabi-cortex-m0 thumbv6m-unknown-unknown-eabi-cortex-m0plus thumbv7em-unknown-unknown-eabi-cortex-m4; do - mkdir -p ${target} - for libc in compiler-rt picolibc; do - TINYGOROOT=$PWD \ - %{gobuilddir}/bin/tinygo \ - build-library -target=${target#*eabi-} -o ${target}/${libc} ${libc} - chmod -R a+rX ${target}/${libc} - done -done -%make_build wasi-libc CLANG=clang-%{clang_llvm_version} LLVM_AR=llvm-ar LLVM_NM=llvm-nm +GO111MODULE=off %make_build gen-device RENESAS=0 STM32=0 %install -#gopkginstall install -vdm 0755 %{buildroot}%{_bindir} install -vpm 0755 %{gobuilddir}/bin/* %{buildroot}%{_bindir}/ install -vdm 0755 %{buildroot}%{tinygoroot} install -vdm 0755 %{buildroot}%{tinygoroot}/lib +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/bdwgc +cp -rp lib/bdwgc/* %{buildroot}%{tinygoroot}/lib/bdwgc install -vdm 0755 %{buildroot}%{tinygoroot}/lib/CMSIS install -vpm 0644 lib/CMSIS/README.md %{buildroot}%{tinygoroot}/lib/CMSIS/ install -vdm 0755 %{buildroot}%{tinygoroot}/lib/CMSIS/CMSIS/Include @@ -253,6 +294,25 @@ install -vpm 0644 lib/CMSIS/CMSIS/Include/* %{buildroot}%{tinygoroot}/lib/CMSIS/ cp -rp lib/compiler-rt-builtins %{buildroot}%{tinygoroot}/lib install -vdm 0755 %{buildroot}%{tinygoroot}/lib/macos-minimal-sdk cp -rp lib/macos-minimal-sdk/* %{buildroot}%{tinygoroot}/lib/macos-minimal-sdk +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt +cp -rp lib/mingw-w64/mingw-w64-crt/def-include %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt +cp -rp lib/mingw-w64/mingw-w64-crt/gdtoa %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt +cp -rp lib/mingw-w64/mingw-w64-crt/include %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt +cp -rp lib/mingw-w64/mingw-w64-crt/misc %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt +cp -rp lib/mingw-w64/mingw-w64-crt/stdio %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/crt +cp -rp lib/mingw-w64/mingw-w64-crt/crt/pseudo-reloc.c %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/crt +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/math +cp -rp lib/mingw-w64/mingw-w64-crt/math/x86 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/math +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/lib-common +cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/api-ms-win-crt-* %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/lib-common +cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/advapi32.def.in %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/lib-common +cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/kernel32.def.in %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/lib-common +cp -rp lib/mingw-w64/mingw-w64-crt/lib-common/msvcrt.def.in %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-crt/lib-common +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-headers/defaults +cp -rp lib/mingw-w64/mingw-w64-headers/crt/ %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-headers +cp -rp lib/mingw-w64/mingw-w64-headers/include %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-headers +cp -rp lib/mingw-w64/mingw-w64-headers/defaults/include %{buildroot}%{tinygoroot}/lib/mingw-w64/mingw-w64-headers/defaults install -vdm 0755 %{buildroot}%{tinygoroot}/lib/musl cp -rp lib/musl/COPYRIGHT %{buildroot}%{tinygoroot}/lib/musl cp -rp lib/musl/include %{buildroot}%{tinygoroot}/lib/musl @@ -261,28 +321,79 @@ cp -rp lib/musl/arch/aarch64 %{buildroot}%{tinygoroot}/lib/musl/arch cp -rp lib/musl/arch/arm %{buildroot}%{tinygoroot}/lib/musl/arch cp -rp lib/musl/arch/generic %{buildroot}%{tinygoroot}/lib/musl/arch cp -rp lib/musl/arch/i386 %{buildroot}%{tinygoroot}/lib/musl/arch +cp -rp lib/musl/arch/mips %{buildroot}%{tinygoroot}/lib/musl/arch cp -rp lib/musl/arch/x86_64 %{buildroot}%{tinygoroot}/lib/musl/arch install -vdm 0755 %{buildroot}%{tinygoroot}/lib/musl/crt cp -rp lib/musl/crt/crt1.c %{buildroot}%{tinygoroot}/lib/musl/crt install -vdm 0755 %{buildroot}%{tinygoroot}/lib/musl/src +cp -rp lib/musl/src/conf %{buildroot}%{tinygoroot}/lib/musl/src +cp -rp lib/musl/src/ctype %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/env %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/errno %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/exit %{buildroot}%{tinygoroot}/lib/musl/src +cp -rp lib/musl/src/fcntl %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/include %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/internal %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/legacy %{buildroot}%{tinygoroot}/lib/musl/src +cp -rp lib/musl/src/linux %{buildroot}%{tinygoroot}/lib/musl/src +cp -rp lib/musl/src/locale %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/malloc %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/mman %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/math %{buildroot}%{tinygoroot}/lib/musl/src +cp -rp lib/musl/src/misc %{buildroot}%{tinygoroot}/lib/musl/src +cp -rp lib/musl/src/multibyte %{buildroot}%{tinygoroot}/lib/musl/src +cp -rp lib/musl/src/sched %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/signal %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/stdio %{buildroot}%{tinygoroot}/lib/musl/src +cp -rp lib/musl/src/stdlib %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/string %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/thread %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/time %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/musl/src/unistd %{buildroot}%{tinygoroot}/lib/musl/src +cp -rp lib/musl/src/process %{buildroot}%{tinygoroot}/lib/musl/src cp -rp lib/nrfx %{buildroot}%{tinygoroot}/lib/ install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc -cp -rp lib/wasi-libc/sysroot %{buildroot}%{tinygoroot}/lib/wasi-libc/ +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/dlmalloc +cp -rp lib/wasi-libc/dlmalloc/src %{buildroot}%{tinygoroot}/lib/wasi-libc/dlmalloc +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-bottom-half +cp -rp lib/wasi-libc/libc-bottom-half/cloudlibc %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-bottom-half +cp -rp lib/wasi-libc/libc-bottom-half/headers %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-bottom-half +cp -rp lib/wasi-libc/libc-bottom-half/sources %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-bottom-half +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half +cp -rp lib/wasi-libc/libc-top-half/headers %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half +cp -rp lib/wasi-libc/libc-top-half/sources %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl +cp -rp lib/wasi-libc/libc-top-half/musl/include %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/arch +cp -rp lib/wasi-libc/libc-top-half/musl/arch/generic %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/arch +cp -rp lib/wasi-libc/libc-top-half/musl/arch/wasm32 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/arch +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/conf %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/dirent %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/env %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/errno %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/exit %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/fcntl %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/fenv %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/include %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/internal %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/legacy %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/locale %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/math %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/misc %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/multibyte %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/network %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/stat %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/stdio %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/stdlib %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/string %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/thread %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/time %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +cp -rp lib/wasi-libc/libc-top-half/musl/src/unistd %{buildroot}%{tinygoroot}/lib/wasi-libc/libc-top-half/musl/src +%if %{with wasi_cli} +install -vdm 0755 %{buildroot}%{tinygoroot}/lib/wasi-cli +cp -rp lib/wasi-cli/wit %{buildroot}%{tinygoroot}/lib/wasi-cli/wit +%endif install -vdm 0755 %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libc cp -rp lib/picolibc/newlib/libc/ctype %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libc chmod -x %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libc/ctype/{mkcaseconv,mkcategories,mkunidata} @@ -296,20 +407,13 @@ install -vdm 0755 %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libm cp -rp lib/picolibc/newlib/libm/common %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libm cp -rp lib/picolibc/newlib/libm/math %{buildroot}%{tinygoroot}/lib/picolibc/newlib/libm cp -rp lib/picolibc-stdio.c %{buildroot}%{tinygoroot}/lib -install -vdm 0755 %{buildroot}%{tinygoroot}/pkg -for target in thumbv6m-unknown-unknown-eabi-cortex-m0 thumbv6m-unknown-unknown-eabi-cortex-m0plus thumbv7em-unknown-unknown-eabi-cortex-m4; do - install -vdm 0755 %{buildroot}%{tinygoroot}/pkg/${target} - for libc in compiler-rt picolibc; do - cp -rp ${target}/${libc} %{buildroot}%{tinygoroot}/pkg/${target}/ - done -done cp -rp src %{buildroot}%{tinygoroot}/ rm %{buildroot}%{tinygoroot}/src/examples/wasm/.gitignore cp -rp targets %{buildroot}%{tinygoroot}/ %if %{with check} -%global gotestflags %gocompilerflags -v -tags="llvm%{clang_llvm_version}" +%global gotestflags %gocompilerflags -v -tags="llvm%{clang_llvm_version}" -timeout 30m %check export TINYGOROOT=%{buildroot}%{tinygoroot} export GOPATH=%{buildroot}%{tinygoroot}:%{gopath} @@ -318,17 +422,11 @@ export GO111MODULE=off export XDG_CACHE_HOME="${PWD}/$(mktemp -d tinygo.XXXXXX)" %gocheck -v -t src -t tests ( cd _build/src/%{goipath} && GOPATH=%{currentgosourcedir}/_build:$GOPATH make smoketest STM32=0 XTENSA=0 ) -%ifnarch %{ix86} aarch64 +%ifnarch aarch64 make wasmtest %endif -# Ignoring errors due to CGo issue: -# https://github.com/tinygo-org/tinygo/issues/3057 -%ifarch %{ix86} -make tinygo-test-fast -%else make tinygo-test %endif -%endif %files @@ -336,6 +434,8 @@ make tinygo-test %license LICENSE %{_bindir}/tinygo %{tinygoroot} +%doc %{tinygoroot}/lib/bdwgc/README.md +%license %{tinygoroot}/lib/bdwgc/LICENSE %doc %{tinygoroot}/lib/CMSIS/README.md %license %{tinygoroot}/lib/compiler-rt-builtins/LICENSE.TXT %doc %{tinygoroot}/lib/compiler-rt-builtins/README.txt @@ -343,8 +443,6 @@ make tinygo-test %doc %{tinygoroot}/lib/nrfx/README.md %license %{tinygoroot}/lib/musl/COPYRIGHT -#gopkgfiles - %changelog %autochangelog