diff --git a/src/ir/effects.h b/src/ir/effects.h index 2ff70910d46..a3525fd6d6c 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -846,6 +846,10 @@ class EffectAnalyzer { // so we set these to true. parent.readsSharedMemory = true; parent.writesSharedMemory = true; + parent.readsSharedMutableStruct = true; + parent.writesSharedStruct = true; + parent.readsSharedMutableArray = true; + parent.writesSharedArray = true; parent.readOrder = parent.writeOrder = MemoryOrder::SeqCst; } void visitPause(Pause* curr) { diff --git a/test/lit/passes/simplify-locals-atomic-effects.wast b/test/lit/passes/simplify-locals-atomic-effects.wast index d7dd36e3434..b10d57009c0 100644 --- a/test/lit/passes/simplify-locals-atomic-effects.wast +++ b/test/lit/passes/simplify-locals-atomic-effects.wast @@ -795,4 +795,107 @@ ) (local.get $x) ) + + ;; CHECK: (func $read-struct-fence (type $3) (param $shared (ref null $shared-struct)) (result i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (struct.get $shared-struct 0 + ;; CHECK-NEXT: (local.get $shared) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (atomic.fence) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + (func $read-struct-fence (param $shared (ref null $shared-struct)) (result i32) + (local $x i32) + ;; A shared struct read cannot be moved past an atomic.fence. + (local.set $x + (struct.get $shared-struct 0 (local.get $shared)) + ) + (atomic.fence) + (local.get $x) + ) + + ;; CHECK: (func $read-array-fence (type $2) (param $shared (ref null $shared-struct)) (param $shared-array (ref null $shared-array)) (result i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (array.get $shared-array + ;; CHECK-NEXT: (local.get $shared-array) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (atomic.fence) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + (func $read-array-fence (param $shared (ref null $shared-struct)) (param $shared-array (ref null $shared-array)) (result i32) + (local $x i32) + ;; A shared array read cannot be moved past an atomic.fence. + (local.set $x + (array.get $shared-array (local.get $shared-array) (i32.const 0)) + ) + (atomic.fence) + (local.get $x) + ) + + ;; CHECK: (func $write-struct-fence (type $3) (param $shared (ref null $shared-struct)) (result i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (struct.set $shared-struct 0 + ;; CHECK-NEXT: (local.get $shared) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (atomic.fence) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + (func $write-struct-fence (param $shared (ref null $shared-struct)) (result i32) + (local $x i32) + ;; A shared struct read cannot be moved past an atomic.fence. + (local.set $x + (block (result i32) + (struct.set $shared-struct 0 + (local.get $shared) + (i32.const 0) + ) + (i32.const 1) + ) + ) + (atomic.fence) + (local.get $x) + ) + + ;; CHECK: (func $write-array-fence (type $6) (param $shared (ref null $shared-array)) (result i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (array.set $shared-array + ;; CHECK-NEXT: (local.get $shared) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (atomic.fence) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + (func $write-array-fence (param $shared (ref null $shared-array)) (result i32) + (local $x i32) + ;; A shared struct read cannot be moved past an atomic.fence. + (local.set $x + (block (result i32) + (array.set $shared-array + (local.get $shared) + (i32.const 0) + (i32.const 0) + ) + (i32.const 1) + ) + ) + (atomic.fence) + (local.get $x) + ) )