From e653ef542d044b2993734d9e19b47f9b5b21974a Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 20 May 2026 11:07:35 +0200 Subject: [PATCH 1/2] compiler: clean up pointer pack code This means runtime.alloc isn't allocated every time but instead only when it is actually needed. It also just cleans up the compiler code a little bit, and makes the next commit a bit nicer. --- compiler/compiler.go | 3 - compiler/llvm.go | 4 +- compiler/testdata/basic.ll | 62 +++++++------- compiler/testdata/channel.ll | 46 +++++------ compiler/testdata/defer-cortex-m-qemu.ll | 46 +++++------ compiler/testdata/float.ll | 28 +++---- compiler/testdata/func.ll | 26 +++--- compiler/testdata/gc.ll | 28 +++---- compiler/testdata/generics.ll | 26 +++--- compiler/testdata/go1.20.ll | 30 +++---- compiler/testdata/go1.21.ll | 82 +++++++++---------- .../testdata/goroutine-cortex-m-qemu-tasks.ll | 56 ++++++------- compiler/testdata/goroutine-wasm-asyncify.ll | 58 ++++++------- compiler/testdata/interface.ll | 78 +++++++++--------- compiler/testdata/pointer.ll | 28 +++---- compiler/testdata/pragma.ll | 56 ++++++------- compiler/testdata/slice.ll | 62 +++++++------- compiler/testdata/string.ll | 46 +++++------ compiler/testdata/zeromap.ll | 44 +++++----- 19 files changed, 380 insertions(+), 429 deletions(-) diff --git a/compiler/compiler.go b/compiler/compiler.go index 45e6c8a54b..a4dd94859e 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -314,9 +314,6 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package, // Load comments such as //go:extern on globals. c.loadASTComments(pkg) - // Predeclare the runtime.alloc function, which is used by the wordpack - // functionality. - c.getFunction(c.program.ImportedPackage("runtime").Members["alloc"].(*ssa.Function)) if c.NeedsStackObjects { // Predeclare trackPointer, which is used everywhere we use runtime.alloc. c.getFunction(c.program.ImportedPackage("runtime").Members["trackPointer"].(*ssa.Function)) diff --git a/compiler/llvm.go b/compiler/llvm.go index 7ce6c7d615..5ef656ce5e 100644 --- a/compiler/llvm.go +++ b/compiler/llvm.go @@ -129,11 +129,9 @@ func (b *builder) emitPointerPack(values []llvm.Value) llvm.Value { // Packed data is bigger than a pointer, so allocate it on the heap. sizeValue := llvm.ConstInt(b.uintptrType, size, false) align := b.targetData.ABITypeAlignment(packedType) - alloc := b.mod.NamedFunction("runtime.alloc") - packedAlloc := b.CreateCall(alloc.GlobalValueType(), alloc, []llvm.Value{ + packedAlloc := b.createRuntimeCall("alloc", []llvm.Value{ sizeValue, llvm.ConstNull(b.dataPtrType), - llvm.Undef(b.dataPtrType), // unused context parameter }, "") packedAlloc.AddCallSiteAttribute(0, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("align"), uint64(align))) if b.NeedsStackObjects { diff --git a/compiler/testdata/basic.ll b/compiler/testdata/basic.ll index 24558e9dee..f593d6b06d 100644 --- a/compiler/testdata/basic.ll +++ b/compiler/testdata/basic.ll @@ -10,33 +10,30 @@ target triple = "wasm32-unknown-wasi" @main.a = hidden global { ptr, i32, i32 } zeroinitializer, align 4 @main.b = hidden global [2 x ptr] zeroinitializer, align 4 -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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 @@ -50,14 +47,14 @@ divbyzero.next: ; preds = %entry ret i32 %5 divbyzero.throw: ; preds = %entry - call void @runtime.divideByZeroPanic(ptr undef) #3 + call void @runtime.divideByZeroPanic(ptr undef) #2 unreachable } -declare void @runtime.divideByZeroPanic(ptr) #1 +declare void @runtime.divideByZeroPanic(ptr) #0 ; Function Attrs: nounwind -define hidden i32 @main.divUint(i32 %x, i32 %y, ptr %context) unnamed_addr #2 { +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 @@ -67,12 +64,12 @@ divbyzero.next: ; preds = %entry ret i32 %1 divbyzero.throw: ; preds = %entry - call void @runtime.divideByZeroPanic(ptr undef) #3 + call void @runtime.divideByZeroPanic(ptr undef) #2 unreachable } ; Function Attrs: nounwind -define hidden i32 @main.remInt(i32 %x, i32 %y, ptr %context) unnamed_addr #2 { +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 @@ -86,12 +83,12 @@ divbyzero.next: ; preds = %entry ret i32 %5 divbyzero.throw: ; preds = %entry - call void @runtime.divideByZeroPanic(ptr undef) #3 + call void @runtime.divideByZeroPanic(ptr undef) #2 unreachable } ; Function Attrs: nounwind -define hidden i32 @main.remUint(i32 %x, i32 %y, ptr %context) unnamed_addr #2 { +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 @@ -101,66 +98,66 @@ divbyzero.next: ; preds = %entry ret i32 %1 divbyzero.throw: ; preds = %entry - call void @runtime.divideByZeroPanic(ptr undef) #3 + call void @runtime.divideByZeroPanic(ptr undef) #2 unreachable } ; Function Attrs: nounwind -define hidden i1 @main.floatEQ(float %x, float %y, ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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 @@ -170,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, ptr %context) unnamed_addr #2 { +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 @@ -180,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, ptr %context) unnamed_addr #2 { +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 @@ -194,19 +191,18 @@ entry: } ; Function Attrs: nounwind -define hidden void @main.foo(ptr %context) unnamed_addr #2 { +define hidden void @main.foo(ptr %context) unnamed_addr #1 { entry: 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 %b, ptr %context) unnamed_addr #2 { +define internal void @"main.foo$1"(%main.kv.0 %b, ptr %context) unnamed_addr #1 { entry: ret void } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { nounwind } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { nounwind } diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll index 6f39f1d09b..bd91a57736 100644 --- a/compiler/testdata/channel.ll +++ b/compiler/testdata/channel.ll @@ -6,76 +6,73 @@ target triple = "wasm32-unknown-wasi" %runtime.channelOp = type { ptr, ptr, i32, ptr } %runtime.chanSelectState = type { ptr, ptr } -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden void @main.chanIntSend(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #2 { +define hidden void @main.chanIntSend(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 { entry: %chan.op = alloca %runtime.channelOp, align 8 %chan.value = alloca i32, align 4 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 16, ptr nonnull %chan.op) - call void @runtime.chanSend(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.op, ptr undef) #4 + call void @runtime.chanSend(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.op, ptr undef) #3 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op) call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %chan.value) ret void } ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #3 +declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #2 -declare void @runtime.chanSend(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #1 +declare void @runtime.chanSend(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #0 ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #3 +declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #2 ; Function Attrs: nounwind -define hidden void @main.chanIntRecv(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #2 { +define hidden void @main.chanIntRecv(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 { entry: %chan.op = alloca %runtime.channelOp, align 8 %chan.value = alloca i32, align 4 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %chan.value) call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op) - %0 = call i1 @runtime.chanRecv(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.op, ptr undef) #4 + %0 = call i1 @runtime.chanRecv(ptr %ch, ptr nonnull %chan.value, ptr nonnull %chan.op, ptr undef) #3 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %chan.value) call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op) ret void } -declare i1 @runtime.chanRecv(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #1 +declare i1 @runtime.chanRecv(ptr dereferenceable_or_null(36), ptr, ptr dereferenceable_or_null(16), ptr) #0 ; Function Attrs: nounwind -define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #2 { +define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 { entry: %chan.op = alloca %runtime.channelOp, align 8 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op) - call void @runtime.chanSend(ptr %ch, ptr null, ptr nonnull %chan.op, ptr undef) #4 + call void @runtime.chanSend(ptr %ch, ptr null, ptr nonnull %chan.op, ptr undef) #3 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op) ret void } ; Function Attrs: nounwind -define hidden void @main.chanZeroRecv(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #2 { +define hidden void @main.chanZeroRecv(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 { entry: %chan.op = alloca %runtime.channelOp, align 8 call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %chan.op) - %0 = call i1 @runtime.chanRecv(ptr %ch, ptr null, ptr nonnull %chan.op, ptr undef) #4 + %0 = call i1 @runtime.chanRecv(ptr %ch, ptr null, ptr nonnull %chan.op, ptr undef) #3 call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %chan.op) ret void } ; Function Attrs: nounwind -define hidden void @main.selectZeroRecv(ptr dereferenceable_or_null(36) %ch1, ptr dereferenceable_or_null(36) %ch2, ptr %context) unnamed_addr #2 { +define hidden void @main.selectZeroRecv(ptr dereferenceable_or_null(36) %ch1, ptr dereferenceable_or_null(36) %ch2, ptr %context) unnamed_addr #1 { entry: %select.states.alloca = alloca [2 x %runtime.chanSelectState], align 8 %select.send.value = alloca i32, align 4 @@ -88,7 +85,7 @@ entry: store ptr %ch2, ptr %0, align 4 %.repack3 = getelementptr inbounds nuw i8, ptr %select.states.alloca, i32 12 store ptr null, ptr %.repack3, align 4 - %select.result = call { i32, i1 } @runtime.chanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr null, i32 0, i32 0, ptr undef) #4 + %select.result = call { i32, i1 } @runtime.chanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr null, i32 0, i32 0, 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 @@ -105,10 +102,9 @@ select.body: ; preds = %select.next br label %select.done } -declare { i32, i1 } @runtime.chanSelect(ptr, ptr, i32, i32, ptr, i32, i32, ptr) #1 +declare { i32, i1 } @runtime.chanSelect(ptr, ptr, i32, i32, ptr, i32, i32, ptr) #0 -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } -attributes #4 = { nounwind } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +attributes #3 = { nounwind } diff --git a/compiler/testdata/defer-cortex-m-qemu.ll b/compiler/testdata/defer-cortex-m-qemu.ll index 53acb20b90..ec40049dd6 100644 --- a/compiler/testdata/defer-cortex-m-qemu.ll +++ b/compiler/testdata/defer-cortex-m-qemu.ll @@ -6,19 +6,16 @@ target triple = "thumbv7m-unknown-unknown-eabi" %runtime.deferFrame = type { ptr, ptr, [0 x ptr], ptr, i8, %runtime._interface } %runtime._interface = type { ptr, ptr } -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #1 { +define hidden void @main.init(ptr %context) unnamed_addr #0 { entry: ret void } -declare void @main.external(ptr) #2 +declare void @main.external(ptr) #1 ; Function Attrs: nounwind -define hidden void @main.deferSimple(ptr %context) unnamed_addr #1 { +define hidden void @main.deferSimple(ptr %context) unnamed_addr #0 { entry: %defer.alloca = alloca { i32, ptr }, align 4 %deferPtr = alloca ptr, align 4 @@ -112,14 +109,14 @@ rundefers.end3: ; preds = %rundefers.loophead6 } ; Function Attrs: nocallback nofree nosync nounwind willreturn -declare ptr @llvm.stacksave.p0() #3 +declare ptr @llvm.stacksave.p0() #2 -declare void @runtime.setupDeferFrame(ptr dereferenceable_or_null(24), ptr, ptr) #2 +declare void @runtime.setupDeferFrame(ptr dereferenceable_or_null(24), ptr, ptr) #1 -declare void @runtime.destroyDeferFrame(ptr dereferenceable_or_null(24), ptr) #2 +declare void @runtime.destroyDeferFrame(ptr dereferenceable_or_null(24), ptr) #1 ; Function Attrs: nounwind -define internal void @"main.deferSimple$1"(ptr %context) unnamed_addr #1 { +define internal void @"main.deferSimple$1"(ptr %context) unnamed_addr #0 { entry: call void @runtime.printlock(ptr undef) #4 call void @runtime.printint32(i32 3, ptr undef) #4 @@ -127,14 +124,14 @@ entry: ret void } -declare void @runtime.printlock(ptr) #2 +declare void @runtime.printlock(ptr) #1 -declare void @runtime.printint32(i32, ptr) #2 +declare void @runtime.printint32(i32, ptr) #1 -declare void @runtime.printunlock(ptr) #2 +declare void @runtime.printunlock(ptr) #1 ; Function Attrs: nounwind -define hidden void @main.deferMultiple(ptr %context) unnamed_addr #1 { +define hidden void @main.deferMultiple(ptr %context) unnamed_addr #0 { entry: %defer.alloca2 = alloca { i32, ptr }, align 4 %defer.alloca = alloca { i32, ptr }, align 4 @@ -253,7 +250,7 @@ rundefers.end7: ; preds = %rundefers.loophead1 } ; Function Attrs: nounwind -define internal void @"main.deferMultiple$1"(ptr %context) unnamed_addr #1 { +define internal void @"main.deferMultiple$1"(ptr %context) unnamed_addr #0 { entry: call void @runtime.printlock(ptr undef) #4 call void @runtime.printint32(i32 3, ptr undef) #4 @@ -262,7 +259,7 @@ entry: } ; Function Attrs: nounwind -define internal void @"main.deferMultiple$2"(ptr %context) unnamed_addr #1 { +define internal void @"main.deferMultiple$2"(ptr %context) unnamed_addr #0 { entry: call void @runtime.printlock(ptr undef) #4 call void @runtime.printint32(i32 5, ptr undef) #4 @@ -271,7 +268,7 @@ entry: } ; Function Attrs: nounwind -define hidden void @main.deferInfiniteLoop(ptr %context) unnamed_addr #1 { +define hidden void @main.deferInfiniteLoop(ptr %context) unnamed_addr #0 { entry: %deferPtr = alloca ptr, align 4 store ptr null, ptr %deferPtr, align 4 @@ -315,8 +312,11 @@ rundefers.end: ; preds = %rundefers.loophead br label %recover } +; Function Attrs: allockind("alloc,zeroed") allocsize(0) +declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #3 + ; Function Attrs: nounwind -define hidden void @main.deferLoop(ptr %context) unnamed_addr #1 { +define hidden void @main.deferLoop(ptr %context) unnamed_addr #0 { entry: %deferPtr = alloca ptr, align 4 store ptr null, ptr %deferPtr, align 4 @@ -405,7 +405,7 @@ rundefers.end1: ; preds = %rundefers.loophead4 } ; Function Attrs: nounwind -define hidden void @main.deferBetweenLoops(ptr %context) unnamed_addr #1 { +define hidden void @main.deferBetweenLoops(ptr %context) unnamed_addr #0 { entry: %defer.alloca = alloca { i32, ptr, i32 }, align 4 %deferPtr = alloca ptr, align 4 @@ -505,9 +505,9 @@ rundefers.end4: ; preds = %rundefers.loophead7 br label %recover } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+armv7-m,+hwdiv,+soft-float,+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,+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 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+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 #3 = { nocallback nofree nosync nounwind willreturn } +attributes #0 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+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 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+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 = { nocallback nofree nosync nounwind willreturn } +attributes #3 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+armv7-m,+hwdiv,+soft-float,+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 #4 = { nounwind } attributes #5 = { nounwind returns_twice } diff --git a/compiler/testdata/float.ll b/compiler/testdata/float.ll index 304a045e06..6a531be520 100644 --- a/compiler/testdata/float.ll +++ b/compiler/testdata/float.ll @@ -3,19 +3,16 @@ source_filename = "float.go" target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20" target triple = "wasm32-unknown-wasi" -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden i32 @main.f32tou32(float %v, ptr %context) unnamed_addr #2 { +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 @@ -27,25 +24,25 @@ entry: } ; Function Attrs: nounwind -define hidden float @main.maxu32f(ptr %context) unnamed_addr #2 { +define hidden float @main.maxu32f(ptr %context) unnamed_addr #1 { entry: ret float 0x41F0000000000000 } ; Function Attrs: nounwind -define hidden i32 @main.maxu32tof32(ptr %context) unnamed_addr #2 { +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(ptr %context) unnamed_addr #2 { +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, ptr %context) unnamed_addr #2 { +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 @@ -55,7 +52,7 @@ entry: } ; Function Attrs: nounwind -define hidden float @main.f32tou32tof32(float %v, ptr %context) unnamed_addr #2 { +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 @@ -68,7 +65,7 @@ entry: } ; Function Attrs: nounwind -define hidden i8 @main.f32tou8(float %v, ptr %context) unnamed_addr #2 { +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 @@ -80,7 +77,7 @@ entry: } ; Function Attrs: nounwind -define hidden i8 @main.f32toi8(float %v, ptr %context) unnamed_addr #2 { +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 @@ -93,6 +90,5 @@ entry: ret i8 %0 } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } diff --git a/compiler/testdata/func.ll b/compiler/testdata/func.ll index 0912ef04ea..fd708789ed 100644 --- a/compiler/testdata/func.ll +++ b/compiler/testdata/func.ll @@ -3,48 +3,44 @@ source_filename = "func.go" target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20" target triple = "wasm32-unknown-wasi" -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden void @main.foo(ptr %callback.context, ptr %callback.funcptr, ptr %context) unnamed_addr #2 { +define hidden void @main.foo(ptr %callback.context, ptr %callback.funcptr, ptr %context) unnamed_addr #1 { entry: %0 = icmp eq ptr %callback.funcptr, null br i1 %0, label %fpcall.throw, label %fpcall.next fpcall.next: ; preds = %entry - call void %callback.funcptr(i32 3, ptr %callback.context) #3 + call void %callback.funcptr(i32 3, ptr %callback.context) #2 ret void fpcall.throw: ; preds = %entry - call void @runtime.nilPanic(ptr undef) #3 + call void @runtime.nilPanic(ptr undef) #2 unreachable } -declare void @runtime.nilPanic(ptr) #1 +declare void @runtime.nilPanic(ptr) #0 ; Function Attrs: nounwind -define hidden void @main.bar(ptr %context) unnamed_addr #2 { +define hidden void @main.bar(ptr %context) unnamed_addr #1 { entry: call void @main.foo(ptr undef, ptr nonnull @main.someFunc, ptr undef) ret void } ; Function Attrs: nounwind -define hidden void @main.someFunc(i32 %arg0, ptr %context) unnamed_addr #2 { +define hidden void @main.someFunc(i32 %arg0, ptr %context) unnamed_addr #1 { entry: ret void } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { nounwind } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { nounwind } diff --git a/compiler/testdata/gc.ll b/compiler/testdata/gc.ll index 42a278b66e..14f9aa8b25 100644 --- a/compiler/testdata/gc.ll +++ b/compiler/testdata/gc.ll @@ -25,19 +25,16 @@ target triple = "wasm32-unknown-wasi" @"reflect/types.type:basic:complex128" = linkonce_odr constant { i8, ptr } { i8 80, ptr @"reflect/types.type:pointer:basic:complex128" }, align 4 @"reflect/types.type:pointer:basic:complex128" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:basic:complex128" }, align 4 -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden void @main.newScalar(ptr %context) unnamed_addr #2 { +define hidden void @main.newScalar(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %new = call align 1 dereferenceable(1) ptr @runtime.alloc(i32 1, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3 @@ -55,8 +52,11 @@ entry: ret void } +; Function Attrs: allockind("alloc,zeroed") allocsize(0) +declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #2 + ; Function Attrs: nounwind -define hidden void @main.newArray(ptr %context) unnamed_addr #2 { +define hidden void @main.newArray(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %new = call align 1 dereferenceable(3) ptr @runtime.alloc(i32 3, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3 @@ -72,7 +72,7 @@ entry: } ; Function Attrs: nounwind -define hidden void @main.newStruct(ptr %context) unnamed_addr #2 { +define hidden void @main.newStruct(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %new = call align 1 ptr @runtime.alloc(i32 0, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3 @@ -94,7 +94,7 @@ entry: } ; Function Attrs: nounwind -define hidden ptr @main.newFuncValue(ptr %context) unnamed_addr #2 { +define hidden ptr @main.newFuncValue(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %new = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 197 to ptr), ptr undef) #3 @@ -103,7 +103,7 @@ entry: } ; Function Attrs: nounwind -define hidden void @main.makeSlice(ptr %context) unnamed_addr #2 { +define hidden void @main.makeSlice(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %makeslice = call align 1 dereferenceable(5) ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3 @@ -125,7 +125,7 @@ entry: } ; Function Attrs: nounwind -define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, ptr %context) unnamed_addr #2 { +define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %0 = call align 8 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #3 @@ -139,7 +139,7 @@ entry: ret %runtime._interface %1 } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } attributes #3 = { nounwind } diff --git a/compiler/testdata/generics.ll b/compiler/testdata/generics.ll index 6dc5d30ad2..de682b76cb 100644 --- a/compiler/testdata/generics.ll +++ b/compiler/testdata/generics.ll @@ -6,19 +6,16 @@ target triple = "wasm32-unknown-wasi" %"main.Point[float32]" = type { float, float } %"main.Point[int]" = type { i32, i32 } -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden void @main.main(ptr %context) unnamed_addr #2 { +define hidden void @main.main(ptr %context) unnamed_addr #1 { entry: %0 = call %"main.Point[float32]" @"main.Add[float32]"(float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, ptr undef) %1 = call %"main.Point[int]" @"main.Add[int]"(i32 0, i32 0, i32 0, i32 0, ptr undef) @@ -26,7 +23,7 @@ entry: } ; Function Attrs: nounwind -define linkonce_odr hidden %"main.Point[float32]" @"main.Add[float32]"(float %a.X, float %a.Y, float %b.X, float %b.Y, ptr %context) unnamed_addr #2 { +define linkonce_odr hidden %"main.Point[float32]" @"main.Add[float32]"(float %a.X, float %a.Y, float %b.X, float %b.Y, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %a = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3 @@ -96,12 +93,15 @@ store.throw7: ; preds = %store.next unreachable } -declare void @main.checkSize(i32, ptr) #1 +; Function Attrs: allockind("alloc,zeroed") allocsize(0) +declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #2 + +declare void @main.checkSize(i32, ptr) #0 -declare void @runtime.nilPanic(ptr) #1 +declare void @runtime.nilPanic(ptr) #0 ; Function Attrs: nounwind -define linkonce_odr hidden %"main.Point[int]" @"main.Add[int]"(i32 %a.X, i32 %a.Y, i32 %b.X, i32 %b.Y, ptr %context) unnamed_addr #2 { +define linkonce_odr hidden %"main.Point[int]" @"main.Add[int]"(i32 %a.X, i32 %a.Y, i32 %b.X, i32 %b.Y, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %a = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3 @@ -171,7 +171,7 @@ store.throw7: ; preds = %store.next unreachable } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } attributes #3 = { nounwind } diff --git a/compiler/testdata/go1.20.ll b/compiler/testdata/go1.20.ll index dff746667d..3ef92b634a 100644 --- a/compiler/testdata/go1.20.ll +++ b/compiler/testdata/go1.20.ll @@ -5,27 +5,24 @@ target triple = "wasm32-unknown-wasi" %runtime._string = type { ptr, i32 } -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden ptr @main.unsafeSliceData(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #2 { +define hidden ptr @main.unsafeSliceData(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 - call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef) #3 + call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %s.data } ; Function Attrs: nounwind -define hidden %runtime._string @main.unsafeString(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #2 { +define hidden %runtime._string @main.unsafeString(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %0 = icmp slt i16 %len, 0 @@ -39,25 +36,24 @@ unsafe.String.next: ; preds = %entry %5 = zext nneg i16 %len to i32 %6 = insertvalue %runtime._string undef, ptr %ptr, 0 %7 = insertvalue %runtime._string %6, i32 %5, 1 - call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #3 + call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2 ret %runtime._string %7 unsafe.String.throw: ; preds = %entry - call void @runtime.unsafeSlicePanic(ptr undef) #3 + call void @runtime.unsafeSlicePanic(ptr undef) #2 unreachable } -declare void @runtime.unsafeSlicePanic(ptr) #1 +declare void @runtime.unsafeSlicePanic(ptr) #0 ; Function Attrs: nounwind -define hidden ptr @main.unsafeStringData(ptr readonly %s.data, i32 %s.len, ptr %context) unnamed_addr #2 { +define hidden ptr @main.unsafeStringData(ptr readonly %s.data, i32 %s.len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 - call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef) #3 + call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %s.data } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { nounwind } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { nounwind } diff --git a/compiler/testdata/go1.21.ll b/compiler/testdata/go1.21.ll index 57c63c90c0..664309518e 100644 --- a/compiler/testdata/go1.21.ll +++ b/compiler/testdata/go1.21.ll @@ -5,35 +5,32 @@ target triple = "wasm32-unknown-wasi" %runtime._string = type { ptr, i32 } -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden i32 @main.min1(i32 %a, ptr %context) unnamed_addr #2 { +define hidden i32 @main.min1(i32 %a, ptr %context) unnamed_addr #1 { entry: ret i32 %a } ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) -declare i32 @llvm.smin.i32(i32, i32) #3 +declare i32 @llvm.smin.i32(i32, i32) #2 ; Function Attrs: nounwind -define hidden i32 @main.min2(i32 %a, i32 %b, ptr %context) unnamed_addr #2 { +define hidden i32 @main.min2(i32 %a, i32 %b, ptr %context) unnamed_addr #1 { entry: %0 = call i32 @llvm.smin.i32(i32 %a, i32 %b) ret i32 %0 } ; Function Attrs: nounwind -define hidden i32 @main.min3(i32 %a, i32 %b, i32 %c, ptr %context) unnamed_addr #2 { +define hidden i32 @main.min3(i32 %a, i32 %b, i32 %c, ptr %context) unnamed_addr #1 { entry: %0 = call i32 @llvm.smin.i32(i32 %a, i32 %b) %1 = call i32 @llvm.smin.i32(i32 %0, i32 %c) @@ -41,7 +38,7 @@ entry: } ; Function Attrs: nounwind -define hidden i32 @main.min4(i32 %a, i32 %b, i32 %c, i32 %d, ptr %context) unnamed_addr #2 { +define hidden i32 @main.min4(i32 %a, i32 %b, i32 %c, i32 %d, ptr %context) unnamed_addr #1 { entry: %0 = call i32 @llvm.smin.i32(i32 %a, i32 %b) %1 = call i32 @llvm.smin.i32(i32 %0, i32 %c) @@ -50,109 +47,109 @@ entry: } ; Function Attrs: nounwind -define hidden i8 @main.minUint8(i8 %a, i8 %b, ptr %context) unnamed_addr #2 { +define hidden i8 @main.minUint8(i8 %a, i8 %b, ptr %context) unnamed_addr #1 { entry: %0 = call i8 @llvm.umin.i8(i8 %a, i8 %b) ret i8 %0 } ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) -declare i8 @llvm.umin.i8(i8, i8) #3 +declare i8 @llvm.umin.i8(i8, i8) #2 ; Function Attrs: nounwind -define hidden i32 @main.minUnsigned(i32 %a, i32 %b, ptr %context) unnamed_addr #2 { +define hidden i32 @main.minUnsigned(i32 %a, i32 %b, ptr %context) unnamed_addr #1 { entry: %0 = call i32 @llvm.umin.i32(i32 %a, i32 %b) ret i32 %0 } ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) -declare i32 @llvm.umin.i32(i32, i32) #3 +declare i32 @llvm.umin.i32(i32, i32) #2 ; Function Attrs: nounwind -define hidden float @main.minFloat32(float %a, float %b, ptr %context) unnamed_addr #2 { +define hidden float @main.minFloat32(float %a, float %b, ptr %context) unnamed_addr #1 { entry: %0 = call float @llvm.minimum.f32(float %a, float %b) ret float %0 } ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) -declare float @llvm.minimum.f32(float, float) #3 +declare float @llvm.minimum.f32(float, float) #2 ; Function Attrs: nounwind -define hidden double @main.minFloat64(double %a, double %b, ptr %context) unnamed_addr #2 { +define hidden double @main.minFloat64(double %a, double %b, ptr %context) unnamed_addr #1 { entry: %0 = call double @llvm.minimum.f64(double %a, double %b) ret double %0 } ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) -declare double @llvm.minimum.f64(double, double) #3 +declare double @llvm.minimum.f64(double, double) #2 ; Function Attrs: nounwind -define hidden %runtime._string @main.minString(ptr readonly %a.data, i32 %a.len, ptr readonly %b.data, i32 %b.len, ptr %context) unnamed_addr #2 { +define hidden %runtime._string @main.minString(ptr readonly %a.data, i32 %a.len, ptr readonly %b.data, i32 %b.len, ptr %context) unnamed_addr #1 { entry: %0 = insertvalue %runtime._string zeroinitializer, ptr %a.data, 0 %1 = insertvalue %runtime._string %0, i32 %a.len, 1 %2 = insertvalue %runtime._string zeroinitializer, ptr %b.data, 0 %3 = insertvalue %runtime._string %2, i32 %b.len, 1 %stackalloc = alloca i8, align 1 - %4 = call i1 @runtime.stringLess(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr undef) #5 + %4 = call i1 @runtime.stringLess(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr undef) #4 %5 = select i1 %4, %runtime._string %1, %runtime._string %3 %6 = select i1 %4, ptr %a.data, ptr %b.data - call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5 + call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #4 ret %runtime._string %5 } -declare i1 @runtime.stringLess(ptr readonly, i32, ptr readonly, i32, ptr) #1 +declare i1 @runtime.stringLess(ptr readonly, i32, ptr readonly, i32, ptr) #0 ; Function Attrs: nounwind -define hidden i32 @main.maxInt(i32 %a, i32 %b, ptr %context) unnamed_addr #2 { +define hidden i32 @main.maxInt(i32 %a, i32 %b, ptr %context) unnamed_addr #1 { entry: %0 = call i32 @llvm.smax.i32(i32 %a, i32 %b) ret i32 %0 } ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) -declare i32 @llvm.smax.i32(i32, i32) #3 +declare i32 @llvm.smax.i32(i32, i32) #2 ; Function Attrs: nounwind -define hidden i32 @main.maxUint(i32 %a, i32 %b, ptr %context) unnamed_addr #2 { +define hidden i32 @main.maxUint(i32 %a, i32 %b, ptr %context) unnamed_addr #1 { entry: %0 = call i32 @llvm.umax.i32(i32 %a, i32 %b) ret i32 %0 } ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) -declare i32 @llvm.umax.i32(i32, i32) #3 +declare i32 @llvm.umax.i32(i32, i32) #2 ; Function Attrs: nounwind -define hidden float @main.maxFloat32(float %a, float %b, ptr %context) unnamed_addr #2 { +define hidden float @main.maxFloat32(float %a, float %b, ptr %context) unnamed_addr #1 { entry: %0 = call float @llvm.maximum.f32(float %a, float %b) ret float %0 } ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) -declare float @llvm.maximum.f32(float, float) #3 +declare float @llvm.maximum.f32(float, float) #2 ; Function Attrs: nounwind -define hidden %runtime._string @main.maxString(ptr readonly %a.data, i32 %a.len, ptr readonly %b.data, i32 %b.len, ptr %context) unnamed_addr #2 { +define hidden %runtime._string @main.maxString(ptr readonly %a.data, i32 %a.len, ptr readonly %b.data, i32 %b.len, ptr %context) unnamed_addr #1 { entry: %0 = insertvalue %runtime._string zeroinitializer, ptr %a.data, 0 %1 = insertvalue %runtime._string %0, i32 %a.len, 1 %2 = insertvalue %runtime._string zeroinitializer, ptr %b.data, 0 %3 = insertvalue %runtime._string %2, i32 %b.len, 1 %stackalloc = alloca i8, align 1 - %4 = call i1 @runtime.stringLess(ptr %b.data, i32 %b.len, ptr %a.data, i32 %a.len, ptr undef) #5 + %4 = call i1 @runtime.stringLess(ptr %b.data, i32 %b.len, ptr %a.data, i32 %a.len, ptr undef) #4 %5 = select i1 %4, %runtime._string %1, %runtime._string %3 %6 = select i1 %4, ptr %a.data, ptr %b.data - call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5 + call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #4 ret %runtime._string %5 } ; Function Attrs: nounwind -define hidden void @main.clearSlice(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #2 { +define hidden void @main.clearSlice(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 { entry: %0 = shl i32 %s.len, 2 call void @llvm.memset.p0.i32(ptr align 4 %s.data, i8 0, i32 %0, i1 false) @@ -160,26 +157,25 @@ entry: } ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write) -declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg) #4 +declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg) #3 ; Function Attrs: nounwind -define hidden void @main.clearZeroSizedSlice(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #2 { +define hidden void @main.clearZeroSizedSlice(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden void @main.clearMap(ptr dereferenceable_or_null(48) %m, ptr %context) unnamed_addr #2 { +define hidden void @main.clearMap(ptr dereferenceable_or_null(48) %m, ptr %context) unnamed_addr #1 { entry: - call void @runtime.hashmapClear(ptr %m, ptr undef) #5 + call void @runtime.hashmapClear(ptr %m, ptr undef) #4 ret void } -declare void @runtime.hashmapClear(ptr dereferenceable_or_null(48), ptr) #1 +declare void @runtime.hashmapClear(ptr dereferenceable_or_null(48), ptr) #0 -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } -attributes #4 = { nocallback nofree nounwind willreturn memory(argmem: write) } -attributes #5 = { nounwind } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +attributes #3 = { nocallback nofree nounwind willreturn memory(argmem: write) } +attributes #4 = { nounwind } diff --git a/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll b/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll index 96e5a84801..a1e81a9b1b 100644 --- a/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll +++ b/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll @@ -5,39 +5,36 @@ target triple = "thumbv7m-unknown-unknown-eabi" @"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #1 { +define hidden void @main.init(ptr %context) unnamed_addr #0 { entry: ret void } ; Function Attrs: nounwind -define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #1 { +define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #0 { entry: %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr undef) #11 call void @"internal/task.start"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 %stacksize, ptr undef) #11 ret void } -declare void @main.regularFunction(i32, ptr) #2 +declare void @main.regularFunction(i32, ptr) #1 ; Function Attrs: nounwind -define linkonce_odr void @"main.regularFunction$gowrapper"(ptr %0) unnamed_addr #3 { +define linkonce_odr void @"main.regularFunction$gowrapper"(ptr %0) unnamed_addr #2 { entry: %unpack.int = ptrtoint ptr %0 to i32 call void @main.regularFunction(i32 %unpack.int, ptr undef) #11 ret void } -declare i32 @"internal/task.getGoroutineStackSize"(i32, ptr) #2 +declare i32 @"internal/task.getGoroutineStackSize"(i32, ptr) #1 -declare void @"internal/task.start"(i32, ptr, i32, ptr) #2 +declare void @"internal/task.start"(i32, ptr, i32, ptr) #1 ; Function Attrs: nounwind -define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #1 { +define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #0 { entry: %stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.inlineFunctionGoroutine$1$gowrapper" to i32), ptr undef) #11 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) #11 @@ -45,13 +42,13 @@ entry: } ; Function Attrs: nounwind -define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 { +define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #0 { entry: ret void } ; Function Attrs: nounwind -define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #4 { +define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #3 { entry: %unpack.int = ptrtoint ptr %0 to i32 call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, ptr undef) @@ -59,7 +56,7 @@ entry: } ; Function Attrs: nounwind -define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 { +define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #0 { entry: %n = call align 4 dereferenceable(4) ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #11 store i32 3, ptr %n, align 4 @@ -76,8 +73,11 @@ entry: ret void } +; Function Attrs: allockind("alloc,zeroed") allocsize(0) +declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #4 + ; Function Attrs: nounwind -define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 { +define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #0 { entry: store i32 7, ptr %context, align 4 ret void @@ -93,14 +93,14 @@ entry: ret void } -declare void @runtime.printlock(ptr) #2 +declare void @runtime.printlock(ptr) #1 -declare void @runtime.printint32(i32, ptr) #2 +declare void @runtime.printint32(i32, ptr) #1 -declare void @runtime.printunlock(ptr) #2 +declare void @runtime.printunlock(ptr) #1 ; Function Attrs: nounwind -define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #1 { +define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #0 { entry: %0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #11 store i32 5, ptr %0, align 4 @@ -126,13 +126,13 @@ entry: } ; Function Attrs: nounwind -define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #1 { +define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #0 { entry: ret void } ; Function Attrs: nounwind -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 { +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 #0 { entry: %copy.n = call i32 @llvm.umin.i32(i32 %dst.len, i32 %src.len) call void @llvm.memmove.p0.p0.i32(ptr align 1 %dst.data, ptr align 1 %src.data, i32 %copy.n, i1 false) @@ -146,16 +146,16 @@ declare i32 @llvm.umin.i32(i32, i32) #7 declare void @llvm.memmove.p0.p0.i32(ptr nocapture writeonly, ptr nocapture readonly, i32, i1 immarg) #8 ; Function Attrs: nounwind -define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 { +define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #0 { entry: call void @runtime.chanClose(ptr %ch, ptr undef) #11 ret void } -declare void @runtime.chanClose(ptr dereferenceable_or_null(36), ptr) #2 +declare void @runtime.chanClose(ptr dereferenceable_or_null(36), ptr) #1 ; Function Attrs: nounwind -define hidden void @main.startInterfaceMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { +define hidden void @main.startInterfaceMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #0 { entry: %0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #11 store ptr %itf.value, ptr %0, align 4 @@ -186,11 +186,11 @@ entry: ret void } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+armv7-m,+hwdiv,+soft-float,+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,+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 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+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 #3 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+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" "tinygo-gowrapper"="main.regularFunction" } -attributes #4 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+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" "tinygo-gowrapper"="main.inlineFunctionGoroutine$1" } +attributes #0 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+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 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+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 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+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" "tinygo-gowrapper"="main.regularFunction" } +attributes #3 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+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" "tinygo-gowrapper"="main.inlineFunctionGoroutine$1" } +attributes #4 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+armv7-m,+hwdiv,+soft-float,+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 #5 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+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" "tinygo-gowrapper"="main.closureFunctionGoroutine$1" } attributes #6 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+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" "tinygo-gowrapper" } attributes #7 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } diff --git a/compiler/testdata/goroutine-wasm-asyncify.ll b/compiler/testdata/goroutine-wasm-asyncify.ll index 75185afbf5..137b601f77 100644 --- a/compiler/testdata/goroutine-wasm-asyncify.ll +++ b/compiler/testdata/goroutine-wasm-asyncify.ll @@ -5,30 +5,27 @@ target triple = "wasm32-unknown-wasi" @"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #2 { +define hidden void @main.regularFunctionGoroutine(ptr %context) unnamed_addr #1 { entry: call void @"internal/task.start"(i32 ptrtoint (ptr @"main.regularFunction$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 65536, ptr undef) #11 ret void } -declare void @main.regularFunction(i32, ptr) #1 +declare void @main.regularFunction(i32, ptr) #0 -declare void @runtime.deadlock(ptr) #1 +declare void @runtime.deadlock(ptr) #0 ; Function Attrs: nounwind -define linkonce_odr void @"main.regularFunction$gowrapper"(ptr %0) unnamed_addr #3 { +define linkonce_odr void @"main.regularFunction$gowrapper"(ptr %0) unnamed_addr #2 { entry: %unpack.int = ptrtoint ptr %0 to i32 call void @main.regularFunction(i32 %unpack.int, ptr undef) #11 @@ -36,23 +33,23 @@ entry: unreachable } -declare void @"internal/task.start"(i32, ptr, i32, ptr) #1 +declare void @"internal/task.start"(i32, ptr, i32, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #2 { +define hidden void @main.inlineFunctionGoroutine(ptr %context) unnamed_addr #1 { entry: call void @"internal/task.start"(i32 ptrtoint (ptr @"main.inlineFunctionGoroutine$1$gowrapper" to i32), ptr nonnull inttoptr (i32 5 to ptr), i32 65536, ptr undef) #11 ret void } ; Function Attrs: nounwind -define internal void @"main.inlineFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #2 { +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"(ptr %0) unnamed_addr #4 { +define linkonce_odr void @"main.inlineFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #3 { entry: %unpack.int = ptrtoint ptr %0 to i32 call void @"main.inlineFunctionGoroutine$1"(i32 %unpack.int, ptr undef) @@ -61,7 +58,7 @@ entry: } ; Function Attrs: nounwind -define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #2 { +define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %n = call align 4 dereferenceable(4) ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #11 @@ -82,8 +79,11 @@ entry: ret void } +; Function Attrs: allockind("alloc,zeroed") allocsize(0) +declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #4 + ; Function Attrs: nounwind -define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #2 { +define internal void @"main.closureFunctionGoroutine$1"(i32 %x, ptr %context) unnamed_addr #1 { entry: store i32 7, ptr %context, align 4 ret void @@ -100,14 +100,14 @@ entry: unreachable } -declare void @runtime.printlock(ptr) #1 +declare void @runtime.printlock(ptr) #0 -declare void @runtime.printint32(i32, ptr) #1 +declare void @runtime.printint32(i32, ptr) #0 -declare void @runtime.printunlock(ptr) #1 +declare void @runtime.printunlock(ptr) #0 ; Function Attrs: nounwind -define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #2 { +define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #11 @@ -135,13 +135,13 @@ entry: } ; Function Attrs: nounwind -define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #2 { +define hidden void @main.recoverBuiltinGoroutine(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -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 #2 { +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 @llvm.umin.i32(i32 %dst.len, i32 %src.len) call void @llvm.memmove.p0.p0.i32(ptr align 1 %dst.data, ptr align 1 %src.data, i32 %copy.n, i1 false) @@ -155,16 +155,16 @@ declare i32 @llvm.umin.i32(i32, i32) #7 declare void @llvm.memmove.p0.p0.i32(ptr nocapture writeonly, ptr nocapture readonly, i32, i1 immarg) #8 ; Function Attrs: nounwind -define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #2 { +define hidden void @main.closeBuiltinGoroutine(ptr dereferenceable_or_null(36) %ch, ptr %context) unnamed_addr #1 { entry: call void @runtime.chanClose(ptr %ch, ptr undef) #11 ret void } -declare void @runtime.chanClose(ptr dereferenceable_or_null(36), ptr) #1 +declare void @runtime.chanClose(ptr dereferenceable_or_null(36), ptr) #0 ; Function Attrs: nounwind -define hidden void @main.startInterfaceMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 { +define hidden void @main.startInterfaceMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #11 @@ -197,11 +197,11 @@ entry: unreachable } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.regularFunction" } -attributes #4 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.inlineFunctionGoroutine$1" } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.regularFunction" } +attributes #3 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.inlineFunctionGoroutine$1" } +attributes #4 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } attributes #5 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.closureFunctionGoroutine$1" } attributes #6 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper" } attributes #7 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } diff --git a/compiler/testdata/interface.ll b/compiler/testdata/interface.ll index 4bec11c419..f1ba5858ea 100644 --- a/compiler/testdata/interface.ll +++ b/compiler/testdata/interface.ll @@ -19,57 +19,54 @@ target triple = "wasm32-unknown-wasi" @"reflect/types.type:interface:{String:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr, { i32, [1 x ptr] } } { i8 84, ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", { i32, [1 x ptr] } { i32 1, [1 x ptr] [ptr @"reflect/types.signature:String:func:{}{basic:string}"] } }, align 4 @"reflect/types.typeid:basic:int" = external constant i8 -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden %runtime._interface @main.simpleType(ptr %context) unnamed_addr #2 { +define hidden %runtime._interface @main.simpleType(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 - call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:basic:int", ptr nonnull %stackalloc, ptr undef) #7 - call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #7 + call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:basic:int", ptr nonnull %stackalloc, ptr undef) #6 + call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6 ret %runtime._interface { ptr @"reflect/types.type:basic:int", ptr null } } ; Function Attrs: nounwind -define hidden %runtime._interface @main.pointerType(ptr %context) unnamed_addr #2 { +define hidden %runtime._interface @main.pointerType(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 - call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:basic:int", ptr nonnull %stackalloc, ptr undef) #7 - call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #7 + call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:basic:int", ptr nonnull %stackalloc, ptr undef) #6 + call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6 ret %runtime._interface { ptr @"reflect/types.type:pointer:basic:int", ptr null } } ; Function Attrs: nounwind -define hidden %runtime._interface @main.interfaceType(ptr %context) unnamed_addr #2 { +define hidden %runtime._interface @main.interfaceType(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 - call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:named:error", ptr nonnull %stackalloc, ptr undef) #7 - call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #7 + call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:named:error", ptr nonnull %stackalloc, ptr undef) #6 + call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6 ret %runtime._interface { ptr @"reflect/types.type:pointer:named:error", ptr null } } ; Function Attrs: nounwind -define hidden %runtime._interface @main.anonymousInterfaceType(ptr %context) unnamed_addr #2 { +define hidden %runtime._interface @main.anonymousInterfaceType(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 - call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", ptr nonnull %stackalloc, ptr undef) #7 - call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #7 + call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", ptr nonnull %stackalloc, ptr undef) #6 + call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6 ret %runtime._interface { ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}", ptr null } } ; Function Attrs: nounwind -define hidden i1 @main.isInt(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 { +define hidden i1 @main.isInt(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: - %typecode = call i1 @runtime.typeAssert(ptr %itf.typecode, ptr nonnull @"reflect/types.typeid:basic:int", ptr undef) #7 + %typecode = call i1 @runtime.typeAssert(ptr %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 @@ -79,12 +76,12 @@ typeassert.ok: ; preds = %entry br label %typeassert.next } -declare i1 @runtime.typeAssert(ptr, ptr dereferenceable_or_null(1), ptr) #1 +declare i1 @runtime.typeAssert(ptr, ptr dereferenceable_or_null(1), ptr) #0 ; Function Attrs: nounwind -define hidden i1 @main.isError(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 { +define hidden i1 @main.isError(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: - %0 = call i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(ptr %itf.typecode) #7 + %0 = call i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(ptr %itf.typecode) #6 br i1 %0, label %typeassert.ok, label %typeassert.next typeassert.next: ; preds = %typeassert.ok, %entry @@ -94,12 +91,12 @@ typeassert.ok: ; preds = %entry br label %typeassert.next } -declare i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(ptr) #3 +declare i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(ptr) #2 ; Function Attrs: nounwind -define hidden i1 @main.isStringer(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 { +define hidden i1 @main.isStringer(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: - %0 = call i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(ptr %itf.typecode) #7 + %0 = call i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(ptr %itf.typecode) #6 br i1 %0, label %typeassert.ok, label %typeassert.next typeassert.next: ; preds = %typeassert.ok, %entry @@ -109,34 +106,33 @@ typeassert.ok: ; preds = %entry br label %typeassert.next } -declare i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(ptr) #4 +declare i1 @"interface:{String:func:{}{basic:string}}.$typeassert"(ptr) #3 ; Function Attrs: nounwind -define hidden i8 @main.callFooMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 { +define hidden i8 @main.callFooMethod(ptr %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"(ptr %itf.value, i32 3, ptr %itf.typecode, ptr undef) #7 + %0 = call i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr %itf.value, i32 3, ptr %itf.typecode, ptr undef) #6 ret i8 %0 } -declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr, i32, ptr, ptr) #5 +declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{basic:uint8}}.foo$invoke"(ptr, i32, ptr, ptr) #4 ; Function Attrs: nounwind -define hidden %runtime._string @main.callErrorMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #2 { +define hidden %runtime._string @main.callErrorMethod(ptr %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 - %0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr %itf.value, ptr %itf.typecode, ptr undef) #7 + %0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr %itf.value, ptr %itf.typecode, ptr undef) #6 %1 = extractvalue %runtime._string %0, 0 - call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #7 + call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #6 ret %runtime._string %0 } -declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr, ptr, ptr) #6 +declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr, ptr, ptr) #5 -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.Error() string" } -attributes #4 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.String() string" } -attributes #5 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="main.$methods.foo(int) uint8" "tinygo-methods"="reflect/methods.String() string; main.$methods.foo(int) uint8" } -attributes #6 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Error() string" "tinygo-methods"="reflect/methods.Error() string" } -attributes #7 = { nounwind } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.Error() string" } +attributes #3 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.String() string" } +attributes #4 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="main.$methods.foo(int) uint8" "tinygo-methods"="reflect/methods.String() string; main.$methods.foo(int) uint8" } +attributes #5 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Error() string" "tinygo-methods"="reflect/methods.Error() string" } +attributes #6 = { nounwind } diff --git a/compiler/testdata/pointer.ll b/compiler/testdata/pointer.ll index dec495e6e5..ee58e59f83 100644 --- a/compiler/testdata/pointer.ll +++ b/compiler/testdata/pointer.ll @@ -3,48 +3,44 @@ source_filename = "pointer.go" target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20" target triple = "wasm32-unknown-wasi" -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden [0 x i32] @main.pointerDerefZero(ptr %x, ptr %context) unnamed_addr #2 { +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 ptr @main.pointerCastFromUnsafe(ptr %x, ptr %context) unnamed_addr #2 { +define hidden ptr @main.pointerCastFromUnsafe(ptr %x, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 - call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #3 + call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %x } ; Function Attrs: nounwind -define hidden ptr @main.pointerCastToUnsafe(ptr dereferenceable_or_null(4) %x, ptr %context) unnamed_addr #2 { +define hidden ptr @main.pointerCastToUnsafe(ptr dereferenceable_or_null(4) %x, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 - call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #3 + call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %x } ; Function Attrs: nounwind -define hidden ptr @main.pointerCastToUnsafeNoop(ptr dereferenceable_or_null(1) %x, ptr %context) unnamed_addr #2 { +define hidden ptr @main.pointerCastToUnsafeNoop(ptr dereferenceable_or_null(1) %x, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 - call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #3 + call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #2 ret ptr %x } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { nounwind } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { nounwind } diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll index f9ddc59846..173f2d8c66 100644 --- a/compiler/testdata/pragma.ll +++ b/compiler/testdata/pragma.ll @@ -11,95 +11,91 @@ target triple = "wasm32-unknown-wasi" @undefinedGlobalNotInSection = external global i32, align 4 @main.multipleGlobalPragmas = hidden global i32 0, section ".global_section", align 1024 -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define void @extern_func() #3 { +define void @extern_func() #2 { entry: ret void } ; Function Attrs: nounwind -define hidden void @somepkg.someFunction1(ptr %context) unnamed_addr #2 { +define hidden void @somepkg.someFunction1(ptr %context) unnamed_addr #1 { entry: ret void } -declare void @somepkg.someFunction2(ptr) #1 +declare void @somepkg.someFunction2(ptr) #0 ; Function Attrs: inlinehint nounwind -define hidden void @main.inlineFunc(ptr %context) unnamed_addr #4 { +define hidden void @main.inlineFunc(ptr %context) unnamed_addr #3 { entry: ret void } ; Function Attrs: noinline nounwind -define hidden void @main.noinlineFunc(ptr %context) unnamed_addr #5 { +define hidden void @main.noinlineFunc(ptr %context) unnamed_addr #4 { entry: ret void } ; Function Attrs: nounwind -define hidden void @main.useGeneric(ptr %context) unnamed_addr #2 { +define hidden void @main.useGeneric(ptr %context) unnamed_addr #1 { entry: call void @"main.noinlineGenericFunc[int8]"(ptr undef) ret void } ; Function Attrs: noinline nounwind -define linkonce_odr hidden void @"main.noinlineGenericFunc[int8]"(ptr %context) unnamed_addr #5 { +define linkonce_odr hidden void @"main.noinlineGenericFunc[int8]"(ptr %context) unnamed_addr #4 { entry: ret void } ; Function Attrs: noinline nounwind -define hidden void @main.functionInSection(ptr %context) unnamed_addr #5 section ".special_function_section" { +define hidden void @main.functionInSection(ptr %context) unnamed_addr #4 section ".special_function_section" { entry: ret void } ; Function Attrs: noinline nounwind -define void @exportedFunctionInSection() #6 section ".special_function_section" { +define void @exportedFunctionInSection() #5 section ".special_function_section" { entry: ret void } -declare void @main.declaredImport() #7 +declare void @main.declaredImport() #6 -declare void @imported() #8 +declare void @imported() #7 ; Function Attrs: nounwind -define void @exported() #9 { +define void @exported() #8 { entry: ret void } -declare void @main.undefinedFunctionNotInSection(ptr) #1 +declare void @main.undefinedFunctionNotInSection(ptr) #0 -declare void @main.doesNotEscapeParam(ptr nocapture dereferenceable_or_null(4), ptr nocapture, i32, i32, ptr nocapture dereferenceable_or_null(36), ptr nocapture, ptr) #1 +declare void @main.doesNotEscapeParam(ptr nocapture dereferenceable_or_null(4), ptr nocapture, i32, i32, ptr nocapture dereferenceable_or_null(36), ptr nocapture, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.stillEscapes(ptr dereferenceable_or_null(4) %a, ptr %b.data, i32 %b.len, i32 %b.cap, ptr dereferenceable_or_null(36) %c, ptr %d, ptr %context) unnamed_addr #2 { +define hidden void @main.stillEscapes(ptr dereferenceable_or_null(4) %a, ptr %b.data, i32 %b.len, i32 %b.cap, ptr dereferenceable_or_null(36) %c, ptr %d, ptr %context) unnamed_addr #1 { entry: ret void } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="extern_func" } -attributes #4 = { inlinehint nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #5 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #6 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exportedFunctionInSection" } -attributes #7 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="modulename" "wasm-import-name"="import1" } -attributes #8 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="foobar" "wasm-import-name"="imported" } -attributes #9 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exported" } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="extern_func" } +attributes #3 = { inlinehint nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #4 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #5 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exportedFunctionInSection" } +attributes #6 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="modulename" "wasm-import-name"="import1" } +attributes #7 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="foobar" "wasm-import-name"="imported" } +attributes #8 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exported" } diff --git a/compiler/testdata/slice.ll b/compiler/testdata/slice.ll index 9ce4cd51a8..a0756b54b6 100644 --- a/compiler/testdata/slice.ll +++ b/compiler/testdata/slice.ll @@ -3,31 +3,28 @@ source_filename = "slice.go" target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20" target triple = "wasm32-unknown-wasi" -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden i32 @main.sliceLen(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #2 { +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(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #2 { +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(ptr %ints.data, i32 %ints.len, i32 %ints.cap, i32 %index, ptr %context) unnamed_addr #2 { +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 @@ -42,10 +39,10 @@ lookup.throw: ; preds = %entry unreachable } -declare void @runtime.lookupPanic(ptr) #1 +declare void @runtime.lookupPanic(ptr) #0 ; Function Attrs: nounwind -define hidden { ptr, i32, i32 } @main.sliceAppendValues(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #2 { +define hidden { ptr, i32, i32 } @main.sliceAppendValues(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %varargs = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #5 @@ -66,10 +63,13 @@ entry: ret { ptr, i32, i32 } %4 } -declare { ptr, i32, i32 } @runtime.sliceAppend(ptr, ptr nocapture readonly, i32, i32, i32, i32, ptr, ptr) #1 +; Function Attrs: allockind("alloc,zeroed") allocsize(0) +declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #2 + +declare { ptr, i32, i32 } @runtime.sliceAppend(ptr, ptr nocapture readonly, i32, i32, i32, i32, ptr, ptr) #0 ; Function Attrs: nounwind -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 #2 { +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: %stackalloc = alloca i8, align 1 %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 nonnull inttoptr (i32 3 to ptr), ptr undef) #5 @@ -84,7 +84,7 @@ entry: } ; Function Attrs: nounwind -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 #2 { +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.n = call i32 @llvm.umin.i32(i32 %dst.len, i32 %src.len) %copy.size = shl nuw i32 %copy.n, 2 @@ -99,7 +99,7 @@ declare i32 @llvm.umin.i32(i32, i32) #3 declare void @llvm.memmove.p0.p0.i32(ptr nocapture writeonly, ptr nocapture readonly, i32, i1 immarg) #4 ; Function Attrs: nounwind -define hidden { ptr, i32, i32 } @main.makeByteSlice(i32 %len, ptr %context) unnamed_addr #2 { +define hidden { ptr, i32, i32 } @main.makeByteSlice(i32 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %slice.maxcap = icmp slt i32 %len, 0 @@ -118,10 +118,10 @@ slice.throw: ; preds = %entry unreachable } -declare void @runtime.slicePanic(ptr) #1 +declare void @runtime.slicePanic(ptr) #0 ; Function Attrs: nounwind -define hidden { ptr, i32, i32 } @main.makeInt16Slice(i32 %len, ptr %context) unnamed_addr #2 { +define hidden { ptr, i32, i32 } @main.makeInt16Slice(i32 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %slice.maxcap = icmp slt i32 %len, 0 @@ -142,7 +142,7 @@ slice.throw: ; preds = %entry } ; Function Attrs: nounwind -define hidden { ptr, i32, i32 } @main.makeArraySlice(i32 %len, ptr %context) unnamed_addr #2 { +define hidden { ptr, i32, i32 } @main.makeArraySlice(i32 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %slice.maxcap = icmp ugt i32 %len, 1431655765 @@ -163,7 +163,7 @@ slice.throw: ; preds = %entry } ; Function Attrs: nounwind -define hidden { ptr, i32, i32 } @main.makeInt32Slice(i32 %len, ptr %context) unnamed_addr #2 { +define hidden { ptr, i32, i32 } @main.makeInt32Slice(i32 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %slice.maxcap = icmp ugt i32 %len, 1073741823 @@ -184,7 +184,7 @@ slice.throw: ; preds = %entry } ; Function Attrs: nounwind -define hidden ptr @main.Add32(ptr %p, i32 %len, ptr %context) unnamed_addr #2 { +define hidden ptr @main.Add32(ptr %p, i32 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %0 = getelementptr i8, ptr %p, i32 %len @@ -193,7 +193,7 @@ entry: } ; Function Attrs: nounwind -define hidden ptr @main.Add64(ptr %p, i64 %len, ptr %context) unnamed_addr #2 { +define hidden ptr @main.Add64(ptr %p, i64 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %0 = trunc i64 %len to i32 @@ -203,7 +203,7 @@ entry: } ; Function Attrs: nounwind -define hidden ptr @main.SliceToArray(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #2 { +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 @@ -216,10 +216,10 @@ slicetoarray.throw: ; preds = %entry unreachable } -declare void @runtime.sliceToArrayPointerPanic(ptr) #1 +declare void @runtime.sliceToArrayPointerPanic(ptr) #0 ; Function Attrs: nounwind -define hidden ptr @main.SliceToArrayConst(ptr %context) unnamed_addr #2 { +define hidden ptr @main.SliceToArrayConst(ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %makeslice = call align 4 dereferenceable(24) ptr @runtime.alloc(i32 24, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #5 @@ -234,7 +234,7 @@ slicetoarray.throw: ; preds = %entry } ; Function Attrs: nounwind -define hidden { ptr, i32, i32 } @main.SliceInt(ptr dereferenceable_or_null(4) %ptr, i32 %len, ptr %context) unnamed_addr #2 { +define hidden { ptr, i32, i32 } @main.SliceInt(ptr dereferenceable_or_null(4) %ptr, i32 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %0 = icmp ugt i32 %len, 1073741823 @@ -256,10 +256,10 @@ unsafe.Slice.throw: ; preds = %entry unreachable } -declare void @runtime.unsafeSlicePanic(ptr) #1 +declare void @runtime.unsafeSlicePanic(ptr) #0 ; Function Attrs: nounwind -define hidden { ptr, i32, i32 } @main.SliceUint16(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #2 { +define hidden { ptr, i32, i32 } @main.SliceUint16(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %0 = icmp eq ptr %ptr, null @@ -281,7 +281,7 @@ unsafe.Slice.throw: ; preds = %entry } ; Function Attrs: nounwind -define hidden { ptr, i32, i32 } @main.SliceUint64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #2 { +define hidden { ptr, i32, i32 } @main.SliceUint64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %0 = icmp ugt i64 %len, 1073741823 @@ -305,7 +305,7 @@ unsafe.Slice.throw: ; preds = %entry } ; Function Attrs: nounwind -define hidden { ptr, i32, i32 } @main.SliceInt64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #2 { +define hidden { ptr, i32, i32 } @main.SliceInt64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 { entry: %stackalloc = alloca i8, align 1 %0 = icmp ugt i64 %len, 1073741823 @@ -328,9 +328,9 @@ unsafe.Slice.throw: ; preds = %entry unreachable } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } attributes #3 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } attributes #4 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } attributes #5 = { nounwind } diff --git a/compiler/testdata/string.ll b/compiler/testdata/string.ll index 8c95323ccf..dd9986ed3d 100644 --- a/compiler/testdata/string.ll +++ b/compiler/testdata/string.ll @@ -7,37 +7,34 @@ target triple = "wasm32-unknown-wasi" @"main$string" = internal unnamed_addr constant [3 x i8] c"foo", align 1 -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: nounwind -define hidden %runtime._string @main.someString(ptr %context) unnamed_addr #2 { +define hidden %runtime._string @main.someString(ptr %context) unnamed_addr #1 { entry: ret %runtime._string { ptr @"main$string", i32 3 } } ; Function Attrs: nounwind -define hidden %runtime._string @main.zeroLengthString(ptr %context) unnamed_addr #2 { +define hidden %runtime._string @main.zeroLengthString(ptr %context) unnamed_addr #1 { entry: ret %runtime._string zeroinitializer } ; Function Attrs: nounwind -define hidden i32 @main.stringLen(ptr readonly %s.data, i32 %s.len, ptr %context) unnamed_addr #2 { +define hidden i32 @main.stringLen(ptr readonly %s.data, i32 %s.len, ptr %context) unnamed_addr #1 { entry: ret i32 %s.len } ; Function Attrs: nounwind -define hidden i8 @main.stringIndex(ptr readonly %s.data, i32 %s.len, i32 %index, ptr %context) unnamed_addr #2 { +define hidden i8 @main.stringIndex(ptr readonly %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 @@ -48,40 +45,40 @@ lookup.next: ; preds = %entry ret i8 %1 lookup.throw: ; preds = %entry - call void @runtime.lookupPanic(ptr undef) #3 + call void @runtime.lookupPanic(ptr undef) #2 unreachable } -declare void @runtime.lookupPanic(ptr) #1 +declare void @runtime.lookupPanic(ptr) #0 ; Function Attrs: nounwind -define hidden i1 @main.stringCompareEqual(ptr readonly %s1.data, i32 %s1.len, ptr readonly %s2.data, i32 %s2.len, ptr %context) unnamed_addr #2 { +define hidden i1 @main.stringCompareEqual(ptr readonly %s1.data, i32 %s1.len, ptr readonly %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 { entry: - %0 = call i1 @runtime.stringEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr undef) #3 + %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(ptr readonly, i32, ptr readonly, i32, ptr) #1 +declare i1 @runtime.stringEqual(ptr readonly, i32, ptr readonly, i32, ptr) #0 ; Function Attrs: nounwind -define hidden i1 @main.stringCompareUnequal(ptr readonly %s1.data, i32 %s1.len, ptr readonly %s2.data, i32 %s2.len, ptr %context) unnamed_addr #2 { +define hidden i1 @main.stringCompareUnequal(ptr readonly %s1.data, i32 %s1.len, ptr readonly %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 { entry: - %0 = call i1 @runtime.stringEqual(ptr %s1.data, i32 %s1.len, ptr %s2.data, i32 %s2.len, ptr undef) #3 + %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(ptr readonly %s1.data, i32 %s1.len, ptr readonly %s2.data, i32 %s2.len, ptr %context) unnamed_addr #2 { +define hidden i1 @main.stringCompareLarger(ptr readonly %s1.data, i32 %s1.len, ptr readonly %s2.data, i32 %s2.len, ptr %context) unnamed_addr #1 { entry: - %0 = call i1 @runtime.stringLess(ptr %s2.data, i32 %s2.len, ptr %s1.data, i32 %s1.len, ptr undef) #3 + %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(ptr readonly, i32, ptr readonly, i32, ptr) #1 +declare i1 @runtime.stringLess(ptr readonly, i32, ptr readonly, i32, ptr) #0 ; Function Attrs: nounwind -define hidden i8 @main.stringLookup(ptr readonly %s.data, i32 %s.len, i8 %x, ptr %context) unnamed_addr #2 { +define hidden i8 @main.stringLookup(ptr readonly %s.data, i32 %s.len, i8 %x, ptr %context) unnamed_addr #1 { entry: %0 = zext i8 %x to i32 %.not = icmp ugt i32 %s.len, %0 @@ -93,11 +90,10 @@ lookup.next: ; preds = %entry ret i8 %2 lookup.throw: ; preds = %entry - call void @runtime.lookupPanic(ptr undef) #3 + call void @runtime.lookupPanic(ptr undef) #2 unreachable } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { nounwind } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { nounwind } diff --git a/compiler/testdata/zeromap.ll b/compiler/testdata/zeromap.ll index 5ce2ebcb8a..be8b924c21 100644 --- a/compiler/testdata/zeromap.ll +++ b/compiler/testdata/zeromap.ll @@ -5,19 +5,16 @@ target triple = "wasm32-unknown-wasi" %main.hasPadding = type { i1, i32, i1 } -; Function Attrs: allockind("alloc,zeroed") allocsize(0) -declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 - -declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #1 +declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0 ; Function Attrs: nounwind -define hidden void @main.init(ptr %context) unnamed_addr #2 { +define hidden void @main.init(ptr %context) unnamed_addr #1 { entry: ret void } ; Function Attrs: noinline nounwind -define hidden i32 @main.testZeroGet(ptr dereferenceable_or_null(48) %m, i1 %s.b1, i32 %s.i, i1 %s.b2, ptr %context) unnamed_addr #3 { +define hidden i32 @main.testZeroGet(ptr dereferenceable_or_null(48) %m, i1 %s.b1, i32 %s.i, i1 %s.b2, ptr %context) unnamed_addr #2 { entry: %hashmap.key = alloca %main.hasPadding, align 8 %hashmap.value = alloca i32, align 4 @@ -27,7 +24,7 @@ entry: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value) call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key) store %main.hasPadding %2, ptr %hashmap.key, align 4 - %3 = call i1 @runtime.hashmapGenericGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #5 + %3 = call i1 @runtime.hashmapGenericGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #4 call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key) %4 = load i32, ptr %hashmap.value, align 4 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %hashmap.value) @@ -35,15 +32,15 @@ entry: } ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #4 +declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #3 -declare i1 @runtime.hashmapGenericGet(ptr dereferenceable_or_null(48), ptr nocapture, ptr nocapture, i32, ptr) #1 +declare i1 @runtime.hashmapGenericGet(ptr dereferenceable_or_null(48), ptr nocapture, ptr nocapture, i32, ptr) #0 ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #4 +declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #3 ; Function Attrs: noinline nounwind -define hidden void @main.testZeroSet(ptr dereferenceable_or_null(48) %m, i1 %s.b1, i32 %s.i, i1 %s.b2, ptr %context) unnamed_addr #3 { +define hidden void @main.testZeroSet(ptr dereferenceable_or_null(48) %m, i1 %s.b1, i32 %s.i, i1 %s.b2, ptr %context) unnamed_addr #2 { entry: %hashmap.key = alloca %main.hasPadding, align 8 %hashmap.value = alloca i32, align 4 @@ -54,16 +51,16 @@ entry: store i32 5, ptr %hashmap.value, align 4 call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key) store %main.hasPadding %2, ptr %hashmap.key, align 4 - call void @runtime.hashmapGenericSet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #5 + call void @runtime.hashmapGenericSet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #4 call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key) call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %hashmap.value) ret void } -declare void @runtime.hashmapGenericSet(ptr dereferenceable_or_null(48), ptr nocapture, ptr nocapture, ptr) #1 +declare void @runtime.hashmapGenericSet(ptr dereferenceable_or_null(48), ptr nocapture, ptr nocapture, ptr) #0 ; Function Attrs: noinline nounwind -define hidden i32 @main.testZeroArrayGet(ptr dereferenceable_or_null(48) %m, [2 x %main.hasPadding] %s, ptr %context) unnamed_addr #3 { +define hidden i32 @main.testZeroArrayGet(ptr dereferenceable_or_null(48) %m, [2 x %main.hasPadding] %s, ptr %context) unnamed_addr #2 { entry: %hashmap.key = alloca [2 x %main.hasPadding], align 8 %hashmap.value = alloca i32, align 4 @@ -74,7 +71,7 @@ entry: %hashmap.key.repack1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 12 %s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1 store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4 - %0 = call i1 @runtime.hashmapGenericGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #5 + %0 = call i1 @runtime.hashmapGenericGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #4 call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key) %1 = load i32, ptr %hashmap.value, align 4 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %hashmap.value) @@ -82,7 +79,7 @@ entry: } ; Function Attrs: noinline nounwind -define hidden void @main.testZeroArraySet(ptr dereferenceable_or_null(48) %m, [2 x %main.hasPadding] %s, ptr %context) unnamed_addr #3 { +define hidden void @main.testZeroArraySet(ptr dereferenceable_or_null(48) %m, [2 x %main.hasPadding] %s, ptr %context) unnamed_addr #2 { entry: %hashmap.key = alloca [2 x %main.hasPadding], align 8 %hashmap.value = alloca i32, align 4 @@ -94,21 +91,20 @@ entry: %hashmap.key.repack1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 12 %s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1 store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4 - call void @runtime.hashmapGenericSet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #5 + call void @runtime.hashmapGenericSet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #4 call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key) call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %hashmap.value) ret void } ; Function Attrs: nounwind -define hidden void @main.main(ptr %context) unnamed_addr #2 { +define hidden void @main.main(ptr %context) unnamed_addr #1 { entry: ret void } -attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #3 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } -attributes #4 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } -attributes #5 = { nounwind } +attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #2 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +attributes #4 = { nounwind } From 994c1c46ad1ee5dca837003a221c4d0b643979c4 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 20 May 2026 11:01:50 +0200 Subject: [PATCH 2/2] compiler: add //go:noheap pragma --- builder/tools.go | 6 +++- compiler/compiler.go | 14 ++++++-- compiler/defer.go | 2 +- compiler/llvm.go | 2 +- compiler/symbol.go | 6 +++- compiler/testdata/pragma.go | 5 +++ compiler/testdata/pragma.ll | 14 ++++++++ errors_test.go | 1 + interp/interpreter.go | 2 +- src/runtime/runtime.go | 5 +++ testdata/errors/noheap.go | 69 +++++++++++++++++++++++++++++++++++++ transform/allocs.go | 19 ++++++++-- 12 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 testdata/errors/noheap.go diff --git a/builder/tools.go b/builder/tools.go index 9d15e4ccaa..8a5762cb55 100644 --- a/builder/tools.go +++ b/builder/tools.go @@ -122,12 +122,16 @@ func parseLLDErrors(text string) error { parsedError = true line, _ := strconv.Atoi(matches[3]) // TODO: detect common mistakes like -gc=none? + msg := "linker could not find symbol " + symbolName + if symbolName == "runtime.alloc_noheap" { + msg = "object allocated on the heap in //go:noheap function" + } linkErrors = append(linkErrors, scanner.Error{ Pos: token.Position{ Filename: matches[2], Line: line, }, - Msg: "linker could not find symbol " + symbolName, + Msg: msg, }) } } diff --git a/compiler/compiler.go b/compiler/compiler.go index a4dd94859e..eaf7b58b1c 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -192,6 +192,16 @@ func newBuilder(c *compilerContext, irbuilder llvm.Builder, f *ssa.Function) *bu } } +// Return the runtime.alloc function variant. +// This is normally just "alloc", but is "alloc_noheap" if the //go:noheap +// pragma is used. +func (b *builder) allocFunc() string { + if b.info.noheap { + return "alloc_noheap" + } + return "alloc" +} + type blockInfo struct { // entry is the LLVM basic block corresponding to the start of this *ssa.Block. entry llvm.BasicBlock @@ -2173,7 +2183,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { } sizeValue := llvm.ConstInt(b.uintptrType, size, false) layoutValue := b.createObjectLayout(typ, expr.Pos()) - buf := b.createRuntimeCall("alloc", []llvm.Value{sizeValue, layoutValue}, expr.Comment) + buf := b.createRuntimeCall(b.allocFunc(), []llvm.Value{sizeValue, layoutValue}, expr.Comment) align := b.targetData.ABITypeAlignment(typ) buf.AddCallSiteAttribute(0, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("align"), uint64(align))) return buf, nil @@ -2405,7 +2415,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { } sliceSize := b.CreateBinOp(llvm.Mul, elemSizeValue, sliceCapCast, "makeslice.cap") layoutValue := b.createObjectLayout(llvmElemType, expr.Pos()) - slicePtr := b.createRuntimeCall("alloc", []llvm.Value{sliceSize, layoutValue}, "makeslice.buf") + slicePtr := b.createRuntimeCall(b.allocFunc(), []llvm.Value{sliceSize, layoutValue}, "makeslice.buf") slicePtr.AddCallSiteAttribute(0, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("align"), uint64(elemAlign))) // Extend or truncate if necessary. This is safe as we've already done diff --git a/compiler/defer.go b/compiler/defer.go index 7c95f0acf5..ec2bbe00e1 100644 --- a/compiler/defer.go +++ b/compiler/defer.go @@ -488,7 +488,7 @@ func (b *builder) createDefer(instr *ssa.Defer) { size := b.targetData.TypeAllocSize(deferredCallType) sizeValue := llvm.ConstInt(b.uintptrType, size, false) nilPtr := llvm.ConstNull(b.dataPtrType) - alloca = b.createRuntimeCall("alloc", []llvm.Value{sizeValue, nilPtr}, "defer.alloc.call") + alloca = b.createRuntimeCall(b.allocFunc(), []llvm.Value{sizeValue, nilPtr}, "defer.alloc.call") } if b.NeedsStackObjects { b.trackPointer(alloca) diff --git a/compiler/llvm.go b/compiler/llvm.go index 5ef656ce5e..c25a8d4a35 100644 --- a/compiler/llvm.go +++ b/compiler/llvm.go @@ -129,7 +129,7 @@ func (b *builder) emitPointerPack(values []llvm.Value) llvm.Value { // Packed data is bigger than a pointer, so allocate it on the heap. sizeValue := llvm.ConstInt(b.uintptrType, size, false) align := b.targetData.ABITypeAlignment(packedType) - packedAlloc := b.createRuntimeCall("alloc", []llvm.Value{ + packedAlloc := b.createRuntimeCall(b.allocFunc(), []llvm.Value{ sizeValue, llvm.ConstNull(b.dataPtrType), }, "") diff --git a/compiler/symbol.go b/compiler/symbol.go index 16c5433cfa..0e78e2ce30 100644 --- a/compiler/symbol.go +++ b/compiler/symbol.go @@ -34,6 +34,7 @@ type functionInfo struct { interrupt bool // go:interrupt nobounds bool // go:nobounds noescape bool // go:noescape + noheap bool // go:noheap variadic bool // go:variadic (CGo only) inline inlineType // go:inline } @@ -161,7 +162,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value) llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)) case "machine.keepAliveNoEscape", "machine.unsafeNoEscape": llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)) - case "runtime.alloc": + case "runtime.alloc", "runtime.alloc_noheap": // Tell the optimizer that runtime.alloc is an allocator, meaning that it // returns values that are never null and never alias to an existing value. for _, attrName := range []string{"noalias", "nonnull"} { @@ -476,6 +477,9 @@ func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) { if len(f.Blocks) == 0 { info.noescape = true } + case "//go:noheap": + // Ensure this function does not allocate on the heap. + info.noheap = true case "//go:variadic": // The //go:variadic pragma is emitted by the CGo preprocessing // pass for C variadic functions. This includes both explicit diff --git a/compiler/testdata/pragma.go b/compiler/testdata/pragma.go index 1e6e967f53..ebb3a2a67b 100644 --- a/compiler/testdata/pragma.go +++ b/compiler/testdata/pragma.go @@ -115,3 +115,8 @@ func doesNotEscapeParam(a *int, b []int, c chan int, d *[0]byte) //go:noescape func stillEscapes(a *int, b []int, c chan int, d *[0]byte) { } + +//go:noheap +func doesHeapAlloc() *int { + return new(int) +} diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll index 173f2d8c66..c2c06b3d49 100644 --- a/compiler/testdata/pragma.ll +++ b/compiler/testdata/pragma.ll @@ -90,6 +90,18 @@ entry: ret void } +; Function Attrs: nounwind +define hidden ptr @main.doesHeapAlloc(ptr %context) unnamed_addr #1 { +entry: + %stackalloc = alloca i8, align 1 + %new = call align 4 dereferenceable(4) ptr @runtime.alloc_noheap(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #10 + call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #10 + ret ptr %new +} + +; Function Attrs: allockind("alloc,zeroed") allocsize(0) +declare noalias nonnull ptr @runtime.alloc_noheap(i32, ptr, ptr) #9 + attributes #0 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } attributes #1 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="extern_func" } @@ -99,3 +111,5 @@ attributes #5 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory attributes #6 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="modulename" "wasm-import-name"="import1" } attributes #7 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="foobar" "wasm-import-name"="imported" } attributes #8 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exported" } +attributes #9 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" } +attributes #10 = { nounwind } diff --git a/errors_test.go b/errors_test.go index 871dc4c044..69c372bf28 100644 --- a/errors_test.go +++ b/errors_test.go @@ -38,6 +38,7 @@ func TestErrors(t *testing.T) { {name: "loader-invaliddep"}, {name: "loader-invalidpackage"}, {name: "loader-nopackage"}, + {name: "noheap", target: "cortex-m-qemu"}, {name: "optimizer"}, {name: "syntax"}, {name: "types"}, diff --git a/interp/interpreter.go b/interp/interpreter.go index 34bb668da1..710f3e8133 100644 --- a/interp/interpreter.go +++ b/interp/interpreter.go @@ -299,7 +299,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent // means that monotonic time in the time package is counted from // time.Time{}.Sub(1), which should be fine. locals[inst.localIndex] = literalValue{uint64(0)} - case callFn.name == "runtime.alloc": + case callFn.name == "runtime.alloc" || callFn.name == "runtime.alloc_noheap": // Allocate heap memory. At compile time, this is instead done // by creating a global variable. diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go index c9b0959384..872b225b9d 100644 --- a/src/runtime/runtime.go +++ b/src/runtime/runtime.go @@ -66,6 +66,11 @@ func llvm_sponentry() unsafe.Pointer //export strlen func strlen(ptr unsafe.Pointer) uintptr +// Special alloc function that should never actually be called. +// It is used instead of normal alloc in //go:noheap functions, and must either +// be optimized away or throw a linker error. +func alloc_noheap(size uintptr, layout unsafe.Pointer) unsafe.Pointer + //export malloc func malloc(size uintptr) unsafe.Pointer diff --git a/testdata/errors/noheap.go b/testdata/errors/noheap.go new file mode 100644 index 0000000000..074a6221b7 --- /dev/null +++ b/testdata/errors/noheap.go @@ -0,0 +1,69 @@ +package main + +//go:noheap +func main() { + // This object is optimized away, and won't cause a linker failure. + var a int + add(&a) + + // This object is not optimized away since its address is captured. + var b int + escape(&b) + + // A simple defer won't cause a heap allocation. + defer func() { + println("once") + }() + + // A defer in a loop does causes a heap allocation. + for range 3 { + defer func() { + println("many") + }() + } + + // This slice should not be heap-allocated. + s1 := make([]int, 5) + sum(s1) + + // But this slice is. + s2 := make([]int, 5) + escape(&s2[0]) + + // Allocated at compile time as a global, so won't escape at runtime. + escape(globalInt) +} + +func add(n *int) { + *n++ +} + +func sum(slice []int) (result int) { + for n := range slice { + result += n + } + return result +} + +var globalInt = globalNewInt() + +var globalAssign *int + +//go:noheap +func globalNewInt() *int { + return new(int) +} + +func escape(n *int) { + // Do some stuff that will definitely force a heap allocation. + // (This might be optimized in the future, in which case we need to change + // the function again). + n2 := func(n *int) *int { + return n + }(n) + println(n2) +} + +// ERROR: noheap.go:10: object allocated on the heap in //go:noheap function +// ERROR: noheap.go:20: object allocated on the heap in //go:noheap function +// ERROR: noheap.go:30: object allocated on the heap in //go:noheap function diff --git a/transform/allocs.go b/transform/allocs.go index d9c7e47096..18b49998c1 100644 --- a/transform/allocs.go +++ b/transform/allocs.go @@ -23,8 +23,15 @@ import ( // heap allocation explanation should be printed (why the object can't be stack // allocated). func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, maxStackAlloc uint64, logger func(token.Position, string)) { - allocator := mod.NamedFunction("runtime.alloc") - if allocator.IsNil() { + // Find allocator functions. + var allocators []llvm.Value + for _, name := range []string{"runtime.alloc", "runtime.alloc_noheap"} { + allocator := mod.NamedFunction(name) + if !allocator.IsNil() { + allocators = append(allocators, allocator) + } + } + if len(allocators) == 0 { // nothing to optimize return } @@ -43,7 +50,13 @@ func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, maxStackAlloc u fmt.Fprintln(os.Stderr, "mode: set") } - for _, heapalloc := range getUses(allocator) { + // Find all allocator calls. + var heapallocs []llvm.Value + for _, allocator := range allocators { + heapallocs = append(heapallocs, getUses(allocator)...) + } + + for _, heapalloc := range heapallocs { logAllocs := printAllocs != nil && printAllocs.MatchString(heapalloc.InstructionParent().Parent().Name()) if heapalloc.Operand(0).IsAConstantInt().IsNil() { // Do not allocate variable length arrays on the stack.