|
1056 | 1056 | ) |
1057 | 1057 | ) |
1058 | 1058 | ) |
| 1059 | + |
| 1060 | +(module |
| 1061 | + (rec |
| 1062 | + ;; CHECK: (rec |
| 1063 | + ;; CHECK-NEXT: (type $A (descriptor $B (struct (field v128)))) |
| 1064 | + (type $A (descriptor $B (struct (field v128)))) |
| 1065 | + ;; CHECK: (type $B (describes $A (struct))) |
| 1066 | + (type $B (describes $A (struct))) |
| 1067 | + ) |
| 1068 | + |
| 1069 | + ;; CHECK: (type $2 (func)) |
| 1070 | + |
| 1071 | + ;; CHECK: (func $test (type $2) |
| 1072 | + ;; CHECK-NEXT: (local $B (ref null $B)) |
| 1073 | + ;; CHECK-NEXT: (local $v v128) |
| 1074 | + ;; CHECK-NEXT: (local $2 v128) |
| 1075 | + ;; CHECK-NEXT: (local $3 (ref none)) |
| 1076 | + ;; CHECK-NEXT: (local $4 (ref none)) |
| 1077 | + ;; CHECK-NEXT: (drop |
| 1078 | + ;; CHECK-NEXT: (block (result nullref) |
| 1079 | + ;; CHECK-NEXT: (ref.null none) |
| 1080 | + ;; CHECK-NEXT: ) |
| 1081 | + ;; CHECK-NEXT: ) |
| 1082 | + ;; CHECK-NEXT: (local.tee $v |
| 1083 | + ;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit) |
| 1084 | + ;; CHECK-NEXT: (drop |
| 1085 | + ;; CHECK-NEXT: (block |
| 1086 | + ;; CHECK-NEXT: (drop |
| 1087 | + ;; CHECK-NEXT: (block (result nullref) |
| 1088 | + ;; CHECK-NEXT: (local.set $4 |
| 1089 | + ;; CHECK-NEXT: (ref.as_non_null |
| 1090 | + ;; CHECK-NEXT: (ref.null none) |
| 1091 | + ;; CHECK-NEXT: ) |
| 1092 | + ;; CHECK-NEXT: ) |
| 1093 | + ;; CHECK-NEXT: (local.set $2 |
| 1094 | + ;; CHECK-NEXT: (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000) |
| 1095 | + ;; CHECK-NEXT: ) |
| 1096 | + ;; CHECK-NEXT: (local.set $3 |
| 1097 | + ;; CHECK-NEXT: (local.get $4) |
| 1098 | + ;; CHECK-NEXT: ) |
| 1099 | + ;; CHECK-NEXT: (ref.null none) |
| 1100 | + ;; CHECK-NEXT: ) |
| 1101 | + ;; CHECK-NEXT: ) |
| 1102 | + ;; CHECK-NEXT: (drop |
| 1103 | + ;; CHECK-NEXT: (ref.null none) |
| 1104 | + ;; CHECK-NEXT: ) |
| 1105 | + ;; CHECK-NEXT: (unreachable) |
| 1106 | + ;; CHECK-NEXT: ) |
| 1107 | + ;; CHECK-NEXT: ) |
| 1108 | + ;; CHECK-NEXT: (unreachable) |
| 1109 | + ;; CHECK-NEXT: ) |
| 1110 | + ;; CHECK-NEXT: ) |
| 1111 | + ;; CHECK-NEXT: ) |
| 1112 | + (func $test |
| 1113 | + (local $B (ref null $B)) |
| 1114 | + (local $v v128) |
| 1115 | + |
| 1116 | + ;; We can optimize a few times here. As we do so, the local.set becomes |
| 1117 | + ;; unreachable, as its descriptor is null. Later work will replace the |
| 1118 | + ;; nested struct.get there, which was unreachable, with a local.get of a |
| 1119 | + ;; v128, a concrete type, causing an error as now the local.set is |
| 1120 | + ;; unreachable but the child is not. To avoid this problem, we should not |
| 1121 | + ;; modify unreachable code. |
| 1122 | + |
| 1123 | + (drop |
| 1124 | + (ref.as_non_null |
| 1125 | + (local.tee $B |
| 1126 | + (struct.new_default $B) |
| 1127 | + ) |
| 1128 | + ) |
| 1129 | + ) |
| 1130 | + (local.set $v |
| 1131 | + (struct.get $A 0 |
| 1132 | + (ref.cast_desc (ref $A) |
| 1133 | + (struct.new_default $A |
| 1134 | + (ref.as_non_null |
| 1135 | + (ref.null none) |
| 1136 | + ) |
| 1137 | + ) |
| 1138 | + (ref.as_non_null |
| 1139 | + (local.get $B) |
| 1140 | + ) |
| 1141 | + ) |
| 1142 | + ) |
| 1143 | + ) |
| 1144 | + ) |
| 1145 | +) |
| 1146 | + |
0 commit comments