diff --git a/scripts/test/fuzzing.py b/scripts/test/fuzzing.py index e4dba951dc6..8aaa46b1707 100644 --- a/scripts/test/fuzzing.py +++ b/scripts/test/fuzzing.py @@ -83,6 +83,7 @@ 'unsubtyping-cmpxchg.wast', 'struct-atomic-threads.wast', 'type-refining-gufa-rmw.wast', + 'precompute-gc-atomics-rmw.wast', # contains too many segments to run in a wasm VM 'limit-segments_disable-bulk-memory.wast', # https://github.com/WebAssembly/binaryen/issues/7176 diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index f8d9164747f..90556f9bd7f 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -143,6 +143,10 @@ class PrecomputingExpressionRunner return getGCAllocation(curr, [&]() { return Super::visitStructNew(curr); }); } Flow visitStructSet(StructSet* curr) { return Flow(NONCONSTANT_FLOW); } + Flow visitStructRMW(StructRMW* curr) { return Flow(NONCONSTANT_FLOW); } + Flow visitStructCmpxchg(StructCmpxchg* curr) { + return Flow(NONCONSTANT_FLOW); + } Flow visitStructGet(StructGet* curr) { if (curr->ref->type == Type::unreachable || curr->ref->type.isNull()) { return Flow(NONCONSTANT_FLOW); @@ -184,6 +188,8 @@ class PrecomputingExpressionRunner [&]() { return Super::visitArrayNewFixed(curr); }); } Flow visitArraySet(ArraySet* curr) { return Flow(NONCONSTANT_FLOW); } + Flow visitArrayRMW(ArrayRMW* curr) { return Flow(NONCONSTANT_FLOW); } + Flow visitArrayCmpxchg(ArrayCmpxchg* curr) { return Flow(NONCONSTANT_FLOW); } Flow visitArrayGet(ArrayGet* curr) { if (curr->ref->type == Type::unreachable || curr->ref->type.isNull()) { return Flow(NONCONSTANT_FLOW); diff --git a/test/lit/passes/precompute-gc-atomics-rmw.wast b/test/lit/passes/precompute-gc-atomics-rmw.wast new file mode 100644 index 00000000000..eef9a1f7863 --- /dev/null +++ b/test/lit/passes/precompute-gc-atomics-rmw.wast @@ -0,0 +1,86 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --precompute --all-features -S -o - | filecheck %s + +;; We should not precompute RMW operations because they read from and write to +;; the heap. + +(module + ;; CHECK: (type $struct (sub (shared (struct (field (mut i64)))))) + (type $struct (sub (shared (struct (field (mut i64)))))) + ;; CHECK: (type $array (sub (shared (array (mut i64))))) + (type $array (sub (shared (array (mut i64))))) + + ;; CHECK: (global $struct (ref $struct) (struct.new $struct + ;; CHECK-NEXT: (i64.const -39) + ;; CHECK-NEXT: )) + (global $struct (ref $struct) + (struct.new $struct (i64.const -39)) + ) + ;; CHECK: (global $array (ref $array) (array.new $array + ;; CHECK-NEXT: (i64.const -39) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: )) + (global $array (ref $array) + (array.new $array (i64.const -39) (i32.const 1)) + ) + + ;; CHECK: (func $struct-rmw-xchg (type $0) (result i64) + ;; CHECK-NEXT: (struct.atomic.rmw.xchg acqrel acqrel $struct 0 + ;; CHECK-NEXT: (global.get $struct) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $struct-rmw-xchg (result i64) + (struct.atomic.rmw.xchg acqrel acqrel $struct 0 + (global.get $struct) + (i64.const 0) + ) + ) + + ;; CHECK: (func $struct-rmw-cmpxchg (type $0) (result i64) + ;; CHECK-NEXT: (struct.atomic.rmw.cmpxchg acqrel acqrel $struct 0 + ;; CHECK-NEXT: (global.get $struct) + ;; CHECK-NEXT: (i64.const -39) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $struct-rmw-cmpxchg (result i64) + (struct.atomic.rmw.cmpxchg acqrel acqrel $struct 0 + (global.get $struct) + (i64.const -39) + (i64.const 0) + ) + ) + + ;; CHECK: (func $array-rmw-xchg (type $0) (result i64) + ;; CHECK-NEXT: (array.atomic.rmw.xchg acqrel acqrel $array + ;; CHECK-NEXT: (global.get $array) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $array-rmw-xchg (result i64) + (array.atomic.rmw.xchg acqrel acqrel $array + (global.get $array) + (i32.const 0) + (i64.const 0) + ) + ) + + ;; CHECK: (func $array-rmw-cmpxchg (type $0) (result i64) + ;; CHECK-NEXT: (array.atomic.rmw.cmpxchg acqrel acqrel $array + ;; CHECK-NEXT: (global.get $array) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i64.const -39) + ;; CHECK-NEXT: (i64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $array-rmw-cmpxchg (result i64) + (array.atomic.rmw.cmpxchg acqrel acqrel $array + (global.get $array) + (i32.const 0) + (i64.const -39) + (i64.const 0) + ) + ) +)