blob: 6422431617cc0fb9d93984dca41d7047f1aa1a19 [file] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; RUN: foreach %s %t wasm-opt --closed-world --cfp-reftest -all -S -o - | filecheck %s
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $A (sub (struct (field (mut i32)))))
(type $A (sub (struct (field (mut i32)))))
;; CHECK: (type $B (sub $A (struct (field (mut i32)))))
(type $B (sub $A (struct (field (mut i32)))))
;; CHECK: (type $other (sub (struct (field (mut i32)))))
(type $other (sub (struct (field (mut i32)))))
)
;; CHECK: (type $3 (func (param (ref $other) (ref $A))))
;; CHECK: (type $4 (func (param (ref $other) (ref (exact $A)))))
;; CHECK: (type $5 (func (param (ref $A)) (result i32)))
;; CHECK: (func $init (type $3) (param $other (ref $other)) (param $A (ref $A))
;; CHECK-NEXT: (struct.set $other 0
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $init (param $other (ref $other)) (param $A (ref $A))
(struct.set $other 0
(local.get $other)
(i32.const 10)
)
;; Set inexact A.
(struct.set $A 0
(local.get $A)
(i32.const 20)
)
)
;; CHECK: (func $copy (type $4) (param $other (ref $other)) (param $A-exact (ref (exact $A)))
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A-exact)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $copy (param $other (ref $other)) (param $A-exact (ref (exact $A)))
;; Copy to exact A.
(struct.set $A 0
(local.get $A-exact)
(struct.get $other 0
(local.get $other)
)
)
)
;; CHECK: (func $get (type $5) (param $A (ref $A)) (result i32)
;; CHECK-NEXT: (struct.get $A 0
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $get (param $A (ref $A)) (result i32)
;; We won't be able to optimize because the set of inexact A could go to
;; anything.
(struct.get $A 0
(local.get $A)
)
)
)
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $A (sub (struct (field (mut i32)))))
(type $A (sub (struct (field (mut i32)))))
;; CHECK: (type $B (sub $A (struct (field (mut i32)))))
(type $B (sub $A (struct (field (mut i32)))))
;; CHECK: (type $other (sub (struct (field (mut i32)))))
(type $other (sub (struct (field (mut i32)))))
)
;; CHECK: (type $3 (func (param (ref $other) (ref $A))))
;; CHECK: (type $4 (func (param (ref $other) (ref $B))))
;; CHECK: (type $5 (func (param (ref $A)) (result i32)))
;; CHECK: (func $init (type $3) (param $other (ref $other)) (param $A (ref $A))
;; CHECK-NEXT: (struct.set $other 0
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $init (param $other (ref $other)) (param $A (ref $A))
(struct.set $other 0
(local.get $other)
(i32.const 10)
)
;; Set inexact A.
(struct.set $A 0
(local.get $A)
(i32.const 20)
)
)
;; CHECK: (func $copy (type $4) (param $other (ref $other)) (param $B (ref $B))
;; CHECK-NEXT: (struct.set $B 0
;; CHECK-NEXT: (local.get $B)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $copy (param $other (ref $other)) (param $B (ref $B))
;; Copy to inexact B.
(struct.set $B 0
(local.get $B)
(struct.get $other 0
(local.get $other)
)
)
)
;; CHECK: (func $get (type $5) (param $A (ref $A)) (result i32)
;; CHECK-NEXT: (struct.get $A 0
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $get (param $A (ref $A)) (result i32)
;; We won't be able to optimize because the set of inexact A could go to
;; anything.
(struct.get $A 0
(local.get $A)
)
)
)
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $A (sub (struct (field (mut i32)))))
(type $A (sub (struct (field (mut i32)))))
;; CHECK: (type $B (sub $A (struct (field (mut i32)))))
(type $B (sub $A (struct (field (mut i32)))))
;; CHECK: (type $other (sub (struct (field (mut i32)))))
(type $other (sub (struct (field (mut i32)))))
)
;; CHECK: (type $3 (func (param (ref $other) (ref $A))))
;; CHECK: (type $4 (func (param (ref $other) (ref (exact $B)))))
;; CHECK: (type $5 (func (param (ref $A)) (result i32)))
;; CHECK: (func $init (type $3) (param $other (ref $other)) (param $A (ref $A))
;; CHECK-NEXT: (struct.set $other 0
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $init (param $other (ref $other)) (param $A (ref $A))
(struct.set $other 0
(local.get $other)
(i32.const 10)
)
;; Set inexact A.
(struct.set $A 0
(local.get $A)
(i32.const 20)
)
)
;; CHECK: (func $copy (type $4) (param $other (ref $other)) (param $B-exact (ref (exact $B)))
;; CHECK-NEXT: (struct.set $B 0
;; CHECK-NEXT: (local.get $B-exact)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $copy (param $other (ref $other)) (param $B-exact (ref (exact $B)))
;; Copy to exact B.
(struct.set $B 0
(local.get $B-exact)
(struct.get $other 0
(local.get $other)
)
)
)
;; CHECK: (func $get (type $5) (param $A (ref $A)) (result i32)
;; CHECK-NEXT: (struct.get $A 0
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $get (param $A (ref $A)) (result i32)
;; We won't be able to optimize because the set of inexact A could go to
;; anything.
(struct.get $A 0
(local.get $A)
)
)
)
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $A (sub (struct (field (mut i32)))))
(type $A (sub (struct (field (mut i32)))))
;; CHECK: (type $B (sub $A (struct (field (mut i32)))))
(type $B (sub $A (struct (field (mut i32)))))
;; CHECK: (type $other (sub (struct (field (mut i32)))))
(type $other (sub (struct (field (mut i32)))))
)
;; CHECK: (type $3 (func (param (ref $other) (ref (exact $A)))))
;; CHECK: (type $4 (func (param (ref $other) (ref $A))))
;; CHECK: (type $5 (func (param (ref $A)) (result i32)))
;; CHECK: (func $init (type $3) (param $other (ref $other)) (param $A-exact (ref (exact $A)))
;; CHECK-NEXT: (struct.set $other 0
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A-exact)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $init (param $other (ref $other)) (param $A-exact (ref (exact $A)))
(struct.set $other 0
(local.get $other)
(i32.const 10)
)
;; Set exact A.
(struct.set $A 0
(local.get $A-exact)
(i32.const 20)
)
)
;; CHECK: (func $copy (type $4) (param $other (ref $other)) (param $A (ref $A))
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $copy (param $other (ref $other)) (param $A (ref $A))
;; Copy to inexact A.
(struct.set $A 0
(local.get $A)
(struct.get $other 0
(local.get $other)
)
)
)
;; CHECK: (func $get (type $5) (param $A (ref $A)) (result i32)
;; CHECK-NEXT: (struct.get $A 0
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $get (param $A (ref $A)) (result i32)
;; We won't be able to optimize because the copy to inexact A could go to
;; anything.
(struct.get $A 0
(local.get $A)
)
)
)
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $A (sub (struct (field (mut i32)))))
(type $A (sub (struct (field (mut i32)))))
;; CHECK: (type $B (sub $A (struct (field (mut i32)))))
(type $B (sub $A (struct (field (mut i32)))))
;; CHECK: (type $other (sub (struct (field (mut i32)))))
(type $other (sub (struct (field (mut i32)))))
)
;; CHECK: (type $3 (func (param (ref $other) (ref (exact $A)))))
;; CHECK: (type $4 (func (param (ref $other) (ref $B))))
;; CHECK: (type $5 (func (param (ref $A)) (result i32)))
;; CHECK: (func $init (type $3) (param $other (ref $other)) (param $A-exact (ref (exact $A)))
;; CHECK-NEXT: (struct.set $other 0
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A-exact)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $init (param $other (ref $other)) (param $A-exact (ref (exact $A)))
(struct.set $other 0
(local.get $other)
(i32.const 10)
)
;; Set exact A.
(struct.set $A 0
(local.get $A-exact)
(i32.const 20)
)
)
;; CHECK: (func $copy (type $4) (param $other (ref $other)) (param $B (ref $B))
;; CHECK-NEXT: (struct.set $B 0
;; CHECK-NEXT: (local.get $B)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $copy (param $other (ref $other)) (param $B (ref $B))
;; Copy to inexact B.
(struct.set $B 0
(local.get $B)
(struct.get $other 0
(local.get $other)
)
)
)
;; CHECK: (func $get (type $5) (param $A (ref $A)) (result i32)
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (ref.test (ref $B)
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $get (param $A (ref $A)) (result i32)
;; We can optimize! Only B will have the copied value.
(struct.get $A 0
(local.get $A)
)
)
)
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $A (sub (struct (field (mut i32)))))
(type $A (sub (struct (field (mut i32)))))
;; CHECK: (type $B (sub $A (struct (field (mut i32)))))
(type $B (sub $A (struct (field (mut i32)))))
;; CHECK: (type $other (sub (struct (field (mut i32)))))
(type $other (sub (struct (field (mut i32)))))
)
;; CHECK: (type $3 (func (param (ref $other) (ref (exact $A)))))
;; CHECK: (type $4 (func (param (ref $other) (ref (exact $B)))))
;; CHECK: (type $5 (func (param (ref $A)) (result i32)))
;; CHECK: (func $init (type $3) (param $other (ref $other)) (param $A-exact (ref (exact $A)))
;; CHECK-NEXT: (struct.set $other 0
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A-exact)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $init (param $other (ref $other)) (param $A-exact (ref (exact $A)))
(struct.set $other 0
(local.get $other)
(i32.const 10)
)
;; Set exact A.
(struct.set $A 0
(local.get $A-exact)
(i32.const 20)
)
)
;; CHECK: (func $copy (type $4) (param $other (ref $other)) (param $B-exact (ref (exact $B)))
;; CHECK-NEXT: (struct.set $B 0
;; CHECK-NEXT: (local.get $B-exact)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $copy (param $other (ref $other)) (param $B-exact (ref (exact $B)))
;; Copy to exact B.
(struct.set $B 0
(local.get $B-exact)
(struct.get $other 0
(local.get $other)
)
)
)
;; CHECK: (func $get (type $5) (param $A (ref $A)) (result i32)
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (ref.test (ref $B)
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $get (param $A (ref $A)) (result i32)
;; We can optimize! Only B will have the copied value.
(struct.get $A 0
(local.get $A)
)
)
)
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $A (sub (struct (field (mut i32)))))
(type $A (sub (struct (field (mut i32)))))
;; CHECK: (type $B (sub $A (struct (field (mut i32)))))
(type $B (sub $A (struct (field (mut i32)))))
;; CHECK: (type $other (sub (struct (field (mut i32)))))
(type $other (sub (struct (field (mut i32)))))
)
;; CHECK: (type $3 (func (param (ref $other) (ref (exact $B)))))
;; CHECK: (type $4 (func (param (ref $other) (ref (exact $A)))))
;; CHECK: (type $5 (func (param (ref $A)) (result i32)))
;; CHECK: (func $init (type $3) (param $other (ref $other)) (param $B-exact (ref (exact $B)))
;; CHECK-NEXT: (struct.set $other 0
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $B 0
;; CHECK-NEXT: (local.get $B-exact)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $init (param $other (ref $other)) (param $B-exact (ref (exact $B)))
(struct.set $other 0
(local.get $other)
(i32.const 10)
)
;; Set exact B.
(struct.set $B 0
(local.get $B-exact)
(i32.const 20)
)
)
;; CHECK: (func $copy (type $4) (param $other (ref $other)) (param $A-exact (ref (exact $A)))
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A-exact)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $copy (param $other (ref $other)) (param $A-exact (ref (exact $A)))
;; Copy to exact A.
(struct.set $A 0
(local.get $A-exact)
(struct.get $other 0
(local.get $other)
)
)
)
;; CHECK: (func $get (type $5) (param $A (ref $A)) (result i32)
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (ref.test (ref $B)
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $get (param $A (ref $A)) (result i32)
;; Switch the copy and set destinations from the previous case. We can still
;; optimize!
(struct.get $A 0
(local.get $A)
)
)
)
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $A (sub (struct (field (mut i32)))))
(type $A (sub (struct (field (mut i32)))))
;; CHECK: (type $B (sub $A (struct (field (mut i32)))))
(type $B (sub $A (struct (field (mut i32)))))
;; CHECK: (type $other (sub (struct (field (mut i32)) (field (mut i32)))))
(type $other (sub (struct (field (mut i32)) (field (mut i32)))))
)
;; CHECK: (type $3 (func (param (ref $other) (ref (exact $B)))))
;; CHECK: (type $4 (func (param (ref $other) (ref (exact $A)))))
;; CHECK: (type $5 (func (param (ref $A)) (result i32)))
;; CHECK: (func $init (type $3) (param $other (ref $other)) (param $B-exact (ref (exact $B)))
;; CHECK-NEXT: (struct.set $other 0
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $B 0
;; CHECK-NEXT: (local.get $B-exact)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $init (param $other (ref $other)) (param $B-exact (ref (exact $B)))
(struct.set $other 0
(local.get $other)
(i32.const 10)
)
;; Set exact B.
(struct.set $B 0
(local.get $B-exact)
(i32.const 20)
)
)
;; CHECK: (func $copy (type $4) (param $other (ref $other)) (param $A-exact (ref (exact $A)))
;; CHECK-NEXT: (struct.set $other 1
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A-exact)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $copy (param $other (ref $other)) (param $A-exact (ref (exact $A)))
;; Copy to another field and from there to exact A.
(struct.set $other 1
(local.get $other)
(struct.get $other 0
(local.get $other)
)
)
;; Copy to exact A.
(struct.set $A 0
(local.get $A-exact)
(struct.get $other 1
(local.get $other)
)
)
)
;; CHECK: (func $get (type $5) (param $A (ref $A)) (result i32)
;; CHECK-NEXT: (select
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: (ref.test (ref $B)
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $get (param $A (ref $A)) (result i32)
;; We can still optimize after doing two copies.
(struct.get $A 0
(local.get $A)
)
)
)
(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $A (sub (struct (field (mut i32)))))
(type $A (sub (struct (field (mut i32)))))
;; CHECK: (type $B (sub $A (struct (field (mut i32)))))
(type $B (sub $A (struct (field (mut i32)))))
;; CHECK: (type $other (sub (struct (field (mut i32)) (field (mut i32)))))
(type $other (sub (struct (field (mut i32)) (field (mut i32)))))
)
;; CHECK: (type $3 (func (param (ref $other) (ref (exact $B)))))
;; CHECK: (type $4 (func (param (ref $other) (ref $A))))
;; CHECK: (type $5 (func (param (ref $A)) (result i32)))
;; CHECK: (func $init (type $3) (param $other (ref $other)) (param $B-exact (ref (exact $B)))
;; CHECK-NEXT: (struct.set $other 0
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $B 0
;; CHECK-NEXT: (local.get $B-exact)
;; CHECK-NEXT: (i32.const 20)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $init (param $other (ref $other)) (param $B-exact (ref (exact $B)))
(struct.set $other 0
(local.get $other)
(i32.const 10)
)
;; Set exact B.
(struct.set $B 0
(local.get $B-exact)
(i32.const 20)
)
)
;; CHECK: (func $copy (type $4) (param $other (ref $other)) (param $A (ref $A))
;; CHECK-NEXT: (struct.set $other 1
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (struct.set $A 0
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (local.get $other)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 10)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $copy (param $other (ref $other)) (param $A (ref $A))
;; Copy to another field and from there to inexact A.
(struct.set $other 1
(local.get $other)
(struct.get $other 0
(local.get $other)
)
)
;; Copy to A.
(struct.set $A 0
(local.get $A)
(struct.get $other 1
(local.get $other)
)
)
)
;; CHECK: (func $get (type $5) (param $A (ref $A)) (result i32)
;; CHECK-NEXT: (struct.get $A 0
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $get (param $A (ref $A)) (result i32)
;; We cannot optimize because the copy to inexact A could write to anything.
(struct.get $A 0
(local.get $A)
)
)
)