github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/transform/testdata/gc-stackslots.out.ll (about) 1 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 2 target triple = "wasm32-unknown-unknown-wasm" 3 4 @runtime.stackChainStart = internal global ptr null 5 @someGlobal = global i8 3 6 @ptrGlobal = global ptr null 7 8 declare void @runtime.trackPointer(ptr nocapture readonly) 9 10 declare noalias nonnull ptr @runtime.alloc(i32, ptr) 11 12 define ptr @getPointer() { 13 ret ptr @someGlobal 14 } 15 16 define ptr @needsStackSlots() { 17 %gc.stackobject = alloca { ptr, i32, ptr }, align 8 18 store { ptr, i32, ptr } { ptr null, i32 1, ptr null }, ptr %gc.stackobject, align 4 19 %1 = load ptr, ptr @runtime.stackChainStart, align 4 20 %2 = getelementptr { ptr, i32, ptr }, ptr %gc.stackobject, i32 0, i32 0 21 store ptr %1, ptr %2, align 4 22 store ptr %gc.stackobject, ptr @runtime.stackChainStart, align 4 23 %ptr = call ptr @runtime.alloc(i32 4, ptr null) 24 %3 = getelementptr { ptr, i32, ptr }, ptr %gc.stackobject, i32 0, i32 2 25 store ptr %ptr, ptr %3, align 4 26 call void @someArbitraryFunction() 27 %val = load i8, ptr @someGlobal, align 1 28 store ptr %1, ptr @runtime.stackChainStart, align 4 29 ret ptr %ptr 30 } 31 32 define ptr @needsStackSlots2() { 33 %gc.stackobject = alloca { ptr, i32, ptr, ptr, ptr, ptr, ptr }, align 8 34 store { ptr, i32, ptr, ptr, ptr, ptr, ptr } { ptr null, i32 5, ptr null, ptr null, ptr null, ptr null, ptr null }, ptr %gc.stackobject, align 4 35 %1 = load ptr, ptr @runtime.stackChainStart, align 4 36 %2 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 0 37 store ptr %1, ptr %2, align 4 38 store ptr %gc.stackobject, ptr @runtime.stackChainStart, align 4 39 %ptr1 = call ptr @getPointer() 40 %3 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 4 41 store ptr %ptr1, ptr %3, align 4 42 %4 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 3 43 store ptr %ptr1, ptr %4, align 4 44 %5 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 2 45 store ptr %ptr1, ptr %5, align 4 46 %ptr2 = getelementptr i8, ptr @someGlobal, i32 0 47 %6 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 5 48 store ptr %ptr2, ptr %6, align 4 49 %unused = call ptr @runtime.alloc(i32 4, ptr null) 50 %7 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 6 51 store ptr %unused, ptr %7, align 4 52 store ptr %1, ptr @runtime.stackChainStart, align 4 53 ret ptr %ptr1 54 } 55 56 define ptr @noAllocatingFunction() { 57 %ptr = call ptr @getPointer() 58 ret ptr %ptr 59 } 60 61 define ptr @fibNext(ptr %x, ptr %y) { 62 %gc.stackobject = alloca { ptr, i32, ptr }, align 8 63 store { ptr, i32, ptr } { ptr null, i32 1, ptr null }, ptr %gc.stackobject, align 4 64 %1 = load ptr, ptr @runtime.stackChainStart, align 4 65 %2 = getelementptr { ptr, i32, ptr }, ptr %gc.stackobject, i32 0, i32 0 66 store ptr %1, ptr %2, align 4 67 store ptr %gc.stackobject, ptr @runtime.stackChainStart, align 4 68 %x.val = load i8, ptr %x, align 1 69 %y.val = load i8, ptr %y, align 1 70 %out.val = add i8 %x.val, %y.val 71 %out.alloc = call ptr @runtime.alloc(i32 1, ptr null) 72 %3 = getelementptr { ptr, i32, ptr }, ptr %gc.stackobject, i32 0, i32 2 73 store ptr %out.alloc, ptr %3, align 4 74 store i8 %out.val, ptr %out.alloc, align 1 75 store ptr %1, ptr @runtime.stackChainStart, align 4 76 ret ptr %out.alloc 77 } 78 79 define ptr @allocLoop() { 80 entry: 81 %gc.stackobject = alloca { ptr, i32, ptr, ptr, ptr, ptr, ptr }, align 8 82 store { ptr, i32, ptr, ptr, ptr, ptr, ptr } { ptr null, i32 5, ptr null, ptr null, ptr null, ptr null, ptr null }, ptr %gc.stackobject, align 4 83 %0 = load ptr, ptr @runtime.stackChainStart, align 4 84 %1 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 0 85 store ptr %0, ptr %1, align 4 86 store ptr %gc.stackobject, ptr @runtime.stackChainStart, align 4 87 %entry.x = call ptr @runtime.alloc(i32 1, ptr null) 88 %2 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 2 89 store ptr %entry.x, ptr %2, align 4 90 %entry.y = call ptr @runtime.alloc(i32 1, ptr null) 91 %3 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 3 92 store ptr %entry.y, ptr %3, align 4 93 store i8 1, ptr %entry.y, align 1 94 br label %loop 95 96 loop: ; preds = %loop, %entry 97 %prev.y = phi ptr [ %entry.y, %entry ], [ %prev.x, %loop ] 98 %prev.x = phi ptr [ %entry.x, %entry ], [ %next.x, %loop ] 99 %4 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 5 100 store ptr %prev.y, ptr %4, align 4 101 %5 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 4 102 store ptr %prev.x, ptr %5, align 4 103 %next.x = call ptr @fibNext(ptr %prev.x, ptr %prev.y) 104 %6 = getelementptr { ptr, i32, ptr, ptr, ptr, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 6 105 store ptr %next.x, ptr %6, align 4 106 %next.x.val = load i8, ptr %next.x, align 1 107 %loop.done = icmp ult i8 40, %next.x.val 108 br i1 %loop.done, label %end, label %loop 109 110 end: ; preds = %loop 111 store ptr %0, ptr @runtime.stackChainStart, align 4 112 ret ptr %next.x 113 } 114 115 declare ptr @arrayAlloc() 116 117 define void @testGEPBitcast() { 118 %gc.stackobject = alloca { ptr, i32, ptr, ptr }, align 8 119 store { ptr, i32, ptr, ptr } { ptr null, i32 2, ptr null, ptr null }, ptr %gc.stackobject, align 4 120 %1 = load ptr, ptr @runtime.stackChainStart, align 4 121 %2 = getelementptr { ptr, i32, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 0 122 store ptr %1, ptr %2, align 4 123 store ptr %gc.stackobject, ptr @runtime.stackChainStart, align 4 124 %arr = call ptr @arrayAlloc() 125 %arr.bitcast = getelementptr [32 x i8], ptr %arr, i32 0, i32 0 126 %3 = getelementptr { ptr, i32, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 2 127 store ptr %arr.bitcast, ptr %3, align 4 128 %other = call ptr @runtime.alloc(i32 1, ptr null) 129 %4 = getelementptr { ptr, i32, ptr, ptr }, ptr %gc.stackobject, i32 0, i32 3 130 store ptr %other, ptr %4, align 4 131 store ptr %1, ptr @runtime.stackChainStart, align 4 132 ret void 133 } 134 135 define void @someArbitraryFunction() { 136 ret void 137 } 138 139 define void @earlyPopRegression() { 140 %gc.stackobject = alloca { ptr, i32, ptr }, align 8 141 store { ptr, i32, ptr } { ptr null, i32 1, ptr null }, ptr %gc.stackobject, align 4 142 %1 = load ptr, ptr @runtime.stackChainStart, align 4 143 %2 = getelementptr { ptr, i32, ptr }, ptr %gc.stackobject, i32 0, i32 0 144 store ptr %1, ptr %2, align 4 145 store ptr %gc.stackobject, ptr @runtime.stackChainStart, align 4 146 %x.alloc = call ptr @runtime.alloc(i32 4, ptr null) 147 %3 = getelementptr { ptr, i32, ptr }, ptr %gc.stackobject, i32 0, i32 2 148 store ptr %x.alloc, ptr %3, align 4 149 call void @allocAndSave(ptr %x.alloc) 150 store ptr %1, ptr @runtime.stackChainStart, align 4 151 ret void 152 } 153 154 define void @allocAndSave(ptr %x) { 155 %gc.stackobject = alloca { ptr, i32, ptr }, align 8 156 store { ptr, i32, ptr } { ptr null, i32 1, ptr null }, ptr %gc.stackobject, align 4 157 %1 = load ptr, ptr @runtime.stackChainStart, align 4 158 %2 = getelementptr { ptr, i32, ptr }, ptr %gc.stackobject, i32 0, i32 0 159 store ptr %1, ptr %2, align 4 160 store ptr %gc.stackobject, ptr @runtime.stackChainStart, align 4 161 %y = call ptr @runtime.alloc(i32 4, ptr null) 162 %3 = getelementptr { ptr, i32, ptr }, ptr %gc.stackobject, i32 0, i32 2 163 store ptr %y, ptr %3, align 4 164 store ptr %y, ptr %x, align 4 165 store ptr %x, ptr @ptrGlobal, align 4 166 store ptr %1, ptr @runtime.stackChainStart, align 4 167 ret void 168 }