Line data Source code
1 : // Copyright 2018 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "test/cctest/wasm/wasm-atomics-utils.h"
6 : #include "test/common/wasm/wasm-macro-gen.h"
7 :
8 : namespace v8 {
9 : namespace internal {
10 : namespace wasm {
11 : namespace test_run_wasm_atomics_64 {
12 :
13 90 : void RunU64BinOp(ExecutionTier execution_tier, WasmOpcode wasm_op,
14 : Uint64BinOp expected_op) {
15 : EXPERIMENTAL_FLAG_SCOPE(threads);
16 90 : WasmRunner<uint64_t, uint64_t> r(execution_tier);
17 590490 : uint64_t* memory =
18 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
19 : r.builder().SetHasSharedMemory();
20 :
21 90 : BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
22 : MachineRepresentation::kWord64));
23 :
24 7380 : FOR_UINT64_INPUTS(i) {
25 7290 : uint64_t initial = *i;
26 597780 : FOR_UINT64_INPUTS(j) {
27 : r.builder().WriteMemory(&memory[0], initial);
28 590490 : CHECK_EQ(initial, r.Call(*j));
29 590490 : uint64_t expected = expected_op(*i, *j);
30 590490 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
31 : }
32 : }
33 90 : }
34 :
35 : #define TEST_OPERATION(Name) \
36 : WASM_EXEC_TEST(I64Atomic##Name) { \
37 : RunU64BinOp(execution_tier, kExprI64Atomic##Name, Name); \
38 : }
39 28427 : OPERATION_LIST(TEST_OPERATION)
40 : #undef TEST_OPERATION
41 :
42 90 : void RunU32BinOp(ExecutionTier execution_tier, WasmOpcode wasm_op,
43 : Uint32BinOp expected_op) {
44 : EXPERIMENTAL_FLAG_SCOPE(threads);
45 90 : WasmRunner<uint64_t, uint64_t> r(execution_tier);
46 302760 : uint32_t* memory =
47 : r.builder().AddMemoryElems<uint32_t>(kWasmPageSize / sizeof(uint32_t));
48 : r.builder().SetHasSharedMemory();
49 :
50 90 : BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
51 : MachineRepresentation::kWord32));
52 :
53 5310 : FOR_UINT32_INPUTS(i) {
54 5220 : uint32_t initial = *i;
55 307980 : FOR_UINT32_INPUTS(j) {
56 : r.builder().WriteMemory(&memory[0], initial);
57 605520 : CHECK_EQ(initial, r.Call(*j));
58 302760 : uint32_t expected = expected_op(*i, *j);
59 302760 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
60 : }
61 : }
62 90 : }
63 :
64 : #define TEST_OPERATION(Name) \
65 : WASM_EXEC_TEST(I64Atomic##Name##32U) { \
66 : RunU32BinOp(execution_tier, kExprI64Atomic##Name##32U, Name); \
67 : }
68 28427 : OPERATION_LIST(TEST_OPERATION)
69 : #undef TEST_OPERATION
70 :
71 90 : void RunU16BinOp(ExecutionTier tier, WasmOpcode wasm_op,
72 : Uint16BinOp expected_op) {
73 : EXPERIMENTAL_FLAG_SCOPE(threads);
74 90 : WasmRunner<uint64_t, uint64_t> r(tier);
75 : r.builder().SetHasSharedMemory();
76 7290 : uint16_t* memory =
77 : r.builder().AddMemoryElems<uint16_t>(kWasmPageSize / sizeof(uint16_t));
78 :
79 90 : BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
80 : MachineRepresentation::kWord16));
81 :
82 900 : FOR_UINT16_INPUTS(i) {
83 810 : uint16_t initial = *i;
84 8100 : FOR_UINT16_INPUTS(j) {
85 : r.builder().WriteMemory(&memory[0], initial);
86 14580 : CHECK_EQ(initial, r.Call(*j));
87 7290 : uint16_t expected = expected_op(*i, *j);
88 7290 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
89 : }
90 : }
91 90 : }
92 :
93 : #define TEST_OPERATION(Name) \
94 : WASM_EXEC_TEST(I64Atomic##Name##16U) { \
95 : RunU16BinOp(execution_tier, kExprI64Atomic##Name##16U, Name); \
96 : }
97 28427 : OPERATION_LIST(TEST_OPERATION)
98 : #undef TEST_OPERATION
99 :
100 90 : void RunU8BinOp(ExecutionTier execution_tier, WasmOpcode wasm_op,
101 : Uint8BinOp expected_op) {
102 : EXPERIMENTAL_FLAG_SCOPE(threads);
103 90 : WasmRunner<uint64_t, uint64_t> r(execution_tier);
104 : r.builder().SetHasSharedMemory();
105 7290 : uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(kWasmPageSize);
106 :
107 90 : BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
108 : MachineRepresentation::kWord8));
109 :
110 900 : FOR_UINT8_INPUTS(i) {
111 810 : uint8_t initial = *i;
112 8100 : FOR_UINT8_INPUTS(j) {
113 : r.builder().WriteMemory(&memory[0], initial);
114 14580 : CHECK_EQ(initial, r.Call(*j));
115 7290 : uint8_t expected = expected_op(*i, *j);
116 7290 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
117 : }
118 : }
119 90 : }
120 :
121 : #define TEST_OPERATION(Name) \
122 : WASM_EXEC_TEST(I64Atomic##Name##8U) { \
123 : RunU8BinOp(execution_tier, kExprI64Atomic##Name##8U, Name); \
124 : }
125 28427 : OPERATION_LIST(TEST_OPERATION)
126 : #undef TEST_OPERATION
127 :
128 28367 : WASM_EXEC_TEST(I64AtomicCompareExchange) {
129 : EXPERIMENTAL_FLAG_SCOPE(threads);
130 15 : WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_tier);
131 : r.builder().SetHasSharedMemory();
132 98415 : uint64_t* memory =
133 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
134 15 : BUILD(r, WASM_ATOMICS_TERNARY_OP(
135 : kExprI64AtomicCompareExchange, WASM_I32V_1(0), WASM_GET_LOCAL(0),
136 : WASM_GET_LOCAL(1), MachineRepresentation::kWord64));
137 :
138 1230 : FOR_UINT64_INPUTS(i) {
139 1215 : uint64_t initial = *i;
140 99630 : FOR_UINT64_INPUTS(j) {
141 : r.builder().WriteMemory(&memory[0], initial);
142 98415 : CHECK_EQ(initial, r.Call(*i, *j));
143 98415 : uint64_t expected = CompareExchange(initial, *i, *j);
144 98415 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
145 : }
146 : }
147 15 : }
148 :
149 28367 : WASM_EXEC_TEST(I64AtomicCompareExchange32U) {
150 : EXPERIMENTAL_FLAG_SCOPE(threads);
151 15 : WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_tier);
152 : r.builder().SetHasSharedMemory();
153 50460 : uint32_t* memory =
154 : r.builder().AddMemoryElems<uint32_t>(kWasmPageSize / sizeof(uint32_t));
155 15 : BUILD(r, WASM_ATOMICS_TERNARY_OP(kExprI64AtomicCompareExchange32U,
156 : WASM_I32V_1(0), WASM_GET_LOCAL(0),
157 : WASM_GET_LOCAL(1),
158 : MachineRepresentation::kWord32));
159 :
160 885 : FOR_UINT32_INPUTS(i) {
161 870 : uint32_t initial = *i;
162 51330 : FOR_UINT32_INPUTS(j) {
163 : r.builder().WriteMemory(&memory[0], initial);
164 100920 : CHECK_EQ(initial, r.Call(*i, *j));
165 50460 : uint32_t expected = CompareExchange(initial, *i, *j);
166 50460 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
167 : }
168 : }
169 15 : }
170 :
171 28367 : WASM_EXEC_TEST(I64AtomicCompareExchange16U) {
172 : EXPERIMENTAL_FLAG_SCOPE(threads);
173 15 : WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_tier);
174 : r.builder().SetHasSharedMemory();
175 1215 : uint16_t* memory =
176 : r.builder().AddMemoryElems<uint16_t>(kWasmPageSize / sizeof(uint16_t));
177 15 : BUILD(r, WASM_ATOMICS_TERNARY_OP(kExprI64AtomicCompareExchange16U,
178 : WASM_I32V_1(0), WASM_GET_LOCAL(0),
179 : WASM_GET_LOCAL(1),
180 : MachineRepresentation::kWord16));
181 :
182 150 : FOR_UINT16_INPUTS(i) {
183 135 : uint16_t initial = *i;
184 1350 : FOR_UINT16_INPUTS(j) {
185 : r.builder().WriteMemory(&memory[0], initial);
186 2430 : CHECK_EQ(initial, r.Call(*i, *j));
187 1215 : uint16_t expected = CompareExchange(initial, *i, *j);
188 1215 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
189 : }
190 : }
191 15 : }
192 :
193 28367 : WASM_EXEC_TEST(I32AtomicCompareExchange8U) {
194 : EXPERIMENTAL_FLAG_SCOPE(threads);
195 15 : WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_tier);
196 : r.builder().SetHasSharedMemory();
197 1215 : uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(kWasmPageSize);
198 15 : BUILD(r,
199 : WASM_ATOMICS_TERNARY_OP(kExprI64AtomicCompareExchange8U, WASM_I32V_1(0),
200 : WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
201 : MachineRepresentation::kWord8));
202 150 : FOR_UINT8_INPUTS(i) {
203 135 : uint8_t initial = *i;
204 1350 : FOR_UINT8_INPUTS(j) {
205 : r.builder().WriteMemory(&memory[0], initial);
206 2430 : CHECK_EQ(initial, r.Call(*i, *j));
207 1215 : uint8_t expected = CompareExchange(initial, *i, *j);
208 1215 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
209 : }
210 : }
211 15 : }
212 :
213 28367 : WASM_EXEC_TEST(I64AtomicLoad) {
214 : EXPERIMENTAL_FLAG_SCOPE(threads);
215 15 : WasmRunner<uint64_t> r(execution_tier);
216 : r.builder().SetHasSharedMemory();
217 : uint64_t* memory =
218 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
219 15 : BUILD(r, WASM_ATOMICS_LOAD_OP(kExprI64AtomicLoad, WASM_ZERO,
220 : MachineRepresentation::kWord64));
221 :
222 1230 : FOR_UINT64_INPUTS(i) {
223 1215 : uint64_t expected = *i;
224 : r.builder().WriteMemory(&memory[0], expected);
225 1215 : CHECK_EQ(expected, r.Call());
226 : }
227 15 : }
228 :
229 28367 : WASM_EXEC_TEST(I64AtomicLoad32U) {
230 : EXPERIMENTAL_FLAG_SCOPE(threads);
231 15 : WasmRunner<uint64_t> r(execution_tier);
232 : r.builder().SetHasSharedMemory();
233 : uint32_t* memory =
234 : r.builder().AddMemoryElems<uint32_t>(kWasmPageSize / sizeof(uint32_t));
235 15 : BUILD(r, WASM_ATOMICS_LOAD_OP(kExprI64AtomicLoad32U, WASM_ZERO,
236 : MachineRepresentation::kWord32));
237 :
238 885 : FOR_UINT32_INPUTS(i) {
239 870 : uint32_t expected = *i;
240 : r.builder().WriteMemory(&memory[0], expected);
241 1740 : CHECK_EQ(expected, r.Call());
242 : }
243 15 : }
244 :
245 28367 : WASM_EXEC_TEST(I64AtomicLoad16U) {
246 : EXPERIMENTAL_FLAG_SCOPE(threads);
247 15 : WasmRunner<uint64_t> r(execution_tier);
248 : r.builder().SetHasSharedMemory();
249 : uint16_t* memory =
250 : r.builder().AddMemoryElems<uint16_t>(kWasmPageSize / sizeof(uint16_t));
251 15 : BUILD(r, WASM_ATOMICS_LOAD_OP(kExprI64AtomicLoad16U, WASM_ZERO,
252 : MachineRepresentation::kWord16));
253 :
254 150 : FOR_UINT16_INPUTS(i) {
255 135 : uint16_t expected = *i;
256 : r.builder().WriteMemory(&memory[0], expected);
257 270 : CHECK_EQ(expected, r.Call());
258 : }
259 15 : }
260 :
261 28367 : WASM_EXEC_TEST(I64AtomicLoad8U) {
262 : EXPERIMENTAL_FLAG_SCOPE(threads);
263 15 : WasmRunner<uint64_t> r(execution_tier);
264 : r.builder().SetHasSharedMemory();
265 : uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(kWasmPageSize);
266 15 : BUILD(r, WASM_ATOMICS_LOAD_OP(kExprI64AtomicLoad8U, WASM_ZERO,
267 : MachineRepresentation::kWord8));
268 :
269 150 : FOR_UINT8_INPUTS(i) {
270 135 : uint8_t expected = *i;
271 : r.builder().WriteMemory(&memory[0], expected);
272 270 : CHECK_EQ(expected, r.Call());
273 : }
274 15 : }
275 :
276 28367 : WASM_EXEC_TEST(I64AtomicStoreLoad) {
277 : EXPERIMENTAL_FLAG_SCOPE(threads);
278 15 : WasmRunner<uint64_t, uint64_t> r(execution_tier);
279 : r.builder().SetHasSharedMemory();
280 1215 : uint64_t* memory =
281 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
282 :
283 15 : BUILD(r,
284 : WASM_ATOMICS_STORE_OP(kExprI64AtomicStore, WASM_ZERO, WASM_GET_LOCAL(0),
285 : MachineRepresentation::kWord64),
286 : WASM_ATOMICS_LOAD_OP(kExprI64AtomicLoad, WASM_ZERO,
287 : MachineRepresentation::kWord64));
288 :
289 1230 : FOR_UINT64_INPUTS(i) {
290 1215 : uint64_t expected = *i;
291 1215 : CHECK_EQ(expected, r.Call(*i));
292 1215 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
293 : }
294 15 : }
295 :
296 28367 : WASM_EXEC_TEST(I64AtomicStoreLoad32U) {
297 : EXPERIMENTAL_FLAG_SCOPE(threads);
298 15 : WasmRunner<uint64_t, uint64_t> r(execution_tier);
299 : r.builder().SetHasSharedMemory();
300 870 : uint32_t* memory =
301 : r.builder().AddMemoryElems<uint32_t>(kWasmPageSize / sizeof(uint32_t));
302 :
303 15 : BUILD(
304 : r,
305 : WASM_ATOMICS_STORE_OP(kExprI64AtomicStore32U, WASM_ZERO,
306 : WASM_GET_LOCAL(0), MachineRepresentation::kWord32),
307 : WASM_ATOMICS_LOAD_OP(kExprI64AtomicLoad32U, WASM_ZERO,
308 : MachineRepresentation::kWord32));
309 :
310 885 : FOR_UINT32_INPUTS(i) {
311 870 : uint32_t expected = *i;
312 870 : CHECK_EQ(expected, r.Call(*i));
313 870 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
314 : }
315 15 : }
316 :
317 28367 : WASM_EXEC_TEST(I64AtomicStoreLoad16U) {
318 : EXPERIMENTAL_FLAG_SCOPE(threads);
319 15 : WasmRunner<uint64_t, uint64_t> r(execution_tier);
320 : r.builder().SetHasSharedMemory();
321 135 : uint16_t* memory =
322 : r.builder().AddMemoryElems<uint16_t>(kWasmPageSize / sizeof(uint16_t));
323 :
324 15 : BUILD(
325 : r,
326 : WASM_ATOMICS_STORE_OP(kExprI64AtomicStore16U, WASM_ZERO,
327 : WASM_GET_LOCAL(0), MachineRepresentation::kWord16),
328 : WASM_ATOMICS_LOAD_OP(kExprI64AtomicLoad16U, WASM_ZERO,
329 : MachineRepresentation::kWord16));
330 :
331 150 : FOR_UINT16_INPUTS(i) {
332 135 : uint16_t expected = *i;
333 135 : CHECK_EQ(expected, r.Call(*i));
334 135 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
335 : }
336 15 : }
337 :
338 28367 : WASM_EXEC_TEST(I64AtomicStoreLoad8U) {
339 : EXPERIMENTAL_FLAG_SCOPE(threads);
340 15 : WasmRunner<uint64_t, uint64_t> r(execution_tier);
341 : r.builder().SetHasSharedMemory();
342 135 : uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(kWasmPageSize);
343 :
344 15 : BUILD(r,
345 : WASM_ATOMICS_STORE_OP(kExprI64AtomicStore8U, WASM_ZERO,
346 : WASM_GET_LOCAL(0), MachineRepresentation::kWord8),
347 : WASM_ATOMICS_LOAD_OP(kExprI64AtomicLoad8U, WASM_ZERO,
348 : MachineRepresentation::kWord8));
349 :
350 150 : FOR_UINT8_INPUTS(i) {
351 135 : uint8_t expected = *i;
352 135 : CHECK_EQ(expected, r.Call(*i));
353 135 : CHECK_EQ(*i, r.builder().ReadMemory(&memory[0]));
354 : }
355 15 : }
356 :
357 : // Drop tests verify atomic operations are run correctly when the
358 : // entire 64-bit output is optimized out
359 90 : void RunDropTest(ExecutionTier execution_tier, WasmOpcode wasm_op,
360 : Uint64BinOp op) {
361 : EXPERIMENTAL_FLAG_SCOPE(threads);
362 90 : WasmRunner<uint64_t, uint64_t> r(execution_tier);
363 90 : uint64_t* memory =
364 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
365 : r.builder().SetHasSharedMemory();
366 :
367 90 : BUILD(r,
368 : WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
369 : MachineRepresentation::kWord64),
370 : WASM_DROP, WASM_GET_LOCAL(0));
371 :
372 : uint64_t initial = 0x1111222233334444, local = 0x1111111111111111;
373 : r.builder().WriteMemory(&memory[0], initial);
374 90 : CHECK_EQ(local, r.Call(local));
375 90 : uint64_t expected = op(initial, local);
376 90 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
377 90 : }
378 :
379 : #define TEST_OPERATION(Name) \
380 : WASM_EXEC_TEST(I64Atomic##Name##Drop) { \
381 : RunDropTest(execution_tier, kExprI64Atomic##Name, Name); \
382 : }
383 28427 : OPERATION_LIST(TEST_OPERATION)
384 : #undef TEST_OPERATION
385 :
386 28367 : WASM_EXEC_TEST(I64AtomicSub16UDrop) {
387 : EXPERIMENTAL_FLAG_SCOPE(threads);
388 15 : WasmRunner<uint64_t, uint64_t> r(execution_tier);
389 15 : uint16_t* memory =
390 : r.builder().AddMemoryElems<uint16_t>(kWasmPageSize / sizeof(uint16_t));
391 : r.builder().SetHasSharedMemory();
392 :
393 15 : BUILD(r,
394 : WASM_ATOMICS_BINOP(kExprI64AtomicSub16U, WASM_I32V_1(0),
395 : WASM_GET_LOCAL(0), MachineRepresentation::kWord16),
396 : WASM_DROP, WASM_GET_LOCAL(0));
397 :
398 : uint16_t initial = 0x7, local = 0xffe0;
399 : r.builder().WriteMemory(&memory[0], initial);
400 15 : CHECK_EQ(local, r.Call(local));
401 : uint16_t expected = Sub(initial, local);
402 15 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
403 15 : }
404 :
405 28367 : WASM_EXEC_TEST(I64AtomicCompareExchangeDrop) {
406 : EXPERIMENTAL_FLAG_SCOPE(threads);
407 15 : WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_tier);
408 : r.builder().SetHasSharedMemory();
409 15 : uint64_t* memory =
410 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
411 15 : BUILD(r,
412 : WASM_ATOMICS_TERNARY_OP(kExprI64AtomicCompareExchange, WASM_I32V_1(0),
413 : WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
414 : MachineRepresentation::kWord64),
415 : WASM_DROP, WASM_GET_LOCAL(1));
416 :
417 : uint64_t initial = 0x1111222233334444, local = 0x1111111111111111;
418 : r.builder().WriteMemory(&memory[0], initial);
419 15 : CHECK_EQ(local, r.Call(initial, local));
420 : uint64_t expected = CompareExchange(initial, initial, local);
421 15 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
422 15 : }
423 :
424 28367 : WASM_EXEC_TEST(I64AtomicStoreLoadDrop) {
425 : EXPERIMENTAL_FLAG_SCOPE(threads);
426 15 : WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_tier);
427 : r.builder().SetHasSharedMemory();
428 15 : uint64_t* memory =
429 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
430 :
431 15 : BUILD(r,
432 : WASM_ATOMICS_STORE_OP(kExprI64AtomicStore, WASM_ZERO, WASM_GET_LOCAL(0),
433 : MachineRepresentation::kWord64),
434 : WASM_ATOMICS_LOAD_OP(kExprI64AtomicLoad, WASM_ZERO,
435 : MachineRepresentation::kWord64),
436 : WASM_DROP, WASM_GET_LOCAL(1));
437 :
438 : uint64_t store_value = 0x1111111111111111, expected = 0xC0DE;
439 15 : CHECK_EQ(expected, r.Call(store_value, expected));
440 15 : CHECK_EQ(store_value, r.builder().ReadMemory(&memory[0]));
441 15 : }
442 :
443 28367 : WASM_EXEC_TEST(I64AtomicAddConvertDrop) {
444 : EXPERIMENTAL_FLAG_SCOPE(threads);
445 15 : WasmRunner<uint64_t, uint64_t> r(execution_tier);
446 15 : uint64_t* memory =
447 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
448 : r.builder().SetHasSharedMemory();
449 :
450 15 : BUILD(r,
451 : WASM_ATOMICS_BINOP(kExprI64AtomicAdd, WASM_I32V_1(0), WASM_GET_LOCAL(0),
452 : MachineRepresentation::kWord64),
453 : kExprI32ConvertI64, WASM_DROP, WASM_GET_LOCAL(0));
454 :
455 : uint64_t initial = 0x1111222233334444, local = 0x1111111111111111;
456 : r.builder().WriteMemory(&memory[0], initial);
457 15 : CHECK_EQ(local, r.Call(local));
458 : uint64_t expected = Add(initial, local);
459 15 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
460 15 : }
461 :
462 28367 : WASM_EXEC_TEST(I64AtomicLoadConvertDrop) {
463 : EXPERIMENTAL_FLAG_SCOPE(threads);
464 15 : WasmRunner<uint32_t, uint64_t> r(execution_tier);
465 : uint64_t* memory =
466 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
467 : r.builder().SetHasSharedMemory();
468 :
469 15 : BUILD(r, WASM_I32_CONVERT_I64(WASM_ATOMICS_LOAD_OP(
470 : kExprI64AtomicLoad, WASM_ZERO, MachineRepresentation::kWord64)));
471 :
472 : uint64_t initial = 0x1111222233334444;
473 : r.builder().WriteMemory(&memory[0], initial);
474 15 : CHECK_EQ(static_cast<uint32_t>(initial), r.Call(initial));
475 15 : }
476 :
477 : // Convert tests verify atomic operations are run correctly when the
478 : // upper half of the 64-bit output is optimized out
479 90 : void RunConvertTest(ExecutionTier execution_tier, WasmOpcode wasm_op,
480 : Uint64BinOp op) {
481 : EXPERIMENTAL_FLAG_SCOPE(threads);
482 90 : WasmRunner<uint32_t, uint64_t> r(execution_tier);
483 90 : uint64_t* memory =
484 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
485 : r.builder().SetHasSharedMemory();
486 :
487 90 : BUILD(r, WASM_I32_CONVERT_I64(WASM_ATOMICS_BINOP(
488 : kExprI64AtomicAdd, WASM_ZERO, WASM_GET_LOCAL(0),
489 : MachineRepresentation::kWord64)));
490 :
491 : uint64_t initial = 0x1111222233334444, local = 0x1111111111111111;
492 : r.builder().WriteMemory(&memory[0], initial);
493 90 : CHECK_EQ(static_cast<uint32_t>(initial), r.Call(local));
494 : uint64_t expected = Add(initial, local);
495 90 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
496 90 : }
497 :
498 : #define TEST_OPERATION(Name) \
499 : WASM_EXEC_TEST(I64AtomicConvert##Name) { \
500 : RunConvertTest(execution_tier, kExprI64Atomic##Name, Name); \
501 : }
502 28427 : OPERATION_LIST(TEST_OPERATION)
503 : #undef TEST_OPERATION
504 :
505 28367 : WASM_EXEC_TEST(I64AtomicConvertCompareExchange) {
506 : EXPERIMENTAL_FLAG_SCOPE(threads);
507 15 : WasmRunner<uint32_t, uint64_t, uint64_t> r(execution_tier);
508 15 : uint64_t* memory =
509 : r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
510 : r.builder().SetHasSharedMemory();
511 :
512 15 : BUILD(r, WASM_I32_CONVERT_I64(WASM_ATOMICS_TERNARY_OP(
513 : kExprI64AtomicCompareExchange, WASM_I32V_1(0), WASM_GET_LOCAL(0),
514 : WASM_GET_LOCAL(1), MachineRepresentation::kWord64)));
515 :
516 : uint64_t initial = 0x1111222233334444, local = 0x1111111111111111;
517 : r.builder().WriteMemory(&memory[0], initial);
518 15 : CHECK_EQ(static_cast<uint32_t>(initial), r.Call(initial, local));
519 : uint64_t expected = CompareExchange(initial, initial, local);
520 15 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
521 15 : }
522 :
523 : } // namespace test_run_wasm_atomics_64
524 : } // namespace wasm
525 : } // namespace internal
526 85011 : } // namespace v8
|