diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/dae-gc.wast | 226 |
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)) + ) ) |