| ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. |
| ;; RUN: foreach %s %t wasm-opt -all --minimize-rec-groups -S -o - | filecheck %s |
| |
| ;; Independent SCCs of described/descriptor types are separated. |
| (module |
| (rec |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $a (descriptor $a.desc) (struct)) |
| (type $a (descriptor $a.desc) (struct)) |
| ;; CHECK: (type $a.desc (describes $a) (struct)) |
| (type $a.desc (describes $a) (struct)) |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $b (descriptor $b.desc) (struct (field i32))) |
| (type $b (descriptor $b.desc) (struct (field i32))) |
| ;; CHECK: (type $b.desc (describes $b) (struct)) |
| (type $b.desc (describes $b) (struct)) |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $c (descriptor $c.desc) (struct (field i64))) |
| (type $c (descriptor $c.desc) (struct (field i64))) |
| ;; CHECK: (type $c.desc (describes $c) (struct)) |
| (type $c.desc (describes $c) (struct)) |
| ) |
| ;; CHECK: (global $a (ref null $a) (ref.null none)) |
| (global $a (ref null $a) (ref.null none)) |
| ;; CHECK: (global $b (ref null $b) (ref.null none)) |
| (global $b (ref null $b) (ref.null none)) |
| ;; CHECK: (global $c (ref null $c) (ref.null none)) |
| (global $c (ref null $c) (ref.null none)) |
| ) |
| |
| ;; Same as above, but there are three types in each chain. |
| (module |
| (rec |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $a.1 (descriptor $a.2) (struct)) |
| (type $a.1 (descriptor $a.2) (struct)) |
| ;; CHECK: (type $a.2 (describes $a.1) (descriptor $a.3) (struct)) |
| (type $a.2 (describes $a.1) (descriptor $a.3) (struct)) |
| ;; CHECK: (type $a.3 (describes $a.2) (struct)) |
| (type $a.3 (describes $a.2) (struct)) |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $b.1 (descriptor $b.2) (struct (field i32))) |
| (type $b.1 (descriptor $b.2) (struct (field i32))) |
| ;; CHECK: (type $b.2 (describes $b.1) (descriptor $b.3) (struct)) |
| (type $b.2 (describes $b.1) (descriptor $b.3) (struct)) |
| ;; CHECK: (type $b.3 (describes $b.2) (struct)) |
| (type $b.3 (describes $b.2) (struct)) |
| ) |
| |
| ;; CHECK: (global $a (ref null $a.1) (ref.null none)) |
| (global $a (ref null $a.1) (ref.null none)) |
| ;; CHECK: (global $b (ref null $b.1) (ref.null none)) |
| (global $b (ref null $b.1) (ref.null none)) |
| ) |
| |
| ;; Now the SCCs all have the same shape. The types cannot be reordered because |
| ;; described types must precede their descriptors, so we must use brands. |
| (module |
| (rec |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $a (descriptor $a.desc) (struct)) |
| (type $a (descriptor $a.desc) (struct)) |
| ;; CHECK: (type $a.desc (describes $a) (struct)) |
| (type $a.desc (describes $a) (struct)) |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $2 (struct)) |
| |
| ;; CHECK: (type $b (descriptor $b.desc) (struct)) |
| (type $b (descriptor $b.desc) (struct)) |
| ;; CHECK: (type $b.desc (describes $b) (struct)) |
| (type $b.desc (describes $b) (struct)) |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $c (descriptor $c.desc) (struct)) |
| (type $c (descriptor $c.desc) (struct)) |
| ;; CHECK: (type $6 (struct)) |
| |
| ;; CHECK: (type $c.desc (describes $c) (struct)) |
| (type $c.desc (describes $c) (struct)) |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $d (descriptor $d.desc) (struct)) |
| (type $d (descriptor $d.desc) (struct)) |
| ;; CHECK: (type $d.desc (describes $d) (struct)) |
| (type $d.desc (describes $d) (struct)) |
| ;; CHECK: (type $10 (struct)) |
| |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $11 (array (mut i8))) |
| |
| ;; CHECK: (type $e (descriptor $e.desc) (struct)) |
| (type $e (descriptor $e.desc) (struct)) |
| ;; CHECK: (type $e.desc (describes $e) (struct)) |
| (type $e.desc (describes $e) (struct)) |
| ) |
| |
| ;; CHECK: (global $a (ref null $a) (ref.null none)) |
| (global $a (ref null $a) (ref.null none)) |
| ;; CHECK: (global $b (ref null $b) (ref.null none)) |
| (global $b (ref null $b) (ref.null none)) |
| ;; CHECK: (global $c (ref null $c) (ref.null none)) |
| (global $c (ref null $c) (ref.null none)) |
| ;; CHECK: (global $d (ref null $d) (ref.null none)) |
| (global $d (ref null $d) (ref.null none)) |
| ;; CHECK: (global $e (ref null $e) (ref.null none)) |
| (global $e (ref null $e) (ref.null none)) |
| ) |
| |
| ;; The SCCs here contain an additional type that can be reordered around the |
| ;; described and descriptor types to differentiate the rec groups. |
| (module |
| (rec |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $a.other (struct (field (ref $a.desc)))) |
| |
| ;; CHECK: (type $a (descriptor $a.desc) (struct (field (ref $a.other)))) |
| (type $a (descriptor $a.desc) (struct (ref $a.other))) |
| ;; CHECK: (type $a.desc (describes $a) (struct)) |
| (type $a.desc (describes $a) (struct)) |
| (type $a.other (struct (ref $a.desc))) |
| |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $b (descriptor $b.desc) (struct (field (ref $b.other)))) |
| (type $b (descriptor $b.desc) (struct (ref $b.other))) |
| ;; CHECK: (type $b.other (struct (field (ref $b.desc)))) |
| |
| ;; CHECK: (type $b.desc (describes $b) (struct)) |
| (type $b.desc (describes $b) (struct)) |
| (type $b.other (struct (ref $b.desc))) |
| |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $c (descriptor $c.desc) (struct (field (ref $c.other)))) |
| (type $c (descriptor $c.desc) (struct (ref $c.other))) |
| ;; CHECK: (type $c.desc (describes $c) (struct)) |
| (type $c.desc (describes $c) (struct)) |
| ;; CHECK: (type $c.other (struct (field (ref $c.desc)))) |
| (type $c.other (struct (ref $c.desc))) |
| |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $9 (struct)) |
| |
| ;; CHECK: (type $d.other (struct (field (ref $d.desc)))) |
| |
| ;; CHECK: (type $d (descriptor $d.desc) (struct (field (ref $d.other)))) |
| (type $d (descriptor $d.desc) (struct (ref $d.other))) |
| ;; CHECK: (type $d.desc (describes $d) (struct)) |
| (type $d.desc (describes $d) (struct)) |
| (type $d.other (struct (ref $d.desc))) |
| ) |
| |
| ;; CHECK: (global $a (ref null $a) (ref.null none)) |
| (global $a (ref null $a) (ref.null none)) |
| ;; CHECK: (global $b (ref null $b) (ref.null none)) |
| (global $b (ref null $b) (ref.null none)) |
| ;; CHECK: (global $c (ref null $c) (ref.null none)) |
| (global $c (ref null $c) (ref.null none)) |
| ;; CHECK: (global $d (ref null $d) (ref.null none)) |
| (global $d (ref null $d) (ref.null none)) |
| ) |
| |
| ;; Here we have two chains in the same SCC. The types can be reordered around |
| ;; types in the other chain to differentiate the SCCs. |
| (module |
| (rec |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $a.2 (descriptor $a.2.desc) (struct (field (ref $a.1)))) |
| |
| ;; CHECK: (type $a.1 (descriptor $a.1.desc) (struct (field (ref $a.2)))) |
| (type $a.1 (descriptor $a.1.desc) (struct (field (ref $a.2)))) |
| ;; CHECK: (type $a.2.desc (describes $a.2) (struct)) |
| |
| ;; CHECK: (type $a.1.desc (describes $a.1) (struct)) |
| (type $a.1.desc (describes $a.1) (struct)) |
| (type $a.2 (descriptor $a.2.desc) (struct (field (ref $a.1)))) |
| (type $a.2.desc (describes $a.2) (struct)) |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $b.2 (descriptor $b.2.desc) (struct (field (ref $b.1)))) |
| |
| ;; CHECK: (type $b.1 (descriptor $b.1.desc) (struct (field (ref $b.2)))) |
| (type $b.1 (descriptor $b.1.desc) (struct (field (ref $b.2)))) |
| ;; CHECK: (type $b.1.desc (describes $b.1) (struct)) |
| (type $b.1.desc (describes $b.1) (struct)) |
| (type $b.2 (descriptor $b.2.desc) (struct (field (ref $b.1)))) |
| ;; CHECK: (type $b.2.desc (describes $b.2) (struct)) |
| (type $b.2.desc (describes $b.2) (struct)) |
| ;; CHECK: (rec |
| ;; CHECK-NEXT: (type $c.2 (descriptor $c.2.desc) (struct (field (ref $c.1)))) |
| |
| ;; CHECK: (type $c.2.desc (describes $c.2) (struct)) |
| |
| ;; CHECK: (type $c.1 (descriptor $c.1.desc) (struct (field (ref $c.2)))) |
| (type $c.1 (descriptor $c.1.desc) (struct (field (ref $c.2)))) |
| ;; CHECK: (type $c.1.desc (describes $c.1) (struct)) |
| (type $c.1.desc (describes $c.1) (struct)) |
| (type $c.2 (descriptor $c.2.desc) (struct (field (ref $c.1)))) |
| (type $c.2.desc (describes $c.2) (struct)) |
| ) |
| |
| ;; CHECK: (global $a (ref null $a.1) (ref.null none)) |
| (global $a (ref null $a.1) (ref.null none)) |
| ;; CHECK: (global $b (ref null $b.1) (ref.null none)) |
| (global $b (ref null $b.1) (ref.null none)) |
| ;; CHECK: (global $c (ref null $c.1) (ref.null none)) |
| (global $c (ref null $c.1) (ref.null none)) |
| ) |