summaryrefslogtreecommitdiff
path: root/test/lit/passes/multi-memory-lowering.wast
diff options
context:
space:
mode:
authorAshley Nelson <nashley@google.com>2022-12-12 15:33:45 -0800
committerGitHub <noreply@github.com>2022-12-12 15:33:45 -0800
commit6c0d8f7bb674da1cf22499873f6fe87e45f3be64 (patch)
tree5787b22097c08fa94ab02cc8cd906f24a8877d47 /test/lit/passes/multi-memory-lowering.wast
parent05dda84ea6d175237a92d3c2aae94cde0e6a6abb (diff)
downloadbinaryen-6c0d8f7bb674da1cf22499873f6fe87e45f3be64.tar.gz
binaryen-6c0d8f7bb674da1cf22499873f6fe87e45f3be64.tar.bz2
binaryen-6c0d8f7bb674da1cf22499873f6fe87e45f3be64.zip
Add Atomics support to Multi-Memory Lowering Pass (#5339)
This PR adds support for Atomic instructions in the multi-memory lowering pass. Also includes optional bounds checks per the wasm spec guidelines, (visitAtomicRMW, visitAtomicCmpxchg, visitAtomicWait, visitAtomicNotify). Note: The latter two instructions, memory.atomic.wait and memory.atomic.notify, have browser engine implementations that predate the still-in-progress threads spec. And whether or not atomic.notify should trap for out-of-bounds addresses remains an open issue. For now, this PR is using the same semantics as v8, which is to bounds check all Atomic instructions the same way and trap for out-of-bounds.
Diffstat (limited to 'test/lit/passes/multi-memory-lowering.wast')
-rw-r--r--test/lit/passes/multi-memory-lowering.wast187
1 files changed, 185 insertions, 2 deletions
diff --git a/test/lit/passes/multi-memory-lowering.wast b/test/lit/passes/multi-memory-lowering.wast
index dba7260a0..6cac24ee0 100644
--- a/test/lit/passes/multi-memory-lowering.wast
+++ b/test/lit/passes/multi-memory-lowering.wast
@@ -1,6 +1,6 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
-;; RUN: wasm-opt %s --enable-multi-memories --multi-memory-lowering --enable-bulk-memory --enable-extended-const --enable-simd -S -o - | filecheck %s
-;; RUN: wasm-opt %s --enable-multi-memories --multi-memory-lowering-with-bounds-checks --enable-bulk-memory --enable-extended-const --enable-simd -S -o - | filecheck %s --check-prefix BOUNDS
+;; RUN: wasm-opt %s --enable-multi-memories --multi-memory-lowering --enable-bulk-memory --enable-extended-const --enable-simd --enable-threads -S -o - | filecheck %s
+;; RUN: wasm-opt %s --enable-multi-memories --multi-memory-lowering-with-bounds-checks --enable-bulk-memory --enable-extended-const --enable-simd --enable-threads -S -o - | filecheck %s --check-prefix BOUNDS
(module
(memory $memory1 1)
@@ -18,6 +18,8 @@
;; CHECK: (type $i32_v128_=>_v128 (func (param i32 v128) (result v128)))
+ ;; CHECK: (type $i32_i64_=>_none (func (param i32 i64)))
+
;; CHECK: (global $memory2_byte_offset (mut i32) (i32.const 65536))
;; CHECK: (global $memory3_byte_offset (mut i32) (i32.const 196608))
@@ -64,6 +66,8 @@
;; BOUNDS: (type $i32_v128_=>_v128 (func (param i32 v128) (result v128)))
+ ;; BOUNDS: (type $i32_i64_=>_none (func (param i32 i64)))
+
;; BOUNDS: (global $memory2_byte_offset (mut i32) (i32.const 65536))
;; BOUNDS: (global $memory3_byte_offset (mut i32) (i32.const 196608))
@@ -445,6 +449,185 @@
(local.get $0)
)
)
+
+ ;; CHECK: (func $atomics (param $0 i32) (param $1 i64)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.atomic.rmw.add offset=4
+ ;; CHECK-NEXT: (i32.add
+ ;; CHECK-NEXT: (global.get $memory3_byte_offset)
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i64.atomic.rmw32.cmpxchg_u offset=48
+ ;; CHECK-NEXT: (i32.add
+ ;; CHECK-NEXT: (global.get $memory2_byte_offset)
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (memory.atomic.wait32 offset=16
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (memory.atomic.notify offset=24
+ ;; CHECK-NEXT: (i32.add
+ ;; CHECK-NEXT: (global.get $memory2_byte_offset)
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; BOUNDS: (func $atomics (param $0 i32) (param $1 i64)
+ ;; BOUNDS-NEXT: (local $2 i32)
+ ;; BOUNDS-NEXT: (local $3 i32)
+ ;; BOUNDS-NEXT: (local $4 i32)
+ ;; BOUNDS-NEXT: (local $5 i32)
+ ;; BOUNDS-NEXT: (drop
+ ;; BOUNDS-NEXT: (i32.atomic.rmw.add offset=4
+ ;; BOUNDS-NEXT: (block (result i32)
+ ;; BOUNDS-NEXT: (local.set $2
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (global.get $memory3_byte_offset)
+ ;; BOUNDS-NEXT: (local.get $0)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (if
+ ;; BOUNDS-NEXT: (i32.gt_u
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (local.get $2)
+ ;; BOUNDS-NEXT: (i32.const 4)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (i32.const 4)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (call $memory3_size)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (unreachable)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (local.get $2)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (local.get $0)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (drop
+ ;; BOUNDS-NEXT: (i64.atomic.rmw32.cmpxchg_u offset=48
+ ;; BOUNDS-NEXT: (block (result i32)
+ ;; BOUNDS-NEXT: (local.set $3
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (global.get $memory2_byte_offset)
+ ;; BOUNDS-NEXT: (local.get $0)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (if
+ ;; BOUNDS-NEXT: (i32.gt_u
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (local.get $3)
+ ;; BOUNDS-NEXT: (i32.const 48)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (i32.const 4)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (call $memory2_size)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (unreachable)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (local.get $3)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (local.get $1)
+ ;; BOUNDS-NEXT: (local.get $1)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (drop
+ ;; BOUNDS-NEXT: (memory.atomic.wait32 offset=16
+ ;; BOUNDS-NEXT: (block (result i32)
+ ;; BOUNDS-NEXT: (local.set $4
+ ;; BOUNDS-NEXT: (local.get $0)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (if
+ ;; BOUNDS-NEXT: (i32.gt_u
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (local.get $4)
+ ;; BOUNDS-NEXT: (i32.const 16)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (i32.const 4)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (call $memory1_size)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (unreachable)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (local.get $4)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (local.get $0)
+ ;; BOUNDS-NEXT: (local.get $1)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (drop
+ ;; BOUNDS-NEXT: (memory.atomic.notify offset=24
+ ;; BOUNDS-NEXT: (block (result i32)
+ ;; BOUNDS-NEXT: (local.set $5
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (global.get $memory2_byte_offset)
+ ;; BOUNDS-NEXT: (local.get $0)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (if
+ ;; BOUNDS-NEXT: (i32.gt_u
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (i32.add
+ ;; BOUNDS-NEXT: (local.get $5)
+ ;; BOUNDS-NEXT: (i32.const 24)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (i32.const 4)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (call $memory2_size)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (unreachable)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (local.get $5)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: (local.get $0)
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: )
+ ;; BOUNDS-NEXT: )
+ (func $atomics (param $0 i32) (param $1 i64)
+ (drop
+ (i32.atomic.rmw.add $memory3 offset=4
+ (local.get $0)
+ (local.get $0)
+ )
+ )
+(drop
+ (i64.atomic.rmw32.cmpxchg_u $memory2 offset=48
+ (local.get $0)
+ (local.get $1)
+ (local.get $1)
+ )
+ )
+(drop
+ (memory.atomic.wait32 $memory1 offset=16
+ (local.get $0)
+ (local.get $0)
+ (local.get $1)
+ )
+ )
+(drop
+ (memory.atomic.notify $memory2 offset=24
+ (local.get $0)
+ (local.get $0)
+ )
+ )
+ )
)
;; CHECK: (func $memory1_size (result i32)