|
3 | 3 | ;; Check that we don't refine in ways that might require invalid exact casts |
4 | 4 | ;; when custom descriptors is disabled. |
5 | 5 |
|
6 | | -;; RUN: wasm-opt %s -all --closed-world --preserve-type-order \ |
| 6 | +;; RUN: foreach %s %t wasm-opt -all --closed-world --preserve-type-order \ |
7 | 7 | ;; RUN: --type-refining-gufa -S -o - | filecheck %s |
8 | 8 |
|
9 | | -;; RUN: wasm-opt %s -all --disable-custom-descriptors --closed-world --preserve-type-order \ |
| 9 | +;; RUN: foreach %s %t wasm-opt -all --disable-custom-descriptors --closed-world --preserve-type-order \ |
10 | 10 | ;; RUN: --type-refining-gufa -S -o - | filecheck %s --check-prefix=NO_CD |
11 | 11 |
|
12 | 12 | (module |
|
78 | 78 | ) |
79 | 79 | ) |
80 | 80 | ) |
| 81 | + |
| 82 | +;; Avoid casting continuations. |
| 83 | +(module |
| 84 | + (rec |
| 85 | + ;; CHECK: (rec |
| 86 | + ;; CHECK-NEXT: (type $func (func)) |
| 87 | + ;; NO_CD: (rec |
| 88 | + ;; NO_CD-NEXT: (type $func (func)) |
| 89 | + (type $func (func)) |
| 90 | + ;; CHECK: (type $cont (cont $func)) |
| 91 | + ;; NO_CD: (type $cont (cont $func)) |
| 92 | + (type $cont (cont $func)) |
| 93 | + ;; CHECK: (type $struct (struct (field (ref $cont)))) |
| 94 | + ;; NO_CD: (type $struct (struct (field (ref $cont)))) |
| 95 | + (type $struct (struct (field (ref $cont)))) |
| 96 | + ) |
| 97 | + |
| 98 | + ;; CHECK: (func $nop (type $func) |
| 99 | + ;; CHECK-NEXT: (nop) |
| 100 | + ;; CHECK-NEXT: ) |
| 101 | + ;; NO_CD: (func $nop (type $func) |
| 102 | + ;; NO_CD-NEXT: (nop) |
| 103 | + ;; NO_CD-NEXT: ) |
| 104 | + (func $nop (type $func) |
| 105 | + (nop) |
| 106 | + ) |
| 107 | + |
| 108 | + ;; CHECK: (func $trap (type $3) (result (ref $cont)) |
| 109 | + ;; CHECK-NEXT: (unreachable) |
| 110 | + ;; CHECK-NEXT: ) |
| 111 | + ;; NO_CD: (func $trap (type $3) (result (ref $cont)) |
| 112 | + ;; NO_CD-NEXT: (unreachable) |
| 113 | + ;; NO_CD-NEXT: ) |
| 114 | + (func $trap (result (ref $cont)) |
| 115 | + (unreachable) |
| 116 | + ) |
| 117 | + |
| 118 | + ;; CHECK: (func $make (type $4) |
| 119 | + ;; CHECK-NEXT: (drop |
| 120 | + ;; CHECK-NEXT: (struct.new $struct |
| 121 | + ;; CHECK-NEXT: (cont.new $cont |
| 122 | + ;; CHECK-NEXT: (ref.func $nop) |
| 123 | + ;; CHECK-NEXT: ) |
| 124 | + ;; CHECK-NEXT: ) |
| 125 | + ;; CHECK-NEXT: ) |
| 126 | + ;; CHECK-NEXT: (drop |
| 127 | + ;; CHECK-NEXT: (struct.new $struct |
| 128 | + ;; CHECK-NEXT: (call $trap) |
| 129 | + ;; CHECK-NEXT: ) |
| 130 | + ;; CHECK-NEXT: ) |
| 131 | + ;; CHECK-NEXT: ) |
| 132 | + ;; NO_CD: (func $make (type $4) |
| 133 | + ;; NO_CD-NEXT: (drop |
| 134 | + ;; NO_CD-NEXT: (struct.new $struct |
| 135 | + ;; NO_CD-NEXT: (cont.new $cont |
| 136 | + ;; NO_CD-NEXT: (ref.func $nop) |
| 137 | + ;; NO_CD-NEXT: ) |
| 138 | + ;; NO_CD-NEXT: ) |
| 139 | + ;; NO_CD-NEXT: ) |
| 140 | + ;; NO_CD-NEXT: (drop |
| 141 | + ;; NO_CD-NEXT: (struct.new $struct |
| 142 | + ;; NO_CD-NEXT: (call $trap) |
| 143 | + ;; NO_CD-NEXT: ) |
| 144 | + ;; NO_CD-NEXT: ) |
| 145 | + ;; NO_CD-NEXT: ) |
| 146 | + (func $make |
| 147 | + ;; Make the struct twice, once with a proper continuation, and once with a |
| 148 | + ;; call to a function that GUFA infers a trap in. The latter would usually |
| 149 | + ;; be fixed up, allowing the struct field to be refined to be exact, but a cast is not |
| 150 | + ;; valid on a continuation, so we must avoid refining this struct to have an |
| 151 | + ;; exact field. |
| 152 | + (drop |
| 153 | + (struct.new $struct |
| 154 | + (cont.new $cont |
| 155 | + (ref.func $nop) |
| 156 | + ) |
| 157 | + ) |
| 158 | + ) |
| 159 | + (drop |
| 160 | + (struct.new $struct |
| 161 | + (call $trap) |
| 162 | + ) |
| 163 | + ) |
| 164 | + ) |
| 165 | +) |
| 166 | + |
0 commit comments