summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/dae-gc.wast226
1 files changed, 226 insertions, 0 deletions
diff --git a/test/lit/passes/dae-gc.wast b/test/lit/passes/dae-gc.wast
index 65d65d4c9..b3f8eddd2 100644
--- a/test/lit/passes/dae-gc.wast
+++ b/test/lit/passes/dae-gc.wast
@@ -2,8 +2,18 @@
;; RUN: wasm-opt %s -all --dae -S -o - | filecheck %s
(module
+ ;; CHECK: (type ${i32} (struct (field i32)))
+
;; CHECK: (type ${} (struct ))
(type ${} (struct))
+ (type ${i32} (struct (field i32)))
+ ;; CHECK: (type ${i32_i64} (struct (field i32) (field i64)))
+
+ ;; CHECK: (type ${f64} (struct (field f64)))
+ (type ${f64} (struct (field f64)))
+ (type ${i32_i64} (struct (field i32) (field i64)))
+ ;; CHECK: (type ${i32_f32} (struct (field i32) (field f32)))
+ (type ${i32_f32} (struct (field i32) (field f32)))
;; CHECK: (func $foo
;; CHECK-NEXT: (call $bar)
@@ -67,4 +77,220 @@
(rtt.canon ${})
)
)
+
+ ;; CHECK: (func $call-various-params-no
+ ;; CHECK-NEXT: (call $various-params-no
+ ;; CHECK-NEXT: (ref.null ${})
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $various-params-no
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (ref.null ${f64})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $call-various-params-no
+ ;; The first argument gets {} and {i32}; the second {i32} and {f64}; none of
+ ;; those pairs can be optimized.
+ (call $various-params-no
+ (ref.null ${})
+ (ref.null ${i32})
+ )
+ (call $various-params-no
+ (ref.null ${i32})
+ (ref.null ${f64})
+ )
+ )
+ ;; This function is called in ways that do not allow us to alter the types of
+ ;; its parameters (see last function).
+ ;; CHECK: (func $various-params-no (param $x (ref null ${})) (param $y (ref null ${}))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $various-params-no (param $x (ref null ${})) (param $y (ref null ${}))
+ ;; "Use" the locals to avoid other optimizations kicking in.
+ (drop (local.get $x))
+ (drop (local.get $y))
+ )
+
+ ;; CHECK: (func $call-various-params-yes
+ ;; CHECK-NEXT: (call $various-params-yes
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $various-params-yes
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: (ref.null ${i32_i64})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $call-various-params-yes
+ ;; The first argument gets {i32} and {i32}; the second {i32} and {i32_i64};
+ ;; both of those pairs can be optimized to {i32}.
+ ;; There is also an i32 in the middle, which should not confuse us.
+ (call $various-params-yes
+ (ref.null ${i32})
+ (i32.const 0)
+ (ref.null ${i32})
+ )
+ (call $various-params-yes
+ (ref.null ${i32})
+ (i32.const 1)
+ (ref.null ${i32_i64})
+ )
+ )
+ ;; This function is called in ways that *do* allow us to alter the types of
+ ;; its parameters (see last function).
+ ;; CHECK: (func $various-params-yes (param $x (ref null ${i32})) (param $i i32) (param $y (ref null ${i32}))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $i)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $various-params-yes (param $x (ref null ${})) (param $i i32) (param $y (ref null ${}))
+ ;; "Use" the locals to avoid other optimizations kicking in.
+ (drop (local.get $x))
+ (drop (local.get $i))
+ (drop (local.get $y))
+ )
+
+ ;; CHECK: (func $call-various-params-set
+ ;; CHECK-NEXT: (call $various-params-set
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $various-params-set
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: (ref.null ${i32_i64})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $call-various-params-set
+ ;; The first argument gets {i32} and {i32}; the second {i32} and {i32_i64;
+ ;; both of those pairs can be optimized to {i32}
+ (call $various-params-set
+ (ref.null ${i32})
+ (ref.null ${i32})
+ )
+ (call $various-params-set
+ (ref.null ${i32})
+ (ref.null ${i32_i64})
+ )
+ )
+ ;; This function is called in ways that *do* allow us to alter the types of
+ ;; its parameters (see last function), however, we reuse the parameters by
+ ;; writing to them, which causes problems in one case.
+ ;; CHECK: (func $various-params-set (param $x (ref null ${})) (param $y (ref null ${i32}))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (ref.null ${})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $y
+ ;; CHECK-NEXT: (ref.null ${i32_i64})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $various-params-set (param $x (ref null ${})) (param $y (ref null ${}))
+ ;; "Use" the locals to avoid other optimizations kicking in.
+ (drop (local.get $x))
+ (drop (local.get $y))
+ ;; Write to $x in a way that prevents us making the type more specific.
+ (local.set $x (ref.null ${}))
+ ;; Write to $y in a way that still allows us to make the type more specific.
+ (local.set $y (ref.null ${i32_i64}))
+ )
+
+ ;; CHECK: (func $call-various-params-null
+ ;; CHECK-NEXT: (call $various-params-null
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $various-params-null
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (ref.null ${i32})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $call-various-params-null
+ ;; The first argument gets non-null values, allowing us to refine it. The
+ ;; second gets only one.
+ (call $various-params-null
+ (ref.as_non_null (ref.null ${i32}))
+ (ref.null ${i32})
+ )
+ (call $various-params-null
+ (ref.as_non_null (ref.null ${i32}))
+ (ref.as_non_null (ref.null ${i32}))
+ )
+ )
+ ;; This function is called in ways that allow us to make the first parameter
+ ;; non-nullable.
+ ;; CHECK: (func $various-params-null (param $x (ref ${i32})) (param $y (ref null ${i32}))
+ ;; CHECK-NEXT: (local $temp i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $temp
+ ;; CHECK-NEXT: (local.get $temp)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $various-params-null (param $x (ref null ${})) (param $y (ref null ${}))
+ (local $temp i32)
+ ;; "Use" the locals to avoid other optimizations kicking in.
+ (drop (local.get $x))
+ (drop (local.get $y))
+ ;; Use a local in this function as well, which should be ignored by this pass
+ ;; (when we scan and update all local.gets and sets, we should only do so on
+ ;; parameters, and not vars - and we can crash if we scan/update things we
+ ;; should not).
+ (local.set $temp (local.get $temp))
+ )
+
+ ;; CHECK: (func $call-various-params-middle
+ ;; CHECK-NEXT: (call $various-params-middle
+ ;; CHECK-NEXT: (ref.null ${i32_i64})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $various-params-middle
+ ;; CHECK-NEXT: (ref.null ${i32_f32})
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $call-various-params-middle
+ ;; The argument gets {i32_i64} and {i32_f32}. This allows us to refine from
+ ;; {} to {i32}, a type "in the middle".
+ (call $various-params-middle
+ (ref.null ${i32_i64})
+ )
+ (call $various-params-middle
+ (ref.null ${i32_f32})
+ )
+ )
+ ;; CHECK: (func $various-params-middle (param $x (ref null ${i32}))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $various-params-middle (param $x (ref null ${}))
+ ;; "Use" the local to avoid other optimizations kicking in.
+ (drop (local.get $x))
+ )
)