diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/help/optimization-opts.test | 2 | ||||
-rw-r--r-- | test/lit/passes/intrinsic-lowering.wast | 53 | ||||
-rw-r--r-- | test/lit/passes/vacuum-intrinsics.wast | 233 |
3 files changed, 288 insertions, 0 deletions
diff --git a/test/lit/help/optimization-opts.test b/test/lit/help/optimization-opts.test index 18f8970c2..177a1b620 100644 --- a/test/lit/help/optimization-opts.test +++ b/test/lit/help/optimization-opts.test @@ -284,6 +284,8 @@ ;; CHECK-NEXT: to intercept all loads and ;; CHECK-NEXT: stores ;; CHECK-NEXT: +;; CHECK-NEXT: --intrinsic-lowering lower away binaryen intrinsics +;; CHECK-NEXT: ;; CHECK-NEXT: --legalize-js-interface legalizes i64 types on the ;; CHECK-NEXT: import/export boundary ;; CHECK-NEXT: diff --git a/test/lit/passes/intrinsic-lowering.wast b/test/lit/passes/intrinsic-lowering.wast new file mode 100644 index 000000000..01bafbf86 --- /dev/null +++ b/test/lit/passes/intrinsic-lowering.wast @@ -0,0 +1,53 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --intrinsic-lowering -all -S -o - | filecheck %s + +(module + ;; CHECK: (type $none (func)) + (type $none (func)) + + ;; call.without.effects with no params. + ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $cwe-v (param funcref) (result i32))) + (import "binaryen-intrinsics" "call.without.effects" (func $cwe-v (param funcref) (result i32))) + + ;; call.without.effects with some params. + ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $cwe-dif (param f64 i32 funcref) (result f32))) + (import "binaryen-intrinsics" "call.without.effects" (func $cwe-dif (param f64) (param i32) (param funcref) (result f32))) + + ;; call.without.effects with no result. + ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $cwe-n (param funcref))) + (import "binaryen-intrinsics" "call.without.effects" (func $cwe-n (param funcref))) + + ;; CHECK: (func $test (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $test) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $dif + ;; CHECK-NEXT: (f64.const 3.14159) + ;; CHECK-NEXT: (i32.const 42) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_ref + ;; CHECK-NEXT: (ref.null $none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $test (result i32) + ;; These will be lowered into calls. + (drop (call $cwe-v (ref.func $test))) + (drop (call $cwe-dif (f64.const 3.14159) (i32.const 42) (ref.func $dif))) + ;; The last must be a call_ref, as we don't see a constant ref.func + (call $cwe-n + (ref.null $none) + ) + (i32.const 1) + ) + + ;; CHECK: (func $dif (param $0 f64) (param $1 i32) (result f32) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $dif (param f64) (param i32) (result f32) + ;; Helper function for the above. + (unreachable) + ) +) diff --git a/test/lit/passes/vacuum-intrinsics.wast b/test/lit/passes/vacuum-intrinsics.wast new file mode 100644 index 000000000..bd0f8ed60 --- /dev/null +++ b/test/lit/passes/vacuum-intrinsics.wast @@ -0,0 +1,233 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: wasm-opt %s --vacuum -all -S -o - | filecheck %s + +(module + ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects (param funcref) (result i32))) + (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects (param funcref) (result i32))) + + ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects-fj (param f32 funcref) (result i64))) + (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects-fj (param f32) (param funcref) (result i64))) + + ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects-ref (param funcref) (result (ref any)))) + (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects-ref (param funcref) (result (ref any)))) + + ;; CHECK: (func $used + ;; CHECK-NEXT: (local $i32 i32) + ;; CHECK-NEXT: (local.set $i32 + ;; CHECK-NEXT: (call $call.without.effects + ;; CHECK-NEXT: (ref.func $i) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $used + (local $i32 i32) + ;; The result is used (by the local.set), so we cannot do anything here. + (local.set $i32 + (call $call.without.effects (ref.func $i)) + ) + ) + + ;; CHECK: (func $unused + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $unused + ;; The result is unused, so we can remove the call. + (drop + (call $call.without.effects (ref.func $i)) + ) + ) + + ;; CHECK: (func $unused-fj + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $unused-fj + ;; As above, but with an extra float param and a different result type. + (drop + (call $call.without.effects-fj (f32.const 2.71828) (ref.func $fj)) + ) + ) + + ;; CHECK: (func $unused-fj-side-effects + ;; CHECK-NEXT: (local $f32 f32) + ;; CHECK-NEXT: (local.set $f32 + ;; CHECK-NEXT: (f32.const 2.718280076980591) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unused-fj-side-effects + (local $f32 f32) + ;; As above, but side effects in the param. We must keep the params around + ;; and drop them. + (drop + (call $call.without.effects-fj + (local.tee $f32 + (f32.const 2.71828) + ) + (ref.func $fj) + ) + ) + ) + + ;; CHECK: (func $unused-unreachable + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call $call.without.effects-fj + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (ref.func $fj) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unused-unreachable + ;; An unused result, but the call is unreachable and so we ignore it (and + ;; leave it for DCE). + (drop + (call $call.without.effects-fj (unreachable) (ref.func $fj)) + ) + ) + + ;; CHECK: (func $used-fallthrough + ;; CHECK-NEXT: (local $i32 i32) + ;; CHECK-NEXT: (local.set $i32 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (block $condition (result i32) + ;; CHECK-NEXT: (call $nop) + ;; CHECK-NEXT: (call $call.without.effects + ;; CHECK-NEXT: (ref.func $i) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $ifTrue (result i32) + ;; CHECK-NEXT: (call $nop) + ;; CHECK-NEXT: (call $call.without.effects + ;; CHECK-NEXT: (ref.func $i) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $ifFalse (result i32) + ;; CHECK-NEXT: (call $nop) + ;; CHECK-NEXT: (call $call.without.effects + ;; CHECK-NEXT: (ref.func $i) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $used-fallthrough + (local $i32 i32) + (local.set $i32 + (if (result i32) + ;; The block falls through a value that is used as the if condition. + (block $condition (result i32) + ;; Add a call to $nop so that the blocks are not optimized away. + (call $nop) + (call $call.without.effects (ref.func $i)) + ) + ;; The arms fall through their blocks and also through the if, and end + ;; up used by the set. + (block $ifTrue (result i32) + (call $nop) + (call $call.without.effects (ref.func $i)) + ) + (block $ifFalse (result i32) + (call $nop) + (call $call.without.effects (ref.func $i)) + ) + ) + ) + ) + + ;; CHECK: (func $unused-fallthrough + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (block $condition (result i32) + ;; CHECK-NEXT: (call $nop) + ;; CHECK-NEXT: (call $call.without.effects + ;; CHECK-NEXT: (ref.func $i) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $ifTrue (result i32) + ;; CHECK-NEXT: (call $nop) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $ifFalse (result i32) + ;; CHECK-NEXT: (call $nop) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unused-fallthrough + (drop + (if (result i32) + (block $condition (result i32) + (call $nop) + (call $call.without.effects (ref.func $i)) + ) + ;; As above, but now there is a drop outside the if, so the arms are + ;; unused and we can optimize them. + (block $ifTrue (result i32) + (call $nop) + (call $call.without.effects (ref.func $i)) + ) + (block $ifFalse (result i32) + (call $nop) + (call $call.without.effects (ref.func $i)) + ) + ) + ) + ) + + ;; CHECK: (func $unused-fallthrough-bad-type + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if (result (ref any)) + ;; CHECK-NEXT: (call $i) + ;; CHECK-NEXT: (call $call.without.effects-ref + ;; CHECK-NEXT: (ref.func $ref) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $call.without.effects-ref + ;; CHECK-NEXT: (ref.func $ref) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unused-fallthrough-bad-type + (drop + (if (result (ref any)) + (call $i) + ;; As above, but the type of these unused values prevents us from + ;; optimizing as we cannot create a "zero" for them. + (call $call.without.effects-ref (ref.func $ref)) + (call $call.without.effects-ref (ref.func $ref)) + ) + ) + ) + + ;; CHECK: (func $i (result i32) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $i (result i32) + ;; Helper function for the above. + (unreachable) + ) + + ;; CHECK: (func $fj (param $0 f32) (result i64) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $fj (param f32) (result i64) + ;; Helper function for the above. + (unreachable) + ) + + ;; CHECK: (func $ref (result (ref any)) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $ref (result (ref any)) + ;; Helper function for the above. + (unreachable) + ) + + + ;; CHECK: (func $nop + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $nop + ;; Helper function for the above. + (nop) + ) +) |