Skip to content

Commit 9a96c2e

Browse files
authored
[Custom Descriptors] AbstractTypeRefining: Fix up ref.get_desc (WebAssembly#7922)
When removing a descriptor type, we may need to fix up uses of it.
1 parent da45c6c commit 9a96c2e

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

src/passes/AbstractTypeRefining.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,22 @@ struct AbstractTypeRefining : public Pass {
394394
}
395395
}
396396

397+
// If we optimize away a descriptor type, then we must fix up any
398+
// ref.get_desc of it, as ReFinalize would fix us up to return it. This
399+
// can only happen when no such descriptor is created, which means the
400+
// instruction will never be reached (no struct with such a descriptor was
401+
// created).
402+
void visitRefGetDesc(RefGetDesc* curr) {
403+
auto optimized = getOptimized(curr->type);
404+
if (!optimized) {
405+
return;
406+
}
407+
408+
Builder builder(*getModule());
409+
replaceCurrent(builder.makeSequence(builder.makeDrop(curr->ref),
410+
builder.makeUnreachable()));
411+
}
412+
397413
void visitBrOn(BrOn* curr) {
398414
if (curr->op == BrOnNull || curr->op == BrOnNonNull) {
399415
return;

test/lit/passes/abstract-type-refining-desc.wast

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,3 +1020,48 @@
10201020
)
10211021
)
10221022
)
1023+
1024+
(module
1025+
;; $B is never created. When removing it from the result of the function, we
1026+
;; must remove the ref.get_desc too (otherwise it would return a non-
1027+
;; validating type for the new result; and it traps anyhow).
1028+
(rec
1029+
;; YESTNH: (rec
1030+
;; YESTNH-NEXT: (type $A (sub (descriptor $B (struct))))
1031+
;; NO_TNH: (rec
1032+
;; NO_TNH-NEXT: (type $A (sub (descriptor $B (struct))))
1033+
(type $A (sub (descriptor $B (struct))))
1034+
;; YESTNH: (type $B (describes $A (struct)))
1035+
;; NO_TNH: (type $B (describes $A (struct)))
1036+
(type $B (describes $A (struct)))
1037+
)
1038+
1039+
;; YESTNH: (type $2 (func (result (ref none))))
1040+
1041+
;; YESTNH: (func $test (type $2) (result (ref none))
1042+
;; YESTNH-NEXT: (drop
1043+
;; YESTNH-NEXT: (struct.new_default $A
1044+
;; YESTNH-NEXT: (ref.null none)
1045+
;; YESTNH-NEXT: )
1046+
;; YESTNH-NEXT: )
1047+
;; YESTNH-NEXT: (unreachable)
1048+
;; YESTNH-NEXT: )
1049+
;; NO_TNH: (type $2 (func (result (ref none))))
1050+
1051+
;; NO_TNH: (func $test (type $2) (result (ref none))
1052+
;; NO_TNH-NEXT: (drop
1053+
;; NO_TNH-NEXT: (struct.new_default $A
1054+
;; NO_TNH-NEXT: (ref.null none)
1055+
;; NO_TNH-NEXT: )
1056+
;; NO_TNH-NEXT: )
1057+
;; NO_TNH-NEXT: (unreachable)
1058+
;; NO_TNH-NEXT: )
1059+
(func $test (result (ref (exact $B)))
1060+
(ref.get_desc $A
1061+
(struct.new_default $A
1062+
(ref.null none)
1063+
)
1064+
)
1065+
)
1066+
)
1067+

0 commit comments

Comments
 (0)