Skip to content

Commit dcc704c

Browse files
authored
Directize: Refine results (WebAssembly#7974)
If the actual target is of a subtype, its results may be more refined.
1 parent 5898877 commit dcc704c

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

src/passes/Directize.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,15 @@ struct FunctionDirectizer : public WalkerPass<PostWalker<FunctionDirectizer>> {
189189

190190
// Everything looks good!
191191
auto name = std::get<CallUtils::Known>(info).target;
192-
replaceCurrent(
193-
Builder(*getModule())
194-
.makeCall(name, operands, original->type, original->isReturn));
192+
auto results = getModule()->getFunction(name)->getResults();
193+
replaceCurrent(Builder(*getModule())
194+
.makeCall(name, operands, results, original->isReturn));
195+
196+
// When we call a function of a subtype of the call_indirect's call type, we
197+
// may be refining results.
198+
if (results != original->type) {
199+
changedTypes = true;
200+
}
195201
}
196202
};
197203

test/lit/passes/directize-gc.wast

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,40 @@
112112
)
113113
)
114114

115+
;; call_indirect using the supertype. The direct call has a more refined type,
116+
;; which we must update the IR to.
117+
(module
118+
(rec
119+
;; CHECK: (rec
120+
;; CHECK-NEXT: (type $super (sub (func (result (ref any)))))
121+
(type $super (sub (func (result (ref any)))))
122+
;; CHECK: (type $sub (sub $super (func (result (ref none)))))
123+
(type $sub (sub $super (func (result (ref none)))))
124+
)
125+
126+
;; CHECK: (table $table 42 funcref)
127+
(table $table 42 funcref)
128+
;; CHECK: (elem $elem (i32.const 0) $sub)
129+
(elem $elem (i32.const 0) $sub)
130+
131+
;; CHECK: (func $super (type $super) (result (ref any))
132+
;; CHECK-NEXT: (block $show-type (result (ref none))
133+
;; CHECK-NEXT: (call $sub)
134+
;; CHECK-NEXT: )
135+
;; CHECK-NEXT: )
136+
(func $super (type $super) (result (ref any))
137+
(block $show-type (result (ref any))
138+
(call_indirect $table (type $super)
139+
(i32.const 0)
140+
)
141+
)
142+
)
143+
144+
;; CHECK: (func $sub (type $sub) (result (ref none))
145+
;; CHECK-NEXT: (unreachable)
146+
;; CHECK-NEXT: )
147+
(func $sub (type $sub) (result (ref none))
148+
(unreachable)
149+
)
150+
)
151+

0 commit comments

Comments
 (0)