aboutsummaryrefslogtreecommitdiffhomepage
path: root/interp/testdata/basic.ll
blob: 6d1d010f493ecad312a36c2f5b2f6506293175dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64--linux"

@main.v1 = internal global i64 0
@main.nonConst1 = global [4 x i64] zeroinitializer
@main.nonConst2 = global i64 0
@main.someArray = global [8 x {i16, i32}] zeroinitializer
@main.exportedValue = global [1 x ptr] [ptr @main.exposedValue1]
@main.exportedConst = constant i64 42
@main.exposedValue1 = global i16 0
@main.exposedValue2 = global i16 0
@main.insertedValue = global {i8, i32, {float, {i64, i16}}} zeroinitializer

declare void @runtime.printint64(i64) unnamed_addr

declare void @runtime.printnl() unnamed_addr

define void @runtime.initAll() unnamed_addr {
entry:
  call void @runtime.init()
  call void @main.init()
  ret void
}

define void @main() unnamed_addr {
entry:
  %0 = load i64, ptr @main.v1
  call void @runtime.printint64(i64 %0)
  call void @runtime.printnl()
  ret void
}

define internal void @runtime.init() unnamed_addr {
entry:
  ret void
}

define internal void @main.init() unnamed_addr {
entry:
  store i64 3, ptr @main.v1
  call void @"main.init#1"()

  ; test the following pattern:
  ;     func someValue() int // extern function
  ;     var nonConst1 = [4]int{someValue(), 0, 0, 0}
  %value1 = call i64 @someValue()
  %gep1 = getelementptr [4 x i64], ptr @main.nonConst1, i32 0, i32 0
  store i64 %value1, ptr %gep1

  ; Test that the global really is marked dirty:
  ;     var nonConst2 = nonConst1[0]
  %gep2 = getelementptr [4 x i64], ptr @main.nonConst1, i32 0, i32 0
  %value2 = load i64, ptr %gep2
  store i64 %value2, ptr @main.nonConst2

  ; Test that the following GEP works:
  ;     var someArray
  ;     modifyExternal(&someArray[3].field1)
  %gep3 = getelementptr [8 x {i16, i32}], ptr @main.someArray, i32 0, i32 3, i32 1
  call void @modifyExternal(ptr %gep3)

  ; Test that marking a value as external also marks all referenced values.
  call void @modifyExternal(ptr @main.exportedValue)
  store i16 5, ptr @main.exposedValue1

  ; Test that marking a constant as external still allows loading from it.
  call void @readExternal(ptr @main.exportedConst)
  %constLoad = load i64, ptr @main.exportedConst
  call void @runtime.printint64(i64 %constLoad)

  ; Test that this even propagates through functions.
  call void @modifyExternal(ptr @willModifyGlobal)
  store i16 7, ptr @main.exposedValue2

  ; Test that inline assembly is ignored.
  call void @modifyExternal(ptr @hasInlineAsm)

  ; Test switch statement.
  %switch1 = call i64 @testSwitch(i64 1) ; 1 returns 6
  %switch2 = call i64 @testSwitch(i64 9) ; 9 returns the default value -1
  call void @runtime.printint64(i64 %switch1)
  call void @runtime.printint64(i64 %switch2)

  ; Test extractvalue/insertvalue with multiple operands.
  %agg = call {i8, i32, {float, {i64, i16}}} @nestedStruct()
  %elt = extractvalue {i8, i32, {float, {i64, i16}}} %agg, 2, 1, 0
  call void @runtime.printint64(i64 %elt)
  %agg2 = insertvalue {i8, i32, {float, {i64, i16}}} %agg, i64 5, 2, 1, 0
  store {i8, i32, {float, {i64, i16}}} %agg2, ptr @main.insertedValue

  ret void
}

define internal void @"main.init#1"() unnamed_addr {
entry:
  call void @runtime.printint64(i64 5)
  call void @runtime.printnl()
  ret void
}

declare i64 @someValue()

declare void @modifyExternal(ptr)

declare void @readExternal(ptr)

; This function will modify an external value. By passing this function as a
; function pointer to an external function, @main.exposedValue2 should be
; marked as external.
define void @willModifyGlobal() {
entry:
  store i16 8, ptr @main.exposedValue2
  ret void
}

; Inline assembly should be ignored in the interp package. While it is possible
; to modify other globals that way, usually that's not the case and there is no
; real way to check.
define void @hasInlineAsm() {
entry:
  call void asm sideeffect "", ""()
  ret void
}

define i64 @testSwitch(i64 %val) {
entry:
  ; Test switch statement.
  switch i64 %val, label %otherwise [ i64 0, label %zero
                                      i64 1, label %one
                                      i64 2, label %two ]
zero:
  ret i64 5

one:
  ret i64 6

two:
  ret i64 7

otherwise:
  ret i64 -1
}

declare {i8, i32, {float, {i64, i16}}} @nestedStruct()