summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/heap2local.wast116
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)
+ )
+)