1 ; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.atomics.o -mattr=+atomics,-bulk-memory
2 ; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.bulk-mem.o -mattr=+bulk-memory
3 ; RUN: llc --mtriple=wasm64-unknown-unknown -filetype=obj %s -o %t.bulk-mem64.o -mattr=+bulk-memory
4 ; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.atomics.bulk-mem.o -mattr=+atomics,+bulk-memory
5 ; RUN: llc --mtriple=wasm64-unknown-unknown -filetype=obj %s -o %t.atomics.bulk-mem64.o -mattr=+atomics,+bulk-memory
6 ; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.atomics.bulk-mem.pic.o -relocation-model=pic -mattr=+atomics,+bulk-memory,+mutable-globals
7 ; RUN: llc --mtriple=wasm64-unknown-unknown -filetype=obj %s -o %t.atomics.bulk-mem.pic-mem64.o -relocation-model=pic -mattr=+atomics,+bulk-memory,+mutable-globals
9 ; atomics, shared memory => error
10 ; RUN: not wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.o -o %t.atomics.wasm 2>&1 | FileCheck %s --check-prefix ERROR
12 ; bulk memory, unshared memory => active segments
13 ; RUN: wasm-ld -no-gc-sections --no-entry %t.bulk-mem.o -o %t.bulk-mem.wasm
14 ; RUN: obj2yaml %t.bulk-mem.wasm | FileCheck %s --check-prefixes ACTIVE,ACTIVE32
16 ; bulk memory, unshared memory, wasm64 => active segments
17 ; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry %t.bulk-mem64.o -o %t.bulk-mem64.wasm
18 ; RUN: obj2yaml %t.bulk-mem64.wasm | FileCheck %s --check-prefixes ACTIVE,ACTIVE64
20 ; atomics, bulk memory, shared memory => passive segments
21 ; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.o -o %t.atomics.bulk-mem.wasm
22 ; RUN: obj2yaml %t.atomics.bulk-mem.wasm | FileCheck %s --check-prefix PASSIVE
23 ; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.atomics.bulk-mem.wasm | FileCheck %s --check-prefixes DIS,NOPIC-DIS -DPTR=i32
25 ; atomics, bulk memory, shared memory, wasm64 => passive segments
26 ; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem64.o -o %t.atomics.bulk-mem64.wasm
27 ; RUN: obj2yaml %t.atomics.bulk-mem64.wasm | FileCheck %s --check-prefix PASSIVE
28 ; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.atomics.bulk-mem64.wasm | FileCheck %s --check-prefixes DIS,NOPIC-DIS -DPTR=i64
30 ; Also test in combination with PIC/pie
31 ; RUN: wasm-ld --experimental-pic -pie -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.pic.o -o %t.pic.wasm
32 ; RUN: obj2yaml %t.pic.wasm | FileCheck %s --check-prefixes PASSIVE-PIC,PASSIVE32-PIC
33 ; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.pic.wasm | FileCheck %s --check-prefixes DIS,PIC-DIS -DPTR=i32
35 ; Also test in combination with PIC/pie + wasm64
36 ; RUN: wasm-ld -mwasm64 --experimental-pic -pie -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.pic-mem64.o -o %t.pic-mem64.wasm
37 ; RUN: obj2yaml %t.pic-mem64.wasm | FileCheck %s --check-prefixes PASSIVE-PIC,PASSIVE64-PIC
38 ; RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs,__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.pic-mem64.wasm | FileCheck %s --check-prefixes DIS,PIC-DIS -DPTR=i64
40 @a = hidden global [6 x i8] c"hello\00", align 1
41 @b = hidden global [8 x i8] c"goodbye\00", align 1
42 @c = hidden global [10000 x i8] zeroinitializer, align 1
43 @d = hidden global i32 42, align 4
45 @e = private constant [9 x i8] c"constant\00", align 1
46 @f = private constant i8 43, align 4
48 @g = thread_local global i32 99, align 4
50 ; ERROR: 'bulk-memory' feature must be used in order to use shared memory
52 ; ACTIVE-LABEL: - Type: CODE
53 ; ACTIVE-NEXT: Functions:
54 ; ACTIVE-NEXT: - Index: 0
55 ; ACTIVE-NEXT: Locals: []
56 ; ACTIVE-NEXT: Body: 0B
57 ; ACTIVE-NEXT: - Type: DATA
58 ; ACTIVE-NEXT: Segments:
59 ; ACTIVE-NEXT: - SectionOffset: 7
60 ; ACTIVE-NEXT: InitFlags: 0
61 ; ACTIVE-NEXT: Offset:
62 ; ACTIVE32-NEXT: Opcode: I32_CONST
63 ; ACTIVE64-NEXT: Opcode: I64_CONST
64 ; ACTIVE-NEXT: Value: 1024
65 ; ACTIVE-NEXT: Content: 636F6E7374616E74000000002B
66 ; ACTIVE-NEXT: - SectionOffset: 26
67 ; ACTIVE-NEXT: InitFlags: 0
68 ; ACTIVE-NEXT: Offset:
69 ; ACTIVE32-NEXT: Opcode: I32_CONST
70 ; ACTIVE64-NEXT: Opcode: I64_CONST
71 ; ACTIVE-NEXT: Value: 1040
72 ; ACTIVE-NEXT: Content: 68656C6C6F00676F6F646279650000002A000000
73 ; ACTIVE-NEXT: - Type: CUSTOM
74 ; ACTIVE-NEXT: Name: name
75 ; ACTIVE-NEXT: FunctionNames:
76 ; ACTIVE-NEXT: - Index: 0
77 ; ACTIVE-NEXT: Name: __wasm_call_ctors
79 ; PASSIVE-LABEL: - Type: START
80 ; PASSIVE-NEXT: StartFunction: 2
81 ; PASSIVE-LABEL: - Type: DATACOUNT
82 ; PASSIVE-NEXT: Count: 3
83 ; PASSIVE-LABEL: - Type: CODE
84 ; PASSIVE-NEXT: Functions:
85 ; PASSIVE-NEXT: - Index: 0
86 ; PASSIVE-NEXT: Locals: []
87 ; PASSIVE-NEXT: Body: 0B
88 ; PASSIVE-NEXT: - Index: 1
89 ; PASSIVE-NEXT: Locals: []
90 ; PASSIVE-NEXT: Body: {{.*}}
91 ; PASSIVE-NEXT: - Index: 2
92 ; PASSIVE-NEXT: Locals: []
93 ; PASSIVE-NEXT: Body: {{.*}}
94 ; PASSIVE-NEXT: - Type: DATA
95 ; PASSIVE-NEXT: Segments:
96 ; PASSIVE-NEXT: - SectionOffset: 3
97 ; PASSIVE-NEXT: InitFlags: 1
98 ; PASSIVE-NEXT: Content: '63000000'
99 ; PASSIVE-NEXT: - SectionOffset: 9
100 ; PASSIVE-NEXT: InitFlags: 1
101 ; PASSIVE-NEXT: Content: 636F6E7374616E74000000002B
102 ; PASSIVE-NEXT: - SectionOffset: 24
103 ; PASSIVE-NEXT: InitFlags: 1
104 ; PASSIVE-NEXT: Content: 68656C6C6F00676F6F646279650000002A000000
105 ; PASSIVE-NEXT: - Type: CUSTOM
106 ; PASSIVE-NEXT: Name: name
107 ; PASSIVE-NEXT: FunctionNames:
108 ; PASSIVE-NEXT: - Index: 0
109 ; PASSIVE-NEXT: Name: __wasm_call_ctors
110 ; PASSIVE-NEXT: - Index: 1
111 ; PASSIVE-NEXT: Name: __wasm_init_tls
112 ; PASSIVE-NEXT: - Index: 2
113 ; PASSIVE-NEXT: Name: __wasm_init_memory
115 ; PASSIVE-PIC: - Type: START
116 ; PASSIVE-PIC-NEXT: StartFunction: 2
117 ; PASSIVE-PIC-NEXT: - Type: DATACOUNT
118 ; PASSIVE-PIC-NEXT: Count: 3
119 ; PASSIVE-PIC-NEXT: - Type: CODE
120 ; PASSIVE-PIC-NEXT: Functions:
121 ; PASSIVE-PIC-NEXT: - Index: 0
122 ; PASSIVE-PIC-NEXT: Locals: []
123 ; PASSIVE-PIC-NEXT: Body: 0B
124 ; PASSIVE-PIC-NEXT: - Index: 1
125 ; PASSIVE-PIC-NEXT: Locals: []
126 ; PASSIVE-PIC-NEXT: Body: {{.*}}
127 ; PASSIVE-PIC-NEXT: - Index: 2
128 ; PASSIVE-PIC-NEXT: Locals:
129 ; PASSIVE32-PIC-NEXT: - Type: I32
130 ; PASSIVE64-PIC-NEXT: - Type: I64
131 ; PASSIVE-PIC-NEXT: Count: 2
132 ; PASSIVE-PIC-NEXT: Body: {{.*}}
133 ; PASSIVE-PIC-NEXT: - Type: DATA
134 ; PASSIVE-PIC-NEXT: Segments:
135 ; PASSIVE-PIC-NEXT: - SectionOffset: 3
136 ; PASSIVE-PIC-NEXT: InitFlags: 1
137 ; PASSIVE-PIC-NEXT: Content: '63000000'
138 ; PASSIVE-PIC-NEXT: - SectionOffset: 9
139 ; PASSIVE-PIC-NEXT: InitFlags: 1
140 ; PASSIVE-PIC-NEXT: Content: 636F6E7374616E74000000002B
141 ; PASSIVE-PIC-NEXT: - SectionOffset: 24
142 ; PASSIVE-PIC-NEXT: InitFlags: 1
143 ; PASSIVE-PIC-NEXT: Content: 68656C6C6F00676F6F646279650000002A000000
144 ; PASSIVE-PIC-NEXT: - Type: CUSTOM
145 ; PASSIVE-PIC-NEXT: Name: name
146 ; PASSIVE-PIC-NEXT: FunctionNames:
147 ; PASSIVE-PIC-NEXT: - Index: 0
148 ; PASSIVE-PIC-NEXT: Name: __wasm_call_ctors
149 ; PASSIVE-PIC-NEXT: - Index: 1
150 ; PASSIVE-PIC-NEXT: Name: __wasm_init_tls
151 ; PASSIVE-PIC-NEXT: - Index: 2
152 ; PASSIVE-PIC-NEXT: Name: __wasm_init_memory
154 ; no data relocations.
155 ; DIS-LABEL: <__wasm_call_ctors>:
161 ; DIS-LABEL: <__wasm_init_memory>:
163 ; PIC-DIS: .local [[PTR]]
164 ; PIC-DIS-NEXT: global.get 1
165 ; PIC-DIS-NEXT: [[PTR]].const 10040
166 ; PIC-DIS-NEXT: [[PTR]].add
167 ; PIC-DIS-NEXT: local.set 0
173 ; NOPIC-DIS-NEXT: [[PTR]].const 11064
174 ; PIC-DIS-NEXT: local.get 0
176 ; DIS-NEXT: i32.const 0
177 ; DIS-NEXT: i32.const 1
178 ; DIS-NEXT: i32.atomic.rmw.cmpxchg 0
179 ; DIS-NEXT: br_table {0, 1, 2} # 1: down to label1
180 ; DIS-NEXT: # 2: down to label0
183 ; NOPIC-DIS-NEXT: [[PTR]].const 1024
184 ; NOPIC-DIS-NEXT: [[PTR]].const 1024
185 ; NOPIC-DIS-NEXT: global.set 1
186 ; PIC-DIS-NEXT: [[PTR]].const 0
187 ; PIC-DIS-NEXT: global.get 1
188 ; PIC-DIS-NEXT: [[PTR]].add
189 ; PIC-DIS-NEXT: local.tee 1
190 ; PIC-DIS-NEXT: global.set {{\d*}}
191 ; PIC-DIS-NEXT: local.get 1
192 ; DIS-NEXT: i32.const 0
193 ; DIS-NEXT: i32.const 4
194 ; DIS-NEXT: memory.init 0, 0
196 ; NOPIC-DIS-NEXT: [[PTR]].const 1028
197 ; PIC-DIS-NEXT: [[PTR]].const 4
198 ; PIC-DIS-NEXT: global.get 1
199 ; PIC-DIS-NEXT: [[PTR]].add
201 ; DIS-NEXT: i32.const 0
202 ; DIS-NEXT: i32.const 13
203 ; DIS-NEXT: memory.init 1, 0
205 ; NOPIC-DIS-NEXT: [[PTR]].const 1044
206 ; PIC-DIS-NEXT: [[PTR]].const 20
207 ; PIC-DIS-NEXT: global.get 1
208 ; PIC-DIS-NEXT: [[PTR]].add
210 ; DIS-NEXT: i32.const 0
211 ; DIS-NEXT: i32.const 20
212 ; DIS-NEXT: memory.init 2, 0
213 ; NOPIC-DIS-NEXT: [[PTR]].const 1064
214 ; PIC-DIS-NEXT: [[PTR]].const 40
215 ; PIC-DIS-NEXT: global.get 1
216 ; PIC-DIS-NEXT: [[PTR]].add
217 ; DIS-NEXT: i32.const 0
218 ; DIS-NEXT: [[PTR]].const 10000
219 ; DIS-NEXT: memory.fill 0
221 ; NOPIC-DIS-NEXT: [[PTR]].const 11064
222 ; PIC-DIS-NEXT: local.get 0
224 ; DIS-NEXT: i32.const 2
225 ; DIS-NEXT: i32.atomic.store 0
227 ; NOPIC-DIS-NEXT: [[PTR]].const 11064
228 ; PIC-DIS-NEXT: local.get 0
230 ; DIS-NEXT: i32.const -1
231 ; DIS-NEXT: memory.atomic.notify 0
233 ; DIS-NEXT: br 1 # 1: down to label1
236 ; NOPIC-DIS-NEXT: [[PTR]].const 11064
237 ; PIC-DIS-NEXT: local.get 0
239 ; DIS-NEXT: i32.const 1
240 ; DIS-NEXT: i64.const -1
241 ; DIS-NEXT: memory.atomic.wait32 0
244 ; DIS-NEXT: data.drop 1
245 ; DIS-NEXT: data.drop 2