summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-09-07 17:13:10 -0700
committerGitHub <noreply@github.com>2022-09-08 00:13:10 +0000
commitd4d33b1e175c962548347c59339783c11d5d1a23 (patch)
tree6af9da0d244365d3bbc7f5ecb7d3346cd2d643af
parentd81caf99281b0054b98e27e3665f251add6c1d79 (diff)
downloadbinaryen-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.h3
-rw-r--r--test/lit/passes/simplify-locals-gc.wast52
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)
+ )
)