summaryrefslogtreecommitdiff
path: root/test/lit/passes/gsi.wast
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-01-03 16:31:42 -0800
committerGitHub <noreply@github.com>2023-01-03 16:31:42 -0800
commitce267f5b800a906b9556657bf98ad92166d3f431 (patch)
tree2a96880567c15067e1b6f7879b801e026c8436f2 /test/lit/passes/gsi.wast
parent6a52a44255d57efd27b3979bd7b2ef3ad132f54a (diff)
downloadbinaryen-ce267f5b800a906b9556657bf98ad92166d3f431.tar.gz
binaryen-ce267f5b800a906b9556657bf98ad92166d3f431.tar.bz2
binaryen-ce267f5b800a906b9556657bf98ad92166d3f431.zip
[Wasm GC] Fix GlobalStructInference reasoning on unoptimizability (#5381)
We have a data structure there, typeGlobals, which maps types to the list of globals for that type. Previously we used the convention of not having an entry in the map to mean that a type is unoptimizable. However, this was not used consistently, and in fact one place could insert to the map in a dangerous way: a subtype's global is added to the list of globals of the super, and typeGlobals[super].add(sub-global) would then effectively make an unoptimizable super into an optimizable one. To fix that, check for unoptimizability before propagating sub-globals. We do still use the convention of not keeping data in typeGlobals for unoptimizable things as it is a minor optimization to avoid wasted work. Fixes #5379
Diffstat (limited to 'test/lit/passes/gsi.wast')
-rw-r--r--test/lit/passes/gsi.wast159
1 files changed, 159 insertions, 0 deletions
diff --git a/test/lit/passes/gsi.wast b/test/lit/passes/gsi.wast
index 4cec6aa3c..6fe4da95a 100644
--- a/test/lit/passes/gsi.wast
+++ b/test/lit/passes/gsi.wast
@@ -1268,3 +1268,162 @@
)
)
)
+
+;; Two subtypes, each with a global. A get of the parent can be optimized into
+;; a select, as it must read one of the children.
+(module
+ ;; CHECK: (type $struct (struct (field i32)))
+ (type $struct (struct_subtype i32 data))
+
+ ;; CHECK: (type $sub-struct1 (struct_subtype (field i32) $struct))
+ (type $sub-struct1 (struct_subtype i32 $struct))
+
+ ;; CHECK: (type $sub-struct2 (struct_subtype (field i32) $struct))
+ (type $sub-struct2 (struct_subtype i32 $struct))
+
+ ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct))))
+
+ ;; CHECK: (global $global1 (ref $sub-struct1) (struct.new $sub-struct1
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: ))
+ (global $global1 (ref $sub-struct1) (struct.new $sub-struct1
+ (i32.const 42)
+ ))
+
+ ;; CHECK: (global $global2 (ref $sub-struct2) (struct.new $sub-struct2
+ ;; CHECK-NEXT: (i32.const 1337)
+ ;; CHECK-NEXT: ))
+ (global $global2 (ref $sub-struct2) (struct.new $sub-struct2
+ (i32.const 1337)
+ ))
+
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (select
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: (i32.const 1337)
+ ;; CHECK-NEXT: (ref.eq
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (global.get $global1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $test (param $struct (ref null $struct))
+ (drop
+ (struct.get $struct 0
+ (local.get $struct)
+ )
+ )
+ )
+)
+
+;; As above, but now the parent is unoptimizable due to a struct.new in a
+;; function. We must not optimize here to a select.
+(module
+ ;; CHECK: (type $struct (struct (field i32)))
+ (type $struct (struct_subtype i32 data))
+
+ ;; CHECK: (type $sub-struct1 (struct_subtype (field i32) $struct))
+ (type $sub-struct1 (struct_subtype i32 $struct))
+
+ ;; CHECK: (type $sub-struct2 (struct_subtype (field i32) $struct))
+ (type $sub-struct2 (struct_subtype i32 $struct))
+
+ ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct))))
+
+ ;; CHECK: (global $global1 (ref $sub-struct1) (struct.new $sub-struct1
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: ))
+ (global $global1 (ref $sub-struct1) (struct.new $sub-struct1
+ (i32.const 42)
+ ))
+
+ ;; CHECK: (global $global2 (ref $sub-struct2) (struct.new $sub-struct2
+ ;; CHECK-NEXT: (i32.const 1337)
+ ;; CHECK-NEXT: ))
+ (global $global2 (ref $sub-struct2) (struct.new $sub-struct2
+ (i32.const 1337)
+ ))
+
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (struct.new $struct
+ ;; CHECK-NEXT: (i32.const 999999)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (struct.get $struct 0
+ ;; CHECK-NEXT: (local.get $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $test (param $struct (ref null $struct))
+ (drop
+ (struct.new $struct
+ (i32.const 999999)
+ )
+ )
+ (drop
+ (struct.get $struct 0
+ (local.get $struct)
+ )
+ )
+ )
+)
+
+;; As above, the struct.new in a function is of a subtype. Again, we cannot
+;; optimize, as unoptimizability spreads to supertypes.
+(module
+ ;; CHECK: (type $struct (struct (field i32)))
+ (type $struct (struct_subtype i32 data))
+
+ ;; CHECK: (type $sub-struct1 (struct_subtype (field i32) $struct))
+ (type $sub-struct1 (struct_subtype i32 $struct))
+
+ ;; CHECK: (type $sub-struct2 (struct_subtype (field i32) $struct))
+ (type $sub-struct2 (struct_subtype i32 $struct))
+
+ ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct))))
+
+ ;; CHECK: (global $global1 (ref $sub-struct1) (struct.new $sub-struct1
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: ))
+ (global $global1 (ref $sub-struct1) (struct.new $sub-struct1
+ (i32.const 42)
+ ))
+
+ ;; CHECK: (global $global2 (ref $sub-struct2) (struct.new $sub-struct2
+ ;; CHECK-NEXT: (i32.const 1337)
+ ;; CHECK-NEXT: ))
+ (global $global2 (ref $sub-struct2) (struct.new $sub-struct2
+ (i32.const 1337)
+ ))
+
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (struct.new $sub-struct1
+ ;; CHECK-NEXT: (i32.const 999999)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (struct.get $struct 0
+ ;; CHECK-NEXT: (local.get $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $test (param $struct (ref null $struct))
+ (drop
+ (struct.new $sub-struct1
+ (i32.const 999999)
+ )
+ )
+ (drop
+ (struct.get $struct 0
+ (local.get $struct)
+ )
+ )
+ )
+)