1; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.atomics.o -mattr=+atomics
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
8
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
11
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
15
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
19
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
24
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
29
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
34
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
39
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
44
45@e = private constant [9 x i8] c"constant\00", align 1
46@f = private constant i8 43, align 4
47
48@g = thread_local global i32 99, align 4
49
50; ERROR: 'bulk-memory' feature must be used in order to use shared memory
51
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
78
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
114
115;      PASSIVE-PIC:  - Type:            START
116; PASSIVE-PIC-NEXT:    StartFunction:   3
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; PASSIVE-PIC-NEXT:        Body:            0B
130; PASSIVE-PIC-NEXT:      - Index:           3
131; PASSIVE-PIC-NEXT:        Locals:
132; PASSIVE32-PIC-NEXT:          - Type:            I32
133; PASSIVE64-PIC-NEXT:          - Type:            I64
134; PASSIVE-PIC-NEXT:              Count:           2
135; PASSIVE-PIC-NEXT:        Body:            {{.*}}
136; PASSIVE-PIC-NEXT:  - Type:            DATA
137; PASSIVE-PIC-NEXT:    Segments:
138; PASSIVE-PIC-NEXT:      - SectionOffset:   3
139; PASSIVE-PIC-NEXT:        InitFlags:       1
140; PASSIVE-PIC-NEXT:        Content:         '63000000'
141; PASSIVE-PIC-NEXT:      - SectionOffset:   9
142; PASSIVE-PIC-NEXT:        InitFlags:       1
143; PASSIVE-PIC-NEXT:        Content:         636F6E7374616E74000000002B
144; PASSIVE-PIC-NEXT:      - SectionOffset:   24
145; PASSIVE-PIC-NEXT:        InitFlags:       1
146; PASSIVE-PIC-NEXT:        Content:         68656C6C6F00676F6F646279650000002A000000
147; PASSIVE-PIC-NEXT:  - Type:            CUSTOM
148; PASSIVE-PIC-NEXT:    Name:            name
149; PASSIVE-PIC-NEXT:    FunctionNames:
150; PASSIVE-PIC-NEXT:      - Index:           0
151; PASSIVE-PIC-NEXT:        Name:            __wasm_call_ctors
152; PASSIVE-PIC-NEXT:      - Index:           1
153; PASSIVE-PIC-NEXT:        Name:            __wasm_init_tls
154; PASSIVE-PIC-NEXT:      - Index:           2
155; PASSIVE-PIC-NEXT:        Name:            __wasm_apply_data_relocs
156; PASSIVE-PIC-NEXT:      - Index:           3
157; PASSIVE-PIC-NEXT:        Name:            __wasm_init_memory
158
159; no data relocations.
160; DIS-LABEL:       <__wasm_call_ctors>:
161; DIS-EMPTY:
162; DIS-NEXT:        end
163
164; In PIC mode __wasm_apply_data_relocs is export seperatly to __wasm_call_ctors
165; PIC-DIS:     <__wasm_apply_data_relocs>:
166; PIC-DIS-EMPTY:
167
168; DIS-LABEL:       <__wasm_init_memory>:
169
170; PIC-DIS:           .local [[PTR]]
171; PIC-DIS-NEXT:      global.get      1
172; PIC-DIS-NEXT:      [[PTR]].const   10040
173; PIC-DIS-NEXT:      [[PTR]].add
174; PIC-DIS-NEXT:      local.set       0
175
176; DIS:               block
177; DIS-NEXT:           block
178; DIS-NEXT:            block
179
180; NOPIC-DIS-NEXT:       [[PTR]].const   11064
181; PIC-DIS-NEXT:         local.get       0
182
183; DIS-NEXT:             i32.const       0
184; DIS-NEXT:             i32.const       1
185; DIS-NEXT:             i32.atomic.rmw.cmpxchg  0
186; DIS-NEXT:             br_table        {0, 1, 2}      # 1:     down to label1
187; DIS-NEXT:                                            # 2:     down to label0
188; DIS-NEXT:            end
189
190; NOPIC-DIS-NEXT:      [[PTR]].const   1024
191; NOPIC-DIS-NEXT:      [[PTR]].const   1024
192; NOPIC-DIS-NEXT:      global.set      1
193; PIC-DIS-NEXT:        [[PTR]].const   0
194; PIC-DIS-NEXT:        global.get      1
195; PIC-DIS-NEXT:        [[PTR]].add
196; PIC-DIS-NEXT:        local.tee       1
197; PIC-DIS-NEXT:        global.set      {{\d*}}
198; PIC-DIS-NEXT:        local.get       1
199; DIS-NEXT:            i32.const       0
200; DIS-NEXT:            i32.const       4
201; DIS-NEXT:            memory.init  0, 0
202
203; NOPIC-DIS-NEXT:      [[PTR]].const   1028
204; PIC-DIS-NEXT:        [[PTR]].const   4
205; PIC-DIS-NEXT:        global.get      1
206; PIC-DIS-NEXT:        [[PTR]].add
207
208; DIS-NEXT:            i32.const       0
209; DIS-NEXT:            i32.const       13
210; DIS-NEXT:            memory.init     1, 0
211
212; NOPIC-DIS-NEXT:      [[PTR]].const   1044
213; PIC-DIS-NEXT:        [[PTR]].const   20
214; PIC-DIS-NEXT:        global.get      1
215; PIC-DIS-NEXT:        [[PTR]].add
216
217; DIS-NEXT:            i32.const       0
218; DIS-NEXT:            i32.const       20
219; DIS-NEXT:            memory.init     2, 0
220; NOPIC-DIS-NEXT:      [[PTR]].const   1064
221; PIC-DIS-NEXT:        [[PTR]].const   40
222; PIC-DIS-NEXT:        global.get      1
223; PIC-DIS-NEXT:        [[PTR]].add
224; DIS-NEXT:            i32.const       0
225; DIS-NEXT:            i32.const       10000
226; DIS-NEXT:            memory.fill     0
227
228; NOPIC-DIS-NEXT:      [[PTR]].const   11064
229; PIC-DIS-NEXT:        local.get       0
230
231; DIS-NEXT:            i32.const       2
232; DIS-NEXT:            i32.atomic.store        0
233
234; NOPIC-DIS-NEXT:      [[PTR]].const   11064
235; PIC-DIS-NEXT:        local.get       0
236
237; DIS-NEXT:            i32.const       -1
238; DIS-NEXT:            memory.atomic.notify    0
239; DIS-NEXT:            drop
240; DIS-NEXT:            br              1               # 1:     down to label1
241; DIS-NEXT:           end
242
243; NOPIC-DIS-NEXT:     [[PTR]].const   11064
244; PIC-DIS-NEXT:       local.get       0
245
246; DIS-NEXT:           i32.const       1
247; DIS-NEXT:           i64.const       -1
248; DIS-NEXT:           memory.atomic.wait32    0
249; DIS-NEXT:           drop
250; DIS-NEXT:          end
251; DIS-NEXT:          data.drop       1
252; DIS-NEXT:          data.drop       2
253; DIS-NEXT:         end
254