From 8bc0621c0764205da4c7f614d8ae5ea186e9f070 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Jan 04 2022 05:45:01 +0000 Subject: Backport patches for LLVM 12 --- diff --git a/0001-Skip-WASI-tests.patch b/0001-Skip-WASI-tests.patch index 2f841d8..2d236fe 100644 --- a/0001-Skip-WASI-tests.patch +++ b/0001-Skip-WASI-tests.patch @@ -1,7 +1,7 @@ From 9b9f5ddc40d838c0141a81f718bb57e546dbc742 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 15 Dec 2020 05:06:04 -0500 -Subject: [PATCH 1/5] Skip WASI tests. +Subject: [PATCH 1/7] Skip WASI tests. We do not have wasmtime available. diff --git a/0002-Add-canThrow-argument-to-llvm.InlineAsm-calls.patch b/0002-Add-canThrow-argument-to-llvm.InlineAsm-calls.patch index 295ecf4..bf348e5 100644 --- a/0002-Add-canThrow-argument-to-llvm.InlineAsm-calls.patch +++ b/0002-Add-canThrow-argument-to-llvm.InlineAsm-calls.patch @@ -1,7 +1,7 @@ From 2b069365b3d57dc0be1dfc32db62847ff4ae744c Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Mon, 6 Sep 2021 05:01:19 -0400 -Subject: [PATCH 2/5] Add canThrow argument to llvm.InlineAsm calls +Subject: [PATCH 2/7] Add canThrow argument to llvm.InlineAsm calls This is new in LLVM 13, and uses the default `false` which matches the default in the LLVM-internal `InlineAsm::get`, but I don't know if diff --git a/0003-Use-system-mingw64-headers-and-crt.patch b/0003-Use-system-mingw64-headers-and-crt.patch index 5e4ca3e..524e404 100644 --- a/0003-Use-system-mingw64-headers-and-crt.patch +++ b/0003-Use-system-mingw64-headers-and-crt.patch @@ -1,7 +1,7 @@ From e26581e0d413b241195b7eee63d6499aa9fca3d5 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sun, 2 Jan 2022 05:47:18 -0500 -Subject: [PATCH 3/5] Use system mingw64 headers and crt +Subject: [PATCH 3/7] Use system mingw64 headers and crt Signed-off-by: Elliott Sales de Andrade --- diff --git a/0004-arm-Explicitly-disable-unwind-tables.patch b/0004-arm-Explicitly-disable-unwind-tables.patch index ccd76cc..bbd695a 100644 --- a/0004-arm-Explicitly-disable-unwind-tables.patch +++ b/0004-arm-Explicitly-disable-unwind-tables.patch @@ -1,7 +1,7 @@ From 4f3e80094626a2b67075efdb6b899f2ab806725c Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Mon, 3 Jan 2022 18:40:21 -0500 -Subject: [PATCH 4/5] arm: Explicitly disable unwind tables +Subject: [PATCH 4/7] arm: Explicitly disable unwind tables Some clang builds (e.g., Fedora's) enable unwind tables by default. As tinygo does not need nor support them, that leads to undefined symbols diff --git a/0005-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch b/0005-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch index 3741d2f..6213390 100644 --- a/0005-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch +++ b/0005-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch @@ -1,7 +1,7 @@ From 4681ad345b38e1fa9627614adf3348886fa4a71c Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Mon, 3 Jan 2022 22:39:31 -0500 -Subject: [PATCH 5/5] Skip some cross Linux tests where qemu is broken +Subject: [PATCH 5/7] Skip some cross Linux tests where qemu is broken The upstream issues will hopefully be fixed soon: diff --git a/0006-targets-change-LLVM-features-to-match-vanilla-Clang.patch b/0006-targets-change-LLVM-features-to-match-vanilla-Clang.patch new file mode 100644 index 0000000..d0e418a --- /dev/null +++ b/0006-targets-change-LLVM-features-to-match-vanilla-Clang.patch @@ -0,0 +1,129 @@ +From a0ebf57f6164d5f795b7022fa26ac8bb66bee9e8 Mon Sep 17 00:00:00 2001 +From: Ayke van Laethem +Date: Fri, 19 Nov 2021 14:47:55 +0100 +Subject: [PATCH 6/7] targets: change LLVM features to match vanilla Clang + +I mistakenly believed the difference was in LLVM version 11.0.0 vs LLVM +11.1.0. However, the difference is in whether we use the Debian version +of Clang. + +The Debian version has had lots of patches. I'm not sure which is to +blame, but it could be this one: +https://salsa.debian.org/pkg-llvm-team/llvm-toolchain/-/blob/snapshot/debian/patches/clang-arm-default-vfp3-on-armv7a.patch + +Signed-off-by: Elliott Sales de Andrade +--- + builder/builder_test.go | 19 ++++++++++++------- + compileopts/target.go | 2 +- + targets/cortex-m0.json | 2 +- + targets/cortex-m0plus.json | 2 +- + targets/cortex-m3.json | 2 +- + targets/gameboy-advance.json | 2 +- + 6 files changed, 17 insertions(+), 12 deletions(-) + +diff --git a/builder/builder_test.go b/builder/builder_test.go +index cff43db8..c38d360a 100644 +--- a/builder/builder_test.go ++++ b/builder/builder_test.go +@@ -5,6 +5,7 @@ import ( + "io/ioutil" + "os" + "path/filepath" ++ "runtime" + "testing" + + "github.com/tinygo-org/tinygo/compileopts" +@@ -60,7 +61,11 @@ func TestClangAttributes(t *testing.T) { + {GOOS: "darwin", GOARCH: "arm64"}, + {GOOS: "windows", GOARCH: "amd64"}, + } { +- t.Run("GOOS="+options.GOOS+",GOARCH="+options.GOARCH, func(t *testing.T) { ++ name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH ++ if options.GOARCH == "arm" { ++ name += ",GOARM=" + options.GOARM ++ } ++ t.Run(name, func(t *testing.T) { + testClangAttributes(t, options) + }) + } +@@ -131,12 +136,12 @@ func testClangAttributes(t *testing.T, options *compileopts.Options) { + t.Errorf("target has CPU %#v but Clang makes it CPU %#v", config.CPU(), cpu) + } + if features != config.Features() { +- if llvm.Version != "11.0.0" { +- // This needs to be removed once we switch to LLVM 12. +- // LLVM 11.0.0 uses a different "target-features" string than LLVM +- // 11.1.0 for Thumb targets. The Xtensa fork is still based on LLVM +- // 11.0.0, so we need to skip this check on that version. +- t.Errorf("target has LLVM features %#v but Clang makes it %#v", config.Features(), features) ++ if hasBuiltinTools || runtime.GOOS != "linux" { ++ // Skip this step when using an external Clang invocation on Linux. ++ // The reason is that Debian has patched Clang in a way that ++ // modifies the LLVM features string, changing lots of FPU/float ++ // related flags. We want to test vanilla Clang, not Debian Clang. ++ t.Errorf("target has LLVM features\n\t%#v\nbut Clang makes it\n\t%#v", config.Features(), features) + } + } + } +diff --git a/compileopts/target.go b/compileopts/target.go +index 829b481e..bdd77613 100644 +--- a/compileopts/target.go ++++ b/compileopts/target.go +@@ -263,7 +263,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { + case "armv6": + spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-thumb-mode" + case "armv7": +- spec.Features = "+armv7-a,+dsp,+fp64,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp,-thumb-mode" ++ spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-thumb-mode" + } + case "arm64": + spec.CPU = "generic" +diff --git a/targets/cortex-m0.json b/targets/cortex-m0.json +index fe356805..315d6658 100644 +--- a/targets/cortex-m0.json ++++ b/targets/cortex-m0.json +@@ -2,5 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv6m-unknown-unknown-eabi", + "cpu": "cortex-m0", +- "features": "+armv6-m,+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,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" ++ "features": "+armv6-m,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" + } +diff --git a/targets/cortex-m0plus.json b/targets/cortex-m0plus.json +index a21d06ca..6ac9b531 100644 +--- a/targets/cortex-m0plus.json ++++ b/targets/cortex-m0plus.json +@@ -2,5 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv6m-unknown-unknown-eabi", + "cpu": "cortex-m0plus", +- "features": "+armv6-m,+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,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" ++ "features": "+armv6-m,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" + } +diff --git a/targets/cortex-m3.json b/targets/cortex-m3.json +index 7b878d52..07d88dfe 100644 +--- a/targets/cortex-m3.json ++++ b/targets/cortex-m3.json +@@ -2,5 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv7m-unknown-unknown-eabi", + "cpu": "cortex-m3", +- "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,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" ++ "features": "+armv7-m,+hwdiv,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" + } +diff --git a/targets/gameboy-advance.json b/targets/gameboy-advance.json +index 24e16cda..2467b4b9 100644 +--- a/targets/gameboy-advance.json ++++ b/targets/gameboy-advance.json +@@ -1,7 +1,7 @@ + { + "llvm-target": "armv4t-unknown-unknown-eabi", + "cpu": "arm7tdmi", +- "features": "+armv4t,+soft-float,+strict-align,-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,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp", ++ "features": "+armv4t,+strict-align,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2,-thumb-mode", + "build-tags": ["gameboyadvance", "arm7tdmi", "baremetal", "linux", "arm"], + "goos": "linux", + "goarch": "arm", +-- +2.31.1 + diff --git a/0007-all-add-LLVM-12-support.patch b/0007-all-add-LLVM-12-support.patch new file mode 100644 index 0000000..ff708c7 --- /dev/null +++ b/0007-all-add-LLVM-12-support.patch @@ -0,0 +1,469 @@ +From aefb7735476f11cbe3b7cb2a026afd34ab74d771 Mon Sep 17 00:00:00 2001 +From: Ayke van Laethem +Date: Sun, 28 Mar 2021 19:56:03 -0400 +Subject: [PATCH 7/7] all: add LLVM 12 support + +Originally based on a PR by @QuLogic, but extended a lot to get all +tests to pass. + +Signed-off-by: Elliott Sales de Andrade +--- + .circleci/config.yml | 18 +++++++++--------- + .github/workflows/windows.yml | 4 ++-- + Makefile | 14 ++++++-------- + cgo/libclang_config.go | 1 + + cgo/libclang_config_llvm12.go | 14 ++++++++++++++ + compileopts/target.go | 14 ++++++++++++++ + compiler/compiler_test.go | 27 ++++++++++++++++++++++----- + compiler/testdata/channel.ll | 6 +++--- + compiler/testdata/intrinsics-wasm.ll | 6 +++--- + go.mod | 4 ++-- + go.sum | 10 ++++------ + interp/interp_test.go | 1 + + transform/maps_test.go | 1 + + transform/testdata/coroutines.out.ll | 6 +++--- + transform/transform_test.go | 3 ++- + 15 files changed, 87 insertions(+), 42 deletions(-) + create mode 100644 cgo/libclang_config_llvm12.go + +diff --git a/.circleci/config.yml b/.circleci/config.yml +index 61c7e287..50bdd087 100644 +--- a/.circleci/config.yml ++++ b/.circleci/config.yml +@@ -52,12 +52,12 @@ commands: + steps: + - restore_cache: + keys: +- - llvm-source-11-v2 ++ - llvm-source-12-v1 + - run: + name: "Fetch LLVM source" + command: make llvm-source + - save_cache: +- key: llvm-source-11-v2 ++ key: llvm-source-12-v1 + paths: + - llvm-project/clang/lib/Headers + - llvm-project/clang/include +@@ -332,12 +332,12 @@ commands: + - go-cache-macos-v3-{{ checksum "go.mod" }} + - restore_cache: + keys: +- - llvm-source-11-macos-v3 ++ - llvm-source-12-macos-v1 + - run: + name: "Fetch LLVM source" + command: make llvm-source + - save_cache: +- key: llvm-source-11-macos-v3 ++ key: llvm-source-12-macos-v1 + paths: + - llvm-project/clang/lib/Headers + - llvm-project/clang/include +@@ -345,7 +345,7 @@ commands: + - llvm-project/llvm/include + - restore_cache: + keys: +- - llvm-build-11-macos-v5 ++ - llvm-build-12-macos-v1 + - run: + name: "Build LLVM" + command: | +@@ -359,7 +359,7 @@ commands: + find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \; + fi + - save_cache: +- key: llvm-build-11-macos-v5 ++ key: llvm-build-12-macos-v1 + paths: + llvm-build + - restore_cache: +@@ -418,12 +418,12 @@ jobs: + steps: + - test-linux: + llvm: "11" +- test-llvm11-go116: ++ test-llvm12-go116: + docker: + - image: circleci/golang:1.16-buster + steps: + - test-linux: +- llvm: "11" ++ llvm: "12" + assert-test-linux: + docker: + - image: circleci/golang:1.17-buster +@@ -451,7 +451,7 @@ workflows: + test-all: + jobs: + - test-llvm11-go115 +- - test-llvm11-go116 ++ - test-llvm12-go116 + - build-linux + - test-linux-build: + requires: +diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml +index 4bc07d59..8649f635 100644 +--- a/.github/workflows/windows.yml ++++ b/.github/workflows/windows.yml +@@ -27,7 +27,7 @@ jobs: + uses: actions/cache@v2 + id: cache-llvm-source + with: +- key: llvm-source-11-windows-v1 ++ key: llvm-source-12-windows-v1 + path: | + llvm-project/clang/lib/Headers + llvm-project/clang/include +@@ -40,7 +40,7 @@ jobs: + uses: actions/cache@v2 + id: cache-llvm-build + with: +- key: llvm-build-11-windows-v2 ++ key: llvm-build-12-windows-v1 + path: llvm-build + - name: Build LLVM + if: steps.cache-llvm-build.outputs.cache-hit != 'true' +diff --git a/Makefile b/Makefile +index 5de97014..0ebfcd82 100644 +--- a/Makefile ++++ b/Makefile +@@ -59,18 +59,13 @@ ifeq ($(OS),Windows_NT) + + BINARYEN_OPTION += -DCMAKE_EXE_LINKER_FLAGS='-static-libgcc -static-libstdc++' + +- LIBCLANG_NAME = libclang +- + else ifeq ($(shell uname -s),Darwin) + MD5SUM = md5 +- LIBCLANG_NAME = clang + else ifeq ($(shell uname -s),FreeBSD) + MD5SUM = md5 +- LIBCLANG_NAME = clang + START_GROUP = -Wl,--start-group + END_GROUP = -Wl,--end-group + else +- LIBCLANG_NAME = clang + START_GROUP = -Wl,--start-group + END_GROUP = -Wl,--end-group + endif +@@ -86,19 +81,22 @@ LLD_LIBS = $(START_GROUP) $(addprefix -l,$(LLD_LIB_NAMES)) $(END_GROUP) + # Other libraries that are needed to link TinyGo. + EXTRA_LIB_NAMES = LLVMInterpreter + ++# All libraries to be built and linked with the tinygo binary (lib/lib*.a). ++LIB_NAMES = clang $(CLANG_LIB_NAMES) $(LLD_LIB_NAMES) $(EXTRA_LIB_NAMES) ++ + # These build targets appear to be the only ones necessary to build all TinyGo + # dependencies. Only building a subset significantly speeds up rebuilding LLVM. + # The Makefile rules convert a name like lldELF to lib/liblldELF.a to match the + # library path (for ninja). + # This list also includes a few tools that are necessary as part of the full + # TinyGo build. +-NINJA_BUILD_TARGETS = clang llvm-config llvm-ar llvm-nm $(addprefix lib/lib,$(addsuffix .a,$(LIBCLANG_NAME) $(CLANG_LIB_NAMES) $(LLD_LIB_NAMES) $(EXTRA_LIB_NAMES))) ++NINJA_BUILD_TARGETS = clang llvm-config llvm-ar llvm-nm $(addprefix lib/lib,$(addsuffix .a,$(LIB_NAMES))) + + # For static linking. + ifneq ("$(wildcard $(LLVM_BUILDDIR)/bin/llvm-config*)","") + CGO_CPPFLAGS+=$(shell $(LLVM_BUILDDIR)/bin/llvm-config --cppflags) -I$(abspath $(LLVM_BUILDDIR))/tools/clang/include -I$(abspath $(CLANG_SRC))/include -I$(abspath $(LLD_SRC))/include + CGO_CXXFLAGS=-std=c++14 +- CGO_LDFLAGS+=$(abspath $(LLVM_BUILDDIR))/lib/lib$(LIBCLANG_NAME).a -L$(abspath $(LLVM_BUILDDIR)/lib) $(CLANG_LIBS) $(LLD_LIBS) $(shell $(LLVM_BUILDDIR)/bin/llvm-config --ldflags --libs --system-libs $(LLVM_COMPONENTS)) -lstdc++ $(CGO_LDFLAGS_EXTRA) ++ CGO_LDFLAGS+=-L$(abspath $(LLVM_BUILDDIR)/lib) -lclang $(CLANG_LIBS) $(LLD_LIBS) $(shell $(LLVM_BUILDDIR)/bin/llvm-config --ldflags --libs --system-libs $(LLVM_COMPONENTS)) -lstdc++ $(CGO_LDFLAGS_EXTRA) + endif + + +@@ -162,7 +160,7 @@ gen-device-rp: build/gen-device-svd + + # Get LLVM sources. + $(LLVM_PROJECTDIR)/llvm: +- git clone -b xtensa_release_11.0.0 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR) ++ git clone -b xtensa_release_12.0.1 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR) + llvm-source: $(LLVM_PROJECTDIR)/llvm + + # Configure LLVM. +diff --git a/cgo/libclang_config.go b/cgo/libclang_config.go +index 4b4ce2db..9f7cdc1c 100644 +--- a/cgo/libclang_config.go ++++ b/cgo/libclang_config.go +@@ -1,4 +1,5 @@ + // +build !byollvm ++// +build !llvm12 + + package cgo + +diff --git a/cgo/libclang_config_llvm12.go b/cgo/libclang_config_llvm12.go +new file mode 100644 +index 00000000..1837cc15 +--- /dev/null ++++ b/cgo/libclang_config_llvm12.go +@@ -0,0 +1,14 @@ ++// +build !byollvm ++// +build llvm12 ++ ++package cgo ++ ++/* ++#cgo linux CFLAGS: -I/usr/lib/llvm-12/include ++#cgo darwin CFLAGS: -I/usr/local/opt/llvm@12/include ++#cgo freebsd CFLAGS: -I/usr/local/llvm12/include ++#cgo linux LDFLAGS: -L/usr/lib/llvm-12/lib -lclang ++#cgo darwin LDFLAGS: -L/usr/local/opt/llvm@12/lib -lclang -lffi ++#cgo freebsd LDFLAGS: -L/usr/local/llvm12/lib -lclang ++*/ ++import "C" +diff --git a/compileopts/target.go b/compileopts/target.go +index bdd77613..57b5bd84 100644 +--- a/compileopts/target.go ++++ b/compileopts/target.go +@@ -12,9 +12,11 @@ import ( + "path/filepath" + "reflect" + "runtime" ++ "strconv" + "strings" + + "github.com/tinygo-org/tinygo/goenv" ++ "tinygo.org/x/go-llvm" + ) + + // Target specification for a given target. Used for bare metal targets. +@@ -280,6 +282,12 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { + } else if goos == "windows" { + spec.Linker = "ld.lld" + spec.Libc = "mingw-w64" ++ // Note: using a medium code model, low image base and no ASLR ++ // because Go doesn't really need those features. ASLR patches ++ // around issues for unsafe languages like C/C++ that are not ++ // normally present in Go (without explicitly opting in). ++ // For more discussion: ++ // https://groups.google.com/g/Golang-nuts/c/Jd9tlNc6jUE/m/Zo-7zIP_m3MJ?pli=1 + spec.LDFlags = append(spec.LDFlags, + "-m", "i386pep", + "-Bdynamic", +@@ -287,6 +295,12 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { + "--gc-sections", + "--no-insert-timestamp", + ) ++ llvmMajor, _ := strconv.Atoi(strings.Split(llvm.Version, ".")[0]) ++ if llvmMajor >= 12 { ++ // This flag was added in LLVM 12. At the same time, LLVM 12 ++ // switched the default from --dynamicbase to --no-dynamicbase. ++ spec.LDFlags = append(spec.LDFlags, "--no-dynamicbase") ++ } + } else { + spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie + } +diff --git a/compiler/compiler_test.go b/compiler/compiler_test.go +index cbf89fe2..3c978274 100644 +--- a/compiler/compiler_test.go ++++ b/compiler/compiler_test.go +@@ -41,6 +41,13 @@ func TestCompiler(t *testing.T) { + t.Skip("compiler tests require LLVM 11 or above, got LLVM ", llvm.Version) + } + ++ // Determine Go minor version (e.g. 16 in go1.16.3). ++ _, goMinor, err := goenv.GetGorootVersion(goenv.Get("GOROOT")) ++ if err != nil { ++ t.Fatal("could not read Go version:", err) ++ } ++ ++ // Determine which tests to run, depending on the Go and LLVM versions. + tests := []testCase{ + {"basic.go", "", ""}, + {"pointer.go", "", ""}, +@@ -58,12 +65,11 @@ func TestCompiler(t *testing.T) { + {"intrinsics.go", "wasm", ""}, + {"gc.go", "", ""}, + } +- +- _, minor, err := goenv.GetGorootVersion(goenv.Get("GOROOT")) +- if err != nil { +- t.Fatal("could not read Go version:", err) ++ if llvmMajor >= 12 { ++ tests = append(tests, testCase{"intrinsics.go", "cortex-m-qemu", ""}) ++ tests = append(tests, testCase{"intrinsics.go", "wasm", ""}) + } +- if minor >= 17 { ++ if goMinor >= 17 { + tests = append(tests, testCase{"go1.17.go", "", ""}) + } + +@@ -201,6 +207,12 @@ func fuzzyEqualIR(s1, s2 string) bool { + // stripped out. + func filterIrrelevantIRLines(lines []string) []string { + var out []string ++ llvmVersion, err := strconv.Atoi(strings.Split(llvm.Version, ".")[0]) ++ if err != nil { ++ // Note: this should never happen and if it does, it will always happen ++ // for a particular build because llvm.Version is a constant. ++ panic(err) ++ } + for _, line := range lines { + line = strings.Split(line, ";")[0] // strip out comments/info + line = strings.TrimRight(line, "\r ") // drop '\r' on Windows and remove trailing spaces from comments +@@ -210,6 +222,11 @@ func filterIrrelevantIRLines(lines []string) []string { + if strings.HasPrefix(line, "source_filename = ") { + continue + } ++ if llvmVersion < 12 && strings.HasPrefix(line, "attributes ") { ++ // Ignore attribute groups. These may change between LLVM versions. ++ // Right now test outputs are for LLVM 12. ++ continue ++ } + out = append(out, line) + } + return out +diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll +index 04bfa4af..36d7fd96 100644 +--- a/compiler/testdata/channel.ll ++++ b/compiler/testdata/channel.ll +@@ -34,12 +34,12 @@ entry: + ret void + } + +-; Function Attrs: argmemonly nounwind willreturn ++; Function Attrs: argmemonly nofree nosync nounwind willreturn + declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + + declare void @runtime.chanSend(%runtime.channel* dereferenceable_or_null(32), i8*, %runtime.channelBlockedList* dereferenceable_or_null(24), i8*, i8*) + +-; Function Attrs: argmemonly nounwind willreturn ++; Function Attrs: argmemonly nofree nosync nounwind willreturn + declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + + ; Function Attrs: nounwind +@@ -119,4 +119,4 @@ select.body: ; preds = %select.next + declare { i32, i1 } @runtime.tryChanSelect(i8*, %runtime.chanSelectState*, i32, i32, i8*, i8*) + + attributes #0 = { nounwind } +-attributes #1 = { argmemonly nounwind willreturn } ++attributes #1 = { argmemonly nofree nosync nounwind willreturn } +diff --git a/compiler/testdata/intrinsics-wasm.ll b/compiler/testdata/intrinsics-wasm.ll +index bebadb08..9e6687d5 100644 +--- a/compiler/testdata/intrinsics-wasm.ll ++++ b/compiler/testdata/intrinsics-wasm.ll +@@ -18,7 +18,7 @@ entry: + ret double %0 + } + +-; Function Attrs: nounwind readnone speculatable willreturn ++; Function Attrs: nofree nosync nounwind readnone speculatable willreturn + declare double @llvm.sqrt.f64(double) #1 + + ; Function Attrs: nounwind +@@ -28,8 +28,8 @@ entry: + ret double %0 + } + +-; Function Attrs: nounwind readnone speculatable willreturn ++; Function Attrs: nofree nosync nounwind readnone speculatable willreturn + declare double @llvm.trunc.f64(double) #1 + + attributes #0 = { nounwind } +-attributes #1 = { nounwind readnone speculatable willreturn } ++attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +diff --git a/go.mod b/go.mod +index 26a4b027..52dd71c3 100644 +--- a/go.mod ++++ b/go.mod +@@ -3,7 +3,7 @@ module github.com/tinygo-org/tinygo + go 1.15 + + require ( +- github.com/aykevl/go-wasm v0.0.2-0.20211030161413-11881cb9032d // indirect ++ github.com/aykevl/go-wasm v0.0.2-0.20211119014117-0761b1ddcd1a // indirect + github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 + github.com/chromedp/cdproto v0.0.0-20210113043257-dabd2f2e7693 + github.com/chromedp/chromedp v0.6.4 +@@ -13,5 +13,5 @@ require ( + go.bug.st/serial v1.1.3 + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 + golang.org/x/tools v0.1.6-0.20210813165731-45389f592fe9 +- tinygo.org/x/go-llvm v0.0.0-20210325115028-e7b85195e81c ++ tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be + ) +diff --git a/go.sum b/go.sum +index 1daa9388..73697653 100644 +--- a/go.sum ++++ b/go.sum +@@ -1,5 +1,5 @@ +-github.com/aykevl/go-wasm v0.0.2-0.20211030161413-11881cb9032d h1:JeuI5/546naK5hpOIX+Lq5xE8rvt7uwiTp6iL+pLQgk= +-github.com/aykevl/go-wasm v0.0.2-0.20211030161413-11881cb9032d/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw= ++github.com/aykevl/go-wasm v0.0.2-0.20211119014117-0761b1ddcd1a h1:QPU7APo6y/6VkCDq6HU3WWIUzER8iywSac23+1UQv60= ++github.com/aykevl/go-wasm v0.0.2-0.20211119014117-0761b1ddcd1a/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw= + github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI= + github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= + github.com/chromedp/cdproto v0.0.0-20210113043257-dabd2f2e7693 h1:11eq/RkpaotwdF6b1TRMcdgQUPNmyFEJOB7zLvh0O/Y= +@@ -68,7 +68,5 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= + gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +-tinygo.org/x/go-llvm v0.0.0-20210308112806-9ef958b6bed4 h1:CMUHxVTb+UuUePuMf8vkWjZ3gTp9BBK91KrgOCwoNHs= +-tinygo.org/x/go-llvm v0.0.0-20210308112806-9ef958b6bed4/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= +-tinygo.org/x/go-llvm v0.0.0-20210325115028-e7b85195e81c h1:vn9IPshzYmzZis10UEVrsIBRv9FpykADw6M3/tHHROg= +-tinygo.org/x/go-llvm v0.0.0-20210325115028-e7b85195e81c/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= ++tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be h1:syIpWbi/yESuoyijF2nhRdgX4422sNfmij+o73B3+vU= ++tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= +diff --git a/interp/interp_test.go b/interp/interp_test.go +index 516fdd11..ae2635af 100644 +--- a/interp/interp_test.go ++++ b/interp/interp_test.go +@@ -71,6 +71,7 @@ func runTest(t *testing.T, pathPrefix string) { + defer pm.Dispose() + pm.AddGlobalOptimizerPass() + pm.AddDeadStoreEliminationPass() ++ pm.AddAggressiveDCEPass() + pm.Run(mod) + + // Read the expected output IR. +diff --git a/transform/maps_test.go b/transform/maps_test.go +index 1f821d4b..e8b11133 100644 +--- a/transform/maps_test.go ++++ b/transform/maps_test.go +@@ -18,6 +18,7 @@ func TestOptimizeMaps(t *testing.T) { + pm := llvm.NewPassManager() + defer pm.Dispose() + pm.AddDeadStoreEliminationPass() ++ pm.AddAggressiveDCEPass() + pm.Run(mod) + }) + } +diff --git a/transform/testdata/coroutines.out.ll b/transform/testdata/coroutines.out.ll +index d4a49a5e..de902884 100644 +--- a/transform/testdata/coroutines.out.ll ++++ b/transform/testdata/coroutines.out.ll +@@ -301,13 +301,13 @@ declare i8* @llvm.coro.free(token, i8* nocapture readonly) #0 + ; Function Attrs: nounwind + declare token @llvm.coro.save(i8*) #2 + +-; Function Attrs: argmemonly nounwind willreturn ++; Function Attrs: argmemonly nofree nosync nounwind willreturn + declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #3 + +-; Function Attrs: argmemonly nounwind willreturn ++; Function Attrs: argmemonly nofree nosync nounwind willreturn + declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #3 + + attributes #0 = { argmemonly nounwind readonly } + attributes #1 = { nounwind readnone } + attributes #2 = { nounwind } +-attributes #3 = { argmemonly nounwind willreturn } ++attributes #3 = { argmemonly nofree nosync nounwind willreturn } +diff --git a/transform/transform_test.go b/transform/transform_test.go +index ae531eeb..935d660b 100644 +--- a/transform/transform_test.go ++++ b/transform/transform_test.go +@@ -116,8 +116,9 @@ func filterIrrelevantIRLines(lines []string) []string { + if strings.HasPrefix(line, "source_filename = ") { + continue + } +- if llvmVersion < 11 && strings.HasPrefix(line, "attributes ") { ++ if llvmVersion < 12 && strings.HasPrefix(line, "attributes ") { + // Ignore attribute groups. These may change between LLVM versions. ++ // Right now test outputs are for LLVM 12. + continue + } + out = append(out, line) +-- +2.31.1 + diff --git a/tinygo.spec b/tinygo.spec index 08c4568..d29017b 100644 --- a/tinygo.spec +++ b/tinygo.spec @@ -10,7 +10,7 @@ Version: 0.21.0 %global CMSIS_commit 9fe411cef1cef5de58e5957b89760759de44e393 %global avr_commit 6624554c02b237b23dc17d53e992bf54033fc228 -%global clang_llvm_version 11 +%global clang_llvm_version 12 %global cmsis_svd_commit df75ff974c76a911fc2815e29807f5ecaae06fc2 %global compiler_rt_version 9.0.0 %global musl_version 1.2.2 @@ -71,6 +71,11 @@ Patch0004: 0004-arm-Explicitly-disable-unwind-tables.patch # https://gitlab.com/qemu-project/qemu/-/issues/447 # https://gitlab.com/qemu-project/qemu/-/issues/690 Patch0005: 0005-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch +# Backport support for LLVM 12 +# https://github.com/tinygo-org/tinygo/pull/2291 +Patch0006: 0006-targets-change-LLVM-features-to-match-vanilla-Clang.patch +# https://github.com/tinygo-org/tinygo/pull/2300 +Patch0007: 0007-all-add-LLVM-12-support.patch # Not supported upstream yet. ExcludeArch: armv7hl ppc64le s390x