diff options
-rw-r--r-- | src/passes/SimplifyGlobals.cpp | 9 | ||||
-rw-r--r-- | test/lit/passes/simplify-globals-gc.wast | 24 |
2 files changed, 32 insertions, 1 deletions
diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index d4a6e1f3b..461fe2890 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -317,7 +317,14 @@ struct GlobalUseModifier : public WalkerPass<PostWalker<GlobalUseModifier>> { void visitGlobalGet(GlobalGet* curr) { auto iter = copiedParentMap->find(curr->name); if (iter != copiedParentMap->end()) { - curr->name = iter->second; + auto original = iter->second; + // Only apply this optimization if the global we are switching to has the + // right type for us. + // TODO: We could also allow it to be more refined, but would then need to + // refinalize. + if (getModule()->getGlobal(original)->type == curr->type) { + curr->name = original; + } } } diff --git a/test/lit/passes/simplify-globals-gc.wast b/test/lit/passes/simplify-globals-gc.wast index 76ce984e7..97063a1a1 100644 --- a/test/lit/passes/simplify-globals-gc.wast +++ b/test/lit/passes/simplify-globals-gc.wast @@ -31,3 +31,27 @@ ) ) +(module + ;; CHECK: (type $struct (struct )) + (type $struct (struct )) + + ;; CHECK: (type $1 (func (result anyref))) + + ;; CHECK: (global $a (ref $struct) (struct.new_default $struct)) + (global $a (ref $struct) (struct.new_default $struct)) + ;; CHECK: (global $b (ref $struct) (global.get $a)) + (global $b (ref $struct) (global.get $a)) + ;; CHECK: (global $c (ref null $struct) (global.get $a)) + (global $c (ref null $struct) (global.get $a)) + + ;; CHECK: (func $get-c (type $1) (result anyref) + ;; CHECK-NEXT: (global.get $c) + ;; CHECK-NEXT: ) + (func $get-c (result anyref) + ;; $c has a less-refined type than the other two. We do not switch this to + ;; get from either $a or $b because of that, but we could if we also + ;; refinalized TODO + (global.get $c) + ) +) + |