summaryrefslogtreecommitdiff
path: root/test/lit/passes
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-11-15 11:21:44 -0800
committerGitHub <noreply@github.com>2022-11-15 11:21:44 -0800
commit0ffafa5d4f4bca8a6ab77e193caacc5292218a5d (patch)
treeb0ea0aa88f03e231ec746f2ad18f394106ac6c3e /test/lit/passes
parent59cbdd818dc3397a823a37e9821fd32f4522b2fc (diff)
downloadbinaryen-0ffafa5d4f4bca8a6ab77e193caacc5292218a5d.tar.gz
binaryen-0ffafa5d4f4bca8a6ab77e193caacc5292218a5d.tar.bz2
binaryen-0ffafa5d4f4bca8a6ab77e193caacc5292218a5d.zip
GlobalStructInference: Handle the case of just 1 value (#5259)
#5253 handled the case of just one possible global. It is also possible we have multiple globals but just one value. This handles that case. (It slightly overlaps with other passes, but as this pass actually identifies the creations of the objects in globals, it has a guarantee of success that the others don't, and it is very easy to just do given all the work done to handle the case of 2 values). Also fix a minor bug in #5253 - we need to trap if the old reference were null. That is, we know the reference must point to the only object ever created of that type, but that is only if it is not null; if it's null we need to trap.
Diffstat (limited to 'test/lit/passes')
-rw-r--r--test/lit/passes/gsi.wast63
-rw-r--r--test/lit/passes/gsi_vacuum_precompute.wast4
2 files changed, 61 insertions, 6 deletions
diff --git a/test/lit/passes/gsi.wast b/test/lit/passes/gsi.wast
index ae54796d6..66ca43de8 100644
--- a/test/lit/passes/gsi.wast
+++ b/test/lit/passes/gsi.wast
@@ -121,7 +121,9 @@
;; CHECK-NEXT: (struct.get $struct1 0
;; CHECK-NEXT: (block (result (ref $struct1))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $struct1)
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $struct1)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global1)
;; CHECK-NEXT: )
@@ -131,7 +133,9 @@
;; CHECK-NEXT: (struct.get $struct2 0
;; CHECK-NEXT: (block (result (ref $struct2))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $struct2)
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $struct2)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global2)
;; CHECK-NEXT: )
@@ -846,7 +850,9 @@
;; CHECK-NEXT: (struct.get $struct 0
;; CHECK-NEXT: (block (result (ref $struct))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $struct)
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $struct)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global2)
;; CHECK-NEXT: )
@@ -975,7 +981,9 @@
;; CHECK-NEXT: (struct.get $struct1 0
;; CHECK-NEXT: (block (result (ref $struct1))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $struct1)
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $struct1)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global1)
;; CHECK-NEXT: )
@@ -985,7 +993,9 @@
;; CHECK-NEXT: (struct.get $struct2 0
;; CHECK-NEXT: (block (result (ref $struct2))
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (local.get $struct2)
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $struct2)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (global.get $global2)
;; CHECK-NEXT: )
@@ -1123,3 +1133,46 @@
)
)
)
+
+;; Multiple globals, but all the same value, so we do not even need a select and
+;; can just apply the value.
+(module
+ ;; CHECK: (type $struct (struct_subtype (field i32) data))
+ (type $struct (struct i32))
+
+ ;; CHECK: (type $ref?|$struct|_=>_none (func_subtype (param (ref null $struct)) func))
+
+ ;; CHECK: (global $global1 (ref $struct) (struct.new $struct
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: ))
+ (global $global1 (ref $struct) (struct.new $struct
+ (i32.const 42)
+ ))
+
+ ;; CHECK: (global $global2 (ref $struct) (struct.new $struct
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: ))
+ (global $global2 (ref $struct) (struct.new $struct
+ (i32.const 42)
+ ))
+
+ ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $test (param $struct (ref null $struct))
+ (drop
+ (struct.get $struct 0
+ (local.get $struct)
+ )
+ )
+ )
+)
diff --git a/test/lit/passes/gsi_vacuum_precompute.wast b/test/lit/passes/gsi_vacuum_precompute.wast
index 404de1a7e..856499ba8 100644
--- a/test/lit/passes/gsi_vacuum_precompute.wast
+++ b/test/lit/passes/gsi_vacuum_precompute.wast
@@ -1,5 +1,5 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
-;; RUN: foreach %s %t wasm-opt --nominal --gsi --vacuum --precompute -all -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt --nominal --gsi --vacuum --precompute -tnh -all -S -o - | filecheck %s
;; Test a common pattern in j2wasm where itables are differentiated by type, but
;; vtables are not. For example, the vtable might be "hashable" and provide a
@@ -16,6 +16,8 @@
;; from a global.get of an itable, get a vtable, and get a
;; field in the vtable, and we end up optimizing to produce
;; the final value in that vtable.
+;; * -tnh : This is needed for vacuum to successfully remove the dropped stuff
+;; that could prevent later opts.
(module
;; CHECK: (type $vtable (struct_subtype (field funcref) data))