diff options
author | Alon Zakai <azakai@google.com> | 2024-10-22 09:17:05 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-22 09:17:05 -0700 |
commit | 0d9b7508e5de1ca7befef493ed3e357b8a5613a1 (patch) | |
tree | c14721e0059d5c05ea3f2c80424b9fd3d3e7b92c /test/lit/passes | |
parent | bc36c02d1a54c91d9fc4bdbffe00608929ec3169 (diff) | |
download | binaryen-0d9b7508e5de1ca7befef493ed3e357b8a5613a1.tar.gz binaryen-0d9b7508e5de1ca7befef493ed3e357b8a5613a1.tar.bz2 binaryen-0d9b7508e5de1ca7befef493ed3e357b8a5613a1.zip |
[GC] Fix assertion in GlobalTypeOptimization about public super (#7026)
We only checked for the case of the immediate super being public while we
are private, but it might be a grandsuper instead. That is, any ancestor that
is public will prevent GTO from removing a field (since we can only add
fields on top of our ancestors). Also, the ancestors might not all have the
field, which would add more complexity to that particular assertion, so just
remove it, and add comprehensive tests.
Diffstat (limited to 'test/lit/passes')
-rw-r--r-- | test/lit/passes/gto-removals.wast | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index 61396cf8f..99579f8ab 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -1495,3 +1495,80 @@ ) ) ) + +;; The type $A is public because it is on an exported global. As a result we +;; cannot remove the unused i32 field from its child or grandchild. +(module + ;; CHECK: (type $A (sub (struct (field (mut i32))))) + (type $A (sub (struct (field (mut i32))))) + ;; CHECK: (type $B (sub $A (struct (field (mut i32))))) + (type $B (sub $A (struct (field (mut i32))))) + ;; CHECK: (type $C (sub $B (struct (field (mut i32))))) + (type $C (sub $B (struct (field (mut i32))))) + + ;; Use $C so it isn't removed trivially, which also keeps $B alive as its + ;; super. + ;; CHECK: (global $global (ref $A) (struct.new_default $C)) + (global $global (ref $A) (struct.new_default $C)) + + ;; CHECK: (export "global" (global $global)) + (export "global" (global $global)) +) + +;; As above, but now there is an f64 field on $C that can be removed, since it +;; is not on the parents. +(module + ;; CHECK: (type $A (sub (struct (field (mut i32))))) + (type $A (sub (struct (field (mut i32))))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $B (sub $A (struct (field (mut i32))))) + (type $B (sub $A (struct (field (mut i32))))) + ;; CHECK: (type $C (sub $B (struct (field (mut i32))))) + (type $C (sub $B (struct (field (mut i32)) (field (mut f64))))) + + ;; CHECK: (global $global (ref $A) (struct.new_default $C)) + (global $global (ref $A) (struct.new_default $C)) + + ;; CHECK: (export "global" (global $global)) + (export "global" (global $global)) +) + +;; As above, but the f64 field is now on $B as well. We can still remove it. +(module + ;; CHECK: (type $A (sub (struct (field (mut i32))))) + (type $A (sub (struct (field (mut i32))))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $B (sub $A (struct (field (mut i32))))) + (type $B (sub $A (struct (field (mut i32)) (field (mut f64))))) + ;; CHECK: (type $C (sub $B (struct (field (mut i32))))) + (type $C (sub $B (struct (field (mut i32)) (field (mut f64))))) + + ;; CHECK: (global $global (ref $A) (struct.new_default $C)) + (global $global (ref $A) (struct.new_default $C)) + + ;; CHECK: (export "global" (global $global)) + (export "global" (global $global)) +) + +;; As above, but now $B is public as well. Now we cannot remove the f64. +(module + ;; CHECK: (type $A (sub (struct (field (mut i32))))) + (type $A (sub (struct (field (mut i32))))) + ;; CHECK: (type $B (sub $A (struct (field (mut i32)) (field (mut f64))))) + (type $B (sub $A (struct (field (mut i32)) (field (mut f64))))) + ;; CHECK: (type $C (sub $B (struct (field (mut i32)) (field (mut f64))))) + (type $C (sub $B (struct (field (mut i32)) (field (mut f64))))) + + ;; CHECK: (global $global (ref $A) (struct.new_default $C)) + (global $global (ref $A) (struct.new_default $C)) + + ;; CHECK: (global $globalB (ref $B) (struct.new_default $C)) + (global $globalB (ref $B) (struct.new_default $C)) + + ;; CHECK: (export "global" (global $global)) + (export "global" (global $global)) + + ;; CHECK: (export "globalB" (global $globalB)) + (export "globalB" (global $globalB)) +) + |