1;;! threads = true
2
3(module $Mem
4  (memory (export "shared") 1 1 shared)
5)
6
7(thread $T1 (shared (module $Mem))
8  (register "mem" $Mem)
9  (module
10    (memory (import "mem" "shared") 1 10 shared)
11    (func (export "run")
12      (i32.atomic.store (i32.const 0) (i32.const 42))
13      (i32.atomic.store (i32.const 4) (i32.const 1))
14    )
15  )
16  (invoke "run")
17)
18
19(thread $T2 (shared (module $Mem))
20  (register "mem" $Mem)
21  (module
22    (memory (import "mem" "shared") 1 1 shared)
23    (func (export "run")
24      (local i32 i32)
25      (i32.atomic.load (i32.const 4))
26      (local.set 0)
27      (i32.atomic.load (i32.const 0))
28      (local.set 1)
29
30      ;; store results for checking
31      (i32.store (i32.const 24) (local.get 0))
32      (i32.store (i32.const 32) (local.get 1))
33    )
34  )
35
36  (invoke "run")
37)
38
39(wait $T1)
40(wait $T2)
41
42(module $Check
43  (memory (import "Mem" "shared") 1 1 shared)
44
45  (func (export "check") (result i32)
46    (local i32 i32)
47    (i32.load (i32.const 24))
48    (local.set 0)
49    (i32.load (i32.const 32))
50    (local.set 1)
51
52    ;; allowed results: (L_0 = 1 && L_1 = 42) || (L_0 = 0 && L_1 = 0) || (L_0 = 0 && L_1 = 42)
53
54    (i32.and (i32.eq (local.get 0) (i32.const 1)) (i32.eq (local.get 1) (i32.const 42)))
55    (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 0)))
56    (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 42)))
57    (i32.or)
58    (i32.or)
59    (return)
60  )
61)
62
63(assert_return (invoke $Check "check") (i32.const 1))
64