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 }