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  }