diff options
author | Alon Zakai <azakai@google.com> | 2022-09-07 17:13:10 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-08 00:13:10 +0000 |
commit | d4d33b1e175c962548347c59339783c11d5d1a23 (patch) | |
tree | 6af9da0d244365d3bbc7f5ecb7d3346cd2d643af | |
parent | d81caf99281b0054b98e27e3665f251add6c1d79 (diff) | |
download | binaryen-d4d33b1e175c962548347c59339783c11d5d1a23.tar.gz binaryen-d4d33b1e175c962548347c59339783c11d5d1a23.tar.bz2 binaryen-d4d33b1e175c962548347c59339783c11d5d1a23.zip |
[Effects] Fix hasAnything on mutable global state (#5026)
We explicitly wrote out memory, table, and globals, but did not add structs. This switches
us to use readsMutableGlobalState which has the full list of all relevant global state,
including the memory, table, and globals as well as structs.
-rw-r--r-- | src/ir/effects.h | 3 | ||||
-rw-r--r-- | test/lit/passes/simplify-locals-gc.wast | 52 |
2 files changed, 53 insertions, 2 deletions
diff --git a/src/ir/effects.h b/src/ir/effects.h index f5fdc5184..d3ae9ba20 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -188,8 +188,7 @@ public: } bool hasAnything() const { - return hasSideEffects() || accessesLocal() || readsMemory || readsTable || - accessesMutableGlobal(); + return hasSideEffects() || accessesLocal() || readsMutableGlobalState(); } // check if we break to anything external from ourselves diff --git a/test/lit/passes/simplify-locals-gc.wast b/test/lit/passes/simplify-locals-gc.wast index 8d15c213e..ba9e144c6 100644 --- a/test/lit/passes/simplify-locals-gc.wast +++ b/test/lit/passes/simplify-locals-gc.wast @@ -391,4 +391,56 @@ (local.get $a) ) ) + + ;; CHECK: (func $call-vs-mutable-read (param $0 (ref $struct)) (result i32) + ;; CHECK-NEXT: (local $temp i32) + ;; CHECK-NEXT: (local.set $temp + ;; CHECK-NEXT: (call $side-effect) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (struct.get $struct 0 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) + ;; NOMNL: (func $call-vs-mutable-read (type $ref|$struct|_=>_i32) (param $0 (ref $struct)) (result i32) + ;; NOMNL-NEXT: (local $temp i32) + ;; NOMNL-NEXT: (local.set $temp + ;; NOMNL-NEXT: (call $side-effect) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (struct.get $struct 0 + ;; NOMNL-NEXT: (local.get $0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $temp) + ;; NOMNL-NEXT: ) + (func $call-vs-mutable-read (param $0 (ref $struct)) (result i32) + (local $temp i32) + (local.set $temp + ;; This call may have arbitrary side effects, for all we know, as we + ;; optimize this function using --simplify-locals. + (call $side-effect) + ) + (drop + ;; This reads a mutable field, which means the call might modify it. + (struct.get $struct 0 + (local.get $0) + ) + ) + ;; We should not move the call to here! + (local.get $temp) + ) + + ;; CHECK: (func $side-effect (result i32) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; NOMNL: (func $side-effect (type $none_=>_i32) (result i32) + ;; NOMNL-NEXT: (unreachable) + ;; NOMNL-NEXT: ) + (func $side-effect (result i32) + ;; Helper function for the above. + (unreachable) + ) ) |