diff options
-rw-r--r-- | src/ir/possible-contents.cpp | 7 | ||||
-rw-r--r-- | test/lit/passes/gufa.wast | 51 |
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) + ) + ) +) |