diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/heap2local.wast | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index 04c0936c6..37a9e7919 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -2078,3 +2078,119 @@ ) ) ) + +(module + ;; CHECK: (type $struct (struct (field (mut anyref)))) + (type $struct (struct (field (mut anyref)))) + + ;; CHECK: (func $multiple-interactions (type $1) + ;; CHECK-NEXT: (local $temp (ref $struct)) + ;; CHECK-NEXT: (local $1 anyref) + ;; CHECK-NEXT: (local.set $temp + ;; CHECK-NEXT: (struct.new_default $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $multiple-interactions + (local $temp (ref $struct)) + (local.set $temp + (struct.new_default $struct) + ) + ;; This expression interacts with its children in two different ways: the + ;; reference does not escape from the function, so we can optimize it into + ;; locals, while the value read from the local is written to the heap, so it + ;; does escape. However, we can optimize it after we optimize the first + ;; allocation away, which would happen if we ran another pass of heap2local + ;; (but we do not here). + (struct.set $struct 0 + (struct.new_default $struct) + (local.get $temp) + ) + ) + + ;; CHECK: (func $multiple-interactions-both-locals (type $1) + ;; CHECK-NEXT: (local $temp (ref $struct)) + ;; CHECK-NEXT: (local $temp2 (ref $struct)) + ;; CHECK-NEXT: (local $2 anyref) + ;; CHECK-NEXT: (local.set $temp + ;; CHECK-NEXT: (struct.new_default $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $multiple-interactions-both-locals + (local $temp (ref $struct)) + (local $temp2 (ref $struct)) + (local.set $temp + (struct.new_default $struct) + ) + ;; Now both allocations are written to locals. We can still optimize the + ;; second. + (local.set $temp2 + (struct.new_default $struct) + ) + (struct.set $struct 0 + (local.get $temp2) + (local.get $temp) + ) + ) + + ;; CHECK: (func $multiple-interactions-escapes (type $2) (result anyref) + ;; CHECK-NEXT: (local $temp (ref $struct)) + ;; CHECK-NEXT: (local $temp2 (ref $struct)) + ;; CHECK-NEXT: (local.set $temp + ;; CHECK-NEXT: (struct.new_default $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $temp2 + ;; CHECK-NEXT: (struct.new_default $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.set $struct 0 + ;; CHECK-NEXT: (local.get $temp2) + ;; CHECK-NEXT: (local.get $temp) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $temp2) + ;; CHECK-NEXT: ) + (func $multiple-interactions-escapes (result anyref) + (local $temp (ref $struct)) + (local $temp2 (ref $struct)) + (local.set $temp + (struct.new_default $struct) + ) + (local.set $temp2 + (struct.new_default $struct) + ) + (struct.set $struct 0 + (local.get $temp2) + (local.get $temp) + ) + ;; As above, but now the second allocation escapes, so nothing is + ;; optimized. + (local.get $temp2) + ) +) |