blob: ac7405fd50925ad40cad949d620b116fb2556932 [file] [edit]
;; 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))
)