summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/lit/help/optimization-opts.test2
-rw-r--r--test/lit/passes/intrinsic-lowering.wast53
-rw-r--r--test/lit/passes/vacuum-intrinsics.wast233
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)
+ )
+)