summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/simplify-globals-single_use.wast332
1 files changed, 332 insertions, 0 deletions
diff --git a/test/lit/passes/simplify-globals-single_use.wast b/test/lit/passes/simplify-globals-single_use.wast
new file mode 100644
index 000000000..daba2588d
--- /dev/null
+++ b/test/lit/passes/simplify-globals-single_use.wast
@@ -0,0 +1,332 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up.
+
+;; RUN: foreach %s %t wasm-opt -all --simplify-globals -S -o - | filecheck %s
+
+;; $single-use has a single use, and we can fold a copy of that code into its
+;; use. That global then becomes unused.
+(module
+ ;; CHECK: (type $A (struct (field anyref)))
+ (type $A (struct (field anyref)))
+
+ ;; CHECK: (type $1 (func))
+
+ ;; CHECK: (global $single-use anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $single-use anyref (struct.new $A
+ (i31.new
+ (i32.const 42)
+ )
+ ))
+
+ ;; CHECK: (global $other (mut anyref) (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $other (mut anyref) (global.get $single-use))
+
+ ;; CHECK: (func $user (type $1)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (global.get $other)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (global.set $other
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $user
+ ;; Uses of $other do not affect optimization
+ (drop
+ (global.get $other)
+ )
+ (global.set $other
+ (ref.null any)
+ )
+ )
+)
+
+;; As above, but now there is a second use, so we do nothing.
+(module
+ ;; CHECK: (type $A (struct (field anyref)))
+ (type $A (struct (field anyref)))
+
+ ;; CHECK: (global $single-use anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $single-use anyref (struct.new $A
+ (i31.new
+ (i32.const 42)
+ )
+ ))
+
+ ;; CHECK: (global $other anyref (global.get $single-use))
+ (global $other anyref (global.get $single-use))
+
+ ;; CHECK: (global $other2 anyref (global.get $single-use))
+ (global $other2 anyref (global.get $single-use))
+)
+
+;; As the first testcase, but now there is a second use in function code, so
+;; again we do nothing.
+(module
+ ;; CHECK: (type $A (struct (field anyref)))
+ (type $A (struct (field anyref)))
+
+ ;; CHECK: (type $1 (func))
+
+ ;; CHECK: (global $single-use anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $single-use anyref (struct.new $A
+ (i31.new
+ (i32.const 42)
+ )
+ ))
+
+ ;; CHECK: (global $other anyref (global.get $single-use))
+ (global $other anyref (global.get $single-use))
+
+ ;; CHECK: (func $user (type $1)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (global.get $single-use)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $user
+ (drop
+ (global.get $single-use)
+ )
+ )
+)
+
+;; As the first testcase, but now $single-use is imported, so there is no code
+;; to fold.
+(module
+ (type $A (struct (field anyref)))
+
+ ;; CHECK: (import "a" "b" (global $single-use anyref))
+ (import "a" "b" (global $single-use anyref))
+
+ ;; CHECK: (global $other anyref (global.get $single-use))
+ (global $other anyref (global.get $single-use))
+)
+
+;; As the first testcase, but here the single use is in function code, so
+;; we do nothing (as it could be executed more than once).
+(module
+ ;; CHECK: (type $A (struct (field anyref)))
+ (type $A (struct (field anyref)))
+
+ ;; CHECK: (type $1 (func))
+
+ ;; CHECK: (global $single-use anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $single-use anyref (struct.new $A
+ (i31.new
+ (i32.const 42)
+ )
+ ))
+
+ ;; CHECK: (func $user (type $1)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (global.get $single-use)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $user
+ (drop
+ (global.get $single-use)
+ )
+ )
+)
+
+;; As the first testcase, but now the single use is nested in other code. We
+;; can still optimize.
+(module
+ ;; CHECK: (type $A (struct (field anyref)))
+ (type $A (struct (field anyref)))
+
+ ;; CHECK: (global $single-use anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $single-use anyref (struct.new $A
+ (i31.new
+ (i32.const 42)
+ )
+ ))
+
+ ;; CHECK: (global $other anyref (struct.new $A
+ ;; CHECK-NEXT: (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $other anyref (struct.new $A
+ (global.get $single-use)
+ ))
+)
+
+;; Test multiple separate optimizations in one module.
+(module
+ ;; CHECK: (type $A (struct (field anyref)))
+ (type $A (struct (field anyref)))
+
+ ;; CHECK: (global $single-use1 anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $single-use1 anyref (struct.new $A
+ (i31.new
+ (i32.const 42)
+ )
+ ))
+
+ ;; CHECK: (global $single-use2 anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 1337)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $single-use2 anyref (struct.new $A
+ (i31.new
+ (i32.const 1337)
+ )
+ ))
+
+ ;; CHECK: (global $other1 anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $other1 anyref (global.get $single-use1))
+
+ ;; CHECK: (global $single-use3 anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 99999)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $single-use3 anyref (struct.new $A
+ (i31.new
+ (i32.const 99999)
+ )
+ ))
+
+ ;; CHECK: (global $other2 anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 1337)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $other2 anyref (global.get $single-use2))
+
+ ;; CHECK: (global $other3 anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 99999)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $other3 anyref (global.get $single-use3))
+)
+
+;; Test multiple related optimizations in one module: more than one nesting into
+;; one global
+(module
+ ;; CHECK: (type $A (struct (field anyref) (field anyref)))
+ (type $A (struct (field anyref) (field anyref)))
+
+ ;; CHECK: (global $single-use1 anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: ))
+ (global $single-use1 anyref (struct.new $A
+ (i31.new
+ (i32.const 42)
+ )
+ (ref.null any)
+ ))
+
+ ;; CHECK: (global $single-use2 anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 1337)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $single-use2 anyref (struct.new $A
+ (ref.null any)
+ (i31.new
+ (i32.const 1337)
+ )
+ ))
+
+ ;; CHECK: (global $other anyref (struct.new $A
+ ;; CHECK-NEXT: (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (struct.new $A
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 1337)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $other anyref (struct.new $A
+ (global.get $single-use1)
+ (global.get $single-use2)
+ ))
+)
+
+;; Test multiple related optimizations in one module: a chain.
+(module
+ ;; CHECK: (type $A (struct (field anyref)))
+ (type $A (struct (field anyref)))
+
+ ;; CHECK: (global $single-use1 anyref (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: ))
+ (global $single-use1 anyref (i31.new
+ (i32.const 42)
+ ))
+
+ ;; CHECK: (global $other1 anyref (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $other1 anyref (struct.new $A
+ (global.get $single-use1)
+ ))
+
+ ;; CHECK: (global $other2 anyref (struct.new $A
+ ;; CHECK-NEXT: (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $other2 anyref (struct.new $A
+ (global.get $other1)
+ ))
+
+ ;; CHECK: (global $other3 anyref (struct.new $A
+ ;; CHECK-NEXT: (struct.new $A
+ ;; CHECK-NEXT: (ref.i31
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: ))
+ (global $other3 anyref (global.get $other2))
+)