diff options
Diffstat (limited to 'test/lit')
-rw-r--r-- | test/lit/help/wasm-opt.test | 5 | ||||
-rw-r--r-- | test/lit/help/wasm2js.test | 5 | ||||
-rw-r--r-- | test/lit/passes/global-effects.wast | 323 |
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) + ) +) |