File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -761,6 +761,18 @@ struct GlobalTypeOptimization : public Pass {
761761 curr->index = newIndex;
762762 }
763763
764+ void visitRefCast (RefCast* curr) {
765+ // Unreachable ref.cast_desc instructions would not have been counted as
766+ // reading the descriptor field, so their descriptor operands may no
767+ // longer be descriptors. This is invalid, so replace such casts
768+ // entirely.
769+ if (curr->type == Type::unreachable && curr->desc &&
770+ curr->desc ->type != Type::unreachable) {
771+ assert (curr->ref ->type == Type::unreachable);
772+ replaceCurrent (curr->ref );
773+ }
774+ }
775+
764776 void visitFunction (Function* curr) {
765777 if (needEHFixups) {
766778 EHUtils::handleBlockNestedPops (curr, *getModule ());
Original file line number Diff line number Diff line change 13961396 )
13971397)
13981398
1399+ ;; We can optimize away the descriptor since its only use is unreachable, but
1400+ ;; we must update that use to remain valid despite being unreachable.
1401+ (module
1402+ (rec
1403+ ;; CHECK: (rec
1404+ ;; CHECK-NEXT: (type $struct (sub (struct)))
1405+ (type $struct (sub (descriptor $desc (struct ))))
1406+ ;; CHECK: (type $desc (sub (struct)))
1407+ (type $desc (sub (describes $struct (struct ))))
1408+ )
1409+ ;; CHECK: (type $2 (func))
1410+
1411+ ;; CHECK: (func $test (type $2)
1412+ ;; CHECK-NEXT: (local $struct (ref $struct))
1413+ ;; CHECK-NEXT: (local $desc (ref $desc))
1414+ ;; CHECK-NEXT: (drop
1415+ ;; CHECK-NEXT: (unreachable)
1416+ ;; CHECK-NEXT: )
1417+ ;; CHECK-NEXT: )
1418+ (func $test
1419+ (local $struct (ref $struct ))
1420+ (local $desc (ref $desc ))
1421+ (drop
1422+ (ref.cast_desc (ref $struct )
1423+ (unreachable )
1424+ (struct.new $desc )
1425+ )
1426+ )
1427+ )
1428+ )
1429+
You can’t perform that action at this time.
0 commit comments