|
1085 | 1085 | ;; CHECK: (type $0 (func)) |
1086 | 1086 |
|
1087 | 1087 | ;; CHECK: (rec |
1088 | | - ;; CHECK-NEXT: (type $array (array i8)) |
1089 | | - (type $array (array i8)) |
1090 | | - ;; CHECK: (type $struct (struct (field (mut anyref)))) |
1091 | | - (type $struct (struct (field (mut anyref)))) |
| 1088 | + ;; CHECK-NEXT: (type $inner (array i8)) |
| 1089 | + (type $inner (array i8)) |
| 1090 | + ;; CHECK: (type $struct (struct (field (mut eqref)))) |
| 1091 | + (type $struct (struct (field (mut eqref)))) |
| 1092 | + ;; CHECK: (type $array (array (mut eqref))) |
| 1093 | + (type $array (array (field (mut eqref)))) |
1092 | 1094 | ) |
1093 | 1095 | ;; CHECK: (func $test-cmpxchg-scratch-oob (type $0) |
1094 | 1096 | ;; CHECK-NEXT: (local $a arrayref) |
1095 | 1097 | ;; CHECK-NEXT: (local $1 (ref null (exact $struct))) |
1096 | | - ;; CHECK-NEXT: (local $2 anyref) |
| 1098 | + ;; CHECK-NEXT: (local $2 eqref) |
1097 | 1099 | ;; CHECK-NEXT: (drop |
1098 | 1100 | ;; CHECK-NEXT: (block (result nullref) |
1099 | 1101 | ;; CHECK-NEXT: (ref.null none) |
1100 | 1102 | ;; CHECK-NEXT: ) |
1101 | 1103 | ;; CHECK-NEXT: ) |
1102 | 1104 | ;; CHECK-NEXT: (drop |
1103 | | - ;; CHECK-NEXT: (block (result anyref) |
| 1105 | + ;; CHECK-NEXT: (block (result eqref) |
1104 | 1106 | ;; CHECK-NEXT: (drop |
1105 | 1107 | ;; CHECK-NEXT: (block (result nullref) |
1106 | 1108 | ;; CHECK-NEXT: (local.set $2 |
|
1115 | 1117 | ;; CHECK-NEXT: ) |
1116 | 1118 | ;; CHECK-NEXT: ) |
1117 | 1119 | ;; CHECK-NEXT: (drop |
1118 | | - ;; CHECK-NEXT: (array.new_fixed $array 0) |
| 1120 | + ;; CHECK-NEXT: (array.new_fixed $inner 0) |
1119 | 1121 | ;; CHECK-NEXT: ) |
1120 | | - ;; CHECK-NEXT: (block (result anyref) |
| 1122 | + ;; CHECK-NEXT: (block (result eqref) |
1121 | 1123 | ;; CHECK-NEXT: (drop |
1122 | 1124 | ;; CHECK-NEXT: (ref.null none) |
1123 | 1125 | ;; CHECK-NEXT: ) |
|
1131 | 1133 | (local $a arrayref) |
1132 | 1134 | ;; This allocation and set get optimized, creating the LocalGraph flower. |
1133 | 1135 | (local.set $a |
1134 | | - (array.new_fixed $array 0) |
| 1136 | + (array.new_fixed $inner 0) |
1135 | 1137 | ) |
1136 | 1138 | (drop |
1137 | 1139 | ;; Then `expected` gets optimized, creating a new scratch local. Since the |
1138 | 1140 | ;; flower is already created, the index of the scratch local would be out |
1139 | 1141 | ;; of bounds if we tried to look it up in the LocalGraph. |
1140 | 1142 | (struct.atomic.rmw.cmpxchg $struct 0 |
1141 | 1143 | (struct.new_default $struct) |
1142 | | - (array.new_fixed $array 0) |
1143 | | - (array.new_fixed $array 0) |
| 1144 | + (array.new_fixed $inner 0) |
| 1145 | + (array.new_fixed $inner 0) |
| 1146 | + ) |
| 1147 | + ) |
| 1148 | + (unreachable) |
| 1149 | + ) |
| 1150 | + |
| 1151 | + ;; CHECK: (func $test-cmpxchg-scratch-oob-array (type $0) |
| 1152 | + ;; CHECK-NEXT: (local $a arrayref) |
| 1153 | + ;; CHECK-NEXT: (local $1 eqref) |
| 1154 | + ;; CHECK-NEXT: (local $2 eqref) |
| 1155 | + ;; CHECK-NEXT: (local $3 eqref) |
| 1156 | + ;; CHECK-NEXT: (local $4 eqref) |
| 1157 | + ;; CHECK-NEXT: (drop |
| 1158 | + ;; CHECK-NEXT: (block (result nullref) |
| 1159 | + ;; CHECK-NEXT: (ref.null none) |
| 1160 | + ;; CHECK-NEXT: ) |
| 1161 | + ;; CHECK-NEXT: ) |
| 1162 | + ;; CHECK-NEXT: (drop |
| 1163 | + ;; CHECK-NEXT: (block (result eqref) |
| 1164 | + ;; CHECK-NEXT: (drop |
| 1165 | + ;; CHECK-NEXT: (block (result nullref) |
| 1166 | + ;; CHECK-NEXT: (local.set $1 |
| 1167 | + ;; CHECK-NEXT: (ref.null none) |
| 1168 | + ;; CHECK-NEXT: ) |
| 1169 | + ;; CHECK-NEXT: (ref.null none) |
| 1170 | + ;; CHECK-NEXT: ) |
| 1171 | + ;; CHECK-NEXT: ) |
| 1172 | + ;; CHECK-NEXT: (local.set $3 |
| 1173 | + ;; CHECK-NEXT: (block (result nullref) |
| 1174 | + ;; CHECK-NEXT: (ref.null none) |
| 1175 | + ;; CHECK-NEXT: ) |
| 1176 | + ;; CHECK-NEXT: ) |
| 1177 | + ;; CHECK-NEXT: (local.set $4 |
| 1178 | + ;; CHECK-NEXT: (array.new_fixed $inner 0) |
| 1179 | + ;; CHECK-NEXT: ) |
| 1180 | + ;; CHECK-NEXT: (local.set $2 |
| 1181 | + ;; CHECK-NEXT: (local.get $1) |
| 1182 | + ;; CHECK-NEXT: ) |
| 1183 | + ;; CHECK-NEXT: (if |
| 1184 | + ;; CHECK-NEXT: (ref.eq |
| 1185 | + ;; CHECK-NEXT: (local.get $1) |
| 1186 | + ;; CHECK-NEXT: (local.get $3) |
| 1187 | + ;; CHECK-NEXT: ) |
| 1188 | + ;; CHECK-NEXT: (then |
| 1189 | + ;; CHECK-NEXT: (local.set $1 |
| 1190 | + ;; CHECK-NEXT: (local.get $4) |
| 1191 | + ;; CHECK-NEXT: ) |
| 1192 | + ;; CHECK-NEXT: ) |
| 1193 | + ;; CHECK-NEXT: ) |
| 1194 | + ;; CHECK-NEXT: (local.get $2) |
| 1195 | + ;; CHECK-NEXT: ) |
| 1196 | + ;; CHECK-NEXT: ) |
| 1197 | + ;; CHECK-NEXT: (unreachable) |
| 1198 | + ;; CHECK-NEXT: ) |
| 1199 | + (func $test-cmpxchg-scratch-oob-array |
| 1200 | + ;; Same as above, but accessing an array type. `ref` is always processed |
| 1201 | + ;; first, so we do not have the same problem to avoid. |
| 1202 | + (local $a arrayref) |
| 1203 | + (local.set $a |
| 1204 | + (array.new_fixed $inner 0) |
| 1205 | + ) |
| 1206 | + (drop |
| 1207 | + (array.atomic.rmw.cmpxchg $array |
| 1208 | + (array.new_default $array |
| 1209 | + (i32.const 1) |
| 1210 | + ) |
| 1211 | + (i32.const 0) |
| 1212 | + (array.new_fixed $inner 0) |
| 1213 | + (array.new_fixed $inner 0) |
1144 | 1214 | ) |
1145 | 1215 | ) |
1146 | 1216 | (unreachable) |
|
1318 | 1388 | ) |
1319 | 1389 | ) |
1320 | 1390 | ) |
| 1391 | + |
| 1392 | +(module |
| 1393 | + ;; CHECK: (type $array (array (mut eqref))) |
| 1394 | + (type $array (array (mut eqref))) |
| 1395 | + |
| 1396 | + ;; CHECK: (type $1 (func (param (ref $array)))) |
| 1397 | + |
| 1398 | + ;; CHECK: (func $array-cmpxchg-expected (type $1) (param $array (ref $array)) |
| 1399 | + ;; CHECK-NEXT: (local $1 eqref) |
| 1400 | + ;; CHECK-NEXT: (local $2 (ref null $array)) |
| 1401 | + ;; CHECK-NEXT: (drop |
| 1402 | + ;; CHECK-NEXT: (block (result eqref) |
| 1403 | + ;; CHECK-NEXT: (local.set $2 |
| 1404 | + ;; CHECK-NEXT: (local.get $array) |
| 1405 | + ;; CHECK-NEXT: ) |
| 1406 | + ;; CHECK-NEXT: (drop |
| 1407 | + ;; CHECK-NEXT: (block (result nullref) |
| 1408 | + ;; CHECK-NEXT: (local.set $1 |
| 1409 | + ;; CHECK-NEXT: (ref.null none) |
| 1410 | + ;; CHECK-NEXT: ) |
| 1411 | + ;; CHECK-NEXT: (ref.null none) |
| 1412 | + ;; CHECK-NEXT: ) |
| 1413 | + ;; CHECK-NEXT: ) |
| 1414 | + ;; CHECK-NEXT: (drop |
| 1415 | + ;; CHECK-NEXT: (ref.null none) |
| 1416 | + ;; CHECK-NEXT: ) |
| 1417 | + ;; CHECK-NEXT: (array.atomic.get $array |
| 1418 | + ;; CHECK-NEXT: (local.get $2) |
| 1419 | + ;; CHECK-NEXT: (i32.const 0) |
| 1420 | + ;; CHECK-NEXT: ) |
| 1421 | + ;; CHECK-NEXT: ) |
| 1422 | + ;; CHECK-NEXT: ) |
| 1423 | + ;; CHECK-NEXT: ) |
| 1424 | + (func $array-cmpxchg-expected (param $array (ref $array)) |
| 1425 | + (drop |
| 1426 | + ;; We should not convert this to a struct cmpxchg because we do not |
| 1427 | + ;; optimize the `ref`. We should still be able to optimize the `expected` |
| 1428 | + ;; field, though. |
| 1429 | + (array.atomic.rmw.cmpxchg $array |
| 1430 | + (local.get $array) |
| 1431 | + (i32.const 0) |
| 1432 | + (array.new_default $array |
| 1433 | + (i32.const 1) |
| 1434 | + ) |
| 1435 | + (ref.null none) |
| 1436 | + ) |
| 1437 | + ) |
| 1438 | + ) |
| 1439 | +) |
0 commit comments