diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/heap2local.wast | 318 |
1 files changed, 310 insertions, 8 deletions
diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index 80eb9bd26..bd613e18c 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -13,9 +13,9 @@ ;; CHECK: (type $struct.recursive (struct (field (mut (ref null $struct.recursive))))) - ;; CHECK: (type $4 (func (param (ref null $struct.A)))) + ;; CHECK: (type $4 (func (result i32))) - ;; CHECK: (type $5 (func (result i32))) + ;; CHECK: (type $5 (func (param (ref null $struct.A)))) ;; CHECK: (type $6 (func (result anyref))) @@ -36,6 +36,10 @@ ;; CHECK: (type $11 (func (param i32))) + ;; CHECK: (type $12 (func (param eqref) (result i32))) + + ;; CHECK: (type $13 (func (param eqref eqref) (result i32))) + ;; CHECK: (func $simple (type $1) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 f64) @@ -474,7 +478,7 @@ ) ) - ;; CHECK: (func $send-ref (type $4) (param $0 (ref null $struct.A)) + ;; CHECK: (func $send-ref (type $5) (param $0 (ref null $struct.A)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $send-ref (param (ref null $struct.A)) @@ -887,7 +891,7 @@ ) ) - ;; CHECK: (func $tee (type $5) (result i32) + ;; CHECK: (func $tee (type $4) (result i32) ;; CHECK-NEXT: (local $ref (ref null $struct.A)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) @@ -1786,7 +1790,7 @@ ) ) - ;; CHECK: (func $ref-as-non-null-through-local (type $5) (result i32) + ;; CHECK: (func $ref-as-non-null-through-local (type $4) (result i32) ;; CHECK-NEXT: (local $ref (ref null $struct.A)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) @@ -1959,7 +1963,7 @@ (local.get $0) ) - ;; CHECK: (func $to-param (type $4) (param $ref (ref null $struct.A)) + ;; CHECK: (func $to-param (type $5) (param $ref (ref null $struct.A)) ;; CHECK-NEXT: (local $1 i32) ;; CHECK-NEXT: (local $2 f64) ;; CHECK-NEXT: (drop @@ -2006,7 +2010,7 @@ ) ) - ;; CHECK: (func $to-param-loop (type $4) (param $ref (ref null $struct.A)) + ;; CHECK: (func $to-param-loop (type $5) (param $ref (ref null $struct.A)) ;; CHECK-NEXT: (loop $loop ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get $struct.A 0 @@ -2046,7 +2050,7 @@ ) ) - ;; CHECK: (func $ref-cast (type $5) (result i32) + ;; CHECK: (func $ref-cast (type $4) (result i32) ;; CHECK-NEXT: (local $0 i32) ;; CHECK-NEXT: (local $1 f64) ;; CHECK-NEXT: (local $2 i32) @@ -2080,6 +2084,304 @@ ) ) ) + + ;; CHECK: (func $ref-eq (type $4) (result i32) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f64) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $ref-eq (result i32) + ;; Comparing an allocation to something else results in 0, and we can + ;; optimize away the allocation. + (ref.eq + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + (ref.null eq) + ) + ) + + ;; CHECK: (func $ref-eq-flip (type $12) (param $other eqref) (result i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 f64) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (local.get $other) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $ref-eq-flip (param $other eqref) (result i32) + ;; As above, but flipped, and compared to a local. + (ref.eq + (local.get $other) + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + ) + + ;; CHECK: (func $ref-eq-self (type $4) (result i32) + ;; CHECK-NEXT: (local $eq eqref) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 f64) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $ref-eq-self (result i32) + (local $eq eqref) + ;; Comparing to oneself results in 1, and we can optimize away the + ;; allocation. + (ref.eq + (local.tee $eq + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + (local.get $eq) + ) + ) + + ;; CHECK: (func $ref-eq-unreachable (type $4) (result i32) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f64) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq-unreachable (result i32) + ;; When a child is unreachable, the result does not matter (but we should + ;; still emit validating code). + (ref.eq + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + (unreachable) + ) + ) + + ;; CHECK: (func $ref-eq-unreachable-flipped (type $4) (result i32) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f64) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq-unreachable-flipped (result i32) + ;; As above, but with children flipped. + (ref.eq + (unreachable) + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + ) + + ;; CHECK: (func $ref-eq-unrelated (type $13) (param $x eqref) (param $y eqref) (result i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ref-eq-unrelated (param $x eqref) (param $y eqref) (result i32) + ;; We know nothing about either ref.eq arm, and do nothing, despite + ;; another allocation in the function (which ensures we enter the + ;; optimization part of the pass; that other allocation can be removed). + (drop + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + ) + (ref.eq + (local.get $x) + (local.get $y) + ) + ) + + ;; CHECK: (func $ref-eq-two (type $4) (result i32) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f64) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 f64) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 f64) + ;; CHECK-NEXT: (local $6 i32) + ;; CHECK-NEXT: (local $7 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.eq + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (f64.const 2.2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + (func $ref-eq-two (result i32) + ;; Two separate allocations. We can optimize them away, and the result is 0. + (ref.eq + (struct.new $struct.A + (i32.const 0) + (f64.const 0) + ) + (struct.new $struct.A + (i32.const 1) + (f64.const 2.2) + ) + ) + ) ) (module |