summaryrefslogtreecommitdiff
path: root/test/lit/passes
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-10-14 14:11:59 -0700
committerGitHub <noreply@github.com>2021-10-14 21:11:59 +0000
commitbf665976b1526ca7cf11bacf5745563dfe193206 (patch)
treea6bb2cf0fa5d1972fe55f872418665778e00dde5 /test/lit/passes
parentd592bad2b8fa777dab9682d2d2e47f9957c8051d (diff)
downloadbinaryen-bf665976b1526ca7cf11bacf5745563dfe193206.tar.gz
binaryen-bf665976b1526ca7cf11bacf5745563dfe193206.tar.bz2
binaryen-bf665976b1526ca7cf11bacf5745563dfe193206.zip
Switch from "extends" to M4 nominal syntax (#4248)
Switch from "extends" to M4 nominal syntax Change all test inputs from using the old (extends $super) syntax to using the new *_subtype syntax for their inputs and also update the printer to emit the new syntax. Add a new test explicitly testing the old notation to make sure it keeps working until we remove support for it.
Diffstat (limited to 'test/lit/passes')
-rw-r--r--test/lit/passes/cfp.wast188
-rw-r--r--test/lit/passes/dae-gc-refine-params.wast18
-rw-r--r--test/lit/passes/dae-gc-refine-return.wast16
-rw-r--r--test/lit/passes/dae-gc.wast29
-rw-r--r--test/lit/passes/gto-mutability.wast52
-rw-r--r--test/lit/passes/heap2local.wast1142
-rw-r--r--test/lit/passes/inlining_all-features.wast83
-rw-r--r--test/lit/passes/instrument-memory-gc.wast132
-rw-r--r--test/lit/passes/local-subtyping-nn.wast33
-rw-r--r--test/lit/passes/name-types.wast10
-rw-r--r--test/lit/passes/optimize-instructions-call_ref-roundtrip.wast8
-rw-r--r--test/lit/passes/optimize-instructions-gc-iit.wast14
-rw-r--r--test/lit/passes/optimize-instructions-gc.wast20
-rw-r--r--test/lit/passes/precompute-gc.wast457
-rw-r--r--test/lit/passes/roundtrip-gc-types.wast10
-rw-r--r--test/lit/passes/simplify-locals-gc.wast65
16 files changed, 2105 insertions, 172 deletions
diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast
index db6e108bf..99fd9d209 100644
--- a/test/lit/passes/cfp.wast
+++ b/test/lit/passes/cfp.wast
@@ -4,9 +4,9 @@
;; name getting in the way)
(module
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $struct (struct (field i32)))
+ ;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
;; CHECK: (func $impossible-get
;; CHECK-NEXT: (drop
@@ -31,9 +31,9 @@
)
(module
- ;; CHECK: (type $struct (struct (field i64)))
+ ;; CHECK: (type $struct (struct_subtype (field i64) data))
(type $struct (struct i64))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $test
;; CHECK-NEXT: (drop
@@ -74,9 +74,9 @@
)
(module
- ;; CHECK: (type $struct (struct (field f32)))
+ ;; CHECK: (type $struct (struct_subtype (field f32) data))
(type $struct (struct f32))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $test
;; CHECK-NEXT: (drop
@@ -114,9 +114,9 @@
)
(module
- ;; CHECK: (type $struct (struct (field f32)))
+ ;; CHECK: (type $struct (struct_subtype (field f32) data))
(type $struct (struct f32))
- ;; CHECK: (type $f32_=>_none (func (param f32)))
+ ;; CHECK: (type $f32_=>_none (func_subtype (param f32) func))
;; CHECK: (func $test (param $f f32)
;; CHECK-NEXT: (drop
@@ -150,9 +150,9 @@
;; Create in one function, get in another. The 10 should be forwarded to the
;; get.
(module
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $struct (struct (field i32)))
+ ;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -194,9 +194,9 @@
;; As before, but with the order of functions reversed to check for any ordering
;; issues.
(module
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $struct (struct (field i32)))
+ ;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
;; CHECK: (func $get
@@ -240,9 +240,9 @@
;; Different values assigned in the same function, in different struct.news,
;; so we cannot optimize the struct.get away.
(module
- ;; CHECK: (type $struct (struct (field f32)))
+ ;; CHECK: (type $struct (struct_subtype (field f32) data))
(type $struct (struct f32))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $test
;; CHECK-NEXT: (drop
@@ -286,9 +286,9 @@
;; Different values assigned in different functions, and one is a struct.set.
(module
- ;; CHECK: (type $struct (struct (field (mut f32))))
+ ;; CHECK: (type $struct (struct_subtype (field (mut f32)) data))
(type $struct (struct (mut f32)))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -337,9 +337,9 @@
;; As the last testcase, but the values happen to coincide, so we can optimize
;; the get into a constant.
(module
- ;; CHECK: (type $struct (struct (field (mut f32))))
+ ;; CHECK: (type $struct (struct_subtype (field (mut f32)) data))
(type $struct (struct (mut f32)))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -392,11 +392,11 @@
;; Check that we look into the fallthrough value that is assigned.
(module
- ;; CHECK: (type $struct (struct (field (mut f32))))
+ ;; CHECK: (type $struct (struct_subtype (field (mut f32)) data))
(type $struct (struct (mut f32)))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $i32_=>_none (func (param i32)))
+ ;; CHECK: (type $i32_=>_none (func_subtype (param i32) func))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -465,9 +465,9 @@
;; Test a function reference instead of a number.
(module
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $struct (struct (field funcref)))
+ ;; CHECK: (type $struct (struct_subtype (field funcref) data))
(type $struct (struct funcref))
;; CHECK: (elem declare func $test)
@@ -507,7 +507,7 @@
;; Test for unreachable creations, sets, and gets.
(module
(type $struct (struct (mut i32)))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $test
;; CHECK-NEXT: (drop
@@ -555,12 +555,12 @@
;; subtype, the get must trap anyhow (the reference it receives can
;; only be null in this closed world).
(module
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $struct (struct (field i32)))
+ ;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $substruct (struct (field i32)) (extends $struct))
- (type $substruct (struct i32) (extends $struct))
+ ;; CHECK: (type $substruct (struct_subtype (field i32) $struct))
+ (type $substruct (struct_subtype i32 $struct))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -602,12 +602,12 @@
;; will optimize the result to the only possible value. (In practice, though,
;; it will trap anyhow.)
(module
- ;; CHECK: (type $struct (struct (field (mut i32))))
+ ;; CHECK: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $substruct (struct (field (mut i32))) (extends $struct))
- (type $substruct (struct (mut i32)) (extends $struct))
+ ;; CHECK: (type $substruct (struct_subtype (field (mut i32)) $struct))
+ (type $substruct (struct_subtype (mut i32) $struct))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -658,12 +658,12 @@
;; reference to the subtype (we never create a supertype) and so we
;; can optimize.
(module
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $substruct (struct (field i32) (field f64)) (extends $struct))
- (type $substruct (struct i32 f64) (extends $struct))
+ ;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct))
+ (type $substruct (struct_subtype i32 f64 $struct))
- ;; CHECK: (type $struct (struct (field i32)))
+ ;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
;; CHECK: (func $create
@@ -708,12 +708,12 @@
;; Subtyping: Create both a subtype and a supertype, with identical constants
;; for the shared field, and get the supertype.
(module
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $struct (struct (field i32)))
+ ;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $substruct (struct (field i32) (field f64)) (extends $struct))
- (type $substruct (struct i32 f64) (extends $struct))
+ ;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct))
+ (type $substruct (struct_subtype i32 f64 $struct))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -770,12 +770,12 @@
;; for the shared field, preventing optimization, as a get of the
;; supertype may receive an instance of the subtype.
(module
- ;; CHECK: (type $struct (struct (field i32)))
+ ;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $substruct (struct (field i32) (field f64)) (extends $struct))
- (type $substruct (struct i32 f64) (extends $struct))
+ ;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct))
+ (type $substruct (struct_subtype i32 f64 $struct))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -828,12 +828,12 @@
;; shared between the types, but we only create the substruct with
;; one value, so we can optimize.
(module
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $substruct (struct (field i32) (field f64)) (extends $struct))
- (type $substruct (struct i32 f64) (extends $struct))
+ ;; CHECK: (type $substruct (struct_subtype (field i32) (field f64) $struct))
+ (type $substruct (struct_subtype i32 f64 $struct))
- ;; CHECK: (type $struct (struct (field i32)))
+ ;; CHECK: (type $struct (struct_subtype (field i32) data))
(type $struct (struct i32))
;; CHECK: (func $create
@@ -889,13 +889,13 @@
;; As above, but add a set of $struct. The set prevents the optimization.
(module
- ;; CHECK: (type $struct (struct (field (mut i32))))
+ ;; CHECK: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
- ;; CHECK: (type $substruct (struct (field (mut i32)) (field f64)) (extends $struct))
- (type $substruct (struct (mut i32) f64) (extends $struct))
+ ;; CHECK: (type $substruct (struct_subtype (field (mut i32)) (field f64) $struct))
+ (type $substruct (struct_subtype (mut i32) f64 $struct))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -954,15 +954,15 @@
;; Multi-level subtyping, check that we propagate not just to the immediate
;; supertype but all the way as needed.
(module
- ;; CHECK: (type $struct3 (struct (field i32) (field f64) (field anyref)) (extends $struct2))
- (type $struct3 (struct i32 f64 anyref) (extends $struct2))
+ ;; CHECK: (type $struct3 (struct_subtype (field i32) (field f64) (field anyref) $struct2))
+ (type $struct3 (struct_subtype i32 f64 anyref $struct2))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $struct2 (struct (field i32) (field f64)) (extends $struct1))
- (type $struct2 (struct i32 f64) (extends $struct1))
+ ;; CHECK: (type $struct2 (struct_subtype (field i32) (field f64) $struct1))
+ (type $struct2 (struct_subtype i32 f64 $struct1))
- ;; CHECK: (type $struct1 (struct (field i32)))
+ ;; CHECK: (type $struct1 (struct_subtype (field i32) data))
(type $struct1 (struct i32))
;; CHECK: (func $create
@@ -1089,18 +1089,18 @@
;; different values in the sub-most type. Create the top and bottom types, but
;; not the middle one.
(module
- ;; CHECK: (type $struct3 (struct (field i32) (field i32) (field f64) (field f64) (field anyref) (field anyref)) (extends $struct2))
- (type $struct3 (struct i32 i32 f64 f64 anyref anyref) (extends $struct2))
+ ;; CHECK: (type $struct3 (struct_subtype (field i32) (field i32) (field f64) (field f64) (field anyref) (field anyref) $struct2))
+ (type $struct3 (struct_subtype i32 i32 f64 f64 anyref anyref $struct2))
- ;; CHECK: (type $struct1 (struct (field i32) (field i32)))
+ ;; CHECK: (type $struct1 (struct_subtype (field i32) (field i32) data))
(type $struct1 (struct i32 i32))
- ;; CHECK: (type $struct2 (struct (field i32) (field i32) (field f64) (field f64)) (extends $struct1))
- (type $struct2 (struct i32 i32 f64 f64) (extends $struct1))
+ ;; CHECK: (type $struct2 (struct_subtype (field i32) (field i32) (field f64) (field f64) $struct1))
+ (type $struct2 (struct_subtype i32 i32 f64 f64 $struct1))
- ;; CHECK: (type $anyref_=>_none (func (param anyref)))
+ ;; CHECK: (type $anyref_=>_none (func_subtype (param anyref) func))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create (param $any anyref)
;; CHECK-NEXT: (drop
@@ -1323,14 +1323,14 @@
;; Multi-level subtyping with a different value in the middle of the chain. We
;; can only optimize $struct3.
(module
- ;; CHECK: (type $struct1 (struct (field (mut i32))))
+ ;; CHECK: (type $struct1 (struct_subtype (field (mut i32)) data))
(type $struct1 (struct (mut i32)))
- ;; CHECK: (type $struct2 (struct (field (mut i32)) (field f64)) (extends $struct1))
- (type $struct2 (struct (mut i32) f64) (extends $struct1))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $struct2 (struct_subtype (field (mut i32)) (field f64) $struct1))
+ (type $struct2 (struct_subtype (mut i32) f64 $struct1))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $struct3 (struct (field (mut i32)) (field f64) (field anyref)) (extends $struct2))
- (type $struct3 (struct (mut i32) f64 anyref) (extends $struct2))
+ ;; CHECK: (type $struct3 (struct_subtype (field (mut i32)) (field f64) (field anyref) $struct2))
+ (type $struct3 (struct_subtype (mut i32) f64 anyref $struct2))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -1423,16 +1423,16 @@
;; As above, but add not just a new of the middle class with a different value
;; but also a set. That prevents all optimizations.
(module
- ;; CHECK: (type $struct2 (struct (field (mut i32)) (field f64)) (extends $struct1))
- (type $struct2 (struct (mut i32) f64) (extends $struct1))
+ ;; CHECK: (type $struct2 (struct_subtype (field (mut i32)) (field f64) $struct1))
+ (type $struct2 (struct_subtype (mut i32) f64 $struct1))
- ;; CHECK: (type $struct1 (struct (field (mut i32))))
+ ;; CHECK: (type $struct1 (struct_subtype (field (mut i32)) data))
(type $struct1 (struct (mut i32)))
- ;; CHECK: (type $struct3 (struct (field (mut i32)) (field f64) (field anyref)) (extends $struct2))
- (type $struct3 (struct (mut i32) f64 anyref) (extends $struct2))
+ ;; CHECK: (type $struct3 (struct_subtype (field (mut i32)) (field f64) (field anyref) $struct2))
+ (type $struct3 (struct_subtype (mut i32) f64 anyref $struct2))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -1529,10 +1529,10 @@
;; Test for a struct with multiple fields, some of which are constant and hence
;; optimizable, and some not. Also test that some have the same type.
(module
- ;; CHECK: (type $struct (struct (field i32) (field f64) (field i32) (field f64) (field i32)))
+ ;; CHECK: (type $struct (struct_subtype (field i32) (field f64) (field i32) (field f64) (field i32) data))
(type $struct (struct i32 f64 i32 f64 i32))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -1653,20 +1653,20 @@
;; sets, and the final subtype C has a create and a get. The set to A should
;; apply to it, preventing optimization.
(module
- ;; CHECK: (type $C (struct (field (mut i32))) (extends $B))
- (type $C (struct (mut i32)) (extends $B))
+ ;; CHECK: (type $C (struct_subtype (field (mut i32)) $B))
+ (type $C (struct_subtype (mut i32) $B))
- ;; CHECK: (type $A (struct (field (mut i32))))
+ ;; CHECK: (type $A (struct_subtype (field (mut i32)) data))
(type $A (struct (mut i32)))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $ref|$A|_=>_none (func (param (ref $A))))
+ ;; CHECK: (type $ref|$A|_=>_none (func_subtype (param (ref $A)) func))
- ;; CHECK: (type $ref|$C|_=>_none (func (param (ref $C))))
+ ;; CHECK: (type $ref|$C|_=>_none (func_subtype (param (ref $C)) func))
- ;; CHECK: (type $B (struct (field (mut i32))) (extends $A))
- (type $B (struct (mut i32)) (extends $A))
+ ;; CHECK: (type $B (struct_subtype (field (mut i32)) $A))
+ (type $B (struct_subtype (mut i32) $A))
;; CHECK: (func $create
;; CHECK-NEXT: (drop
@@ -1715,10 +1715,10 @@
;; Copies of a field to itself can be ignored. As a result, we can optimize both
;; of the gets here.
(module
- ;; CHECK: (type $struct (struct (field (mut i32))))
+ ;; CHECK: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $test
;; CHECK-NEXT: (drop
@@ -1773,11 +1773,11 @@
;; Test of a near-copy, of a similar looking field (same index, and same field
;; type) but in a different struct.
(module
- ;; CHECK: (type $struct (struct (field (mut f32)) (field (mut i32))))
+ ;; CHECK: (type $struct (struct_subtype (field (mut f32)) (field (mut i32)) data))
(type $struct (struct (mut f32) (mut i32)))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $other (struct (field (mut f64)) (field (mut i32))))
+ ;; CHECK: (type $other (struct_subtype (field (mut f64)) (field (mut i32)) data))
(type $other (struct (mut f64) (mut i32)))
;; CHECK: (func $test
@@ -1824,10 +1824,10 @@
;; Test of a near-copy, of a different index.
(module
- ;; CHECK: (type $struct (struct (field (mut i32)) (field (mut i32))))
+ ;; CHECK: (type $struct (struct_subtype (field (mut i32)) (field (mut i32)) data))
(type $struct (struct (mut i32) (mut i32)))
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
;; CHECK: (func $test
;; CHECK-NEXT: (drop
diff --git a/test/lit/passes/dae-gc-refine-params.wast b/test/lit/passes/dae-gc-refine-params.wast
index f4d4ab056..7c986bd4e 100644
--- a/test/lit/passes/dae-gc-refine-params.wast
+++ b/test/lit/passes/dae-gc-refine-params.wast
@@ -4,24 +4,24 @@
(module
;; CHECK: (type ${i32} (struct (field i32)))
- ;; NOMNL: (type ${i32} (struct (field i32)) (extends ${}))
- (type ${i32} (struct (field i32)) (extends ${}))
+ ;; NOMNL: (type ${i32} (struct_subtype (field i32) ${}))
+ (type ${i32} (struct_subtype (field i32) ${}))
;; CHECK: (type ${} (struct ))
- ;; NOMNL: (type ${} (struct ))
+ ;; NOMNL: (type ${} (struct_subtype data))
(type ${} (struct))
;; CHECK: (type ${i32_i64} (struct (field i32) (field i64)))
- ;; NOMNL: (type ${i32_i64} (struct (field i32) (field i64)) (extends ${i32}))
- (type ${i32_i64} (struct (field i32) (field i64)) (extends ${i32}))
+ ;; NOMNL: (type ${i32_i64} (struct_subtype (field i32) (field i64) ${i32}))
+ (type ${i32_i64} (struct_subtype (field i32) (field i64) ${i32}))
;; CHECK: (type ${f64} (struct (field f64)))
- ;; NOMNL: (type ${f64} (struct (field f64)) (extends ${}))
- (type ${f64} (struct (field f64)) (extends ${}))
+ ;; NOMNL: (type ${f64} (struct_subtype (field f64) ${}))
+ (type ${f64} (struct_subtype (field f64) ${}))
;; CHECK: (type ${i32_f32} (struct (field i32) (field f32)))
- ;; NOMNL: (type ${i32_f32} (struct (field i32) (field f32)) (extends ${i32}))
- (type ${i32_f32} (struct (field i32) (field f32)) (extends ${i32}))
+ ;; NOMNL: (type ${i32_f32} (struct_subtype (field i32) (field f32) ${i32}))
+ (type ${i32_f32} (struct_subtype (field i32) (field f32) ${i32}))
;; CHECK: (func $call-various-params-no
;; CHECK-NEXT: (call $various-params-no
diff --git a/test/lit/passes/dae-gc-refine-return.wast b/test/lit/passes/dae-gc-refine-return.wast
index 73f1d040f..60b340cdc 100644
--- a/test/lit/passes/dae-gc-refine-return.wast
+++ b/test/lit/passes/dae-gc-refine-return.wast
@@ -4,23 +4,23 @@
(module
;; CHECK: (type $return_{} (func (result (ref ${}))))
- ;; NOMNL: (type $return_{} (func (result (ref ${}))))
+ ;; NOMNL: (type $return_{} (func_subtype (result (ref ${})) func))
(type $return_{} (func (result (ref ${}))))
;; CHECK: (type ${i32_f32} (struct (field i32) (field f32)))
- ;; NOMNL: (type ${i32_f32} (struct (field i32) (field f32)) (extends ${i32}))
- (type ${i32_f32} (struct (field i32) (field f32)) (extends ${i32}))
+ ;; NOMNL: (type ${i32_f32} (struct_subtype (field i32) (field f32) ${i32}))
+ (type ${i32_f32} (struct_subtype (field i32) (field f32) ${i32}))
;; CHECK: (type ${i32_i64} (struct (field i32) (field i64)))
- ;; NOMNL: (type ${i32_i64} (struct (field i32) (field i64)) (extends ${i32}))
- (type ${i32_i64} (struct (field i32) (field i64)) (extends ${i32}))
+ ;; NOMNL: (type ${i32_i64} (struct_subtype (field i32) (field i64) ${i32}))
+ (type ${i32_i64} (struct_subtype (field i32) (field i64) ${i32}))
;; CHECK: (type ${i32} (struct (field i32)))
- ;; NOMNL: (type ${i32} (struct (field i32)) (extends ${}))
- (type ${i32} (struct (field i32)) (extends ${}))
+ ;; NOMNL: (type ${i32} (struct_subtype (field i32) ${}))
+ (type ${i32} (struct_subtype (field i32) ${}))
;; CHECK: (type ${} (struct ))
- ;; NOMNL: (type ${} (struct ))
+ ;; NOMNL: (type ${} (struct_subtype data))
(type ${} (struct))
(table 1 1 funcref)
diff --git a/test/lit/passes/dae-gc.wast b/test/lit/passes/dae-gc.wast
index 899087e7f..3cc1c8653 100644
--- a/test/lit/passes/dae-gc.wast
+++ b/test/lit/passes/dae-gc.wast
@@ -1,14 +1,18 @@
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
;; RUN: wasm-opt %s -all --dae -S -o - | filecheck %s
-;; RUN: wasm-opt %s -all --dae --nominal -S -o - | filecheck %s
+;; RUN: wasm-opt %s -all --dae --nominal -S -o - | filecheck %s --check-prefix=NOMNL
(module
;; CHECK: (type ${} (struct ))
+ ;; NOMNL: (type ${} (struct_subtype data))
(type ${} (struct))
;; CHECK: (func $foo
;; CHECK-NEXT: (call $bar)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $foo
+ ;; NOMNL-NEXT: (call $bar)
+ ;; NOMNL-NEXT: )
(func $foo
(call $bar
(i31.new
@@ -31,6 +35,21 @@
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $bar
+ ;; NOMNL-NEXT: (local $0 (ref null i31))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (local.tee $0
+ ;; NOMNL-NEXT: (i31.new
+ ;; NOMNL-NEXT: (i32.const 2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.tee $0
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $bar (param $0 i31ref)
(drop
;; after the parameter is removed, we create a nullable local to replace it,
@@ -55,6 +74,9 @@
;; CHECK: (func $get-rtt (param $0 (rtt ${}))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $get-rtt (param $0 (rtt ${}))
+ ;; NOMNL-NEXT: (nop)
+ ;; NOMNL-NEXT: )
(func $get-rtt (param $0 (rtt ${}))
(nop)
)
@@ -63,6 +85,11 @@
;; CHECK-NEXT: (rtt.canon ${})
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $send-rtt
+ ;; NOMNL-NEXT: (call $get-rtt
+ ;; NOMNL-NEXT: (rtt.canon ${})
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $send-rtt
(call $get-rtt
(rtt.canon ${})
diff --git a/test/lit/passes/gto-mutability.wast b/test/lit/passes/gto-mutability.wast
index 83b9f4bf5..8610e0760 100644
--- a/test/lit/passes/gto-mutability.wast
+++ b/test/lit/passes/gto-mutability.wast
@@ -7,13 +7,13 @@
;; The struct here has three fields, and the second of them has no struct.set
;; which means we can make it immutable.
- ;; CHECK: (type $struct (struct (field (mut funcref)) (field funcref) (field (mut funcref))))
+ ;; CHECK: (type $struct (struct_subtype (field (mut funcref)) (field funcref) (field (mut funcref)) data))
(type $struct (struct (field (mut funcref)) (field (mut funcref)) (field (mut funcref))))
;; Test that we update tag types properly.
- ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct))))
+ ;; CHECK: (type $ref|$struct|_=>_none (func_subtype (param (ref $struct)) func))
- ;; CHECK: (type $none_=>_ref?|$struct| (func (result (ref null $struct))))
+ ;; CHECK: (type $none_=>_ref?|$struct| (func_subtype (result (ref null $struct)) func))
;; CHECK: (tag $tag (param (ref $struct)))
(tag $tag (param (ref $struct)))
@@ -120,12 +120,12 @@
;; Test recursion between structs where we only modify one. Specifically $B
;; has no writes to either of its fields.
- ;; CHECK: (type $A (struct (field (mut (ref null $B))) (field (mut i32))))
+ ;; CHECK: (type $A (struct_subtype (field (mut (ref null $B))) (field (mut i32)) data))
(type $A (struct (field (mut (ref null $B))) (field (mut i32)) ))
- ;; CHECK: (type $B (struct (field (ref null $A)) (field f64)))
+ ;; CHECK: (type $B (struct_subtype (field (ref null $A)) (field f64) data))
(type $B (struct (field (mut (ref null $A))) (field (mut f64)) ))
- ;; CHECK: (type $ref|$A|_=>_none (func (param (ref $A))))
+ ;; CHECK: (type $ref|$A|_=>_none (func_subtype (param (ref $A)) func))
;; CHECK: (func $func (param $x (ref $A))
;; CHECK-NEXT: (struct.set $A 0
@@ -152,13 +152,13 @@
(module
;; As before, but flipped so that $A's fields can become immutable.
- ;; CHECK: (type $B (struct (field (mut (ref null $A))) (field (mut f64))))
+ ;; CHECK: (type $B (struct_subtype (field (mut (ref null $A))) (field (mut f64)) data))
(type $B (struct (field (mut (ref null $A))) (field (mut f64)) ))
- ;; CHECK: (type $A (struct (field (ref null $B)) (field i32)))
+ ;; CHECK: (type $A (struct_subtype (field (ref null $B)) (field i32) data))
(type $A (struct (field (mut (ref null $B))) (field (mut i32)) ))
- ;; CHECK: (type $ref|$B|_=>_none (func (param (ref $B))))
+ ;; CHECK: (type $ref|$B|_=>_none (func_subtype (param (ref $B)) func))
;; CHECK: (func $func (param $x (ref $B))
;; CHECK-NEXT: (struct.set $B 0
@@ -185,13 +185,13 @@
(module
;; As before, but now one field in each can become immutable.
- ;; CHECK: (type $B (struct (field (ref null $A)) (field (mut f64))))
+ ;; CHECK: (type $B (struct_subtype (field (ref null $A)) (field (mut f64)) data))
(type $B (struct (field (mut (ref null $A))) (field (mut f64)) ))
- ;; CHECK: (type $A (struct (field (mut (ref null $B))) (field i32)))
+ ;; CHECK: (type $A (struct_subtype (field (mut (ref null $B))) (field i32) data))
(type $A (struct (field (mut (ref null $B))) (field (mut i32)) ))
- ;; CHECK: (type $ref|$A|_ref|$B|_=>_none (func (param (ref $A) (ref $B))))
+ ;; CHECK: (type $ref|$A|_ref|$B|_=>_none (func_subtype (param (ref $A) (ref $B)) func))
;; CHECK: (func $func (param $x (ref $A)) (param $y (ref $B))
;; CHECK-NEXT: (struct.set $A 0
@@ -220,10 +220,10 @@
;; Field #1 is mutable and can become so.
;; Field #2 is mutable and must remain so.
- ;; CHECK: (type $struct (struct (field i32) (field i32) (field (mut i32))))
+ ;; CHECK: (type $struct (struct_subtype (field i32) (field i32) (field (mut i32)) data))
(type $struct (struct (field i32) (field (mut i32)) (field (mut i32))))
- ;; CHECK: (type $ref|$struct|_=>_none (func (param (ref $struct))))
+ ;; CHECK: (type $ref|$struct|_=>_none (func_subtype (param (ref $struct)) func))
;; CHECK: (func $func (param $x (ref $struct))
;; CHECK-NEXT: (struct.set $struct 2
@@ -243,12 +243,12 @@
;; Subtyping. Without a write in either supertype or subtype, we can
;; optimize the field to be immutable.
- ;; CHECK: (type $none_=>_none (func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
- ;; CHECK: (type $super (struct (field i32)))
+ ;; CHECK: (type $super (struct_subtype (field i32) data))
(type $super (struct (field (mut i32))))
- ;; CHECK: (type $sub (struct (field i32)) (extends $super))
- (type $sub (struct (field (mut i32))) (extends $super))
+ ;; CHECK: (type $sub (struct_subtype (field i32) $super))
+ (type $sub (struct_subtype (field (mut i32)) $super))
;; CHECK: (func $func
;; CHECK-NEXT: (drop
@@ -280,12 +280,12 @@
(module
;; As above, but add a write in the super, which prevents optimization.
- ;; CHECK: (type $super (struct (field (mut i32))))
+ ;; CHECK: (type $super (struct_subtype (field (mut i32)) data))
(type $super (struct (field (mut i32))))
- ;; CHECK: (type $ref|$super|_=>_none (func (param (ref $super))))
+ ;; CHECK: (type $ref|$super|_=>_none (func_subtype (param (ref $super)) func))
- ;; CHECK: (type $sub (struct (field (mut i32))) (extends $super))
- (type $sub (struct (field (mut i32))) (extends $super))
+ ;; CHECK: (type $sub (struct_subtype (field (mut i32)) $super))
+ (type $sub (struct_subtype (field (mut i32)) $super))
;; CHECK: (func $func (param $x (ref $super))
;; CHECK-NEXT: (drop
@@ -325,13 +325,13 @@
(module
;; As above, but add a write in the sub, which prevents optimization.
- ;; CHECK: (type $sub (struct (field (mut i32))) (extends $super))
+ ;; CHECK: (type $sub (struct_subtype (field (mut i32)) $super))
- ;; CHECK: (type $ref|$sub|_=>_none (func (param (ref $sub))))
+ ;; CHECK: (type $ref|$sub|_=>_none (func_subtype (param (ref $sub)) func))
- ;; CHECK: (type $super (struct (field (mut i32))))
+ ;; CHECK: (type $super (struct_subtype (field (mut i32)) data))
(type $super (struct (field (mut i32))))
- (type $sub (struct (field (mut i32))) (extends $super))
+ (type $sub (struct_subtype (field (mut i32)) $super))
;; CHECK: (func $func (param $x (ref $sub))
;; CHECK-NEXT: (struct.set $sub 0
diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast
index 90ac8a418..0d79cca5b 100644
--- a/test/lit/passes/heap2local.wast
+++ b/test/lit/passes/heap2local.wast
@@ -2,10 +2,11 @@
;; (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: wasm-opt %s -all --remove-unused-names --heap2local --nominal -S -o - | filecheck %s
+;; RUN: wasm-opt %s -all --remove-unused-names --heap2local --nominal -S -o - | filecheck %s --check-prefix=NOMNL
(module
;; CHECK: (type $struct.A (struct (field (mut i32)) (field (mut f64))))
+ ;; NOMNL: (type $struct.A (struct_subtype (field (mut i32)) (field (mut f64)) data))
(type $struct.A (struct (field (mut i32)) (field (mut f64))))
;; CHECK: (type $struct.recursive (struct (field (mut (ref null $struct.recursive)))))
@@ -13,9 +14,15 @@
;; CHECK: (type $struct.nonnullable (struct (field (ref $struct.A))))
;; CHECK: (type $struct.packed (struct (field (mut i8))))
+ ;; NOMNL: (type $struct.recursive (struct_subtype (field (mut (ref null $struct.recursive))) data))
+
+ ;; NOMNL: (type $struct.nonnullable (struct_subtype (field (ref $struct.A)) data))
+
+ ;; NOMNL: (type $struct.packed (struct_subtype (field (mut i8)) data))
(type $struct.packed (struct (field (mut i8))))
;; CHECK: (type $struct.nondefaultable (struct (field (rtt $struct.A))))
+ ;; NOMNL: (type $struct.nondefaultable (struct_subtype (field (rtt $struct.A)) data))
(type $struct.nondefaultable (struct (field (rtt $struct.A))))
(type $struct.recursive (struct (field (mut (ref null $struct.recursive)))))
@@ -40,6 +47,24 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $simple
+ ;; NOMNL-NEXT: (local $0 i32)
+ ;; NOMNL-NEXT: (local $1 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $simple
;; Other passes can remove such a trivial case of an unused allocation, but
;; we still optimize it.
@@ -69,6 +94,25 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $to-local
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $to-local
(local $ref (ref null $struct.A))
;; While set to a local, this allocation has no get/set operations. Other
@@ -105,6 +149,29 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $one-get
+ ;; NOMNL-NEXT: (local $0 i32)
+ ;; NOMNL-NEXT: (local $1 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $one-get
;; An allocation followed by an immediate get of a field. This is a non-
;; escaping allocation, with a use, so we can optimize it out. The
@@ -143,6 +210,29 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $one-get-b
+ ;; NOMNL-NEXT: (local $0 i32)
+ ;; NOMNL-NEXT: (local $1 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $one-get-b
;; Similar to the above, but using a different field index.
(drop
@@ -175,6 +265,27 @@
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $one-set
+ ;; NOMNL-NEXT: (local $0 i32)
+ ;; NOMNL-NEXT: (local $1 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $one-set
;; A simple optimizable allocation only used in one set.
(struct.set $struct.A 0
@@ -194,6 +305,15 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $packed
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (struct.get_u $struct.packed 0
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.packed
+ ;; NOMNL-NEXT: (rtt.canon $struct.packed)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $packed
;; We do not optimize packed structs yet.
(drop
@@ -236,6 +356,37 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $with-init-values
+ ;; NOMNL-NEXT: (local $0 i32)
+ ;; NOMNL-NEXT: (local $1 f64)
+ ;; NOMNL-NEXT: (local $2 i32)
+ ;; NOMNL-NEXT: (local $3 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (i32.const 2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $3
+ ;; NOMNL-NEXT: (f64.const 3.14159)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (local.get $3)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $with-init-values
;; When we get values to initialize the struct with, assign them to the
;; proper locals.
@@ -263,6 +414,19 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $ignore-unreachable
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block
+ ;; NOMNL-NEXT: (i32.const 2)
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $ignore-unreachable
;; An unreachable allocation is not worth trying to process; DCE should
;; remove it.
@@ -287,6 +451,16 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $nondefaultable
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (struct.get $struct.nondefaultable 0
+ ;; NOMNL-NEXT: (struct.new_with_rtt $struct.nondefaultable
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: (rtt.canon $struct.nondefaultable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $nondefaultable
;; We do not optimize structs with nondefaultable types that we cannot
;; handle, like rtts.
@@ -327,6 +501,33 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $simple-one-local-set
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $simple-one-local-set
(local $ref (ref null $struct.A))
;; A simple optimizable allocation only used in one set, and also stored
@@ -368,6 +569,31 @@
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $simple-one-local-get (result f64)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $simple-one-local-get (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
@@ -384,6 +610,9 @@
;; CHECK: (func $send-ref (param $0 (ref null $struct.A))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $send-ref (param $0 (ref null $struct.A))
+ ;; NOMNL-NEXT: (nop)
+ ;; NOMNL-NEXT: )
(func $send-ref (param (ref null $struct.A))
)
@@ -415,6 +644,34 @@
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $safe-to-drop (result f64)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $safe-to-drop (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
@@ -445,6 +702,20 @@
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $escape-via-call (result f64)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $ref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $send-ref
+ ;; NOMNL-NEXT: (local.get $ref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.get $struct.A 1
+ ;; NOMNL-NEXT: (local.get $ref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $escape-via-call (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
@@ -493,6 +764,38 @@
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $safe-to-drop-multiflow (result f64)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $safe-to-drop-multiflow (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
@@ -533,6 +836,24 @@
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $escape-after-multiflow (result f64)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $ref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $send-ref
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.get $ref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.get $struct.A 1
+ ;; NOMNL-NEXT: (local.get $ref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $escape-after-multiflow (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
@@ -572,6 +893,23 @@
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $non-exclusive-set (result f64)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $ref
+ ;; NOMNL-NEXT: (select (result (ref $struct.A))
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.get $struct.A 1
+ ;; NOMNL-NEXT: (local.get $ref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $non-exclusive-set (result f64)
(local $ref (ref null $struct.A))
;; A set that receives two different allocations, and so we should not try
@@ -620,6 +958,34 @@
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $local-copies (result f64)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $local-copies (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
@@ -675,6 +1041,45 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $local-copies-2
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $ref-2 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $2 i32)
+ ;; NOMNL-NEXT: (local $3 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $3
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $3)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $local-copies-2
(local $ref (ref null $struct.A))
(local $ref-2 (ref null $struct.A))
@@ -731,6 +1136,37 @@
;; CHECK-NEXT: (local.get $3)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $local-copies-conditional (param $x i32) (result f64)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $2 i32)
+ ;; NOMNL-NEXT: (local $3 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $3
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (if
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $3)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $local-copies-conditional (param $x i32) (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
@@ -781,6 +1217,36 @@
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $block-value (result f64)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (call $send-ref
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $block-value (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
@@ -817,6 +1283,23 @@
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $non-exclusive-get (param $x i32) (result f64)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $ref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (if
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (local.set $ref
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.get $struct.A 1
+ ;; NOMNL-NEXT: (local.get $ref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $non-exclusive-get (param $x i32) (result f64)
(local $ref (ref null $struct.A))
(local.set $ref
@@ -856,6 +1339,26 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $tee (result i32)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $1)
+ ;; NOMNL-NEXT: )
(func $tee (result i32)
(local $ref (ref null $struct.A))
(struct.get $struct.A 0
@@ -886,6 +1389,24 @@
;; CHECK-NEXT: (ref.null $struct.recursive)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $tee-set
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (local $1 (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.recursive)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $tee-set
(local $ref (ref null $struct.recursive))
;; As above, but with a set, and also a recursive type.
@@ -910,6 +1431,17 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $set-value
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (struct.set $struct.recursive 0
+ ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: (local.tee $ref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.recursive
+ ;; NOMNL-NEXT: (rtt.canon $struct.recursive)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $set-value
(local $ref (ref null $struct.recursive))
(struct.set $struct.recursive 0
@@ -953,6 +1485,35 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $initialize-with-reference
+ ;; NOMNL-NEXT: (local $0 (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (local $1 (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (local $2 (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.recursive
+ ;; NOMNL-NEXT: (rtt.canon $struct.recursive)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.recursive)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.recursive))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.recursive)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $initialize-with-reference
(local $0 (ref null $struct.recursive))
(local.set $0
@@ -990,6 +1551,18 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $escape-flow-out (result anyref)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (struct.set $struct.A 0
+ ;; NOMNL-NEXT: (local.tee $ref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $ref)
+ ;; NOMNL-NEXT: )
(func $escape-flow-out (result anyref)
(local $ref (ref null $struct.A))
(struct.set $struct.A 0
@@ -1018,6 +1591,20 @@
;; CHECK-NEXT: (local.get $ref)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $escape-return (result anyref)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (struct.set $struct.A 0
+ ;; NOMNL-NEXT: (local.tee $ref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (return
+ ;; NOMNL-NEXT: (local.get $ref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $escape-return (result anyref)
(local $ref (ref null $struct.A))
(struct.set $struct.A 0
@@ -1061,6 +1648,33 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $non-nullable (param $a (ref $struct.A))
+ ;; NOMNL-NEXT: (local $1 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $2 (ref null $struct.A))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref $struct.A))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.nonnullable))
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (local.get $a)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.nonnullable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.nonnullable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (local.get $1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $non-nullable (param $a (ref $struct.A))
(drop
;; An optimizable case where the type is non-nullable, which requires
@@ -1171,6 +1785,103 @@
;; CHECK-NEXT: (br $outer)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $before-loop-use-multi (param $x i32)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $2 i32)
+ ;; NOMNL-NEXT: (local $3 f64)
+ ;; NOMNL-NEXT: (local $4 i32)
+ ;; NOMNL-NEXT: (local $5 f64)
+ ;; NOMNL-NEXT: (loop $outer
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $4
+ ;; NOMNL-NEXT: (i32.const 2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $5
+ ;; NOMNL-NEXT: (f64.const 2.1828)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (local.get $4)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $3
+ ;; NOMNL-NEXT: (local.get $5)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (if
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $3)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $3
+ ;; NOMNL-NEXT: (f64.const 42)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (loop $inner
+ ;; NOMNL-NEXT: (block
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (i32.add
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (br_if $inner
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (if
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $3)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (br $outer)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $before-loop-use-multi (param $x i32)
(local $ref (ref null $struct.A))
;; Allocate in a loop, and use that allocation multiple times in that loop
@@ -1294,6 +2005,71 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $multi-separate
+ ;; NOMNL-NEXT: (local $0 i32)
+ ;; NOMNL-NEXT: (local $1 f64)
+ ;; NOMNL-NEXT: (local $2 i32)
+ ;; NOMNL-NEXT: (local $3 f64)
+ ;; NOMNL-NEXT: (local $4 i32)
+ ;; NOMNL-NEXT: (local $5 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $3
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $4
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $5
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $5)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $multi-separate
;; Multiple independent things we can optimize.
(drop
@@ -1370,6 +2146,57 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $multi-separate-same-local-index
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (local $3 i32)
+ ;; NOMNL-NEXT: (local $4 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $3
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $4
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $3)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $multi-separate-same-local-index
(local $ref (ref null $struct.A))
;; Multiple independent things we can optimize that use the same local
@@ -1448,6 +2275,58 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $multi-separate-different-local-index-overlapping-lifetimes
+ ;; NOMNL-NEXT: (local $ref1 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $ref2 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $2 i32)
+ ;; NOMNL-NEXT: (local $3 f64)
+ ;; NOMNL-NEXT: (local $4 i32)
+ ;; NOMNL-NEXT: (local $5 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $3
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $4
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $5
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $4)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $multi-separate-different-local-index-overlapping-lifetimes
(local $ref1 (ref null $struct.A))
(local $ref2 (ref null $struct.A))
@@ -1494,6 +2373,25 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $get-through-block (result f64)
+ ;; NOMNL-NEXT: (local $0 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.get $struct.A 1
+ ;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_if $block
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $get-through-block (result f64)
(local $0 (ref null $struct.A))
(local.set $0
@@ -1537,6 +2435,25 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $branch-to-block (result f64)
+ ;; NOMNL-NEXT: (local $0 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.get $struct.A 1
+ ;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_if $block
+ ;; NOMNL-NEXT: (local.get $0)
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $branch-to-block (result f64)
(local $0 (ref null $struct.A))
(local.set $0
@@ -1594,6 +2511,41 @@
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $branch-to-block-no-fallthrough (result f64)
+ ;; NOMNL-NEXT: (local $0 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block (result f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_if $block
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (return
+ ;; NOMNL-NEXT: (f64.const 2.1828)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $branch-to-block-no-fallthrough (result f64)
(local $0 (ref null $struct.A))
(local.set $0
@@ -1644,6 +2596,33 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $two-branches (result f64)
+ ;; NOMNL-NEXT: (local $0 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.get $struct.A 1
+ ;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_if $block
+ ;; NOMNL-NEXT: (local.get $0)
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_if $block
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (return
+ ;; NOMNL-NEXT: (f64.const 2.1828)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $two-branches (result f64)
(local $0 (ref null $struct.A))
(local.set $0
@@ -1699,6 +2678,33 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $two-branches-b (result f64)
+ ;; NOMNL-NEXT: (local $0 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.get $struct.A 1
+ ;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_if $block
+ ;; NOMNL-NEXT: (local.get $0)
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_if $block
+ ;; NOMNL-NEXT: (local.get $0)
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (return
+ ;; NOMNL-NEXT: (f64.const 2.1828)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $two-branches-b (result f64)
(local $0 (ref null $struct.A))
(local.set $0
@@ -1749,6 +2755,27 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $br_if_flow (result f64)
+ ;; NOMNL-NEXT: (local $0 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct.A
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.get $struct.A 1
+ ;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (call $send-ref
+ ;; NOMNL-NEXT: (br_if $block
+ ;; NOMNL-NEXT: (local.get $0)
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (return
+ ;; NOMNL-NEXT: (f64.const 2.1828)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $br_if_flow (result f64)
(local $0 (ref null $struct.A))
(local.set $0
@@ -1804,6 +2831,38 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $ref-as-non-null
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (ref.null any)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $ref-as-non-null
(local $ref (ref null $struct.A))
(local.set $ref
@@ -1856,6 +2915,34 @@
;; CHECK-NEXT: (local.get $1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $ref-as-non-null-through-local (result i32)
+ ;; NOMNL-NEXT: (local $ref (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $ref-as-non-null-through-local (result i32)
(local $ref (ref null $struct.A))
(local.set $ref
@@ -1917,6 +3004,44 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $2)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $br_if-allocation (result f64)
+ ;; NOMNL-NEXT: (local $0 (ref null $struct.A))
+ ;; NOMNL-NEXT: (local $1 i32)
+ ;; NOMNL-NEXT: (local $2 f64)
+ ;; NOMNL-NEXT: (local $3 i32)
+ ;; NOMNL-NEXT: (local $4 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block $block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_if $block
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $3
+ ;; NOMNL-NEXT: (i32.const 42)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $4
+ ;; NOMNL-NEXT: (f64.const 13.37)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (local.get $3)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $2
+ ;; NOMNL-NEXT: (local.get $4)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (rtt.canon $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (return
+ ;; NOMNL-NEXT: (f64.const 2.1828)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $2)
+ ;; NOMNL-NEXT: )
(func $br_if-allocation (result f64)
(local $0 (ref null $struct.A))
(struct.get $struct.A 1
@@ -1953,6 +3078,21 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $simple-no-rtt
+ ;; NOMNL-NEXT: (local $0 i32)
+ ;; NOMNL-NEXT: (local $1 f64)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result (ref null $struct.A))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $1
+ ;; NOMNL-NEXT: (f64.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null $struct.A)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $simple-no-rtt
(drop
;; This allocation has no rtt, so we have nothing to drop from it when
diff --git a/test/lit/passes/inlining_all-features.wast b/test/lit/passes/inlining_all-features.wast
index b3089baeb..fce3cc460 100644
--- a/test/lit/passes/inlining_all-features.wast
+++ b/test/lit/passes/inlining_all-features.wast
@@ -1,7 +1,7 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: foreach %s %t wasm-opt --inlining --all-features -S -o - | filecheck %s
-;; RUN: foreach %s %t wasm-opt --inlining --all-features --nominal -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt --inlining --all-features --nominal -S -o - | filecheck %s --check-prefix=NOMNL
(module
;; CHECK: (type $none_=>_none (func))
@@ -11,6 +11,13 @@
;; CHECK: (elem declare func $foo)
;; CHECK: (export "ref_func_test" (func $ref_func_test))
+ ;; NOMNL: (type $none_=>_none (func_subtype func))
+
+ ;; NOMNL: (type $none_=>_funcref (func_subtype (result funcref) func))
+
+ ;; NOMNL: (elem declare func $foo)
+
+ ;; NOMNL: (export "ref_func_test" (func $ref_func_test))
(export "ref_func_test" (func $ref_func_test))
;; $foo should not be removed after being inlined, because there is 'ref.func'
@@ -18,6 +25,9 @@
;; CHECK: (func $foo
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $foo
+ ;; NOMNL-NEXT: (nop)
+ ;; NOMNL-NEXT: )
(func $foo)
;; CHECK: (func $ref_func_test (result funcref)
@@ -28,6 +38,14 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (ref.func $foo)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $ref_func_test (result funcref)
+ ;; NOMNL-NEXT: (block
+ ;; NOMNL-NEXT: (block $__inlined_func$foo
+ ;; NOMNL-NEXT: (nop)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.func $foo)
+ ;; NOMNL-NEXT: )
(func $ref_func_test (result funcref)
(call $foo)
(ref.func $foo)
@@ -40,11 +58,17 @@
;; CHECK: (type $none_=>_i32 (func (result i32)))
;; CHECK: (global $global$0 (mut funcref) (ref.func $0))
+ ;; NOMNL: (type $none_=>_i32 (func_subtype (result i32) func))
+
+ ;; NOMNL: (global $global$0 (mut funcref) (ref.func $0))
(global $global$0 (mut funcref) (ref.func $0))
;; CHECK: (func $0 (result i32)
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $0 (result i32)
+ ;; NOMNL-NEXT: (i32.const 1337)
+ ;; NOMNL-NEXT: )
(func $0 (result i32)
(i32.const 1337)
)
@@ -54,6 +78,11 @@
;; CHECK-NEXT: (i32.const 1337)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $1 (result i32)
+ ;; NOMNL-NEXT: (block $__inlined_func$0 (result i32)
+ ;; NOMNL-NEXT: (i32.const 1337)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $1 (result i32)
(call $0)
)
@@ -65,11 +94,17 @@
;; CHECK: (type $none_=>_none (func))
;; CHECK: (start $0)
+ ;; NOMNL: (type $none_=>_none (func_subtype func))
+
+ ;; NOMNL: (start $0)
(start $0)
;; CHECK: (func $0
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $0
+ ;; NOMNL-NEXT: (nop)
+ ;; NOMNL-NEXT: )
(func $0
(nop)
)
@@ -79,6 +114,11 @@
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $1
+ ;; NOMNL-NEXT: (block $__inlined_func$0
+ ;; NOMNL-NEXT: (nop)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $1
(call $0)
)
@@ -87,9 +127,11 @@
;; inline a return_call_ref
(module
;; CHECK: (type $none_=>_none (func))
+ ;; NOMNL: (type $none_=>_none (func_subtype func))
(type $none_=>_none (func))
;; CHECK: (export "func_36_invoker" (func $1))
+ ;; NOMNL: (export "func_36_invoker" (func $1))
(export "func_36_invoker" (func $1))
(func $0
@@ -108,6 +150,17 @@
;; CHECK-NEXT: (br $__inlined_func$0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $1
+ ;; NOMNL-NEXT: (block $__inlined_func$0
+ ;; NOMNL-NEXT: (block
+ ;; NOMNL-NEXT: (call_ref
+ ;; NOMNL-NEXT: (ref.null $none_=>_none)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (br $__inlined_func$0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (br $__inlined_func$0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $1
(call $0)
)
@@ -134,6 +187,21 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (type $none_=>_ref|func| (func_subtype (result (ref func)) func))
+
+ ;; NOMNL: (elem declare func $1)
+
+ ;; NOMNL: (func $1 (result (ref func))
+ ;; NOMNL-NEXT: (local $0 funcref)
+ ;; NOMNL-NEXT: (block $__inlined_func$0 (result (ref func))
+ ;; NOMNL-NEXT: (local.set $0
+ ;; NOMNL-NEXT: (ref.func $1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (local.get $0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $1 (result (ref func))
(call $0
(ref.func $1)
@@ -144,6 +212,7 @@
;; never inline an rtt parameter, as those cannot be handled as locals
(module
;; CHECK: (type $struct (struct ))
+ ;; NOMNL: (type $struct (struct_subtype data))
(type $struct (struct))
;; CHECK: (type $rtt_$struct_=>_none (func (param (rtt $struct))))
@@ -152,6 +221,13 @@
;; CHECK: (func $0 (param $rtt (rtt $struct))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; NOMNL: (type $rtt_$struct_=>_none (func_subtype (param (rtt $struct)) func))
+
+ ;; NOMNL: (type $none_=>_none (func_subtype func))
+
+ ;; NOMNL: (func $0 (param $rtt (rtt $struct))
+ ;; NOMNL-NEXT: (nop)
+ ;; NOMNL-NEXT: )
(func $0 (param $rtt (rtt $struct))
)
;; CHECK: (func $1
@@ -159,6 +235,11 @@
;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $1
+ ;; NOMNL-NEXT: (call $0
+ ;; NOMNL-NEXT: (rtt.canon $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $1
(call $0
(rtt.canon $struct)
diff --git a/test/lit/passes/instrument-memory-gc.wast b/test/lit/passes/instrument-memory-gc.wast
index 1866bdcb8..bbc55ba77 100644
--- a/test/lit/passes/instrument-memory-gc.wast
+++ b/test/lit/passes/instrument-memory-gc.wast
@@ -1,7 +1,7 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: foreach %s %t wasm-opt --instrument-memory -all -S -o - | filecheck %s
-;; RUN: foreach %s %t wasm-opt --instrument-memory --nominal -all -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt --instrument-memory --nominal -all -S -o - | filecheck %s --check-prefix=NOMNL
(module
;; CHECK: (type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
@@ -13,6 +13,15 @@
;; CHECK: (type $i32_f64_=>_f64 (func (param i32 f64) (result f64)))
;; CHECK: (type $struct (struct (field (mut i32)) (field f32) (field $named f64)))
+ ;; NOMNL: (type $i32_i32_=>_i32 (func_subtype (param i32 i32) (result i32) func))
+
+ ;; NOMNL: (type $i32_i64_=>_i64 (func_subtype (param i32 i64) (result i64) func))
+
+ ;; NOMNL: (type $i32_f32_=>_f32 (func_subtype (param i32 f32) (result f32) func))
+
+ ;; NOMNL: (type $i32_f64_=>_f64 (func_subtype (param i32 f64) (result f64) func))
+
+ ;; NOMNL: (type $struct (struct_subtype (field (mut i32)) (field f32) (field $named f64) data))
(type $struct (struct
(field (mut i32))
(field f32)
@@ -25,6 +34,13 @@
;; CHECK: (type $ref|$array|_=>_none (func (param (ref $array))))
;; CHECK: (type $array (array (mut f64)))
+ ;; NOMNL: (type $i32_i32_i32_i32_=>_i32 (func_subtype (param i32 i32 i32 i32) (result i32) func))
+
+ ;; NOMNL: (type $ref|$struct|_=>_none (func_subtype (param (ref $struct)) func))
+
+ ;; NOMNL: (type $ref|$array|_=>_none (func_subtype (param (ref $array)) func))
+
+ ;; NOMNL: (type $array (array_subtype (mut f64) data))
(type $array (array (mut f64)))
;; CHECK: (import "env" "load_ptr" (func $load_ptr (param i32 i32 i32 i32) (result i32)))
@@ -116,6 +132,95 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (import "env" "load_ptr" (func $load_ptr (param i32 i32 i32 i32) (result i32)))
+
+ ;; NOMNL: (import "env" "load_val_i32" (func $load_val_i32 (param i32 i32) (result i32)))
+
+ ;; NOMNL: (import "env" "load_val_i64" (func $load_val_i64 (param i32 i64) (result i64)))
+
+ ;; NOMNL: (import "env" "load_val_f32" (func $load_val_f32 (param i32 f32) (result f32)))
+
+ ;; NOMNL: (import "env" "load_val_f64" (func $load_val_f64 (param i32 f64) (result f64)))
+
+ ;; NOMNL: (import "env" "store_ptr" (func $store_ptr (param i32 i32 i32 i32) (result i32)))
+
+ ;; NOMNL: (import "env" "store_val_i32" (func $store_val_i32 (param i32 i32) (result i32)))
+
+ ;; NOMNL: (import "env" "store_val_i64" (func $store_val_i64 (param i32 i64) (result i64)))
+
+ ;; NOMNL: (import "env" "store_val_f32" (func $store_val_f32 (param i32 f32) (result f32)))
+
+ ;; NOMNL: (import "env" "store_val_f64" (func $store_val_f64 (param i32 f64) (result f64)))
+
+ ;; NOMNL: (import "env" "struct_get_val_i32" (func $struct_get_val_i32 (param i32 i32) (result i32)))
+
+ ;; NOMNL: (import "env" "struct_get_val_i64" (func $struct_get_val_i64 (param i32 i64) (result i64)))
+
+ ;; NOMNL: (import "env" "struct_get_val_f32" (func $struct_get_val_f32 (param i32 f32) (result f32)))
+
+ ;; NOMNL: (import "env" "struct_get_val_f64" (func $struct_get_val_f64 (param i32 f64) (result f64)))
+
+ ;; NOMNL: (import "env" "struct_set_val_i32" (func $struct_set_val_i32 (param i32 i32) (result i32)))
+
+ ;; NOMNL: (import "env" "struct_set_val_i64" (func $struct_set_val_i64 (param i32 i64) (result i64)))
+
+ ;; NOMNL: (import "env" "struct_set_val_f32" (func $struct_set_val_f32 (param i32 f32) (result f32)))
+
+ ;; NOMNL: (import "env" "struct_set_val_f64" (func $struct_set_val_f64 (param i32 f64) (result f64)))
+
+ ;; NOMNL: (import "env" "array_get_val_i32" (func $array_get_val_i32 (param i32 i32) (result i32)))
+
+ ;; NOMNL: (import "env" "array_get_val_i64" (func $array_get_val_i64 (param i32 i64) (result i64)))
+
+ ;; NOMNL: (import "env" "array_get_val_f32" (func $array_get_val_f32 (param i32 f32) (result f32)))
+
+ ;; NOMNL: (import "env" "array_get_val_f64" (func $array_get_val_f64 (param i32 f64) (result f64)))
+
+ ;; NOMNL: (import "env" "array_set_val_i32" (func $array_set_val_i32 (param i32 i32) (result i32)))
+
+ ;; NOMNL: (import "env" "array_set_val_i64" (func $array_set_val_i64 (param i32 i64) (result i64)))
+
+ ;; NOMNL: (import "env" "array_set_val_f32" (func $array_set_val_f32 (param i32 f32) (result f32)))
+
+ ;; NOMNL: (import "env" "array_set_val_f64" (func $array_set_val_f64 (param i32 f64) (result f64)))
+
+ ;; NOMNL: (import "env" "array_get_index" (func $array_get_index (param i32 i32) (result i32)))
+
+ ;; NOMNL: (import "env" "array_set_index" (func $array_set_index (param i32 i32) (result i32)))
+
+ ;; NOMNL: (func $structs (param $x (ref $struct))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (call $struct_get_val_i32
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: (struct.get $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (call $struct_get_val_f32
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: (struct.get $struct 1
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (call $struct_get_val_f64
+ ;; NOMNL-NEXT: (i32.const 2)
+ ;; NOMNL-NEXT: (struct.get $struct $named
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.set $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (call $struct_set_val_i32
+ ;; NOMNL-NEXT: (i32.const 3)
+ ;; NOMNL-NEXT: (i32.const 42)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $structs (param $x (ref $struct))
(drop
(struct.get $struct 0 (local.get $x))
@@ -154,6 +259,31 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $arrays (param $x (ref $array))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (call $array_get_val_f64
+ ;; NOMNL-NEXT: (i32.const 5)
+ ;; NOMNL-NEXT: (array.get $array
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (call $array_get_index
+ ;; NOMNL-NEXT: (i32.const 4)
+ ;; NOMNL-NEXT: (i32.const 10)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (array.set $array
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (call $array_set_index
+ ;; NOMNL-NEXT: (i32.const 6)
+ ;; NOMNL-NEXT: (i32.const 42)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $array_set_val_f64
+ ;; NOMNL-NEXT: (i32.const 7)
+ ;; NOMNL-NEXT: (f64.const 3.14159)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $arrays (param $x (ref $array))
(drop
(array.get $array (local.get $x) (i32.const 10))
diff --git a/test/lit/passes/local-subtyping-nn.wast b/test/lit/passes/local-subtyping-nn.wast
index bcf13f7c2..290fe032d 100644
--- a/test/lit/passes/local-subtyping-nn.wast
+++ b/test/lit/passes/local-subtyping-nn.wast
@@ -2,13 +2,15 @@
;; RUN: wasm-opt %s --local-subtyping -all --enable-gc-nn-locals -S -o - \
;; RUN: | filecheck %s
;; RUN: wasm-opt %s --local-subtyping -all --enable-gc-nn-locals --nominal -S -o - \
-;; RUN: | filecheck %s
+;; RUN: | filecheck %s --check-prefix=NOMNL
(module
;; CHECK: (type $struct (struct ))
+ ;; NOMNL: (type $struct (struct_subtype data))
(type $struct (struct))
;; CHECK: (import "out" "i32" (func $i32 (result i32)))
+ ;; NOMNL: (import "out" "i32" (func $i32 (result i32)))
(import "out" "i32" (func $i32 (result i32)))
;; CHECK: (func $non-nullable
@@ -26,6 +28,21 @@
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $non-nullable
+ ;; NOMNL-NEXT: (local $x (ref $struct))
+ ;; NOMNL-NEXT: (local $y (ref $none_=>_i32))
+ ;; NOMNL-NEXT: (local.set $x
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (ref.null $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $y
+ ;; NOMNL-NEXT: (ref.func $i32)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $non-nullable
(local $x (ref null $struct))
(local $y anyref)
@@ -58,6 +75,20 @@
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $uses-default (param $i i32)
+ ;; NOMNL-NEXT: (local $x (ref null $struct))
+ ;; NOMNL-NEXT: (if
+ ;; NOMNL-NEXT: (local.get $i)
+ ;; NOMNL-NEXT: (local.set $x
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (ref.null $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $uses-default (param $i i32)
(local $x (ref null any))
(if
diff --git a/test/lit/passes/name-types.wast b/test/lit/passes/name-types.wast
index 39cc00423..12fe549ea 100644
--- a/test/lit/passes/name-types.wast
+++ b/test/lit/passes/name-types.wast
@@ -1,6 +1,6 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: wasm-opt %s -all --name-types -S -o - | filecheck %s
-;; RUN: wasm-opt %s -all --name-types --nominal -S -o - | filecheck %s
+;; RUN: wasm-opt %s -all --name-types --nominal -S -o - | filecheck %s --check-prefix=NOMNL
(module
;; An obnoxious name that will be renamed.
@@ -12,11 +12,19 @@
;; CHECK: (type $type$1 (struct ))
;; CHECK: (type $reasonable-name (struct (field i32)))
+ ;; NOMNL: (type $type$0 (func_subtype (param (ref $type$1) (ref $reasonable-name)) func))
+
+ ;; NOMNL: (type $type$1 (struct_subtype data))
+
+ ;; NOMNL: (type $reasonable-name (struct_subtype (field i32) data))
(type $reasonable-name (struct (field i32)))
;; CHECK: (func $foo (param $x (ref $type$1)) (param $y (ref $reasonable-name))
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $foo (param $x (ref $type$1)) (param $y (ref $reasonable-name))
+ ;; NOMNL-NEXT: (nop)
+ ;; NOMNL-NEXT: )
(func $foo
;; Use the types to keep them alive.
(param $x (ref $obnoxious-super-long-type-name_____________________________1))
diff --git a/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast b/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast
index 5bbec4b64..0477abe79 100644
--- a/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast
+++ b/test/lit/passes/optimize-instructions-call_ref-roundtrip.wast
@@ -10,16 +10,16 @@
;; distinct nominally. The three tables will use different ones, and the
;; emitted call_indirects should use the corresponding ones.
- ;; CHECK: (type $v1 (func))
+ ;; CHECK: (type $v1 (func_subtype func))
(type $v1 (func))
- ;; CHECK: (type $v2 (func))
+ ;; CHECK: (type $v2 (func_subtype func))
(type $v2 (func))
- ;; CHECK: (type $v3 (func))
+ ;; CHECK: (type $v3 (func_subtype func))
(type $v3 (func))
- ;; CHECK: (type $i32_=>_none (func (param i32)))
+ ;; CHECK: (type $i32_=>_none (func_subtype (param i32) func))
;; CHECK: (table $table-1 10 (ref null $v1))
(table $table-1 10 (ref null $v1))
diff --git a/test/lit/passes/optimize-instructions-gc-iit.wast b/test/lit/passes/optimize-instructions-gc-iit.wast
index d6bb9eb31..9923bf89b 100644
--- a/test/lit/passes/optimize-instructions-gc-iit.wast
+++ b/test/lit/passes/optimize-instructions-gc-iit.wast
@@ -9,16 +9,16 @@
(module
;; CHECK: (type $parent (struct (field i32)))
- ;; NOMNL: (type $parent (struct (field i32)))
- ;; NOMNL-TNH: (type $parent (struct (field i32)))
+ ;; NOMNL: (type $parent (struct_subtype (field i32) data))
+ ;; NOMNL-TNH: (type $parent (struct_subtype (field i32) data))
(type $parent (struct (field i32)))
;; CHECK: (type $child (struct (field i32) (field f64)))
- ;; NOMNL: (type $child (struct (field i32) (field f64)) (extends $parent))
- ;; NOMNL-TNH: (type $child (struct (field i32) (field f64)) (extends $parent))
- (type $child (struct (field i32) (field f64)) (extends $parent))
+ ;; NOMNL: (type $child (struct_subtype (field i32) (field f64) $parent))
+ ;; NOMNL-TNH: (type $child (struct_subtype (field i32) (field f64) $parent))
+ (type $child (struct_subtype (field i32) (field f64) $parent))
;; CHECK: (type $other (struct (field i64) (field f32)))
- ;; NOMNL: (type $other (struct (field i64) (field f32)))
- ;; NOMNL-TNH: (type $other (struct (field i64) (field f32)))
+ ;; NOMNL: (type $other (struct_subtype (field i64) (field f32) data))
+ ;; NOMNL-TNH: (type $other (struct_subtype (field i64) (field f32) data))
(type $other (struct (field i64) (field f32)))
;; CHECK: (func $foo
diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast
index ab973ffae..47d2a17bc 100644
--- a/test/lit/passes/optimize-instructions-gc.wast
+++ b/test/lit/passes/optimize-instructions-gc.wast
@@ -6,7 +6,7 @@
(module
;; CHECK: (type $struct (struct (field $i8 (mut i8)) (field $i16 (mut i16)) (field $i32 (mut i32)) (field $i64 (mut i64))))
- ;; NOMNL: (type $struct (struct (field $i8 (mut i8)) (field $i16 (mut i16)) (field $i32 (mut i32)) (field $i64 (mut i64))))
+ ;; NOMNL: (type $struct (struct_subtype (field $i8 (mut i8)) (field $i16 (mut i16)) (field $i32 (mut i32)) (field $i64 (mut i64)) data))
(type $struct (struct
(field $i8 (mut i8))
(field $i16 (mut i16))
@@ -15,28 +15,28 @@
))
;; CHECK: (type $A (struct (field i32)))
- ;; NOMNL: (type $A (struct (field i32)))
+ ;; NOMNL: (type $A (struct_subtype (field i32) data))
(type $A (struct (field i32)))
;; CHECK: (type $array (array (mut i8)))
- ;; NOMNL: (type $array (array (mut i8)))
+ ;; NOMNL: (type $array (array_subtype (mut i8) data))
(type $array (array (mut i8)))
;; CHECK: (type $B (struct (field i32) (field i32) (field f32)))
- ;; NOMNL: (type $B (struct (field i32) (field i32) (field f32)) (extends $A))
- (type $B (struct (field i32) (field i32) (field f32)) (extends $A))
+ ;; NOMNL: (type $B (struct_subtype (field i32) (field i32) (field f32) $A))
+ (type $B (struct_subtype (field i32) (field i32) (field f32) $A))
;; CHECK: (type $B-child (struct (field i32) (field i32) (field f32) (field i64)))
- ;; NOMNL: (type $B-child (struct (field i32) (field i32) (field f32) (field i64)) (extends $B))
- (type $B-child (struct (field i32) (field i32) (field f32) (field i64)) (extends $B))
+ ;; NOMNL: (type $B-child (struct_subtype (field i32) (field i32) (field f32) (field i64) $B))
+ (type $B-child (struct_subtype (field i32) (field i32) (field f32) (field i64) $B))
;; CHECK: (type $empty (struct ))
- ;; NOMNL: (type $empty (struct ))
+ ;; NOMNL: (type $empty (struct_subtype data))
(type $empty (struct))
;; CHECK: (type $C (struct (field i32) (field i32) (field f64)))
- ;; NOMNL: (type $C (struct (field i32) (field i32) (field f64)) (extends $A))
- (type $C (struct (field i32) (field i32) (field f64)) (extends $A))
+ ;; NOMNL: (type $C (struct_subtype (field i32) (field i32) (field f64) $A))
+ (type $C (struct_subtype (field i32) (field i32) (field f64) $A))
;; CHECK: (import "env" "get-i32" (func $get-i32 (result i32)))
;; NOMNL: (import "env" "get-i32" (func $get-i32 (result i32)))
diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast
index c12e86635..2d50fcaa6 100644
--- a/test/lit/passes/precompute-gc.wast
+++ b/test/lit/passes/precompute-gc.wast
@@ -2,24 +2,29 @@
;; RUN: wasm-opt %s --remove-unused-names --precompute-propagate --fuzz-exec -all -S -o - \
;; RUN: | filecheck %s
;; RUN: wasm-opt %s --remove-unused-names --precompute-propagate --fuzz-exec -all --nominal -S -o - \
-;; RUN: | filecheck %s
+;; RUN: | filecheck %s --check-prefix=NOMNL
(module
;; CHECK: (type $empty (struct ))
+ ;; NOMNL: (type $empty (struct_subtype data))
+ (type $empty (struct))
;; CHECK: (type $struct (struct (field (mut i32))))
+ ;; NOMNL: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (mut i32)))
- (type $empty (struct))
;; two incompatible struct types
(type $A (struct (field (mut f32))))
;; CHECK: (type $B (struct (field (mut f64))))
+ ;; NOMNL: (type $B (struct_subtype (field (mut f64)) data))
(type $B (struct (field (mut f64))))
;; CHECK: (type $func-return-i32 (func (result i32)))
+ ;; NOMNL: (type $func-return-i32 (func_subtype (result i32) func))
(type $func-return-i32 (func (result i32)))
;; CHECK: (import "fuzzing-support" "log-i32" (func $log (param i32)))
+ ;; NOMNL: (import "fuzzing-support" "log-i32" (func $log (param i32)))
(import "fuzzing-support" "log-i32" (func $log (param i32)))
;; CHECK: (func $test-fallthrough (result i32)
@@ -34,6 +39,18 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $test-fallthrough (result i32)
+ ;; NOMNL-NEXT: (local $x funcref)
+ ;; NOMNL-NEXT: (local.set $x
+ ;; NOMNL-NEXT: (block (result funcref)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (call $test-fallthrough)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (ref.null func)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
(func $test-fallthrough (result i32)
(local $x funcref)
(local.set $x
@@ -88,6 +105,40 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $load-from-struct
+ ;; NOMNL-NEXT: (local $x (ref null $struct))
+ ;; NOMNL-NEXT: (local.set $x
+ ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: (rtt.canon $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $log
+ ;; NOMNL-NEXT: (struct.get $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $x
+ ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (i32.const 2)
+ ;; NOMNL-NEXT: (rtt.canon $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $log
+ ;; NOMNL-NEXT: (struct.get $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.set $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (i32.const 3)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $log
+ ;; NOMNL-NEXT: (struct.get $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $load-from-struct
(local $x (ref null $struct))
(local.set $x
@@ -143,6 +194,29 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $load-from-struct-bad-merge (param $i i32)
+ ;; NOMNL-NEXT: (local $x (ref null $struct))
+ ;; NOMNL-NEXT: (if
+ ;; NOMNL-NEXT: (local.get $i)
+ ;; NOMNL-NEXT: (local.set $x
+ ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: (rtt.canon $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $x
+ ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (i32.const 2)
+ ;; NOMNL-NEXT: (rtt.canon $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $log
+ ;; NOMNL-NEXT: (struct.get $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $load-from-struct-bad-merge (param $i i32)
(local $x (ref null $struct))
;; a merge of two different $x values cannot be precomputed
@@ -176,6 +250,17 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $modify-gc-heap (param $x (ref null $struct))
+ ;; NOMNL-NEXT: (struct.set $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (i32.add
+ ;; NOMNL-NEXT: (struct.get $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $modify-gc-heap (param $x (ref null $struct))
(struct.set $struct 0
(local.get $x)
@@ -206,6 +291,23 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $load-from-struct-bad-escape
+ ;; NOMNL-NEXT: (local $x (ref null $struct))
+ ;; NOMNL-NEXT: (local.set $x
+ ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: (rtt.canon $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $modify-gc-heap
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $log
+ ;; NOMNL-NEXT: (struct.get $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $load-from-struct-bad-escape (export "test")
(local $x (ref null $struct))
(local.set $x
@@ -228,6 +330,13 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $load-from-struct-bad-arrive (param $x (ref null $struct))
+ ;; NOMNL-NEXT: (call $log
+ ;; NOMNL-NEXT: (struct.get $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $load-from-struct-bad-arrive (param $x (ref null $struct))
;; a parameter cannot be precomputed
(call $log
@@ -259,6 +368,31 @@
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $ref-comparisons (param $x (ref null $struct)) (param $y (ref null $struct))
+ ;; NOMNL-NEXT: (local $z (ref null $struct))
+ ;; NOMNL-NEXT: (local $w (ref null $struct))
+ ;; NOMNL-NEXT: (call $log
+ ;; NOMNL-NEXT: (ref.eq
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (local.get $y)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $log
+ ;; NOMNL-NEXT: (ref.eq
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (ref.null $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $log
+ ;; NOMNL-NEXT: (ref.eq
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (ref.null $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (call $log
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $ref-comparisons
(param $x (ref null $struct))
(param $y (ref null $struct))
@@ -310,6 +444,24 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $new-ref-comparisons (result i32)
+ ;; NOMNL-NEXT: (local $x (ref null $struct))
+ ;; NOMNL-NEXT: (local $y (ref null $struct))
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local.set $x
+ ;; NOMNL-NEXT: (struct.new_with_rtt $struct
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: (rtt.canon $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $y
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
(func $new-ref-comparisons (result i32)
(local $x (ref null $struct))
(local $y (ref null $struct))
@@ -349,6 +501,21 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $propagate-equal (result i32)
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local $tempref (ref null $empty))
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (ref.eq
+ ;; NOMNL-NEXT: (local.tee $tempref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $tempref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
(func $propagate-equal (result i32)
(local $tempresult i32)
(local $tempref (ref null $empty))
@@ -376,6 +543,14 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $propagate-unequal (result i32)
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local $tempref (ref null $empty))
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
(func $propagate-unequal (result i32)
(local $tempresult i32)
(local $tempref (ref null $empty))
@@ -410,6 +585,19 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $tempresult)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $propagate-uncertain-param (param $input (ref $empty)) (result i32)
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local $tempref (ref null $empty))
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (ref.eq
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $input)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $tempresult)
+ ;; NOMNL-NEXT: )
(func $propagate-uncertain-param (param $input (ref $empty)) (result i32)
(local $tempresult i32)
(local $tempref (ref null $empty))
@@ -436,6 +624,16 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $tempresult)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $propagate-different-params (param $input1 (ref $empty)) (param $input2 (ref $empty)) (result i32)
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (ref.eq
+ ;; NOMNL-NEXT: (local.get $input1)
+ ;; NOMNL-NEXT: (local.get $input2)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $tempresult)
+ ;; NOMNL-NEXT: )
(func $propagate-different-params (param $input1 (ref $empty)) (param $input2 (ref $empty)) (result i32)
(local $tempresult i32)
(local.set $tempresult
@@ -458,6 +656,16 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $tempresult)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $propagate-same-param (param $input (ref $empty)) (result i32)
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (ref.eq
+ ;; NOMNL-NEXT: (local.get $input)
+ ;; NOMNL-NEXT: (local.get $input)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $tempresult)
+ ;; NOMNL-NEXT: )
(func $propagate-same-param (param $input (ref $empty)) (result i32)
(local $tempresult i32)
(local.set $tempresult
@@ -501,6 +709,36 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $tempresult)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $propagate-uncertain-local (result i32)
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local $tempref (ref null $empty))
+ ;; NOMNL-NEXT: (local $stashedref (ref null $empty))
+ ;; NOMNL-NEXT: (local.set $tempref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $stashedref
+ ;; NOMNL-NEXT: (local.get $tempref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (if
+ ;; NOMNL-NEXT: (call $helper
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $tempref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (ref.eq
+ ;; NOMNL-NEXT: (local.get $tempref)
+ ;; NOMNL-NEXT: (local.get $stashedref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $tempresult)
+ ;; NOMNL-NEXT: )
(func $propagate-uncertain-local (result i32)
(local $tempresult i32)
(local $tempref (ref null $empty))
@@ -565,6 +803,37 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $propagate-uncertain-loop
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local $tempref (ref null $empty))
+ ;; NOMNL-NEXT: (local $stashedref (ref null $empty))
+ ;; NOMNL-NEXT: (local.set $tempref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $stashedref
+ ;; NOMNL-NEXT: (local.get $tempref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (loop $loop
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (ref.eq
+ ;; NOMNL-NEXT: (local.get $tempref)
+ ;; NOMNL-NEXT: (local.get $stashedref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $tempref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (br_if $loop
+ ;; NOMNL-NEXT: (call $helper
+ ;; NOMNL-NEXT: (local.get $tempresult)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $propagate-uncertain-loop
(local $tempresult i32)
(local $tempref (ref null $empty))
@@ -622,6 +891,29 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $propagate-certain-loop
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local $tempref (ref null $empty))
+ ;; NOMNL-NEXT: (local $stashedref (ref null $empty))
+ ;; NOMNL-NEXT: (local.set $tempref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $stashedref
+ ;; NOMNL-NEXT: (local.get $tempref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (loop $loop
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (br_if $loop
+ ;; NOMNL-NEXT: (call $helper
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $propagate-certain-loop
(local $tempresult i32)
(local $tempref (ref null $empty))
@@ -674,6 +966,29 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $propagate-certain-loop-2
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local $tempref (ref null $empty))
+ ;; NOMNL-NEXT: (local $stashedref (ref null $empty))
+ ;; NOMNL-NEXT: (loop $loop
+ ;; NOMNL-NEXT: (local.set $tempref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $stashedref
+ ;; NOMNL-NEXT: (local.get $tempref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (br_if $loop
+ ;; NOMNL-NEXT: (call $helper
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $propagate-certain-loop-2
(local $tempresult i32)
(local $tempref (ref null $empty))
@@ -734,6 +1049,37 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $propagate-possibly-certain-loop
+ ;; NOMNL-NEXT: (local $tempresult i32)
+ ;; NOMNL-NEXT: (local $tempref (ref null $empty))
+ ;; NOMNL-NEXT: (local $stashedref (ref null $empty))
+ ;; NOMNL-NEXT: (loop $loop
+ ;; NOMNL-NEXT: (if
+ ;; NOMNL-NEXT: (call $helper
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $tempref
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $stashedref
+ ;; NOMNL-NEXT: (local.get $tempref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $tempresult
+ ;; NOMNL-NEXT: (ref.eq
+ ;; NOMNL-NEXT: (local.get $tempref)
+ ;; NOMNL-NEXT: (local.get $stashedref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (br_if $loop
+ ;; NOMNL-NEXT: (call $helper
+ ;; NOMNL-NEXT: (local.get $tempresult)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $propagate-possibly-certain-loop
(local $tempresult i32)
(local $tempref (ref null $empty))
@@ -773,6 +1119,9 @@
;; CHECK: (func $helper (param $0 i32) (result i32)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $helper (param $0 i32) (result i32)
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
(func $helper (param i32) (result i32)
(unreachable)
)
@@ -788,6 +1137,17 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $odd-cast-and-get
+ ;; NOMNL-NEXT: (local $temp (ref null $B))
+ ;; NOMNL-NEXT: (local.set $temp
+ ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (struct.get $B 0
+ ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $odd-cast-and-get
(local $temp (ref null $B))
;; Try to cast a null of A to B. While the types are incompatible, ref.cast
@@ -823,6 +1183,20 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $odd-cast-and-get-tuple
+ ;; NOMNL-NEXT: (local $temp ((ref null $B) i32))
+ ;; NOMNL-NEXT: (local.set $temp
+ ;; NOMNL-NEXT: (tuple.make
+ ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: (i32.const 10)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (struct.get $B 0
+ ;; NOMNL-NEXT: (ref.null $B)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $odd-cast-and-get-tuple
(local $temp ((ref null $B) i32))
;; As above, but with a tuple.
@@ -847,6 +1221,9 @@
;; CHECK: (func $receive-f64 (param $0 f64)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $receive-f64 (param $0 f64)
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
(func $receive-f64 (param f64)
(unreachable)
)
@@ -864,6 +1241,19 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $odd-cast-and-get-non-null (param $temp (ref $func-return-i32))
+ ;; NOMNL-NEXT: (local.set $temp
+ ;; NOMNL-NEXT: (ref.cast
+ ;; NOMNL-NEXT: (ref.func $receive-f64)
+ ;; NOMNL-NEXT: (rtt.canon $func-return-i32)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (call_ref
+ ;; NOMNL-NEXT: (local.get $temp)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $odd-cast-and-get-non-null (param $temp (ref $func-return-i32))
;; Try to cast a function to an incompatible type.
(local.set $temp
@@ -889,6 +1279,14 @@
;; CHECK-NEXT: (rtt.canon $struct)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $new_block_unreachable (result anyref)
+ ;; NOMNL-NEXT: (block
+ ;; NOMNL-NEXT: (block
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (rtt.canon $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $new_block_unreachable (result anyref)
(struct.new_with_rtt $struct
;; The value is a block with an unreachable. precompute will get rid of the
@@ -914,6 +1312,19 @@
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $br_on_cast-on-creation-rtt (result (ref $empty))
+ ;; NOMNL-NEXT: (block $label (result (ref $empty))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_on_cast $label
+ ;; NOMNL-NEXT: (struct.new_default_with_rtt $empty
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (rtt.canon $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $br_on_cast-on-creation-rtt (result (ref $empty))
(block $label (result (ref $empty))
(drop
@@ -941,6 +1352,16 @@
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $br_on_cast-on-creation-nortt (result (ref $empty))
+ ;; NOMNL-NEXT: (block $label (result (ref $empty))
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_on_cast_static $label $empty
+ ;; NOMNL-NEXT: (struct.new_default $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $br_on_cast-on-creation-nortt (result (ref $empty))
(block $label (result (ref $empty))
(drop
@@ -985,6 +1406,38 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $ref.is_null (param $param i32)
+ ;; NOMNL-NEXT: (local $ref (ref null $empty))
+ ;; NOMNL-NEXT: (local.set $ref
+ ;; NOMNL-NEXT: (struct.new_default $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (call $helper
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $ref
+ ;; NOMNL-NEXT: (ref.null $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (call $helper
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (if
+ ;; NOMNL-NEXT: (local.get $param)
+ ;; NOMNL-NEXT: (local.set $ref
+ ;; NOMNL-NEXT: (struct.new_default $empty)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (call $helper
+ ;; NOMNL-NEXT: (ref.is_null
+ ;; NOMNL-NEXT: (local.get $ref)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $ref.is_null (param $param i32)
(local $ref (ref null $empty))
;; Test ref.null on references, and also test that we can infer multiple
diff --git a/test/lit/passes/roundtrip-gc-types.wast b/test/lit/passes/roundtrip-gc-types.wast
index c5ed84d54..d14415f3b 100644
--- a/test/lit/passes/roundtrip-gc-types.wast
+++ b/test/lit/passes/roundtrip-gc-types.wast
@@ -8,19 +8,19 @@
(module
;; CHECK: (type $A (struct (field (ref $C))))
- ;; NOMNL: (type $A (struct (field (ref $C))))
+ ;; NOMNL: (type $A (struct_subtype (field (ref $C)) data))
(type $A (struct (field (ref $C))))
;; CHECK: (type $C (struct (field (mut (ref $B)))))
;; CHECK: (type $B (func (param (ref $A)) (result (ref $B))))
- ;; NOMNL: (type $C (struct (field (mut (ref $B)))))
+ ;; NOMNL: (type $C (struct_subtype (field (mut (ref $B))) data))
- ;; NOMNL: (type $B (func (param (ref $A)) (result (ref $B))))
+ ;; NOMNL: (type $B (func_subtype (param (ref $A)) (result (ref $B)) func))
(type $B (func (param (ref $A)) (result (ref $B))))
(type $C (struct (field (mut (ref $B)))))
;; CHECK: (type $D (struct (field (ref $C)) (field (ref $A))))
- ;; NOMNL: (type $D (struct (field (ref $C)) (field (ref $A))) (extends $A))
- (type $D (struct (field (ref $C)) (field (ref $A))) (extends $A))
+ ;; NOMNL: (type $D (struct_subtype (field (ref $C)) (field (ref $A)) $A))
+ (type $D (struct_subtype (field (ref $C)) (field (ref $A)) $A))
;; CHECK: (global $g0 (rtt 0 $A) (rtt.canon $A))
;; NOMNL: (global $g0 (rtt 0 $A) (rtt.canon $A))
(global $g0 (rtt 0 $A) (rtt.canon $A))
diff --git a/test/lit/passes/simplify-locals-gc.wast b/test/lit/passes/simplify-locals-gc.wast
index 97891aca4..380bcc16b 100644
--- a/test/lit/passes/simplify-locals-gc.wast
+++ b/test/lit/passes/simplify-locals-gc.wast
@@ -2,13 +2,15 @@
;; RUN: wasm-opt %s --simplify-locals -all -S -o - \
;; RUN: | filecheck %s
;; RUN: wasm-opt %s --simplify-locals -all --nominal -S -o - \
-;; RUN: | filecheck %s
+;; RUN: | filecheck %s --check-prefix=NOMNL
(module
;; CHECK: (type $struct (struct (field (mut i32))))
+ ;; NOMNL: (type $struct (struct_subtype (field (mut i32)) data))
(type $struct (struct (field (mut i32))))
;; CHECK: (type $struct-immutable (struct (field i32)))
+ ;; NOMNL: (type $struct-immutable (struct_subtype (field i32) data))
(type $struct-immutable (struct (field i32)))
;; Writes to heap objects cannot be reordered with reads.
@@ -25,6 +27,19 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $temp)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $no-reorder-past-write (param $x (ref $struct)) (result i32)
+ ;; NOMNL-NEXT: (local $temp i32)
+ ;; NOMNL-NEXT: (local.set $temp
+ ;; NOMNL-NEXT: (struct.get $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.set $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (i32.const 42)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $temp)
+ ;; NOMNL-NEXT: )
(func $no-reorder-past-write (param $x (ref $struct)) (result i32)
(local $temp i32)
(local.set $temp
@@ -50,6 +65,17 @@
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $reorder-past-write-if-immutable (param $x (ref $struct)) (param $y (ref $struct-immutable)) (result i32)
+ ;; NOMNL-NEXT: (local $temp i32)
+ ;; NOMNL-NEXT: (nop)
+ ;; NOMNL-NEXT: (struct.set $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (i32.const 42)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.get $struct-immutable 0
+ ;; NOMNL-NEXT: (local.get $y)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $reorder-past-write-if-immutable (param $x (ref $struct)) (param $y (ref $struct-immutable)) (result i32)
(local $temp i32)
(local.set $temp
@@ -79,6 +105,21 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.get $temp)
;; CHECK-NEXT: )
+ ;; NOMNL: (func $unreachable-struct.get (param $x (ref $struct)) (param $y (ref $struct-immutable)) (result i32)
+ ;; NOMNL-NEXT: (local $temp i32)
+ ;; NOMNL-NEXT: (local.tee $temp
+ ;; NOMNL-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (struct.set $struct 0
+ ;; NOMNL-NEXT: (local.get $x)
+ ;; NOMNL-NEXT: (i32.const 42)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.get $temp)
+ ;; NOMNL-NEXT: )
(func $unreachable-struct.get (param $x (ref $struct)) (param $y (ref $struct-immutable)) (result i32)
(local $temp i32)
;; As above, but the get's ref is unreachable. This tests we do not hit an
@@ -119,6 +160,28 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; NOMNL: (func $no-block-values-if-br_on
+ ;; NOMNL-NEXT: (local $temp anyref)
+ ;; NOMNL-NEXT: (block $block
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (br_on_null $block
+ ;; NOMNL-NEXT: (ref.null any)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (local.set $temp
+ ;; NOMNL-NEXT: (ref.null any)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (br $block)
+ ;; NOMNL-NEXT: (local.set $temp
+ ;; NOMNL-NEXT: (ref.null any)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (local.get $temp)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
(func $no-block-values-if-br_on
(local $temp (ref null any))
(block $block