diff --git a/.circleci/config.yml b/.circleci/config.yml index f33f9de3..ca09e4aa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -102,21 +102,16 @@ commands: - run: make fmt-check jobs: - test-llvm11-go116: + test-llvm13-go116: docker: - image: circleci/golang:1.16-buster steps: - test-linux: - llvm: "11" - test-llvm12-go117: - docker: - - image: circleci/golang:1.17-buster - steps: - - test-linux: - llvm: "12" + llvm: "13" workflows: test-all: jobs: - - test-llvm11-go116 - - test-llvm12-go117 + # This tests our lowest supported versions of Go and LLVM, to make sure at + # least the smoke tests still pass. + - test-llvm13-go116 diff --git a/builder/build.go b/builder/build.go index 6f5e73f9..adf89d00 100644 --- a/builder/build.go +++ b/builder/build.go @@ -935,17 +935,6 @@ func optimizeProgram(mod llvm.Module, config *compileopts.Config) error { return errors.New("verification failure after LLVM optimization passes") } - // LLVM 11 by default tries to emit tail calls (even with the target feature - // disabled) unless it is explicitly disabled with a function attribute. - // This is a problem, as it tries to emit them and prints an error when it - // can't with this feature disabled. - // Because as of september 2020 tail calls are not yet widely supported, - // they need to be disabled until they are widely supported (at which point - // the +tail-call target feautre can be set). - if strings.HasPrefix(config.Triple(), "wasm") { - transform.DisableTailCalls(mod) - } - return nil } diff --git a/builder/builder_test.go b/builder/builder_test.go index c38d360a..42727e4a 100644 --- a/builder/builder_test.go +++ b/builder/builder_test.go @@ -26,7 +26,7 @@ func TestClangAttributes(t *testing.T) { "cortex-m0", "cortex-m0plus", "cortex-m3", - //"cortex-m33", // TODO: broken in LLVM 11, fixed in https://reviews.llvm.org/D90305 + "cortex-m33", "cortex-m4", "cortex-m7", "esp32c3", diff --git a/builder/darwin-libsystem.go b/builder/darwin-libsystem.go index 0eb262c1..d2846f27 100644 --- a/builder/darwin-libsystem.go +++ b/builder/darwin-libsystem.go @@ -6,7 +6,6 @@ import ( "github.com/tinygo-org/tinygo/compileopts" "github.com/tinygo-org/tinygo/goenv" - "tinygo.org/x/go-llvm" ) // Create a job that builds a Darwin libSystem.dylib stub library. This library @@ -39,12 +38,8 @@ func makeDarwinLibSystemJob(config *compileopts.Config, tmpdir string) *compileJ // Link object file to dynamic library. platformVersion := strings.TrimPrefix(strings.Split(config.Triple(), "-")[2], "macosx") - flavor := "darwin" - if strings.Split(llvm.Version, ".")[0] < "13" { - flavor = "darwinnew" // needed on LLVM 12 and below - } flags = []string{ - "-flavor", flavor, + "-flavor", "darwin", "-demangle", "-dynamic", "-dylib", diff --git a/builder/tools-builtin.go b/builder/tools-builtin.go index e8b7070c..ceb493be 100644 --- a/builder/tools-builtin.go +++ b/builder/tools-builtin.go @@ -54,7 +54,7 @@ func RunTool(tool string, args ...string) error { ok = C.tinygo_clang_driver(C.int(len(args)), (**C.char)(buf)) case "ld.lld": switch linker { - case "darwin", "darwinnew": // darwinnew is only needed for LLVM 12 and below + case "darwin": ok = C.tinygo_link_macho(C.int(len(args)), (**C.char)(buf)) case "elf": ok = C.tinygo_link_elf(C.int(len(args)), (**C.char)(buf)) diff --git a/cgo/libclang_config_llvm11.go b/cgo/libclang_config_llvm11.go deleted file mode 100644 index a967d471..00000000 --- a/cgo/libclang_config_llvm11.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build !byollvm && llvm11 -// +build !byollvm,llvm11 - -package cgo - -/* -#cgo linux CFLAGS: -I/usr/lib/llvm-11/include -#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@11/include -#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@11/include -#cgo freebsd CFLAGS: -I/usr/local/llvm11/include -#cgo linux LDFLAGS: -L/usr/lib/llvm-11/lib -lclang -#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@11/lib -lclang -lffi -#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@11/lib -lclang -lffi -#cgo freebsd LDFLAGS: -L/usr/local/llvm11/lib -lclang -*/ -import "C" diff --git a/cgo/libclang_config_llvm12.go b/cgo/libclang_config_llvm12.go deleted file mode 100644 index 736b3336..00000000 --- a/cgo/libclang_config_llvm12.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build !byollvm && llvm12 -// +build !byollvm,llvm12 - -package cgo - -/* -#cgo linux CFLAGS: -I/usr/lib/llvm-12/include -#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@12/include -#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@12/include -#cgo freebsd CFLAGS: -I/usr/local/llvm12/include -#cgo linux LDFLAGS: -L/usr/lib/llvm-12/lib -lclang -#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@12/lib -lclang -lffi -#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@12/lib -lclang -lffi -#cgo freebsd LDFLAGS: -L/usr/local/llvm12/lib -lclang -*/ -import "C" diff --git a/cgo/libclang_config_llvm13.go b/cgo/libclang_config_llvm13.go index 60708542..7a3db615 100644 --- a/cgo/libclang_config_llvm13.go +++ b/cgo/libclang_config_llvm13.go @@ -1,5 +1,5 @@ -//go:build !byollvm && !llvm11 && !llvm12 && !llvm14 -// +build !byollvm,!llvm11,!llvm12,!llvm14 +//go:build !byollvm && !llvm14 +// +build !byollvm,!llvm14 package cgo diff --git a/compileopts/target.go b/compileopts/target.go index 6a1dbf12..d2be8cfa 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -12,11 +12,9 @@ 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. @@ -266,12 +264,8 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { spec.Libc = "darwin-libSystem" arch := strings.Split(triple, "-")[0] platformVersion := strings.TrimPrefix(strings.Split(triple, "-")[2], "macosx") - flavor := "darwin" - if strings.Split(llvm.Version, ".")[0] < "13" { - flavor = "darwinnew" // needed on LLVM 12 and below - } spec.LDFlags = append(spec.LDFlags, - "-flavor", flavor, + "-flavor", "darwin", "-dead_strip", "-arch", arch, "-platform_version", "macos", platformVersion, platformVersion, @@ -296,13 +290,8 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { "--image-base", "0x400000", "--gc-sections", "--no-insert-timestamp", + "--no-dynamicbase", ) - 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/atomic.go b/compiler/atomic.go index 7a931b7f..c6938bdd 100644 --- a/compiler/atomic.go +++ b/compiler/atomic.go @@ -52,30 +52,6 @@ func (b *builder) createAtomicOp(call *ssa.CallCommon) (llvm.Value, bool) { ptr := b.getValue(call.Args[0]) old := b.getValue(call.Args[1]) newVal := b.getValue(call.Args[2]) - if strings.HasSuffix(name, "64") { - if strings.HasPrefix(b.Triple, "thumb") { - // Work around a bug in LLVM, at least LLVM 11: - // https://reviews.llvm.org/D95891 - // Check for thumbv6m, thumbv7, thumbv7em, and perhaps others. - // See also: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html - compareAndSwap := b.mod.NamedFunction("__sync_val_compare_and_swap_8") - if compareAndSwap.IsNil() { - // Declare the function if it isn't already declared. - i64Type := b.ctx.Int64Type() - fnType := llvm.FunctionType(i64Type, []llvm.Type{llvm.PointerType(i64Type, 0), i64Type, i64Type}, false) - compareAndSwap = llvm.AddFunction(b.mod, "__sync_val_compare_and_swap_8", fnType) - } - actualOldValue := b.CreateCall(compareAndSwap, []llvm.Value{ptr, old, newVal}, "") - // The __sync_val_compare_and_swap_8 function returns the old - // value. However, we shouldn't return the old value, we should - // return whether the compare/exchange was successful. This is - // easily done by comparing the returned (actual) old value with - // the expected old value passed to - // __sync_val_compare_and_swap_8. - swapped := b.CreateICmp(llvm.IntEQ, old, actualOldValue, "") - return swapped, true - } - } tuple := b.CreateAtomicCmpXchg(ptr, old, newVal, llvm.AtomicOrderingSequentiallyConsistent, llvm.AtomicOrderingSequentiallyConsistent, true) swapped := b.CreateExtractValue(tuple, 1, "") return swapped, true diff --git a/compiler/compiler_test.go b/compiler/compiler_test.go index 8364752c..f88a4a33 100644 --- a/compiler/compiler_test.go +++ b/compiler/compiler_test.go @@ -28,18 +28,11 @@ type testCase struct { func TestCompiler(t *testing.T) { t.Parallel() - // Check LLVM version. + // Determine LLVM version. llvmMajor, err := strconv.Atoi(strings.SplitN(llvm.Version, ".", 2)[0]) if err != nil { t.Fatal("could not parse LLVM version:", llvm.Version) } - if llvmMajor < 11 { - // It is likely this version needs to be bumped in the future. - // The goal is to at least test the LLVM version that's used by default - // in TinyGo and (if possible without too many workarounds) also some - // previous versions. - 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")) @@ -221,11 +214,6 @@ 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 and higher. - continue - } if llvmVersion < 14 && strings.HasPrefix(line, "target datalayout = ") { // The datalayout string may vary betewen LLVM versions. // Right now test outputs are for LLVM 14 and higher. diff --git a/src/runtime/gc_conservative.go b/src/runtime/gc_conservative.go index e28618b3..00cadc30 100644 --- a/src/runtime/gc_conservative.go +++ b/src/runtime/gc_conservative.go @@ -233,14 +233,6 @@ func setHeapEnd(newHeapEnd uintptr) { // This function can be called again when the heap size increases. The caller is // responsible for copying the metadata to the new location. func calculateHeapAddresses() { - if GOARCH == "wasm" { - // This is a workaround for a bug in wasm-ld: wasm-ld doesn't always - // align __heap_base and when this memory is shared through an API, it - // might result in unaligned memory. For details, see: - // https://reviews.llvm.org/D106499 - // It should be removed once we switch to LLVM 13, where this is fixed. - heapStart = align(heapStart) - } totalSize := heapEnd - heapStart // Allocate some memory to keep 2 bits of information about every block. diff --git a/src/runtime/gc_globals_conservative.go b/src/runtime/gc_globals_conservative.go index ba276748..56aa4674 100644 --- a/src/runtime/gc_globals_conservative.go +++ b/src/runtime/gc_globals_conservative.go @@ -4,21 +4,10 @@ package runtime -import "unsafe" - // markGlobals marks all globals, which are reachable by definition. // // This implementation marks all globals conservatively and assumes it can use // linker-defined symbols for the start and end of the .data section. func markGlobals() { - end := globalsEnd - if GOARCH == "wasm" { - // This is a workaround for a bug in wasm-ld: wasm-ld doesn't always - // align __heap_base and when this memory is shared through an API, it - // might result in unaligned memory. For details, see: - // https://reviews.llvm.org/D106499 - // It should be removed once we switch to LLVM 13, where this is fixed. - end = end &^ (unsafe.Alignof(end) - 1) - } - markRoots(globalsStart, end) + markRoots(globalsStart, globalsEnd) } diff --git a/src/runtime/gc_leaking.go b/src/runtime/gc_leaking.go index 897ed225..88d52eca 100644 --- a/src/runtime/gc_leaking.go +++ b/src/runtime/gc_leaking.go @@ -67,12 +67,7 @@ func SetFinalizer(obj interface{}, finalizer interface{}) { func initHeap() { // preinit() may have moved heapStart; reset heapptr - ptr := heapStart - if GOARCH == "wasm" { - // llvm11 and llvm12 do not correctly align the heap on wasm - ptr = align(ptr) - } - heapptr = ptr + heapptr = heapStart } // setHeapEnd sets a new (larger) heapEnd pointer. diff --git a/targets/cortex-m33.json b/targets/cortex-m33.json index 6e77c3f2..556b1e2a 100644 --- a/targets/cortex-m33.json +++ b/targets/cortex-m33.json @@ -1,4 +1,6 @@ { "inherits": ["cortex-m"], - "llvm-target": "thumbv7m-unknown-unknown-eabi" + "llvm-target": "thumbv8m.main-unknown-unknown-eabi", + "cpu": "cortex-m33", + "features": "+armv8-m.main,+dsp,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-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" } diff --git a/transform/globals.go b/transform/globals.go index d147062b..cc506f02 100644 --- a/transform/globals.go +++ b/transform/globals.go @@ -18,17 +18,3 @@ func ApplyFunctionSections(mod llvm.Module) { llvmFn = llvm.NextFunction(llvmFn) } } - -// DisableTailCalls adds the "disable-tail-calls"="true" function attribute to -// all functions. This may be necessary, in particular to avoid an error with -// WebAssembly in LLVM 11. -func DisableTailCalls(mod llvm.Module) { - attribute := mod.Context().CreateStringAttribute("disable-tail-calls", "true") - llvmFn := mod.FirstFunction() - for !llvmFn.IsNil() { - if !llvmFn.IsDeclaration() { - llvmFn.AddFunctionAttr(attribute) - } - llvmFn = llvm.NextFunction(llvmFn) - } -} diff --git a/transform/transform_test.go b/transform/transform_test.go index 2296c97f..bde1351f 100644 --- a/transform/transform_test.go +++ b/transform/transform_test.go @@ -9,7 +9,6 @@ import ( "io/ioutil" "os" "path/filepath" - "strconv" "strings" "testing" @@ -101,12 +100,6 @@ 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 @@ -116,11 +109,6 @@ 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