blob: 9c1053395a9d2c3545ad2797e70296034f09ef5b [file] [log] [blame]
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
;; RUN: wasm-opt %s -all --simplify-locals -S -o - | filecheck %s
(module
;; CHECK: (type $shared-struct (shared (struct (field (mut i32)))))
(type $shared-struct (shared (struct (field (mut i32)))))
;; CHECK: (type $unshared-struct (struct (field (mut i32))))
(type $unshared-struct (struct (field (mut i32))))
;; CHECK: (memory $shared 1 1 shared)
(memory $shared 1 1 shared)
;; CHECK: (memory $unshared 1 1)
(memory $unshared 1 1)
;; CHECK: (func $memory.size-shared-shared (type $2) (param $shared (ref null $shared-struct)) (result i32)
;; CHECK-NEXT: (local $x i32)
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (memory.size $shared)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.atomic.set $shared-struct 0
;; CHECK-NEXT: (local.get $shared)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
(func $memory.size-shared-shared (param $shared (ref null $shared-struct)) (result i32)
(local $x i32)
;; memory.size can synchronize with memory.grow on another thread when the
;; memory is shared. It cannot be moved past a write to a shared struct.
(local.set $x
(memory.size $shared)
)
(struct.atomic.set $shared-struct 0 (local.get $shared) (i32.const 0))
(local.get $x)
)
;; CHECK: (func $memory.size-unshared-shared (type $2) (param $shared (ref null $shared-struct)) (result i32)
;; CHECK-NEXT: (local $x i32)
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (memory.size $unshared)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.atomic.set $shared-struct 0
;; CHECK-NEXT: (local.get $shared)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
(func $memory.size-unshared-shared (param $shared (ref null $shared-struct)) (result i32)
(local $x i32)
;; Now the memory is unshared. In principle we could reorder because no
;; other thread could observe the reordering, but we do not distinguish
;; between accesses to shared and unshared state. TODO.
(local.set $x
(memory.size $unshared)
)
(struct.atomic.set $shared-struct 0 (local.get $shared) (i32.const 0))
(local.get $x)
)
;; CHECK: (func $memory.size-shared-unshared (type $3) (param $unshared (ref null $unshared-struct)) (result i32)
;; CHECK-NEXT: (local $x i32)
;; CHECK-NEXT: (local.set $x
;; CHECK-NEXT: (memory.size $shared)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.atomic.set $unshared-struct 0
;; CHECK-NEXT: (local.get $unshared)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
(func $memory.size-shared-unshared (param $unshared (ref null $unshared-struct)) (result i32)
(local $x i32)
;; Now the memory is shared but the struct is unshared. Again, we could
;; reorder in principle, but we do not yet. TODO.
(local.set $x
(memory.size $shared)
)
(struct.atomic.set $unshared-struct 0 (local.get $unshared) (i32.const 0))
(local.get $x)
)
;; CHECK: (func $memory.size-unshared-unshared (type $3) (param $unshared (ref null $unshared-struct)) (result i32)
;; CHECK-NEXT: (local $x i32)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (struct.atomic.set $unshared-struct 0
;; CHECK-NEXT: (local.get $unshared)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (memory.size $unshared)
;; CHECK-NEXT: )
(func $memory.size-unshared-unshared (param $unshared (ref null $unshared-struct)) (result i32)
(local $x i32)
;; Now both the memory and struct are unshared, so neither can synchronize
;; with anything and we reorder freely.
(local.set $x
(memory.size $unshared)
)
(struct.atomic.set $unshared-struct 0 (local.get $unshared) (i32.const 0))
(local.get $x)
)
)