github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/compiler/testdata/defer-cortex-m-qemu.ll (about) 1 ; ModuleID = 'defer.go' 2 source_filename = "defer.go" 3 target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" 4 target triple = "thumbv7m-unknown-unknown-eabi" 5 6 %runtime.deferFrame = type { ptr, ptr, [0 x ptr], ptr, i1, %runtime._interface } 7 %runtime._interface = type { ptr, ptr } 8 %runtime._defer = type { i32, ptr } 9 10 ; Function Attrs: allockind("alloc,zeroed") allocsize(0) 11 declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0 12 13 ; Function Attrs: nounwind 14 define hidden void @main.init(ptr %context) unnamed_addr #1 { 15 entry: 16 ret void 17 } 18 19 declare void @main.external(ptr) #2 20 21 ; Function Attrs: nounwind 22 define hidden void @main.deferSimple(ptr %context) unnamed_addr #1 { 23 entry: 24 %defer.alloca = alloca { i32, ptr }, align 4 25 %deferPtr = alloca ptr, align 4 26 store ptr null, ptr %deferPtr, align 4 27 %deferframe.buf = alloca %runtime.deferFrame, align 4 28 %0 = call ptr @llvm.stacksave() 29 call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4 30 store i32 0, ptr %defer.alloca, align 4 31 %defer.alloca.repack15 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1 32 store ptr null, ptr %defer.alloca.repack15, align 4 33 store ptr %defer.alloca, ptr %deferPtr, align 4 34 %setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5 35 %setjmp.result = icmp eq i32 %setjmp, 0 36 br i1 %setjmp.result, label %1, label %lpad 37 38 1: ; preds = %entry 39 call void @main.external(ptr undef) #4 40 br label %rundefers.block 41 42 rundefers.after: ; preds = %rundefers.end 43 call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #4 44 ret void 45 46 rundefers.block: ; preds = %1 47 br label %rundefers.loophead 48 49 rundefers.loophead: ; preds = %3, %rundefers.block 50 %2 = load ptr, ptr %deferPtr, align 4 51 %stackIsNil = icmp eq ptr %2, null 52 br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop 53 54 rundefers.loop: ; preds = %rundefers.loophead 55 %stack.next.gep = getelementptr inbounds %runtime._defer, ptr %2, i32 0, i32 1 56 %stack.next = load ptr, ptr %stack.next.gep, align 4 57 store ptr %stack.next, ptr %deferPtr, align 4 58 %callback = load i32, ptr %2, align 4 59 switch i32 %callback, label %rundefers.default [ 60 i32 0, label %rundefers.callback0 61 ] 62 63 rundefers.callback0: ; preds = %rundefers.loop 64 %setjmp1 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5 65 %setjmp.result2 = icmp eq i32 %setjmp1, 0 66 br i1 %setjmp.result2, label %3, label %lpad 67 68 3: ; preds = %rundefers.callback0 69 call void @"main.deferSimple$1"(ptr undef) 70 br label %rundefers.loophead 71 72 rundefers.default: ; preds = %rundefers.loop 73 unreachable 74 75 rundefers.end: ; preds = %rundefers.loophead 76 br label %rundefers.after 77 78 recover: ; preds = %rundefers.end3 79 call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #4 80 ret void 81 82 lpad: ; preds = %rundefers.callback012, %rundefers.callback0, %entry 83 br label %rundefers.loophead6 84 85 rundefers.loophead6: ; preds = %5, %lpad 86 %4 = load ptr, ptr %deferPtr, align 4 87 %stackIsNil7 = icmp eq ptr %4, null 88 br i1 %stackIsNil7, label %rundefers.end3, label %rundefers.loop5 89 90 rundefers.loop5: ; preds = %rundefers.loophead6 91 %stack.next.gep8 = getelementptr inbounds %runtime._defer, ptr %4, i32 0, i32 1 92 %stack.next9 = load ptr, ptr %stack.next.gep8, align 4 93 store ptr %stack.next9, ptr %deferPtr, align 4 94 %callback11 = load i32, ptr %4, align 4 95 switch i32 %callback11, label %rundefers.default4 [ 96 i32 0, label %rundefers.callback012 97 ] 98 99 rundefers.callback012: ; preds = %rundefers.loop5 100 %setjmp13 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5 101 %setjmp.result14 = icmp eq i32 %setjmp13, 0 102 br i1 %setjmp.result14, label %5, label %lpad 103 104 5: ; preds = %rundefers.callback012 105 call void @"main.deferSimple$1"(ptr undef) 106 br label %rundefers.loophead6 107 108 rundefers.default4: ; preds = %rundefers.loop5 109 unreachable 110 111 rundefers.end3: ; preds = %rundefers.loophead6 112 br label %recover 113 } 114 115 ; Function Attrs: nocallback nofree nosync nounwind willreturn 116 declare ptr @llvm.stacksave() #3 117 118 declare void @runtime.setupDeferFrame(ptr dereferenceable_or_null(24), ptr, ptr) #2 119 120 declare void @runtime.destroyDeferFrame(ptr dereferenceable_or_null(24), ptr) #2 121 122 ; Function Attrs: nounwind 123 define internal void @"main.deferSimple$1"(ptr %context) unnamed_addr #1 { 124 entry: 125 call void @runtime.printint32(i32 3, ptr undef) #4 126 ret void 127 } 128 129 declare void @runtime.printint32(i32, ptr) #2 130 131 ; Function Attrs: nounwind 132 define hidden void @main.deferMultiple(ptr %context) unnamed_addr #1 { 133 entry: 134 %defer.alloca2 = alloca { i32, ptr }, align 4 135 %defer.alloca = alloca { i32, ptr }, align 4 136 %deferPtr = alloca ptr, align 4 137 store ptr null, ptr %deferPtr, align 4 138 %deferframe.buf = alloca %runtime.deferFrame, align 4 139 %0 = call ptr @llvm.stacksave() 140 call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4 141 store i32 0, ptr %defer.alloca, align 4 142 %defer.alloca.repack22 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1 143 store ptr null, ptr %defer.alloca.repack22, align 4 144 store ptr %defer.alloca, ptr %deferPtr, align 4 145 store i32 1, ptr %defer.alloca2, align 4 146 %defer.alloca2.repack23 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca2, i32 0, i32 1 147 store ptr %defer.alloca, ptr %defer.alloca2.repack23, align 4 148 store ptr %defer.alloca2, ptr %deferPtr, align 4 149 %setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5 150 %setjmp.result = icmp eq i32 %setjmp, 0 151 br i1 %setjmp.result, label %1, label %lpad 152 153 1: ; preds = %entry 154 call void @main.external(ptr undef) #4 155 br label %rundefers.block 156 157 rundefers.after: ; preds = %rundefers.end 158 call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #4 159 ret void 160 161 rundefers.block: ; preds = %1 162 br label %rundefers.loophead 163 164 rundefers.loophead: ; preds = %4, %3, %rundefers.block 165 %2 = load ptr, ptr %deferPtr, align 4 166 %stackIsNil = icmp eq ptr %2, null 167 br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop 168 169 rundefers.loop: ; preds = %rundefers.loophead 170 %stack.next.gep = getelementptr inbounds %runtime._defer, ptr %2, i32 0, i32 1 171 %stack.next = load ptr, ptr %stack.next.gep, align 4 172 store ptr %stack.next, ptr %deferPtr, align 4 173 %callback = load i32, ptr %2, align 4 174 switch i32 %callback, label %rundefers.default [ 175 i32 0, label %rundefers.callback0 176 i32 1, label %rundefers.callback1 177 ] 178 179 rundefers.callback0: ; preds = %rundefers.loop 180 %setjmp3 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5 181 %setjmp.result4 = icmp eq i32 %setjmp3, 0 182 br i1 %setjmp.result4, label %3, label %lpad 183 184 3: ; preds = %rundefers.callback0 185 call void @"main.deferMultiple$1"(ptr undef) 186 br label %rundefers.loophead 187 188 rundefers.callback1: ; preds = %rundefers.loop 189 %setjmp5 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5 190 %setjmp.result6 = icmp eq i32 %setjmp5, 0 191 br i1 %setjmp.result6, label %4, label %lpad 192 193 4: ; preds = %rundefers.callback1 194 call void @"main.deferMultiple$2"(ptr undef) 195 br label %rundefers.loophead 196 197 rundefers.default: ; preds = %rundefers.loop 198 unreachable 199 200 rundefers.end: ; preds = %rundefers.loophead 201 br label %rundefers.after 202 203 recover: ; preds = %rundefers.end7 204 call void @runtime.destroyDeferFrame(ptr nonnull %deferframe.buf, ptr undef) #4 205 ret void 206 207 lpad: ; preds = %rundefers.callback119, %rundefers.callback016, %rundefers.callback1, %rundefers.callback0, %entry 208 br label %rundefers.loophead10 209 210 rundefers.loophead10: ; preds = %7, %6, %lpad 211 %5 = load ptr, ptr %deferPtr, align 4 212 %stackIsNil11 = icmp eq ptr %5, null 213 br i1 %stackIsNil11, label %rundefers.end7, label %rundefers.loop9 214 215 rundefers.loop9: ; preds = %rundefers.loophead10 216 %stack.next.gep12 = getelementptr inbounds %runtime._defer, ptr %5, i32 0, i32 1 217 %stack.next13 = load ptr, ptr %stack.next.gep12, align 4 218 store ptr %stack.next13, ptr %deferPtr, align 4 219 %callback15 = load i32, ptr %5, align 4 220 switch i32 %callback15, label %rundefers.default8 [ 221 i32 0, label %rundefers.callback016 222 i32 1, label %rundefers.callback119 223 ] 224 225 rundefers.callback016: ; preds = %rundefers.loop9 226 %setjmp17 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5 227 %setjmp.result18 = icmp eq i32 %setjmp17, 0 228 br i1 %setjmp.result18, label %6, label %lpad 229 230 6: ; preds = %rundefers.callback016 231 call void @"main.deferMultiple$1"(ptr undef) 232 br label %rundefers.loophead10 233 234 rundefers.callback119: ; preds = %rundefers.loop9 235 %setjmp20 = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5 236 %setjmp.result21 = icmp eq i32 %setjmp20, 0 237 br i1 %setjmp.result21, label %7, label %lpad 238 239 7: ; preds = %rundefers.callback119 240 call void @"main.deferMultiple$2"(ptr undef) 241 br label %rundefers.loophead10 242 243 rundefers.default8: ; preds = %rundefers.loop9 244 unreachable 245 246 rundefers.end7: ; preds = %rundefers.loophead10 247 br label %recover 248 } 249 250 ; Function Attrs: nounwind 251 define internal void @"main.deferMultiple$1"(ptr %context) unnamed_addr #1 { 252 entry: 253 call void @runtime.printint32(i32 3, ptr undef) #4 254 ret void 255 } 256 257 ; Function Attrs: nounwind 258 define internal void @"main.deferMultiple$2"(ptr %context) unnamed_addr #1 { 259 entry: 260 call void @runtime.printint32(i32 5, ptr undef) #4 261 ret void 262 } 263 264 attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } 265 attributes #1 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } 266 attributes #2 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } 267 attributes #3 = { nocallback nofree nosync nounwind willreturn } 268 attributes #4 = { nounwind } 269 attributes #5 = { nounwind returns_twice }