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()