github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/interp/testdata/revert.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 declare void @externalCall(i64) 5 6 declare i64 @ptrHash(ptr nocapture) 7 8 @foo.knownAtRuntime = global i64 0 9 @bar.knownAtRuntime = global i64 0 10 @baz.someGlobal = external global [3 x {i64, i32}] 11 @baz.someInt = global i32 0 12 @x.atomicNum = global i32 0 13 @x.volatileNum = global i32 0 14 @y.ready = global i32 0 15 @z.bloom = global i64 0 16 @z.arr = global [32 x i8] zeroinitializer 17 18 define void @runtime.initAll() unnamed_addr { 19 entry: 20 call void @baz.init(ptr undef) 21 call void @foo.init(ptr undef) 22 call void @bar.init(ptr undef) 23 call void @main.init(ptr undef) 24 call void @x.init(ptr undef) 25 call void @y.init(ptr undef) 26 call void @z.init(ptr undef) 27 ret void 28 } 29 30 define internal void @foo.init(ptr %context) unnamed_addr { 31 store i64 5, ptr @foo.knownAtRuntime 32 unreachable ; this triggers a revert of @foo.init. 33 } 34 35 define internal void @bar.init(ptr %context) unnamed_addr { 36 %val = load i64, ptr @foo.knownAtRuntime 37 store i64 %val, ptr @bar.knownAtRuntime 38 ret void 39 } 40 41 define internal void @baz.init(ptr %context) unnamed_addr { 42 ; Test extractvalue/insertvalue with more than one index. 43 %val = load [3 x {i64, i32}], ptr @baz.someGlobal 44 %part = extractvalue [3 x {i64, i32}] %val, 0, 1 45 %val2 = insertvalue [3 x {i64, i32}] %val, i32 5, 2, 1 46 unreachable ; trigger revert 47 } 48 49 define internal void @main.init(ptr %context) unnamed_addr { 50 entry: 51 call void @externalCall(i64 3) 52 ret void 53 } 54 55 56 define internal void @x.init(ptr %context) unnamed_addr { 57 ; Test atomic and volatile memory accesses. 58 store atomic i32 1, ptr @x.atomicNum seq_cst, align 4 59 %x = load atomic i32, ptr @x.atomicNum seq_cst, align 4 60 store i32 %x, ptr @x.atomicNum 61 %y = load volatile i32, ptr @x.volatileNum 62 store volatile i32 %y, ptr @x.volatileNum 63 ret void 64 } 65 66 define internal void @y.init(ptr %context) unnamed_addr { 67 entry: 68 br label %loop 69 70 loop: 71 ; Test a wait-loop. 72 ; This function must be reverted. 73 %val = load atomic i32, ptr @y.ready seq_cst, align 4 74 %ready = icmp eq i32 %val, 1 75 br i1 %ready, label %end, label %loop 76 77 end: 78 ret void 79 } 80 81 define internal void @z.init(ptr %context) unnamed_addr { 82 ; This can be safely expanded. 83 call void @z.setArr(ptr @z.bloom, i64 1, ptr @z.bloom) 84 85 ; This call should be reverted to prevent unrolling. 86 call void @z.setArr(ptr @z.arr, i64 32, ptr @z.bloom) 87 88 ret void 89 } 90 91 define internal void @z.setArr(ptr %arr, i64 %n, ptr %context) unnamed_addr { 92 entry: 93 br label %loop 94 95 loop: 96 %prev = phi i64 [ %n, %entry ], [ %idx, %loop ] 97 %idx = sub i64 %prev, 1 98 %elem = getelementptr i8, ptr %arr, i64 %idx 99 call void @z.set(ptr %elem, ptr %context) 100 %done = icmp eq i64 %idx, 0 101 br i1 %done, label %end, label %loop 102 103 end: 104 ret void 105 } 106 107 define internal void @z.set(ptr %ptr, ptr %context) unnamed_addr { 108 ; Insert the pointer into the Bloom filter. 109 %hash = call i64 @ptrHash(ptr %ptr) 110 %index = lshr i64 %hash, 58 111 %bit = shl i64 1, %index 112 %old = load i64, ptr %context 113 %new = or i64 %old, %bit 114 store i64 %new, ptr %context 115 ret void 116 }