From 2b7f56220210198dc850df7d03017d7908bb119c Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 22 Sep 2022 13:39:51 +0200 Subject: [PATCH] ci: add support for LLVM 15 This commit switches to LLVM 15 everywhere by default, while still keeping LLVM 14 support. --- .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 | 265 +++++++++--------- 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 | 204 ++++++-------- compiler/testdata/interface.ll | 81 +++--- 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, 895 insertions(+), 881 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 e5724751..182ca5f4 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 7d5fad9e..2d0f3602 100644 --- a/Makefile +++ b/Makefile @@ -113,7 +113,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 @@ -148,7 +148,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. @@ -236,7 +236,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 bdfdc4a8..a65a920b 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 @@ -104,6 +106,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, error) { 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 +lpad: ; preds = %rundefers.callback119, %rundefers.callback016, %rundefers.callback1, %rundefers.callback0, %entry + br label %rundefers.loophead10 -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.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.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 +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 +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 + +6: ; preds = %rundefers.callback016 + call void @"main.deferMultiple$1"(ptr undef) + br label %rundefers.loophead10 + +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 %9, label %lpad + br i1 %setjmp.result21, label %7, label %lpad -9: ; preds = %rundefers.callback018 - call void @"main.deferMultiple$1"(i8* undef) - br label %rundefers.loophead12 +7: ; preds = %rundefers.callback119 + call void @"main.deferMultiple$2"(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 - -10: ; preds = %rundefers.callback122 - call void @"main.deferMultiple$2"(i8* undef) - br label %rundefers.loophead12 - -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 { +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* - 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 + %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 } +%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 { %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) } +@"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 136915d5..81dcc3f3 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, "")