summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/heap2local.wast52
1 files changed, 51 insertions, 1 deletions
diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast
index ca6439a8a..090ab4de0 100644
--- a/test/lit/passes/heap2local.wast
+++ b/test/lit/passes/heap2local.wast
@@ -1,7 +1,7 @@
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
;; (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: foreach %s %t wasm-opt -all --remove-unused-names --heap2local -S -o - | filecheck %s
(module
;; CHECK: (type $struct.A (struct (field (mut i32)) (field (mut f64))))
@@ -1896,3 +1896,53 @@
)
)
)
+
+(module
+ ;; CHECK: (type $A (struct (field (ref null $A))))
+ (type $A (struct (field (ref null $A))))
+ ;; CHECK: (type $B (sub $A (struct (field (ref $A)))))
+ (type $B (sub $A (struct (field (ref $A)))))
+
+ ;; CHECK: (func $func (type $none_=>_anyref) (result anyref)
+ ;; CHECK-NEXT: (local $a (ref $A))
+ ;; CHECK-NEXT: (local $1 (ref $A))
+ ;; CHECK-NEXT: (local $2 (ref $A))
+ ;; CHECK-NEXT: (ref.cast $B
+ ;; CHECK-NEXT: (block (result (ref $A))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result nullref)
+ ;; CHECK-NEXT: (local.set $2
+ ;; CHECK-NEXT: (struct.new $A
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $1
+ ;; CHECK-NEXT: (local.get $2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $func (result anyref)
+ (local $a (ref $A))
+ ;; Refinalization will be needed here, as a struct.new of $B can be
+ ;; optimized, and that reference flows through a tee, which loses type
+ ;; precision, into a local.get of $A. After heap2local we'll end up using a
+ ;; local of the type of $B's field which is more precise than $A's, and the
+ ;; cast must be updated to be non-nullable.
+ (ref.cast null $B
+ (struct.get $A 0
+ (local.tee $a
+ (struct.new $B
+ (struct.new $A
+ (ref.null none)
+ )
+ )
+ )
+ )
+ )
+ )
+)