summaryrefslogtreecommitdiff
path: root/test/lit/passes
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-10-22 09:17:05 -0700
committerGitHub <noreply@github.com>2024-10-22 09:17:05 -0700
commit0d9b7508e5de1ca7befef493ed3e357b8a5613a1 (patch)
treec14721e0059d5c05ea3f2c80424b9fd3d3e7b92c /test/lit/passes
parentbc36c02d1a54c91d9fc4bdbffe00608929ec3169 (diff)
downloadbinaryen-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.wast77
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))
+)
+