summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/possible-contents.cpp7
-rw-r--r--test/lit/passes/gufa.wast51
2 files changed, 58 insertions, 0 deletions
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp
index d9c608bda..f1302b3dd 100644
--- a/src/ir/possible-contents.cpp
+++ b/src/ir/possible-contents.cpp
@@ -1234,6 +1234,13 @@ Flower::Flower(Module& wasm) : wasm(wasm) {
}
}
}
+ } else if (ex->kind == ExternalKind::Global) {
+ // Exported mutable globals are roots, since the outside may write any
+ // value to them.
+ auto name = ex->value;
+ if (wasm.getGlobal(name)->mutable_) {
+ roots[GlobalLocation{name}] = PossibleContents::many();
+ }
}
}
diff --git a/test/lit/passes/gufa.wast b/test/lit/passes/gufa.wast
index cf8e36097..ae86e3b84 100644
--- a/test/lit/passes/gufa.wast
+++ b/test/lit/passes/gufa.wast
@@ -1066,3 +1066,54 @@
)
)
)
+
+;; Exported mutable globals can contain any value, as the outside can write to
+;; them.
+(module
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (global $exported-mutable (mut i32) (i32.const 42))
+ (global $exported-mutable (mut i32) (i32.const 42))
+ ;; CHECK: (global $exported-immutable i32 (i32.const 42))
+ (global $exported-immutable i32 (i32.const 42))
+ ;; CHECK: (global $mutable (mut i32) (i32.const 42))
+ (global $mutable (mut i32) (i32.const 42))
+ ;; CHECK: (global $immutable i32 (i32.const 42))
+ (global $immutable i32 (i32.const 42))
+
+ ;; CHECK: (export "exported-mutable" (global $exported-mutable))
+ (export "exported-mutable" (global $exported-mutable))
+ ;; CHECK: (export "exported-immutable" (global $exported-immutable))
+ (export "exported-immutable" (global $exported-immutable))
+
+ ;; CHECK: (func $test
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (global.get $exported-mutable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $test
+ ;; This should not be optimized to a constant.
+ (drop
+ (global.get $exported-mutable)
+ )
+ ;; All the rest can be optimized.
+ (drop
+ (global.get $exported-immutable)
+ )
+ (drop
+ (global.get $mutable)
+ )
+ (drop
+ (global.get $immutable)
+ )
+ )
+)