summaryrefslogtreecommitdiff
path: root/test/lit
diff options
context:
space:
mode:
Diffstat (limited to 'test/lit')
-rw-r--r--test/lit/help/wasm-opt.test5
-rw-r--r--test/lit/help/wasm2js.test5
-rw-r--r--test/lit/passes/global-effects.wast323
3 files changed, 333 insertions, 0 deletions
diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test
index 6bc5bf770..64119ecd2 100644
--- a/test/lit/help/wasm-opt.test
+++ b/test/lit/help/wasm-opt.test
@@ -129,6 +129,8 @@
;; CHECK-NEXT: --directize turns indirect calls into direct
;; CHECK-NEXT: ones
;; CHECK-NEXT:
+;; CHECK-NEXT: --discard-global-effects discards global effect info
+;; CHECK-NEXT:
;; CHECK-NEXT: --duplicate-function-elimination removes duplicate functions
;; CHECK-NEXT:
;; CHECK-NEXT: --duplicate-import-elimination removes duplicate imports
@@ -157,6 +159,9 @@
;; CHECK-NEXT: --generate-dyncalls generate dynCall fuctions used
;; CHECK-NEXT: by emscripten ABI
;; CHECK-NEXT:
+;; CHECK-NEXT: --generate-global-effects generate global effect info
+;; CHECK-NEXT: (helps later passes)
+;; CHECK-NEXT:
;; CHECK-NEXT: --generate-i64-dyncalls generate dynCall functions used
;; CHECK-NEXT: by emscripten ABI, but only for
;; CHECK-NEXT: functions with i64 in their
diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test
index 3d483206a..e4ceab4b7 100644
--- a/test/lit/help/wasm2js.test
+++ b/test/lit/help/wasm2js.test
@@ -88,6 +88,8 @@
;; CHECK-NEXT: --directize turns indirect calls into direct
;; CHECK-NEXT: ones
;; CHECK-NEXT:
+;; CHECK-NEXT: --discard-global-effects discards global effect info
+;; CHECK-NEXT:
;; CHECK-NEXT: --duplicate-function-elimination removes duplicate functions
;; CHECK-NEXT:
;; CHECK-NEXT: --duplicate-import-elimination removes duplicate imports
@@ -116,6 +118,9 @@
;; CHECK-NEXT: --generate-dyncalls generate dynCall fuctions used
;; CHECK-NEXT: by emscripten ABI
;; CHECK-NEXT:
+;; CHECK-NEXT: --generate-global-effects generate global effect info
+;; CHECK-NEXT: (helps later passes)
+;; CHECK-NEXT:
;; CHECK-NEXT: --generate-i64-dyncalls generate dynCall functions used
;; CHECK-NEXT: by emscripten ABI, but only for
;; CHECK-NEXT: functions with i64 in their
diff --git a/test/lit/passes/global-effects.wast b/test/lit/passes/global-effects.wast
new file mode 100644
index 000000000..4207ae01f
--- /dev/null
+++ b/test/lit/passes/global-effects.wast
@@ -0,0 +1,323 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+
+;; Run without global effects, and run with, and also run with but discard them
+;; first (to check that discard works; that should be the same as without).
+
+;; RUN: foreach %s %t wasm-opt -all --vacuum -S -o - | filecheck %s --check-prefix WITHOUT
+;; RUN: foreach %s %t wasm-opt -all --generate-global-effects --vacuum -S -o - | filecheck %s --check-prefix INCLUDE
+;; RUN: foreach %s %t wasm-opt -all --generate-global-effects --discard-global-effects --vacuum -S -o - | filecheck %s --check-prefix DISCARD
+
+(module
+ ;; WITHOUT: (type $none_=>_none (func))
+
+ ;; WITHOUT: (type $none_=>_i32 (func (result i32)))
+
+ ;; WITHOUT: (type $i32_=>_none (func (param i32)))
+
+ ;; WITHOUT: (tag $tag (param))
+ ;; INCLUDE: (type $none_=>_none (func))
+
+ ;; INCLUDE: (type $none_=>_i32 (func (result i32)))
+
+ ;; INCLUDE: (type $i32_=>_none (func (param i32)))
+
+ ;; INCLUDE: (tag $tag (param))
+ ;; DISCARD: (type $none_=>_none (func))
+
+ ;; DISCARD: (type $none_=>_i32 (func (result i32)))
+
+ ;; DISCARD: (type $i32_=>_none (func (param i32)))
+
+ ;; DISCARD: (tag $tag (param))
+ (tag $tag)
+
+ ;; WITHOUT: (func $main
+ ;; WITHOUT-NEXT: (call $nop)
+ ;; WITHOUT-NEXT: (call $unreachable)
+ ;; WITHOUT-NEXT: (call $call-nop)
+ ;; WITHOUT-NEXT: (call $call-unreachable)
+ ;; WITHOUT-NEXT: (drop
+ ;; WITHOUT-NEXT: (call $unimportant-effects)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $main
+ ;; INCLUDE-NEXT: (call $unreachable)
+ ;; INCLUDE-NEXT: (call $call-nop)
+ ;; INCLUDE-NEXT: (call $call-unreachable)
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $main
+ ;; DISCARD-NEXT: (call $nop)
+ ;; DISCARD-NEXT: (call $unreachable)
+ ;; DISCARD-NEXT: (call $call-nop)
+ ;; DISCARD-NEXT: (call $call-unreachable)
+ ;; DISCARD-NEXT: (drop
+ ;; DISCARD-NEXT: (call $unimportant-effects)
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: )
+ (func $main
+ ;; Calling a function with no effects can be optimized away in INCLUDE (but
+ ;; not WITHOUT or DISCARD, where the global effect info is not available).
+ (call $nop)
+ ;; Calling a function with effects cannot.
+ (call $unreachable)
+ ;; Calling something that calls something with no effects can be optimized
+ ;; away in principle, but atm we don't look that far, so this is not
+ ;; optimized.
+ (call $call-nop)
+ ;; Calling something that calls something with effects cannot.
+ (call $call-unreachable)
+ ;; Calling something that only has unimportant effects can be optimized
+ ;; (see below for details).
+ (drop
+ (call $unimportant-effects)
+ )
+ )
+
+ ;; WITHOUT: (func $cycle
+ ;; WITHOUT-NEXT: (call $cycle)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $cycle
+ ;; INCLUDE-NEXT: (call $cycle)
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $cycle
+ ;; DISCARD-NEXT: (call $cycle)
+ ;; DISCARD-NEXT: )
+ (func $cycle
+ ;; Calling a function with no effects in a cycle cannot be optimized out -
+ ;; this must keep hanging forever.
+ (call $cycle)
+ )
+
+ ;; WITHOUT: (func $nop
+ ;; WITHOUT-NEXT: (nop)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $nop
+ ;; INCLUDE-NEXT: (nop)
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $nop
+ ;; DISCARD-NEXT: (nop)
+ ;; DISCARD-NEXT: )
+ (func $nop
+ (nop)
+ )
+
+ ;; WITHOUT: (func $unreachable
+ ;; WITHOUT-NEXT: (unreachable)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $unreachable
+ ;; INCLUDE-NEXT: (unreachable)
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $unreachable
+ ;; DISCARD-NEXT: (unreachable)
+ ;; DISCARD-NEXT: )
+ (func $unreachable
+ (unreachable)
+ )
+
+ ;; WITHOUT: (func $call-nop
+ ;; WITHOUT-NEXT: (call $nop)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $call-nop
+ ;; INCLUDE-NEXT: (nop)
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $call-nop
+ ;; DISCARD-NEXT: (call $nop)
+ ;; DISCARD-NEXT: )
+ (func $call-nop
+ ;; This call to a nop can be optimized out, as above, in INCLUDE.
+ (call $nop)
+ )
+
+ ;; WITHOUT: (func $call-unreachable
+ ;; WITHOUT-NEXT: (call $unreachable)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $call-unreachable
+ ;; INCLUDE-NEXT: (call $unreachable)
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $call-unreachable
+ ;; DISCARD-NEXT: (call $unreachable)
+ ;; DISCARD-NEXT: )
+ (func $call-unreachable
+ (call $unreachable)
+ )
+
+ ;; WITHOUT: (func $unimportant-effects (result i32)
+ ;; WITHOUT-NEXT: (local $x i32)
+ ;; WITHOUT-NEXT: (local.set $x
+ ;; WITHOUT-NEXT: (i32.const 100)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (return
+ ;; WITHOUT-NEXT: (local.get $x)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $unimportant-effects (result i32)
+ ;; INCLUDE-NEXT: (local $x i32)
+ ;; INCLUDE-NEXT: (local.set $x
+ ;; INCLUDE-NEXT: (i32.const 100)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: (return
+ ;; INCLUDE-NEXT: (local.get $x)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $unimportant-effects (result i32)
+ ;; DISCARD-NEXT: (local $x i32)
+ ;; DISCARD-NEXT: (local.set $x
+ ;; DISCARD-NEXT: (i32.const 100)
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: (return
+ ;; DISCARD-NEXT: (local.get $x)
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: )
+ (func $unimportant-effects (result i32)
+ (local $x i32)
+ ;; Operations on locals should not prevent optimization, as when we return
+ ;; from the function they no longer matter.
+ (local.set $x
+ (i32.const 100)
+ )
+ ;; A return is an effect that no longer matters once we exit the function.
+ (return
+ (local.get $x)
+ )
+ )
+
+ ;; WITHOUT: (func $call-throw-and-catch
+ ;; WITHOUT-NEXT: (try $try
+ ;; WITHOUT-NEXT: (do
+ ;; WITHOUT-NEXT: (call $throw)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (catch_all
+ ;; WITHOUT-NEXT: (nop)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $call-throw-and-catch
+ ;; INCLUDE-NEXT: (nop)
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $call-throw-and-catch
+ ;; DISCARD-NEXT: (try $try
+ ;; DISCARD-NEXT: (do
+ ;; DISCARD-NEXT: (call $throw)
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: (catch_all
+ ;; DISCARD-NEXT: (nop)
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: )
+ (func $call-throw-and-catch
+ (try
+ (do
+ ;; This call cannot be optimized out, as the target throws. However, the
+ ;; entire try-catch can be, since the call's only effect is to throw,
+ ;; and the catch_all catches that.
+ (call $throw)
+ )
+ (catch_all)
+ )
+ )
+
+ ;; WITHOUT: (func $call-unreachable-and-catch
+ ;; WITHOUT-NEXT: (try $try
+ ;; WITHOUT-NEXT: (do
+ ;; WITHOUT-NEXT: (call $unreachable)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (catch_all
+ ;; WITHOUT-NEXT: (nop)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $call-unreachable-and-catch
+ ;; INCLUDE-NEXT: (call $unreachable)
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $call-unreachable-and-catch
+ ;; DISCARD-NEXT: (try $try
+ ;; DISCARD-NEXT: (do
+ ;; DISCARD-NEXT: (call $unreachable)
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: (catch_all
+ ;; DISCARD-NEXT: (nop)
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: )
+ (func $call-unreachable-and-catch
+ (try
+ (do
+ ;; This call has a non-throw effect. We can optimize away the try-catch
+ ;; (since no exception can be thrown anyhow), but we must leave the
+ ;; call.
+ (call $unreachable)
+ )
+ (catch_all)
+ )
+ )
+
+ ;; WITHOUT: (func $call-throw-or-unreachable-and-catch (param $x i32)
+ ;; WITHOUT-NEXT: (try $try
+ ;; WITHOUT-NEXT: (do
+ ;; WITHOUT-NEXT: (if
+ ;; WITHOUT-NEXT: (local.get $x)
+ ;; WITHOUT-NEXT: (call $throw)
+ ;; WITHOUT-NEXT: (call $unreachable)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (catch_all
+ ;; WITHOUT-NEXT: (nop)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $call-throw-or-unreachable-and-catch (param $x i32)
+ ;; INCLUDE-NEXT: (try $try
+ ;; INCLUDE-NEXT: (do
+ ;; INCLUDE-NEXT: (if
+ ;; INCLUDE-NEXT: (local.get $x)
+ ;; INCLUDE-NEXT: (call $throw)
+ ;; INCLUDE-NEXT: (call $unreachable)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: (catch_all
+ ;; INCLUDE-NEXT: (nop)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $call-throw-or-unreachable-and-catch (param $x i32)
+ ;; DISCARD-NEXT: (try $try
+ ;; DISCARD-NEXT: (do
+ ;; DISCARD-NEXT: (if
+ ;; DISCARD-NEXT: (local.get $x)
+ ;; DISCARD-NEXT: (call $throw)
+ ;; DISCARD-NEXT: (call $unreachable)
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: (catch_all
+ ;; DISCARD-NEXT: (nop)
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: )
+ ;; DISCARD-NEXT: )
+ (func $call-throw-or-unreachable-and-catch (param $x i32)
+ ;; This try-catch-all's body will either call a throw or an unreachable.
+ ;; Since we have both possible effects, we cannot optimize anything here.
+ (try
+ (do
+ (if
+ (local.get $x)
+ (call $throw)
+ (call $unreachable)
+ )
+ )
+ (catch_all)
+ )
+ )
+
+ ;; WITHOUT: (func $throw
+ ;; WITHOUT-NEXT: (throw $tag)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $throw
+ ;; INCLUDE-NEXT: (throw $tag)
+ ;; INCLUDE-NEXT: )
+ ;; DISCARD: (func $throw
+ ;; DISCARD-NEXT: (throw $tag)
+ ;; DISCARD-NEXT: )
+ (func $throw
+ (throw $tag)
+ )
+)