diff options
Diffstat (limited to 'test/lit/passes/heap2local.wast')
-rw-r--r-- | test/lit/passes/heap2local.wast | 1142 |
1 files changed, 1141 insertions, 1 deletions
diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index 90ac8a418..0d79cca5b 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -2,10 +2,11 @@ ;; (remove-unused-names allows the pass to see that blocks flow values) ;; RUN: wasm-opt %s -all --remove-unused-names --heap2local -S -o - | filecheck %s -;; RUN: wasm-opt %s -all --remove-unused-names --heap2local --nominal -S -o - | filecheck %s +;; RUN: wasm-opt %s -all --remove-unused-names --heap2local --nominal -S -o - | filecheck %s --check-prefix=NOMNL (module ;; CHECK: (type $struct.A (struct (field (mut i32)) (field (mut f64)))) + ;; NOMNL: (type $struct.A (struct_subtype (field (mut i32)) (field (mut f64)) data)) (type $struct.A (struct (field (mut i32)) (field (mut f64)))) ;; CHECK: (type $struct.recursive (struct (field (mut (ref null $struct.recursive))))) @@ -13,9 +14,15 @@ ;; CHECK: (type $struct.nonnullable (struct (field (ref $struct.A)))) ;; CHECK: (type $struct.packed (struct (field (mut i8)))) + ;; NOMNL: (type $struct.recursive (struct_subtype (field (mut (ref null $struct.recursive))) data)) + + ;; NOMNL: (type $struct.nonnullable (struct_subtype (field (ref $struct.A)) data)) + + ;; NOMNL: (type $struct.packed (struct_subtype (field (mut i8)) data)) (type $struct.packed (struct (field (mut i8)))) ;; CHECK: (type $struct.nondefaultable (struct (field (rtt $struct.A)))) + ;; NOMNL: (type $struct.nondefaultable (struct_subtype (field (rtt $struct.A)) data)) (type $struct.nondefaultable (struct (field (rtt $struct.A)))) (type $struct.recursive (struct (field (mut (ref null $struct.recursive))))) @@ -40,6 +47,24 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $simple + ;; NOMNL-NEXT: (local $0 i32) + ;; NOMNL-NEXT: (local $1 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $simple ;; Other passes can remove such a trivial case of an unused allocation, but ;; we still optimize it. @@ -69,6 +94,25 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $to-local + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $to-local (local $ref (ref null $struct.A)) ;; While set to a local, this allocation has no get/set operations. Other @@ -105,6 +149,29 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $one-get + ;; NOMNL-NEXT: (local $0 i32) + ;; NOMNL-NEXT: (local $1 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $one-get ;; An allocation followed by an immediate get of a field. This is a non- ;; escaping allocation, with a use, so we can optimize it out. The @@ -143,6 +210,29 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $one-get-b + ;; NOMNL-NEXT: (local $0 i32) + ;; NOMNL-NEXT: (local $1 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $one-get-b ;; Similar to the above, but using a different field index. (drop @@ -175,6 +265,27 @@ ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $one-set + ;; NOMNL-NEXT: (local $0 i32) + ;; NOMNL-NEXT: (local $1 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $one-set ;; A simple optimizable allocation only used in one set. (struct.set $struct.A 0 @@ -194,6 +305,15 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $packed + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (struct.get_u $struct.packed 0 + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.packed + ;; NOMNL-NEXT: (rtt.canon $struct.packed) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $packed ;; We do not optimize packed structs yet. (drop @@ -236,6 +356,37 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $with-init-values + ;; NOMNL-NEXT: (local $0 i32) + ;; NOMNL-NEXT: (local $1 f64) + ;; NOMNL-NEXT: (local $2 i32) + ;; NOMNL-NEXT: (local $3 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (i32.const 2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $3 + ;; NOMNL-NEXT: (f64.const 3.14159) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (local.get $3) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $with-init-values ;; When we get values to initialize the struct with, assign them to the ;; proper locals. @@ -263,6 +414,19 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $ignore-unreachable + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block ;; (replaces something unreachable we can't emit) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block + ;; NOMNL-NEXT: (i32.const 2) + ;; NOMNL-NEXT: (unreachable) + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $ignore-unreachable ;; An unreachable allocation is not worth trying to process; DCE should ;; remove it. @@ -287,6 +451,16 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $nondefaultable + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (struct.get $struct.nondefaultable 0 + ;; NOMNL-NEXT: (struct.new_with_rtt $struct.nondefaultable + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: (rtt.canon $struct.nondefaultable) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $nondefaultable ;; We do not optimize structs with nondefaultable types that we cannot ;; handle, like rtts. @@ -327,6 +501,33 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $simple-one-local-set + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $simple-one-local-set (local $ref (ref null $struct.A)) ;; A simple optimizable allocation only used in one set, and also stored @@ -368,6 +569,31 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $simple-one-local-get (result f64) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $simple-one-local-get (result f64) (local $ref (ref null $struct.A)) (local.set $ref @@ -384,6 +610,9 @@ ;; CHECK: (func $send-ref (param $0 (ref null $struct.A)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) + ;; NOMNL: (func $send-ref (param $0 (ref null $struct.A)) + ;; NOMNL-NEXT: (nop) + ;; NOMNL-NEXT: ) (func $send-ref (param (ref null $struct.A)) ) @@ -415,6 +644,34 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $safe-to-drop (result f64) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $safe-to-drop (result f64) (local $ref (ref null $struct.A)) (local.set $ref @@ -445,6 +702,20 @@ ;; CHECK-NEXT: (local.get $ref) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $escape-via-call (result f64) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $ref + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (call $send-ref + ;; NOMNL-NEXT: (local.get $ref) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.get $struct.A 1 + ;; NOMNL-NEXT: (local.get $ref) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $escape-via-call (result f64) (local $ref (ref null $struct.A)) (local.set $ref @@ -493,6 +764,38 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $safe-to-drop-multiflow (result f64) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $safe-to-drop-multiflow (result f64) (local $ref (ref null $struct.A)) (local.set $ref @@ -533,6 +836,24 @@ ;; CHECK-NEXT: (local.get $ref) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $escape-after-multiflow (result f64) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $ref + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (call $send-ref + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.get $ref) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.get $struct.A 1 + ;; NOMNL-NEXT: (local.get $ref) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $escape-after-multiflow (result f64) (local $ref (ref null $struct.A)) (local.set $ref @@ -572,6 +893,23 @@ ;; CHECK-NEXT: (local.get $ref) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $non-exclusive-set (result f64) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $ref + ;; NOMNL-NEXT: (select (result (ref $struct.A)) + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.get $struct.A 1 + ;; NOMNL-NEXT: (local.get $ref) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $non-exclusive-set (result f64) (local $ref (ref null $struct.A)) ;; A set that receives two different allocations, and so we should not try @@ -620,6 +958,34 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $local-copies (result f64) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $local-copies (result f64) (local $ref (ref null $struct.A)) (local.set $ref @@ -675,6 +1041,45 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $local-copies-2 + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $ref-2 (ref null $struct.A)) + ;; NOMNL-NEXT: (local $2 i32) + ;; NOMNL-NEXT: (local $3 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $3 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $3) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $local-copies-2 (local $ref (ref null $struct.A)) (local $ref-2 (ref null $struct.A)) @@ -731,6 +1136,37 @@ ;; CHECK-NEXT: (local.get $3) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $local-copies-conditional (param $x i32) (result f64) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $2 i32) + ;; NOMNL-NEXT: (local $3 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $3 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $3) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $local-copies-conditional (param $x i32) (result f64) (local $ref (ref null $struct.A)) (local.set $ref @@ -781,6 +1217,36 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $block-value (result f64) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (call $send-ref + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $block-value (result f64) (local $ref (ref null $struct.A)) (local.set $ref @@ -817,6 +1283,23 @@ ;; CHECK-NEXT: (local.get $ref) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $non-exclusive-get (param $x i32) (result f64) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $ref + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: (local.set $ref + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.get $struct.A 1 + ;; NOMNL-NEXT: (local.get $ref) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $non-exclusive-get (param $x i32) (result f64) (local $ref (ref null $struct.A)) (local.set $ref @@ -856,6 +1339,26 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tee (result i32) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $1) + ;; NOMNL-NEXT: ) (func $tee (result i32) (local $ref (ref null $struct.A)) (struct.get $struct.A 0 @@ -886,6 +1389,24 @@ ;; CHECK-NEXT: (ref.null $struct.recursive) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $tee-set + ;; NOMNL-NEXT: (local $ref (ref null $struct.recursive)) + ;; NOMNL-NEXT: (local $1 (ref null $struct.recursive)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.recursive)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (ref.null $struct.recursive) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.recursive) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.recursive) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (ref.null $struct.recursive) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $tee-set (local $ref (ref null $struct.recursive)) ;; As above, but with a set, and also a recursive type. @@ -910,6 +1431,17 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $set-value + ;; NOMNL-NEXT: (local $ref (ref null $struct.recursive)) + ;; NOMNL-NEXT: (struct.set $struct.recursive 0 + ;; NOMNL-NEXT: (ref.null $struct.recursive) + ;; NOMNL-NEXT: (local.tee $ref + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.recursive + ;; NOMNL-NEXT: (rtt.canon $struct.recursive) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $set-value (local $ref (ref null $struct.recursive)) (struct.set $struct.recursive 0 @@ -953,6 +1485,35 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $initialize-with-reference + ;; NOMNL-NEXT: (local $0 (ref null $struct.recursive)) + ;; NOMNL-NEXT: (local $1 (ref null $struct.recursive)) + ;; NOMNL-NEXT: (local $2 (ref null $struct.recursive)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.recursive)) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.recursive + ;; NOMNL-NEXT: (rtt.canon $struct.recursive) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.recursive) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.recursive) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.recursive)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.recursive) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $initialize-with-reference (local $0 (ref null $struct.recursive)) (local.set $0 @@ -990,6 +1551,18 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $ref) ;; CHECK-NEXT: ) + ;; NOMNL: (func $escape-flow-out (result anyref) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (struct.set $struct.A 0 + ;; NOMNL-NEXT: (local.tee $ref + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $ref) + ;; NOMNL-NEXT: ) (func $escape-flow-out (result anyref) (local $ref (ref null $struct.A)) (struct.set $struct.A 0 @@ -1018,6 +1591,20 @@ ;; CHECK-NEXT: (local.get $ref) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $escape-return (result anyref) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (struct.set $struct.A 0 + ;; NOMNL-NEXT: (local.tee $ref + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (local.get $ref) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $escape-return (result anyref) (local $ref (ref null $struct.A)) (struct.set $struct.A 0 @@ -1061,6 +1648,33 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $non-nullable (param $a (ref $struct.A)) + ;; NOMNL-NEXT: (local $1 (ref null $struct.A)) + ;; NOMNL-NEXT: (local $2 (ref null $struct.A)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref $struct.A)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.nonnullable)) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (local.get $a) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (ref.as_non_null + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.nonnullable) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.nonnullable) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.as_non_null + ;; NOMNL-NEXT: (local.get $1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $non-nullable (param $a (ref $struct.A)) (drop ;; An optimizable case where the type is non-nullable, which requires @@ -1171,6 +1785,103 @@ ;; CHECK-NEXT: (br $outer) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $before-loop-use-multi (param $x i32) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $2 i32) + ;; NOMNL-NEXT: (local $3 f64) + ;; NOMNL-NEXT: (local $4 i32) + ;; NOMNL-NEXT: (local $5 f64) + ;; NOMNL-NEXT: (loop $outer + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $4 + ;; NOMNL-NEXT: (i32.const 2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $5 + ;; NOMNL-NEXT: (f64.const 2.1828) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (local.get $4) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $3 + ;; NOMNL-NEXT: (local.get $5) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $3) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $3 + ;; NOMNL-NEXT: (f64.const 42) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (loop $inner + ;; NOMNL-NEXT: (block + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (i32.add + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (br_if $inner + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (if + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $3) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (br $outer) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $before-loop-use-multi (param $x i32) (local $ref (ref null $struct.A)) ;; Allocate in a loop, and use that allocation multiple times in that loop @@ -1294,6 +2005,71 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $multi-separate + ;; NOMNL-NEXT: (local $0 i32) + ;; NOMNL-NEXT: (local $1 f64) + ;; NOMNL-NEXT: (local $2 i32) + ;; NOMNL-NEXT: (local $3 f64) + ;; NOMNL-NEXT: (local $4 i32) + ;; NOMNL-NEXT: (local $5 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $3 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $4 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $5 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $5) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $multi-separate ;; Multiple independent things we can optimize. (drop @@ -1370,6 +2146,57 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $multi-separate-same-local-index + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (local $3 i32) + ;; NOMNL-NEXT: (local $4 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $3 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $4 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $3) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $multi-separate-same-local-index (local $ref (ref null $struct.A)) ;; Multiple independent things we can optimize that use the same local @@ -1448,6 +2275,58 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $multi-separate-different-local-index-overlapping-lifetimes + ;; NOMNL-NEXT: (local $ref1 (ref null $struct.A)) + ;; NOMNL-NEXT: (local $ref2 (ref null $struct.A)) + ;; NOMNL-NEXT: (local $2 i32) + ;; NOMNL-NEXT: (local $3 f64) + ;; NOMNL-NEXT: (local $4 i32) + ;; NOMNL-NEXT: (local $5 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $3 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $4 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $5 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $4) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $multi-separate-different-local-index-overlapping-lifetimes (local $ref1 (ref null $struct.A)) (local $ref2 (ref null $struct.A)) @@ -1494,6 +2373,25 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $get-through-block (result f64) + ;; NOMNL-NEXT: (local $0 (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.get $struct.A 1 + ;; NOMNL-NEXT: (block $block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (br_if $block + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $get-through-block (result f64) (local $0 (ref null $struct.A)) (local.set $0 @@ -1537,6 +2435,25 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $branch-to-block (result f64) + ;; NOMNL-NEXT: (local $0 (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.get $struct.A 1 + ;; NOMNL-NEXT: (block $block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (br_if $block + ;; NOMNL-NEXT: (local.get $0) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $branch-to-block (result f64) (local $0 (ref null $struct.A)) (local.set $0 @@ -1594,6 +2511,41 @@ ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $branch-to-block-no-fallthrough (result f64) + ;; NOMNL-NEXT: (local $0 (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block (result f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block $block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (br_if $block + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (f64.const 2.1828) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $branch-to-block-no-fallthrough (result f64) (local $0 (ref null $struct.A)) (local.set $0 @@ -1644,6 +2596,33 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $two-branches (result f64) + ;; NOMNL-NEXT: (local $0 (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.get $struct.A 1 + ;; NOMNL-NEXT: (block $block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (br_if $block + ;; NOMNL-NEXT: (local.get $0) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (br_if $block + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (f64.const 2.1828) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $two-branches (result f64) (local $0 (ref null $struct.A)) (local.set $0 @@ -1699,6 +2678,33 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $two-branches-b (result f64) + ;; NOMNL-NEXT: (local $0 (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.get $struct.A 1 + ;; NOMNL-NEXT: (block $block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (br_if $block + ;; NOMNL-NEXT: (local.get $0) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (br_if $block + ;; NOMNL-NEXT: (local.get $0) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (f64.const 2.1828) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $two-branches-b (result f64) (local $0 (ref null $struct.A)) (local.set $0 @@ -1749,6 +2755,27 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $br_if_flow (result f64) + ;; NOMNL-NEXT: (local $0 (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.get $struct.A 1 + ;; NOMNL-NEXT: (block $block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (call $send-ref + ;; NOMNL-NEXT: (br_if $block + ;; NOMNL-NEXT: (local.get $0) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (f64.const 2.1828) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $br_if_flow (result f64) (local $0 (ref null $struct.A)) (local.set $0 @@ -1804,6 +2831,38 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $ref-as-non-null + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.as_non_null + ;; NOMNL-NEXT: (ref.null any) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $ref-as-non-null (local $ref (ref null $struct.A)) (local.set $ref @@ -1856,6 +2915,34 @@ ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $ref-as-non-null-through-local (result i32) + ;; NOMNL-NEXT: (local $ref (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (block (result i32) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $1) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $ref-as-non-null-through-local (result i32) (local $ref (ref null $struct.A)) (local.set $ref @@ -1917,6 +3004,44 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) + ;; NOMNL: (func $br_if-allocation (result f64) + ;; NOMNL-NEXT: (local $0 (ref null $struct.A)) + ;; NOMNL-NEXT: (local $1 i32) + ;; NOMNL-NEXT: (local $2 f64) + ;; NOMNL-NEXT: (local $3 i32) + ;; NOMNL-NEXT: (local $4 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block $block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (br_if $block + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $3 + ;; NOMNL-NEXT: (i32.const 42) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $4 + ;; NOMNL-NEXT: (f64.const 13.37) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (local.get $3) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $2 + ;; NOMNL-NEXT: (local.get $4) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (rtt.canon $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (return + ;; NOMNL-NEXT: (f64.const 2.1828) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.get $2) + ;; NOMNL-NEXT: ) (func $br_if-allocation (result f64) (local $0 (ref null $struct.A)) (struct.get $struct.A 1 @@ -1953,6 +3078,21 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; NOMNL: (func $simple-no-rtt + ;; NOMNL-NEXT: (local $0 i32) + ;; NOMNL-NEXT: (local $1 f64) + ;; NOMNL-NEXT: (drop + ;; NOMNL-NEXT: (block (result (ref null $struct.A)) + ;; NOMNL-NEXT: (local.set $0 + ;; NOMNL-NEXT: (i32.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (local.set $1 + ;; NOMNL-NEXT: (f64.const 0) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (ref.null $struct.A) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: ) (func $simple-no-rtt (drop ;; This allocation has no rtt, so we have nothing to drop from it when |