summaryrefslogtreecommitdiff
path: root/test/lit/passes/global-effects-eh-legacy.wast
diff options
context:
space:
mode:
Diffstat (limited to 'test/lit/passes/global-effects-eh-legacy.wast')
-rw-r--r--test/lit/passes/global-effects-eh-legacy.wast507
1 files changed, 507 insertions, 0 deletions
diff --git a/test/lit/passes/global-effects-eh-legacy.wast b/test/lit/passes/global-effects-eh-legacy.wast
new file mode 100644
index 000000000..7390f996d
--- /dev/null
+++ b/test/lit/passes/global-effects-eh-legacy.wast
@@ -0,0 +1,507 @@
+;; 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 WITHOUT
+
+(module
+
+ ;; WITHOUT: (type $void (func))
+ ;; INCLUDE: (type $void (func))
+ (type $void (func))
+
+ ;; WITHOUT: (type $1 (func (result i32)))
+
+ ;; WITHOUT: (type $2 (func (param i32)))
+
+ ;; WITHOUT: (import "a" "b" (func $import (type $void)))
+ ;; INCLUDE: (type $1 (func (result i32)))
+
+ ;; INCLUDE: (type $2 (func (param i32)))
+
+ ;; INCLUDE: (import "a" "b" (func $import (type $void)))
+ (import "a" "b" (func $import))
+
+ ;; WITHOUT: (table $t 0 funcref)
+ ;; INCLUDE: (table $t 0 funcref)
+ (table $t 0 funcref)
+
+ ;; WITHOUT: (elem declare func $throw)
+
+ ;; WITHOUT: (tag $tag)
+ ;; INCLUDE: (elem declare func $throw)
+
+ ;; INCLUDE: (tag $tag)
+ (tag $tag)
+
+ ;; WITHOUT: (func $main (type $void)
+ ;; 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: (call $throw)
+ ;; WITHOUT-NEXT: (call $throw-and-import)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $main (type $void)
+ ;; INCLUDE-NEXT: (call $unreachable)
+ ;; INCLUDE-NEXT: (call $call-unreachable)
+ ;; INCLUDE-NEXT: (call $throw)
+ ;; INCLUDE-NEXT: (call $throw-and-import)
+ ;; INCLUDE-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, since we compute transitive effects
+ (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)
+ )
+ ;; A throwing function cannot be removed.
+ (call $throw)
+ ;; A function that throws and calls an import definitely cannot be removed.
+ (call $throw-and-import)
+ )
+
+ ;; WITHOUT: (func $cycle (type $void)
+ ;; WITHOUT-NEXT: (call $cycle)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $cycle (type $void)
+ ;; INCLUDE-NEXT: (call $cycle)
+ ;; INCLUDE-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 $cycle-1 (type $void)
+ ;; WITHOUT-NEXT: (call $cycle-2)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $cycle-1 (type $void)
+ ;; INCLUDE-NEXT: (call $cycle-2)
+ ;; INCLUDE-NEXT: )
+ (func $cycle-1
+ ;; $cycle-1 and -2 form a cycle together, in which no call can be removed.
+ (call $cycle-2)
+ )
+
+ ;; WITHOUT: (func $cycle-2 (type $void)
+ ;; WITHOUT-NEXT: (call $cycle-1)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $cycle-2 (type $void)
+ ;; INCLUDE-NEXT: (call $cycle-1)
+ ;; INCLUDE-NEXT: )
+ (func $cycle-2
+ (call $cycle-1)
+ )
+
+ ;; WITHOUT: (func $nop (type $void)
+ ;; WITHOUT-NEXT: (nop)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $nop (type $void)
+ ;; INCLUDE-NEXT: (nop)
+ ;; INCLUDE-NEXT: )
+ (func $nop
+ (nop)
+ )
+
+ ;; WITHOUT: (func $unreachable (type $void)
+ ;; WITHOUT-NEXT: (unreachable)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $unreachable (type $void)
+ ;; INCLUDE-NEXT: (unreachable)
+ ;; INCLUDE-NEXT: )
+ (func $unreachable
+ (unreachable)
+ )
+
+ ;; WITHOUT: (func $call-nop (type $void)
+ ;; WITHOUT-NEXT: (call $nop)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $call-nop (type $void)
+ ;; INCLUDE-NEXT: (nop)
+ ;; INCLUDE-NEXT: )
+ (func $call-nop
+ ;; This call to a nop can be optimized out, as above, in INCLUDE.
+ (call $nop)
+ )
+
+ ;; WITHOUT: (func $call-unreachable (type $void)
+ ;; WITHOUT-NEXT: (call $unreachable)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $call-unreachable (type $void)
+ ;; INCLUDE-NEXT: (call $unreachable)
+ ;; INCLUDE-NEXT: )
+ (func $call-unreachable
+ (call $unreachable)
+ )
+
+ ;; WITHOUT: (func $unimportant-effects (type $1) (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 (type $1) (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: )
+ (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 (type $void)
+ ;; WITHOUT-NEXT: (try
+ ;; WITHOUT-NEXT: (do
+ ;; WITHOUT-NEXT: (call $throw)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (catch_all
+ ;; WITHOUT-NEXT: (nop)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (try
+ ;; WITHOUT-NEXT: (do
+ ;; WITHOUT-NEXT: (call $throw-and-import)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (catch_all
+ ;; WITHOUT-NEXT: (nop)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $call-throw-and-catch (type $void)
+ ;; INCLUDE-NEXT: (try
+ ;; INCLUDE-NEXT: (do
+ ;; INCLUDE-NEXT: (call $throw-and-import)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: (catch_all
+ ;; INCLUDE-NEXT: (nop)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-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)
+ )
+ (try
+ (do
+ ;; This call both throws and calls an import, and cannot be removed.
+ (call $throw-and-import)
+ )
+ (catch_all)
+ )
+ )
+
+ ;; WITHOUT: (func $return-call-throw-and-catch (type $void)
+ ;; WITHOUT-NEXT: (return_call $throw)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $return-call-throw-and-catch (type $void)
+ ;; INCLUDE-NEXT: (return_call $throw)
+ ;; INCLUDE-NEXT: )
+ (func $return-call-throw-and-catch
+ (try
+ (do
+ ;; This call cannot be optimized out, as the target throws. However, the
+ ;; surrounding try-catch can be removed even without global effects
+ ;; because the throw from the return_call is never observed by this
+ ;; try-catch.
+ (return_call $throw)
+ )
+ (catch_all)
+ )
+ )
+
+ ;; WITHOUT: (func $return-call-indirect-throw-and-catch (type $void)
+ ;; WITHOUT-NEXT: (return_call_indirect $t (type $void)
+ ;; WITHOUT-NEXT: (i32.const 0)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $return-call-indirect-throw-and-catch (type $void)
+ ;; INCLUDE-NEXT: (return_call_indirect $t (type $void)
+ ;; INCLUDE-NEXT: (i32.const 0)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ (func $return-call-indirect-throw-and-catch
+ (try
+ (do
+ ;; This call cannot be optimized out, as the target may throw. However,
+ ;; the surrounding try-catch can be removed even without global effects
+ ;; because the throw from the return_call is never observed by this
+ ;; try-catch.
+ (return_call_indirect
+ (i32.const 0)
+ )
+ )
+ (catch_all)
+ )
+ )
+
+ ;; WITHOUT: (func $return-call-ref-throw-and-catch (type $void)
+ ;; WITHOUT-NEXT: (return_call_ref $void
+ ;; WITHOUT-NEXT: (ref.func $throw)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $return-call-ref-throw-and-catch (type $void)
+ ;; INCLUDE-NEXT: (return_call_ref $void
+ ;; INCLUDE-NEXT: (ref.func $throw)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ (func $return-call-ref-throw-and-catch
+ (try
+ (do
+ ;; This call cannot be optimized out, as the target may throw. However,
+ ;; the surrounding try-catch can be removed even without global effects
+ ;; because the throw from the return_call is never observed by this
+ ;; try-catch.
+ (return_call_ref $void
+ (ref.func $throw)
+ )
+ )
+ (catch_all)
+ )
+ )
+
+ ;; WITHOUT: (func $call-return-call-throw-and-catch (type $void)
+ ;; WITHOUT-NEXT: (try
+ ;; WITHOUT-NEXT: (do
+ ;; WITHOUT-NEXT: (call $return-call-throw-and-catch)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (catch_all
+ ;; WITHOUT-NEXT: (nop)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (try
+ ;; WITHOUT-NEXT: (do
+ ;; WITHOUT-NEXT: (call $return-call-indirect-throw-and-catch)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (catch_all
+ ;; WITHOUT-NEXT: (nop)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (try
+ ;; WITHOUT-NEXT: (do
+ ;; WITHOUT-NEXT: (call $return-call-ref-throw-and-catch)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (catch_all
+ ;; WITHOUT-NEXT: (nop)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (call $return-call-throw-and-catch)
+ ;; WITHOUT-NEXT: (call $return-call-indirect-throw-and-catch)
+ ;; WITHOUT-NEXT: (call $return-call-ref-throw-and-catch)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $call-return-call-throw-and-catch (type $void)
+ ;; INCLUDE-NEXT: (try
+ ;; INCLUDE-NEXT: (do
+ ;; INCLUDE-NEXT: (call $return-call-indirect-throw-and-catch)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: (catch_all
+ ;; INCLUDE-NEXT: (nop)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: (try
+ ;; INCLUDE-NEXT: (do
+ ;; INCLUDE-NEXT: (call $return-call-ref-throw-and-catch)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: (catch_all
+ ;; INCLUDE-NEXT: (nop)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: (call $return-call-throw-and-catch)
+ ;; INCLUDE-NEXT: (call $return-call-indirect-throw-and-catch)
+ ;; INCLUDE-NEXT: (call $return-call-ref-throw-and-catch)
+ ;; INCLUDE-NEXT: )
+ (func $call-return-call-throw-and-catch
+ (try
+ (do
+ ;; Even though the body of the previous function is a try-catch_all, the
+ ;; function still throws because of its return_call, so this cannot be
+ ;; optimized out, but once again the entire try-catch can be.
+ (call $return-call-throw-and-catch)
+ )
+ (catch_all)
+ )
+ (try
+ (do
+ ;; This would be the same, except since it performs an indirect call, we
+ ;; conservatively assume it could have any effect, so we can't optimize.
+ (call $return-call-indirect-throw-and-catch)
+ )
+ (catch_all)
+ )
+ (try
+ (do
+ ;; Same here.
+ (call $return-call-ref-throw-and-catch)
+ )
+ (catch_all)
+ )
+
+ ;; These cannot be optimized out at all.
+ (call $return-call-throw-and-catch)
+ (call $return-call-indirect-throw-and-catch)
+ (call $return-call-ref-throw-and-catch)
+ )
+
+ ;; WITHOUT: (func $call-unreachable-and-catch (type $void)
+ ;; WITHOUT-NEXT: (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 (type $void)
+ ;; INCLUDE-NEXT: (call $unreachable)
+ ;; INCLUDE-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 (type $2) (param $x i32)
+ ;; WITHOUT-NEXT: (try
+ ;; WITHOUT-NEXT: (do
+ ;; WITHOUT-NEXT: (if
+ ;; WITHOUT-NEXT: (local.get $x)
+ ;; WITHOUT-NEXT: (then
+ ;; WITHOUT-NEXT: (call $throw)
+ ;; WITHOUT-NEXT: )
+ ;; WITHOUT-NEXT: (else
+ ;; WITHOUT-NEXT: (call $unreachable)
+ ;; WITHOUT-NEXT: )
+ ;; 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 (type $2) (param $x i32)
+ ;; INCLUDE-NEXT: (try
+ ;; INCLUDE-NEXT: (do
+ ;; INCLUDE-NEXT: (if
+ ;; INCLUDE-NEXT: (local.get $x)
+ ;; INCLUDE-NEXT: (then
+ ;; INCLUDE-NEXT: (call $throw)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: (else
+ ;; INCLUDE-NEXT: (call $unreachable)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: (catch_all
+ ;; INCLUDE-NEXT: (nop)
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-NEXT: )
+ ;; INCLUDE-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)
+ (then
+ (call $throw)
+ )
+ (else
+ (call $unreachable)
+ )
+ )
+ )
+ (catch_all)
+ )
+ )
+
+ ;; WITHOUT: (func $throw (type $void)
+ ;; WITHOUT-NEXT: (throw $tag)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $throw (type $void)
+ ;; INCLUDE-NEXT: (throw $tag)
+ ;; INCLUDE-NEXT: )
+ (func $throw
+ (throw $tag)
+ )
+
+ ;; WITHOUT: (func $throw-and-import (type $void)
+ ;; WITHOUT-NEXT: (throw $tag)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $throw-and-import (type $void)
+ ;; INCLUDE-NEXT: (throw $tag)
+ ;; INCLUDE-NEXT: )
+ (func $throw-and-import
+ (if
+ (i32.const 1)
+ (then
+ (throw $tag)
+ )
+ (else
+ (call $import)
+ )
+ )
+ )
+
+ ;; WITHOUT: (func $cycle-with-unknown-call (type $void)
+ ;; WITHOUT-NEXT: (call $cycle-with-unknown-call)
+ ;; WITHOUT-NEXT: (call $import)
+ ;; WITHOUT-NEXT: )
+ ;; INCLUDE: (func $cycle-with-unknown-call (type $void)
+ ;; INCLUDE-NEXT: (call $cycle-with-unknown-call)
+ ;; INCLUDE-NEXT: (call $import)
+ ;; INCLUDE-NEXT: )
+ (func $cycle-with-unknown-call
+ ;; This function can not only call itself recursively, but also calls an
+ ;; import. We should not remove anything here, and not error during the
+ ;; analysis (this guards against a bug where the import would make us toss
+ ;; away the effects object, and the infinite loop makes us set a property on
+ ;; that object, so it must check the object still exists).
+ (call $cycle-with-unknown-call)
+ (call $import)
+ )
+)