diff options
40 files changed, 898 insertions, 884 deletions
diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index 2059574a9..9197ea3cd 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 8fc527177..cf26a4f24 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 e57247516..182ca5f45 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' @@ -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 115001213..cd3229adb 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<EmitDwarfUnwindType>(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<MCAsmInfo> 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<MCObjectFileInfo> 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<MCCodeEmitter> CE; if (Opts.ShowEncoding) - CE.reset(TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx)); + CE.reset(TheTarget->createMCCodeEmitter(*MCII, Ctx)); std::unique_ptr<MCAsmBackend> MAB( TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions)); @@ -367,7 +382,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts, } std::unique_ptr<MCCodeEmitter> CE( - TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx)); + TheTarget->createMCCodeEmitter(*MCII, Ctx)); std::unique_ptr<MCAsmBackend> 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 538e9a268..150d6f143 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<llvm::Triple> 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 bdfdc4a8a..a65a920b7 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 0553bd50d..953ce8e23 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 000000000..e918a473a --- /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 4203fdf76..404c73163 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 9fedfbd67..a511e518b 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 e73b68dad..ca2777654 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 01b3fc377..61ca4473c 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 e9fcbad31..d2b4a96db 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 4d88f66fd..6ef0dc92c 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 [email protected] = 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 ec3dd6b93..8f4ed74e7 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 693f1b07a..0841e2550 100644 --- a/compiler/testdata/defer-cortex-m-qemu.ll +++ b/compiler/testdata/defer-cortex-m-qemu.ll @@ -3,103 +3,99 @@ source_filename = "defer.go" target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" target triple = "thumbv7m-unknown-unknown-eabi" -%runtime._defer = type { i32, %runtime._defer* } -%runtime.deferFrame = type { i8*, i8*, [0 x i8*], %runtime.deferFrame*, i1, %runtime._interface } -%runtime._interface = type { i32, i8* } +%runtime.deferFrame = type { ptr, ptr, [0 x ptr], ptr, i1, %runtime._interface } +%runtime._interface = type { i32, ptr } +%runtime._defer = type { i32, ptr } -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 +declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(i8* %context) unnamed_addr #1 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } -declare void @main.external(i8*) #0 +declare void @main.external(ptr) #0 ; Function Attrs: nounwind -define hidden void @main.deferSimple(i8* %context) unnamed_addr #1 { +define hidden void @main.deferSimple(ptr %context) unnamed_addr #1 { entry: - %defer.alloca = alloca { i32, %runtime._defer* }, align 4 - %deferPtr = alloca %runtime._defer*, align 4 - store %runtime._defer* null, %runtime._defer** %deferPtr, align 4 + %defer.alloca = alloca { i32, ptr }, align 4 + %deferPtr = alloca ptr, align 4 + store ptr null, ptr %deferPtr, align 4 %deferframe.buf = alloca %runtime.deferFrame, align 4 - %0 = call i8* @llvm.stacksave() - call void @runtime.setupDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* %0, i8* undef) #3 - %defer.alloca.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 0 - store i32 0, i32* %defer.alloca.repack, align 4 - %defer.alloca.repack16 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 1 - store %runtime._defer* null, %runtime._defer** %defer.alloca.repack16, align 4 - %1 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }** - store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %1, align 4 - %setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 + %0 = call ptr @llvm.stacksave() + call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #3 + store i32 0, ptr %defer.alloca, align 4 + %defer.alloca.repack15 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1 + store ptr null, ptr %defer.alloca.repack15, align 4 + store ptr %defer.alloca, ptr %deferPtr, align 4 + %setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 %setjmp.result = icmp eq i32 %setjmp, 0 - br i1 %setjmp.result, label %2, label %lpad + br i1 %setjmp.result, label %1, label %lpad -2: ; preds = %entry - call void @main.external(i8* undef) #3 +1: ; preds = %entry + call void @main.external(ptr undef) #3 br label %rundefers.loophead -rundefers.loophead: ; preds = %4, %2 - %3 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4 - %stackIsNil = icmp eq %runtime._defer* %3, null +rundefers.loophead: ; preds = %3, %1 + %2 = load ptr, ptr %deferPtr, align 4 + %stackIsNil = icmp eq ptr %2, null br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop rundefers.loop: ; preds = %rundefers.loophead - %stack.next.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %3, i32 0, i32 1 - %stack.next = load %runtime._defer*, %runtime._defer** %stack.next.gep, align 4 - store %runtime._defer* %stack.next, %runtime._defer** %deferPtr, align 4 - %callback.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %3, i32 0, i32 0 - %callback = load i32, i32* %callback.gep, align 4 + %stack.next.gep = getelementptr inbounds %runtime._defer, ptr %2, i32 0, i32 1 + %stack.next = load ptr, ptr %stack.next.gep, align 4 + store ptr %stack.next, ptr %deferPtr, align 4 + %callback = load i32, ptr %2, align 4 switch i32 %callback, label %rundefers.default [ i32 0, label %rundefers.callback0 ] rundefers.callback0: ; preds = %rundefers.loop - %setjmp1 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 + %setjmp1 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 %setjmp.result2 = icmp eq i32 %setjmp1, 0 - br i1 %setjmp.result2, label %4, label %lpad + br i1 %setjmp.result2, label %3, label %lpad -4: ; preds = %rundefers.callback0 - call void @"main.deferSimple$1"(i8* undef) +3: ; preds = %rundefers.callback0 + call void @"main.deferSimple$1"(ptr undef) br label %rundefers.loophead rundefers.default: ; preds = %rundefers.loop unreachable rundefers.end: ; preds = %rundefers.loophead - call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3 + call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3 ret void recover: ; preds = %rundefers.end3 - call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3 + call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3 ret void lpad: ; preds = %rundefers.callback012, %rundefers.callback0, %entry br label %rundefers.loophead6 -rundefers.loophead6: ; preds = %6, %lpad - %5 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4 - %stackIsNil7 = icmp eq %runtime._defer* %5, null +rundefers.loophead6: ; preds = %5, %lpad + %4 = load ptr, ptr %deferPtr, align 4 + %stackIsNil7 = icmp eq ptr %4, null br i1 %stackIsNil7, label %rundefers.end3, label %rundefers.loop5 rundefers.loop5: ; preds = %rundefers.loophead6 - %stack.next.gep8 = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 1 - %stack.next9 = load %runtime._defer*, %runtime._defer** %stack.next.gep8, align 4 - store %runtime._defer* %stack.next9, %runtime._defer** %deferPtr, align 4 - %callback.gep10 = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 0 - %callback11 = load i32, i32* %callback.gep10, align 4 + %stack.next.gep8 = getelementptr inbounds %runtime._defer, ptr %4, i32 0, i32 1 + %stack.next9 = load ptr, ptr %stack.next.gep8, align 4 + store ptr %stack.next9, ptr %deferPtr, align 4 + %callback11 = load i32, ptr %4, align 4 switch i32 %callback11, label %rundefers.default4 [ i32 0, label %rundefers.callback012 ] rundefers.callback012: ; preds = %rundefers.loop5 - %setjmp14 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 - %setjmp.result15 = icmp eq i32 %setjmp14, 0 - br i1 %setjmp.result15, label %6, label %lpad + %setjmp13 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 + %setjmp.result14 = icmp eq i32 %setjmp13, 0 + br i1 %setjmp.result14, label %5, label %lpad -6: ; preds = %rundefers.callback012 - call void @"main.deferSimple$1"(i8* undef) +5: ; preds = %rundefers.callback012 + call void @"main.deferSimple$1"(ptr undef) br label %rundefers.loophead6 rundefers.default4: ; preds = %rundefers.loop5 @@ -109,158 +105,151 @@ rundefers.end3: ; preds = %rundefers.loophead6 br label %recover } -; Function Attrs: nofree nosync nounwind willreturn -declare i8* @llvm.stacksave() #2 +; Function Attrs: nocallback nofree nosync nounwind willreturn +declare ptr @llvm.stacksave() #2 -declare void @runtime.setupDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*, i8*) #0 +declare void @runtime.setupDeferFrame(ptr dereferenceable_or_null(24), ptr, ptr) #0 ; Function Attrs: nounwind -define internal void @"main.deferSimple$1"(i8* %context) unnamed_addr #1 { +define internal void @"main.deferSimple$1"(ptr %context) unnamed_addr #1 { entry: - call void @runtime.printint32(i32 3, i8* undef) #3 + call void @runtime.printint32(i32 3, ptr undef) #3 ret void } -declare void @runtime.destroyDeferFrame(%runtime.deferFrame* dereferenceable_or_null(24), i8*) #0 +declare void @runtime.destroyDeferFrame(ptr dereferenceable_or_null(24), ptr) #0 -declare void @runtime.printint32(i32, i8*) #0 +declare void @runtime.printint32(i32, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.deferMultiple(i8* %context) unnamed_addr #1 { +define hidden void @main.deferMultiple(ptr %context) unnamed_addr #1 { entry: - %defer.alloca2 = alloca { i32, %runtime._defer* }, align 4 - %defer.alloca = alloca { i32, %runtime._defer* }, align 4 - %deferPtr = alloca %runtime._defer*, align 4 - store %runtime._defer* null, %runtime._defer** %deferPtr, align 4 + %defer.alloca2 = alloca { i32, ptr }, align 4 + %defer.alloca = alloca { i32, ptr }, align 4 + %deferPtr = alloca ptr, align 4 + store ptr null, ptr %deferPtr, align 4 %deferframe.buf = alloca %runtime.deferFrame, align 4 - %0 = call i8* @llvm.stacksave() - call void @runtime.setupDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* %0, i8* undef) #3 - %defer.alloca.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 0 - store i32 0, i32* %defer.alloca.repack, align 4 - %defer.alloca.repack26 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca, i32 0, i32 1 - store %runtime._defer* null, %runtime._defer** %defer.alloca.repack26, align 4 - %1 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }** - store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %1, align 4 - %defer.alloca2.repack = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca2, i32 0, i32 0 - store i32 1, i32* %defer.alloca2.repack, align 4 - %defer.alloca2.repack27 = getelementptr inbounds { i32, %runtime._defer* }, { i32, %runtime._defer* }* %defer.alloca2, i32 0, i32 1 - %2 = bitcast %runtime._defer** %defer.alloca2.repack27 to { i32, %runtime._defer* }** - store { i32, %runtime._defer* }* %defer.alloca, { i32, %runtime._defer* }** %2, align 4 - %3 = bitcast %runtime._defer** %deferPtr to { i32, %runtime._defer* }** - store { i32, %runtime._defer* }* %defer.alloca2, { i32, %runtime._defer* }** %3, align 4 - %setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 + %0 = call ptr @llvm.stacksave() + call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #3 + store i32 0, ptr %defer.alloca, align 4 + %defer.alloca.repack22 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1 + store ptr null, ptr %defer.alloca.repack22, align 4 + store ptr %defer.alloca, ptr %deferPtr, align 4 + store i32 1, ptr %defer.alloca2, align 4 + %defer.alloca2.repack23 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca2, i32 0, i32 1 + store ptr %defer.alloca, ptr %defer.alloca2.repack23, align 4 + store ptr %defer.alloca2, ptr %deferPtr, align 4 + %setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 %setjmp.result = icmp eq i32 %setjmp, 0 - br i1 %setjmp.result, label %4, label %lpad + br i1 %setjmp.result, label %1, label %lpad -4: ; preds = %entry - call void @main.external(i8* undef) #3 +1: ; preds = %entry + call void @main.external(ptr undef) #3 br label %rundefers.loophead -rundefers.loophead: ; preds = %7, %6, %4 - %5 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4 - %stackIsNil = icmp eq %runtime._defer* %5, null +rundefers.loophead: ; preds = %4, %3, %1 + %2 = load ptr, ptr %deferPtr, align 4 + %stackIsNil = icmp eq ptr %2, null br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop rundefers.loop: ; preds = %rundefers.loophead - %stack.next.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 1 - %stack.next = load %runtime._defer*, %runtime._defer** %stack.next.gep, align 4 - store %runtime._defer* %stack.next, %runtime._defer** %deferPtr, align 4 - %callback.gep = getelementptr inbounds %runtime._defer, %runtime._defer* %5, i32 0, i32 0 - %callback = load i32, i32* %callback.gep, align 4 + %stack.next.gep = getelementptr inbounds %runtime._defer, ptr %2, i32 0, i32 1 + %stack.next = load ptr, ptr %stack.next.gep, align 4 + store ptr %stack.next, ptr %deferPtr, align 4 + %callback = load i32, ptr %2, align 4 switch i32 %callback, label %rundefers.default [ i32 0, label %rundefers.callback0 i32 1, label %rundefers.callback1 ] rundefers.callback0: ; preds = %rundefers.loop - %setjmp4 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 - %setjmp.result5 = icmp eq i32 %setjmp4, 0 - br i1 %setjmp.result5, label %6, label %lpad + %setjmp3 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 + %setjmp.result4 = icmp eq i32 %setjmp3, 0 + br i1 %setjmp.result4, label %3, label %lpad -6: ; preds = %rundefers.callback0 - call void @"main.deferMultiple$1"(i8* undef) +3: ; preds = %rundefers.callback0 + call void @"main.deferMultiple$1"(ptr undef) br label %rundefers.loophead rundefers.callback1: ; preds = %rundefers.loop - %setjmp7 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 - %setjmp.result8 = icmp eq i32 %setjmp7, 0 - br i1 %setjmp.result8, label %7, label %lpad + %setjmp5 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 + %setjmp.result6 = icmp eq i32 %setjmp5, 0 + br i1 %setjmp.result6, label %4, label %lpad -7: ; preds = %rundefers.callback1 - call void @"main.deferMultiple$2"(i8* undef) +4: ; preds = %rundefers.callback1 + call void @"main.deferMultiple$2"(ptr undef) br label %rundefers.loophead rundefers.default: ; preds = %rundefers.loop unreachable rundefers.end: ; preds = %rundefers.loophead - call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3 + call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3 ret void -recover: ; preds = %rundefers.end9 - call void @runtime.destroyDeferFrame(%runtime.deferFrame* nonnull %deferframe.buf, i8* undef) #3 +recover: ; preds = %rundefers.end7 + call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #3 ret void -lpad: ; preds = %rundefers.callback122, %rundefers.callback018, %rundefers.callback1, %rundefers.callback0, %entry - br label %rundefers.loophead12 - -rundefers.loophead12: ; preds = %10, %9, %lpad - %8 = load %runtime._defer*, %runtime._defer** %deferPtr, align 4 - %stackIsNil13 = icmp eq %runtime._defer* %8, null - br i1 %stackIsNil13, label %rundefers.end9, label %rundefers.loop11 - -rundefers.loop11: ; preds = %rundefers.loophead12 - %stack.next.gep14 = getelementptr inbounds %runtime._defer, %runtime._defer* %8, i32 0, i32 1 - %stack.next15 = load %runtime._defer*, %runtime._defer** %stack.next.gep14, align 4 - store %runtime._defer* %stack.next15, %runtime._defer** %deferPtr, align 4 - %callback.gep16 = getelementptr inbounds %runtime._defer, %runtime._defer* %8, i32 0, i32 0 - %callback17 = load i32, i32* %callback.gep16, align 4 - switch i32 %callback17, label %rundefers.default10 [ - i32 0, label %rundefers.callback018 - i32 1, label %rundefers.callback122 +lpad: ; preds = %rundefers.callback119, %rundefers.callback016, %rundefers.callback1, %rundefers.callback0, %entry + br label %rundefers.loophead10 + +rundefers.loophead10: ; preds = %7, %6, %lpad + %5 = load ptr, ptr %deferPtr, align 4 + %stackIsNil11 = icmp eq ptr %5, null + br i1 %stackIsNil11, label %rundefers.end7, label %rundefers.loop9 + +rundefers.loop9: ; preds = %rundefers.loophead10 + %stack.next.gep12 = getelementptr inbounds %runtime._defer, ptr %5, i32 0, i32 1 + %stack.next13 = load ptr, ptr %stack.next.gep12, align 4 + store ptr %stack.next13, ptr %deferPtr, align 4 + %callback15 = load i32, ptr %5, align 4 + switch i32 %callback15, label %rundefers.default8 [ + i32 0, label %rundefers.callback016 + i32 1, label %rundefers.callback119 ] -rundefers.callback018: ; preds = %rundefers.loop11 - %setjmp20 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 - %setjmp.result21 = icmp eq i32 %setjmp20, 0 - br i1 %setjmp.result21, label %9, label %lpad +rundefers.callback016: ; preds = %rundefers.loop9 + %setjmp17 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 + %setjmp.result18 = icmp eq i32 %setjmp17, 0 + br i1 %setjmp.result18, label %6, label %lpad -9: ; preds = %rundefers.callback018 - call void @"main.deferMultiple$1"(i8* undef) - br label %rundefers.loophead12 +6: ; preds = %rundefers.callback016 + call void @"main.deferMultiple$1"(ptr undef) + br label %rundefers.loophead10 -rundefers.callback122: ; preds = %rundefers.loop11 - %setjmp24 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(%runtime.deferFrame* nonnull %deferframe.buf) #4 - %setjmp.result25 = icmp eq i32 %setjmp24, 0 - br i1 %setjmp.result25, label %10, label %lpad +rundefers.callback119: ; preds = %rundefers.loop9 + %setjmp20 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #4 + %setjmp.result21 = icmp eq i32 %setjmp20, 0 + br i1 %setjmp.result21, label %7, label %lpad -10: ; preds = %rundefers.callback122 - call void @"main.deferMultiple$2"(i8* undef) - br label %rundefers.loophead12 +7: ; preds = %rundefers.callback119 + call void @"main.deferMultiple$2"(ptr undef) + br label %rundefers.loophead10 -rundefers.default10: ; preds = %rundefers.loop11 +rundefers.default8: ; preds = %rundefers.loop9 unreachable -rundefers.end9: ; preds = %rundefers.loophead12 +rundefers.end7: ; preds = %rundefers.loophead10 br label %recover } ; Function Attrs: nounwind -define internal void @"main.deferMultiple$1"(i8* %context) unnamed_addr #1 { +define internal void @"main.deferMultiple$1"(ptr %context) unnamed_addr #1 { entry: - call void @runtime.printint32(i32 3, i8* undef) #3 + call void @runtime.printint32(i32 3, ptr undef) #3 ret void } ; Function Attrs: nounwind -define internal void @"main.deferMultiple$2"(i8* %context) unnamed_addr #1 { +define internal void @"main.deferMultiple$2"(ptr %context) unnamed_addr #1 { entry: - call void @runtime.printint32(i32 5, i8* undef) #3 + call void @runtime.printint32(i32 5, ptr undef) #3 ret void } attributes #0 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } attributes #1 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } -attributes #2 = { nofree nosync nounwind willreturn } +attributes #2 = { nocallback nofree nosync nounwind willreturn } attributes #3 = { nounwind } attributes #4 = { nounwind returns_twice } diff --git a/compiler/testdata/float.ll b/compiler/testdata/float.ll index 0ecd21e97..2acc2ed42 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 2ed16eafb..227e52c11 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 26bc4c249..e54b207d4 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 } [email protected] = hidden global i8* null, align 4 [email protected] = hidden global i32* null, align 4 [email protected] = hidden global i64* null, align 4 [email protected] = hidden global float* null, align 4 [email protected] = hidden global [3 x i8]* null, align 4 [email protected] = hidden global [71 x i8]* null, align 4 [email protected] = hidden global [3 x i8*]* null, align 4 [email protected] = hidden global {}* null, align 4 [email protected] = hidden global { i32, i32 }* null, align 4 [email protected] = hidden global { i8*, [60 x i32], i8* }* null, align 4 [email protected] = hidden global { i8*, [61 x i32] }* null, align 4 [email protected] = hidden global { i8*, i32, i32 } zeroinitializer, align 8 [email protected] = hidden global { i32**, i32, i32 } zeroinitializer, align 8 [email protected] = hidden global { { i8*, i32, i32 }*, i32, i32 } zeroinitializer, align 8 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global ptr null, align 4 [email protected] = hidden global { ptr, i32, i32 } zeroinitializer, align 8 [email protected] = hidden global { ptr, i32, i32 } zeroinitializer, align 8 [email protected] = 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 edd4d666b..ac1adaffe 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 21da74774..280f216aa 100644 --- a/compiler/testdata/goroutine-wasm-asyncify.ll +++ b/compiler/testdata/goroutine-wasm-asyncify.ll @@ -3,210 +3,184 @@ source_filename = "goroutine.go" target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" target triple = "wasm32-unknown-wasi" -%runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* } -%runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } } -%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state", i8* } -%"internal/task.gcData" = type { i8* } -%"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 } -%"internal/task.stackState" = type { i32, i32 } -%runtime.chanSelectState = type { %runtime.channel*, i8* } +%runtime._string = type { ptr, i32 } @"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 +declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(i8* %context) unnamed_addr #1 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden void @main.regularFunctionGoroutine(i8* %context) unnamed_addr #1 { +define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #1 { entry: - call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.regularFunction$gowrapper" to i32), i8* nonnull inttoptr (i32 5 to i8*), i32 16384, i8* undef) #8 + call void @"internal/task.start"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 16384, ptr undef) #8 ret void } -declare void @main.regularFunction(i32, i8*) #0 +declare void @main.regularFunction(i32, ptr) #0 -declare void @runtime.deadlock(i8*) #0 +declare void @runtime.deadlock(ptr) #0 ; Function Attrs: nounwind -define linkonce_odr void @"main.regularFunction$gowrapper"(i8* %0) unnamed_addr #2 { +define linkonce_odr void @"main.regularFunction$gowrapper"(ptr %0) unnamed_addr #2 { entry: - %unpack.int = ptrtoint i8* %0 to i32 - call void @main.regularFunction(i32 %unpack.int, i8* undef) #8 - call void @runtime.deadlock(i8* undef) #8 + %unpack.int = ptrtoint ptr %0 to i32 + call void @main.regularFunction(i32 %unpack.int, ptr undef) #8 + call void @runtime.deadlock(ptr undef) #8 unreachable } -declare void @"internal/task.start"(i32, i8*, i32, i8*) #0 +declare void @"internal/task.start"(i32, ptr, i32, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.inlineFunctionGoroutine(i8* %context) unnamed_addr #1 { +define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #1 { entry: - call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.inlineFunctionGoroutine$1$gowrapper" to i32), i8* nonnull inttoptr (i32 5 to i8*), i32 16384, i8* undef) #8 + call void @"internal/task.start"(i32 ptrtoint (ptr @"main.inlineFunctionGoroutine$1$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 16384, ptr undef) #8 ret void } ; Function Attrs: nounwind -define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 { +define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(i8* %0) unnamed_addr #3 { +define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #3 { entry: - %unpack.int = ptrtoint i8* %0 to i32 - call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, i8* undef) - call void @runtime.deadlock(i8* undef) #8 + %unpack.int = ptrtoint ptr %0 to i32 + call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, ptr undef) + call void @runtime.deadlock(ptr undef) #8 unreachable } ; Function Attrs: nounwind -define hidden void @main.closureFunctionGoroutine(i8* %context) unnamed_addr #1 { -entry: - %n = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #8 - %0 = bitcast i8* %n to i32* - call void @runtime.trackPointer(i8* nonnull %n, i8* undef) #8 - store i32 3, i32* %0, align 4 - call void @runtime.trackPointer(i8* nonnull %n, i8* undef) #8 - call void @runtime.trackPointer(i8* bitcast (void (i32, i8*)* @"main.closureFunctionGoroutine$1" to i8*), i8* undef) #8 - %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef) #8 - call void @runtime.trackPointer(i8* nonnull %1, i8* undef) #8 - %2 = bitcast i8* %1 to i32* - store i32 5, i32* %2, align 4 - %3 = getelementptr inbounds i8, i8* %1, i32 4 - %4 = bitcast i8* %3 to i8** - store i8* %n, i8** %4, align 4 - call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"main.closureFunctionGoroutine$1$gowrapper" to i32), i8* nonnull %1, i32 16384, i8* undef) #8 - %5 = load i32, i32* %0, align 4 - call void @runtime.printint32(i32 %5, i8* undef) #8 +define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 { +entry: + %n = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull %n, ptr undef) #8 + store i32 3, ptr %n, align 4 + call void @runtime.trackPointer(ptr nonnull %n, ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull @"main.closureFunctionGoroutine$1", ptr undef) #8 + %0 = call ptr @runtime.alloc(i32 8, ptr null, ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8 + store i32 5, ptr %0, align 4 + %1 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1 + store ptr %n, ptr %1, align 4 + call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 16384, ptr undef) #8 + %2 = load i32, ptr %n, align 4 + call void @runtime.printint32(i32 %2, ptr undef) #8 ret void } ; Function Attrs: nounwind -define internal void @"main.closureFunctionGoroutine$1"(i32 %x, i8* %context) unnamed_addr #1 { +define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 { entry: - %unpack.ptr = bitcast i8* %context to i32* - store i32 7, i32* %unpack.ptr, align 4 + store i32 7, ptr %context, align 4 ret void } ; Function Attrs: nounwind -define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(i8* %0) unnamed_addr #4 { +define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #4 { entry: - %1 = bitcast i8* %0 to i32* - %2 = load i32, i32* %1, align 4 - %3 = getelementptr inbounds i8, i8* %0, i32 4 - %4 = bitcast i8* %3 to i8** - %5 = load i8*, i8** %4, align 4 - call void @"main.closureFunctionGoroutine$1"(i32 %2, i8* %5) - call void @runtime.deadlock(i8* undef) #8 + %1 = load i32, ptr %0, align 4 + %2 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1 + %3 = load ptr, ptr %2, align 4 + call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3) + call void @runtime.deadlock(ptr undef) #8 unreachable } -declare void @runtime.printint32(i32, i8*) #0 +declare void @runtime.printint32(i32, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.funcGoroutine(i8* %fn.context, void ()* %fn.funcptr, i8* %context) unnamed_addr #1 { +define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #1 { entry: - %0 = call i8* @runtime.alloc(i32 12, i8* null, i8* undef) #8 - call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #8 - %1 = bitcast i8* %0 to i32* - store i32 5, i32* %1, align 4 - %2 = getelementptr inbounds i8, i8* %0, i32 4 - %3 = bitcast i8* %2 to i8** - store i8* %fn.context, i8** %3, align 4 - %4 = getelementptr inbounds i8, i8* %0, i32 8 - %5 = bitcast i8* %4 to void ()** - store void ()* %fn.funcptr, void ()** %5, align 4 - call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @main.funcGoroutine.gowrapper to i32), i8* nonnull %0, i32 16384, i8* undef) #8 + %0 = call ptr @runtime.alloc(i32 12, ptr null, ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8 + store i32 5, ptr %0, align 4 + %1 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1 + store ptr %fn.context, ptr %1, align 4 + %2 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 2 + store ptr %fn.funcptr, ptr %2, align 4 + call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 16384, ptr undef) #8 ret void } ; Function Attrs: nounwind -define linkonce_odr void @main.funcGoroutine.gowrapper(i8* %0) unnamed_addr #5 { +define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #5 { entry: - %1 = bitcast i8* %0 to i32* - %2 = load i32, i32* %1, align 4 - %3 = getelementptr inbounds i8, i8* %0, i32 4 - %4 = bitcast i8* %3 to i8** - %5 = load i8*, i8** %4, align 4 - %6 = getelementptr inbounds i8, i8* %0, i32 8 - %7 = bitcast i8* %6 to void (i32, i8*)** - %8 = load void (i32, i8*)*, void (i32, i8*)** %7, align 4 - call void %8(i32 %2, i8* %5) #8 - call void @runtime.deadlock(i8* undef) #8 + %1 = load i32, ptr %0, align 4 + %2 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1 + %3 = load ptr, ptr %2, align 4 + %4 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 2 + %5 = load ptr, ptr %4, align 4 + call void %5(i32 %1, ptr %3) #8 + call void @runtime.deadlock(ptr undef) #8 unreachable } ; Function Attrs: nounwind -define hidden void @main.recoverBuiltinGoroutine(i8* %context) unnamed_addr #1 { +define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden void @main.copyBuiltinGoroutine(i8* %dst.data, i32 %dst.len, i32 %dst.cap, i8* %src.data, i32 %src.len, i32 %src.cap, i8* %context) unnamed_addr #1 { +define hidden void @main.copyBuiltinGoroutine(ptr %dst.data, i32 %dst.len, i32 %dst.cap, ptr %src.data, i32 %src.len, i32 %src.cap, ptr %context) unnamed_addr #1 { entry: - %copy.n = call i32 @runtime.sliceCopy(i8* %dst.data, i8* %src.data, i32 %dst.len, i32 %src.len, i32 1, i8* undef) #8 + %copy.n = call i32 @runtime.sliceCopy(ptr %dst.data, ptr %src.data, i32 %dst.len, i32 %src.len, i32 1, ptr undef) #8 ret void } -declare i32 @runtime.sliceCopy(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i32, i8*) #0 +declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly, i32, i32, i32, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.closeBuiltinGoroutine(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context) unnamed_addr #1 { +define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(32) %ch, ptr %context) unnamed_addr #1 { entry: - call void @runtime.chanClose(%runtime.channel* %ch, i8* undef) #8 + call void @runtime.chanClose(ptr %ch, ptr undef) #8 ret void } -declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i8*) #0 +declare void @runtime.chanClose(ptr dereferenceable_or_null(32), ptr) #0 ; Function Attrs: nounwind -define hidden void @main.startInterfaceMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { +define hidden void @main.startInterfaceMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: - %0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef) #8 - call void @runtime.trackPointer(i8* nonnull %0, i8* undef) #8 - %1 = bitcast i8* %0 to i8** - store i8* %itf.value, i8** %1, align 4 - %2 = getelementptr inbounds i8, i8* %0, i32 4 - %.repack = bitcast i8* %2 to i8** - store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"main$string", i32 0, i32 0), i8** %.repack, align 4 - %.repack1 = getelementptr inbounds i8, i8* %0, i32 8 - %3 = bitcast i8* %.repack1 to i32* - store i32 4, i32* %3, align 4 - %4 = getelementptr inbounds i8, i8* %0, i32 12 - %5 = bitcast i8* %4 to i32* - store i32 %itf.typecode, i32* %5, align 4 - call void @"internal/task.start"(i32 ptrtoint (void (i8*)* @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), i8* nonnull %0, i32 16384, i8* undef) #8 + %0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #8 + call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8 + store ptr %itf.value, ptr %0, align 4 + %1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1 + store ptr @"main$string", ptr %1, align 4 + %.repack1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1, i32 1 + store i32 4, ptr %.repack1, align 4 + %2 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 2 + store i32 %itf.typecode, ptr %2, align 4 + call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 16384, ptr undef) #8 ret void } -declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(i8*, i8*, i32, i32, i8*) #6 +declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr, ptr, i32, i32, ptr) #6 ; Function Attrs: nounwind -define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(i8* %0) unnamed_addr #7 { +define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #7 { entry: - %1 = bitcast i8* %0 to i8** - %2 = load i8*, i8** %1, align 4 - %3 = getelementptr inbounds i8, i8* %0, i32 4 - %4 = bitcast i8* %3 to i8** - %5 = load i8*, i8** %4, align 4 - %6 = getelementptr inbounds i8, i8* %0, i32 8 - %7 = bitcast i8* %6 to i32* - %8 = load i32, i32* %7, align 4 - %9 = getelementptr inbounds i8, i8* %0, i32 12 - %10 = bitcast i8* %9 to i32* - %11 = load i32, i32* %10, align 4 - call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(i8* %2, i8* %5, i32 %8, i32 %11, i8* undef) #8 - call void @runtime.deadlock(i8* undef) #8 + %1 = load ptr, ptr %0, align 4 + %2 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 1 + %3 = load ptr, ptr %2, align 4 + %4 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 2 + %5 = load i32, ptr %4, align 4 + %6 = getelementptr inbounds { ptr, ptr, i32, i32 }, ptr %0, i32 0, i32 3 + %7 = load i32, ptr %6, align 4 + call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, i32 %7, ptr undef) #8 + call void @runtime.deadlock(ptr undef) #8 unreachable } diff --git a/compiler/testdata/interface.ll b/compiler/testdata/interface.ll index 0b44585a4..38d4e567a 100644 --- a/compiler/testdata/interface.ll +++ b/compiler/testdata/interface.ll @@ -3,71 +3,70 @@ source_filename = "interface.go" target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" target triple = "wasm32-unknown-wasi" -%runtime.typecodeID = type { %runtime.typecodeID*, i32, %runtime.interfaceMethodInfo*, %runtime.typecodeID*, i32 } -%runtime.interfaceMethodInfo = type { i8*, i32 } -%runtime._interface = type { i32, i8* } -%runtime._string = type { i8*, i32 } - -@"reflect/types.type:basic:int" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* null, i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:basic:int", i32 0 } -@"reflect/types.type:pointer:basic:int" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:basic:int", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 } -@"reflect/types.type:pointer:named:error" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:named:error", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 } -@"reflect/types.type:named:error" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:named:error", i32 ptrtoint (i1 (i32)* @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) } -@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* bitcast ([1 x i8*]* @"reflect/types.interface:interface{Error() string}$interface" to %runtime.typecodeID*), i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}", i32 ptrtoint (i1 (i32)* @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) } +%runtime.typecodeID = type { ptr, i32, ptr, ptr, i32 } +%runtime._interface = type { i32, ptr } +%runtime._string = type { ptr, i32 } + +@"reflect/types.type:basic:int" = linkonce_odr constant %runtime.typecodeID { ptr null, i32 0, ptr null, ptr @"reflect/types.type:pointer:basic:int", i32 0 } +@"reflect/types.type:pointer:basic:int" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:basic:int", i32 0, ptr null, ptr null, i32 0 } +@"reflect/types.type:pointer:named:error" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:named:error", i32 0, ptr null, ptr null, i32 0 } +@"reflect/types.type:named:error" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, ptr null, ptr @"reflect/types.type:pointer:named:error", i32 ptrtoint (ptr @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) } +@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.interface:interface{Error() string}$interface", i32 0, ptr null, ptr @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}", i32 ptrtoint (ptr @"interface:{Error:func:{}{basic:string}}.$typeassert" to i32) } @"reflect/methods.Error() string" = linkonce_odr constant i8 0, align 1 -@"reflect/types.interface:interface{Error() string}$interface" = linkonce_odr constant [1 x i8*] [i8* @"reflect/methods.Error() string"] -@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 } -@"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:interface:{String:func:{}{basic:string}}", i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* null, i32 0 } -@"reflect/types.type:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { %runtime.typecodeID* bitcast ([1 x i8*]* @"reflect/types.interface:interface{String() string}$interface" to %runtime.typecodeID*), i32 0, %runtime.interfaceMethodInfo* null, %runtime.typecodeID* @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", i32 ptrtoint (i1 (i32)* @"interface:{String:func:{}{basic:string}}.$typeassert" to i32) } +@"reflect/types.interface:interface{Error() string}$interface" = linkonce_odr constant [1 x ptr] [ptr @"reflect/methods.Error() string"] +@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, ptr null, ptr null, i32 0 } +@"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.type:interface:{String:func:{}{basic:string}}", i32 0, ptr null, ptr null, i32 0 } +@"reflect/types.type:interface:{String:func:{}{basic:string}}" = linkonce_odr constant %runtime.typecodeID { ptr @"reflect/types.interface:interface{String() string}$interface", i32 0, ptr null, ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", i32 ptrtoint (ptr @"interface:{String:func:{}{basic:string}}.$typeassert" to i32) } @"reflect/methods.String() string" = linkonce_odr constant i8 0, align 1 -@"reflect/types.interface:interface{String() string}$interface" = linkonce_odr constant [1 x i8*] [i8* @"reflect/methods.String() string"] +@"reflect/types.interface:interface{String() string}$interface" = linkonce_odr constant [1 x ptr] [ptr @"reflect/methods.String() string"] @"reflect/types.typeid:basic:int" = external constant i8 -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0 +declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 -declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(i8* %context) unnamed_addr #1 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden %runtime._interface @main.simpleType(i8* %context) unnamed_addr #1 { +define hidden %runtime._interface @main.simpleType(ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(i8* null, i8* undef) #6 - ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:basic:int" to i32), i8* null } + call void @runtime.trackPointer(ptr null, ptr undef) #6 + ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:int" to i32), ptr null } } ; Function Attrs: nounwind -define hidden %runtime._interface @main.pointerType(i8* %context) unnamed_addr #1 { +define hidden %runtime._interface @main.pointerType(ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(i8* null, i8* undef) #6 - ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:basic:int" to i32), i8* null } + call void @runtime.trackPointer(ptr null, ptr undef) #6 + ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:basic:int" to i32), ptr null } } ; Function Attrs: nounwind -define hidden %runtime._interface @main.interfaceType(i8* %context) unnamed_addr #1 { +define hidden %runtime._interface @main.interfaceType(ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(i8* null, i8* undef) #6 - ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:named:error" to i32), i8* null } + call void @runtime.trackPointer(ptr null, ptr undef) #6 + ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:named:error" to i32), ptr null } } declare i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(i32) #2 ; Function Attrs: nounwind -define hidden %runtime._interface @main.anonymousInterfaceType(i8* %context) unnamed_addr #1 { +define hidden %runtime._interface @main.anonymousInterfaceType(ptr %context) unnamed_addr #1 { entry: - call void @runtime.trackPointer(i8* null, i8* undef) #6 - ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), i8* null } + call void @runtime.trackPointer(ptr null, ptr undef) #6 + ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), ptr null } } declare i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(i32) #3 ; Function Attrs: nounwind -define hidden i1 @main.isInt(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { +define hidden i1 @main.isInt(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: - %typecode = call i1 @runtime.typeAssert(i32 %itf.typecode, i8* nonnull @"reflect/types.typeid:basic:int", i8* undef) #6 + %typecode = call i1 @runtime.typeAssert(i32 %itf.typecode, ptr nonnull @"reflect/types.typeid:basic:int", ptr undef) #6 br i1 %typecode, label %typeassert.ok, label %typeassert.next typeassert.next: ; preds = %typeassert.ok, %entry @@ -77,10 +76,10 @@ typeassert.ok: ; preds = %entry br label %typeassert.next } -declare i1 @runtime.typeAssert(i32, i8* dereferenceable_or_null(1), i8*) #0 +declare i1 @runtime.typeAssert(i32, ptr dereferenceable_or_null(1), ptr) #0 ; Function Attrs: nounwind -define hidden i1 @main.isError(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { +define hidden i1 @main.isError(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: %0 = call i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(i32 %itf.typecode) #6 br i1 %0, label %typeassert.ok, label %typeassert.next @@ -93,7 +92,7 @@ typeassert.ok: ; preds = %entry } ; Function Attrs: nounwind -define hidden i1 @main.isStringer(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { +define hidden i1 @main.isStringer(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: %0 = call i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(i32 %itf.typecode) #6 br i1 %0, label %typeassert.ok, label %typeassert.next @@ -106,24 +105,24 @@ typeassert.ok: ; preds = %entry } ; Function Attrs: nounwind -define hidden i8 @main.callFooMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { +define hidden i8 @main.callFooMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: - %0 = call i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(i8* %itf.value, i32 3, i32 %itf.typecode, i8* undef) #6 + %0 = call i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr %itf.value, i32 3, i32 %itf.typecode, ptr undef) #6 ret i8 %0 } -declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(i8*, i32, i32, i8*) #4 +declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr, i32, i32, ptr) #4 ; Function Attrs: nounwind -define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, i8* %itf.value, i8* %context) unnamed_addr #1 { +define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: - %0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(i8* %itf.value, i32 %itf.typecode, i8* undef) #6 + %0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr %itf.value, i32 %itf.typecode, ptr undef) #6 %1 = extractvalue %runtime._string %0, 0 - call void @runtime.trackPointer(i8* %1, i8* undef) #6 + call void @runtime.trackPointer(ptr %1, ptr undef) #6 ret %runtime._string %0 } -declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(i8*, i32, i8*) #5 +declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr, i32, ptr) #5 attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } diff --git a/compiler/testdata/pointer.ll b/compiler/testdata/pointer.ll index cedea3807..9bc8bd357 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 b243602d3..c49c83bd7 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 c2e3ebd91..56e40f5f7 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 5e1f924c4..bd3b8f5aa 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 } @@ -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 ( @@ -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 83fd2cd9a..c61ce7cf3 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 cde8e2d9c..4e24b923f 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 136915d5f..81dcc3f35 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 e33308f2e..2c9e6b5c8 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 41c39f446..cc0d2ed40 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 84050ff6c..d55a685ce 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 9e2ffa90a..55d1af39b 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 b15ff8a99..043eebb84 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 7042b32d0..045bb050f 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 68beba9b8..b994df61c 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 d70bc6263..209e15ae1 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, "") |