diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/simplify-globals-single_use.wast | 332 |
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)) +) |