github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/interp/testdata/basic.ll (about)

     1  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
     2  target triple = "x86_64--linux"
     3  
     4  @main.v1 = internal global i64 0
     5  @main.nonConst1 = global [4 x i64] zeroinitializer
     6  @main.nonConst2 = global i64 0
     7  @main.someArray = global [8 x {i16, i32}] zeroinitializer
     8  @main.exportedValue = global [1 x ptr] [ptr @main.exposedValue1]
     9  @main.exportedConst = constant i64 42
    10  @main.exposedValue1 = global i16 0
    11  @main.exposedValue2 = global i16 0
    12  @main.insertedValue = global {i8, i32, {float, {i64, i16}}} zeroinitializer
    13  @main.gepArray = global [8 x i8] zeroinitializer
    14  @main.negativeGEP = global ptr null
    15  
    16  declare void @runtime.printint64(i64) unnamed_addr
    17  
    18  declare void @runtime.printnl() unnamed_addr
    19  
    20  define void @runtime.initAll() unnamed_addr {
    21  entry:
    22    call void @runtime.init()
    23    call void @main.init()
    24    ret void
    25  }
    26  
    27  define void @main() unnamed_addr {
    28  entry:
    29    %0 = load i64, ptr @main.v1
    30    call void @runtime.printint64(i64 %0)
    31    call void @runtime.printnl()
    32    ret void
    33  }
    34  
    35  define internal void @runtime.init() unnamed_addr {
    36  entry:
    37    ret void
    38  }
    39  
    40  define internal void @main.init() unnamed_addr {
    41  entry:
    42    store i64 3, ptr @main.v1
    43    call void @"main.init#1"()
    44  
    45    ; test the following pattern:
    46    ;     func someValue() int // extern function
    47    ;     var nonConst1 = [4]int{someValue(), 0, 0, 0}
    48    %value1 = call i64 @someValue()
    49    %gep1 = getelementptr [4 x i64], ptr @main.nonConst1, i32 0, i32 0
    50    store i64 %value1, ptr %gep1
    51  
    52    ; Test that the global really is marked dirty:
    53    ;     var nonConst2 = nonConst1[0]
    54    %gep2 = getelementptr [4 x i64], ptr @main.nonConst1, i32 0, i32 0
    55    %value2 = load i64, ptr %gep2
    56    store i64 %value2, ptr @main.nonConst2
    57  
    58    ; Test that the following GEP works:
    59    ;     var someArray
    60    ;     modifyExternal(&someArray[3].field1)
    61    %gep3 = getelementptr [8 x {i16, i32}], ptr @main.someArray, i32 0, i32 3, i32 1
    62    call void @modifyExternal(ptr %gep3)
    63  
    64    ; Test that marking a value as external also marks all referenced values.
    65    call void @modifyExternal(ptr @main.exportedValue)
    66    store i16 5, ptr @main.exposedValue1
    67  
    68    ; Test that marking a constant as external still allows loading from it.
    69    call void @readExternal(ptr @main.exportedConst)
    70    %constLoad = load i64, ptr @main.exportedConst
    71    call void @runtime.printint64(i64 %constLoad)
    72  
    73    ; Test that this even propagates through functions.
    74    call void @modifyExternal(ptr @willModifyGlobal)
    75    store i16 7, ptr @main.exposedValue2
    76  
    77    ; Test that inline assembly is ignored.
    78    call void @modifyExternal(ptr @hasInlineAsm)
    79  
    80    ; Test switch statement.
    81    %switch1 = call i64 @testSwitch(i64 1) ; 1 returns 6
    82    %switch2 = call i64 @testSwitch(i64 9) ; 9 returns the default value -1
    83    call void @runtime.printint64(i64 %switch1)
    84    call void @runtime.printint64(i64 %switch2)
    85  
    86    ; Test extractvalue/insertvalue with multiple operands.
    87    %agg = call {i8, i32, {float, {i64, i16}}} @nestedStruct()
    88    %elt = extractvalue {i8, i32, {float, {i64, i16}}} %agg, 2, 1, 0
    89    call void @runtime.printint64(i64 %elt)
    90    %agg2 = insertvalue {i8, i32, {float, {i64, i16}}} %agg, i64 5, 2, 1, 0
    91    store {i8, i32, {float, {i64, i16}}} %agg2, ptr @main.insertedValue
    92  
    93    ; negative GEP instruction
    94    %ngep1 = getelementptr [8 x i8], ptr @main.negativeGEP, i32 0, i32 5
    95    %ngep2 = getelementptr [8 x i8], ptr %ngep1, i32 0, i32 -3
    96    store ptr %ngep2, ptr @main.negativeGEP
    97  
    98    ret void
    99  }
   100  
   101  define internal void @"main.init#1"() unnamed_addr {
   102  entry:
   103    call void @runtime.printint64(i64 5)
   104    call void @runtime.printnl()
   105    ret void
   106  }
   107  
   108  declare i64 @someValue()
   109  
   110  declare void @modifyExternal(ptr)
   111  
   112  declare void @readExternal(ptr)
   113  
   114  ; This function will modify an external value. By passing this function as a
   115  ; function pointer to an external function, @main.exposedValue2 should be
   116  ; marked as external.
   117  define void @willModifyGlobal() {
   118  entry:
   119    store i16 8, ptr @main.exposedValue2
   120    ret void
   121  }
   122  
   123  ; Inline assembly should be ignored in the interp package. While it is possible
   124  ; to modify other globals that way, usually that's not the case and there is no
   125  ; real way to check.
   126  define void @hasInlineAsm() {
   127  entry:
   128    call void asm sideeffect "", ""()
   129    ret void
   130  }
   131  
   132  define i64 @testSwitch(i64 %val) {
   133  entry:
   134    ; Test switch statement.
   135    switch i64 %val, label %otherwise [ i64 0, label %zero
   136                                        i64 1, label %one
   137                                        i64 2, label %two ]
   138  zero:
   139    ret i64 5
   140  
   141  one:
   142    ret i64 6
   143  
   144  two:
   145    ret i64 7
   146  
   147  otherwise:
   148    ret i64 -1
   149  }
   150  
   151  declare {i8, i32, {float, {i64, i16}}} @nestedStruct()