Skip to content

Commit ebe21ca

Browse files
authored
SimplifyGlobals: Fix folding of exports (#7940)
An exported global can have extra uses, which prevent folding its value into others.
1 parent 899bac4 commit ebe21ca

2 files changed

Lines changed: 34 additions & 2 deletions

File tree

src/passes/SimplifyGlobals.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -738,10 +738,11 @@ struct SimplifyGlobals : public Pass {
738738

739739
void visitGlobalGet(GlobalGet* curr) {
740740
// If this is a get of a global with a single get and no sets, then we
741-
// can fold that code into here.
741+
// can fold that code into here. We must also avoid an export, as it can
742+
// have additional gets and sets that we do not see.
742743
auto name = curr->name;
743744
auto& info = infos[name];
744-
if (info.written == 0 && info.read == 1) {
745+
if (info.written == 0 && info.read == 1 && !info.exported) {
745746
auto* global = wasm.getGlobal(name);
746747
if (global->init) {
747748
// Copy that global's code. For simplicity we copy it as we have to

test/lit/passes/simplify-globals-gc.wast

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,34 @@
5555
)
5656
)
5757

58+
;; One global reads another, and should contain the same value. We should not
59+
;; erroneously optimize the global.get to a struct.new, as struct.new generates
60+
;; a new value each time, and the export allows that difference to be noticed.
61+
;; TODO: We could flip the export to read $B instead, basically considering it
62+
;; a use that we can modify, like global.gets that we already do.
63+
(module
64+
;; CHECK: (type $struct (struct))
65+
(type $struct (struct))
66+
67+
;; CHECK: (global $A (ref $struct) (struct.new_default $struct))
68+
(global $A (ref $struct) (struct.new_default $struct))
69+
70+
;; CHECK: (global $B (ref $struct) (global.get $A))
71+
(global $B (ref $struct) (global.get $A))
72+
73+
;; CHECK: (export "A" (global $A))
74+
(export "A" (global $A))
75+
)
76+
77+
;; Without that export, we only use $A once, and can fold it into that use.
78+
(module
79+
;; CHECK: (type $struct (struct))
80+
(type $struct (struct))
81+
82+
;; CHECK: (global $A (ref $struct) (struct.new_default $struct))
83+
(global $A (ref $struct) (struct.new_default $struct))
84+
85+
;; CHECK: (global $B (ref $struct) (struct.new_default $struct))
86+
(global $B (ref $struct) (global.get $A))
87+
)
88+

0 commit comments

Comments
 (0)