wasm: avoid miscompile with ThinLTO
I found that when I enable ThinLTO, a miscompilation triggers that had been hidden all the time previously. The bug appears to happen as follows: 1. TinyGo generates a function with a runtime.trackPointer call, but without an alloca (or the alloca gets optimized away). 2. LLVM sees that no alloca needs to be kept alive across the runtime.trackPointer call, and therefore it adds the 'tail' flag. One of the effects of this flag is that it makes it undefined behavior to keep allocas alive across the call (which is still safe at that point). 3. The GC lowering pass adds a stack slot alloca and converts runtime.trackPointer calls into alloca stores. The last step triggers the bug: the compiler inserts an alloca where there was none before but that's not valid as long as the 'tail' flag is present. This patch fixes the bug in a somewhat dirty way, by always creating a dummy alloca so that LLVM won't do the optimization in step 2 (and possibly other optimizations that rely on there being no alloca instruction).
Этот коммит содержится в:
родитель
27824e3c80
коммит
c41a212712
16 изменённых файлов: 122 добавлений и 79 удалений
|
@ -152,6 +152,7 @@ type builder struct {
|
||||||
phis []phiNode
|
phis []phiNode
|
||||||
deferPtr llvm.Value
|
deferPtr llvm.Value
|
||||||
deferFrame llvm.Value
|
deferFrame llvm.Value
|
||||||
|
stackChainAlloca llvm.Value
|
||||||
landingpad llvm.BasicBlock
|
landingpad llvm.BasicBlock
|
||||||
difunc llvm.Metadata
|
difunc llvm.Metadata
|
||||||
dilocals map[*types.Var]llvm.Metadata
|
dilocals map[*types.Var]llvm.Metadata
|
||||||
|
@ -1226,6 +1227,13 @@ func (b *builder) createFunctionStart(intrinsic bool) {
|
||||||
// them.
|
// them.
|
||||||
b.deferInitFunc()
|
b.deferInitFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.NeedsStackObjects {
|
||||||
|
// Create a dummy alloca that will be used in runtime.trackPointer.
|
||||||
|
// It is necessary to pass a dummy alloca to runtime.trackPointer
|
||||||
|
// because runtime.trackPointer is replaced by an alloca store.
|
||||||
|
b.stackChainAlloca = b.CreateAlloca(b.ctx.Int8Type(), "stackalloc")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// createFunction builds the LLVM IR implementation for this function. The
|
// createFunction builds the LLVM IR implementation for this function. The
|
||||||
|
|
|
@ -84,7 +84,7 @@ func (b *builder) trackPointer(value llvm.Value) {
|
||||||
if value.Type() != b.i8ptrType {
|
if value.Type() != b.i8ptrType {
|
||||||
value = b.CreateBitCast(value, b.i8ptrType, "")
|
value = b.CreateBitCast(value, b.i8ptrType, "")
|
||||||
}
|
}
|
||||||
b.createRuntimeCall("trackPointer", []llvm.Value{value}, "")
|
b.createRuntimeCall("trackPointer", []llvm.Value{value, b.stackChainAlloca}, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// typeHasPointers returns whether this type is a pointer or contains pointers.
|
// typeHasPointers returns whether this type is a pointer or contains pointers.
|
||||||
|
|
|
@ -136,11 +136,7 @@ func (b *builder) emitPointerPack(values []llvm.Value) llvm.Value {
|
||||||
llvm.Undef(b.i8ptrType), // unused context parameter
|
llvm.Undef(b.i8ptrType), // unused context parameter
|
||||||
}, "")
|
}, "")
|
||||||
if b.NeedsStackObjects {
|
if b.NeedsStackObjects {
|
||||||
trackPointer := b.mod.NamedFunction("runtime.trackPointer")
|
b.trackPointer(packedHeapAlloc)
|
||||||
b.CreateCall(trackPointer.GlobalValueType(), trackPointer, []llvm.Value{
|
|
||||||
packedHeapAlloc,
|
|
||||||
llvm.Undef(b.i8ptrType), // unused context parameter
|
|
||||||
}, "")
|
|
||||||
}
|
}
|
||||||
packedAlloc := b.CreateBitCast(packedHeapAlloc, llvm.PointerType(packedType, 0), "")
|
packedAlloc := b.CreateBitCast(packedHeapAlloc, llvm.PointerType(packedType, 0), "")
|
||||||
|
|
||||||
|
|
8
compiler/testdata/basic.ll
предоставленный
8
compiler/testdata/basic.ll
предоставленный
|
@ -12,7 +12,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
@ -196,8 +196,9 @@ entry:
|
||||||
define hidden void @main.foo(ptr %context) unnamed_addr #1 {
|
define hidden void @main.foo(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
%complit = alloca %main.kv.0, align 8
|
%complit = alloca %main.kv.0, align 8
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
store %main.kv.0 zeroinitializer, ptr %complit, align 8
|
store %main.kv.0 zeroinitializer, ptr %complit, align 8
|
||||||
call void @runtime.trackPointer(ptr nonnull %complit, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %complit, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
call void @"main.foo$1"(%main.kv.0 zeroinitializer, ptr undef)
|
call void @"main.foo$1"(%main.kv.0 zeroinitializer, ptr undef)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -206,8 +207,9 @@ entry:
|
||||||
define internal void @"main.foo$1"(%main.kv.0 %b, ptr %context) unnamed_addr #1 {
|
define internal void @"main.foo$1"(%main.kv.0 %b, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
%b1 = alloca %main.kv.0, align 8
|
%b1 = alloca %main.kv.0, align 8
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
store %main.kv.0 zeroinitializer, ptr %b1, align 8
|
store %main.kv.0 zeroinitializer, ptr %b1, align 8
|
||||||
call void @runtime.trackPointer(ptr nonnull %b1, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %b1, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store %main.kv.0 %b, ptr %b1, align 8
|
store %main.kv.0 %b, ptr %b1, align 8
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
5
compiler/testdata/channel.ll
предоставленный
5
compiler/testdata/channel.ll
предоставленный
|
@ -8,7 +8,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
@ -58,7 +58,8 @@ define hidden void @main.chanZeroSend(ptr dereferenceable_or_null(32) %ch, ptr %
|
||||||
entry:
|
entry:
|
||||||
%complit = alloca {}, align 8
|
%complit = alloca {}, align 8
|
||||||
%chan.blockedList = alloca %runtime.channelBlockedList, align 8
|
%chan.blockedList = alloca %runtime.channelBlockedList, align 8
|
||||||
call void @runtime.trackPointer(ptr nonnull %complit, ptr undef) #3
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr nonnull %complit, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList)
|
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||||
call void @runtime.chanSend(ptr %ch, ptr null, ptr nonnull %chan.blockedList, ptr undef) #3
|
call void @runtime.chanSend(ptr %ch, ptr null, ptr nonnull %chan.blockedList, ptr undef) #3
|
||||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList)
|
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %chan.blockedList)
|
||||||
|
|
2
compiler/testdata/float.ll
предоставленный
2
compiler/testdata/float.ll
предоставленный
|
@ -5,7 +5,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
|
2
compiler/testdata/func.ll
предоставленный
2
compiler/testdata/func.ll
предоставленный
|
@ -5,7 +5,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
|
42
compiler/testdata/gc.ll
предоставленный
42
compiler/testdata/gc.ll
предоставленный
|
@ -27,7 +27,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
@ -38,17 +38,18 @@ entry:
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.newScalar(ptr %context) unnamed_addr #1 {
|
define hidden void @main.newScalar(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%new = call ptr @runtime.alloc(i32 1, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%new = call ptr @runtime.alloc(i32 1, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new, ptr @main.scalar1, align 4
|
store ptr %new, ptr @main.scalar1, align 4
|
||||||
%new1 = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%new1 = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new1, ptr @main.scalar2, align 4
|
store ptr %new1, ptr @main.scalar2, align 4
|
||||||
%new2 = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%new2 = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new2, ptr @main.scalar3, align 4
|
store ptr %new2, ptr @main.scalar3, align 4
|
||||||
%new3 = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%new3 = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new3, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new3, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new3, ptr @main.scalar4, align 4
|
store ptr %new3, ptr @main.scalar4, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -56,14 +57,15 @@ entry:
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.newArray(ptr %context) unnamed_addr #1 {
|
define hidden void @main.newArray(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%new = call ptr @runtime.alloc(i32 3, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%new = call ptr @runtime.alloc(i32 3, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new, ptr @main.array1, align 4
|
store ptr %new, ptr @main.array1, align 4
|
||||||
%new1 = call ptr @runtime.alloc(i32 71, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%new1 = call ptr @runtime.alloc(i32 71, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new1, ptr @main.array2, align 4
|
store ptr %new1, ptr @main.array2, align 4
|
||||||
%new2 = call ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2
|
%new2 = call ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new2, ptr @main.array3, align 4
|
store ptr %new2, ptr @main.array3, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -71,17 +73,18 @@ entry:
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.newStruct(ptr %context) unnamed_addr #1 {
|
define hidden void @main.newStruct(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%new = call ptr @runtime.alloc(i32 0, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%new = call ptr @runtime.alloc(i32 0, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new, ptr @main.struct1, align 4
|
store ptr %new, ptr @main.struct1, align 4
|
||||||
%new1 = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%new1 = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new1, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new1, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new1, ptr @main.struct2, align 4
|
store ptr %new1, ptr @main.struct2, align 4
|
||||||
%new2 = call ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-2000000000000001", ptr undef) #2
|
%new2 = call ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-2000000000000001", ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new2, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new2, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new2, ptr @main.struct3, align 4
|
store ptr %new2, ptr @main.struct3, align 4
|
||||||
%new3 = call ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-0001", ptr undef) #2
|
%new3 = call ptr @runtime.alloc(i32 248, ptr nonnull @"runtime/gc.layout:62-0001", ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new3, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new3, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %new3, ptr @main.struct4, align 4
|
store ptr %new3, ptr @main.struct4, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -89,26 +92,28 @@ entry:
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.newFuncValue(ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.newFuncValue(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%new = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 197 to ptr), ptr undef) #2
|
%new = call ptr @runtime.alloc(i32 8, ptr nonnull inttoptr (i32 197 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %new, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %new, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %new
|
ret ptr %new
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.makeSlice(ptr %context) unnamed_addr #1 {
|
define hidden void @main.makeSlice(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%makeslice = call ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%makeslice = call ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %makeslice, ptr @main.slice1, align 8
|
store ptr %makeslice, ptr @main.slice1, align 8
|
||||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 1), align 4
|
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 1), align 4
|
||||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 8
|
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 8
|
||||||
%makeslice1 = call ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2
|
%makeslice1 = call ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %makeslice1, ptr @main.slice2, align 8
|
store ptr %makeslice1, ptr @main.slice2, align 8
|
||||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 1), align 4
|
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 1), align 4
|
||||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 8
|
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 8
|
||||||
%makeslice3 = call ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #2
|
%makeslice3 = call ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store ptr %makeslice3, ptr @main.slice3, align 8
|
store ptr %makeslice3, ptr @main.slice3, align 8
|
||||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 1), align 4
|
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 1), align 4
|
||||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 8
|
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 8
|
||||||
|
@ -118,13 +123,14 @@ entry:
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, ptr %context) unnamed_addr #1 {
|
define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #2
|
%0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store double %v.r, ptr %0, align 8
|
store double %v.r, ptr %0, align 8
|
||||||
%.repack1 = getelementptr inbounds { double, double }, ptr %0, i32 0, i32 1
|
%.repack1 = getelementptr inbounds { double, double }, ptr %0, i32 0, i32 1
|
||||||
store double %v.i, ptr %.repack1, align 8
|
store double %v.i, ptr %.repack1, align 8
|
||||||
%1 = insertvalue %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:complex128" to i32), ptr undef }, ptr %0, 1
|
%1 = insertvalue %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:complex128" to i32), ptr undef }, ptr %0, 1
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret %runtime._interface %1
|
ret %runtime._interface %1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
compiler/testdata/go1.20.ll
предоставленный
11
compiler/testdata/go1.20.ll
предоставленный
|
@ -7,7 +7,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
@ -18,13 +18,15 @@ entry:
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.unsafeSliceData(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.unsafeSliceData(ptr %s.data, i32 %s.len, i32 %s.cap, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr %s.data, ptr undef) #2
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %s.data
|
ret ptr %s.data
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden %runtime._string @main.unsafeString(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 {
|
define hidden %runtime._string @main.unsafeString(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = icmp slt i16 %len, 0
|
%0 = icmp slt i16 %len, 0
|
||||||
%1 = icmp eq ptr %ptr, null
|
%1 = icmp eq ptr %ptr, null
|
||||||
%2 = icmp ne i16 %len, 0
|
%2 = icmp ne i16 %len, 0
|
||||||
|
@ -36,7 +38,7 @@ unsafe.String.next: ; preds = %entry
|
||||||
%5 = zext i16 %len to i32
|
%5 = zext i16 %len to i32
|
||||||
%6 = insertvalue %runtime._string undef, ptr %ptr, 0
|
%6 = insertvalue %runtime._string undef, ptr %ptr, 0
|
||||||
%7 = insertvalue %runtime._string %6, i32 %5, 1
|
%7 = insertvalue %runtime._string %6, i32 %5, 1
|
||||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret %runtime._string %7
|
ret %runtime._string %7
|
||||||
|
|
||||||
unsafe.String.throw: ; preds = %entry
|
unsafe.String.throw: ; preds = %entry
|
||||||
|
@ -49,7 +51,8 @@ declare void @runtime.unsafeSlicePanic(ptr) #0
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.unsafeStringData(ptr %s.data, i32 %s.len, ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.unsafeStringData(ptr %s.data, i32 %s.len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr %s.data, ptr undef) #2
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr %s.data, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %s.data
|
ret ptr %s.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
compiler/testdata/goroutine-wasm-asyncify.ll
предоставленный
17
compiler/testdata/goroutine-wasm-asyncify.ll
предоставленный
|
@ -9,7 +9,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
@ -64,13 +64,14 @@ entry:
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
define hidden void @main.closureFunctionGoroutine(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%n = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #8
|
%n = call ptr @runtime.alloc(i32 4, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #8
|
||||||
call void @runtime.trackPointer(ptr nonnull %n, ptr undef) #8
|
call void @runtime.trackPointer(ptr nonnull %n, ptr nonnull %stackalloc, ptr undef) #8
|
||||||
store i32 3, ptr %n, align 4
|
store i32 3, ptr %n, align 4
|
||||||
call void @runtime.trackPointer(ptr nonnull %n, ptr undef) #8
|
call void @runtime.trackPointer(ptr nonnull %n, ptr nonnull %stackalloc, ptr undef) #8
|
||||||
call void @runtime.trackPointer(ptr nonnull @"main.closureFunctionGoroutine$1", ptr undef) #8
|
call void @runtime.trackPointer(ptr nonnull @"main.closureFunctionGoroutine$1", ptr nonnull %stackalloc, ptr undef) #8
|
||||||
%0 = call ptr @runtime.alloc(i32 8, ptr null, ptr undef) #8
|
%0 = call ptr @runtime.alloc(i32 8, ptr null, ptr undef) #8
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #8
|
||||||
store i32 5, ptr %0, align 4
|
store i32 5, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1
|
%1 = getelementptr inbounds { i32, ptr }, ptr %0, i32 0, i32 1
|
||||||
store ptr %n, ptr %1, align 4
|
store ptr %n, ptr %1, align 4
|
||||||
|
@ -103,8 +104,9 @@ declare void @runtime.printint32(i32, ptr) #0
|
||||||
; Function Attrs: nounwind
|
; 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 #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = call ptr @runtime.alloc(i32 12, ptr null, ptr undef) #8
|
%0 = call ptr @runtime.alloc(i32 12, ptr null, ptr undef) #8
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #8
|
||||||
store i32 5, ptr %0, align 4
|
store i32 5, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1
|
%1 = getelementptr inbounds { i32, ptr, ptr }, ptr %0, i32 0, i32 1
|
||||||
store ptr %fn.context, ptr %1, align 4
|
store ptr %fn.context, ptr %1, align 4
|
||||||
|
@ -154,8 +156,9 @@ declare void @runtime.chanClose(ptr dereferenceable_or_null(32), ptr) #0
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.startInterfaceMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
define hidden void @main.startInterfaceMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #8
|
%0 = call ptr @runtime.alloc(i32 16, ptr null, ptr undef) #8
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #8
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #8
|
||||||
store ptr %itf.value, ptr %0, align 4
|
store ptr %itf.value, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1
|
%1 = getelementptr inbounds { ptr, %runtime._string, i32 }, ptr %0, i32 0, i32 1
|
||||||
store ptr @"main$string", ptr %1, align 4
|
store ptr @"main$string", ptr %1, align 4
|
||||||
|
|
17
compiler/testdata/interface.ll
предоставленный
17
compiler/testdata/interface.ll
предоставленный
|
@ -23,7 +23,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
@ -34,21 +34,24 @@ entry:
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden %runtime._interface @main.simpleType(ptr %context) unnamed_addr #1 {
|
define hidden %runtime._interface @main.simpleType(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr null, ptr undef) #6
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6
|
||||||
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:int" to i32), ptr null }
|
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:basic:int" to i32), ptr null }
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden %runtime._interface @main.pointerType(ptr %context) unnamed_addr #1 {
|
define hidden %runtime._interface @main.pointerType(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr null, ptr undef) #6
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6
|
||||||
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:basic:int" to i32), ptr null }
|
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:basic:int" to i32), ptr null }
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden %runtime._interface @main.interfaceType(ptr %context) unnamed_addr #1 {
|
define hidden %runtime._interface @main.interfaceType(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr null, ptr undef) #6
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6
|
||||||
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:named:error" to i32), ptr null }
|
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:named:error" to i32), ptr null }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +60,8 @@ declare i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(i32) #2
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden %runtime._interface @main.anonymousInterfaceType(ptr %context) unnamed_addr #1 {
|
define hidden %runtime._interface @main.anonymousInterfaceType(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr null, ptr undef) #6
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr null, ptr nonnull %stackalloc, ptr undef) #6
|
||||||
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), ptr null }
|
ret %runtime._interface { i32 ptrtoint (ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), ptr null }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,9 +120,10 @@ declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{b
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, ptr %itf.value, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr %itf.value, i32 %itf.typecode, ptr undef) #6
|
%0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr %itf.value, i32 %itf.typecode, ptr undef) #6
|
||||||
%1 = extractvalue %runtime._string %0, 0
|
%1 = extractvalue %runtime._string %0, 0
|
||||||
call void @runtime.trackPointer(ptr %1, ptr undef) #6
|
call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #6
|
||||||
ret %runtime._string %0
|
ret %runtime._string %0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
compiler/testdata/pointer.ll
предоставленный
32
compiler/testdata/pointer.ll
предоставленный
|
@ -5,7 +5,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
@ -22,52 +22,58 @@ entry:
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.pointerCastFromUnsafe(ptr %x, ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.pointerCastFromUnsafe(ptr %x, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr %x, ptr undef) #2
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %x
|
ret ptr %x
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.pointerCastToUnsafe(ptr dereferenceable_or_null(4) %x, ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.pointerCastToUnsafe(ptr dereferenceable_or_null(4) %x, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr %x, ptr undef) #2
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %x
|
ret ptr %x
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.pointerCastToUnsafeNoop(ptr dereferenceable_or_null(1) %x, ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.pointerCastToUnsafeNoop(ptr dereferenceable_or_null(1) %x, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr %x, ptr undef) #2
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr %x, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %x
|
ret ptr %x
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.pointerUnsafeGEPFixedOffset(ptr dereferenceable_or_null(1) %ptr, ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.pointerUnsafeGEPFixedOffset(ptr dereferenceable_or_null(1) %ptr, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
%0 = getelementptr inbounds i8, ptr %ptr, i32 10
|
%0 = getelementptr inbounds i8, ptr %ptr, i32 10
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %0
|
ret ptr %0
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.pointerUnsafeGEPByteOffset(ptr dereferenceable_or_null(1) %ptr, i32 %offset, ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.pointerUnsafeGEPByteOffset(ptr dereferenceable_or_null(1) %ptr, i32 %offset, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
%0 = getelementptr inbounds i8, ptr %ptr, i32 %offset
|
%0 = getelementptr inbounds i8, ptr %ptr, i32 %offset
|
||||||
call void @runtime.trackPointer(ptr %0, ptr undef) #2
|
call void @runtime.trackPointer(ptr %0, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr %0, ptr undef) #2
|
call void @runtime.trackPointer(ptr %0, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %0
|
ret ptr %0
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.pointerUnsafeGEPIntOffset(ptr dereferenceable_or_null(4) %ptr, i32 %offset, ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.pointerUnsafeGEPIntOffset(ptr dereferenceable_or_null(4) %ptr, i32 %offset, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
%stackalloc = alloca i8, align 1
|
||||||
|
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
%0 = shl i32 %offset, 2
|
%0 = shl i32 %offset, 2
|
||||||
%1 = getelementptr inbounds i8, ptr %ptr, i32 %0
|
%1 = getelementptr inbounds i8, ptr %ptr, i32 %0
|
||||||
call void @runtime.trackPointer(ptr %1, ptr undef) #2
|
call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr %1, ptr undef) #2
|
call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %1
|
ret ptr %1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
compiler/testdata/pragma.ll
предоставленный
2
compiler/testdata/pragma.ll
предоставленный
|
@ -12,7 +12,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
|
43
compiler/testdata/slice.ll
предоставленный
43
compiler/testdata/slice.ll
предоставленный
|
@ -5,7 +5,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
@ -46,8 +46,9 @@ declare void @runtime.lookupPanic(ptr) #0
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden { ptr, i32, i32 } @main.sliceAppendValues(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 {
|
define hidden { ptr, i32, i32 } @main.sliceAppendValues(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%varargs = call ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%varargs = call ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %varargs, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %varargs, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
store i32 1, ptr %varargs, align 4
|
store i32 1, ptr %varargs, align 4
|
||||||
%0 = getelementptr inbounds [3 x i32], ptr %varargs, i32 0, i32 1
|
%0 = getelementptr inbounds [3 x i32], ptr %varargs, i32 0, i32 1
|
||||||
store i32 2, ptr %0, align 4
|
store i32 2, ptr %0, align 4
|
||||||
|
@ -60,7 +61,7 @@ entry:
|
||||||
%2 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0
|
%2 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0
|
||||||
%3 = insertvalue { ptr, i32, i32 } %2, i32 %append.newLen, 1
|
%3 = insertvalue { ptr, i32, i32 } %2, i32 %append.newLen, 1
|
||||||
%4 = insertvalue { ptr, i32, i32 } %3, i32 %append.newCap, 2
|
%4 = insertvalue { ptr, i32, i32 } %3, i32 %append.newCap, 2
|
||||||
call void @runtime.trackPointer(ptr %append.newPtr, ptr undef) #2
|
call void @runtime.trackPointer(ptr %append.newPtr, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret { ptr, i32, i32 } %4
|
ret { ptr, i32, i32 } %4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +70,7 @@ declare { ptr, i32, i32 } @runtime.sliceAppend(ptr, ptr nocapture readonly, i32,
|
||||||
; Function Attrs: nounwind
|
; 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 #1 {
|
define hidden { ptr, i32, i32 } @main.sliceAppendSlice(ptr %ints.data, i32 %ints.len, i32 %ints.cap, ptr %added.data, i32 %added.len, i32 %added.cap, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
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 undef) #2
|
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr %added.data, i32 %ints.len, i32 %ints.cap, i32 %added.len, i32 4, ptr undef) #2
|
||||||
%append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0
|
%append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0
|
||||||
%append.newLen = extractvalue { ptr, i32, i32 } %append.new, 1
|
%append.newLen = extractvalue { ptr, i32, i32 } %append.new, 1
|
||||||
|
@ -76,7 +78,7 @@ entry:
|
||||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0
|
%0 = insertvalue { ptr, i32, i32 } undef, ptr %append.newPtr, 0
|
||||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %append.newLen, 1
|
%1 = insertvalue { ptr, i32, i32 } %0, i32 %append.newLen, 1
|
||||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %append.newCap, 2
|
%2 = insertvalue { ptr, i32, i32 } %1, i32 %append.newCap, 2
|
||||||
call void @runtime.trackPointer(ptr %append.newPtr, ptr undef) #2
|
call void @runtime.trackPointer(ptr %append.newPtr, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret { ptr, i32, i32 } %2
|
ret { ptr, i32, i32 } %2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +94,7 @@ declare i32 @runtime.sliceCopy(ptr nocapture writeonly, ptr nocapture readonly,
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden { ptr, i32, i32 } @main.makeByteSlice(i32 %len, ptr %context) unnamed_addr #1 {
|
define hidden { ptr, i32, i32 } @main.makeByteSlice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%slice.maxcap = icmp slt i32 %len, 0
|
%slice.maxcap = icmp slt i32 %len, 0
|
||||||
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
||||||
|
|
||||||
|
@ -100,7 +103,7 @@ slice.next: ; preds = %entry
|
||||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret { ptr, i32, i32 } %2
|
ret { ptr, i32, i32 } %2
|
||||||
|
|
||||||
slice.throw: ; preds = %entry
|
slice.throw: ; preds = %entry
|
||||||
|
@ -113,6 +116,7 @@ declare void @runtime.slicePanic(ptr) #0
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden { ptr, i32, i32 } @main.makeInt16Slice(i32 %len, ptr %context) unnamed_addr #1 {
|
define hidden { ptr, i32, i32 } @main.makeInt16Slice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%slice.maxcap = icmp slt i32 %len, 0
|
%slice.maxcap = icmp slt i32 %len, 0
|
||||||
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
||||||
|
|
||||||
|
@ -122,7 +126,7 @@ slice.next: ; preds = %entry
|
||||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret { ptr, i32, i32 } %2
|
ret { ptr, i32, i32 } %2
|
||||||
|
|
||||||
slice.throw: ; preds = %entry
|
slice.throw: ; preds = %entry
|
||||||
|
@ -133,6 +137,7 @@ slice.throw: ; preds = %entry
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden { ptr, i32, i32 } @main.makeArraySlice(i32 %len, ptr %context) unnamed_addr #1 {
|
define hidden { ptr, i32, i32 } @main.makeArraySlice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%slice.maxcap = icmp ugt i32 %len, 1431655765
|
%slice.maxcap = icmp ugt i32 %len, 1431655765
|
||||||
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
||||||
|
|
||||||
|
@ -142,7 +147,7 @@ slice.next: ; preds = %entry
|
||||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret { ptr, i32, i32 } %2
|
ret { ptr, i32, i32 } %2
|
||||||
|
|
||||||
slice.throw: ; preds = %entry
|
slice.throw: ; preds = %entry
|
||||||
|
@ -153,6 +158,7 @@ slice.throw: ; preds = %entry
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden { ptr, i32, i32 } @main.makeInt32Slice(i32 %len, ptr %context) unnamed_addr #1 {
|
define hidden { ptr, i32, i32 } @main.makeInt32Slice(i32 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%slice.maxcap = icmp ugt i32 %len, 1073741823
|
%slice.maxcap = icmp ugt i32 %len, 1073741823
|
||||||
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
||||||
|
|
||||||
|
@ -162,7 +168,7 @@ slice.next: ; preds = %entry
|
||||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||||
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
%2 = insertvalue { ptr, i32, i32 } %1, i32 %len, 2
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %makeslice.buf, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret { ptr, i32, i32 } %2
|
ret { ptr, i32, i32 } %2
|
||||||
|
|
||||||
slice.throw: ; preds = %entry
|
slice.throw: ; preds = %entry
|
||||||
|
@ -173,17 +179,19 @@ slice.throw: ; preds = %entry
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.Add32(ptr %p, i32 %len, ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.Add32(ptr %p, i32 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = getelementptr i8, ptr %p, i32 %len
|
%0 = getelementptr i8, ptr %p, i32 %len
|
||||||
call void @runtime.trackPointer(ptr %0, ptr undef) #2
|
call void @runtime.trackPointer(ptr %0, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %0
|
ret ptr %0
|
||||||
}
|
}
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.Add64(ptr %p, i64 %len, ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.Add64(ptr %p, i64 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = trunc i64 %len to i32
|
%0 = trunc i64 %len to i32
|
||||||
%1 = getelementptr i8, ptr %p, i32 %0
|
%1 = getelementptr i8, ptr %p, i32 %0
|
||||||
call void @runtime.trackPointer(ptr %1, ptr undef) #2
|
call void @runtime.trackPointer(ptr %1, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret ptr %1
|
ret ptr %1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,8 +214,9 @@ declare void @runtime.sliceToArrayPointerPanic(ptr) #0
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden ptr @main.SliceToArrayConst(ptr %context) unnamed_addr #1 {
|
define hidden ptr @main.SliceToArrayConst(ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%makeslice = call ptr @runtime.alloc(i32 24, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
%makeslice = call ptr @runtime.alloc(i32 24, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #2
|
||||||
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr undef) #2
|
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
br i1 false, label %slicetoarray.throw, label %slicetoarray.next
|
br i1 false, label %slicetoarray.throw, label %slicetoarray.next
|
||||||
|
|
||||||
slicetoarray.next: ; preds = %entry
|
slicetoarray.next: ; preds = %entry
|
||||||
|
@ -220,6 +229,7 @@ slicetoarray.throw: ; preds = %entry
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden { ptr, i32, i32 } @main.SliceInt(ptr dereferenceable_or_null(4) %ptr, i32 %len, ptr %context) unnamed_addr #1 {
|
define hidden { ptr, i32, i32 } @main.SliceInt(ptr dereferenceable_or_null(4) %ptr, i32 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = icmp ugt i32 %len, 1073741823
|
%0 = icmp ugt i32 %len, 1073741823
|
||||||
%1 = icmp eq ptr %ptr, null
|
%1 = icmp eq ptr %ptr, null
|
||||||
%2 = icmp ne i32 %len, 0
|
%2 = icmp ne i32 %len, 0
|
||||||
|
@ -231,7 +241,7 @@ unsafe.Slice.next: ; preds = %entry
|
||||||
%5 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
%5 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||||
%6 = insertvalue { ptr, i32, i32 } %5, i32 %len, 1
|
%6 = insertvalue { ptr, i32, i32 } %5, i32 %len, 1
|
||||||
%7 = insertvalue { ptr, i32, i32 } %6, i32 %len, 2
|
%7 = insertvalue { ptr, i32, i32 } %6, i32 %len, 2
|
||||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret { ptr, i32, i32 } %7
|
ret { ptr, i32, i32 } %7
|
||||||
|
|
||||||
unsafe.Slice.throw: ; preds = %entry
|
unsafe.Slice.throw: ; preds = %entry
|
||||||
|
@ -244,6 +254,7 @@ declare void @runtime.unsafeSlicePanic(ptr) #0
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden { ptr, i32, i32 } @main.SliceUint16(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 {
|
define hidden { ptr, i32, i32 } @main.SliceUint16(ptr dereferenceable_or_null(1) %ptr, i16 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = icmp eq ptr %ptr, null
|
%0 = icmp eq ptr %ptr, null
|
||||||
%1 = icmp ne i16 %len, 0
|
%1 = icmp ne i16 %len, 0
|
||||||
%2 = and i1 %0, %1
|
%2 = and i1 %0, %1
|
||||||
|
@ -254,7 +265,7 @@ unsafe.Slice.next: ; preds = %entry
|
||||||
%4 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
%4 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||||
%5 = insertvalue { ptr, i32, i32 } %4, i32 %3, 1
|
%5 = insertvalue { ptr, i32, i32 } %4, i32 %3, 1
|
||||||
%6 = insertvalue { ptr, i32, i32 } %5, i32 %3, 2
|
%6 = insertvalue { ptr, i32, i32 } %5, i32 %3, 2
|
||||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret { ptr, i32, i32 } %6
|
ret { ptr, i32, i32 } %6
|
||||||
|
|
||||||
unsafe.Slice.throw: ; preds = %entry
|
unsafe.Slice.throw: ; preds = %entry
|
||||||
|
@ -265,6 +276,7 @@ unsafe.Slice.throw: ; preds = %entry
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden { ptr, i32, i32 } @main.SliceUint64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 {
|
define hidden { ptr, i32, i32 } @main.SliceUint64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = icmp ugt i64 %len, 1073741823
|
%0 = icmp ugt i64 %len, 1073741823
|
||||||
%1 = icmp eq ptr %ptr, null
|
%1 = icmp eq ptr %ptr, null
|
||||||
%2 = icmp ne i64 %len, 0
|
%2 = icmp ne i64 %len, 0
|
||||||
|
@ -277,7 +289,7 @@ unsafe.Slice.next: ; preds = %entry
|
||||||
%6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
%6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||||
%7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1
|
%7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1
|
||||||
%8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2
|
%8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2
|
||||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret { ptr, i32, i32 } %8
|
ret { ptr, i32, i32 } %8
|
||||||
|
|
||||||
unsafe.Slice.throw: ; preds = %entry
|
unsafe.Slice.throw: ; preds = %entry
|
||||||
|
@ -288,6 +300,7 @@ unsafe.Slice.throw: ; preds = %entry
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden { ptr, i32, i32 } @main.SliceInt64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 {
|
define hidden { ptr, i32, i32 } @main.SliceInt64(ptr dereferenceable_or_null(4) %ptr, i64 %len, ptr %context) unnamed_addr #1 {
|
||||||
entry:
|
entry:
|
||||||
|
%stackalloc = alloca i8, align 1
|
||||||
%0 = icmp ugt i64 %len, 1073741823
|
%0 = icmp ugt i64 %len, 1073741823
|
||||||
%1 = icmp eq ptr %ptr, null
|
%1 = icmp eq ptr %ptr, null
|
||||||
%2 = icmp ne i64 %len, 0
|
%2 = icmp ne i64 %len, 0
|
||||||
|
@ -300,7 +313,7 @@ unsafe.Slice.next: ; preds = %entry
|
||||||
%6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
%6 = insertvalue { ptr, i32, i32 } undef, ptr %ptr, 0
|
||||||
%7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1
|
%7 = insertvalue { ptr, i32, i32 } %6, i32 %5, 1
|
||||||
%8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2
|
%8 = insertvalue { ptr, i32, i32 } %7, i32 %5, 2
|
||||||
call void @runtime.trackPointer(ptr %ptr, ptr undef) #2
|
call void @runtime.trackPointer(ptr %ptr, ptr nonnull %stackalloc, ptr undef) #2
|
||||||
ret { ptr, i32, i32 } %8
|
ret { ptr, i32, i32 } %8
|
||||||
|
|
||||||
unsafe.Slice.throw: ; preds = %entry
|
unsafe.Slice.throw: ; preds = %entry
|
||||||
|
|
2
compiler/testdata/string.ll
предоставленный
2
compiler/testdata/string.ll
предоставленный
|
@ -9,7 +9,7 @@ target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||||
|
|
||||||
declare void @runtime.trackPointer(ptr nocapture readonly, ptr) #0
|
declare void @runtime.trackPointer(ptr nocapture readonly, ptr, ptr) #0
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
define hidden void @main.init(ptr %context) unnamed_addr #1 {
|
||||||
|
|
|
@ -53,7 +53,7 @@ func markStack() {
|
||||||
// trackPointer is a stub function call inserted by the compiler during IR
|
// trackPointer is a stub function call inserted by the compiler during IR
|
||||||
// construction. Calls to it are later replaced with regular stack bookkeeping
|
// construction. Calls to it are later replaced with regular stack bookkeeping
|
||||||
// code.
|
// code.
|
||||||
func trackPointer(ptr unsafe.Pointer)
|
func trackPointer(ptr, alloca unsafe.Pointer)
|
||||||
|
|
||||||
// swapStackChain swaps the stack chain.
|
// swapStackChain swaps the stack chain.
|
||||||
// This is called from internal/task when switching goroutines.
|
// This is called from internal/task when switching goroutines.
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче