Skip to content

Commit 7d1b989

Browse files
Add test
1 parent bf88eae commit 7d1b989

1 file changed

Lines changed: 232 additions & 0 deletions

File tree

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
2+
;; RUN: wasm-opt %s -all --closed-world --generate-global-effects --vacuum -S -o - | filecheck %s
3+
4+
(module
5+
;; CHECK: (type $maybe-has-effects (func (param i32 i32)))
6+
(type $maybe-has-effects (func (param i32 i32)))
7+
8+
;; CHECK: (type $only-has-effects-in-non-exported-function (func (param f32 f32)))
9+
10+
;; CHECK: (type $nopType (func (param i32)))
11+
(type $nopType (func (param i32)))
12+
13+
;; CHECK: (type $super (sub (struct)))
14+
(type $super (sub (struct)))
15+
;; CHECK: (type $sub (sub $super (struct)))
16+
(type $sub (sub $super (struct)))
17+
18+
;; CHECK: (type $func-with-sub-param (sub (func (param (ref $sub)))))
19+
20+
;; CHECK: (type $uninhabited (func (param f32)))
21+
(type $uninhabited (func (param f32)))
22+
23+
;; Subtype
24+
(type $func-with-sub-param (sub (func (param (ref $sub)))))
25+
26+
;; Subtype
27+
;; CHECK: (type $ttt (func (param i64)))
28+
29+
;; CHECK: (type $func-with-super-param (sub $func-with-sub-param (func (param (ref $super)))))
30+
(type $func-with-super-param (sub $func-with-sub-param (func (param (ref $super)))))
31+
32+
(type $only-has-effects-in-non-exported-function (func (param f32 f32)))
33+
34+
(table 10 funcref)
35+
36+
;; CHECK: (global $g (mut i32) (i32.const 0))
37+
(global $g (mut i32) (i32.const 0))
38+
39+
;; CHECK: (elem declare func $A)
40+
41+
;; CHECK: (func $nop (type $nopType) (param $0 i32)
42+
;; CHECK-NEXT: (nop)
43+
;; CHECK-NEXT: )
44+
(func $nop (export "nop") (type $nopType)
45+
(nop)
46+
)
47+
48+
;; CHECK: (func $unreachable (type $maybe-has-effects) (param $0 i32) (param $1 i32)
49+
;; CHECK-NEXT: (unreachable)
50+
;; CHECK-NEXT: )
51+
(func $unreachable (export "unreachable") (type $maybe-has-effects) (param i32 i32)
52+
(unreachable)
53+
)
54+
55+
;; CHECK: (func $nop2 (type $maybe-has-effects) (param $0 i32) (param $1 i32)
56+
;; CHECK-NEXT: (nop)
57+
;; CHECK-NEXT: )
58+
(func $nop2 (export "nop2") (type $maybe-has-effects) (param i32 i32)
59+
(nop)
60+
)
61+
62+
;; CHECK: (func $calls-nop-via-ref (type $8) (param $ref (ref $nopType))
63+
;; CHECK-NEXT: (call_ref $nopType
64+
;; CHECK-NEXT: (i32.const 1)
65+
;; CHECK-NEXT: (local.get $ref)
66+
;; CHECK-NEXT: )
67+
;; CHECK-NEXT: )
68+
(func $calls-nop-via-ref (param $ref (ref $nopType))
69+
;; This can only possibly be a nop in closed-world
70+
;; Ideally vacuum could optimize this out but we don't have a way to share
71+
;; this information with other passes today.
72+
;; For now, we can at least annotate that $f has no effects.
73+
(call_ref $nopType (i32.const 1) (local.get $ref))
74+
)
75+
76+
;; CHECK: (func $f (type $8) (param $ref (ref $nopType))
77+
;; CHECK-NEXT: (nop)
78+
;; CHECK-NEXT: )
79+
(func $f (param $ref (ref $nopType))
80+
;; $calls-nop-via-ref has no effects because we determined that it can only
81+
;; call $nop. We can optimize this call out.
82+
(call $calls-nop-via-ref (local.get $ref))
83+
)
84+
85+
;; CHECK: (func $calls-effectful-function-via-ref (type $9) (param $ref (ref $maybe-has-effects))
86+
;; CHECK-NEXT: (call_ref $maybe-has-effects
87+
;; CHECK-NEXT: (i32.const 1)
88+
;; CHECK-NEXT: (i32.const 2)
89+
;; CHECK-NEXT: (local.get $ref)
90+
;; CHECK-NEXT: )
91+
;; CHECK-NEXT: )
92+
(func $calls-effectful-function-via-ref (param $ref (ref $maybe-has-effects))
93+
(call_ref $maybe-has-effects (i32.const 1) (i32.const 2) (local.get $ref))
94+
)
95+
96+
;; CHECK: (func $g (type $9) (param $ref (ref $maybe-has-effects))
97+
;; CHECK-NEXT: (call $calls-effectful-function-via-ref
98+
;; CHECK-NEXT: (local.get $ref)
99+
;; CHECK-NEXT: )
100+
;; CHECK-NEXT: )
101+
(func $g (param $ref (ref $maybe-has-effects))
102+
;; This may be a nop or it may trap depending on the ref
103+
;; We don't know so don't optimize it out.
104+
(call $calls-effectful-function-via-ref (local.get $ref))
105+
)
106+
107+
;; CHECK: (func $calls-uninhabited (type $10) (param $ref (ref $uninhabited))
108+
;; CHECK-NEXT: (call_ref $uninhabited
109+
;; CHECK-NEXT: (f32.const 0)
110+
;; CHECK-NEXT: (local.get $ref)
111+
;; CHECK-NEXT: )
112+
;; CHECK-NEXT: )
113+
(func $calls-uninhabited (param $ref (ref $uninhabited))
114+
(call_ref $uninhabited (f32.const 0) (local.get $ref))
115+
)
116+
117+
;; CHECK: (func $h (type $10) (param $ref (ref $uninhabited))
118+
;; CHECK-NEXT: (nop)
119+
;; CHECK-NEXT: )
120+
(func $h (param $ref (ref $uninhabited))
121+
;; There's no function with this type, so it's impossible to create a ref to
122+
;; call this function with and there are no effects to aggregate.
123+
;; Remove this call.
124+
(call $calls-uninhabited (local.get $ref))
125+
)
126+
127+
;; CHECK: (func $nop-with-supertype (type $func-with-sub-param) (param $0 (ref $sub))
128+
;; CHECK-NEXT: (nop)
129+
;; CHECK-NEXT: )
130+
(func $nop-with-supertype (export "nop-with-supertype") (type $func-with-sub-param) (param (ref $sub))
131+
)
132+
133+
;; CHECK: (func $effectful-with-subtype (type $func-with-super-param) (param $0 (ref $super))
134+
;; CHECK-NEXT: (unreachable)
135+
;; CHECK-NEXT: )
136+
(func $effectful-with-subtype (export "effectful-with-subtype") (type $func-with-super-param) (param (ref $super))
137+
(unreachable)
138+
)
139+
140+
;; CHECK: (func $calls-ref-with-subtype (type $11) (param $func (ref $func-with-sub-param)) (param $sub (ref $sub))
141+
;; CHECK-NEXT: (call_ref $func-with-sub-param
142+
;; CHECK-NEXT: (local.get $sub)
143+
;; CHECK-NEXT: (local.get $func)
144+
;; CHECK-NEXT: )
145+
;; CHECK-NEXT: )
146+
(func $calls-ref-with-subtype (param $func (ref $func-with-sub-param)) (param $sub (ref $sub))
147+
(call_ref $func-with-sub-param (local.get $sub) (local.get $func))
148+
)
149+
150+
;; CHECK: (func $asdf (type $11) (param $func (ref $func-with-sub-param)) (param $sub (ref $sub))
151+
;; CHECK-NEXT: (call $calls-ref-with-subtype
152+
;; CHECK-NEXT: (local.get $func)
153+
;; CHECK-NEXT: (local.get $sub)
154+
;; CHECK-NEXT: )
155+
;; CHECK-NEXT: )
156+
(func $asdf (param $func (ref $func-with-sub-param)) (param $sub (ref $sub))
157+
;; Check that we account for subtyping correctly.
158+
;; The type $func-with-sub-param (the supertype) has no effects (i.e. the
159+
;; union of all effects of functions with this type is empty).
160+
;; However, a subtype of $func-with-sub-param ($func-with-super-param) does
161+
;; have effects, and we can call_ref with that subtype, so we need to
162+
;; include the unreachable effect and we can't optimize out this call.
163+
(call $calls-ref-with-subtype (local.get $func) (local.get $sub))
164+
)
165+
166+
;; CHECK: (func $no-effects (type $only-has-effects-in-non-exported-function) (param $0 f32) (param $1 f32)
167+
;; CHECK-NEXT: (nop)
168+
;; CHECK-NEXT: )
169+
(func $no-effects (type $only-has-effects-in-non-exported-function) (param f32 f32)
170+
)
171+
172+
;; CHECK: (func $has-effects-but-not-exported (type $only-has-effects-in-non-exported-function) (param $0 f32) (param $1 f32)
173+
;; CHECK-NEXT: (unreachable)
174+
;; CHECK-NEXT: )
175+
(func $has-effects-but-not-exported (type $only-has-effects-in-non-exported-function) (param f32 f32)
176+
(unreachable)
177+
)
178+
179+
;; CHECK: (func $calls-type-with-effects-but-not-addressable (type $12) (param $ref (ref $only-has-effects-in-non-exported-function))
180+
;; CHECK-NEXT: (call_ref $only-has-effects-in-non-exported-function
181+
;; CHECK-NEXT: (f32.const 0)
182+
;; CHECK-NEXT: (f32.const 0)
183+
;; CHECK-NEXT: (local.get $ref)
184+
;; CHECK-NEXT: )
185+
;; CHECK-NEXT: )
186+
(func $calls-type-with-effects-but-not-addressable (param $ref (ref $only-has-effects-in-non-exported-function))
187+
(call_ref $only-has-effects-in-non-exported-function (f32.const 0) (f32.const 0) (local.get $ref))
188+
)
189+
190+
;; CHECK: (func $i (type $12) (param $ref (ref $only-has-effects-in-non-exported-function))
191+
;; CHECK-NEXT: (nop)
192+
;; CHECK-NEXT: )
193+
(func $i (param $ref (ref $only-has-effects-in-non-exported-function))
194+
(call $calls-type-with-effects-but-not-addressable (local.get $ref))
195+
)
196+
197+
;; CHECK: (func $B (type $6)
198+
;; CHECK-NEXT: (unreachable)
199+
;; CHECK-NEXT: )
200+
(func $B
201+
(unreachable)
202+
)
203+
204+
(type $ttt (func (param i64)))
205+
206+
;; CHECK: (func $A (type $ttt) (param $0 i64)
207+
;; CHECK-NEXT: (call $B)
208+
;; CHECK-NEXT: )
209+
(func $A (param i64)
210+
(call $B)
211+
;; (call_ref $ttt (ref.func $u))
212+
)
213+
214+
(elem declare $two)
215+
216+
;; CHECK: (func $C (type $6)
217+
;; CHECK-NEXT: (call_ref $ttt
218+
;; CHECK-NEXT: (i64.const 0)
219+
;; CHECK-NEXT: (ref.func $A)
220+
;; CHECK-NEXT: )
221+
;; CHECK-NEXT: )
222+
(func $C
223+
(call_ref $ttt (i64.const 0) (ref.func $A))
224+
)
225+
226+
;; CHECK: (func $foo (type $6)
227+
;; CHECK-NEXT: (nop)
228+
;; CHECK-NEXT: )
229+
(func $foo
230+
(call $C)
231+
)
232+
)

0 commit comments

Comments
 (0)