Skip to content

Commit 2010baa

Browse files
authored
[GC] Directize: Fix subtyping (#7960)
This pass was written before function subtyping, and just checked equality.
1 parent d345393 commit 2010baa

2 files changed

Lines changed: 115 additions & 1 deletion

File tree

src/passes/Directize.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ struct FunctionDirectizer : public WalkerPass<PostWalker<FunctionDirectizer>> {
153153
return CallUtils::Trap{};
154154
}
155155
auto* func = getModule()->getFunction(name);
156-
if (original->heapType != func->type) {
156+
if (!HeapType::isSubType(func->type, original->heapType)) {
157157
return CallUtils::Trap{};
158158
}
159159
return CallUtils::Known{name};

test/lit/passes/directize-gc.wast

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
2+
;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up.
3+
4+
;; RUN: foreach %s %t wasm-opt --directize -all -S -o - | filecheck %s
5+
6+
;; Call a subtype with the supertype. This call should succeed.
7+
(module
8+
(rec
9+
;; CHECK: (type $0 (func))
10+
11+
;; CHECK: (rec
12+
;; CHECK-NEXT: (type $super (sub (func)))
13+
(type $super (sub (func)))
14+
;; CHECK: (type $sub (sub final $super (func)))
15+
(type $sub (sub final $super (func)))
16+
)
17+
18+
;; CHECK: (table $table 93 funcref)
19+
(table $table 93 funcref)
20+
21+
;; CHECK: (elem $elem (i32.const 0) $target)
22+
(elem $elem (i32.const 0) $target)
23+
24+
;; CHECK: (export "caller" (func $caller))
25+
26+
;; CHECK: (func $caller (type $0)
27+
;; CHECK-NEXT: (call $target)
28+
;; CHECK-NEXT: )
29+
(func $caller (export "caller")
30+
;; This turns into a direct call.
31+
(call_indirect (type $super)
32+
(i32.const 0)
33+
)
34+
)
35+
36+
;; CHECK: (func $target (type $sub)
37+
;; CHECK-NEXT: )
38+
(func $target (type $sub)
39+
)
40+
)
41+
42+
;; Remove the subtyping. This call should error.
43+
(module
44+
(rec
45+
;; CHECK: (type $0 (func))
46+
47+
;; CHECK: (rec
48+
;; CHECK-NEXT: (type $super (sub (func)))
49+
(type $super (sub (func)))
50+
;; CHECK: (type $other (sub (func)))
51+
(type $other (sub (func)))
52+
)
53+
54+
;; CHECK: (table $table 93 funcref)
55+
(table $table 93 funcref)
56+
57+
;; CHECK: (elem $elem (i32.const 0) $target)
58+
(elem $elem (i32.const 0) $target)
59+
60+
;; CHECK: (export "caller" (func $caller))
61+
62+
;; CHECK: (func $caller (type $0)
63+
;; CHECK-NEXT: (unreachable)
64+
;; CHECK-NEXT: )
65+
(func $caller (export "caller")
66+
;; This turns into an unreachable.
67+
(call_indirect (type $super)
68+
(i32.const 0)
69+
)
70+
)
71+
72+
;; CHECK: (func $target (type $other)
73+
;; CHECK-NEXT: )
74+
(func $target (type $other)
75+
)
76+
)
77+
78+
;; Reverse the subtyping: Call a supertype with a subtype. This call should
79+
;; fail.
80+
(module
81+
(rec
82+
;; CHECK: (type $0 (func))
83+
84+
;; CHECK: (rec
85+
;; CHECK-NEXT: (type $super (sub (func)))
86+
(type $super (sub (func)))
87+
;; CHECK: (type $sub (sub final $super (func)))
88+
(type $sub (sub final $super (func)))
89+
)
90+
91+
;; CHECK: (table $table 93 funcref)
92+
(table $table 93 funcref)
93+
94+
;; CHECK: (elem $elem (i32.const 0) $target)
95+
(elem $elem (i32.const 0) $target)
96+
97+
;; CHECK: (export "caller" (func $caller))
98+
99+
;; CHECK: (func $caller (type $0)
100+
;; CHECK-NEXT: (unreachable)
101+
;; CHECK-NEXT: )
102+
(func $caller (export "caller")
103+
;; This turns into a direct call.
104+
(call_indirect (type $sub)
105+
(i32.const 0)
106+
)
107+
)
108+
109+
;; CHECK: (func $target (type $super)
110+
;; CHECK-NEXT: )
111+
(func $target (type $super)
112+
)
113+
)
114+

0 commit comments

Comments
 (0)