|
3 | 3 |
|
4 | 4 | (module |
5 | 5 | ;; CHECK: (type $maybe-has-effects (func (param i32 i32))) |
| 6 | + (type $maybe-has-effects (func (param i32 i32))) |
6 | 7 |
|
7 | 8 | ;; CHECK: (type $nopType (func (param i32))) |
8 | 9 | (type $nopType (func (param i32))) |
9 | 10 |
|
10 | | - (type $maybe-has-effects (func (param i32 i32))) |
| 11 | + ;; CHECK: (type $super (sub (struct))) |
| 12 | + (type $super (sub (struct))) |
| 13 | + ;; CHECK: (type $sub (sub $super (struct))) |
| 14 | + (type $sub (sub $super (struct))) |
| 15 | + |
| 16 | + ;; CHECK: (type $func-with-sub-param (func (param (ref $sub)))) |
| 17 | + |
| 18 | + ;; CHECK: (type $uninhabited (func (param f32))) |
| 19 | + (type $uninhabited (func (param f32))) |
| 20 | + |
| 21 | + ;; Subtype |
| 22 | + ;; CHECK: (type $func-with-super-param (func (param (ref $super)))) |
| 23 | + (type $func-with-super-param (func (param (ref $super)))) |
| 24 | + ;; Supertype |
| 25 | + (type $func-with-sub-param (func (param (ref $sub)))) |
11 | 26 |
|
12 | 27 | ;; CHECK: (global $g (mut i32) (i32.const 0)) |
13 | 28 | (global $g (mut i32) (i32.const 0)) |
|
33 | 48 | (nop) |
34 | 49 | ) |
35 | 50 |
|
36 | | - ;; CHECK: (func $calls-nop-via-ref (type $2) (param $ref (ref $nopType)) |
| 51 | + ;; CHECK: (func $calls-nop-via-ref (type $6) (param $ref (ref $nopType)) |
37 | 52 | ;; CHECK-NEXT: (call_ref $nopType |
38 | 53 | ;; CHECK-NEXT: (i32.const 1) |
39 | 54 | ;; CHECK-NEXT: (local.get $ref) |
|
47 | 62 | (call_ref $nopType (i32.const 1) (local.get $ref)) |
48 | 63 | ) |
49 | 64 |
|
50 | | - ;; CHECK: (func $f (type $3) (param $ref (ref $nopType)) (result i32) |
51 | | - ;; CHECK-NEXT: (i32.const 1) |
| 65 | + ;; CHECK: (func $f (type $6) (param $ref (ref $nopType)) |
| 66 | + ;; CHECK-NEXT: (nop) |
52 | 67 | ;; CHECK-NEXT: ) |
53 | | - (func $f (param $ref (ref $nopType)) (result i32) |
| 68 | + (func $f (param $ref (ref $nopType)) |
54 | 69 | ;; $calls-nop-via-ref has no effects because we determined that it can only |
55 | 70 | ;; call $nop. We can optimize this call out. |
56 | 71 | (call $calls-nop-via-ref (local.get $ref)) |
57 | | - (i32.const 1) |
58 | 72 | ) |
59 | 73 |
|
60 | | - ;; CHECK: (func $calls-effectful-function-via-ref (type $4) (param $ref (ref $maybe-has-effects)) |
| 74 | + ;; CHECK: (func $calls-effectful-function-via-ref (type $9) (param $ref (ref $maybe-has-effects)) |
61 | 75 | ;; CHECK-NEXT: (call_ref $maybe-has-effects |
62 | 76 | ;; CHECK-NEXT: (i32.const 1) |
63 | 77 | ;; CHECK-NEXT: (i32.const 2) |
|
68 | 82 | (call_ref $maybe-has-effects (i32.const 1) (i32.const 2) (local.get $ref)) |
69 | 83 | ) |
70 | 84 |
|
71 | | - ;; CHECK: (func $g (type $5) (param $ref (ref $maybe-has-effects)) (result i32) |
| 85 | + ;; CHECK: (func $g (type $10) (param $ref (ref $maybe-has-effects)) (result i32) |
72 | 86 | ;; CHECK-NEXT: (call $calls-effectful-function-via-ref |
73 | 87 | ;; CHECK-NEXT: (local.get $ref) |
74 | 88 | ;; CHECK-NEXT: ) |
|
80 | 94 | (call $calls-effectful-function-via-ref (local.get $ref)) |
81 | 95 | (i32.const 1) |
82 | 96 | ) |
| 97 | + |
| 98 | + ;; CHECK: (func $calls-uninhabited (type $7) (param $ref (ref $uninhabited)) |
| 99 | + ;; CHECK-NEXT: (call_ref $uninhabited |
| 100 | + ;; CHECK-NEXT: (f32.const 0) |
| 101 | + ;; CHECK-NEXT: (local.get $ref) |
| 102 | + ;; CHECK-NEXT: ) |
| 103 | + ;; CHECK-NEXT: ) |
| 104 | + (func $calls-uninhabited (param $ref (ref $uninhabited)) |
| 105 | + (call_ref $uninhabited (f32.const 0) (local.get $ref)) |
| 106 | + ) |
| 107 | + |
| 108 | + ;; CHECK: (func $h (type $7) (param $ref (ref $uninhabited)) |
| 109 | + ;; CHECK-NEXT: (nop) |
| 110 | + ;; CHECK-NEXT: ) |
| 111 | + (func $h (param $ref (ref $uninhabited)) |
| 112 | + ;; There's no function with this type, so it's impossible to create a ref to |
| 113 | + ;; call this function with and there are no effects to aggregate. |
| 114 | + ;; Remove this call. |
| 115 | + (call $calls-uninhabited (local.get $ref)) |
| 116 | + ) |
| 117 | + |
| 118 | + ;; CHECK: (func $nop-with-supertype (type $func-with-sub-param) (param $0 (ref $sub)) |
| 119 | + ;; CHECK-NEXT: (nop) |
| 120 | + ;; CHECK-NEXT: ) |
| 121 | + (func $nop-with-supertype (type $func-with-sub-param) (param (ref $sub)) |
| 122 | + ) |
| 123 | + |
| 124 | + ;; CHECK: (func $effectful-with-subtype (type $func-with-super-param) (param $0 (ref $super)) |
| 125 | + ;; CHECK-NEXT: (unreachable) |
| 126 | + ;; CHECK-NEXT: ) |
| 127 | + (func $effectful-with-subtype (type $func-with-super-param) (param (ref $super)) |
| 128 | + (unreachable) |
| 129 | + ) |
| 130 | + |
| 131 | + ;; CHECK: (func $calls-ref-with-subtype (type $8) (param $func (ref $func-with-sub-param)) (param $sub (ref $sub)) |
| 132 | + ;; CHECK-NEXT: (call_ref $func-with-sub-param |
| 133 | + ;; CHECK-NEXT: (local.get $sub) |
| 134 | + ;; CHECK-NEXT: (local.get $func) |
| 135 | + ;; CHECK-NEXT: ) |
| 136 | + ;; CHECK-NEXT: ) |
| 137 | + (func $calls-ref-with-subtype (param $func (ref $func-with-sub-param)) (param $sub (ref $sub)) |
| 138 | + (call_ref $func-with-sub-param (local.get $sub) (local.get $func)) |
| 139 | + ) |
| 140 | + |
| 141 | + ;; CHECK: (func $asdf (type $8) (param $func (ref $func-with-sub-param)) (param $sub (ref $sub)) |
| 142 | + ;; CHECK-NEXT: (nop) |
| 143 | + ;; CHECK-NEXT: ) |
| 144 | + (func $asdf (param $func (ref $func-with-sub-param)) (param $sub (ref $sub)) |
| 145 | + ;; Check that we account for subtyping correctly. |
| 146 | + ;; The type $func-with-sub-param (the supertype) has no effects (i.e. the |
| 147 | + ;; union of all effects of functions with this type is empty). |
| 148 | + ;; However, a subtype of $func-with-sub-param ($func-with-super-param) does |
| 149 | + ;; have effects, and we can call_ref with that subtype, so we need to |
| 150 | + ;; include the unreachable effect and we can't optimize out this call. |
| 151 | + (call $calls-ref-with-subtype (local.get $func) (local.get $sub)) |
| 152 | + ) |
83 | 153 | ) |
0 commit comments