diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/heap2local.wast | 52 |
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) + ) + ) + ) + ) + ) + ) +) |